- preparation work.

# Conflicts:
#	source/core/gamecontrol.cpp
This commit is contained in:
Christoph Oelckers 2020-06-11 09:22:16 +02:00
parent 1bb7da173a
commit e9925eee0f
127 changed files with 75025 additions and 119 deletions

View file

@ -1305,6 +1305,7 @@ unset( PCH_SOURCES )
unset( HEADER_FILES )
unset( NOT_COMPILED_SOURCE_FILES )
add_subdirectory( duke )
add_subdirectory( duke3d )
add_subdirectory( blood )
add_subdirectory( rr )

View file

@ -419,6 +419,10 @@ void UserConfig::ProcessOptions()
//
//==========================================================================
namespace Duke3d
{
::GameInterface* CreateInterface();
}
namespace Duke
{
::GameInterface* CreateInterface();
@ -445,6 +449,7 @@ extern int MinFPSRate; // this is a bit messy.
void CheckFrontend(int flags)
{
auto old = Args->CheckValue("-duke_old");
MinFPSRate = 30;
bool duke_compat = duke_compatibility_15;
// This point is too early to have cmdline CVAR checkers working so it must be with a switch.
@ -458,10 +463,6 @@ void CheckFrontend(int flags)
{
gi = Blood::CreateInterface();
}
else if (flags & GAMEFLAG_RRALL)
{
gi = Redneck::CreateInterface();
}
else if (flags & GAMEFLAG_SW)
{
MinFPSRate = 40;
@ -471,6 +472,14 @@ void CheckFrontend(int flags)
{
gi = Powerslave::CreateInterface();
}
else if (old)
{
gi = Duke3d::CreateInterface();
}
else if (flags & GAMEFLAG_RRALL)
{
gi = Redneck::CreateInterface();
}
else if ((flags & GAMEFLAG_FURY) || GameStartupInfo.modern > 0)
{
gi = Duke::CreateInterface();

View file

@ -57,6 +57,7 @@
#include "v_video.h"
void RegisterDukeMenus();
void RegisterDuke3dMenus();
void RegisterRedneckMenus();
void RegisterBloodMenus();
void RegisterSWMenus();
@ -1017,6 +1018,7 @@ void M_PreviousMenu()
void M_Init (void)
{
RegisterDukeMenus();
RegisterDuke3dMenus();
RegisterRedneckMenus();
RegisterBloodMenus();
RegisterSWMenus();

View file

@ -2,9 +2,12 @@
#ifndef NO_NAMESPACE
#define BEGIN_DUKE_NS namespace Duke {
#define BEGIN_DUKE_NS namespace Duke3d {
#define END_DUKE_NS }
#define BEGIN_EDUKE_NS namespace Duke {
#define END_EDUKE_NS }
#define BEGIN_RR_NS namespace Redneck {
#define END_RR_NS }
@ -19,6 +22,9 @@
#else
#define BEGIN_EDUKE_NS
#define END_EDUKE_NS
#define BEGIN_DUKE_NS
#define END_DUKE_NS

View file

@ -0,0 +1,30 @@
set( PCH_SOURCES
src/actors.cpp
src/anim.cpp
src/cheats.cpp
src/cmdline.cpp
src/common.cpp
src/config.cpp
src/d_menu.cpp
src/demo.cpp
src/game.cpp
src/gamedef.cpp
src/gameexec.cpp
src/gamevars.cpp
src/global.cpp
src/namesdyn.cpp
src/net.cpp
src/osdcmds.cpp
src/player.cpp
src/premap.cpp
src/savegame.cpp
src/sbar.cpp
src/screens.cpp
src/text.cpp
src/sector.cpp
src/sounds.cpp
src/soundsdyn.cpp
src/rrdh.cpp)
add_game_library( duke )

9748
source/duke/src/actors.cpp Normal file

File diff suppressed because it is too large Load diff

340
source/duke/src/actors.h Normal file
View file

@ -0,0 +1,340 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef actors_h_
#define actors_h_
#include "player.h"
# include "namesdyn.h"
BEGIN_DUKE_NS
#define MAXSLEEPDIST 16384
#define SLEEPTIME 1536
#define ZOFFSET (1<<8)
#define ZOFFSET2 (16<<8)
#define ZOFFSET3 (8<<8)
#define ZOFFSET4 (12<<8)
#define ZOFFSET5 (32<<8)
#define ZOFFSET6 (4<<8)
#define ACTOR_MAXFALLINGZVEL 6144
#define ACTOR_ONWATER_ADDZ (24<<8)
#define STAT_DEFAULT 0
#define STAT_ACTOR 1
#define STAT_ZOMBIEACTOR 2
#define STAT_EFFECTOR 3
#define STAT_PROJECTILE 4
#define STAT_MISC 5
#define STAT_STANDABLE 6
#define STAT_LOCATOR 7
#define STAT_ACTIVATOR 8
#define STAT_TRANSPORT 9
#define STAT_PLAYER 10
#define STAT_FX 11
#define STAT_FALLER 12
#define STAT_DUMMYPLAYER 13
#define STAT_LIGHT 14
#define STAT_RAROR 15
#define STAT_NETALLOC MAXSTATUS-1
// Defines the motion characteristics of an actor
enum amoveflags_t
{
face_player = 1,
geth = 2,
getv = 4,
random_angle = 8,
face_player_slow = 16,
spin = 32,
face_player_smart = 64,
fleeenemy = 128,
jumptoplayer_only = 256,
jumptoplayer_bits = 257, // NOTE: two bits set!
seekplayer = 512,
furthestdir = 1024,
dodgebullet = 4096,
justjump2 = 8192,
windang = 16384,
antifaceplayerslow = 32768
};
// Defines for 'useractor' keyword
enum uactortypes_t
{
notenemy,
enemy,
enemystayput
};
// These macros are there to give names to the t_data[]/T*/vm.g_t[] indices
// when used with actors. Greppability of source code is certainly a virtue.
#define AC_COUNT(t) ((t)[0]) /* the actor's count */
/* The ID of the actor's current move. In C-CON, the bytecode offset to the
* move composite: */
#define AC_MOVE_ID(t) ((t)[1])
#define AC_ACTION_COUNT(t) ((t)[2]) /* the actor's action count */
#define AC_CURFRAME(t) ((t)[3]) /* the actor's current frame offset */
/* The ID of the actor's current action. In C-CON, the bytecode offset to the
* action composite: */
#define AC_ACTION_ID(t) ((t)[4])
#define AC_AI_ID(t) ((t)[5]) /* the ID of the actor's current ai */
enum actionparams
{
ACTION_STARTFRAME = 0,
ACTION_NUMFRAMES,
ACTION_VIEWTYPE,
ACTION_INCVAL,
ACTION_DELAY,
ACTION_FLAGS,
ACTION_PARAM_COUNT,
};
enum actionflags
{
AF_VIEWPOINT = 1u<<0u,
};
// <spr>: sprite pointer
// <a>: actor_t pointer
# define AC_ACTIONTICS(spr, a) ((spr)->lotag)
# define AC_MOVFLAGS(spr, a) ((spr)->hitag)
// (+ 40 16 16 4 8 6 8 6 4 20)
#pragma pack(push, 1)
typedef struct
{
int32_t t_data[10]; // 40b sometimes used to hold offsets to con code
int32_t flags; // 4b
vec3_t bpos; // 12b
int32_t floorz, ceilingz; // 8b
vec2_t lastv; // 8b
int16_t picnum, ang, extra, owner; // 8b
int16_t movflag, tempang, timetosleep; // 6b
int16_t actorstayput; // 2b
uint8_t cgg, lasttransport; // 2b
// NOTE: 'dispicnum' is updated every frame, not in sync with game tics!
int16_t dispicnum; // 2b
#ifdef POLYMER
int16_t lightId, lightmaxrange; // 4b
_prlight *lightptr; // 4b/8b aligned on 96 bytes
uint8_t lightcount, filler[3];
#endif
} actor_t;
// this struct needs to match the beginning of actor_t above
typedef struct
{
int32_t t_data[10]; // 40b sometimes used to hold offsets to con code
int32_t flags; // 4b
vec3_t bpos; // 12b
int32_t floorz, ceilingz; // 8b
vec2_t lastv; // 8b
int16_t picnum, ang, extra, owner; // 8b
int16_t movflag, tempang, timetosleep; // 6b
int16_t actorstayput;
uint8_t cgg, lasttransport;
spritetype sprite;
int16_t netIndex;
} netactor_t;
#pragma pack(pop)
typedef struct
{
intptr_t *execPtr; // pointer to CON script for this tile, formerly actorscrptr
intptr_t *loadPtr; // pointer to load time CON script, formerly actorLoadEventScrPtr or something
uint32_t flags; // formerly SpriteFlags, ActorType
int32_t cacherange; // formerly SpriteCache
} tiledata_t;
enum sflags_t
{
SFLAG_SHADOW = 0x00000001,
SFLAG_NVG = 0x00000002,
SFLAG_NOSHADE = 0x00000004,
SFLAG_PROJECTILE = 0x00000008,
SFLAG_DECAL = 0x00000010,
SFLAG_BADGUY = 0x00000020,
SFLAG_NOPAL = 0x00000040,
SFLAG_NOEVENTCODE = 0x00000080,
SFLAG_NOLIGHT = 0x00000100,
SFLAG_USEACTIVATOR = 0x00000200,
SFLAG_NULL = 0x00000400, // null sprite in multiplayer
SFLAG_NOCLIP = 0x00000800, // clipmove it with cliptype 0
SFLAG_NOFLOORSHADOW = 0x00001000, // for temp. internal use, per-tile flag not checked
SFLAG_SMOOTHMOVE = 0x00002000,
SFLAG_NOTELEPORT = 0x00004000,
SFLAG_BADGUYSTAYPUT = 0x00008000,
SFLAG_CACHE = 0x00010000,
// rotation-fixed wrt a pivot point to prevent position diverging due to
// roundoff error accumulation:
SFLAG_ROTFIXED = 0x00020000,
SFLAG_HARDCODED_BADGUY = 0x00040000,
SFLAG_DIDNOSE7WATER = 0x00080000, // used temporarily
SFLAG_NODAMAGEPUSH = 0x00100000,
SFLAG_NOWATERDIP = 0x00200000,
SFLAG_HURTSPAWNBLOOD = 0x00400000,
SFLAG_GREENSLIMEFOOD = 0x00800000,
SFLAG_REALCLIPDIST = 0x01000000,
SFLAG_WAKEUPBADGUYS = 0x02000000,
SFLAG_DAMAGEEVENT = 0x04000000,
SFLAG_BADGUY_TILE = 0x08000000,
SFLAG_KILLCOUNT = 0x10000000,
SFLAG_NOCANSEECHECK = 0x20000000,
};
// Custom projectiles "workslike" flags.
// XXX: Currently not predefined from CON.
enum pflags_t
{
PROJECTILE_HITSCAN = 0x00000001,
PROJECTILE_RPG = 0x00000002,
PROJECTILE_BOUNCESOFFWALLS = 0x00000004,
PROJECTILE_BOUNCESOFFMIRRORS = 0x00000008,
PROJECTILE_KNEE = 0x00000010,
PROJECTILE_WATERBUBBLES = 0x00000020,
PROJECTILE_TIMED = 0x00000040,
PROJECTILE_BOUNCESOFFSPRITES = 0x00000080,
PROJECTILE_SPIT = 0x00000100,
PROJECTILE_COOLEXPLOSION1 = 0x00000200,
PROJECTILE_BLOOD = 0x00000400,
PROJECTILE_LOSESVELOCITY = 0x00000800,
PROJECTILE_NOAIM = 0x00001000,
PROJECTILE_RANDDECALSIZE = 0x00002000,
PROJECTILE_EXPLODEONTIMER = 0x00004000,
PROJECTILE_RPG_IMPACT = 0x00008000,
PROJECTILE_RADIUS_PICNUM = 0x00010000,
PROJECTILE_ACCURATE_AUTOAIM = 0x00020000,
PROJECTILE_FORCEIMPACT = 0x00040000,
PROJECTILE_REALCLIPDIST = 0x00080000,
PROJECTILE_ACCURATE = 0x00100000,
PROJECTILE_NOSETOWNERSHADE = 0x00200000,
PROJECTILE_RPG_IMPACT_DAMAGE = 0x00400000,
PROJECTILE_MOVED = 0x80000000, // internal flag, do not document
PROJECTILE_TYPE_MASK = PROJECTILE_HITSCAN | PROJECTILE_RPG | PROJECTILE_KNEE | PROJECTILE_BLOOD,
};
extern tiledata_t g_tile[MAXTILES];
extern actor_t actor[MAXSPRITES];
extern int32_t block_deletesprite;
extern int32_t g_noEnemies;
extern int32_t otherp;
extern int32_t ticrandomseed;
extern int g_canSeePlayer;
int A_CheckNoSE7Water(uspritetype const *pSprite, int sectNum, int sectLotag, int32_t *pOther);
int A_CheckSwitchTile(int spriteNum);
int A_IncurDamage(int spriteNum);
void A_AddToDeleteQueue(int spriteNum);
void A_DeleteSprite(int spriteNum);
void A_DoGuts(int spriteNum, int tileNum, int spawnCnt);
void A_DoGutsDir(int spriteNum, int tileNum, int spawnCnt);
void A_MoveCyclers(void);
void A_MoveDummyPlayers(void);
void A_MoveSector(int spriteNum);
void A_PlayAlertSound(int spriteNum);
void A_RadiusDamage(int spriteNum, int blastRadius, int dmg1, int dmg2, int dmg3, int dmg4);
void A_SpawnMultiple(int spriteNum, int tileNum, int spawnCnt);
void A_ResetLanePics(void);
int G_SetInterpolation(int32_t *posptr);
void G_AddGameLight(int lightRadius, int spriteNum, int zOffset, int lightRange, int lightColor, int lightPrio);
void G_ClearCameraView(DukePlayer_t *ps);
void G_DoInterpolations(int smoothRatio);
void G_MoveWorld(void);
void G_RefreshLights(void);
void G_StopInterpolation(const int32_t *posptr);
// PK 20110701: changed input argument: int32_t i (== sprite, whose sectnum...) --> sectnum directly
void Sect_ToggleInterpolation(int sectnum, int setInterpolation);
static FORCE_INLINE void Sect_ClearInterpolation(int sectnum) { Sect_ToggleInterpolation(sectnum, 0); }
static FORCE_INLINE void Sect_SetInterpolation(int sectnum) { Sect_ToggleInterpolation(sectnum, 1); }
#if KRANDDEBUG
# define ACTOR_INLINE __fastcall
# define ACTOR_INLINE_HEADER extern __fastcall
#else
# define ACTOR_INLINE EXTERN_INLINE
# define ACTOR_INLINE_HEADER EXTERN_INLINE_HEADER
#endif
extern int32_t A_MoveSprite(int32_t spritenum, vec3_t const * change, uint32_t cliptype);
ACTOR_INLINE_HEADER int A_CheckEnemyTile(int tileNum);
ACTOR_INLINE_HEADER int A_SetSprite(int spriteNum, uint32_t cliptype);
EXTERN_INLINE_HEADER int G_CheckForSpaceCeiling(int sectnum);
EXTERN_INLINE_HEADER int G_CheckForSpaceFloor(int sectnum);
EXTERN_INLINE_HEADER int A_CheckEnemySprite(void const * s);
#if defined actors_c_ || !defined DISABLE_INLINING
# if !KRANDDEBUG || (KRANDDEBUG && defined actors_c_)
ACTOR_INLINE int A_CheckEnemyTile(int const tileNum)
{
return ((g_tile[tileNum].flags & (SFLAG_BADGUY_TILE | SFLAG_BADGUY)) != 0);
}
ACTOR_INLINE int A_SetSprite(int const spriteNum, uint32_t cliptype)
{
vec3_t davect = { (sprite[spriteNum].xvel * (sintable[(sprite[spriteNum].ang + 512) & 2047])) >> 14,
(sprite[spriteNum].xvel * (sintable[sprite[spriteNum].ang & 2047])) >> 14, sprite[spriteNum].zvel };
return (A_MoveSprite(spriteNum, &davect, cliptype) == 0);
}
# endif
EXTERN_INLINE int G_CheckForSpaceCeiling(int const sectnum)
{
return ((sector[sectnum].ceilingstat&1) && sector[sectnum].ceilingpal == 0 &&
(sector[sectnum].ceilingpicnum==MOONSKY1 || sector[sectnum].ceilingpicnum==BIGORBIT1));
}
EXTERN_INLINE int G_CheckForSpaceFloor(int const sectnum)
{
return ((sector[sectnum].floorstat&1) && sector[sectnum].ceilingpal == 0 &&
(sector[sectnum].floorpicnum==MOONSKY1 || sector[sectnum].floorpicnum==BIGORBIT1));
}
EXTERN_INLINE int A_CheckEnemySprite(void const * const pSprite)
{
return A_CheckEnemyTile(((uspritetype const *) pSprite)->picnum);
}
#endif
END_DUKE_NS
#endif

574
source/duke/src/anim.cpp Normal file
View file

@ -0,0 +1,574 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "baselayer.h"
#include "baselayer.h"
#include "duke3d.h"
#include "animlib.h"
#include "compat.h"
#include "cmdlib.h"
#include "v_2ddrawer.h"
#include "animtexture.h"
#include "../glbackend/glbackend.h"
#include "anim.h"
#ifdef USE_LIBVPX
# include "animvpx.h"
#endif
BEGIN_DUKE_NS
// animsound_t.sound
TArray<dukeanim_t> g_Animations;
dukeanim_t * g_animPtr;
dukeanim_t* Anim_Find(const char* s)
{
auto index = g_Animations.FindEx([=](dukeanim_t& anm) { return !anm.name.CompareNoCase(s); });
if (index == g_Animations.Size())
{
FString fname = s;
DefaultExtension(fname, ".anm");
index = g_Animations.FindEx([=](dukeanim_t& anm) { return !anm.name.CompareNoCase(fname); });
if (index == g_Animations.Size())
{
fname = s;
DefaultExtension(fname, ".ivf");
index = g_Animations.FindEx([=](dukeanim_t& anm) { return !anm.name.CompareNoCase(fname); });
if (index == g_Animations.Size()) return nullptr;
}
}
return &g_Animations[index];
}
dukeanim_t * Anim_Create(char const * fn)
{
g_Animations.Reserve(1);
auto p = &g_Animations.Last();
p->name = fn;
return p;
}
#ifdef DYNSOUNDREMAP_ENABLE
static int32_t const StopAllSounds = -1;
#else
# define StopAllSounds -1
#endif
void Anim_Init(void)
{
struct defaultanmsound {
#ifdef DYNSOUNDREMAP_ENABLE
int32_t const & sound;
#else
int16_t sound;
#endif
uint8_t frame;
};
static defaultanmsound const logo[] =
{
{ FLY_BY, 1 },
{ PIPEBOMB_EXPLODE, 19 },
};
static defaultanmsound const cineov2[] =
{
{ WIND_AMBIENCE, 1 },
{ ENDSEQVOL2SND1, 26 },
{ ENDSEQVOL2SND2, 36 },
{ THUD, 54 },
{ ENDSEQVOL2SND3, 62 },
{ ENDSEQVOL2SND4, 75 },
{ ENDSEQVOL2SND5, 81 },
{ ENDSEQVOL2SND6, 115 },
{ ENDSEQVOL2SND7, 124 },
};
static defaultanmsound const cineov3[] =
{
{ WIND_REPEAT, 1 },
{ DUKE_GRUNT, 98 },
{ THUD, 82+20 },
{ SQUISHED, 82+20 },
{ ENDSEQVOL3SND3, 104+20 },
{ ENDSEQVOL3SND2, 114+20 },
{ PIPEBOMB_EXPLODE, 158 },
};
static defaultanmsound const vol42a[] =
{
{ INTRO4_B, 1 },
{ SHORT_CIRCUIT, 12 },
{ INTRO4_5, 18 },
{ SHORT_CIRCUIT, 34 },
};
static defaultanmsound const vol41a[] =
{
{ INTRO4_1, 1 },
{ INTRO4_3, 7 },
{ INTRO4_2, 12 },
{ INTRO4_4, 26 },
};
static defaultanmsound const vol43a[] =
{
{ INTRO4_6, 10 },
};
static defaultanmsound const vol4e1[] =
{
{ DUKE_UNDERWATER, 3 },
{ VOL4ENDSND1, 35 },
};
static defaultanmsound const vol4e2[] =
{
{ DUKE_UNDERWATER, 11 },
{ VOL4ENDSND1, 20 },
{ VOL4ENDSND2, 39 },
{ StopAllSounds, 50 },
};
static defaultanmsound const vol4e3[] =
{
{ BOSS4_DEADSPEECH, 1 },
{ VOL4ENDSND1, 40 },
{ DUKE_UNDERWATER, 40 },
{ BIGBANG, 50 },
};
static defaultanmsound const rr_intro[] =
{
{ 29, 1 },
};
static defaultanmsound const redneck[] =
{
{ 478, 1 },
};
static defaultanmsound const xatlogo[] =
{
{ 479, 1 },
};
static defaultanmsound const turdmov[] =
{
{ 82, 1 },
};
static defaultanmsound const rr_outro[] =
{
{ 35, 1 },
};
struct defaultanm {
char const *fn;
defaultanmsound const *sounds;
uint8_t numsounds;
uint8_t fdelay;
};
#define anmsnd(x) (x), ARRAY_SIZE(x)
static defaultanm const anms[] =
{
{ "logo.anm", anmsnd(logo), 9 },
{ "3dr.anm", NULL, 0, 10 },
{ "vol4e1.anm", anmsnd(vol4e1), 10 },
{ "vol4e2.anm", anmsnd(vol4e2), 14 },
{ "vol4e3.anm", anmsnd(vol4e3), 10 },
{ "vol41a.anm", anmsnd(vol41a), 14 },
{ "vol42a.anm", anmsnd(vol42a), 18 },
{ "vol43a.anm", anmsnd(vol43a), 10 },
{ "duketeam.anm", NULL, 0, 10 },
{ "radlogo.anm", NULL, 0, 10 },
{ "cineov2.anm", anmsnd(cineov2), 18 },
{ "cineov3.anm", anmsnd(cineov3), 10 },
{ "rr_intro.anm", anmsnd(rr_intro), 9 },
{ "redneck.anm", anmsnd(redneck), 9 },
{ "xatlogo.anm", anmsnd(xatlogo), 9 },
{ "turdmov.anm", anmsnd(turdmov), 9 },
{ "rr_outro.anm", anmsnd(rr_outro), 9 },
{ "lvl1.anm", NULL, 0, 20 },
{ "lvl2.anm", NULL, 0, 20 },
{ "lvl3.anm", NULL, 0, 20 },
{ "lvl4.anm", NULL, 0, 20 },
{ "lvl5.anm", NULL, 0, 20 },
{ "lvl6.anm", NULL, 0, 20 },
{ "lvl7.anm", NULL, 0, 20 },
{ "lvl8.anm", NULL, 0, 20 },
{ "lvl9.anm", NULL, 0, 20 },
{ "lvl10.anm", NULL, 0, 20 },
{ "lvl11.anm", NULL, 0, 20 },
{ "lvl12.anm", NULL, 0, 20 },
{ "lvl13.anm", NULL, 0, 20 },
};
#undef anmsnd
for (defaultanm const& anm : anms)
{
dukeanim_t* anim = Anim_Create(anm.fn);
anim->framedelay = anm.fdelay;
if (anm.numsounds)
{
anim->Sounds.Resize(anm.numsounds);
int const numsounds = anm.numsounds;
for (int i = 0; i < numsounds; ++i)
{
defaultanmsound const& src = anm.sounds[i];
animsound_t& dst = anim->Sounds[i];
dst.sound = src.sound;
dst.frame = src.frame;
}
}
anim->frameflags = 0;
}
}
int32_t Anim_Play(const char *fn)
{
dukeanim_t *anim = Anim_Find(fn);
if (!anim)
{
Printf("Animation %s is undefined!\n", fn);
return 0;
}
uint16_t soundidx = 0; // custom anim sounds
int32_t running = 1, i;
inputState.ClearAllInput();
#ifdef USE_LIBVPX
uint16_t framenum = 0;
while (videoGetRenderMode() >= REND_POLYMOST) // if, really
{
char const * dot = Bstrrchr(fn, '.');
if (!dot)
break;
dukeanim_t const * origanim = anim;
FileReader handle;
if (!Bstrcmp(dot, ".ivf"))
{
handle = fileSystem.OpenFileReader(fn);
if (!handle.isOpen())
break;
}
else
{
char vpxfn[BMAX_PATH];
Bstrncpyz(vpxfn, fn, BMAX_PATH);
ptrdiff_t dotpos = dot - fn;
if (dotpos + 4 >= BMAX_PATH)
break;
char *vpxfndot = vpxfn + dotpos;
vpxfndot[1] = 'i';
vpxfndot[2] = 'v';
vpxfndot[3] = 'f';
vpxfndot[4] = '\0';
handle = fileSystem.OpenFileReader(vpxfn);
if (!handle.isOpen())
break;
anim = Anim_Find(vpxfn);
}
animvpx_ivf_header_t info;
i = animvpx_read_ivf_header(handle, &info);
if (i)
{
Printf("Failed reading IVF file: %s\n", animvpx_read_ivf_header_errmsg[i]);
return 0;
}
if (anim)
animvpx_setup_glstate(anim->frameflags);
else
animvpx_setup_glstate(origanim->frameflags);
animvpx_codec_ctx codec;
if (animvpx_init_codec(&info, handle, &codec))
{
Printf("Error initializing VPX codec.\n");
animvpx_restore_glstate();
return 0;
}
uint32_t const convnumer = 120 * info.fpsdenom;
uint32_t const convdenom = info.fpsnumer * origanim->framedelay;
uint32_t const msecsperframe = scale(info.fpsdenom, 1000, info.fpsnumer);
uint32_t nextframetime = timerGetTicks();
uint8_t *pic;
// Printf("msecs per frame: %d\n", msecsperframe);
do
{
nextframetime += msecsperframe;
i = animvpx_nextpic(&codec, &pic);
if (i)
{
Printf("Failed getting next pic: %s\n", animvpx_nextpic_errmsg[i]);
if (codec.errmsg)
{
Printf(" %s\n", codec.errmsg);
if (codec.errmsg_detail)
Printf(" detail: %s\n", codec.errmsg_detail);
}
break;
}
if (!pic)
break; // no more pics!
twod->ClearScreen();
ototalclock = totalclock + 1; // pause game like ANMs
if (anim)
{
if (anim->frameaspect1 == 0 || anim->frameaspect2 == 0)
animvpx_render_frame(&codec, 0);
else
animvpx_render_frame(&codec, anim->frameaspect1 / anim->frameaspect2);
}
else
{
if (origanim->frameaspect1 == 0 || origanim->frameaspect2 == 0)
animvpx_render_frame(&codec, 0);
else
animvpx_render_frame(&codec, origanim->frameaspect1 / origanim->frameaspect2);
}
// after rendering the frame but before displaying: maybe play sound...
framenum++;
if (anim)
{
while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= framenum)
{
int16_t sound = anim->Sounds[soundidx].sound;
if (sound == -1)
FX_StopAllSounds();
else
S_PlaySound(sound, CHAN_AUTO, CHANF_UI);
soundidx++;
}
}
else
{
uint16_t convframenum = scale(framenum, convnumer, convdenom);
while (soundidx < origanim->Sounds.Size() && origanim->Sounds[soundidx].frame <= convframenum)
{
int16_t sound = origanim->Sounds[soundidx].sound;
if (sound == -1)
FX_StopAllSounds();
else
S_PlaySound(sound, CHAN_AUTO, CHANF_UI);
soundidx++;
}
}
videoNextPage();
do
{
G_HandleAsync();
if (inputState.CheckAllInput())
{
running = 0;
break;
}
} while (timerGetTicks() < nextframetime);
} while (running);
#ifdef DEBUGGINGAIDS
animvpx_print_stats(&codec);
#endif
//
animvpx_restore_glstate();
animvpx_uninit_codec(&codec);
inputState.ClearAllInput();
return !running; // done with playing VP8!
}
#endif
// ANM playback --- v v v ---
int32_t ogltexfiltermode = gl_texture_filter;
auto fr = fileSystem.OpenFileReader(fn);
if (!fr.isOpen())
return 0;
auto buffer = fr.ReadPadded(1);
fr.Close();
if (buffer.Size() <= 5)
{
Printf("Warning: skipping playback of empty ANM file \"%s\".\n", fn);
goto end_anim;
}
anim->animbuf = buffer.Data();
uint32_t firstfour;
Bmemcpy(&firstfour, anim->animbuf, 4);
// "DKIF" (.ivf)
if (firstfour == B_LITTLE32(0x46494B44))
goto end_anim;
int32_t numframes;
// "LPF " (.anm)
if (firstfour != B_LITTLE32(0x2046504C) ||
ANIM_LoadAnim(anim->animbuf, buffer.Size()-1) < 0 ||
(numframes = ANIM_NumFrames()) <= 0)
{
// XXX: ANM_LoadAnim() still checks less than the bare minimum,
// e.g. ANM file could still be too small and not contain any frames.
Printf("Error: malformed ANM file \"%s\".\n", fn);
goto end_anim;
}
ototalclock = totalclock;
i = 1;
int32_t frametime; frametime = 0;
{
AnimTextures animtex;
animtex.SetSize(320, 200);
do
{
if (i > 4 && totalclock > frametime + 60)
{
Printf("WARNING: slowdown in %s, skipping playback\n", fn);
goto end_anim_restore_gl;
}
G_HandleAsync();
if (totalclock < ototalclock - 1)
continue;
animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(i));
if (inputState.CheckAllInput())
{
running = 0;
goto end_anim_restore_gl;
}
if (g_restorePalette == 1)
{
P_SetGamePalette(g_player[myconnectindex].ps, ANIMPAL, 0);
g_restorePalette = 0;
}
frametime = (int32_t)totalclock;
videoClearScreen(0);
int32_t z;
#if 0
if (anim->frameaspect1 > 0 && anim->frameaspect2 > 0 && ((anim->frameaspect1 / anim->frameaspect2) != (tilesiz[TILE_ANIM].y / (tilesiz[TILE_ANIM].x * 1.2))))
{
int32_t const oyxaspect = yxaspect;
if ((anim->frameaspect1 / anim->frameaspect2) >= ((decltype(anim->frameaspect1))xdim / ydim))
z = divscale16(320, tilesiz[TILE_ANIM].y);
else
z = divscale16(lrint(320 * ydim * anim->frameaspect1), lrint(tilesiz[TILE_ANIM].y * xdim * anim->frameaspect2));
int32_t aspect = divscale16(lrint(tilesiz[TILE_ANIM].y * anim->frameaspect2), lrint(tilesiz[TILE_ANIM].x * anim->frameaspect1));
renderSetAspect(viewingrange, aspect);
rotatesprite_fs(160 << 16, 100 << 16, z, 512, TILE_ANIM, 0, 0, 2 | 4 | 8 | 64 | 1024);
renderSetAspect(viewingrange, oyxaspect);
}
else
#endif
{
if ((320 / (200 * 1.2f)) > (1.f * xdim / ydim))
z = divscale16(320 * xdim * 3, 320 * ydim * 4);
else
z = divscale16(200, 200);
rotatesprite_fs(160 << 16, 100 << 16, z, 0, -1, 0, 0, 2 | 8 | 64, animtex.GetFrame());
}
g_animPtr = NULL;
videoNextPage();
inputState.ClearAllInput();
ototalclock += anim->framedelay;
while (soundidx < anim->Sounds.Size() && anim->Sounds[soundidx].frame <= (uint16_t)i)
{
int16_t sound = anim->Sounds[soundidx].sound;
if (sound == -1)
FX_StopAllSounds();
else
S_PlaySound(sound, CHAN_AUTO, CHANF_UI);
soundidx++;
}
++i;
} while (i < numframes);
}
end_anim_restore_gl:
gl_texture_filter = ogltexfiltermode;
gltexapplyprops();
end_anim:
inputState.ClearAllInput();
anim->animbuf = nullptr;
ANIM_FreeAnim();
tileDelete(TILE_ANIM);
return !running;
}
END_DUKE_NS

52
source/duke/src/anim.h Normal file
View file

@ -0,0 +1,52 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef anim_h_
#define anim_h_
BEGIN_DUKE_NS
struct animsound_t {
uint16_t frame = 0;
int16_t sound = 0;
};
struct dukeanim_t
{
FString name;
double frameaspect1 = 0, frameaspect2 = 0;
uint8_t* animbuf = nullptr;
TArray<animsound_t> Sounds;
uint8_t framedelay = 0;
uint8_t frameflags = 0;
};
extern dukeanim_t* g_animPtr;
extern TArray<dukeanim_t> g_Animations;
extern dukeanim_t * Anim_Find(const char *s);
extern dukeanim_t * Anim_Create(const char *fn);
int32_t Anim_Play(const char *fn);
void Anim_Init(void);
END_DUKE_NS
#endif

939
source/duke/src/cheats.cpp Normal file
View file

@ -0,0 +1,939 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "duke3d.h"
#include "osdcmds.h"
#include "cheats.h"
#include "mapinfo.h"
#include "c_dispatch.h"
BEGIN_DUKE_NS
// KEEPINSYNC game.h: enum cheatindex_t
char CheatStrings [NUMCHEATS][MAXCHEATLEN] =
{
"cornholio", // 0
"stuff", // 1
"scotty###", // 2
"coords", // 3
"view", // 4
"time", // 5
"unlock", // 6
"cashman", // 7
"items", // 8
"rate", // 9
"skill#", // 10
"beta", // 11
"hyper", // 12
"monsters", // 13
"<RESERVED>", // 14
"<RESERVED>", // 15
"todd", // 16
"showmap", // 17
"kroz", // 18
"allen", // 19
"clip", // 20
"weapons", // 21
"inventory", // 22
"keys", // 23
"debug", // 24
"<RESERVED>", // 25
"<RESERVED>", // 26
"<RESERVED>", // 27
"<RESERVED>", // 28
"<RESERVED>", // 29
"<RESERVED>", // 30
"<RESERVED>", // 31
"<RESERVED>", // 32
"<RESERVED>", // 33
"<RESERVED>", // 34
"<RESERVED>", // 35
"<RESERVED>", // 36
"<RESERVED>", // 37
"<RESERVED>", // 38
"<RESERVED>", // 39
};
const uint32_t CheatFunctionFlags [NUMCHEATS] =
{
1 << CHEATFUNC_GOD,
1 << CHEATFUNC_GIVEEVERYTHING,
1 << CHEATFUNC_WARP,
1 << CHEATFUNC_COORDS,
1 << CHEATFUNC_VIEW,
0,
1 << CHEATFUNC_UNLOCK,
1 << CHEATFUNC_CASHMAN,
1 << CHEATFUNC_GIVEALLITEMS,
1 << CHEATFUNC_FRAMERATE,
1 << CHEATFUNC_SKILL,
1 << CHEATFUNC_QUOTEBETA,
1 << CHEATFUNC_HYPER,
1 << CHEATFUNC_MONSTERS,
0,
0,
1 << CHEATFUNC_QUOTETODD,
1 << CHEATFUNC_SHOWMAP,
1 << CHEATFUNC_GOD,
1 << CHEATFUNC_QUOTEALLEN,
1 << CHEATFUNC_CLIP,
1 << CHEATFUNC_GIVEWEAPONS,
1 << CHEATFUNC_GIVEINVENTORY,
1 << CHEATFUNC_GIVEKEYS,
1 << CHEATFUNC_DEBUG,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
};
// KEEPINSYNC game.h: enum CheatCodeFunctions
// KEEPINSYNC menus.c: MenuEntry_t ME_CheatCodes[]
const uint8_t CheatFunctionIDs[NUMCHEATS] =
{
CHEAT_CASHMAN,
CHEAT_CORNHOLIO,
CHEAT_STUFF,
CHEAT_WEAPONS,
CHEAT_ITEMS,
CHEAT_INVENTORY,
CHEAT_KEYS,
CHEAT_HYPER,
CHEAT_VIEW,
CHEAT_SHOWMAP,
CHEAT_UNLOCK,
CHEAT_CLIP,
CHEAT_SCOTTY,
CHEAT_SKILL,
CHEAT_MONSTERS,
CHEAT_RATE,
CHEAT_BETA,
CHEAT_TODD,
CHEAT_ALLEN,
CHEAT_COORDS,
CHEAT_DEBUG,
};
char const * const g_NAMMattCheatQuote = "Matt Saettler. matts@seanet.com";
void G_SetupCheats(void)
{
if (RR)
{
CheatKeys[0] = sc_R;
CheatKeys[1] = sc_D;
Bstrcpy(CheatStrings[0], "hounddog");
Bstrcpy(CheatStrings[1], "all");
Bstrcpy(CheatStrings[2], "meadow###");
Bstrcpy(CheatStrings[3], "yerat");
Bstrcpy(CheatStrings[7], "cluck");
Bstrcpy(CheatStrings[11], "teachers");
Bstrcpy(CheatStrings[12], "moonshine");
Bstrcpy(CheatStrings[13], "critters");
Bstrcpy(CheatStrings[16], "rafael");
Bstrcpy(CheatStrings[18], "elvis");
Bstrcpy(CheatStrings[19], "<RESERVED>");
Bstrcpy(CheatStrings[21], "guns");
if (RRRA)
{
Bstrcpy(CheatStrings[25], "joseph");
Bstrcpy(CheatStrings[26], "mrbill");
Bstrcpy(CheatStrings[27], "tony");
Bstrcpy(CheatStrings[28], "gary");
Bstrcpy(CheatStrings[29], "rhett");
Bstrcpy(CheatStrings[30], "aaron");
Bstrcpy(CheatStrings[31], "nocheat");
Bstrcpy(CheatStrings[32], "woleslagle");
Bstrcpy(CheatStrings[33], "mikael");
Bstrcpy(CheatStrings[34], "greg");
Bstrcpy(CheatStrings[35], "noah");
Bstrcpy(CheatStrings[36], "arijit");
Bstrcpy(CheatStrings[37], "donut");
Bstrcpy(CheatStrings[38], "kfc");
Bstrcpy(CheatStrings[39], "van");
}
}
if (WW2GI)
{
#if 0
// WWII GI's original cheat prefix temporarily disabled because W conflicts with WSAD movement
CheatKeys[0] = CheatKeys[1] = sc_W;
#else
CheatKeys[0] = sc_G;
CheatKeys[1] = sc_I;
#endif
Bstrcpy(CheatStrings[0], "2god");
Bstrcpy(CheatStrings[1], "2blood");
Bstrcpy(CheatStrings[2], "2level###");
Bstrcpy(CheatStrings[3], "2coords");
Bstrcpy(CheatStrings[4], "2view");
Bstrcpy(CheatStrings[5], "<RESERVED>");
Bstrcpy(CheatStrings[7], "<RESERVED>");
Bstrcpy(CheatStrings[8], "<RESERVED>");
Bstrcpy(CheatStrings[9], "2rate");
Bstrcpy(CheatStrings[10], "2skill");
Bstrcpy(CheatStrings[11], "<RESERVED>");
Bstrcpy(CheatStrings[12], "<RESERVED>");
Bstrcpy(CheatStrings[13], "<RESERVED>");
Bstrcpy(CheatStrings[16], "2matt");
Bstrcpy(CheatStrings[17], "2showmap");
Bstrcpy(CheatStrings[18], "2ryan");
Bstrcpy(CheatStrings[19], "<RESERVED>");
Bstrcpy(CheatStrings[20], "2clip");
Bstrcpy(CheatStrings[21], "2weapons");
Bstrcpy(CheatStrings[22], "2inventory");
Bstrcpy(CheatStrings[23], "<RESERVED>");
Bstrcpy(CheatStrings[24], "2debug");
Bstrcpy(CheatStrings[26], "2cgs");
Bstrcpy(g_gametypeNames[0], "GI Match (Spawn)");
Bstrcpy(g_gametypeNames[2], "GI Match (No Spawn)");
}
else if (NAM)
{
CheatKeys[0] = sc_N;
CheatKeys[1] = sc_V;
Bstrcpy(CheatStrings[0], "acaleb");
Bstrcpy(CheatStrings[1], "ablood");
Bstrcpy(CheatStrings[2], "alevel###");
Bstrcpy(CheatStrings[3], "acoords");
Bstrcpy(CheatStrings[4], "aview");
Bstrcpy(CheatStrings[5], "<RESERVED>");
Bstrcpy(CheatStrings[7], "<RESERVED>");
Bstrcpy(CheatStrings[8], "<RESERVED>");
Bstrcpy(CheatStrings[9], "arate");
Bstrcpy(CheatStrings[10], "askill");
Bstrcpy(CheatStrings[11], "<RESERVED>");
Bstrcpy(CheatStrings[12], "ahyper");
Bstrcpy(CheatStrings[13], "<RESERVED>");
Bstrcpy(CheatStrings[16], "amatt");
Bstrcpy(CheatStrings[17], "ashowmap");
Bstrcpy(CheatStrings[18], "agod");
Bstrcpy(CheatStrings[19], "<RESERVED>");
Bstrcpy(CheatStrings[20], "aclip");
Bstrcpy(CheatStrings[21], "aweapons");
Bstrcpy(CheatStrings[22], "ainventory");
Bstrcpy(CheatStrings[23], "<RESERVED>");
Bstrcpy(CheatStrings[24], "adebug");
Bstrcpy(CheatStrings[26], "acgs");
}
}
static void doinvcheat(DukePlayer_t * const pPlayer, int32_t invidx, int32_t defaultnum, int event)
{
defaultnum = VM_OnEventWithReturn(event, pPlayer->i, myconnectindex, defaultnum);
if (defaultnum >= 0)
pPlayer->inv_amount[invidx] = defaultnum;
}
static void G_CheatGetInv(DukePlayer_t *pPlayer)
{
doinvcheat(pPlayer, GET_STEROIDS, 400, EVENT_CHEATGETSTEROIDS);
if (!RR) doinvcheat(pPlayer, GET_HEATS, 1200, EVENT_CHEATGETHEAT);
doinvcheat(pPlayer, GET_BOOTS, RR ? 2000 : 200, EVENT_CHEATGETBOOT);
doinvcheat(pPlayer, GET_SHIELD, 100, EVENT_CHEATGETSHIELD);
doinvcheat(pPlayer, GET_SCUBA, 6400, EVENT_CHEATGETSCUBA);
doinvcheat(pPlayer, GET_HOLODUKE, 2400, EVENT_CHEATGETHOLODUKE);
doinvcheat(pPlayer, GET_JETPACK, RR ? 600 : 1600, EVENT_CHEATGETJETPACK);
doinvcheat(pPlayer, GET_FIRSTAID, pPlayer->max_player_health, EVENT_CHEATGETFIRSTAID);
}
static void end_cheat(DukePlayer_t * const pPlayer)
{
pPlayer->cheat_phase = 0;
inputState.keyFlushChars();
}
static int32_t cheatbuflen;
static int8_t cheatbuf[MAXCHEATLEN];
void G_DoCheats(void)
{
DukePlayer_t * const pPlayer = g_player[myconnectindex].ps;
int consoleCheat = 0;
int cheatNum;
if (DEER)
return;
if (osdcmd_cheatsinfo_stat.cheatnum != -1)
{
cheatNum = osdcmd_cheatsinfo_stat.cheatnum;
if (ud.player_skill == 4 || (RR && ud.player_skill > 3) || (RRRA && pPlayer->nocheat))
{
switch (cheatNum)
{
case CHEAT_DEBUG:
case CHEAT_COORDS:
case CHEAT_RATE:
case CHEAT_RESERVED:
case CHEAT_RESERVED2:
//case CHEAT_RESERVED3:
break;
default:
P_DoQuote(QUOTE_CHEATS_DISABLED, pPlayer);
osdcmd_cheatsinfo_stat.cheatnum = -1;
return;
}
}
// JBF 20030914
osdcmd_cheatsinfo_stat.cheatnum = -1;
consoleCheat = 1;
}
static int volumeOne = 0;
if (VOLUMEONE && !volumeOne)
{
// change "scotty###" to "scotty##"
uint32_t const warpend = Bstrlen(CheatStrings[2]);
if (strcmp(&CheatStrings[2][warpend-3], "###") == 0)
CheatStrings[2][warpend-1] = '\0';
Bstrcpy(CheatStrings[6], "<RESERVED>");
volumeOne = 1;
}
if (consoleCheat && numplayers < 2 && ud.recstat == 0)
goto FOUNDCHEAT;
if ((RR && ud.player_skill > 3) || (RRRA && pPlayer->nocheat))
return;
if (pPlayer->gm & (MODE_TYPE|MODE_MENU))
return;
if (pPlayer->cheat_phase == 1)
{
int ch;
while (inputState.keyBufferWaiting())
{
ch = Btolower(inputState.keyGetChar());
if (!((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')))
{
pPlayer->cheat_phase = 0;
// P_DoQuote(QUOTE_46,pPlayer);
return;
}
cheatbuf[cheatbuflen++] = (int8_t) ch;
// This assertion is not obvious, but it should hold because of the
// cheat string matching logic below.
Bassert(cheatbuflen < (signed)sizeof(cheatbuf));
cheatbuf[cheatbuflen] = 0;
// inputState.ClearAllInput();
for (cheatNum=0; cheatNum < NUMCHEATCODES; cheatNum++)
{
for (bssize_t j = 0; j<cheatbuflen; j++)
{
if (cheatbuf[j] == CheatStrings[cheatNum][j] || (CheatStrings[cheatNum][j] == '#' && ch >= '0' && ch <= '9'))
{
if (CheatStrings[cheatNum][j+1] == 0) goto FOUNDCHEAT;
if (j == cheatbuflen-1) return;
}
else break;
}
}
pPlayer->cheat_phase = 0;
return;
FOUNDCHEAT:;
if (cheatNum == CHEAT_SCOTTY)
{
size_t const i = Bstrlen(CheatStrings[cheatNum])-3+VOLUMEONE;
if (!consoleCheat)
{
// JBF 20030914
int32_t volnume, levnume;
if (VOLUMEALL)
{
volnume = cheatbuf[i] - '0';
levnume = (cheatbuf[i+1] - '0')*10+(cheatbuf[i+2]-'0');
}
else
{
volnume = cheatbuf[i] - '0';
levnume = cheatbuf[i+1] - '0';
}
volnume--;
levnume--;
ud.m_volume_number = volnume;
m_level_number = levnume;
}
else
{
// JBF 20030914
ud.m_volume_number = osdcmd_cheatsinfo_stat.volume;
m_level_number = osdcmd_cheatsinfo_stat.level;
}
}
else if (cheatNum == CHEAT_SKILL)
{
if (!consoleCheat)
{
size_t const i = Bstrlen(CheatStrings[cheatNum])-1;
ud.m_player_skill = cheatbuf[i] - '1';
}
else
{
ud.m_player_skill = osdcmd_cheatsinfo_stat.volume;
}
}
{
switch (cheatNum)
{
case CHEAT_WEAPONS:
{
int const weaponLimit = (VOLUMEONE) ? 6 : 0;
for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < MAX_WEAPONS-weaponLimit; weaponNum++)
{
P_AddAmmo(pPlayer, weaponNum, pPlayer->max_ammo_amount[weaponNum]);
pPlayer->gotweapon |= (1<<weaponNum);
}
if (RRRA) pPlayer->ammo_amount[SLINGBLADE_WEAPON] = 1;
P_DoQuote(QUOTE_CHEAT_ALL_WEAPONS, pPlayer);
end_cheat(pPlayer);
}
return;
case CHEAT_INVENTORY:
G_CheatGetInv(pPlayer);
P_DoQuote(QUOTE_CHEAT_ALL_INV, pPlayer);
end_cheat(pPlayer);
return;
case CHEAT_KEYS:
pPlayer->got_access = 7;
if (RR)
for (int key = 0; key < 5; key++)
pPlayer->keys[key] = 1;
inputState.keyFlushChars();
P_DoQuote(QUOTE_CHEAT_ALL_KEYS, pPlayer);
end_cheat(pPlayer);
return;
case CHEAT_DEBUG:
g_Debug = 1-g_Debug;
G_DumpDebugInfo();
Bsprintf(tempbuf, "Gamevars dumped to log");
G_AddUserQuote(tempbuf);
Bsprintf(tempbuf, "Map dumped to debug.map");
G_AddUserQuote(tempbuf);
end_cheat(pPlayer);
break;
case CHEAT_CLIP:
ud.noclip = !ud.noclip;
P_DoQuote(QUOTE_CHEAT_NOCLIP-!ud.noclip, pPlayer);
end_cheat(pPlayer);
return;
case CHEAT_RESERVED2:
if (RR)
{
P_DoQuote(QUOTE_JETPACK_ON, pPlayer);
inputState.keyFlushChars();
}
else
{
pPlayer->player_par = 0;
pPlayer->gm = MODE_EOL;
}
end_cheat(pPlayer);
return;
case CHEAT_ALLEN:
P_DoQuote(QUOTE_CHEAT_ALLEN, pPlayer);
pPlayer->cheat_phase = 0;
inputState.ClearKeyStatus(sc_N);
return;
case CHEAT_CORNHOLIO:
case CHEAT_KROZ:
//case CHEAT_COMEGETSOME:
{
const int32_t pi = pPlayer->i;
ud.god = 1-ud.god;
if (ud.god)
{
if (RRRA)
S_PlaySound(218);
pus = 1;
pub = 1;
sprite[pi].cstat = 257;
actor[pi].t_data[0] = 0;
actor[pi].t_data[1] = 0;
actor[pi].t_data[2] = 0;
actor[pi].t_data[3] = 0;
actor[pi].t_data[4] = 0;
actor[pi].t_data[5] = 0;
sprite[pi].hitag = 0;
sprite[pi].lotag = 0;
sprite[pi].pal = pPlayer->palookup;
//if (cheatNum != CHEAT_COMEGETSOME)
//{
P_DoQuote(QUOTE_CHEAT_GODMODE_ON, pPlayer);
//}
//else
//{
// Bstrcpy(pStrings[QUOTE_RESERVED4], "Come Get Some!");
//
// S_PlaySound(DUKE_GETWEAPON2);
// P_DoQuote(QUOTE_RESERVED4, pPlayer);
// G_CheatGetInv(pPlayer);
//
// for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < MAX_WEAPONS; weaponNum++)
// pPlayer->gotweapon |= (1<<weaponNum);
//
// for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < MAX_WEAPONS; weaponNum++)
// P_AddAmmo(pPlayer, weaponNum, pPlayer->max_ammo_amount[weaponNum]);
//
// pPlayer->got_access = 7;
//}
}
else
{
sprite[pi].extra = pPlayer->max_player_health;
actor[pi].extra = -1;
pPlayer->last_extra = pPlayer->max_player_health;
P_DoQuote(QUOTE_CHEAT_GODMODE_OFF, pPlayer);
}
sprite[pi].extra = pPlayer->max_player_health;
actor[pi].extra = 0;
//if (cheatNum != CHEAT_COMEGETSOME)
pPlayer->dead_flag = 0;
end_cheat(pPlayer);
return;
}
case CHEAT_STUFF:
{
int const weaponLimit = (VOLUMEONE) ? 6 : 0;
for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < MAX_WEAPONS-weaponLimit; weaponNum++)
pPlayer->gotweapon |= (1<<weaponNum);
for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < MAX_WEAPONS-weaponLimit; weaponNum++)
P_AddAmmo(pPlayer, weaponNum, pPlayer->max_ammo_amount[weaponNum]);
if (RRRA)
pPlayer->ammo_amount[SLINGBLADE_WEAPON] = 1;
G_CheatGetInv(pPlayer);
pPlayer->got_access = 7;
if (RR)
for (int key = 0; key < 5; key++)
pPlayer->keys[key] = 1;
P_DoQuote(QUOTE_CHEAT_EVERYTHING, pPlayer);
// P_DoQuote(QUOTE_21,pPlayer);
pPlayer->inven_icon = ICON_FIRSTAID;
end_cheat(pPlayer);
return;
}
case CHEAT_SCOTTY:
{
if (RR)
g_lastLevel = 0;
int32_t const volnume = ud.m_volume_number, levnume = m_level_number;
if ((!VOLUMEONE || volnume == 0) && (unsigned)volnume < (unsigned)g_volumeCnt &&
(unsigned)levnume < MAXLEVELS && mapList[volnume*MAXLEVELS + levnume].fileName.IsNotEmpty())
{
ud.volume_number = volnume;
ud.level_number = levnume;
#if 0
if (numplayers > 1 && g_netServer)
Net_NewGame(volnume, levnume);
else
#endif
pPlayer->gm |= MODE_RESTART;
}
end_cheat(pPlayer);
return;
}
case CHEAT_SKILL:
if (RR)
g_lastLevel = 0;
ud.player_skill = ud.m_player_skill;
#if 0
if (numplayers > 1 && g_netServer)
Net_NewGame(ud.m_volume_number, m_level_number);
else
#endif
pPlayer->gm |= MODE_RESTART;
end_cheat(pPlayer);
return;
case CHEAT_COORDS:
C_DoCommand("stat coord");
end_cheat(pPlayer);
return;
case CHEAT_VIEW:
if (!RRRA || (!pPlayer->on_motorcycle && !pPlayer->on_boat))
{
pPlayer->over_shoulder_on ^= 1;
CAMERADIST = 0;
CAMERACLOCK = (int32_t) totalclock;
// P_DoQuote(QUOTE_CHEATS_DISABLED,pPlayer);
}
end_cheat(pPlayer);
return;
case CHEAT_TIME:
// P_DoQuote(QUOTE_21,pPlayer);
end_cheat(pPlayer);
return;
case CHEAT_UNLOCK:
if (VOLUMEONE) return;
for (bssize_t i=numsectors-1; i>=0; i--) //Unlock
{
int const lotag = sector[i].lotag;
if (lotag == -1 || lotag == 32767) continue;
if ((lotag & 0x7fff) > 2)
{
if (lotag & (uint16_t)~16384u)
sector[i].lotag &= (uint16_t)~16384u;
G_OperateSectors(i, pPlayer->i);
}
}
G_OperateForceFields(pPlayer->i, -1);
P_DoQuote(QUOTE_CHEAT_UNLOCK, pPlayer);
end_cheat(pPlayer);
return;
case CHEAT_CASHMAN:
ud.cashman = 1-ud.cashman;
inputState.ClearKeyStatus(sc_N);
pPlayer->cheat_phase = 0;
return;
case CHEAT_ITEMS:
G_CheatGetInv(pPlayer);
pPlayer->got_access = 7;
if (RR)
for(int key = 0; key < 5; key++)
pPlayer->keys[key] = 1;
P_DoQuote(QUOTE_CHEAT_EVERYTHING, pPlayer);
end_cheat(pPlayer);
return;
case CHEAT_SHOWMAP: // SHOW ALL OF THE MAP TOGGLE;
gFullMap = !gFullMap;
P_DoQuote(gFullMap ? QUOTE_SHOW_MAP_ON : QUOTE_SHOW_MAP_OFF,
pPlayer);
end_cheat(pPlayer);
return;
case CHEAT_TODD:
if (NAM_WW2GI)
{
quoteMgr.InitializeQuote(QUOTE_RESERVED4, g_NAMMattCheatQuote);
P_DoQuote(QUOTE_RESERVED4, pPlayer);
}
else
{
P_DoQuote(QUOTE_CHEAT_TODD, pPlayer);
}
end_cheat(pPlayer);
return;
case CHEAT_RATE:
r_showfps = clamp(*r_showfps+1, 0, 3);
end_cheat(pPlayer);
return;
case CHEAT_BETA:
P_DoQuote(QUOTE_CHEAT_BETA, pPlayer);
inputState.ClearKeyStatus(sc_H);
end_cheat(pPlayer);
return;
case CHEAT_HYPER:
pPlayer->inv_amount[GET_STEROIDS] = 399;
if (!RR)
pPlayer->inv_amount[GET_HEATS] = 1200;
P_DoQuote(QUOTE_CHEAT_STEROIDS, pPlayer);
end_cheat(pPlayer);
return;
case CHEAT_MONSTERS:
{
const char *s [] = { "OPTVAL_ON", "OPTVAL_OFF", "$TXT_ON2" };
if (++g_noEnemies == 3)
g_noEnemies = 0;
quoteMgr.FormatQuote(QUOTE_RESERVED4, "%s: %s", GStrings("NETMNU_MONSTERS"), s[g_noEnemies]);
P_DoQuote(QUOTE_RESERVED4, pPlayer);
end_cheat(pPlayer);
return;
}
case CHEAT_RESERVED:
//case CHEAT_RESERVED3:
if (RR)
{
P_DoQuote(51, pPlayer);
end_cheat(pPlayer);
}
else
{
ud.eog = 1;
pPlayer->player_par = 0;
pPlayer->gm |= MODE_EOL;
}
inputState.keyFlushChars();
return;
case CHEAT_RAJOSEPH:
G_OnMotorcycle(pPlayer, 0);
pPlayer->ammo_amount[MOTORCYCLE_WEAPON] = pPlayer->max_ammo_amount[MOTORCYCLE_WEAPON];
P_DoQuote(126, pPlayer);
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RAMRBILL:
P_QuickKill(pPlayer);
P_DoQuote(127, pPlayer);
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RAGARY:
S_PlayRRMusic(10);
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RANOAH:
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RARHETT:
ud.god = 0;
pPlayer->gotweapon = 1<<KNEE_WEAPON;
pPlayer->curr_weapon = KNEE_WEAPON;
pPlayer->nocheat = 1;
sprite[pPlayer->i].extra = 1;
P_DoQuote(128, pPlayer);
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RAAARON:
pPlayer->drug_mode = pPlayer->drug_mode ? 0 : 5;
pPlayer->drug_timer = (int32_t) totalclock;
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RANOCHEAT:
pPlayer->nocheat = 1;
P_DoQuote(130, pPlayer);
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RATONY:
g_changeEnemySize = 2;
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RAVAN:
g_changeEnemySize = 3;
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RAKFC:
for (int i = 0; i < 7; i++)
{
int const newSprite = A_Spawn(pPlayer->i, HEN);
sprite[newSprite].pal = 1;
sprite[newSprite].xrepeat <<= 2;
sprite[newSprite].yrepeat <<= 2;
}
P_DoQuote(139, pPlayer);
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RAWOLESLAGLE:
if (pPlayer->drink_amt)
{
pPlayer->drink_amt = 0;
P_DoQuote(132, pPlayer);
}
else
{
pPlayer->drink_amt = 90;
P_DoQuote(131, pPlayer);
}
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RAMIKAEL:
for (bssize_t weaponNum = PISTOL_WEAPON; weaponNum < MAX_WEAPONS; weaponNum++)
{
pPlayer->gotweapon |= 1 << weaponNum;
pPlayer->ammo_amount[weaponNum] = 66;
}
pPlayer->ammo_amount[SLINGBLADE_WEAPON] = 1;
G_CheatGetInv(pPlayer);
pPlayer->got_access = 7;
for (int key = 0; key < 5; key++)
pPlayer->keys[key] = 1;
P_DoQuote(5, pPlayer);
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RAGREG:
if (pPlayer->sea_sick_stat)
{
pPlayer->sea_sick_stat = 0;
P_DoQuote(129, pPlayer);
}
else
{
pPlayer->sea_sick_stat = 1;
P_DoQuote(137, pPlayer);
}
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
case CHEAT_RAARIJIT:
case CHEAT_RADONUT:
G_OnBoat(pPlayer, 0);
pPlayer->ammo_amount[BOAT_WEAPON] = pPlayer->max_ammo_amount[BOAT_WEAPON];
P_DoQuote(136, pPlayer);
end_cheat(pPlayer);
inputState.keyFlushChars();
return;
default:
end_cheat(pPlayer);
return;
}
}
}
}
else
{
if (inputState.GetKeyStatus((uint8_t) CheatKeys[0]))
{
if (pPlayer->cheat_phase >= 0 && numplayers < 2 && ud.recstat == 0)
{
if (CheatKeys[0] == CheatKeys[1])
inputState.ClearKeyStatus((uint8_t) CheatKeys[0]);
pPlayer->cheat_phase = -1;
}
}
if (inputState.GetKeyStatus((uint8_t) CheatKeys[1]))
{
if (pPlayer->cheat_phase == -1)
{
if (ud.player_skill == 4)
{
P_DoQuote(QUOTE_CHEATS_DISABLED, pPlayer);
pPlayer->cheat_phase = 0;
}
else
{
pPlayer->cheat_phase = 1;
// P_DoQuote(QUOTE_25,pPlayer);
cheatbuflen = 0;
}
inputState.keyFlushChars();
}
else if (pPlayer->cheat_phase != 0)
{
pPlayer->cheat_phase = 0;
inputState.ClearKeyStatus((uint8_t) CheatKeys[0]);
inputState.ClearKeyStatus((uint8_t) CheatKeys[1]);
}
}
}
}
END_DUKE_NS

110
source/duke/src/cheats.h Normal file
View file

@ -0,0 +1,110 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
BEGIN_DUKE_NS
#define MAXCHEATLEN 20
#define NUMCHEATCODES (int32_t)ARRAY_SIZE(CheatStrings)
extern void G_DoCheats(void);
extern void G_SetupCheats(void);
// Cheats
// KEEPINSYNC game.c: char CheatStrings[][]
enum cheatindex_t
{
CHEAT_CORNHOLIO, // 0
CHEAT_STUFF,
CHEAT_SCOTTY,
CHEAT_COORDS,
CHEAT_VIEW,
CHEAT_TIME, // 5
CHEAT_UNLOCK,
CHEAT_CASHMAN,
CHEAT_ITEMS,
CHEAT_RATE,
CHEAT_SKILL, // 10
CHEAT_BETA,
CHEAT_HYPER,
CHEAT_MONSTERS,
CHEAT_RESERVED,
CHEAT_RESERVED2, // 15
CHEAT_TODD,
CHEAT_SHOWMAP,
CHEAT_KROZ,
CHEAT_ALLEN,
CHEAT_CLIP, // 20
CHEAT_WEAPONS,
CHEAT_INVENTORY,
CHEAT_KEYS,
CHEAT_DEBUG,
CHEAT_RAJOSEPH, // 25
CHEAT_RAMRBILL,
CHEAT_RATONY,
CHEAT_RAGARY,
CHEAT_RARHETT,
CHEAT_RAAARON, // 30
CHEAT_RANOCHEAT,
CHEAT_RAWOLESLAGLE,
CHEAT_RAMIKAEL,
CHEAT_RAGREG,
CHEAT_RANOAH, // 35
CHEAT_RAARIJIT,
CHEAT_RADONUT,
CHEAT_RAKFC,
CHEAT_RAVAN,
NUMCHEATS,
};
extern char CheatStrings[NUMCHEATS][MAXCHEATLEN];
// KEEPINSYNC game.c: uint8_t CheatFunctionIDs[]
// KEEPINSYNC menus.c: MenuEntry_t ME_CheatCodes[]
enum CheatCodeFunctions
{
CHEATFUNC_CASHMAN,
CHEATFUNC_GOD,
CHEATFUNC_GIVEEVERYTHING,
CHEATFUNC_GIVEWEAPONS,
CHEATFUNC_GIVEALLITEMS,
CHEATFUNC_GIVEINVENTORY,
CHEATFUNC_GIVEKEYS,
CHEATFUNC_HYPER,
CHEATFUNC_VIEW,
CHEATFUNC_SHOWMAP,
CHEATFUNC_UNLOCK,
CHEATFUNC_CLIP,
CHEATFUNC_WARP,
CHEATFUNC_SKILL,
CHEATFUNC_MONSTERS,
CHEATFUNC_FRAMERATE,
CHEATFUNC_QUOTEBETA,
CHEATFUNC_QUOTETODD,
CHEATFUNC_QUOTEALLEN,
CHEATFUNC_COORDS,
CHEATFUNC_DEBUG,
NUMCHEATFUNCS,
};
END_DUKE_NS

View file

@ -0,0 +1,97 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "duke3d.h"
#include "demo.h"
#include "screens.h"
#include "baselayer.h"
#include "cmdline.h"
#include "m_argv.h"
BEGIN_DUKE_NS
int32_t g_fakeMultiMode = 0;
static void G_AddDemo(const char* param)
{
Bstrncpy(tempbuf, param, sizeof(tempbuf));
char * colon = (char *) Bstrchr(tempbuf, ':');
int32_t framespertic=-1, numrepeats=1;
if (colon && colon != tempbuf)
{
// -d<filename>:<num>[,<num>]
// profiling options
*(colon++) = 0;
sscanf(colon, "%d,%d", &framespertic, &numrepeats);
}
Demo_SetFirst(tempbuf);
if (framespertic < 0)
{
Printf("Play demo %s.\n", g_firstDemoFile);
}
else
{
framespertic = clamp(framespertic, 0, 8)+1;
// TODO: repeat count and gathering statistics.
Printf("Profile demo %s, %d frames/gametic, repeated 1x.\n", g_firstDemoFile,
framespertic-1);
Demo_PlayFirst(framespertic, 1);
g_noLogo = 1;
}
}
void G_CheckCommandLine()
{
if (Args->CheckParm("-condebug") || Args->CheckParm("-z")) g_scriptDebug = 1;
if (Args->CheckParm("-altai"))
{
ud.playerai = 1;
Printf("Other player AI.\n");
}
auto val = Args->CheckValue("-skill");
if (val)
{
ud.m_player_skill = ud.player_skill = clamp((int)strtol(val, nullptr, 0), 0, 5);
if (ud.m_player_skill == 4) ud.m_respawn_monsters = ud.respawn_monsters = 1;
}
val = Args->CheckValue("-respawn");
if (val)
{
if (*val == '1') ud.m_respawn_monsters = 1;
else if (*val == '2') ud.m_respawn_items = 1;
else if (*val == '3') ud.m_respawn_inventory = 1;
else
{
ud.m_respawn_monsters = 1;
ud.m_respawn_items = 1;
ud.m_respawn_inventory = 1;
}
Printf("Respawn on.\n");
}
}
END_DUKE_NS

38
source/duke/src/cmdline.h Normal file
View file

@ -0,0 +1,38 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef cmdline_h__
#define cmdline_h__
#include "compat.h"
BEGIN_DUKE_NS
extern void G_CheckCommandLine();
extern void G_ShowParameterHelp(void);
extern void G_ShowDebugHelp(void);
extern int32_t g_fakeMultiMode;
END_DUKE_NS
#endif // cmdline_h__

195
source/duke/src/common.cpp Normal file
View file

@ -0,0 +1,195 @@
//
// Common non-engine code/data for EDuke32 and Mapster32
//
#include "ns.h" // Must come before everything else!
#include "compat.h"
#include "build.h"
#include "baselayer.h"
#include "palette.h"
#include "cmdlib.h"
#include "gamecvars.h"
#include "rts.h"
#include "gamecontrol.h"
#include "palettecontainer.h"
#include "common.h"
#include "common_game.h"
BEGIN_DUKE_NS
//////////
// Set up new-style multi-psky handling.
void G_InitMultiPsky(int CLOUDYOCEAN__DYN, int MOONSKY1__DYN, int BIGORBIT1__DYN, int LA__DYN)
{
// When adding other multi-skies, take care that the tileofs[] values are
// <= PSKYOFF_MAX. (It can be increased up to MAXPSKYTILES, but should be
// set as tight as possible.)
// The default sky properties (all others are implicitly zero):
psky_t *sky = tileSetupSky(DEFAULTPSKY);
sky->lognumtiles = 3;
sky->horizfrac = 32768;
// CLOUDYOCEAN
// Aligns with the drawn scene horizon because it has one itself.
sky = tileSetupSky(CLOUDYOCEAN__DYN);
sky->lognumtiles = 3;
sky->horizfrac = 65536;
// MOONSKY1
// earth mountain mountain sun
sky = tileSetupSky(MOONSKY1__DYN);
sky->lognumtiles = 3;
sky->horizfrac = 32768;
sky->tileofs[6] = 1;
sky->tileofs[1] = 2;
sky->tileofs[4] = 2;
sky->tileofs[2] = 3;
// BIGORBIT1 // orbit
// earth1 2 3 moon/sun
sky = tileSetupSky(BIGORBIT1__DYN);
sky->lognumtiles = 3;
sky->horizfrac = 32768;
sky->tileofs[5] = 1;
sky->tileofs[6] = 2;
sky->tileofs[7] = 3;
sky->tileofs[2] = 4;
// LA // la city
// earth1 2 3 moon/sun
sky = tileSetupSky(LA__DYN);
sky->lognumtiles = 3;
sky->horizfrac = 16384 + 1024;
sky->tileofs[0] = 1;
sky->tileofs[1] = 2;
sky->tileofs[2] = 1;
sky->tileofs[3] = 3;
sky->tileofs[4] = 4;
sky->tileofs[5] = 0;
sky->tileofs[6] = 2;
sky->tileofs[7] = 3;
#if 0
// This assertion should hold. See note above.
for (bssize_t i=0; i<pskynummultis; ++i)
for (bssize_t j=0; j<(1<<multipsky[i].lognumtiles); ++j)
Bassert(multipsky[i].tileofs[j] <= PSKYOFF_MAX);
#endif
}
void G_SetupGlobalPsky(void)
{
int skyIdx = 0;
// NOTE: Loop must be running backwards for the same behavior as the game
// (greatest sector index with matching parallaxed sky takes precedence).
for (bssize_t i = numsectors - 1; i >= 0; i--)
{
if (sector[i].ceilingstat & 1)
{
skyIdx = getpskyidx(sector[i].ceilingpicnum);
if (skyIdx > 0)
break;
}
}
g_pskyidx = skyIdx;
}
//////////
void G_LoadLookups(void)
{
int32_t j;
auto fr = fileSystem.OpenFileReader("lookup.dat");
if (!fr.isOpen())
return;
j = lookups.loadTable(fr);
if (j < 0)
{
if (j == -1)
Printf("ERROR loading \"lookup.dat\": failed reading enough data.\n");
return;
}
uint8_t paldata[768];
for (j=1; j<=5; j++)
{
// Account for TITLE and REALMS swap between basepal number and on-disk order.
int32_t basepalnum = (j == 3 || j == 4) ? 4+3-j : j;
if (fr.Read(paldata, 768) != 768)
return;
for (bssize_t k = 0; k < 768; k++)
paldata[k] <<= 2;
paletteSetColorTable(basepalnum, paldata, basepalnum == DREALMSPAL || basepalnum == ENDINGPAL, basepalnum < DREALMSPAL);
}
for (int i = 0; i < 256; i++)
{
// swap red and blue channels.
paldata[i * 3] = GPalette.BaseColors[i].b;
paldata[i * 3+1] = GPalette.BaseColors[i].g;
paldata[i * 3+2] = GPalette.BaseColors[i].r;
}
paletteSetColorTable(DRUGPAL, paldata, false, false); // todo: implement this as a shader effect (swap R and B in postprocessing.)
if (RR)
{
uint8_t table[256];
for (bssize_t i = 0; i < 256; i++)
table[i] = i;
for (bssize_t i = 0; i < 32; i++)
table[i] = i+32;
lookups.makeTable(7, table, 0, 0, 0, 0);
for (bssize_t i = 0; i < 256; i++)
table[i] = i;
lookups.makeTable(30, table, 0, 0, 0, 0);
lookups.makeTable(31, table, 0, 0, 0, 0);
lookups.makeTable(32, table, 0, 0, 0, 0);
lookups.makeTable(33, table, 0, 0, 0, 0);
if (RRRA)
lookups.makeTable(105, table, 0, 0, 0, 0);
j = 63;
for (bssize_t i = 64; i < 80; i++)
{
j--;
table[i] = j;
table[i+16] = i-24;
}
table[80] = 80;
table[81] = 81;
for (bssize_t i = 0; i < 32; i++)
table[i] = i+32;
lookups.makeTable(34, table, 0, 0, 0, 0);
for (bssize_t i = 0; i < 256; i++)
table[i] = i;
for (bssize_t i = 0; i < 16; i++)
table[i] = i+129;
for (bssize_t i = 16; i < 32; i++)
table[i] = i+192;
lookups.makeTable(35, table, 0, 0, 0, 0);
if (RRRA)
{
lookups.makeTable(50, NULL, 12 * 4, 12 * 4, 12 * 4, 0);
lookups.makeTable(51, NULL, 12 * 4, 12 * 4, 12 * 4, 0);
lookups.makeTable(54, lookups.getTable(8), 32 * 4, 32 * 4, 32 * 4, 0);
}
}
}
END_DUKE_NS

View file

@ -0,0 +1,67 @@
//
// Definitions of common game-only data structures/functions
// (and declarations of data appearing in both)
// for EDuke32 and Mapster32
//
#ifndef EDUKE32_COMMON_GAME_H_
#define EDUKE32_COMMON_GAME_H_
#include "gamecontrol.h"
BEGIN_DUKE_NS
#define DUKE (g_gameType & GAMEFLAG_DUKE)
#define RR (g_gameType & GAMEFLAG_RRALL)
#define RRRA (g_gameType & GAMEFLAG_RRRA)
#define NAM (g_gameType & GAMEFLAG_NAM)
#define NAPALM (g_gameType & GAMEFLAG_NAPALM)
#define WW2GI (g_gameType & GAMEFLAG_WW2GI)
#define NAM_WW2GI (g_gameType & (GAMEFLAG_NAM|GAMEFLAG_WW2GI))
#define SHAREWARE (g_gameType & GAMEFLAG_SHAREWARE)
#define DEER (g_gameType & GAMEFLAG_DEER)
//#define DUKEBETA ((g_gameType & GAMEFLAG_DUKEBETA) == GAMEFLAG_DUKEBETA)
//#define IONMAIDEN (g_gameType & GAMEFLAG_IONMAIDEN)
enum Games_t {
GAME_DUKE = 0,
GAME_RR,
GAME_RRRA,
GAME_NAM,
GAME_NAPALM,
//GAME_WW2GI,
GAMECOUNT
};
typedef enum basepal_ {
BASEPAL = 0,
WATERPAL,
SLIMEPAL,
DREALMSPAL,
TITLEPAL,
ENDINGPAL, // 5
ANIMPAL,
DRUGPAL,
BASEPALCOUNT
} basepal_t;
#include "v_text.h"
extern int loaddefinitions_game(const char *fn, int32_t preload);
//////////
extern void G_InitMultiPsky(int CLOUDYOCEAN__DYN, int MOONSKY1__DYN, int BIGORBIT1__DYN, int LA__DYN);
extern void G_SetupGlobalPsky(void);
//////////
extern void G_LoadLookups(void);
//////////
END_DUKE_NS
#endif

View file

@ -0,0 +1,58 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "duke3d.h"
#include "osdcmds.h"
#include "baselayer.h"
#include "cmdline.h"
// we load this in to get default button and key assignments
// as well as setting up function mappings
BEGIN_DUKE_NS
int32_t CONFIG_ReadSetup(void)
{
g_player[0].ps->aim_mode = 1;
ud.config.ShowOpponentWeapons = 0;
ud.automsg = 0;
ud.camerasprite = -1;
ud.camera_time = 0;//4;
ud.screen_tilting = 1;
ud.statusbarflags = STATUSBAR_NOSHRINK;
playerteam = 0;
ud.angleinterpolation = 0;
ud.display_bonus_screen = 1;
ud.show_level_text = 1;
ud.screenfade = 1;
ud.menubackground = 1;
ud.slidebar_paldisabled = 1;
ud.shadow_pal = 4;
return 0;
}
END_DUKE_NS

37
source/duke/src/config.h Normal file
View file

@ -0,0 +1,37 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef config_public_h_
#define config_public_h_
#include "gamecontrol.h"
BEGIN_DUKE_NS
#define SETUPNAMEPARM "SETUPFILE"
int32_t CONFIG_ReadSetup( void );
void CONFIG_GetSetupFilename( void );
END_DUKE_NS
#endif

795
source/duke/src/d_menu.cpp Normal file
View file

@ -0,0 +1,795 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
Copyright (C) 2019 Christoph Oelckers
This is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "cheats.h"
#include "compat.h"
#include "demo.h"
#include "duke3d.h"
#include "menus.h"
#include "osdcmds.h"
#include "savegame.h"
#include "game.h"
#include "superfasthash.h"
#include "gamecvars.h"
#include "gamecontrol.h"
#include "c_bind.h"
#include "menu/menu.h"
#include "gstrings.h"
#include "version.h"
#include "namesdyn.h"
#include "../../glbackend/glbackend.h"
BEGIN_DUKE_NS
#define MENU_MARGIN_REGULAR 40
#define MENU_MARGIN_WIDE 32
#define MENU_MARGIN_CENTER 160
#define MENU_HEIGHT_CENTER 100
enum MenuTextFlags_t
{
MT_Selected = 1 << 0,
MT_Disabled = 1 << 1,
MT_XCenter = 1 << 2,
MT_XRight = 1 << 3,
MT_YCenter = 1 << 4,
MT_Literal = 1 << 5,
MT_RightSide = 1 << 6,
};
// common font types
// tilenums are set after namesdyn runs.
// These are also modifiable by scripts.
// emptychar x,y between x,y zoom cursorLeft cursorCenter cursorScale textflags
// tilenum shade_deselected shade_disabled pal pal_selected pal_deselected pal_disabled
MenuFont_t MF_Redfont = { { 5<<16, 15<<16 }, { 0, 0 }, 65536, 20<<16, 110<<16, 65536, 65536, 65536, TEXT_BIGALPHANUM | TEXT_UPPERCASE,
-1, 10, 0, 0, 0, 0, 1,
0, 0, 1 };
MenuFont_t MF_Bluefont = { { 5<<16, 7<<16 }, { 0, 0 }, 65536, 10<<16, 110<<16, 32768, 65536, 65536, 0,
-1, 10, 0, 0, 10, 10, 16,
0, 0, 16 };
MenuFont_t MF_Minifont = { { 4<<16, 5<<16 }, { 1<<16, 1<<16 }, 65536, 10<<16, 110<<16, 32768, 65536, 65536, 0,
-1, 10, 0, 0, 2, 2, 0,
0, 0, 16 };
/*
This function prepares data after ART and CON have been processed.
It also initializes some data in loops rather than statically at compile time.
*/
void Menu_Init(void)
{
// prepare menu fonts
// check if tilenum is -1 in case it was set in EVENT_SETDEFAULTS
if ((unsigned)MF_Redfont.tilenum >= MAXTILES) MF_Redfont.tilenum = BIGALPHANUM;
if ((unsigned)MF_Bluefont.tilenum >= MAXTILES) MF_Bluefont.tilenum = STARTALPHANUM;
if ((unsigned)MF_Minifont.tilenum >= MAXTILES) MF_Minifont.tilenum = MINIFONT;
MF_Redfont.emptychar.y = tilesiz[MF_Redfont.tilenum].y << 16;
MF_Bluefont.emptychar.y = tilesiz[MF_Bluefont.tilenum].y << 16;
MF_Minifont.emptychar.y = tilesiz[MF_Minifont.tilenum].y << 16;
if (!minitext_lowercase)
MF_Minifont.textflags |= TEXT_UPPERCASE;
if (RR)
{
MF_Redfont.zoom = 32768;
MF_Redfont.emptychar.x <<= 1;
MF_Redfont.cursorScale = 13107;
MF_Redfont.cursorScale2 = 6553;
//MF_Redfont.emptychar.y <<= 1;
MF_Bluefont.zoom = 32768;
MF_Bluefont.emptychar.x <<= 1;
MF_Bluefont.cursorScale = 6553;
MF_Bluefont.cursorScale2 = 6553;
//MF_Bluefont.emptychar.y <<= 1;
MF_Minifont.zoom = 32768;
MF_Minifont.emptychar.x <<= 1;
MF_Minifont.cursorScale = 6553;
MF_Minifont.cursorScale2 = 6553;
//MF_Minifont.emptychar.y <<= 1;
}
}
static void Menu_DrawBackground(const DVector2 &origin)
{
rotatesprite_fs(int(origin.X * 65536) + (MENU_MARGIN_CENTER << 16), int(origin.Y * 65536) + (100 << 16), 65536L, 0, MENUSCREEN, 16, 0, 10 + 64);
}
static void Menu_DrawTopBar(const DVector2 &origin)
{
rotatesprite_fs(int(origin.X*65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y*65536) + (19<<16), MF_Redfont.cursorScale3, 0,MENUBAR,16,0,10);
}
static void Menu_DrawTopBarCaption(const char* caption, const DVector2& origin)
{
static char t[64];
size_t const srclen = strlen(caption);
size_t const dstlen = min(srclen, ARRAY_SIZE(t) - 1);
memcpy(t, caption, dstlen);
t[dstlen] = '\0';
char* p = &t[dstlen - 1];
if (*p == ':')
*p = '\0';
captionmenutext(int(origin.X * 65536) + (MENU_MARGIN_CENTER << 16), int(origin.Y * 65536) + (24 << 16) + (15 << 15), t);
}
static void Menu_GetFmt(const MenuFont_t* font, uint8_t const status, int32_t* s)
{
if (status & MT_Selected)
*s = sintable[((int32_t)totalclock << 5) & 2047] >> 12;
else
*s = font->shade_deselected;
// sum shade values
if (status & MT_Disabled)
*s += font->shade_disabled;
}
static vec2_t Menu_Text(int32_t x, int32_t y, const MenuFont_t* font, const char* t, uint8_t status, int32_t ydim_upper, int32_t ydim_lower)
{
int32_t s, p, ybetween = font->between.y;
int32_t f = font->textflags;
if (RR) f |= TEXT_RRMENUTEXTHACK;
if (status & MT_XCenter)
f |= TEXT_XCENTER;
if (status & MT_XRight)
f |= TEXT_XRIGHT;
if (status & MT_YCenter)
{
f |= TEXT_YCENTER | TEXT_YOFFSETZERO;
ybetween = font->emptychar.y; // <^ the battle against 'Q'
}
if (status & MT_Literal)
f |= TEXT_LITERALESCAPE;
int32_t z = font->zoom;
if (status & MT_Disabled)
p = (status & MT_RightSide) ? font->pal_disabled_right : font->pal_disabled;
else if (status & MT_Selected)
p = (status & MT_RightSide) ? font->pal_selected_right : font->pal_selected;
else
p = (status & MT_RightSide) ? font->pal_deselected_right : font->pal_deselected;
Menu_GetFmt(font, status, &s);
return G_ScreenText(font->tilenum, x, y, z, 0, 0, t, s, p, 2 | 8 | 16 | ROTATESPRITE_FULL16, 0, font->emptychar.x, font->emptychar.y, font->between.x, ybetween, f, 0, ydim_upper, xdim - 1, ydim_lower);
}
static int32_t Menu_CursorShade(void)
{
return 4 - (sintable[((int32_t)totalclock << 4) & 2047] >> 11);
}
static void Menu_DrawCursorCommon(int32_t x, int32_t y, int32_t z, int32_t picnum, int32_t ydim_upper = 0, int32_t ydim_lower = ydim - 1)
{
rotatesprite_(x, y, z, 0, picnum, Menu_CursorShade(), 0, 2 | 8, 0, 0, 0, ydim_upper, xdim - 1, ydim_lower);
}
static void Menu_DrawCursorLeft(int32_t x, int32_t y, int32_t z)
{
const int frames = RR ? 16 : 7;
Menu_DrawCursorCommon(x, y, z, SPINNINGNUKEICON+(((int32_t) totalclock>>3)%frames));
}
static void Menu_DrawCursorRight(int32_t x, int32_t y, int32_t z)
{
const int frames = RR ? 16 : 7;
Menu_DrawCursorCommon(x, y, z, SPINNINGNUKEICON+frames-1-((frames-1+((int32_t) totalclock>>3))%frames));
}
static int Menu_GetFontHeight(int fontnum)
{
auto& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont;
return font.get_yline();
}
int dword_A99A0, dword_A99A4, dword_A99A8, dword_A99AC;
short word_A99B0, word_A99B2;
int dword_A99B4, dword_A99B8, dword_A99BC, dword_A99C0, dword_A99C4, dword_A99C8;
void Menu_DHLeaonardHeadReset(void)
{
dword_A99A0 = 0;
dword_A99A4 = 0;
dword_A99A8 = 0;
dword_A99AC = 0;
word_A99B2 = 0;
dword_A99B4 = 0;
word_A99B0 = 0;
}
void Menu_DHLeaonardHeadDisplay(vec2_t pos)
{
if (sub_51B68() && !dword_A99C0)
{
dword_A99C0 = (int)totalclock;
}
if (dword_A99C0 && (int)totalclock - dword_A99C0 > 40)
{
dword_A99C0 = 0;
dword_A99C4 = 1;
}
switch (dword_A99A0)
{
case 0:
if ((int)totalclock - dword_A99B8 >= 240 && dword_A99C4 && (rrdh_random() & 63) < 32)
{
dword_A99A0 = 1;
dword_A99A4 = 160 - ((rrdh_random() & 255) - 128);
word_A99B0 = ((rrdh_random() & 127) + 1984) & 2047;
dword_A99AC = (rrdh_random() & 4095) - 4090;
word_A99B2 = SPINNINGNUKEICON + (rrdh_random() & 15);
}
break;
case 1:
if (dword_A99A8 < 54)
{
if ((int)totalclock - dword_A99B4 > 2)
{
dword_A99B4 = (int)totalclock;
dword_A99A8 += 2;
}
}
else
{
dword_A99A0 = 2;
dword_A99BC = (int)totalclock;
}
pos.x += dword_A99A4 << 16;
pos.y += (240 - dword_A99A8) << 16;
rotatesprite(pos.x, pos.y, 32768 - dword_A99AC, word_A99B0, word_A99B2, 0, 0, 10, 0, 0, xdim - 1, ydim - 1);
break;
case 2:
if (dword_A99C4 == 1)
{
if ((rrdh_random() & 63) > 32)
word_A99B2--;
else
word_A99B2++;
}
else
{
if ((rrdh_random() & 127) == 48)
{
if ((int)totalclock - dword_A99BC > 240)
dword_A99A0 = 3;
}
}
if (word_A99B2 < SPINNINGNUKEICON)
word_A99B2 = SPINNINGNUKEICON + 15;
if (word_A99B2 > SPINNINGNUKEICON + 15)
word_A99B2 = SPINNINGNUKEICON;
pos.x += dword_A99A4 << 16;
pos.y += (240 - dword_A99A8) << 16;
rotatesprite(pos.x, pos.y, 32768 - dword_A99AC, word_A99B0, word_A99B2, 0, 0, 10, 0, 0, xdim - 1, ydim - 1);
if ((int)totalclock - dword_A99BC > 960)
dword_A99A0 = 3;
break;
case 3:
if (dword_A99A8 > 0)
{
if ((int)totalclock - dword_A99B4 > 2)
{
dword_A99B4 = (int)totalclock;
dword_A99A8 -= 2;
}
pos.x += dword_A99A4 << 16;
pos.y += (240 - dword_A99A8) << 16;
rotatesprite(pos.x, pos.y, 32768 - dword_A99AC, word_A99B0, word_A99B2, 0, 0, 10, 0, 0, xdim - 1, ydim - 1);
}
else
{
dword_A99B8 = (int)totalclock;
dword_A99A0 = 0;
}
break;
}
dword_A99C4 = 0;
}
//----------------------------------------------------------------------------
//
// Implements the native looking menu used for the main menu
// and the episode/skill selection screens, i.e. the parts
// that need to look authentic
//
//----------------------------------------------------------------------------
class Duke3dListMenu : public DListMenu
{
using Super = DListMenu;
protected:
void Ticker() override
{
// Lay out the menu.
int32_t y_upper = mDesc->mYpos;
int32_t y_lower = y_upper + mDesc->mYbotton;
int32_t y = 0;
int32_t calculatedentryspacing = 0;
int32_t const height = Menu_GetFontHeight(mDesc->mNativeFontNum) >> 16;
int32_t totalheight = 0, numvalidentries = mDesc->mItems.Size();
for (unsigned e = 0; e < mDesc->mItems.Size(); ++e)
{
auto entry = mDesc->mItems[e];
entry->mHidden = false;
entry->SetHeight(height);
totalheight += height;
}
if (mDesc->mSpacing <= 0) calculatedentryspacing = std::max(0, (y_lower - y_upper - totalheight) / (numvalidentries > 1 ? numvalidentries - 1 : 1));
if (calculatedentryspacing <= 0) calculatedentryspacing = mDesc->mSpacing;
// totalHeight calculating pass
int totalHeight;
for (unsigned e = 0; e < mDesc->mItems.Size(); ++e)
{
auto entry = mDesc->mItems[e];
if (!entry->mHidden)
{
entry->SetY(y_upper + y);
y += height;
totalHeight = y;
y += calculatedentryspacing;
}
}
}
};
class Duke3dMainMenu : public Duke3dListMenu
{
virtual void Init(DMenu* parent = NULL, FListMenuDescriptor* desc = NULL) override
{
Duke3dListMenu::Init(parent, desc);
Menu_DHLeaonardHeadReset();
}
void PreDraw() override
{
Duke3dListMenu::PreDraw();
if (DEER)
{
vec2_t forigin = { int(origin.X * 65536), int(origin.Y * 65536) };
Menu_DHLeaonardHeadDisplay(forigin);
rotatesprite_fs(forigin.x + (MENU_MARGIN_CENTER << 16), forigin.y + ((32) << 16), 20480L, 0, DUKENUKEM, 0, 0, 10);
}
else if (RRRA)
{
rotatesprite_fs(int(origin.X * 65536) + ((MENU_MARGIN_CENTER - 5) << 16), int(origin.Y * 65536) + ((57) << 16), 16592L, 0, THREEDEE, 0, 0, 10);
}
else if (RR)
{
rotatesprite_fs(int(origin.X * 65536) + ((MENU_MARGIN_CENTER + 5) << 16), int(origin.Y * 65536) + ((24) << 16), 23592L, 0, INGAMEDUKETHREEDEE, 0, 0, 10);
}
else
{
rotatesprite_fs(int(origin.X * 65536) + (MENU_MARGIN_CENTER<<16), int(origin.Y * 65536) + ((28)<<16), 65536L,0,INGAMEDUKETHREEDEE,0,0,10);
if (PLUTOPAK) // JBF 20030804
rotatesprite_fs(int(origin.X * 65536) + ((MENU_MARGIN_CENTER+100)<<16), int(origin.Y * 65536) + (36<<16), 65536L,0,PLUTOPAKSPRITE+2,(sintable[((int32_t) totalclock<<4)&2047]>>11),0,2+8);
}
}
};
class Duke3dHuntMenu : public Duke3dListMenu
{
void PreDraw() override
{
Duke3dListMenu::PreDraw();
vec2_t forigin = { int(origin.X * 65536), int(origin.Y * 65536) };
int t1, t2;
short ang;
switch (mDesc->mSelectedItem)
{
case 0:
default:
t1 = 7098;
t2 = 7041;
ang = 16;
break;
case 1:
t1 = 7099;
t2 = 7042;
ang = 2032;
break;
case 2:
t1 = 7100;
t2 = 7043;
ang = 16;
break;
case 3:
t1 = 7101;
t2 = 7044;
ang = 2032;
break;
}
rotatesprite_fs(forigin.x + (240 << 16), forigin.y + (56 << 16), 24576L, ang, t1, 2, 0, 64 + 10);
rotatesprite_fs(forigin.x + (240 << 16), forigin.y + (42 << 16), 24576L, ang, 7104, 2, 0, 10);
rotatesprite_fs(forigin.x + (20 << 16), forigin.y + (10 << 16), 32768L, 0, t2, -64, 0, 128 + 16 + 10);
}
};
class Duke3dTargetMenu : public Duke3dListMenu
{
void PreDraw() override
{
Duke3dListMenu::PreDraw();
vec2_t forigin = { int(origin.X * 65536), int(origin.Y * 65536) };
int t1, t2;
short ang;
switch (mDesc->mSelectedItem)
{
case 0:
default:
t1 = 7102;
t2 = 7045;
ang = 16;
break;
case 1:
t1 = 7103;
t2 = 7046;
ang = 2032;
break;
break;
}
rotatesprite_fs(forigin.x + (240 << 16), forigin.y + (56 << 16), 24576L, ang, t1, 2, 0, 64 + 10);
rotatesprite_fs(forigin.x + (240 << 16), forigin.y + (42 << 16), 24576L, ang, 7104, 2, 0, 10);
rotatesprite_fs(forigin.x + (20 << 16), forigin.y + (10 << 16), 32768L, 0, t2, -64, 0, 128 + 16 + 10);
}
};
class Duke3dWeaponMenu : public Duke3dListMenu
{
void PreDraw() override
{
Duke3dListMenu::PreDraw();
vec2_t forigin = { int(origin.X * 65536), int(origin.Y * 65536) };
int t1, t2;
switch (mDesc->mSelectedItem)
{
case 0:
default:
t1 = 7124;
t2 = 7066;
break;
case 1:
t1 = 7125;
t2 = 7067;
break;
case 2:
t1 = 7126;
t2 = 7068;
break;
case 3:
t1 = 7127;
t2 = 7069;
break;
case 4:
t1 = 7128;
t2 = 7070;
break;
}
rotatesprite_fs(forigin.x + (240 << 16), forigin.y + (56 << 16), 32768L, 0, t1, 2, 0, 64 + 10);
rotatesprite_fs(forigin.x + (8 << 16), forigin.y + (4 << 16), 32768L, 0, t2, -64, 0, 128 + 16 + 10);
}
};
class Duke3dTrophiesMenu : public Duke3dListMenu
{
void PreDraw() override
{
Duke3dListMenu::PreDraw();
vec2_t forigin = { int(origin.X * 65536), int(origin.Y * 65536) };
if (g_player[myconnectindex].ps->gm & MODE_GAME)
{
if (ud.level_number < 4)
{
rotatesprite_fs(forigin.x + (160 << 16), forigin.y + (100 << 16), 65536, 0, 1730, 0, 0, 10);
sub_5469C(forigin, 0);
}
else
sub_5469C(forigin, 2);
}
else
{
rotatesprite_fs(forigin.x + (160 << 16), forigin.y + (100 << 16), 65536, 0, 1730, 0, 0, 10);
sub_5469C(forigin, 1);
}
}
};
//----------------------------------------------------------------------------
//
// Menu related game interface functions
//
//----------------------------------------------------------------------------
void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags)
{
int ydim_upper = 0;
int ydim_lower = ydim - 1;
//int32_t const indent = 0; // not set for any relevant menu
int x = int(xpos * 65536);
uint8_t status = 0;
if (state == NIT_SelectedState)
status |= MT_Selected;
if (state == NIT_InactiveState)
status |= MT_Disabled;
if (flags & LMF_Centered)
status |= MT_XCenter;
bool const dodraw = true;
MenuFont_t& font = fontnum == NIT_BigFont ? MF_Redfont : fontnum == NIT_SmallFont ? MF_Bluefont : MF_Minifont;
int32_t const height = font.get_yline();
status |= MT_YCenter;
int32_t const y_internal = int(ypos * 65536) + ((height >> 17) << 16);// -menu->scrollPos;
vec2_t textsize;
if (dodraw)
textsize = Menu_Text(x, y_internal, &font, text, status, ydim_upper, ydim_lower);
if (dodraw && (status & MT_Selected) && state != 1)
{
if (status & MT_XCenter)
{
Menu_DrawCursorLeft(x + font.cursorCenterPosition, y_internal, font.cursorScale);
Menu_DrawCursorRight(x - font.cursorCenterPosition, y_internal, font.cursorScale);
}
else
Menu_DrawCursorLeft(x /*+ indent*/ - font.cursorLeftPosition, y_internal, font.cursorScale);
}
}
void GameInterface::MenuOpened()
{
S_PauseSound(true, false);
if ((!g_netServer && ud.multimode < 2))
{
ready2send = 0;
totalclock = ototalclock;
screenpeek = myconnectindex;
}
auto& gm = g_player[myconnectindex].ps->gm;
if (gm & MODE_GAME)
{
gm |= MODE_MENU;
}
}
void GameInterface::MenuSound(EMenuSounds snd)
{
switch (snd)
{
case ActivateSound:
S_MenuSound();
break;
case CursorSound:
S_PlaySound(RR ? 335 : KICK_HIT, CHAN_AUTO, CHANF_UI);
break;
case AdvanceSound:
S_PlaySound(RR ? 341 : PISTOL_BODYHIT, CHAN_AUTO, CHANF_UI);
break;
case CloseSound:
S_PlaySound(EXITMENUSOUND, CHAN_AUTO, CHANF_UI);
break;
default:
return;
}
}
void GameInterface::MenuClosed()
{
auto& gm = g_player[myconnectindex].ps->gm;
if (gm & MODE_GAME)
{
if (gm & MODE_MENU)
inputState.ClearAllInput();
// The following lines are here so that you cannot close the menu when no game is running.
gm &= ~MODE_MENU;
if ((!g_netServer && ud.multimode < 2) && ud.recstat != 2)
{
ready2send = 1;
totalclock = ototalclock;
CAMERACLOCK = (int32_t)totalclock;
CAMERADIST = 65536;
// Reset next-viewscreen-redraw counter.
// XXX: are there any other cases like that in need of handling?
if (g_curViewscreen >= 0)
actor[g_curViewscreen].t_data[0] = (int32_t)totalclock;
}
G_UpdateScreenArea();
S_ResumeSound(false);
}
}
bool GameInterface::CanSave()
{
if (ud.recstat == 2 || DEER) return false;
auto &myplayer = *g_player[myconnectindex].ps;
if (sprite[myplayer.i].extra <= 0)
{
//P_DoQuote(QUOTE_SAVE_DEAD, &myplayer); // handled by the menu.
return false;
}
return true;
}
void GameInterface::StartGame(FNewGameStartup& gs)
{
int32_t skillsound = PISTOL_BODYHIT;
soundEngine->StopAllChannels();
if (!DEER)
{
switch (gs.Skill)
{
case 0:
skillsound = RR ? 427 : JIBBED_ACTOR6;
break;
case 1:
skillsound = RR ? 428 : BONUS_SPEECH1;
break;
case 2:
skillsound = RR ? 196 : DUKE_GETWEAPON2;
break;
case 3:
skillsound = RR ? 195 : JIBBED_ACTOR5;
break;
case 4:
skillsound = RR ? 197 : JIBBED_ACTOR5; // Does not exist in DN3D.
break;
}
ud.m_player_skill = gs.Skill + 1;
if (menu_sounds && skillsound >= 0 && SoundEnabled())
{
S_PlaySound(skillsound, CHAN_AUTO, CHANF_UI);
while (S_CheckSoundPlaying(skillsound))
{
S_Update();
G_HandleAsync();
}
}
ud.m_respawn_monsters = (gs.Skill == 3);
ud.m_volume_number = gs.Episode;
m_level_number = gs.Level;
}
else
{
ud.m_player_skill = 1;
ud.m_respawn_monsters = 0;
ud.m_volume_number = 0;
m_level_number = gs.Episode;
g_player[myconnectindex].ps->dhat61f = gs.Skill;
}
ud.m_monsters_off = ud.monsters_off = 0;
ud.m_respawn_items = 0;
ud.m_respawn_inventory = 0;
ud.multimode = 1;
G_NewGame_EnterLevel();
}
FSavegameInfo GameInterface::GetSaveSig()
{
return { SAVESIG_RR, MINSAVEVER_RR, SAVEVER_RR };
}
void GameInterface::DrawMenuCaption(const DVector2& origin, const char* text)
{
Menu_DrawTopBar(origin);
Menu_DrawTopBarCaption(text, origin);
}
void GameInterface::DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position, bool bg)
{
if (bg) Menu_DrawBackground(origin);
else
{
// Only used for the confirmation screen.
int lines = 1;
for (int i = 0; text[i]; i++) if (text[i] == '\n') lines++;
int height = lines * Menu_GetFontHeight(NIT_SmallFont);
position -= height >> 17;
if (!RR) Menu_DrawCursorLeft(160 << 16, 130 << 16, 65536);
}
G_ScreenText(MF_Bluefont.tilenum, int((origin.X + 160) * 65536), int((origin.Y + position) * 65536), MF_Bluefont.zoom, 0, 0, text, 0, MF_Bluefont.pal,
2 | 8 | 16 | ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y,
MF_Bluefont.textflags | TEXT_XCENTER, 0, 0, xdim - 1, ydim - 1);
}
void GameInterface::DrawPlayerSprite(const DVector2& origin, bool onteam)
{
if (RR)
rotatesprite_fs(int(origin.X * 65536) + (260<<16), int(origin.Y * 65536) + ((24+(tilesiz[APLAYER].y>>2))<<16), 24576L,0,3845+36-((((8-((int32_t) totalclock>>4)))&7)*5),0,onteam ? G_GetTeamPalette(playerteam) : G_CheckPlayerColor(playercolor),10);
else
rotatesprite_fs(int(origin.X * 65536) + (260<<16), int(origin.Y * 65536) + ((24+(tilesiz[APLAYER].y>>1))<<16), 49152L,0,1441-((((4-((int32_t) totalclock>>4)))&3)*5),0,onteam ? G_GetTeamPalette(playerteam) : G_CheckPlayerColor(playercolor),10);
}
void GameInterface::QuitToTitle()
{
g_player[myconnectindex].ps->gm = MODE_DEMO;
if (ud.recstat == 1)
G_CloseDemoWrite();
artClearMapArt();
}
END_DUKE_NS
//----------------------------------------------------------------------------
//
// Class registration
//
//----------------------------------------------------------------------------
static TMenuClassDescriptor<Duke3d::Duke3dMainMenu> _mm("Duke3d.MainMenu");
static TMenuClassDescriptor<Duke3d::Duke3dListMenu> _lm("Duke3d.ListMenu");
static TMenuClassDescriptor<Duke3d::Duke3dHuntMenu> _dhm("Duke3d.HuntMenu");
static TMenuClassDescriptor<Duke3d::Duke3dTargetMenu> _dtm("Duke3d.TargetMenu");
static TMenuClassDescriptor<Duke3d::Duke3dWeaponMenu> _dwm("Duke3d.WeaponMenu");
static TMenuClassDescriptor<Duke3d::Duke3dTrophiesMenu> _dttm("Duke3d.TrophiesMenu");
static TMenuClassDescriptor<DImageScrollerMenu> _ism("Duke3d.ImageScrollerMenu"); // does not implement a new class, we only need the descriptor.
void RegisterDuke3dMenus()
{
menuClasses.Push(&_mm);
menuClasses.Push(&_lm);
menuClasses.Push(&_ism);
menuClasses.Push(&_dhm);
menuClasses.Push(&_dtm);
menuClasses.Push(&_dwm);
menuClasses.Push(&_dttm);
}

944
source/duke/src/demo.cpp Normal file
View file

@ -0,0 +1,944 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "demo.h"
#include "duke3d.h"
#include "menus.h"
#include "savegame.h"
#include "screens.h"
BEGIN_DUKE_NS
char g_firstDemoFile[BMAX_PATH];
FileWriter *g_demo_filePtr{}; // write
FileReader g_demo_recFilePtr; // read
int32_t g_demo_cnt;
int32_t g_demo_goalCnt=0;
int32_t g_demo_totalCnt;
int32_t g_demo_paused=0;
int32_t g_demo_rewind=0;
int32_t g_demo_showStats=1;
static int32_t g_demo_soundToggle;
static int32_t demo_hasdiffs, demorec_diffs=1, demorec_difftics = 2*REALGAMETICSPERSEC;
int32_t demoplay_diffs=1;
int32_t demorec_seeds_cvar=1;
int32_t demoplay_showsync=1;
static int32_t demorec_seeds=1, demo_hasseeds;
static void Demo_RestoreModes(int32_t menu)
{
if (menu)
M_StartControlPanel(false);
else
M_ClearMenus();
g_player[myconnectindex].ps->gm &= ~MODE_GAME;
g_player[myconnectindex].ps->gm |= MODE_DEMO;
}
void Demo_PrepareWarp(void)
{
if (!g_demo_paused)
{
g_demo_soundToggle = nosound;
nosound = true;
}
FX_StopAllSounds();
S_ClearSoundLocks();
}
static int32_t G_OpenDemoRead(int32_t g_whichDemo) // 0 = mine
{
int32_t i;
savehead_t saveh;
char demofn[14];
const char *demofnptr;
if (DEER)
return 0;
if (g_whichDemo == 1 && g_firstDemoFile[0])
{
demofnptr = g_firstDemoFile;
}
else
{
Bsprintf(demofn, DEMOFN_FMT, g_whichDemo);
demofnptr = demofn;
}
if (!g_demo_recFilePtr.OpenFile(demofnptr))
return 0;
Bassert(g_whichDemo >= 1);
i = sv_loadsnapshot(g_demo_recFilePtr, -g_whichDemo, &saveh);
if (i)
{
Printf(TEXTCOLOR_RED "There were errors opening demo %d (code: %d).\n", g_whichDemo, i);
g_demo_recFilePtr.Close();
return 0;
}
demo_hasdiffs = saveh.recdiffsp;
g_demo_totalCnt = saveh.reccnt;
demo_hasseeds = 0;
i = g_demo_totalCnt/REALGAMETICSPERSEC;
Printf("demo %d duration: %d min %d sec\n", g_whichDemo, i/60, i%60);
g_demo_cnt = 1;
ud.reccnt = 0;
gFullMap = false;
ud.god = ud.cashman = ud.eog = 0;
ud.noclip = ud.scrollmode = ud.overhead_on = 0; //= paused = 0;
totalclock = ototalclock = lockclock = 0;
return 1;
}
#if KRANDDEBUG
extern void krd_enable(int32_t which);
extern int32_t krd_print(const char *filename);
#endif
void G_OpenDemoWrite(void)
{
char demofn[BMAX_PATH];
int32_t i, demonum=1;
if (ud.recstat == 2)
{
g_demo_recFilePtr.Close();
}
if ((g_player[myconnectindex].ps->gm&MODE_GAME) && g_player[myconnectindex].ps->dead_flag)
{
quoteMgr.InitializeQuote(QUOTE_RESERVED4, "CANNOT START DEMO RECORDING WHEN DEAD!");
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
ud.recstat = m_recstat = 0;
return;
}
do
{
if (demonum == MAXDEMOS)
return;
if (snprintf(demofn, sizeof(demofn), "%s" DEMOFN_FMT, G_GetDemoPath().GetChars(), demonum))
{
Printf("Couldn't start demo writing: INTERNAL ERROR: file name too long\n");
goto error_wopen_demo;
}
demonum++;
g_demo_filePtr = FileWriter::Open(demofn);
if (g_demo_filePtr == NULL)
break;
delete g_demo_filePtr;
}
while (1);
g_demo_filePtr = FileWriter::Open(demofn);
if (g_demo_filePtr == NULL)
return;
i=sv_saveandmakesnapshot(*g_demo_filePtr, -1, (demorec_seeds_cvar<<1));
if (i)
{
delete g_demo_filePtr;
g_demo_filePtr = nullptr;
error_wopen_demo:
quoteMgr.InitializeQuote(QUOTE_RESERVED4, "FAILED STARTING DEMO RECORDING. SEE CONSOLE FOR DETAILS.");
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
ud.recstat = m_recstat = 0;
return;
}
demorec_seeds = demorec_seeds_cvar;
demorec_diffs = demorec_diffs_cvar;
demorec_difftics = demorec_difftics_cvar;
quoteMgr.FormatQuote(QUOTE_RESERVED4, "DEMO %d RECORDING STARTED", demonum-1);
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
ud.reccnt = 0;
ud.recstat = m_recstat = 1; //
# if KRANDDEBUG
krd_enable(1);
# endif
g_demo_cnt = 1;
}
// demo_profile: < 0: prepare
static int32_t g_demo_playFirstFlag, g_demo_profile, g_demo_stopProfile;
static int32_t g_demo_exitAfter;
void Demo_PlayFirst(int32_t prof, int32_t exitafter)
{
g_demo_playFirstFlag = 1;
g_demo_exitAfter = exitafter;
Bassert(prof >= 0);
g_demo_profile = -prof; // prepare
}
void Demo_SetFirst(const char *demostr)
{
char *tailptr;
int32_t i = Bstrtol(demostr, &tailptr, 10);
if (tailptr==demostr+Bstrlen(demostr) && (unsigned)i < MAXDEMOS) // demo number passed
Bsprintf(g_firstDemoFile, DEMOFN_FMT, i);
else // demo file name passed
maybe_append_ext(g_firstDemoFile, sizeof(g_firstDemoFile), demostr, ".edm");
}
static uint8_t g_demo_seedbuf[RECSYNCBUFSIZ];
static void Demo_WriteSync()
{
int16_t tmpreccnt;
g_demo_filePtr->Write("sYnC", 4);
tmpreccnt = (int16_t)ud.reccnt;
g_demo_filePtr->Write(&tmpreccnt, sizeof(int16_t));
if (demorec_seeds)
g_demo_filePtr->Write(g_demo_seedbuf, ud.reccnt);
g_demo_filePtr->Write(recsync, sizeof(input_t)* ud.reccnt);
ud.reccnt = 0;
}
void G_DemoRecord(void)
{
int16_t i;
g_demo_cnt++;
if (demorec_diffs && (g_demo_cnt%demorec_difftics == 1))
{
sv_writediff(g_demo_filePtr);
demorec_difftics = demorec_difftics_cvar;
}
if (demorec_seeds)
g_demo_seedbuf[ud.reccnt] = (uint8_t)(randomseed>>24);
for (TRAVERSE_CONNECT(i))
{
Bmemcpy(&recsync[ud.reccnt], g_player[i].input, sizeof(input_t));
ud.reccnt++;
}
if (ud.reccnt > RECSYNCBUFSIZ-MAXPLAYERS || (demorec_diffs && (g_demo_cnt%demorec_difftics == 0)))
Demo_WriteSync();
}
void G_CloseDemoWrite(void)
{
if (ud.recstat == 1)
{
if (ud.reccnt > 0)
Demo_WriteSync();
g_demo_filePtr->Write("EnD!", 4);
// lastly, we need to write the number of written recsyncs to the demo file
g_demo_filePtr->Write(&g_demo_cnt, sizeof(g_demo_cnt));
ud.recstat = m_recstat = 0;
delete g_demo_filePtr;
g_demo_filePtr = nullptr;
sv_freemem();
quoteMgr.InitializeQuote(QUOTE_RESERVED4, "DEMO RECORDING STOPPED");
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
}
#if KRANDDEBUG
krd_print("krandrec.log");
#endif
}
static int32_t g_whichDemo = 1;
static int32_t Demo_UpdateState(int32_t frominit)
{
int32_t j = g_player[myconnectindex].ps->gm&MODE_MENU;
int32_t k = sv_updatestate(frominit);
// tmpdifftime = g_demo_cnt+12;
Demo_RestoreModes(j);
if (k)
Printf("sv_updatestate() returned %d.\n", k);
return k;
}
#define CORRUPT(code) do { corruptcode=code; goto corrupt; } while(0)
static int32_t Demo_ReadSync(int32_t errcode)
{
uint16_t si;
int32_t i;
if (g_demo_recFilePtr.Read(&si, sizeof(uint16_t)) != sizeof(uint16_t))
return errcode;
i = si;
if (demo_hasseeds)
{
if (g_demo_recFilePtr.Read(g_demo_seedbuf, i) != i)
return errcode;
}
int32_t bytes = sizeof(input_t)*i;
if (g_demo_recFilePtr.Read(recsync, bytes) != bytes)
return errcode+2;
ud.reccnt = i;
return 0;
}
////////// DEMO PROFILING (TIMEDEMO MODE) //////////
static struct {
int32_t numtics, numframes;
double totalgamems;
double totalroomsdrawms, totalrestdrawms;
double starthiticks;
} g_prof;
int32_t Demo_IsProfiling(void)
{
return (g_demo_profile > 0);
}
static void Demo_StopProfiling(void)
{
g_demo_stopProfile = 1;
}
static void Demo_GToc(double t)
{
g_prof.numtics++;
g_prof.totalgamems += timerGetHiTicks()-t;
}
static void Demo_RToc(double t1, double t2)
{
g_prof.numframes++;
g_prof.totalroomsdrawms += t2-t1;
g_prof.totalrestdrawms += timerGetHiTicks()-t2;
}
static void Demo_DisplayProfStatus(void)
{
char buf[64];
static int32_t lastpercent=-1;
int32_t percent = (100*g_demo_cnt)/g_demo_totalCnt;
if (lastpercent == percent)
return;
lastpercent = percent;
videoClearScreen(0);
snprintf(buf, sizeof(buf), "timing... %d/%d game tics (%d %%)",
g_demo_cnt, g_demo_totalCnt, percent);
gametext_center(60, buf);
videoNextPage();
}
static void Demo_SetupProfile(void)
{
g_demo_profile *= -1; // now >0: profile for real
g_demo_soundToggle = nosound;
nosound = true; // restored by Demo_FinishProfile()
Bmemset(&g_prof, 0, sizeof(g_prof));
g_prof.starthiticks = timerGetHiTicks();
}
static void Demo_FinishProfile(void)
{
if (Demo_IsProfiling())
{
int32_t dn=g_whichDemo-1;
int32_t nt=g_prof.numtics, nf=g_prof.numframes;
double gms=g_prof.totalgamems;
double dms1=g_prof.totalroomsdrawms, dms2=g_prof.totalrestdrawms;
nosound = g_demo_soundToggle;
if (nt > 0)
{
Printf("== demo %d: %d gametics\n", dn, nt);
Printf("== demo %d game times: %.03f ms (%.03f us/gametic)\n",
dn, gms, (gms*1000.0)/nt);
}
if (nf > 0)
{
Printf("== demo %d: %d frames (%d frames/gametic)\n", dn, nf, g_demo_profile-1);
Printf("== demo %d drawrooms times: %.03f s (%.03f ms/frame)\n",
dn, dms1/1000.0, dms1/nf);
Printf("== demo %d drawrest times: %.03f s (%.03f ms/frame)\n",
dn, dms2/1000.0, dms2/nf);
}
{
double totalprofms = gms+dms1+dms2;
double totalms = timerGetHiTicks()-g_prof.starthiticks;
if (totalprofms != 0)
Printf("== demo %d: non-profiled time overhead: %.02f %%\n",
dn, 100.0*totalms/totalprofms - 100.0);
}
}
g_demo_profile = 0;
g_demo_stopProfile = 0;
}
////////////////////
int32_t G_PlaybackDemo(void)
{
int32_t bigi, j, initsyncofs = 0, lastsyncofs = 0, lastsynctic = 0, lastsyncclock = 0;
int32_t foundemo = 0, corruptcode, outofsync=0;
static int32_t in_menu = 0;
// static int32_t tmpdifftime=0;
totalclock = 0;
ototalclock = 0;
lockclock = 0;
if (ready2send)
return 0;
if (!g_demo_playFirstFlag)
g_demo_profile = 0;
RECHECK:
if (g_demo_playFirstFlag)
g_demo_playFirstFlag = 0;
else if (g_demo_exitAfter)
G_GameExit(" ");
#if KRANDDEBUG
if (foundemo)
krd_print("krandplay.log");
#endif
in_menu = g_player[myconnectindex].ps->gm&MODE_MENU;
pub = NUMPAGES;
pus = NUMPAGES;
renderFlushPerms();
#ifdef PLAYDEMOLOOP // Todo: Make a CVar.
if (!g_netServer && ud.multimode < 2)
foundemo = G_OpenDemoRead(g_whichDemo);
#endif
if (foundemo == 0)
{
ud.recstat = 0;
if (g_whichDemo > 1)
{
g_whichDemo = 1;
goto RECHECK;
}
fadepal(0,0,0, 0,252,28);
P_SetGamePalette(g_player[myconnectindex].ps, BASEPAL, 0); // JBF 20040308
G_DrawBackground();
//M_DisplayMenus();
videoNextPage();
fadepal(0,0,0, 252,0,-28);
ud.reccnt = 0;
}
else
{
ud.recstat = 2;
g_whichDemo++;
if (g_whichDemo == MAXDEMOS)
g_whichDemo = 1;
g_player[myconnectindex].ps->gm &= ~MODE_GAME;
g_player[myconnectindex].ps->gm |= MODE_DEMO;
lastsyncofs = g_demo_recFilePtr.Tell();
initsyncofs = lastsyncofs;
lastsynctic = g_demo_cnt;
lastsyncclock = (int32_t) totalclock;
outofsync = 0;
#if KRANDDEBUG
krd_enable(2);
#endif
if (g_demo_profile < 0)
{
Demo_SetupProfile();
}
}
if (foundemo == 0 || in_menu || inputState.CheckAllInput() || numplayers > 1)
{
FX_StopAllSounds();
S_ClearSoundLocks();
M_StartControlPanel(false);
}
ready2send = 0;
bigi = 0;
inputState.ClearAllInput();
// Printf("ticcnt=%d, total=%d\n", g_demo_cnt, g_demo_totalCnt);
while (g_demo_cnt < g_demo_totalCnt || foundemo==0)
{
// Main loop here. It also runs when there's no demo to show,
// so maybe a better name for this function would be
// G_MainLoopWhenNotInGame()?
// Demo requested from the OSD, its name is in g_firstDemoFile[]
if (g_demo_playFirstFlag)
{
g_demo_playFirstFlag = 0;
g_whichDemo = 1; // force g_firstDemoFile[]
g_demo_paused = 0;
goto nextdemo_nomenu;
}
if (foundemo && (!g_demo_paused || g_demo_goalCnt))
{
if (g_demo_goalCnt>0 && g_demo_goalCnt < g_demo_cnt)
{
// initialize rewind
int32_t menu = g_player[myconnectindex].ps->gm&MODE_MENU;
if (g_demo_goalCnt > lastsynctic)
{
// we can use a previous diff
if (Demo_UpdateState(0)==0)
{
g_demo_cnt = lastsynctic;
g_demo_recFilePtr.Seek(lastsyncofs, FileReader::SeekSet);
ud.reccnt = 0;
totalclock = ototalclock = lockclock = lastsyncclock;
}
else CORRUPT(-1);
}
else
{
// update to initial state
if (Demo_UpdateState(1) == 0)
{
g_demo_recFilePtr.Seek(initsyncofs, FileReader::SeekSet);
g_levelTextTime = 0;
g_demo_cnt = 1;
ud.reccnt = 0;
totalclock = ototalclock = lockclock = 0;
}
else CORRUPT(0);
}
Demo_RestoreModes(menu);
}
if (g_demo_stopProfile)
Demo_FinishProfile();
while (totalclock >= (lockclock+TICSPERFRAME)
// || (ud.reccnt > REALGAMETICSPERSEC*2 && paused)
|| (g_demo_goalCnt>0 && g_demo_cnt<g_demo_goalCnt))
{
if (ud.reccnt<=0)
{
// Record count reached zero (or <0, corrupted), need
// reading another chunk.
char tmpbuf[4];
if (ud.reccnt<0)
{
Printf("G_PlaybackDemo: ud.reccnt<0!\n");
CORRUPT(1);
}
bigi = 0;
//reread:
if (g_demo_recFilePtr.Read(tmpbuf, 4) != 4)
CORRUPT(2);
if (Bmemcmp(tmpbuf, "sYnC", 4)==0)
{
int32_t err = Demo_ReadSync(3);
if (err)
CORRUPT(err);
}
else if (demo_hasdiffs && Bmemcmp(tmpbuf, "dIfF", 4)==0)
{
int32_t k = sv_readdiff(g_demo_recFilePtr);
if (k)
{
Printf("sv_readdiff() returned %d.\n", k);
CORRUPT(6);
}
else
{
lastsyncofs = g_demo_recFilePtr.Tell();
lastsynctic = g_demo_cnt;
lastsyncclock = (int32_t) totalclock;
if (g_demo_recFilePtr.Read(tmpbuf, 4) != 4)
CORRUPT(7);
if (Bmemcmp(tmpbuf, "sYnC", 4))
CORRUPT(8);
{
int32_t err = Demo_ReadSync(9);
if (err)
CORRUPT(err);
}
if ((g_demo_goalCnt==0 && demoplay_diffs) ||
(g_demo_goalCnt>0 && ud.reccnt/ud.multimode >= g_demo_goalCnt-g_demo_cnt))
{
Demo_UpdateState(0);
}
}
}
else if (Bmemcmp(tmpbuf, "EnD!", 4)==0)
goto nextdemo;
else CORRUPT(12);
if (0)
{
corrupt:
Printf(TEXTCOLOR_RED "Demo %d is corrupt (code %d).\n", g_whichDemo-1, corruptcode);
nextdemo:
M_StartControlPanel(false);
nextdemo_nomenu:
foundemo = 0;
ud.reccnt = 0;
g_demo_recFilePtr.Close();
if (g_demo_goalCnt>0)
{
g_demo_goalCnt=0;
nosound = g_demo_soundToggle;
}
if (Demo_IsProfiling()) // don't reset g_demo_profile if it's < 0
Demo_FinishProfile();
goto RECHECK;
}
}
if (demo_hasseeds)
outofsync = ((uint8_t)(randomseed>>24) != g_demo_seedbuf[bigi]);
for (TRAVERSE_CONNECT(j))
{
Bmemcpy(&inputfifo[movefifoplc&(MOVEFIFOSIZ-1)][j], &recsync[bigi], sizeof(input_t));
bigi++;
ud.reccnt--;
}
g_demo_cnt++;
S_Update();
if (Demo_IsProfiling())
{
double t = timerGetHiTicks();
G_DoMoveThings();
Demo_GToc(t);
}
else if (!g_demo_paused)
{
// assumption that ud.multimode doesn't change in a demo may not be true
// sometime in the future v v v v v v v v v
if (g_demo_goalCnt==0 || !demo_hasdiffs || ud.reccnt/ud.multimode>=g_demo_goalCnt-g_demo_cnt)
{
G_DoMoveThings(); // increases lockclock by TICSPERFRAME
}
else
{
lockclock += TICSPERFRAME;
}
}
else
{
int32_t k = nosound;
nosound = true;
G_DoMoveThings();
nosound = k;
}
ototalclock += TICSPERFRAME;
if (g_demo_goalCnt > 0)
{
// if fast-forwarding, we must update totalclock
totalclock += TICSPERFRAME;
// Printf("t:%d, l+T:%d; cnt:%d, goal:%d%s", totalclock, (lockclock+TICSPERFRAME),
// g_demo_cnt, g_demo_goalCnt, g_demo_cnt>=g_demo_goalCnt?" ":"\n");
if (g_demo_cnt>=g_demo_goalCnt)
{
g_demo_goalCnt = 0;
nosound = g_demo_soundToggle;
}
}
}
}
else if (foundemo && g_demo_paused)
{
totalclock = lockclock;
}
if (Demo_IsProfiling())
totalclock += TICSPERFRAME;
if (G_FPSLimit())
{
if (foundemo == 0)
{
G_DrawBackground();
}
else
{
// NOTE: currently, no key/mouse events will be seen while
// demo-profiling because we need 'totalclock' for ourselves.
// And handleevents() -> sampletimer() would mess that up.
G_HandleLocalKeys();
// Render one frame (potentially many if profiling)
if (Demo_IsProfiling())
{
int32_t i, num = g_demo_profile-1;
Bassert(totalclock-ototalclock==4);
for (i=0; i<num; i++)
{
double t1 = timerGetHiTicks(), t2;
// Printf("t=%d, o=%d, t-o = %d\n", totalclock,
// ototalclock, totalclock-ototalclock);
// NOTE: G_DrawRooms() calculates smoothratio inside and
// ignores the function argument, so we set totalclock
// accordingly.
j = (i<<16)/num;
totalclock = ototalclock + (j>>16);
G_DrawRooms(screenpeek, j);
t2 = timerGetHiTicks();
G_DisplayRest(j);
Demo_RToc(t1, t2);
}
totalclock = ototalclock+4;
// draw status
Demo_DisplayProfStatus();
if (inputState.CheckAllInput())
Demo_StopProfiling();
}
else
{
j = calc_smoothratio(totalclock, ototalclock);
if (g_demo_paused && g_demo_rewind)
j = 65536-j;
G_DrawRooms(screenpeek, j);
G_DisplayRest(j);
}
// totalclocklock = totalclock;
if (!Demo_IsProfiling() && (g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
{
if (demoplay_showsync && outofsync)
gametext_center(100, "OUT OF SYNC");
if (g_demo_showStats)
{
#if 0
if (g_demo_cnt<tmpdifftime)
gametext_center(100, "DIFF");
{
char buf[32];
Bsprintf(buf, "RC:%4d TC:%5d", ud.reccnt, g_demo_cnt);
gametext_center_number(100, buf);
}
#endif
j=g_demo_cnt/REALGAMETICSPERSEC;
Bsprintf(buf, "%02d:%02d", j/60, j%60);
gametext_widenumber(18, 16, buf);
rotatesprite(60<<16, 16<<16, 32768, 0, SLIDEBAR, 0, 0, 2+8+16+1024, 0, 0, (xdim*95)/320, ydim-1);
rotatesprite(90<<16, 16<<16, 32768, 0, SLIDEBAR, 0, 0, 2+8+16+1024, (xdim*95)/320, 0, (xdim*125)/320, ydim-1);
rotatesprite(120<<16, 16<<16, 32768, 0, SLIDEBAR, 0, 0, 2+8+16+1024, (xdim*125)/320, 0, (xdim*155)/320, ydim-1);
rotatesprite(150<<16, 16<<16, 32768, 0, SLIDEBAR, 0, 0, 2+8+16+1024, (xdim*155)/320, 0, xdim-1, ydim-1);
j = (182<<16) - (tabledivide32_noinline((120*(g_demo_totalCnt-g_demo_cnt))<<4, g_demo_totalCnt)<<12);
if (RR)
rotatesprite_fs(j, (15<<16)+(1<<15), 16384, 0, BIGALPHANUM-9, 0, 0, 2+8+16+1024);
else
rotatesprite_fs(j, (16<<16)+(1<<15), 32768, 0, SLIDEBAR+1, 0, 0, 2+8+16+1024);
j=(g_demo_totalCnt-g_demo_cnt)/REALGAMETICSPERSEC;
Bsprintf(buf, "-%02d:%02d%s", j/60, j%60, g_demo_paused ? " ^15PAUSED" : "");
gametext_widenumber(194, 16, buf);
}
}
if ((g_netServer || ud.multimode > 1) && g_player[myconnectindex].ps->gm)
Net_GetPackets();
if (g_player[myconnectindex].gotvote == 0 && voting != -1 && voting != myconnectindex)
gametext_center(60, GStrings("TXT_PRESSF1_F2"));
}
if ((g_player[myconnectindex].ps->gm&MODE_MENU) && (g_player[myconnectindex].ps->gm&MODE_EOL))
{
Demo_FinishProfile();
videoNextPage();
goto RECHECK;
}
if (Demo_IsProfiling())
{
// Do nothing: sampletimer() is reached from M_DisplayMenus() ->
// Net_GetPackets() else.
}
else if (g_player[myconnectindex].ps->gm&MODE_TYPE)
{
Net_SendMessage();
if ((g_player[myconnectindex].ps->gm&MODE_TYPE) != MODE_TYPE)
{
g_player[myconnectindex].ps->gm = 0;
M_StartControlPanel(false);
}
}
else
{
//if (ud.recstat != 2)
//M_DisplayMenus();
if ((g_netServer || ud.multimode > 1))// && !Menu_IsTextInput(m_currentMenu))
{
ControlInfo noshareinfo;
CONTROL_GetInput(&noshareinfo);
}
}
if (!Demo_IsProfiling())
G_PrintGameQuotes(screenpeek);
if (ud.last_camsprite != ud.camerasprite)
ud.last_camsprite = ud.camerasprite;
if (VOLUMEONE)
{
if ((g_player[myconnectindex].ps->gm&MODE_MENU) == 0)
rotatesprite_fs((320-50)<<16, 9<<16, 65536L, 0, BETAVERSION, 0, 0, 2+8+16+128);
}
videoNextPage();
}
// NOTE: We must prevent handleevents() and Net_GetPackets() from
// updating totalclock when profiling (both via sampletimer()):
if (!Demo_IsProfiling())
G_HandleAsync();
if (g_player[myconnectindex].ps->gm == MODE_GAME)
{
// user wants to play a game, quit showing demo!
if (foundemo)
{
#if KRANDDEBUG
krd_print("krandplay.log");
#endif
g_demo_recFilePtr.Close();
}
return 0;
}
}
ud.multimode = numplayers; // fixes 2 infinite loops after watching demo
g_demo_recFilePtr.Close();
Demo_FinishProfile();
// if we're in the menu, try next demo immediately
if (g_player[myconnectindex].ps->gm&MODE_MENU)
goto RECHECK;
#if KRANDDEBUG
if (foundemo)
krd_print("krandplay.log");
#endif
// finished playing a demo and not in menu:
// return so that e.g. the title can be shown
return 1;
}
END_DUKE_NS

65
source/duke/src/demo.h Normal file
View file

@ -0,0 +1,65 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef demo_h_
#define demo_h_
#include "compat.h"
#include "files.h"
BEGIN_DUKE_NS
#define DEMOFN_FMT "edemo%03d.edm"
#define LDEMOFN_FMT "demo%d.dmo"
#define MAXDEMOS 1000
extern FileWriter * g_demo_filePtr;
extern char g_firstDemoFile[BMAX_PATH];
extern int32_t g_demo_cnt;
extern int32_t g_demo_goalCnt;
extern int32_t g_demo_paused;
extern FileReader g_demo_recFilePtr;
extern int32_t g_demo_rewind;
extern int32_t g_demo_showStats;
extern int32_t g_demo_totalCnt;
int32_t G_PlaybackDemo(void);
void Demo_PrepareWarp(void);
void G_CloseDemoWrite(void);
void G_DemoRecord(void);
void G_OpenDemoWrite(void);
void Demo_PlayFirst(int32_t prof, int32_t exitafter);
void Demo_SetFirst(const char *demostr);
int32_t Demo_IsProfiling(void);
#if KRANDDEBUG
int32_t krd_print(const char *filename);
void krd_enable(int32_t which);
#endif
END_DUKE_NS
#endif

242
source/duke/src/duke3d.h Normal file
View file

@ -0,0 +1,242 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef duke3d_h_
#define duke3d_h_
// JBF
#include "baselayer.h"
#include "build.h"
#include "compat.h"
#include "pragmas.h"
#include "polymost.h"
#include "gamecvars.h"
#include "menu/menu.h"
BEGIN_DUKE_NS
#define VOLUMEALL (g_Shareware == 0)
#define PLUTOPAK (g_scriptVersion >= 14)
#define VOLUMEONE (g_Shareware == 1)
// increase by 3, because atomic GRP adds 1, and Shareware adds 2
// Non-Lua build
# define BYTEVERSION_EDUKE32 336
//#define BYTEVERSION_13 27
//#define BYTEVERSION_14 116
//#define BYTEVERSION_15 117
#define BYTEVERSION (BYTEVERSION_EDUKE32+(PLUTOPAK?1:(VOLUMEONE<<1)))
#define NUMPAGES 1
#define RECSYNCBUFSIZ 2520 //2520 is the (LCM of 1-8)*3
#define MOVEFIFOSIZ 256
#define MAXLEVELS 64
#define MAXGAMETYPES 16
enum {
MUS_FIRST_SPECIAL = MAXVOLUMES*MAXLEVELS,
MUS_INTRO = MUS_FIRST_SPECIAL,
MUS_BRIEFING = MUS_FIRST_SPECIAL + 1,
MUS_LOADING = MUS_FIRST_SPECIAL + 2,
};
////////// TIMING CONSTANTS //////////
// The number of 'totalclock' increments per second:
#define TICRATE 120
// The number of game state updates per second:
#define REALGAMETICSPERSEC 30
// The number of 'totalclock' increments per game state update:
// NOTE: calling a game state update a 'frame' is really weird.
// (This used to be TICRATE/GAMETICSPERSEC, which was 120/26 = 4.615~ truncated
// to 4 by integer division.)
#define TICSPERFRAME (TICRATE/REALGAMETICSPERSEC)
// Used as a constant to satisfy all of the calculations written with ticrate =
// 26 in mind:
#define GAMETICSPERSEC 26
#define PACKBUF_SIZE 32768
#define TILE_SAVESHOT (MAXTILES-1)
#define TILE_LOADSHOT (MAXTILES-3)
#define TILE_TILT (MAXTILES-2)
#define TILE_ANIM (MAXTILES-4)
#define TILE_VIEWSCR (MAXTILES-5)
// Reserved: TILE_VIEWSCR_1 (MAXTILES-6)
// Reserved: TILE_VIEWSCR_2 (MAXTILES-7)
EDUKE32_STATIC_ASSERT(7 <= MAXTILES-MAXUSERTILES);
// sprites with these statnums should be considered for fixing
#define ROTFIXSPR_STATNUMP(k) ((k)==STAT_DEFAULT || (k)==STAT_STANDABLE || (k)==STAT_FX || \
(k)==STAT_FALLER || (k)==STAT_LIGHT)
#define ROTFIXSPR_MAGIC 0x18190000
// JBF 20040604: sync is a function on some platforms
#define sync dsync
// Uncomment the following to remove calls to a.nasm functions with the GL renderers
// so that debugging with valgrind --smc-check=none is possible:
//#define DEBUG_VALGRIND_NO_SMC
END_DUKE_NS
#include "actors.h"
#include "common_game.h"
#include "config.h"
#include "gamecontrol.h"
#include "game.h"
#include "gamedef.h"
#include "gamedefs.h"
#include "gameexec.h"
#include "gamevars.h"
#include "global.h"
#include "inv.h"
#include "macros.h"
#include "namesdyn.h"
#include "net.h"
#include "player.h"
#include "quotes.h"
#include "rts.h"
#include "text.h"
#include "sector.h"
#include "sounds.h"
#include "soundsdyn.h"
#include "rrdh.h"
BEGIN_DUKE_NS
// Order is that of EDuke32 by necessity because it exposes the key binds to scripting by index instead of by name.
enum GameFunction_t
{
gamefunc_Move_Forward,
gamefunc_Move_Backward,
gamefunc_Turn_Left,
gamefunc_Turn_Right,
gamefunc_Strafe,
gamefunc_Fire,
gamefunc_Open,
gamefunc_Run,
gamefunc_Alt_Fire, // Duke3D, Blood
gamefunc_Jump,
gamefunc_Crouch,
gamefunc_Look_Up,
gamefunc_Look_Down,
gamefunc_Look_Left,
gamefunc_Look_Right,
gamefunc_Strafe_Left,
gamefunc_Strafe_Right,
gamefunc_Aim_Up,
gamefunc_Aim_Down,
gamefunc_Weapon_1,
gamefunc_Weapon_2,
gamefunc_Weapon_3,
gamefunc_Weapon_4,
gamefunc_Weapon_5,
gamefunc_Weapon_6,
gamefunc_Weapon_7,
gamefunc_Weapon_8,
gamefunc_Weapon_9,
gamefunc_Weapon_10,
gamefunc_Inventory,
gamefunc_Inventory_Left,
gamefunc_Inventory_Right,
gamefunc_Holo_Duke, // Duke3D, RR
gamefunc_Jetpack,
gamefunc_NightVision,
gamefunc_MedKit,
gamefunc_TurnAround,
gamefunc_SendMessage,
gamefunc_Map,
gamefunc_Shrink_Screen,
gamefunc_Enlarge_Screen,
gamefunc_Center_View,
gamefunc_Holster_Weapon,
gamefunc_Show_Opponents_Weapon,
gamefunc_Map_Follow_Mode,
gamefunc_See_Coop_View,
gamefunc_Mouse_Aiming,
gamefunc_Toggle_Crosshair,
gamefunc_Steroids,
gamefunc_Quick_Kick,
gamefunc_Next_Weapon,
gamefunc_Previous_Weapon,
gamefunc_Dpad_Select,
gamefunc_Dpad_Aiming,
gamefunc_Last_Weapon,
gamefunc_Alt_Weapon,
gamefunc_Third_Person_View,
gamefunc_Show_DukeMatch_Scores,
gamefunc_Toggle_Crouch, // This is the last one used by EDuke32.
NUM_ACTIONS
};
static inline int32_t G_HaveActor(int spriteNum)
{
return g_tile[spriteNum].execPtr!=NULL;
}
static inline int32_t G_DefaultActorHealth(int spriteNum)
{
return G_HaveActor(spriteNum) ? g_tile[spriteNum].execPtr[0] : 0;
}
struct GameInterface : ::GameInterface
{
const char* Name() override { return "Redneck"; }
int app_main() override;
void UpdateScreenSize() override;
void FreeGameData() override;
bool GenerateSavePic() override;
bool validate_hud(int) override;
void set_hud_layout(int size) override;
void set_hud_scale(int size) override;
FString statFPS() override;
GameStats getStats() override;
void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) override;
void MenuOpened() override;
void MenuSound(EMenuSounds snd) override;
void MenuClosed() override;
bool CanSave() override;
void StartGame(FNewGameStartup& gs) override;
FSavegameInfo GetSaveSig() override;
void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position, bool bg) override;
void DrawMenuCaption(const DVector2& origin, const char* text) override;
bool SaveGame(FSaveGameNode*) override;
bool LoadGame(FSaveGameNode*) override;
void DoPrintMessage(int prio, const char* text) override;
void DrawPlayerSprite(const DVector2& origin, bool onteam) override;
void QuitToTitle() override;
FString GetCoordString() override;
int GetStringTile(int font, const char* t, int f) override;
};
END_DUKE_NS
#endif

View file

@ -0,0 +1,50 @@
#ifndef EDUKE32_EVENTS_DEFS_H_
#define EDUKE32_EVENTS_DEFS_H_
// the order of these can't be changed or else compatibility with EDuke 2.0 mods will break
enum GameEvent_t {
EVENT_INIT, // 0
EVENT_ENTERLEVEL,
EVENT_RESETWEAPONS,
EVENT_RESETINVENTORY,
EVENT_HOLSTER,
EVENT_LOOKLEFT, // 5
EVENT_LOOKRIGHT,
EVENT_SOARUP,
EVENT_SOARDOWN,
EVENT_CROUCH,
EVENT_JUMP, // 10
EVENT_RETURNTOCENTER,
EVENT_LOOKUP,
EVENT_LOOKDOWN,
EVENT_AIMUP,
EVENT_FIRE, // 15
EVENT_CHANGEWEAPON,
EVENT_GETSHOTRANGE,
EVENT_GETAUTOAIMANGLE,
EVENT_GETLOADTILE,
EVENT_CHEATGETSTEROIDS, // 20
EVENT_CHEATGETHEAT,
EVENT_CHEATGETBOOT,
EVENT_CHEATGETSHIELD,
EVENT_CHEATGETSCUBA,
EVENT_CHEATGETHOLODUKE, // 25
EVENT_CHEATGETJETPACK,
EVENT_CHEATGETFIRSTAID,
EVENT_QUICKKICK,
EVENT_INVENTORY,
EVENT_USENIGHTVISION, // 30
EVENT_USESTEROIDS,
EVENT_INVENTORYLEFT,
EVENT_INVENTORYRIGHT,
EVENT_HOLODUKEON,
EVENT_HOLODUKEOFF, // 35
EVENT_USEMEDKIT,
EVENT_USEJETPACK,
EVENT_TURNAROUND,
MAXEVENTS,
EVENT_AIMDOWN = EVENT_AIMUP,
};
#endif

View file

@ -0,0 +1,136 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2020 EDuke32 developers and contributors
Copyright (C) 2020 sirlemonhead
This file is part of Rednukem.
Rednukem is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "filestream.h"
#include <stdlib.h>
namespace RedNukem {
bool FileStream::Open(const char *fileName)
{
file = kopen4loadfrommod(fileName, 0);
if (file == -1)
{
// log error
return false;
}
return true;
}
bool FileStream::Is_Open()
{
return file != -1;
}
void FileStream::Close()
{
kclose(file);
file = -1;
}
int32_t FileStream::ReadBytes(uint8_t *data, uint32_t nBytes)
{
uint32_t nCount = (uint32_t)kread(file, data, static_cast<int32_t>(nBytes));
if (nCount != nBytes) {
return 0;
}
return (int32_t)nCount;
}
uint64_t FileStream::ReadUint64LE()
{
uint64_t value;
kread(file, &value, 8);
return B_LITTLE64(value);
}
uint64_t FileStream::ReadUint64BE()
{
uint64_t value;
kread(file, &value, 8);
return B_BIG64(value);
}
uint32_t FileStream::ReadUint32LE()
{
uint32_t value;
kread(file, &value, 4);
return B_LITTLE32(value);
}
uint32_t FileStream::ReadUint32BE()
{
uint32_t value;
kread(file, &value, 4);
return B_BIG32(value);
}
uint16_t FileStream::ReadUint16LE()
{
uint16_t value;
kread(file, &value, 2);
return B_LITTLE16(value);
}
uint16_t FileStream::ReadUint16BE()
{
uint16_t value;
kread(file, &value, 2);
return B_BIG16(value);
}
uint8_t FileStream::ReadByte()
{
uint8_t value;
kread(file, &value, 1);
return value;
}
int32_t FileStream::Seek(int32_t offset, SeekDirection direction)
{
int32_t nStatus = -1;
if (kSeekStart == direction)
{
nStatus = klseek(file, offset, SEEK_SET);
}
else if (kSeekCurrent == direction)
{
nStatus = klseek(file, offset, SEEK_CUR);
}
else if (kSeekEnd == direction)
{
nStatus = klseek(file, offset, SEEK_END);
}
return nStatus;
}
int32_t FileStream::Skip(int32_t offset)
{
return Seek(offset, kSeekCurrent);
}
int32_t FileStream::GetPosition()
{
return ktell(file);
}
} // close namespace RedNukem

View file

@ -0,0 +1,65 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010-2020 EDuke32 developers and contributors
Copyright (C) 2020 sirlemonhead
This file is part of Rednukem.
Rednukem is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef _RedNukemFileStream_h_
#define _RedNukemFileStream_h_
#include "vfs.h"
#include "compat.h"
#include <stdint.h>
namespace RedNukem {
class FileStream
{
public:
bool Open(const char *fileName);
bool Is_Open();
void Close();
int32_t ReadBytes(uint8_t *data, uint32_t nBytes);
uint64_t ReadUint64LE();
uint64_t ReadUint64BE();
uint32_t ReadUint32LE();
uint32_t ReadUint32BE();
uint16_t ReadUint16LE();
uint16_t ReadUint16BE();
uint8_t ReadByte();
enum SeekDirection {
kSeekCurrent = 0,
kSeekStart = 1,
kSeekEnd = 2
};
int32_t Seek(int32_t offset, SeekDirection = kSeekStart);
int32_t Skip(int32_t offset);
int32_t GetPosition();
private:
buildvfs_kfd file;
};
} // close namespace RedNukem
#endif

7779
source/duke/src/game.cpp Normal file

File diff suppressed because it is too large Load diff

429
source/duke/src/game.h Normal file
View file

@ -0,0 +1,429 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
#ifndef ONLY_USERDEFS
#include "premap.h" // XXX
#endif
#include "fix16.h"
#include "gamedefs.h"
#include "gamedef.h"
#include "net.h"
#include "mmulti.h"
#include "palette.h"
#include "cmdlib.h"
BEGIN_DUKE_NS
#ifndef ONLY_USERDEFS
// Compile game-side legacy Room over Room code?
#define LEGACY_ROR 1
enum GametypeFlags_t {
GAMETYPE_COOP = 0x00000001,
GAMETYPE_WEAPSTAY = 0x00000002,
GAMETYPE_FRAGBAR = 0x00000004,
GAMETYPE_SCORESHEET = 0x00000008,
GAMETYPE_DMSWITCHES = 0x00000010,
GAMETYPE_COOPSPAWN = 0x00000020,
GAMETYPE_ACCESSCARDSPRITES = 0x00000040,
GAMETYPE_COOPVIEW = 0x00000080,
GAMETYPE_COOPSOUND = 0x00000100,
GAMETYPE_OTHERPLAYERSINMAP = 0x00000200,
GAMETYPE_ITEMRESPAWN = 0x00000400,
GAMETYPE_MARKEROPTION = 0x00000800,
GAMETYPE_PLAYERSFRIENDLY = 0x00001000,
GAMETYPE_FIXEDRESPAWN = 0x00002000,
GAMETYPE_ACCESSATSTART = 0x00004000,
GAMETYPE_PRESERVEINVENTORYDEATH = 0x00008000,
GAMETYPE_TDM = 0x00010000,
GAMETYPE_TDMSPAWN = 0x00020000
};
// logo control
enum LogoFlags_t {
LOGO_ENABLED = 0x00000001,
LOGO_PLAYANIM = 0x00000002,
LOGO_PLAYMUSIC = 0x00000004,
LOGO_3DRSCREEN = 0x00000008,
LOGO_TITLESCREEN = 0x00000010,
LOGO_DUKENUKEM = 0x00000020,
LOGO_THREEDEE = 0x00000040,
LOGO_PLUTOPAKSPRITE = 0x00000080,
LOGO_SHAREWARESCREENS = 0x00000100,
LOGO_TENSCREEN = 0x00000200,
LOGO_STOPANIMSOUNDS = 0x00000400,
LOGO_NOE4CUTSCENE = 0x00000800,
LOGO_NOE1BONUSSCENE = 0x00001000,
LOGO_NOE2BONUSSCENE = 0x00002000,
LOGO_NOE3BONUSSCENE = 0x00004000,
LOGO_NOE4BONUSSCENE = 0x00008000,
LOGO_NOE1ENDSCREEN = 0x00010000,
LOGO_NOE2ENDSCREEN = 0x00020000,
LOGO_NOE3RADLOGO = 0x00040000,
LOGO_NODUKETEAMTEXT = 0x00080000,
LOGO_NODUKETEAMPIC = 0x00100000,
LOGO_STOPMISCSOUNDS = 0x00200000,
LOGO_NOGAMETITLE = 0x00400000,
LOGO_NOTITLEBAR = 0x00800000,
LOGO_HIDEEPISODE = 0x01000000,
LOGO_NOHELP = 0x02000000,
LOGO_NOCREDITS = 0x04000000,
};
enum {
STATUSBAR_NONONE = 0x00000001,
STATUSBAR_NOMINI = 0x00000002,
STATUSBAR_NOFULL = 0x00000004,
STATUSBAR_NOSHRINK = 0x00000008,
STATUSBAR_NOFRAGBAR = 0x00000010,
STATUSBAR_NOOVERLAY = 0x00000020,
STATUSBAR_NOMODERN = 0x00000040,
};
void A_DeleteSprite(int spriteNum);
//static inline int32_t G_GetLogoFlags(void)
//{
// return 255;
//}
# define CAMERA(Membname) (ud.camera ## Membname)
# define CAMERADIST g_cameraDistance
# define CAMERACLOCK g_cameraClock
#endif
#define MAXSAVEGAMENAMESTRUCT 32
#define MAXSAVEGAMENAME (MAXSAVEGAMENAMESTRUCT-1)
#define MAXPWLOCKOUT 128
#define MAXRTSNAME 128
#define MAX_RETURN_VALUES 6
typedef struct {
vec3_t camerapos;
int32_t const_visibility,uw_framerate;
int32_t camera_time,folfvel,folavel,folx,foly,fola;
int32_t reccnt;
int32_t statusbarscale,weaponswitch; // JBF 20031125
int32_t statusbarmode;
int32_t noexits,automsg;
int32_t althud;
int32_t statusbarflags, statusbarrange;
int32_t entered_name,screen_tilting;
int32_t coop,screen_size,lockout,crosshair;
int32_t playerai,angleinterpolation;
int32_t respawn_monsters,respawn_items,respawn_inventory,recstat,monsters_off,brightness;
int32_t m_respawn_items,m_respawn_monsters,m_respawn_inventory,m_recstat,m_monsters_off;
int32_t ffire,m_player_skill,m_level_number,m_volume_number,multimode;
int32_t player_skill,level_number,volume_number,marker;
int32_t music_episode, music_level;
int32_t playerbest;
//int32_t returnvar[MAX_RETURN_VALUES-1];
uint32_t userbytever;
fix16_t cameraq16ang, cameraq16horiz;
int16_t camerasect;
int16_t pause_on,from_bonus;
int16_t camerasprite,last_camsprite;
int16_t last_level,secretlevel;
int8_t menutitle_pal, slidebar_palselected, slidebar_paldisabled;
struct {
int32_t AutoAim;
int32_t ShowOpponentWeapons;
} config;
char overhead_on,last_overhead,showweapons;
char god,warp_on,cashman,eog;
char scrollmode,noclip;
char display_bonus_screen;
char show_level_text;
uint8_t user_map;
uint8_t screenfade, menubackground;
uint8_t shadow_pal;
} user_defs;
extern user_defs ud;
#ifndef ONLY_USERDEFS
// this is checked against http://eduke32.com/VERSION
extern const char *s_buildDate;
extern char boardfilename[BMAX_PATH];
#define USERMAPMUSICFAKEVOLUME MAXVOLUMES
#define USERMAPMUSICFAKELEVEL (MAXLEVELS-1)
#define USERMAPMUSICFAKESLOT ((USERMAPMUSICFAKEVOLUME * MAXLEVELS) + USERMAPMUSICFAKELEVEL)
static inline int G_HaveUserMap(void)
{
return (boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0);
}
static inline int Menu_HaveUserMap(void)
{
return (boardfilename[0] != 0 && m_level_number == 7 && ud.m_volume_number == 0);
}
extern const char *defaultrtsfilename[GAMECOUNT];
extern const char *G_DefaultRtsFile(void);
#ifdef LEGACY_ROR
extern char ror_protectedsectors[MAXSECTORS];
#endif
extern int32_t g_Debug;
extern int32_t g_Shareware;
extern int32_t g_cameraClock;
extern int32_t g_cameraDistance;
extern int32_t g_crosshairSum;
extern int32_t g_doQuickSave;
extern int32_t g_levelTextTime;
extern int32_t g_quitDeadline;
extern int32_t g_restorePalette;
extern int32_t tempwallptr;
extern int32_t ticrandomseed;
extern int32_t vote_map;
extern int32_t voting;
//extern int8_t cheatbuf[MAXCHEATLEN],cheatbuflen;
int32_t A_CheckInventorySprite(spritetype *s);
int32_t A_InsertSprite(int16_t whatsect, int32_t s_x, int32_t s_y, int32_t s_z, int16_t s_pn, int8_t s_s, uint8_t s_xr,
uint8_t s_yr, int16_t s_a, int16_t s_ve, int16_t s_zv, int16_t s_ow, int16_t s_ss);
int A_Spawn(int spriteNum,int tileNum);
int G_DoMoveThings(void);
//int32_t G_EndOfLevel(void);
#ifdef YAX_ENABLE
void Yax_SetBunchZs(int32_t sectnum, int32_t cf, int32_t daz);
#else
#define Yax_SetBunchZs(sectnum, cf, daz)
#endif
void G_PostCreateGameState(void);
void A_SpawnCeilingGlass(int spriteNum,int sectNum,int glassCnt);
void A_SpawnGlass(int spriteNum,int glassCnt);
void A_SpawnRandomGlass(int spriteNum,int wallNum,int glassCnt);
void A_SpawnWallGlass(int spriteNum,int wallnum,int glassCnt);
void A_SpawnWallPopcorn(int spriteNum,int wallnum,int glassCnt);
void G_AddUserQuote(const char *daquote);
void G_BackToMenu(void);
void G_DumpDebugInfo(void);
const char* G_PrintYourTime(void);
const char* G_PrintParTime(void);
const char* G_PrintDesignerTime(void);
const char* G_PrintBestTime(void);
void G_BonusScreen(int32_t bonusonly);
void G_BonusScreenRRRA(int32_t bonusonly);
//void G_CheatGetInv(void);
void G_DisplayRest(int32_t smoothratio);
void G_DoSpriteAnimations(int32_t ourx, int32_t oury, int32_t ourz, int32_t oura, int32_t smoothratio);
void G_DrawBackground(void);
void G_DrawFrags(void);
void G_HandleMirror(int32_t x, int32_t y, int32_t z, fix16_t a, fix16_t horiz, int32_t smoothratio);
void G_DrawRooms(int32_t playerNum,int32_t smoothratio);
void G_DrawTXDigiNumZ(int32_t starttile,int32_t x,int32_t y,int32_t n,int32_t s,int32_t pal,int32_t cs,int32_t x1,int32_t y1,int32_t x2,int32_t y2,int32_t z);
void G_GameExit(const char *msg) ATTRIBUTE((noreturn));
void G_GameQuit(void);
void G_HandleLocalKeys(void);
void G_HandleSpecialKeys(void);
void G_PrintGameQuotes(int32_t snum);
//void G_SE40(int32_t smoothratio);
void G_UpdatePlayerFromMenu(void);
void P_DoQuote(int32_t q,DukePlayer_t *p);
void P_SetGamePalette(DukePlayer_t* player, uint32_t palid, ESetPalFlags flags);
void G_OnMotorcycle(DukePlayer_t *pPlayer, int spriteNum);
void G_OffMotorcycle(DukePlayer_t *pPlayer);
void G_OnBoat(DukePlayer_t *pPlayer, int spriteNum);
void G_OffBoat(DukePlayer_t *pPlayer);
// Cstat protection mask for (currently) spawned MASKWALL* sprites.
// TODO: look at more cases of cstat=(cstat&PROTECTED)|ADDED in A_Spawn()?
// 2048+(32+16)+8+4
#define SPAWN_PROTECT_CSTAT_MASK (CSTAT_SPRITE_NOSHADE|CSTAT_SPRITE_ALIGNMENT_SLAB|CSTAT_SPRITE_XFLIP|CSTAT_SPRITE_YFLIP);
void fadepal(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step);
//void fadepaltile(int32_t r,int32_t g,int32_t b,int32_t start,int32_t end,int32_t step,int32_t tile);
void G_InitTimer(int32_t ticspersec);
inline int32_t G_GetTeamPalette(int32_t team)
{
int8_t pal[] = { 3, 10, 11, 12 };
if ((unsigned)team >= ARRAY_SIZE(pal))
return 0;
return pal[team];
}
#define A_CheckSpriteFlags(spriteNum, iType) (((g_tile[sprite[spriteNum].picnum].flags^actor[spriteNum].flags) & iType) != 0)
// (unsigned)iPicnum check: AMC TC Rusty Nails, bayonet MG alt. fire, iPicnum == -1 (via aplWeaponShoots)
#define A_CheckSpriteTileFlags(iPicnum, iType) (((unsigned)iPicnum < MAXTILES) && (g_tile[iPicnum].flags & iType) != 0)
#define S_StopSound(num) S_StopEnvSound(num, -1)
extern int G_StartRTS(int lumpNum, int localPlayer);
extern void G_MaybeAllocPlayer(int32_t pnum);
static inline void G_HandleAsync(void)
{
handleevents();
Net_GetPackets();
}
static inline int32_t calc_smoothratio(ClockTicks totalclk, ClockTicks ototalclk)
{
if (!(((!g_netServer && ud.multimode < 2) && ((g_player[myconnectindex].ps->gm & MODE_MENU) == 0)) ||
(g_netServer || ud.multimode > 1) ||
ud.recstat == 2) ||
paused)
{
return 65536;
}
return CalcSmoothRatio(totalclk, ototalclk, REALGAMETICSPERSEC);
}
// sector effector lotags
enum
{
SE_0_ROTATING_SECTOR = 0,
SE_1_PIVOT = 1,
SE_2_EARTHQUAKE = 2,
SE_3_RANDOM_LIGHTS_AFTER_SHOT_OUT = 3,
SE_4_RANDOM_LIGHTS = 4,
SE_5 = 5,
SE_6_SUBWAY = 6,
// ^^ potentially incomplete substitution in code
// vv almost surely complete substitution
SE_7_TELEPORT = 7,
SE_8_UP_OPEN_DOOR_LIGHTS = 8,
SE_9_DOWN_OPEN_DOOR_LIGHTS = 9,
SE_10_DOOR_AUTO_CLOSE = 10,
SE_11_SWINGING_DOOR = 11,
SE_12_LIGHT_SWITCH = 12,
SE_13_EXPLOSIVE = 13,
SE_14_SUBWAY_CAR = 14,
SE_15_SLIDING_DOOR = 15,
SE_16_REACTOR = 16,
SE_17_WARP_ELEVATOR = 17,
SE_18_INCREMENTAL_SECTOR_RISE_FALL = 18,
SE_19_EXPLOSION_LOWERS_CEILING = 19,
SE_20_STRETCH_BRIDGE = 20,
SE_21_DROP_FLOOR = 21,
SE_22_TEETH_DOOR = 22,
SE_23_ONE_WAY_TELEPORT = 23,
SE_24_CONVEYOR = 24,
SE_25_PISTON = 25,
SE_26 = 26,
SE_27_DEMO_CAM = 27,
SE_28_LIGHTNING = 28,
SE_29_WAVES = 29,
SE_30_TWO_WAY_TRAIN = 30,
SE_31_FLOOR_RISE_FALL = 31,
SE_32_CEILING_RISE_FALL = 32,
SE_33_QUAKE_DEBRIS = 33,
SE_34 = 34, // XXX
SE_35 = 35, // XXX
SE_36_PROJ_SHOOTER = 36,
SE_49_POINT_LIGHT = 49,
SE_50_SPOT_LIGHT = 50,
SE_130 = 130,
SE_131 = 131,
};
// sector lotags
enum
{
ST_0_NO_EFFECT = 0,
ST_1_ABOVE_WATER = 1,
ST_2_UNDERWATER = 2,
ST_3 = 3,
// ^^^ maybe not complete substitution in code
ST_9_SLIDING_ST_DOOR = 9,
ST_15_WARP_ELEVATOR = 15,
ST_16_PLATFORM_DOWN = 16,
ST_17_PLATFORM_UP = 17,
ST_18_ELEVATOR_DOWN = 18,
ST_19_ELEVATOR_UP = 19,
ST_20_CEILING_DOOR = 20,
ST_21_FLOOR_DOOR = 21,
ST_22_SPLITTING_DOOR = 22,
ST_23_SWINGING_DOOR = 23,
ST_25_SLIDING_DOOR = 25,
ST_26_SPLITTING_ST_DOOR = 26,
ST_27_STRETCH_BRIDGE = 27,
ST_28_DROP_FLOOR = 28,
ST_29_TEETH_DOOR = 29,
ST_30_ROTATE_RISE_BRIDGE = 30,
ST_31_TWO_WAY_TRAIN = 31,
// left: ST 32767, 65534, 65535
};
static inline void G_NewGame_EnterLevel(void)
{
G_NewGame(ud.m_volume_number, m_level_number, ud.m_player_skill);
if (G_EnterLevel(MODE_GAME))
G_BackToMenu();
}
static inline int G_GetMusicIdx(const char *str)
{
int32_t lev, ep;
signed char b1, b2;
int numMatches = sscanf(str, "%c%d%c%d", &b1,&ep, &b2,&lev);
if (numMatches != 4 || Btoupper(b1) != 'E' || Btoupper(b2) != 'L')
return -1;
if ((unsigned)--lev >= MAXLEVELS || (unsigned)--ep >= MAXVOLUMES)
return -2;
return (ep * MAXLEVELS) + lev;
}
extern void G_PrintCurrentMusic(void);
#endif
END_DUKE_NS

2793
source/duke/src/gamedef.cpp Normal file

File diff suppressed because it is too large Load diff

354
source/duke/src/gamedef.h Normal file
View file

@ -0,0 +1,354 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef gamedef_h_
#define gamedef_h_
#include "actors.h"
#include "build.h" // hashtable_t
#include "cheats.h"
#include "common.h" // tokenlist
#include "player.h" // projectile_t
BEGIN_DUKE_NS
enum
{
LABEL_ANY = -1,
LABEL_DEFINE = 1,
LABEL_STATE = 2,
LABEL_ACTOR = 4,
LABEL_ACTION = 8,
LABEL_AI = 16,
LABEL_MOVE = 32,
LABEL_EVENT = 0x40,
};
#define LABEL_HASPARM2 1
#define LABEL_ISSTRING 2
// "magic" number for { and }, overrides line number in compiled code for later detection
#define VM_IFELSE_MAGIC 31337
#define VM_INSTMASK 0xfff
#define VM_DECODE_LINE_NUMBER(xxx) ((int)((xxx) >> 12))
#define C_CUSTOMERROR(Text, ...) \
do \
{ \
C_ReportError(-1); \
Printf("%s:%d: error: " Text "\n", g_scriptFileName, g_lineNumber, ##__VA_ARGS__); \
g_errorCnt++; \
} while (0)
#define C_CUSTOMWARNING(Text, ...) \
do \
{ \
C_ReportError(-1); \
Printf("%s:%d: warning: " Text "\n", g_scriptFileName, g_lineNumber, ##__VA_ARGS__); \
g_warningCnt++; \
} while (0)
extern intptr_t const * insptr;
extern void VM_ScriptInfo(intptr_t const *ptr, int range);
extern hashtable_t h_gamevars;
extern hashtable_t h_labels;
extern int32_t g_aimAngleVarID; // var ID of "AUTOAIMANGLE"
extern int32_t g_angRangeVarID; // var ID of "ANGRANGE"
extern int32_t g_returnVarID; // var ID of "RETURN"
extern int32_t g_weaponVarID; // var ID of "WEAPON"
extern int32_t g_worksLikeVarID; // var ID of "WORKSLIKE"
extern int32_t g_zRangeVarID; // var ID of "ZRANGE"
#include "events_defs.h"
extern intptr_t apScriptEvents[MAXEVENTS];
extern char g_scriptFileName[BMAX_PATH];
extern const uint32_t CheatFunctionFlags[];
extern const uint8_t CheatFunctionIDs[];
extern int32_t g_errorCnt;
extern int32_t g_lineNumber;
extern int32_t g_scriptVersion;
extern int32_t g_totalLines;
extern int32_t g_warningCnt;
extern uint32_t g_scriptcrc;
extern int32_t otherp;
extern intptr_t *g_scriptPtr;
typedef struct
{
const char *name;
int lId, flags, maxParm2;
} memberlabel_t;
extern const memberlabel_t ActorLabels[];
extern const memberlabel_t InputLabels[];
extern const memberlabel_t PalDataLabels[];
extern const memberlabel_t PlayerLabels[];
extern const memberlabel_t ProjectileLabels[];
extern const memberlabel_t SectorLabels[];
extern const memberlabel_t TileDataLabels[];
extern const memberlabel_t TsprLabels[];
extern const memberlabel_t UserdefsLabels[];
extern const memberlabel_t WallLabels[];
int32_t C_AllocQuote(int32_t qnum);
void C_InitQuotes(void);
extern int32_t g_numProjectiles;
typedef struct {
int spriteNum;
int playerNum;
int playerDist;
int flags;
union {
spritetype * pSprite;
uspritetype *pUSprite;
};
int32_t * pData;
DukePlayer_t *pPlayer;
actor_t * pActor;
} vmstate_t;
extern vmstate_t vm;
void G_DoGameStartup(const int32_t *params);
void C_DefineMusic(int volumeNum, int levelNum, const char *fileName);
void C_DefineVolumeFlags(int32_t vol, int32_t flags);
void C_UndefineVolume(int32_t vol);
void C_UndefineSkill(int32_t skill);
void C_UndefineLevel(int32_t vol, int32_t lev);
void C_ReportError(int32_t iError);
void C_Compile(const char *filenam);
extern int32_t g_errorLineNum;
extern int32_t g_tw;
typedef struct {
const char* token;
int32_t val;
} tokenmap_t;
extern char const * VM_GetKeywordForID(int32_t id);
enum ScriptError_t
{
ERROR_CLOSEBRACKET,
ERROR_EXCEEDSMAXTILES,
ERROR_EXPECTEDKEYWORD,
ERROR_FOUNDWITHIN,
ERROR_ISAKEYWORD,
ERROR_OPENBRACKET,
ERROR_NOTAGAMEVAR,
ERROR_PARAMUNDEFINED,
ERROR_SYNTAXERROR,
ERROR_VARREADONLY,
ERROR_VARTYPEMISMATCH,
WARNING_BADGAMEVAR,
WARNING_DUPLICATEDEFINITION,
WARNING_LABELSONLY,
WARNING_VARMASKSKEYWORD,
};
enum ScriptKeywords_t
{
CON_ELSE, // 0
CON_ACTOR, // 1
CON_ADDAMMO, // 2
CON_IFRND, // 3
CON_ENDA, // 4
CON_IFCANSEE, // 5
CON_IFHITWEAPON, // 6
CON_ACTION, // 7
CON_IFPDISTL, // 8
CON_IFPDISTG, // 9
CON_DEFINELEVELNAME, // 10
CON_STRENGTH, // 11
CON_BREAK, // 12
CON_SHOOT, // 13
CON_PALFROM, // 14
CON_SOUND, // 15
CON_FALL, // 16
CON_STATE, // 17
CON_ENDS, // 18
CON_DEFINE, // 19
CON_COMMENT, // 20 deprecated
CON_IFAI, // 21
CON_KILLIT, // 22
CON_ADDWEAPON, // 23
CON_AI, // 24
CON_ADDPHEALTH, // 25
CON_IFDEAD, // 26
CON_IFSQUISHED, // 27
CON_SIZETO, // 28
CON_LEFTBRACE, // 29
CON_RIGHTBRACE, // 30
CON_SPAWN, // 31
CON_MOVE, // 32
CON_IFWASWEAPON, // 33
CON_IFACTION, // 34
CON_IFACTIONCOUNT, // 35
CON_RESETACTIONCOUNT, // 36
CON_DEBRIS, // 37
CON_PSTOMP, // 38
CON_BLOCKCOMMENT, // 39 deprecated
CON_CSTAT, // 40
CON_IFMOVE, // 41
CON_RESETPLAYER, // 42
CON_IFONWATER, // 43
CON_IFINWATER, // 44
CON_IFCANSHOOTTARGET, // 45
CON_IFCOUNT, // 46
CON_RESETCOUNT, // 47
CON_ADDINVENTORY, // 48
CON_IFACTORNOTSTAYPUT, // 49
CON_HITRADIUS, // 50
CON_IFP, // 51
CON_COUNT, // 52
CON_IFACTOR, // 53
CON_MUSIC, // 54
CON_INCLUDE, // 55
CON_IFSTRENGTH, // 56
CON_DEFINESOUND, // 57
CON_GUTS, // 58
CON_IFSPAWNEDBY, // 59
CON_GAMESTARTUP, // 60
CON_WACKPLAYER, // 61
CON_IFGAPZL, // 62
CON_IFHITSPACE, // 63
CON_IFOUTSIDE, // 64
CON_IFMULTIPLAYER, // 65
CON_OPERATE, // 66
CON_IFINSPACE, // 67
CON_DEBUG, // 68
CON_ENDOFGAME, // 69
CON_IFBULLETNEAR, // 70
CON_IFRESPAWN, // 71
CON_IFFLOORDISTL, // 72
CON_IFCEILINGDISTL, // 73
CON_SPRITEPAL, // 74
CON_IFPINVENTORY, // 75
CON_BETANAME, // 76
CON_CACTOR, // 77
CON_IFPHEALTHL, // 78
CON_DEFINEQUOTE, // 79
CON_QUOTE, // 80
CON_IFINOUTERSPACE, // 81
CON_IFNOTMOVING, // 82
CON_RESPAWNHITAG, // 83
CON_TIP, // 84
CON_IFSPRITEPAL, // 85
CON_MONEY, // 86
CON_SOUNDONCE, // 87
CON_ADDKILLS, // 88
CON_STOPSOUND, // 89
CON_IFAWAYFROMWALL, // 90
CON_IFCANSEETARGET, // 91
CON_GLOBALSOUND, // 92
CON_LOTSOFGLASS, // 93
CON_IFGOTWEAPONCE, // 94
CON_GETLASTPAL, // 95
CON_PKICK, // 96
CON_MIKESND, // 97
CON_USERACTOR, // 98
CON_SIZEAT, // 99
CON_ADDSTRENGTH, // 100
CON_CSTATOR, // 101
CON_MAIL, // 102
CON_PAPER, // 103
CON_TOSSWEAPON, // 104
CON_SLEEPTIME, // 105
CON_NULLOP, // 106
CON_DEFINEVOLUMENAME, // 107
CON_DEFINESKILLNAME, // 108
CON_IFNOSOUNDS, // 109
CON_CLIPDIST, // 110
CON_IFANGDIFFL, // 111
CON_IFNOCOVER, // 112
CON_IFHITTRUCK, // 113
CON_IFTIPCOW, // 114
CON_ISDRUNK, // 115
CON_ISEAT, // 116
CON_DESTROYIT, // 117
CON_LARRYBIRD, // 118
CON_STRAFELEFT, // 119
CON_STRAFERIGHT, // 120
CON_IFACTORHEALTHG, // 121
CON_IFACTORHEALTHL, // 122
CON_SLAPPLAYER, // 123
CON_IFPDRUNK, // 124
CON_TEARITUP, // 125
CON_SMACKBUBBA, // 126
CON_SOUNDTAGONCE, // 127
CON_SOUNDTAG, // 128
CON_IFSOUNDID, // 129
CON_IFSOUNDDIST, // 130
CON_IFONMUD, // 131
CON_IFCOOP, // 132
CON_IFMOTOFAST, // 133
CON_IFWIND, // 134
CON_SMACKSPRITE, // 135
CON_IFONMOTO, // 136
CON_IFONBOAT, // 137
CON_FAKEBUBBA, // 138
CON_MAMATRIGGER, // 139
CON_MAMASPAWN, // 140
CON_MAMAQUAKE, // 141
CON_MAMAEND, // 142
CON_NEWPIC, // 143
CON_GARYBANJO, // 144
CON_MOTOLOOPSND, // 145
CON_IFSIZEDOWN, // 146
CON_RNDMOVE, // 147
CON_GAMEVAR, // 148
CON_IFVARL, // 149
CON_IFVARG, // 150
CON_SETVARVAR, // 151
CON_SETVAR, // 152
CON_ADDVARVAR, // 153
CON_ADDVAR, // 154
CON_IFVARVARL, // 155
CON_IFVARVARG, // 156
CON_ADDLOGVAR, // 157
CON_ONEVENT, // 158
CON_ENDEVENT, // 159
CON_IFVARE, // 160
CON_IFVARVARE, // 161
CON_IFFINDNEWSPOT, // 162
CON_LEAVETRAX, // 163
CON_LEAVEDROPPINGS, // 164
CON_DEPLOYBIAS, // 165
CON_IFPUPWIND, // 166
CON_END
};
END_DUKE_NS
#endif // gamedef_h_

View file

2988
source/duke/src/gameexec.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,95 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef gameexec_h_
#define gameexec_h_
#include "build.h"
#include "sector.h" // mapstate_t
#include "gamedef.h" // vmstate_t
BEGIN_DUKE_NS
int32_t VM_ExecuteEvent(int const nEventID, int const spriteNum, int const playerNum, int const nDist, int32_t const nReturn);
int32_t VM_ExecuteEvent(int const nEventID, int const spriteNum, int const playerNum, int const nDist);
int32_t VM_ExecuteEvent(int const nEventID, int const spriteNum, int const playerNum);
int32_t VM_ExecuteEventWithValue(int const nEventID, int const spriteNum, int const playerNum, int32_t const nReturn);
static FORCE_INLINE int VM_HaveEvent(int const nEventID)
{
return !!apScriptEvents[nEventID];
}
static FORCE_INLINE int32_t VM_OnEvent(int nEventID, int spriteNum, int playerNum, int nDist, int32_t nReturn)
{
return VM_HaveEvent(nEventID) ? VM_ExecuteEvent(nEventID, spriteNum, playerNum, nDist, nReturn) : nReturn;
}
static FORCE_INLINE int32_t VM_OnEvent(int nEventID, int spriteNum, int playerNum, int nDist)
{
return VM_HaveEvent(nEventID) ? VM_ExecuteEvent(nEventID, spriteNum, playerNum, nDist) : 0;
}
static FORCE_INLINE int32_t VM_OnEvent(int nEventID, int spriteNum = -1, int playerNum = -1)
{
return VM_HaveEvent(nEventID) ? VM_ExecuteEvent(nEventID, spriteNum, playerNum) : 0;
}
static FORCE_INLINE int32_t VM_OnEventWithReturn(int nEventID, int spriteNum, int playerNum, int32_t nReturn)
{
return VM_HaveEvent(nEventID) ? VM_ExecuteEventWithValue(nEventID, spriteNum, playerNum, nReturn) : nReturn;
}
extern int32_t ticrandomseed;
extern vmstate_t vm;
extern int32_t g_tw;
extern int32_t g_currentEvent;
extern int32_t g_errorLineNum;
extern uint32_t g_actorCalls[MAXTILES];
extern double g_actorTotalMs[MAXTILES], g_actorMinMs[MAXTILES], g_actorMaxMs[MAXTILES];
void A_Execute(int spriteNum, int playerNum, int playerDist);
void A_Fall(int spriteNum);
int32_t A_GetFurthestAngle(int spriteNum, int angDiv);
void A_GetZLimits(int spriteNum);
int32_t __fastcall G_GetAngleDelta(int32_t currAngle, int32_t newAngle);
fix16_t __fastcall G_GetQ16AngleDelta(fix16_t oldAngle, fix16_t newAngle);
//void G_RestoreMapState();
//void G_SaveMapState();
#define CON_ERRPRINTF(Text, ...) do { \
Printf("Line %d, %s: " Text, g_errorLineNum, VM_GetKeywordForID(g_tw), ## __VA_ARGS__); \
} while (0)
#define CON_CRITICALERRPRINTF(Text, ...) do { \
I_Error("Line %d, %s: " Text, VM_DECODE_LINE_NUMBER(g_tw), VM_GetKeywordForID(VM_DECODE_INST(g_tw)), ## __VA_ARGS__); \
} while (0)
void G_GetTimeDate(int32_t * pValues);
int G_StartTrack(int levelNum);
void VM_UpdateAnim(int spriteNum, int32_t *pData);
END_DUKE_NS
#endif

View file

@ -0,0 +1,830 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "duke3d.h"
#include "menus.h"
#include "savegame.h"
#include "namesdyn.h"
#include "gamevars.h"
//#include "vfs.h"
BEGIN_DUKE_NS
#define gamevars_c_
gamevar_t aGameVars[MAXGAMEVARS];
int32_t g_gameVarCount = 0;
// pointers to weapon gamevar data
intptr_t *aplWeaponClip[MAX_WEAPONS]; // number of items in magazine
intptr_t *aplWeaponFireDelay[MAX_WEAPONS]; // delay to fire
intptr_t *aplWeaponFireSound[MAX_WEAPONS]; // Sound made when firing (each time for automatic)
intptr_t *aplWeaponFlags[MAX_WEAPONS]; // Flags for weapon
intptr_t *aplWeaponFlashColor[MAX_WEAPONS]; // Muzzle flash color
intptr_t *aplWeaponHoldDelay[MAX_WEAPONS]; // delay after release fire button to fire (0 for none)
intptr_t *aplWeaponInitialSound[MAX_WEAPONS]; // Sound made when weapon starts firing. zero for no sound
intptr_t *aplWeaponReload[MAX_WEAPONS]; // delay to reload (include fire)
intptr_t *aplWeaponShoots[MAX_WEAPONS]; // what the weapon shoots
intptr_t *aplWeaponShotsPerBurst[MAX_WEAPONS]; // number of shots per 'burst' (one ammo per 'burst')
intptr_t *aplWeaponSound2Sound[MAX_WEAPONS]; // Alternate sound sound ID
intptr_t *aplWeaponSound2Time[MAX_WEAPONS]; // Alternate sound time
intptr_t *aplWeaponSpawn[MAX_WEAPONS]; // the item to spawn
intptr_t *aplWeaponSpawnTime[MAX_WEAPONS]; // the frame at which to spawn an item
intptr_t *aplWeaponTotalTime[MAX_WEAPONS]; // The total time the weapon is cycling before next fire.
intptr_t *aplWeaponWorksLike[MAX_WEAPONS]; // What original the weapon works like
// Frees the memory for the *values* of game variables and arrays. Resets their
// counts to zero. Call this function as many times as needed.
//
// Returns: old g_gameVarCount | (g_gameArrayCount<<16).
int Gv_Free(void)
{
for (auto &gameVar : aGameVars)
{
if (gameVar.flags & GAMEVAR_USER_MASK)
ALIGNED_FREE_AND_NULL(gameVar.pValues);
gameVar.flags |= GAMEVAR_RESET;
}
EDUKE32_STATIC_ASSERT(MAXGAMEVARS < 32768);
int const varCount = g_gameVarCount;
g_gameVarCount = 0;
hash_init(&h_gamevars);
return varCount;
}
// Calls Gv_Free() and in addition frees the labels of all game variables and
// arrays.
// Only call this function at exit
void Gv_Clear(void)
{
Gv_Free();
// Now, only do work that Gv_Free() hasn't done.
for (auto & gameVar : aGameVars)
DO_FREE_AND_NULL(gameVar.szLabel);
}
// Note that this entire function is totally architecture dependent and needs to be fixed (which won't be easy...)
int Gv_ReadSave(FileReader &kFile)
{
char tbuf[12];
if (kFile.Read(tbuf, 12)!=12) goto corrupt;
if (Bmemcmp(tbuf, "BEG: EDuke32", 12)) { Printf("BEG ERR\n"); return 2; }
Gv_Free(); // nuke 'em from orbit, it's the only way to be sure...
if (kFile.Read(&g_gameVarCount,sizeof(g_gameVarCount)) != sizeof(g_gameVarCount)) goto corrupt;
for (bssize_t i=0; i<g_gameVarCount; i++)
{
char *const olabel = aGameVars[i].szLabel;
if (kFile.Read(&aGameVars[i], sizeof(gamevar_t)) != sizeof(gamevar_t))
goto corrupt;
aGameVars[i].szLabel = (char *)Xrealloc(olabel, MAXVARLABEL * sizeof(uint8_t));
if (kFile.Read(aGameVars[i].szLabel, MAXVARLABEL) != MAXVARLABEL)
goto corrupt;
hash_add(&h_gamevars, aGameVars[i].szLabel,i, 1);
if (aGameVars[i].flags & GAMEVAR_PERPLAYER)
{
aGameVars[i].pValues = (intptr_t*)Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
if (kFile.Read(aGameVars[i].pValues,sizeof(intptr_t) * MAXPLAYERS) != sizeof(intptr_t) * MAXPLAYERS) goto corrupt;
}
else if (aGameVars[i].flags & GAMEVAR_PERACTOR)
{
aGameVars[i].pValues = (intptr_t*)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
if (kFile.Read(aGameVars[i].pValues,sizeof(intptr_t) * MAXSPRITES) != sizeof(intptr_t) * MAXSPRITES) goto corrupt;
}
}
Gv_InitWeaponPointers();
// Gv_RefreshPointers();
uint8_t savedstate[MAXVOLUMES*MAXLEVELS];
Bmemset(savedstate, 0, sizeof(savedstate));
if (kFile.Read(savedstate, sizeof(savedstate)) != sizeof(savedstate)) goto corrupt;
for (bssize_t i = 0; i < (MAXVOLUMES * MAXLEVELS); i++)
{
G_FreeMapState(i);
if (!savedstate[i])
continue;
g_mapInfo[i].savedstate = (mapstate_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, sizeof(mapstate_t));
if (kFile.Read(g_mapInfo[i].savedstate, sizeof(mapstate_t)) != sizeof(mapstate_t)) return -8;
mapstate_t &sv = *g_mapInfo[i].savedstate;
for (bssize_t j = 0; j < g_gameVarCount; j++)
{
if (aGameVars[j].flags & GAMEVAR_NORESET) continue;
if (aGameVars[j].flags & GAMEVAR_PERPLAYER)
{
sv.vars[j] = (intptr_t *) Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
if (kFile.Read(sv.vars[j], sizeof(intptr_t) * MAXPLAYERS) != sizeof(intptr_t) * MAXPLAYERS) return -9;
}
else if (aGameVars[j].flags & GAMEVAR_PERACTOR)
{
sv.vars[j] = (intptr_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
if (kFile.Read(sv.vars[j], sizeof(intptr_t) * MAXSPRITES) != sizeof(intptr_t) * MAXSPRITES) return -10;
}
}
}
if (kFile.Read(tbuf, 12) != 12) return -13;
if (Bmemcmp(tbuf, "EOF: EDuke32", 12)) { Printf("EOF ERR\n"); return 2; }
return 0;
corrupt:
return -7;
}
// Note that this entire function is totally architecture dependent and needs to be fixed (which won't be easy...)
void Gv_WriteSave(FileWriter &fil)
{
// AddLog("Saving Game Vars to File");
fil.Write("BEG: EDuke32", 12);
fil.Write(&g_gameVarCount,sizeof(g_gameVarCount));
for (bssize_t i = 0; i < g_gameVarCount; i++)
{
fil.Write(&(aGameVars[i]), sizeof(gamevar_t));
fil.Write(aGameVars[i].szLabel, sizeof(uint8_t) * MAXVARLABEL);
if (aGameVars[i].flags & GAMEVAR_PERPLAYER)
fil.Write(aGameVars[i].pValues, sizeof(intptr_t) * MAXPLAYERS);
else if (aGameVars[i].flags & GAMEVAR_PERACTOR)
fil.Write(aGameVars[i].pValues, sizeof(intptr_t) * MAXSPRITES);
}
uint8_t savedstate[MAXVOLUMES * MAXLEVELS];
Bmemset(savedstate, 0, sizeof(savedstate));
for (bssize_t i = 0; i < (MAXVOLUMES * MAXLEVELS); i++)
if (g_mapInfo[i].savedstate != NULL)
savedstate[i] = 1;
fil.Write(savedstate, sizeof(savedstate));
for (bssize_t i = 0; i < (MAXVOLUMES * MAXLEVELS); i++)
{
if (!savedstate[i]) continue;
mapstate_t &sv = *g_mapInfo[i].savedstate;
fil.Write(g_mapInfo[i].savedstate, sizeof(mapstate_t));
for (bssize_t j = 0; j < g_gameVarCount; j++)
{
if (aGameVars[j].flags & GAMEVAR_NORESET) continue;
if (aGameVars[j].flags & GAMEVAR_PERPLAYER)
fil.Write(sv.vars[j], sizeof(intptr_t) * MAXPLAYERS);
else if (aGameVars[j].flags & GAMEVAR_PERACTOR)
fil.Write(sv.vars[j], sizeof(intptr_t) * MAXSPRITES);
}
}
fil.Write("EOF: EDuke32", 12);
}
void Gv_DumpValues(void)
{
buildprint("// Current Game Definitions\n\n");
for (bssize_t i=0; i<g_gameVarCount; i++)
{
buildprint("gamevar ", aGameVars[i].szLabel, " ");
if (aGameVars[i].flags & (GAMEVAR_INT32PTR))
buildprint(*(int32_t *)aGameVars[i].global);
else if (aGameVars[i].flags & (GAMEVAR_INT16PTR))
buildprint(*(int16_t *)aGameVars[i].global);
else
buildprint(aGameVars[i].global);
if (aGameVars[i].flags & (GAMEVAR_PERPLAYER))
buildprint(" GAMEVAR_PERPLAYER");
else if (aGameVars[i].flags & (GAMEVAR_PERACTOR))
buildprint(" GAMEVAR_PERACTOR");
else
buildprint(" ", aGameVars[i].flags/* & (GAMEVAR_USER_MASK)*/);
buildprint(" // ");
if (aGameVars[i].flags & (GAMEVAR_SYSTEM))
buildprint(" (system)");
if (aGameVars[i].flags & (GAMEVAR_PTR_MASK))
buildprint(" (pointer)");
if (aGameVars[i].flags & (GAMEVAR_READONLY))
buildprint(" (read only)");
if (aGameVars[i].flags & (GAMEVAR_SPECIAL))
buildprint(" (special)");
buildprint("\n");
}
buildprint("\n// end of game definitions\n");
}
// XXX: This function is very strange.
void Gv_ResetVars(void) /* this is called during a new game and nowhere else */
{
Gv_Free();
for (auto &aGameVar : aGameVars)
{
if (aGameVar.szLabel != NULL)
Gv_NewVar(aGameVar.szLabel, (aGameVar.flags & GAMEVAR_NODEFAULT) ? aGameVar.global : aGameVar.defaultValue, aGameVar.flags);
}
}
void Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags)
{
if (EDUKE32_PREDICT_FALSE(g_gameVarCount >= MAXGAMEVARS))
{
g_errorCnt++;
C_ReportError(-1);
Printf("%s:%d: error: too many gamevars!\n",g_scriptFileName,g_lineNumber);
return;
}
if (EDUKE32_PREDICT_FALSE(Bstrlen(pszLabel) > (MAXVARLABEL-1)))
{
g_errorCnt++;
C_ReportError(-1);
Printf("%s:%d: error: variable name `%s' exceeds limit of %d characters.\n",g_scriptFileName,g_lineNumber,pszLabel, MAXVARLABEL);
return;
}
int gV = hash_find(&h_gamevars,pszLabel);
if (gV >= 0 && !(aGameVars[gV].flags & GAMEVAR_RESET))
{
// found it...
if (EDUKE32_PREDICT_FALSE(aGameVars[gV].flags & (GAMEVAR_PTR_MASK)))
{
C_ReportError(-1);
Printf("%s:%d: warning: cannot redefine internal gamevar `%s'.\n",g_scriptFileName,g_lineNumber,label+(g_labelCnt<<6));
return;
}
else if (EDUKE32_PREDICT_FALSE(!(aGameVars[gV].flags & GAMEVAR_SYSTEM)))
{
// it's a duplicate in error
g_warningCnt++;
C_ReportError(WARNING_DUPLICATEDEFINITION);
return;
}
}
if (gV == -1)
gV = g_gameVarCount;
// If it's a user gamevar...
if ((aGameVars[gV].flags & GAMEVAR_SYSTEM) == 0)
{
// Allocate and set its label
if (aGameVars[gV].szLabel == NULL)
aGameVars[gV].szLabel = (char *)Xcalloc(MAXVARLABEL,sizeof(uint8_t));
if (aGameVars[gV].szLabel != pszLabel)
Bstrcpy(aGameVars[gV].szLabel,pszLabel);
// and the flags
aGameVars[gV].flags=dwFlags;
// only free if per-{actor,player}
if (aGameVars[gV].flags & GAMEVAR_USER_MASK)
ALIGNED_FREE_AND_NULL(aGameVars[gV].pValues);
}
// if existing is system, they only get to change default value....
aGameVars[gV].defaultValue = lValue;
aGameVars[gV].flags &= ~GAMEVAR_RESET;
if (gV == g_gameVarCount)
{
// we're adding a new one.
hash_add(&h_gamevars, aGameVars[gV].szLabel, g_gameVarCount++, 0);
}
// Set initial values. (Or, override values for system gamevars.)
if (aGameVars[gV].flags & GAMEVAR_PERPLAYER)
{
if (!aGameVars[gV].pValues)
{
aGameVars[gV].pValues = (intptr_t *) Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
Bmemset(aGameVars[gV].pValues, 0, MAXPLAYERS * sizeof(intptr_t));
}
for (bssize_t j=MAXPLAYERS-1; j>=0; --j)
aGameVars[gV].pValues[j]=lValue;
}
else if (aGameVars[gV].flags & GAMEVAR_PERACTOR)
{
if (!aGameVars[gV].pValues)
{
aGameVars[gV].pValues = (intptr_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
Bmemset(aGameVars[gV].pValues, 0, MAXSPRITES * sizeof(intptr_t));
}
for (bssize_t j=MAXSPRITES-1; j>=0; --j)
aGameVars[gV].pValues[j]=lValue;
}
else aGameVars[gV].global = lValue;
}
static int Gv_GetVarIndex(const char *szGameLabel)
{
int const gameVar = hash_find(&h_gamevars,szGameLabel);
if (EDUKE32_PREDICT_FALSE((unsigned)gameVar >= MAXGAMEVARS))
{
Printf(TEXTCOLOR_RED "Gv_GetVarIndex(): INTERNAL ERROR: couldn't find gamevar %s!\n", szGameLabel);
return 0;
}
return gameVar;
}
static FORCE_INLINE int __fastcall getvar__(int const gameVar, int const spriteNum, int const playerNum)
{
auto const &var = aGameVars[gameVar & (MAXGAMEVARS-1)];
int returnValue = 0;
int const varFlags = var.flags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
if (!varFlags) returnValue = var.global;
else if (varFlags == GAMEVAR_PERACTOR)
returnValue = var.pValues[spriteNum & (MAXSPRITES-1)];
else if (varFlags == GAMEVAR_PERPLAYER)
returnValue = var.pValues[playerNum & (MAXPLAYERS-1)];
else switch (varFlags & GAMEVAR_PTR_MASK)
{
case GAMEVAR_RAWQ16PTR:
case GAMEVAR_INT32PTR: returnValue = *(int32_t *)var.global; break;
case GAMEVAR_INT16PTR: returnValue = *(int16_t *)var.global; break;
case GAMEVAR_Q16PTR: returnValue = fix16_to_int(*(fix16_t *)var.global); break;
}
return NEGATE_ON_CONDITION(returnValue, gameVar & GV_FLAG_NEGATIVE);
}
int __fastcall Gv_GetVar(int const gameVar, int const spriteNum, int const playerNum) { return getvar__(gameVar, spriteNum, playerNum); }
int __fastcall Gv_GetVar(int const gameVar) { return getvar__(gameVar, vm.spriteNum, vm.playerNum); }
void __fastcall Gv_GetManyVars(int const numVars, int32_t * const outBuf)
{
for (native_t j = 0; j < numVars; ++j)
outBuf[j] = getvar__(*insptr++, vm.spriteNum, vm.playerNum);
}
static FORCE_INLINE void __fastcall setvar__(int const gameVar, int const newValue, int const spriteNum, int const playerNum)
{
gamevar_t &var = aGameVars[gameVar];
int const varFlags = var.flags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
if (!varFlags) var.global=newValue;
else if (varFlags == GAMEVAR_PERACTOR)
var.pValues[spriteNum & (MAXSPRITES-1)] = newValue;
else if (varFlags == GAMEVAR_PERPLAYER)
var.pValues[playerNum & (MAXPLAYERS-1)] = newValue;
else switch (varFlags & GAMEVAR_PTR_MASK)
{
case GAMEVAR_RAWQ16PTR:
case GAMEVAR_INT32PTR: *((int32_t *)var.global) = (int32_t)newValue; break;
case GAMEVAR_INT16PTR: *((int16_t *)var.global) = (int16_t)newValue; break;
case GAMEVAR_Q16PTR: *(fix16_t *)var.global = fix16_from_int((int16_t)newValue); break;
}
return;
}
void __fastcall Gv_SetVar(int const gameVar, int const newValue) { setvar__(gameVar, newValue, vm.spriteNum, vm.playerNum); }
void __fastcall Gv_SetVar(int const gameVar, int const newValue, int const spriteNum, int const playerNum)
{
setvar__(gameVar, newValue, spriteNum, playerNum);
}
int Gv_GetVarByLabel(const char *szGameLabel, int const defaultValue, int const spriteNum, int const playerNum)
{
int const gameVar = hash_find(&h_gamevars, szGameLabel);
return EDUKE32_PREDICT_TRUE(gameVar >= 0) ? Gv_GetVar(gameVar, spriteNum, playerNum) : defaultValue;
}
static intptr_t *Gv_GetVarDataPtr(const char *szGameLabel)
{
int const gameVar = hash_find(&h_gamevars, szGameLabel);
if (EDUKE32_PREDICT_FALSE((unsigned)gameVar >= MAXGAMEVARS))
return NULL;
gamevar_t &var = aGameVars[gameVar];
if (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK))
return var.pValues;
return &(var.global);
}
void Gv_ResetSystemDefaults(void)
{
// call many times...
char aszBuf[64];
//AddLog("ResetWeaponDefaults");
for (int weaponNum = 0; weaponNum < MAX_WEAPONS; ++weaponNum)
{
for (int playerNum = 0; playerNum < MAXPLAYERS; ++playerNum)
{
Bsprintf(aszBuf, "WEAPON%d_CLIP", weaponNum);
aplWeaponClip[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_RELOAD", weaponNum);
aplWeaponReload[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_FIREDELAY", weaponNum);
aplWeaponFireDelay[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_TOTALTIME", weaponNum);
aplWeaponTotalTime[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_HOLDDELAY", weaponNum);
aplWeaponHoldDelay[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_FLAGS", weaponNum);
aplWeaponFlags[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_SHOOTS", weaponNum);
aplWeaponShoots[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
if ((unsigned)aplWeaponShoots[weaponNum][playerNum] >= MAXTILES)
aplWeaponShoots[weaponNum][playerNum] = 0;
Bsprintf(aszBuf, "WEAPON%d_SPAWNTIME", weaponNum);
aplWeaponSpawnTime[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_SPAWN", weaponNum);
aplWeaponSpawn[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_SHOTSPERBURST", weaponNum);
aplWeaponShotsPerBurst[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_WORKSLIKE", weaponNum);
aplWeaponWorksLike[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_INITIALSOUND", weaponNum);
aplWeaponInitialSound[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_FIRESOUND", weaponNum);
aplWeaponFireSound[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_SOUND2TIME", weaponNum);
aplWeaponSound2Time[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_SOUND2SOUND", weaponNum);
aplWeaponSound2Sound[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
Bsprintf(aszBuf, "WEAPON%d_FLASHCOLOR", weaponNum);
aplWeaponFlashColor[weaponNum][playerNum] = Gv_GetVarByLabel(aszBuf, 0, -1, playerNum);
}
}
g_aimAngleVarID = Gv_GetVarIndex("AUTOAIMANGLE");
g_angRangeVarID = Gv_GetVarIndex("ANGRANGE");
g_returnVarID = Gv_GetVarIndex("RETURN");
g_weaponVarID = Gv_GetVarIndex("WEAPON");
g_worksLikeVarID = Gv_GetVarIndex("WORKSLIKE");
g_zRangeVarID = Gv_GetVarIndex("ZRANGE");
//AddLog("EOF:ResetWeaponDefaults");
}
// Will set members that were overridden at CON translation time to 1.
// For example, if
// gamevar WEAPON1_SHOOTS 2200 GAMEVAR_PERPLAYER
// was specified at file scope, g_weaponOverridden[1].Shoots will be 1.
weapondata_t g_weaponOverridden[MAX_WEAPONS];
static weapondata_t weapondefaults[MAX_WEAPONS] = {
/*
WorksLike, Clip, Reload, FireDelay, TotalTime, HoldDelay,
Flags,
Shoots, SpawnTime, Spawn, ShotsPerBurst, InitialSound, FireSound, Sound2Time, Sound2Sound,
FlashColor
*/
{
KNEE_WEAPON__STATIC, 0, 30, 7, 14, 14,
WEAPON_RANDOMRESTART | WEAPON_AUTOMATIC,
KNEE__STATIC, 0, 0, 0, 0, 0, 0,
0
},
{
PISTOL_WEAPON, 20, 50, 2, 5, 0,
WEAPON_AUTOMATIC | WEAPON_HOLSTER_CLEARS_CLIP,
SHOTSPARK1__STATIC, 2, SHELL__STATIC, 0, 0, PISTOL_FIRE__STATIC, 0, 0,
255+(95<<8)
},
{
SHOTGUN_WEAPON__STATIC, 0, 13, 4, 31, 0,
WEAPON_CHECKATRELOAD,
SHOTGUN__STATIC, 24, SHOTGUNSHELL__STATIC, 7, 0, SHOTGUN_FIRE__STATIC, 15, SHOTGUN_COCK__STATIC,
255+(95<<8)
},
{
CHAINGUN_WEAPON__STATIC, 0, 30, 1, 12, 10,
WEAPON_AUTOMATIC | WEAPON_FIREEVERYTHIRD | WEAPON_AMMOPERSHOT,
CHAINGUN__STATIC, 0, SHELL__STATIC, 0, 0, CHAINGUN_FIRE__STATIC, 0, 0,
255+(95<<8)
},
{
RPG_WEAPON__STATIC, 0, 30, 4, 20, 0,
0,
RPG__STATIC, 0, 0, 0, 0, 0, 0, 0,
255+(95<<8)
},
{
HANDBOMB_WEAPON__STATIC, 0, 30, 6, 19, 12,
WEAPON_THROWIT,
HEAVYHBOMB__STATIC, 0, 0, 0, 0, 0, 0,
0
},
{
SHRINKER_WEAPON__STATIC, 0, 0, 10, 30, 0,
WEAPON_GLOWS,
SHRINKER__STATIC, 0, 0, 0, SHRINKER_FIRE__STATIC, 0, 0, 0,
176+(252<<8)+(120<<16)
},
{
DEVISTATOR_WEAPON__STATIC, 0, 30, 2, 5, 5,
WEAPON_FIREEVERYOTHER,
RPG__STATIC, 0, 0, 2, CAT_FIRE__STATIC, 0, 0, 0,
255+(95<<8)
},
{
TRIPBOMB_WEAPON__STATIC, 0, 30, 3, 16, 0,
WEAPON_STANDSTILL,
HANDHOLDINGLASER__STATIC, 0, 0, 0, 0, 0, 0,
0
},
{
FREEZE_WEAPON__STATIC, 0, 0, 3, 5, 0,
WEAPON_FIREEVERYOTHER,
FREEZEBLAST__STATIC, 0, 0, 0, CAT_FIRE__STATIC, CAT_FIRE__STATIC, 0, 0,
72+(88<<8)+(140<<16)
},
{
HANDREMOTE_WEAPON__STATIC, 0, 30, 2, 10, 0,
WEAPON_BOMB_TRIGGER | WEAPON_NOVISIBLE,
0, 0, 0, 0, 0, 0, 0,
0
},
{
GROW_WEAPON__STATIC, 0, 0, 3, 30, 0,
WEAPON_GLOWS,
GROWSPARK__STATIC, 0, 0, 0, EXPANDERSHOOT__STATIC, EXPANDERSHOOT__STATIC, 0, 0,
216+(52<<8)+(20<<16)
},
};
// KEEPINSYNC with what is contained above
// XXX: ugly
static int32_t G_StaticToDynamicTile(int32_t const tile)
{
switch (tile)
{
#ifndef EDUKE32_STANDALONE
case CHAINGUN__STATIC: return CHAINGUN;
case FREEZEBLAST__STATIC: return FREEZEBLAST;
case GROWSPARK__STATIC: return GROWSPARK;
case HANDHOLDINGLASER__STATIC: return HANDHOLDINGLASER;
case HEAVYHBOMB__STATIC: return HEAVYHBOMB;
case KNEE__STATIC: return KNEE;
case RPG__STATIC: return RPG;
case SHELL__STATIC: return SHELL;
case SHOTGUNSHELL__STATIC: return SHOTGUNSHELL;
case SHOTGUN__STATIC: return SHOTGUN;
case SHOTSPARK1__STATIC: return SHOTSPARK1;
case SHRINKER__STATIC: return SHRINKER;
#endif
default: return tile;
}
}
static int32_t G_StaticToDynamicSound(int32_t const sound)
{
switch (sound)
{
#ifndef EDUKE32_STANDALONE
case CAT_FIRE__STATIC: return CAT_FIRE;
case CHAINGUN_FIRE__STATIC: return CHAINGUN_FIRE;
case EJECT_CLIP__STATIC: return EJECT_CLIP;
case EXPANDERSHOOT__STATIC: return EXPANDERSHOOT;
case INSERT_CLIP__STATIC: return INSERT_CLIP;
case PISTOL_FIRE__STATIC: return PISTOL_FIRE;
case SELECT_WEAPON__STATIC: return SELECT_WEAPON;
case SHOTGUN_FIRE__STATIC: return SHOTGUN_FIRE;
case SHOTGUN_COCK__STATIC: return SHOTGUN_COCK;
case SHRINKER_FIRE__STATIC: return SHRINKER_FIRE;
#endif
default: return sound;
}
}
// Initialize WEAPONx_* gamevars. In C-CON, a new CON variable is defined together with
// its initial value.
# define ADDWEAPONVAR(Weapidx, Membname) do { \
FStringf aszBuf("WEAPON%d_" #Membname, Weapidx); \
aszBuf.ToUpper(); \
Gv_NewVar(aszBuf, weapondefaults[Weapidx].Membname, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM); \
} while (0)
// After CON translation, get not-overridden members from weapondefaults[] back
// into the live arrays!
// NYI
# define POSTADDWEAPONVAR(Weapidx, Membname) do {} while (0)
// Finish a default weapon member after CON translation. If it was not
// overridden from CON itself (see example at g_weaponOverridden[]), we set
// both the weapondefaults[] entry (probably dead by now) and the live value.
#define FINISH_WEAPON_DEFAULT_X(What, i, Membname) do { \
if (!g_weaponOverridden[i].Membname) \
{ \
weapondefaults[i].Membname = G_StaticToDynamic##What(weapondefaults[i].Membname); \
POSTADDWEAPONVAR(i, Membname); \
} \
} while (0)
#define FINISH_WEAPON_DEFAULT_TILE(i, Membname) FINISH_WEAPON_DEFAULT_X(Tile, i, Membname)
#define FINISH_WEAPON_DEFAULT_SOUND(i, Membname) FINISH_WEAPON_DEFAULT_X(Sound, i, Membname)
// Process the dynamic {tile,sound} mappings after CON has been translated.
// We cannot do this before, because the dynamic maps are not yet set up then.
void Gv_FinalizeWeaponDefaults(void)
{
for (int i=0; i<MAX_WEAPONS; i++)
{
FINISH_WEAPON_DEFAULT_TILE(i, Shoots);
FINISH_WEAPON_DEFAULT_TILE(i, Spawn);
FINISH_WEAPON_DEFAULT_SOUND(i, InitialSound);
FINISH_WEAPON_DEFAULT_SOUND(i, FireSound);
FINISH_WEAPON_DEFAULT_SOUND(i, Sound2Sound);
}
}
#undef FINISH_WEAPON_DEFAULT_SOUND
#undef FINISH_WEAPON_DEFAULT_TILE
#undef FINISH_WEAPON_DEFAULT_X
#undef POSTADDWEAPONVAR
static int32_t lastvisinc;
static void Gv_AddSystemVars(void)
{
// only call ONCE
for (int i=0; i<MAX_WEAPONS; i++)
{
ADDWEAPONVAR(i, Clip);
ADDWEAPONVAR(i, FireDelay);
ADDWEAPONVAR(i, FireSound);
ADDWEAPONVAR(i, Flags);
ADDWEAPONVAR(i, FlashColor);
ADDWEAPONVAR(i, HoldDelay);
ADDWEAPONVAR(i, InitialSound);
ADDWEAPONVAR(i, Reload);
ADDWEAPONVAR(i, Shoots);
ADDWEAPONVAR(i, ShotsPerBurst);
ADDWEAPONVAR(i, Sound2Sound);
ADDWEAPONVAR(i, Sound2Time);
ADDWEAPONVAR(i, Spawn);
ADDWEAPONVAR(i, SpawnTime);
ADDWEAPONVAR(i, TotalTime);
ADDWEAPONVAR(i, WorksLike);
}
Gv_NewVar("GRENADE_LIFETIME", NAM_GRENADE_LIFETIME, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
Gv_NewVar("GRENADE_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
Gv_NewVar("STICKYBOMB_LIFETIME", NAM_GRENADE_LIFETIME, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
Gv_NewVar("STICKYBOMB_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
Gv_NewVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
Gv_NewVar("ANGRANGE", 18, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
Gv_NewVar("AUTOAIMANGLE", 0, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
Gv_NewVar("COOP", (intptr_t)&ud.coop, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("FFIRE", (intptr_t)&ud.ffire, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("LEVEL", (intptr_t)&ud.level_number, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR | GAMEVAR_READONLY);
Gv_NewVar("MARKER", (intptr_t)&ud.marker, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("MONSTERS_OFF", (intptr_t)&ud.monsters_off, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("MULTIMODE", (intptr_t)&ud.multimode, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("RESPAWN_INVENTORY", (intptr_t)&ud.respawn_inventory, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("RESPAWN_ITEMS", (intptr_t)&ud.respawn_items, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("RESPAWN_MONSTERS", (intptr_t)&ud.respawn_monsters, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("RETURN", 0, GAMEVAR_SYSTEM);
Gv_NewVar("VOLUME", (intptr_t)&ud.volume_number, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR | GAMEVAR_READONLY);
Gv_NewVar("WEAPON", 0, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER | GAMEVAR_READONLY);
Gv_NewVar("WORKSLIKE", 0, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER | GAMEVAR_READONLY);
Gv_NewVar("ZRANGE", 4, GAMEVAR_SYSTEM | GAMEVAR_PERPLAYER);
}
#undef ADDWEAPONVAR
void Gv_Init(void)
{
// already initialized
if (aGameVars[0].flags)
return;
// Set up weapon defaults, g_playerWeapon[][].
Gv_AddSystemVars();
Gv_InitWeaponPointers();
}
void Gv_InitWeaponPointers(void)
{
char aszBuf[64];
// called from game Init AND when level is loaded...
//AddLog("Gv_InitWeaponPointers");
for (int i=(MAX_WEAPONS-1); i>=0; i--)
{
Bsprintf(aszBuf, "WEAPON%d_CLIP", i);
aplWeaponClip[i] = Gv_GetVarDataPtr(aszBuf);
if (!aplWeaponClip[i])
{
I_Error("ERROR: NULL weapon! WTF?! %s\n", aszBuf);
}
Bsprintf(aszBuf, "WEAPON%d_RELOAD", i);
aplWeaponReload[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_FIREDELAY", i);
aplWeaponFireDelay[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_TOTALTIME", i);
aplWeaponTotalTime[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_HOLDDELAY", i);
aplWeaponHoldDelay[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_FLAGS", i);
aplWeaponFlags[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_SHOOTS", i);
aplWeaponShoots[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_SPAWNTIME", i);
aplWeaponSpawnTime[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_SPAWN", i);
aplWeaponSpawn[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_SHOTSPERBURST", i);
aplWeaponShotsPerBurst[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_WORKSLIKE", i);
aplWeaponWorksLike[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_INITIALSOUND", i);
aplWeaponInitialSound[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_FIRESOUND", i);
aplWeaponFireSound[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_SOUND2TIME", i);
aplWeaponSound2Time[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_SOUND2SOUND", i);
aplWeaponSound2Sound[i] = Gv_GetVarDataPtr(aszBuf);
Bsprintf(aszBuf, "WEAPON%d_FLASHCOLOR", i);
aplWeaponFlashColor[i] = Gv_GetVarDataPtr(aszBuf);
}
}
void Gv_RefreshPointers(void)
{
aGameVars[Gv_GetVarIndex("COOP")].global = (intptr_t)&ud.coop;
aGameVars[Gv_GetVarIndex("FFIRE")].global = (intptr_t)&ud.ffire;
aGameVars[Gv_GetVarIndex("LEVEL")].global = (intptr_t)&ud.level_number;
aGameVars[Gv_GetVarIndex("MARKER")].global = (intptr_t)&ud.marker;
aGameVars[Gv_GetVarIndex("MONSTERS_OFF")].global = (intptr_t)&ud.monsters_off;
aGameVars[Gv_GetVarIndex("MULTIMODE")].global = (intptr_t)&ud.multimode;
aGameVars[Gv_GetVarIndex("RESPAWN_INVENTORY")].global = (intptr_t)&ud.respawn_inventory;
aGameVars[Gv_GetVarIndex("RESPAWN_ITEMS")].global = (intptr_t)&ud.respawn_items;
aGameVars[Gv_GetVarIndex("RESPAWN_MONSTERS")].global = (intptr_t)&ud.respawn_monsters;
aGameVars[Gv_GetVarIndex("VOLUME")].global = (intptr_t)&ud.volume_number;
}
END_DUKE_NS

151
source/duke/src/gamevars.h Normal file
View file

@ -0,0 +1,151 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef gamevars_h_
#define gamevars_h_
#include "gamedef.h"
BEGIN_DUKE_NS
#define MAXGAMEVARS 2048 // must be a power of two
#define MAXVARLABEL 26
#define GV_FLAG_CONSTANT (MAXGAMEVARS)
#define GV_FLAG_NEGATIVE (MAXGAMEVARS<<1)
// store global game definitions
enum GamevarFlags_t
{
GAMEVAR_PERPLAYER = 0x00000001, // per-player variable
GAMEVAR_PERACTOR = 0x00000002, // per-actor variable
GAMEVAR_USER_MASK = (GAMEVAR_PERPLAYER | GAMEVAR_PERACTOR),
GAMEVAR_RESET = 0x00000008, // INTERNAL, don't use
GAMEVAR_DEFAULT = 0x00000100, // UNUSED, but always cleared for user-defined gamevars
GAMEVAR_NODEFAULT = 0x00000400, // don't reset on actor spawn
GAMEVAR_SYSTEM = 0x00000800, // cannot change mode flags...(only default value)
GAMEVAR_READONLY = 0x00001000, // values are read-only (no setvar allowed)
GAMEVAR_INT32PTR = 0x00002000, // plValues is a pointer to an int32_t
GAMEVAR_INT16PTR = 0x00008000, // plValues is a pointer to a short
GAMEVAR_NORESET = 0x00020000, // var values are not reset when restoring map state
GAMEVAR_SPECIAL = 0x00040000, // flag for structure member shortcut vars
GAMEVAR_NOMULTI = 0x00080000, // don't attach to multiplayer packets
GAMEVAR_Q16PTR = 0x00100000, // plValues is a pointer to a q16.16
GAMEVAR_SERIALIZE = 0x00200000, // write into permasaves
GAMEVAR_RAWQ16PTR = GAMEVAR_Q16PTR | GAMEVAR_SPECIAL, // plValues is a pointer to a q16.16 but we don't want conversion
GAMEVAR_PTR_MASK = GAMEVAR_INT32PTR | GAMEVAR_INT16PTR | GAMEVAR_Q16PTR | GAMEVAR_RAWQ16PTR,
};
// Alignments for per-player and per-actor variables.
#define PLAYER_VAR_ALIGNMENT (sizeof(intptr_t))
#define ACTOR_VAR_ALIGNMENT 16
#define ARRAY_ALIGNMENT 16
#pragma pack(push,1)
typedef struct
{
union {
intptr_t global;
intptr_t *pValues; // array of values when 'per-player', or 'per-actor'
};
intptr_t defaultValue;
uintptr_t flags;
char * szLabel;
} gamevar_t;
#pragma pack(pop)
extern gamevar_t aGameVars[MAXGAMEVARS];
extern int32_t g_gameVarCount;
int __fastcall Gv_GetVar(int const gameVar, int const spriteNum, int const playerNum);
void __fastcall Gv_SetVar(int const gameVar, int const newValue, int const spriteNum, int const playerNum);
int __fastcall Gv_GetVar(int const gameVar);
void __fastcall Gv_GetManyVars(int const numVars, int32_t * const outBuf);
void __fastcall Gv_SetVar(int const gameVar, int const newValue);
template <typename T>
static FORCE_INLINE void Gv_FillWithVars(T & rv)
{
EDUKE32_STATIC_ASSERT(sizeof(T) % sizeof(int32_t) == 0);
EDUKE32_STATIC_ASSERT(sizeof(T) > sizeof(int32_t));
Gv_GetManyVars(sizeof(T)/sizeof(int32_t), (int32_t *)&rv);
}
int Gv_GetVarByLabel(const char *szGameLabel,int defaultValue,int spriteNum,int playerNum);
void Gv_NewVar(const char *pszLabel,intptr_t lValue,uint32_t dwFlags);
static FORCE_INLINE void A_ResetVars(int const spriteNum)
{
for (auto &gv : aGameVars)
{
if ((gv.flags & (GAMEVAR_PERACTOR|GAMEVAR_NODEFAULT)) == GAMEVAR_PERACTOR)
gv.pValues[spriteNum] = gv.defaultValue;
}
}
void Gv_DumpValues(void);
void Gv_InitWeaponPointers(void);
void Gv_RefreshPointers(void);
void Gv_ResetVars(void);
int Gv_ReadSave(FileReader &kFile);
void Gv_WriteSave(FileWriter &fil);
void Gv_Clear(void);
void Gv_ResetSystemDefaults(void);
void Gv_Init(void);
void Gv_FinalizeWeaponDefaults(void);
#define VM_GAMEVAR_OPERATOR(func, operator) \
static FORCE_INLINE ATTRIBUTE((flatten)) void __fastcall func(int const id, int32_t const operand) \
{ \
auto &var = aGameVars[id]; \
\
switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) \
{ \
default: \
var.global operator operand; \
break; \
case GAMEVAR_PERPLAYER: \
var.pValues[vm.playerNum & (MAXPLAYERS-1)] operator operand; \
break; \
case GAMEVAR_PERACTOR: \
var.pValues[vm.spriteNum & (MAXSPRITES-1)] operator operand; \
break; \
case GAMEVAR_INT32PTR: *(int32_t *)var.pValues operator(int32_t) operand; break; \
case GAMEVAR_INT16PTR: *(int16_t *)var.pValues operator(int16_t) operand; break; \
case GAMEVAR_Q16PTR: \
{ \
Fix16 *pfix = (Fix16 *)var.global; \
*pfix operator fix16_from_int(operand); \
break; \
} \
} \
}
VM_GAMEVAR_OPERATOR(Gv_AddVar, +=)
VM_GAMEVAR_OPERATOR(Gv_SubVar, -=)
#undef VM_GAMEVAR_OPERATOR
END_DUKE_NS
#endif

123
source/duke/src/global.cpp Normal file
View file

@ -0,0 +1,123 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#define global_c_
#include "global.h"
#include "duke3d.h"
BEGIN_DUKE_NS
user_defs ud;
const char *s_buildDate = "20120522";
char g_gametypeNames[MAXGAMETYPES][33]
= { "DukeMatch (Spawn)", "Cooperative Play", "DukeMatch (No Spawn)", "Team DM (Spawn)", "Team DM (No Spawn)" };
int32_t g_gametypeFlags[MAXGAMETYPES] =
{
GAMETYPE_FRAGBAR |
GAMETYPE_SCORESHEET |
GAMETYPE_DMSWITCHES |
GAMETYPE_ITEMRESPAWN |
GAMETYPE_MARKEROPTION |
GAMETYPE_ACCESSATSTART,
GAMETYPE_COOP |
GAMETYPE_WEAPSTAY |
GAMETYPE_COOPSPAWN |
GAMETYPE_ACCESSCARDSPRITES |
GAMETYPE_COOPVIEW |
GAMETYPE_COOPSOUND |
GAMETYPE_OTHERPLAYERSINMAP |
GAMETYPE_PLAYERSFRIENDLY |
GAMETYPE_FIXEDRESPAWN |
GAMETYPE_PRESERVEINVENTORYDEATH,
GAMETYPE_WEAPSTAY |
GAMETYPE_FRAGBAR |
GAMETYPE_SCORESHEET |
GAMETYPE_DMSWITCHES |
GAMETYPE_ACCESSATSTART,
GAMETYPE_FRAGBAR |
GAMETYPE_SCORESHEET |
GAMETYPE_DMSWITCHES |
GAMETYPE_ITEMRESPAWN |
GAMETYPE_MARKEROPTION |
GAMETYPE_ACCESSATSTART |
GAMETYPE_TDM |
GAMETYPE_TDMSPAWN,
GAMETYPE_WEAPSTAY |
GAMETYPE_FRAGBAR |
GAMETYPE_SCORESHEET |
GAMETYPE_DMSWITCHES |
GAMETYPE_ACCESSATSTART |
GAMETYPE_TDM |
GAMETYPE_TDMSPAWN,
};
float g_gameUpdateAvgTime = -1.f;
int32_t g_actorRespawnTime = 768;
int32_t g_bouncemineRadius = 2500;
int32_t g_deleteQueueSize = 64;
int32_t g_itemRespawnTime = 768;
int32_t g_morterRadius = 2500;
int32_t g_numFreezeBounces = 3;
int32_t g_gametypeCnt = 5;
int32_t g_volumeCnt = 3;
int32_t g_pipebombRadius = 2500;
int32_t g_playerFriction = 0xCFD0;
int32_t g_rpgRadius = 1780;
int32_t g_scriptSize = 1048576;
int32_t g_seenineRadius = 2048;
int32_t g_shrinkerRadius = 650;
int32_t g_spriteGravity = 176;
int32_t g_timerTicsPerSecond = TICRATE;
int32_t g_tripbombRadius = 3880;
int16_t g_blimpSpawnItems[15] =
{
RPGSPRITE__STATIC,
CHAINGUNSPRITE__STATIC,
DEVISTATORAMMO__STATIC,
RPGAMMO__STATIC,
RPGAMMO__STATIC,
JETPACK__STATIC,
SHIELD__STATIC,
FIRSTAID__STATIC,
STEROIDS__STATIC,
RPGAMMO__STATIC,
RPGAMMO__STATIC,
RPGSPRITE__STATIC,
RPGAMMO__STATIC,
FREEZESPRITE__STATIC,
FREEZEAMMO__STATIC
};
char CheatKeys[2] = { sc_D, sc_N };
END_DUKE_NS

311
source/duke/src/global.h Normal file
View file

@ -0,0 +1,311 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef global_h_
#define global_h_
#include "build.h"
#include "compat.h"
#include "duke3d.h"
#include "mmulti.h"
#include "quotes.h"
#include "sector.h"
#include "sounds.h"
BEGIN_DUKE_NS
#define MAXMINECARTS 16
#define MAXJAILDOORS 32
#define MAXLIGHTNINSECTORS 64
#define MAXTORCHSECTORS 64
#define MAXGEOSECTORS 64
#ifdef global_c_
#define G_EXTERN
#else
#define G_EXTERN extern
#endif
#define MAXINTERPOLATIONS MAXSPRITES
// duke3d global soup :(
G_EXTERN int32_t g_interpolationCnt;
G_EXTERN int32_t g_interpolationLock;
G_EXTERN int32_t oldipos[MAXINTERPOLATIONS];
G_EXTERN int32_t *curipos[MAXINTERPOLATIONS];
G_EXTERN int32_t bakipos[MAXINTERPOLATIONS];
G_EXTERN int32_t duke3d_globalflags;
// KEEPINSYNC astub.c (used values only)
enum DUKE3D_GLOBALFLAGS {
DUKE3D_NO_WIDESCREEN_PINNING = 1<<0,
DUKE3D_NO_HARDCODED_FOGPALS = 1<<1,
DUKE3D_NO_PALETTE_CHANGES = 1<<2,
};
G_EXTERN DukeStatus_t sbar;
G_EXTERN actor_t actor[MAXSPRITES];
// g_tile: tile-specific data THAT DOES NOT CHANGE during the course of a game
G_EXTERN tiledata_t g_tile[MAXTILES];
G_EXTERN animwalltype animwall[MAXANIMWALLS];
G_EXTERN char *label;
G_EXTERN char g_loadFromGroupOnly;
G_EXTERN char g_skillCnt;
G_EXTERN char pus,pub;
G_EXTERN char ready2send;
#define MAXPLAYERNAME 32
G_EXTERN char tempbuf[MAXSECTORS<<1],buf[1024];
G_EXTERN uint8_t packbuf[PACKBUF_SIZE];
G_EXTERN input_t localInput;
G_EXTERN input_t recsync[RECSYNCBUFSIZ];
//G_EXTERN uint8_t syncstat, syncval[MAXPLAYERS][MOVEFIFOSIZ];
//G_EXTERN int32_t syncvalhead[MAXPLAYERS], syncvaltail, syncvaltottail;
G_EXTERN int32_t avgfvel, avgsvel, avgbits;
G_EXTERN fix16_t avgavel, avghorz;
G_EXTERN int8_t avgextbits;
G_EXTERN int32_t movefifosendplc;
G_EXTERN int32_t movefifoplc;
G_EXTERN int32_t predictfifoplc;
G_EXTERN vec3_t mypos, omypos, myvel;
G_EXTERN fix16_t myhoriz, omyhoriz, myhorizoff, omyhorizoff, myang, omyang;
G_EXTERN int16_t mycursectnum, myjumpingcounter;
G_EXTERN uint8_t myjumpingtoggle, myonground, myhardlanding, myreturntocenter;
G_EXTERN int16_t my_moto_speed;
G_EXTERN uint8_t my_not_on_water, my_moto_on_ground;
G_EXTERN uint8_t my_moto_do_bump, my_moto_bump_fast, my_moto_on_oil, my_moto_on_mud;
G_EXTERN int16_t my_moto_bump, my_moto_bump_target, my_moto_turb;
G_EXTERN int32_t my_stairs;
G_EXTERN vec3_t myposbak[MOVEFIFOSIZ];
G_EXTERN fix16_t myhorizbak[MOVEFIFOSIZ], myangbak[MOVEFIFOSIZ];
G_EXTERN int32_t myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter;
G_EXTERN int32_t g_networkBroadcastMode, g_movesPerPacket;
G_EXTERN int32_t g_animWallCnt;
G_EXTERN int32_t g_animateCnt;
G_EXTERN int32_t g_cloudCnt;
G_EXTERN int32_t g_curViewscreen;
G_EXTERN int32_t g_frameRate;
G_EXTERN int32_t g_cyclerCnt;
G_EXTERN int32_t g_damageCameras;
G_EXTERN int32_t g_defaultLabelCnt;
G_EXTERN int32_t g_doQuickSave;
G_EXTERN int32_t g_earthquakeTime;
G_EXTERN int32_t g_freezerSelfDamage;
G_EXTERN int32_t g_gameQuit;
G_EXTERN int32_t g_globalRandom;
G_EXTERN int32_t g_impactDamage;
G_EXTERN int32_t g_labelCnt;
G_EXTERN int32_t g_maxPlayerHealth;
G_EXTERN int32_t g_mirrorCount;
G_EXTERN int32_t g_mostConcurrentPlayers;
G_EXTERN int32_t g_musicSize;
G_EXTERN int32_t g_playerSpawnCnt;
G_EXTERN int32_t g_scriptDebug;
G_EXTERN int32_t g_showShareware;
G_EXTERN int32_t g_spriteDeleteQueuePos;
G_EXTERN int32_t g_startArmorAmount;
G_EXTERN int32_t g_tripbombLaserMode;
G_EXTERN int32_t screenpeek;
G_EXTERN int16_t g_animateSect[MAXANIMATES];
G_EXTERN int32_t *g_animatePtr[MAXANIMATES];
G_EXTERN int32_t g_animateGoal[MAXANIMATES];
G_EXTERN int32_t g_animateVel[MAXANIMATES];
G_EXTERN int16_t g_cloudSect[256];
G_EXTERN int16_t g_cloudX;
G_EXTERN int16_t g_cloudY;
G_EXTERN ClockTicks g_cloudClock;
G_EXTERN int16_t SpriteDeletionQueue[1024];
G_EXTERN int16_t g_cyclers[MAXCYCLERS][6];
G_EXTERN int16_t g_mirrorSector[64];
G_EXTERN int16_t g_mirrorWall[64];
G_EXTERN int32_t *labelcode;
G_EXTERN int32_t *labeltype;
G_EXTERN ClockTicks lockclock;
G_EXTERN ClockTicks ototalclock;
G_EXTERN int32_t g_wupass;
G_EXTERN int32_t g_chickenPlant;
G_EXTERN int32_t g_thunderOn;
G_EXTERN int32_t g_ufoSpawn;
G_EXTERN int32_t g_ufoCnt;
G_EXTERN int32_t g_hulkSpawn;
G_EXTERN int32_t g_vixenLevel;
G_EXTERN int32_t g_lastLevel;
G_EXTERN int32_t g_turdLevel;
G_EXTERN int32_t g_mineCartDir[MAXMINECARTS];
G_EXTERN int32_t g_mineCartSpeed[MAXMINECARTS];
G_EXTERN int32_t g_mineCartChildSect[MAXMINECARTS];
G_EXTERN int32_t g_mineCartSound[MAXMINECARTS];
G_EXTERN int32_t g_mineCartDist[MAXMINECARTS];
G_EXTERN int32_t g_mineCartDrag[MAXMINECARTS];
G_EXTERN int32_t g_mineCartOpen[MAXMINECARTS];
G_EXTERN int32_t g_mineCartSect[MAXMINECARTS];
G_EXTERN uint32_t g_mineCartCnt;
G_EXTERN int32_t g_jailDoorSound[MAXJAILDOORS];
G_EXTERN int32_t g_jailDoorDrag[MAXJAILDOORS];
G_EXTERN int32_t g_jailDoorSpeed[MAXJAILDOORS];
G_EXTERN int32_t g_jailDoorSecHitag[MAXJAILDOORS];
G_EXTERN int32_t g_jailDoorDist[MAXJAILDOORS];
G_EXTERN int32_t g_jailDoorDir[MAXJAILDOORS];
G_EXTERN int32_t g_jailDoorOpen[MAXJAILDOORS];
G_EXTERN int32_t g_jailDoorSect[MAXJAILDOORS];
G_EXTERN uint32_t g_jailDoorCnt;
G_EXTERN int32_t g_lightninSector[MAXLIGHTNINSECTORS];
G_EXTERN int32_t g_lightninSectorShade[MAXLIGHTNINSECTORS];
G_EXTERN uint32_t g_lightninCnt;
G_EXTERN int32_t g_torchSector[MAXTORCHSECTORS];
G_EXTERN int32_t g_torchSectorShade[MAXTORCHSECTORS];
G_EXTERN int32_t g_torchType[MAXTORCHSECTORS];
G_EXTERN uint32_t g_torchCnt;
G_EXTERN int32_t g_geoSectorWarp[MAXGEOSECTORS];
G_EXTERN int32_t g_geoSectorWarp2[MAXGEOSECTORS];
G_EXTERN int32_t g_geoSector[MAXGEOSECTORS];
G_EXTERN int32_t g_geoSectorX[MAXGEOSECTORS];
G_EXTERN int32_t g_geoSectorY[MAXGEOSECTORS];
G_EXTERN int32_t g_geoSectorX2[MAXGEOSECTORS];
G_EXTERN int32_t g_geoSectorY2[MAXGEOSECTORS];
G_EXTERN uint32_t g_geoSectorCnt;
G_EXTERN int32_t g_thunderFlash;
G_EXTERN int32_t g_thunderTime;
G_EXTERN int32_t g_winderFlash;
G_EXTERN int32_t g_winderTime;
G_EXTERN int32_t g_brightness;
G_EXTERN int16_t g_ambientLotag[64];
G_EXTERN int16_t g_ambientHitag[64];
G_EXTERN uint32_t g_ambientCnt;
G_EXTERN intptr_t *apScript;
G_EXTERN intptr_t *g_scriptPtr;
G_EXTERN map_t g_mapInfo[(MAXVOLUMES + 1) * MAXLEVELS]; // +1 volume for "intro", "briefing" and "loading" music
G_EXTERN vec2_t g_origins[MAXANIMPOINTS];
G_EXTERN int32_t g_windTime, g_windDir;
G_EXTERN int16_t g_fakeBubbaCnt, g_mamaSpawnCnt, g_banjoSong, g_bellTime, g_bellSprite;
G_EXTERN uint8_t g_spriteExtra[MAXSPRITES], g_sectorExtra[MAXSECTORS];
G_EXTERN uint8_t g_changeEnemySize, g_slotWin, g_ufoSpawnMinion, g_pistonSound, g_chickenWeaponTimer, g_RAendLevel, g_RAendEpisode, g_fogType;
G_EXTERN int32_t g_cdTrack;
// XXX: I think this pragma pack is meaningless here.
// MSDN (https://msdn.microsoft.com/en-us/library/2e70t5y1%28VS.80%29.aspx) says:
// "pack takes effect at the first struct, union, or class declaration after
// the pragma is seen; pack has no effect on definitions."
#pragma pack(push,1)
#ifdef global_c_
static playerdata_t g_player_s[1 + MAXPLAYERS];
playerdata_t *const g_player = &g_player_s[1];
#else
extern playerdata_t *const g_player;
#endif
G_EXTERN playerspawn_t g_playerSpawnPoints[MAXPLAYERS];
G_EXTERN input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
#pragma pack(pop)
G_EXTERN int32_t g_noEnemies;
G_EXTERN int32_t g_restorePalette;
G_EXTERN uint32_t everyothertime;
G_EXTERN uint32_t g_moveThingsCount;
G_EXTERN double g_gameUpdateTime;
G_EXTERN double g_gameUpdateAndDrawTime;
#define GAMEUPDATEAVGTIMENUMSAMPLES 100
extern float g_gameUpdateAvgTime;
#ifndef global_c_
extern char CheatKeys[2];
extern char g_gametypeNames[MAXGAMETYPES][33];
extern int32_t g_actorRespawnTime;
extern int32_t g_bouncemineRadius;
extern int32_t g_deleteQueueSize;
extern int32_t g_gametypeCnt;
extern int32_t g_itemRespawnTime;
extern int32_t g_morterRadius;
extern int32_t g_numFreezeBounces;
extern int32_t g_pipebombRadius;
extern int32_t g_playerFriction;
extern int32_t g_rpgRadius;
extern int32_t g_scriptSize;
extern int32_t g_seenineRadius;
extern int32_t g_shrinkerRadius;
extern int32_t g_spriteGravity;
extern int32_t g_timerTicsPerSecond;
extern int32_t g_tripbombRadius;
extern int32_t g_volumeCnt;
extern int16_t g_blimpSpawnItems[15];
extern int32_t g_gametypeFlags[MAXGAMETYPES];
extern const char *s_buildDate;
#endif
enum
{
EF_HIDEFROMSP = 1<<0,
};
EXTERN_INLINE_HEADER void G_UpdateInterpolations(void);
EXTERN_INLINE_HEADER void G_RestoreInterpolations(void);
#if defined global_c_ || !defined DISABLE_INLINING
EXTERN_INLINE void G_UpdateInterpolations(void) //Stick at beginning of G_DoMoveThings
{
for (bssize_t i=g_interpolationCnt-1; i>=0; i--) oldipos[i] = *curipos[i];
}
EXTERN_INLINE void G_RestoreInterpolations(void) //Stick at end of drawscreen
{
int32_t i=g_interpolationCnt-1;
if (--g_interpolationLock)
return;
for (; i>=0; i--) *curipos[i] = bakipos[i];
}
#endif
END_DUKE_NS
#endif

61
source/duke/src/inv.h Normal file
View file

@ -0,0 +1,61 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
BEGIN_DUKE_NS
enum dukeinv_t
{
GET_STEROIDS, // 0
GET_SHIELD,
GET_SCUBA,
GET_HOLODUKE,
GET_JETPACK,
GET_DUMMY1, // 5
GET_ACCESS,
GET_HEATS,
GET_DUMMY2,
GET_FIRSTAID,
GET_BOOTS, // 10
GET_MAX
};
// these are not in the same order as the above, and it can't be changed for compat reasons. lame!
enum dukeinvicon_t
{
ICON_NONE, // 0
ICON_FIRSTAID,
ICON_STEROIDS,
ICON_HOLODUKE,
ICON_JETPACK,
ICON_HEATS, // 5
ICON_SCUBA,
ICON_BOOTS,
ICON_MAX
};
extern int const icon_to_inv[ICON_MAX];
extern int const inv_to_icon[GET_MAX];
END_DUKE_NS

153
source/duke/src/keys.h Normal file
View file

@ -0,0 +1,153 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef KEYS_H
BEGIN_DUKE_NS
#define KEYS_H
#define NUM_CODES 128
#define ESC 0x1B
#define ENTER 0x0D
#define KEYSC_ESC 0x01
#define KEYSC_1 0x02
#define KEYSC_2 0x03
#define KEYSC_3 0x04
#define KEYSC_4 0x05
#define KEYSC_5 0x06
#define KEYSC_6 0x07
#define KEYSC_7 0x08
#define KEYSC_8 0x09
#define KEYSC_9 0x0a
#define KEYSC_0 0x0b
#define KEYSC_DASH 0x0c
#define KEYSC_EQUAL 0x0d
#define KEYSC_BS 0x0e
#define KEYSC_TAB 0x0f
#define KEYSC_Q 0x10
#define KEYSC_W 0x11
#define KEYSC_E 0x12
#define KEYSC_R 0x13
#define KEYSC_T 0x14
#define KEYSC_Y 0x15
#define KEYSC_U 0x16
#define KEYSC_I 0x17
#define KEYSC_O 0x18
#define KEYSC_P 0x19
#define KEYSC_LBRACK 0x1a
#define KEYSC_RBRACK 0x1b
#define KEYSC_ENTER 0x1c
#define KEYSC_LCTRL 0x1d
#define KEYSC_A 0x1e
#define KEYSC_S 0x1f
#define KEYSC_D 0x20
#define KEYSC_F 0x21
#define KEYSC_G 0x22
#define KEYSC_H 0x23
#define KEYSC_J 0x24
#define KEYSC_K 0x25
#define KEYSC_L 0x26
#define KEYSC_SEMI 0x27
#define KEYSC_QUOTE 0x28
#define KEYSC_BQUOTE 0x29
#define KEYSC_TILDE 0x29
#define KEYSC_LSHIFT 0x2a
#define KEYSC_BSLASH 0x2b
#define KEYSC_Z 0x2c
#define KEYSC_X 0x2d
#define KEYSC_C 0x2e
#define KEYSC_V 0x2f
#define KEYSC_B 0x30
#define KEYSC_N 0x31
#define KEYSC_M 0x32
#define KEYSC_COMMA 0x33
#define KEYSC_PERIOD 0x34
#define KEYSC_SLASH 0x35
#define KEYSC_RSHIFT 0x36
#define KEYSC_gSTAR 0x37
#define KEYSC_LALT 0x38
#define KEYSC_SPACE 0x39
#define KEYSC_CAPS 0x3a
#define KEYSC_F1 0x3b
#define KEYSC_F2 0x3c
#define KEYSC_F3 0x3d
#define KEYSC_F4 0x3e
#define KEYSC_F5 0x3f
#define KEYSC_F6 0x40
#define KEYSC_F7 0x41
#define KEYSC_F8 0x42
#define KEYSC_F9 0x43
#define KEYSC_F10 0x44
#define KEYSC_gNUM 0x45
#define KEYSC_SCROLL 0x46
#define KEYSC_gHOME 0x47
#define KEYSC_gUP 0x48
#define KEYSC_gPGUP 0x49
#define KEYSC_gMINUS 0x4a
#define KEYSC_gLEFT 0x4b
#define KEYSC_gKP5 0x4c
#define KEYSC_gRIGHT 0x4d
#define KEYSC_gPLUS 0x4e
#define KEYSC_gEND 0x4f
#define KEYSC_gDOWN 0x50
#define KEYSC_gPGDN 0x51
#define KEYSC_gINS 0x52
#define KEYSC_gDEL 0x53
#define KEYSC_F11 0x57
#define KEYSC_F12 0x58
#define KEYSC_gENTER 0x9C
#define KEYSC_RCTRL 0x9D
#define KEYSC_gSLASH 0xB5
#define KEYSC_RALT 0xB8
#define KEYSC_PRTSCN 0xB7
#define KEYSC_PAUSE 0xC5
#define KEYSC_HOME 0xC7
#define KEYSC_UP 0xC8
#define KEYSC_PGUP 0xC9
#define KEYSC_LEFT 0xCB
#define KEYSC_RIGHT 0xCD
#define KEYSC_END 0xCF
#define KEYSC_DOWN 0xD0
#define KEYSC_PGDN 0xD1
#define KEYSC_INSERT 0xD2
#define KEYSC_DELETE 0xD3
#define asc_Esc 27
#define asc_Enter 13
#define asc_Space 32
END_DUKE_NS
#endif

212
source/duke/src/macros.h Normal file
View file

@ -0,0 +1,212 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef EDUKE32_MACROS_H_
#define EDUKE32_MACROS_H_
#include "mmulti.h"
BEGIN_DUKE_NS
// Macros, some from SW source
static FORCE_INLINE int32_t krand2(void)
{
randomseed = (randomseed * 27584621ul) + 1ul;
return ((uint32_t) randomseed)>>16;
}
#define BGSTRETCH (hud_bgstretch ? 1024 : 0)
#define RANDOMSCRAP(s, i) \
{ \
int32_t const r1 = krand2(), r2 = krand2(), r3 = krand2(), r4 = krand2(), r5 = krand2(), r6 = krand2(), r7 = krand2(); \
A_InsertSprite(s->sectnum,s->x+(r7&255)-128,s->y+(r6&255)-128,s->z-ZOFFSET3-(r5&8191),\
SCRAP6+(r4&15),-8,RR?16:48,RR?16:48,r3&2047,(r2&63)+64,-512-(r1&2047),i,5); \
}
#define GTFLAGS(x) (g_gametypeFlags[ud.coop] & x)
#define TRAVERSE_SPRITE_SECT(l, o, n) (o) = (l); ((o) != -1) && ((n) = nextspritesect[o]); (o) = (n)
#define TRAVERSE_SPRITE_STAT(l, o, n) (o) = (l); ((o) != -1) && ((n) = nextspritestat[o]); (o) = (n)
#define TRAVERSE_CONNECT(i) i = 0; i != -1; i = connectpoint2[i]
#define TEST(flags,mask) ((flags) & (mask))
#define SET(flags,mask) ((flags) |= (mask))
#define RESET(flags,mask) ((flags) &= ~(mask))
#define FLIP(flags,mask) ((flags) ^= (mask))
// mask definitions
#define BIT(shift) (1u<<(shift))
#define TEST_SYNC_KEY(bits, sync_num) (!!TEST((bits), BIT(sync_num)))
#define AFLAMABLE(X) (X==BOX||X==TREE1||X==TREE2||X==TIRE||X==CONE)
#define rnd(X) ((krand2()>>8)>=(255-(X)))
//
// NETWORK - REDEFINABLE SHARED (SYNC) KEYS BIT POSITIONS
//
#define SK_JUMP 0
#define SK_CROUCH 1
#define SK_FIRE 2
#define SK_AIM_UP 3
#define SK_AIM_DOWN 4
#define SK_RUN 5
#define SK_LOOK_LEFT 6
#define SK_LOOK_RIGHT 7
// weapons take up 4 bits...
#define SK_WEAPON_BITS 8
#define SK_WEAPON_BITS1 9
#define SK_WEAPON_BITS2 10
#define SK_WEAPON_BITS3 11
#define SK_STEROIDS 12
#define SK_LOOK_UP 13
#define SK_LOOK_DOWN 14
#define SK_NIGHTVISION 15
#define SK_MEDKIT 16
#define SK_MULTIFLAG 17
#define SK_CENTER_VIEW 18
#define SK_HOLSTER 19
#define SK_INV_LEFT 20
#define SK_PAUSE 21
#define SK_QUICK_KICK 22
#define SK_AIMMODE 23
#define SK_HOLODUKE 24
#define SK_JETPACK 25
#define SK_GAMEQUIT 26
#define SK_INV_RIGHT 27
#define SK_TURNAROUND 28
#define SK_OPEN 29
#define SK_INVENTORY 30
#define SK_ESCAPE 31
// rotatesprite flags
#define ROTATE_SPRITE_TRANSLUCENT (BIT(0))
#define ROTATE_SPRITE_VIEW_CLIP (BIT(1)) // clip to view
#define ROTATE_SPRITE_YFLIP (BIT(2))
#define ROTATE_SPRITE_IGNORE_START_MOST (BIT(3)) // don't clip to startumost
#define ROTATE_SPRITE_SCREEN_CLIP (BIT(1)|BIT(3)) // use window
#define ROTATE_SPRITE_CORNER (BIT(4)) // place sprite from upper left corner
#define ROTATE_SPRITE_TRANS_FLIP (BIT(5))
#define ROTATE_SPRITE_NON_MASK (BIT(6)) // non masked sprites
#define ROTATE_SPRITE_ALL_PAGES (BIT(7)) // copies to all pages
#define RS_SCALE BIT(16)
// system defines for status bits
#define CEILING_STAT_PLAX BIT(0)
#define CEILING_STAT_SLOPE BIT(1)
#define CEILING_STAT_SWAPXY BIT(2)
#define CEILING_STAT_SMOOSH BIT(3)
#define CEILING_STAT_XFLIP BIT(4)
#define CEILING_STAT_YFLIP BIT(5)
#define CEILING_STAT_RELATIVE BIT(6)
#define CEILING_STAT_TYPE_MASK (BIT(7)|BIT(8))
#define CEILING_STAT_MASKED BIT(7)
#define CEILING_STAT_TRANS BIT(8)
#define CEILING_STAT_TRANS_FLIP (BIT(7)|BIT(8))
#define CEILING_STAT_FAF_BLOCK_HITSCAN BIT(15)
#define FLOOR_STAT_PLAX BIT(0)
#define FLOOR_STAT_SLOPE BIT(1)
#define FLOOR_STAT_SWAPXY BIT(2)
#define FLOOR_STAT_SMOOSH BIT(3)
#define FLOOR_STAT_XFLIP BIT(4)
#define FLOOR_STAT_YFLIP BIT(5)
#define FLOOR_STAT_RELATIVE BIT(6)
#define FLOOR_STAT_TYPE_MASK (BIT(7)|BIT(8))
#define FLOOR_STAT_MASKED BIT(7)
#define FLOOR_STAT_TRANS BIT(8)
#define FLOOR_STAT_TRANS_FLIP (BIT(7)|BIT(8))
#define FLOOR_STAT_FAF_BLOCK_HITSCAN BIT(15)
#define CSTAT_WALL_BLOCK BIT(0)
#define CSTAT_WALL_BOTTOM_SWAP BIT(1)
#define CSTAT_WALL_ALIGN_BOTTOM BIT(2)
#define CSTAT_WALL_XFLIP BIT(3)
#define CSTAT_WALL_MASKED BIT(4)
#define CSTAT_WALL_1WAY BIT(5)
#define CSTAT_WALL_BLOCK_HITSCAN BIT(6)
#define CSTAT_WALL_TRANSLUCENT BIT(7)
#define CSTAT_WALL_YFLIP BIT(8)
#define CSTAT_WALL_TRANS_FLIP BIT(9)
#define CSTAT_WALL_BLOCK_ACTOR (BIT(14)) // my def
#define CSTAT_WALL_WARP_HITSCAN (BIT(15)) // my def
//cstat, bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B"
// bit 1: 1 = 50/50 transluscence, 0 = normal "T"
// bit 2: 1 = x-flipped, 0 = normal "F"
// bit 3: 1 = y-flipped, 0 = normal "F"
// bits 5-4: 00 = FACE sprite (default) "R"
// 01 = WALL sprite (like masked walls)
// 10 = FLOOR sprite (parallel to ceilings&floors)
// 11 = SPIN sprite (face sprite that can spin 2draw style - not done yet)
// bit 6: 1 = 1-sided sprite, 0 = normal "1"
// bit 7: 1 = Real centered centering, 0 = foot center "C"
// bit 8: 1 = Blocking sprite (use with hitscan) "H"
// bit 9: reserved
// bit 10: reserved
// bit 11: 1 = determine shade based only on its own shade member (see CON's spritenoshade command), i.e.
// don't take over shade from parallaxed ceiling/nonparallaxed floor
// (NOTE: implemented on the game side)
// bit 12: reserved
// bit 13: reserved
// bit 14: reserved
// bit 15: 1 = Invisible sprite, 0 = not invisible
#define CSTAT_SPRITE_NOSHADE BIT(11)
#define CSTAT_SPRITE_BREAKABLE (CSTAT_SPRITE_BLOCK_HITSCAN)
#define SP(i) sprite[i].yvel
#define SX(i) sprite[i].x
#define SY(i) sprite[i].y
#define SZ(i) sprite[i].z
#define SS(i) sprite[i].shade
#define PN(i) sprite[i].picnum
#define SA(i) sprite[i].ang
//#define SV sprite[i].xvel
//#define ZV sprite[i].zvel
//#define RX sprite[i].xrepeat
//#define RY sprite[i].yrepeat
#define OW(i) sprite[i].owner
#define CS(i) sprite[i].cstat
#define SH(i) sprite[i].extra
//#define CX sprite[i].xoffset
//#define CY sprite[i].yoffset
//#define CD sprite[i].clipdist
//#define PL sprite[i].pal
#define SLT(i) sprite[i].lotag
#define SHT(i) sprite[i].hitag
#define SECT(i) sprite[i].sectnum
#define T1(i) actor[i].t_data[0]
#define T2(i) actor[i].t_data[1]
#define T3(i) actor[i].t_data[2]
#define T4(i) actor[i].t_data[3]
#define T5(i) actor[i].t_data[4]
#define T6(i) actor[i].t_data[5]
END_DUKE_NS
#endif

62
source/duke/src/menus.h Normal file
View file

@ -0,0 +1,62 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef menus_h_
#define menus_h_
#include "compat.h"
BEGIN_DUKE_NS
// a subset of screentext parameters, restricted because menus require accessibility
typedef struct MenuFont_t
{
// int32_t xspace, yline;
vec2_t emptychar, between;
int32_t zoom;
int32_t cursorLeftPosition, cursorCenterPosition, cursorScale, cursorScale2, cursorScale3;
int32_t textflags;
int16_t tilenum;
// selected shade glows, deselected shade is used by Blood, disabled shade is used by SW
int8_t shade_deselected, shade_disabled;
uint8_t pal;
uint8_t pal_selected, pal_deselected, pal_disabled;
uint8_t pal_selected_right, pal_deselected_right, pal_disabled_right;
int32_t get_yline() const { return mulscale16(emptychar.y, zoom); }
} MenuFont_t;
extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont;
void Menu_Init(void);
inline int G_CheckPlayerColor(int color)
{
static int32_t player_pals[] = { 0, 9, 10, 11, 12, 13, 14, 15, 16, 21, 23, };
if (color >= 0 && color < 10) return player_pals[color];
return 0;
}
END_DUKE_NS
#endif

3051
source/duke/src/namesdyn.cpp Normal file

File diff suppressed because it is too large Load diff

3598
source/duke/src/namesdyn.h Normal file

File diff suppressed because it is too large Load diff

3830
source/duke/src/net.cpp Normal file

File diff suppressed because it is too large Load diff

411
source/duke/src/net.h Normal file
View file

@ -0,0 +1,411 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef netplay_h_
#define netplay_h_
struct ENetHost;
struct ENetPeer;
struct ENetEvent;
struct ENetPacket;
BEGIN_DUKE_NS
// net packet specification/compatibility version
#define NETVERSION 1
extern ENetHost *g_netClient;
extern ENetHost *g_netServer;
extern ENetPeer *g_netClientPeer;
extern char g_netPassword[32];
extern int32_t g_netDisconnect;
extern int32_t g_netPlayersWaiting;
extern uint16_t g_netPort;
#ifndef NETCODE_DISABLE
extern int32_t g_networkMode;
#else
#define g_networkMode 0
#endif
extern int32_t g_netIndex;
extern int32_t lastsectupdate[MAXSECTORS];
extern int32_t lastupdate[MAXSPRITES];
extern int32_t lastwallupdate[MAXWALLS];
extern int16_t g_netStatnums[];
#define NET_REVISIONS 64
enum netchan_t
{
CHAN_REROUTE,
CHAN_GAME,
//CHAN_MOVE, // unreliable movement packets
CHAN_GAMESTATE, // gamestate changes... frags, respawns, player names, etc
CHAN_CHAT, // chat and RTS
//CHAN_MISC, // whatever else
CHAN_MAX
};
enum ServicePacket_t
{
SERVICEPACKET_TYPE_SENDTOID,
};
enum DukePacket_t
{
PACKET_TYPE_MASTER_TO_SLAVE,
PACKET_TYPE_SLAVE_TO_MASTER,
PACKET_TYPE_BROADCAST,
SERVER_GENERATED_BROADCAST,
//PACKET_TYPE_VERSION,
/* don't change anything above this line */
//PACKET_TYPE_MESSAGE,
//
//PACKET_TYPE_NEW_GAME,
//PACKET_TYPE_RTS,
//PACKET_TYPE_MENU_LEVEL_QUIT,
//PACKET_TYPE_WEAPON_CHOICE,
//PACKET_TYPE_PLAYER_OPTIONS,
//PACKET_TYPE_PLAYER_NAME,
//PACKET_TYPE_INIT_SETTINGS,
//
//PACKET_TYPE_USER_MAP,
//
//PACKET_TYPE_MAP_VOTE,
//PACKET_TYPE_MAP_VOTE_INITIATE,
//PACKET_TYPE_MAP_VOTE_CANCEL,
//
//PACKET_TYPE_LOAD_GAME,
PACKET_TYPE_NULL_PACKET,
PACKET_TYPE_PLAYER_READY,
//PACKET_TYPE_FRAGLIMIT_CHANGED,
//PACKET_TYPE_EOL,
//PACKET_TYPE_QUIT = 255, // should match mmulti I think
//PACKET_MASTER_TO_SLAVE,
//PACKET_SLAVE_TO_MASTER,
PACKET_NUM_PLAYERS,
PACKET_PLAYER_INDEX,
PACKET_PLAYER_DISCONNECTED,
//PACKET_PLAYER_SPAWN,
//PACKET_FRAG,
PACKET_ACK,
PACKET_AUTH,
//PACKET_PLAYER_PING,
//PACKET_PLAYER_READY,
//PACKET_MAP_STREAM,
// any packet with an ID higher than PACKET_BROADCAST is rebroadcast by server
// so hacked clients can't create fake server packets and get the server to
// send them to everyone
// newer versions of the netcode also make this determination based on which
// channel the packet was broadcast on
PACKET_BROADCAST,
PACKET_NEW_GAME,
PACKET_RTS,
PACKET_CLIENT_INFO,
PACKET_MESSAGE,
PACKET_USER_MAP,
PACKET_MAP_VOTE,
PACKET_MAP_VOTE_INITIATE,
PACKET_MAP_VOTE_CANCEL,
};
enum netdisconnect_t
{
DISC_BAD_PASSWORD = 1,
DISC_GAME_STARTED,
DISC_VERSION_MISMATCH,
DISC_INVALID,
DISC_SERVER_QUIT,
DISC_SERVER_FULL,
DISC_KICKED,
DISC_BANNED
};
enum netmode_t
{
NET_CLIENT = 0,
NET_SERVER,
//NET_DEDICATED_CLIENT, // client on dedicated server
//NET_DEDICATED_SERVER
};
#define MAXSYNCBYTES 16
#define SYNCFIFOSIZ 1024
// TENSW: on really bad network connections, the sync FIFO queue can overflow if it is the
// same size as the move fifo.
#if MOVEFIFOSIZ >= SYNCFIFOSIZ
#error "MOVEFIFOSIZ is greater than or equal to SYNCFIFOSIZ!"
#endif
extern char syncstat[MAXSYNCBYTES];
extern char g_szfirstSyncMsg[MAXSYNCBYTES][60];
extern int g_numSyncBytes;
extern int g_foundSyncError;
extern int syncvaltail, syncvaltottail;
#pragma pack(push,1)
typedef struct
{
int8_t header;
int8_t connection;
int8_t level_number;
int8_t volume_number;
int8_t player_skill;
int8_t monsters_off;
int8_t respawn_monsters;
int8_t respawn_items;
int8_t respawn_inventory;
int8_t marker;
int8_t ffire;
int8_t noexits;
int8_t coop;
} newgame_t;
#pragma pack(pop)
extern newgame_t pendingnewgame;
#ifndef NETCODE_DISABLE
// Sync
void initsynccrc(void);
char Net_PlayerSync(void);
char Net_PlayerSync2(void);
char Net_ActorSync(void);
char Net_WeaponSync(void);
char Net_MapSync(void);
char Net_RandomSync(void);
void Net_GetSyncStat(void);
void Net_DisplaySyncMsg(void);
void Net_AddSyncInfoToPacket(int* j);
void Net_GetSyncInfoFromPacket(uint8_t* packbuf, int packbufleng, int* j, int otherconnectindex);
// Connect/Disconnect
void Net_Connect(const char *srvaddr);
void Net_Disconnect(void);
void Net_ReceiveDisconnect(ENetEvent *event);
// Packet Handlers
#endif
void Net_ClearFIFO(void);
void Net_GetInput(void);
void Net_GetPackets(void);
#ifndef NETCODE_DISABLE
void Net_SendPacket(int32_t dest, uint8_t* pbuf, int32_t packbufleng);
void Net_HandleServerPackets(void);
void Net_HandleClientPackets(void);
void Net_ParseClientPacket(ENetEvent *event);
void Net_ParseServerPacket(ENetEvent *event);
void Net_ParsePacketCommon(uint8_t *pbuf, int32_t packbufleng, int32_t serverpacketp);
void Net_SendAcknowledge(ENetPeer *client);
void Net_ReceiveAcknowledge(uint8_t *pbuf, int32_t packbufleng);
void Net_SendChallenge();
void Net_ReceiveChallenge(uint8_t *pbuf, int32_t packbufleng, ENetEvent *event);
void Net_SendNewPlayer(int32_t newplayerindex);
void Net_ReceiveNewPlayer(uint8_t *pbuf, int32_t packbufleng);
void Net_SendPlayerIndex(int32_t index, ENetPeer *peer);
void Net_ReceivePlayerIndex(uint8_t *pbuf, int32_t packbufleng);
void Net_SendClientInfo(void);
void Net_ReceiveClientInfo(uint8_t *pbuf, int32_t packbufleng, int32_t fromserver);
void Net_SendUserMapName(void);
void Net_ReceiveUserMapName(uint8_t *pbuf, int32_t packbufleng);
//netmapstate_t *Net_GetRevision(uint8_t revision, uint8_t cancreate);
//void Net_SendMapUpdate(void);
//void Net_ReceiveMapUpdate(ENetEvent *event);
//void Net_FillMapDiff(uint32_t fromRevision, uint32_t toRevision);
//void Net_SaveMapState(netmapstate_t *save);
//void Net_RestoreMapState();
//void Net_CopyToNet(int32_t i, netactor_t *netactor);
//void Net_CopyFromNet(int32_t i, netactor_t *netactor);
//int32_t Net_ActorsAreDifferent(netactor_t *actor1, netactor_t *actor2);
//int32_t Net_IsRelevantSprite(int32_t i);
//int32_t Net_IsRelevantStat(int32_t stat);
//int32_t Net_InsertSprite(int32_t sect, int32_t stat);
//void Net_DeleteSprite(int32_t spritenum);
//void Net_FillPlayerUpdate(playerupdate_t *update, int32_t player);
//void Net_ExtractPlayerUpdate(playerupdate_t *update, int32_t type);
void Net_SendServerUpdates(void);
void Net_ReceiveServerUpdate(ENetEvent *event);
void Net_SendClientUpdate(void);
void Net_ReceiveClientUpdate(ENetEvent *event);
void Net_SendMessage(void);
void Net_ReceiveMessage(uint8_t *pbuf, int32_t packbufleng);
void Net_StartNewGame();
void Net_NotifyNewGame();
void Net_SendNewGame(int32_t frommenu, ENetPeer *peer);
void Net_ReceiveNewGame(ENetEvent* event);
void Net_FillNewGame(newgame_t *newgame, int32_t frommenu);
void Net_ExtractNewGame(newgame_t *newgame, int32_t menuonly);
void Net_SendMapVoteInitiate(void);
void Net_ReceiveMapVoteInitiate(uint8_t *pbuf);
void Net_SendMapVote(int32_t votefor);
void Net_ReceiveMapVote(uint8_t *pbuf);
void Net_CheckForEnoughVotes();
void Net_SendMapVoteCancel(int32_t failed);
void Net_ReceiveMapVoteCancel(uint8_t *pbuf);
//////////
void Net_ResetPrediction(void);
void Net_DoPrediction(void);
void Net_CorrectPrediction(void);
void Net_SpawnPlayer(int32_t player);
void Net_SyncPlayer(ENetEvent *event);
void Net_WaitForEverybody(void);
void Net_Update(void);
void Net_PostPacket(ENetPacket *packet);
void faketimerhandler(void);
void Net_SendTaunt(int ridiculeNum);
void Net_SendRTS(int ridiculeNum);
void Net_InitNetwork();
void Net_PrintLag(FString& output);
#else
/* NETCODE_ENABLE is not defined */
// Connect/Disconnect
#define Net_Connect(...) ((void)0)
#define Net_Disconnect(...) ((void)0)
#define Net_ReceiveDisconnect(...) ((void)0)
// Packet Handlers
#define Net_HandleServerPackets(...) ((void)0)
#define Net_HandleClientPackets(...) ((void)0)
#define Net_ParseClientPacket(...) ((void)0)
#define Net_ParseServerPacket(...) ((void)0)
#define Net_ParsePacketCommon(...) ((void)0)
#define Net_SendAcknowledge(...) ((void)0)
#define Net_ReceiveAcknowledge(...) ((void)0)
#define Net_SendChallenge(...) ((void)0)
#define Net_ReceiveChallenge(...) ((void)0)
#define Net_SendNewPlayer(...) ((void)0)
#define Net_ReceiveNewPlayer(...) ((void)0)
#define Net_SendPlayerIndex(...) ((void)0)
#define Net_ReceivePlayerIndex(...) ((void)0)
#define Net_SendClientInfo(...) ((void)0)
#define Net_ReceiveClientInfo(...) ((void)0)
#define Net_SendUserMapName(...) ((void)0)
#define Net_ReceiveUserMapName(...) ((void)0)
#define Net_SendClientSync(...) ((void)0)
#define Net_ReceiveClientSync(...) ((void)0)
#define Net_SendMapUpdate(...) ((void)0)
#define Net_ReceiveMapUpdate(...) ((void)0)
#define Net_FillPlayerUpdate(...) ((void)0)
#define Net_ExtractPlayerUpdate(...) ((void)0)
#define Net_SendServerUpdates(...) ((void)0)
#define Net_ReceiveServerUpdate(...) ((void)0)
#define Net_SendClientUpdate(...) ((void)0)
#define Net_ReceiveClientUpdate(...) ((void)0)
#define Net_SendMessage(...) ((void)0)
#define Net_ReceiveMessage(...) ((void)0)
#define Net_StartNewGame(...) ((void)0)
#define Net_SendNewGame(...) ((void)0)
#define Net_ReceiveNewGame(...) ((void)0)
#define Net_FillNewGame(...) ((void)0)
#define Net_ExtractNewGame(...) ((void)0)
#define Net_SendMapVoteInitiate(...) ((void)0)
#define Net_ReceiveMapVoteInitiate(...) ((void)0)
#define Net_SendMapVote(...) ((void)0)
#define Net_ReceiveMapVote(...) ((void)0)
#define Net_CheckForEnoughVotes(...) ((void)0)
#define Net_SendMapVoteCancel(...) ((void)0)
#define Net_ReceiveMapVoteCancel(...) ((void)0)
//////////
#define Net_ResetPrediction(...) ((void)0)
#define Net_DoPrediction(...) ((void)0)
#define Net_CorrectPrediction(...) ((void)0)
#define Net_RestoreMapState(...) ((void)0)
#define Net_SyncPlayer(...) ((void)0)
#define Net_WaitForServer(...) ((void)0)
#define Net_ActorsAreDifferent(...) 0
#define Net_IsRelevantSprite(...) 0
#define Net_IsRelevantStat(...) 0
#define Net_InsertSprite(...) 0
#define Net_DeleteSprite(...) ((void)0)
#define Net_NotifyNewGame(...) ((void)0)
#define Net_SendTaunt(...) ((void)0)
#define Net_SendRTS(...) ((void)0)
#define Net_WaitForEverybody(...) ((void)0)
#define initsynccrc(...) ((void)0)
#define Net_GetSyncStat(...) ((void)0)
#define Net_DisplaySyncMsg(...) ((void)0)
#define Net_ClearFIFO(...) ((void)0)
#define Net_GetInput(...) ((void)0)
#endif
END_DUKE_NS
#endif // netplay_h_

495
source/duke/src/osdcmds.cpp Normal file
View file

@ -0,0 +1,495 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
Copyright (C) 2020 Raze developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "cheats.h"
#include "cmdline.h"
#include "demo.h" // g_firstDemoFile[]
#include "duke3d.h"
#include "menus.h"
#include "osdcmds.h"
#include "savegame.h"
#include "sbar.h"
#include "mapinfo.h"
BEGIN_DUKE_NS
struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat = { -1, 0, 0 };
static int osdcmd_levelwarp(CCmdFuncPtr parm)
{
if (parm->numparms != 2)
return OSDCMD_SHOWHELP;
int e = atoi(parm->parms[0]);
int m = atoi(parm->parms[1]);
if (e == 0 || m == 0)
{
Printf(TEXTCOLOR_RED "Invalid level!: E%sL%s\n", parm->parms[0], parm->parms[1]);
return OSDCMD_OK;
}
osdcmd_cheatsinfo_stat.cheatnum = -1;
ud.m_volume_number = e - 1;
m_level_number = m - 1;
ud.m_monsters_off = ud.monsters_off = 0;
ud.m_respawn_items = 0;
ud.m_respawn_inventory = 0;
ud.multimode = 1;
if (g_player[myconnectindex].ps->gm & MODE_GAME)
{
G_NewGame(ud.m_volume_number, m_level_number, ud.m_player_skill);
g_player[myconnectindex].ps->gm = MODE_RESTART;
}
else G_NewGame_EnterLevel();
return OSDCMD_OK;
}
static int osdcmd_map(CCmdFuncPtr parm)
{
if (parm->numparms != 1)
{
return OSDCMD_SHOWHELP;
}
FString mapname = parm->parms[0];
if (!fileSystem.Lookup(mapname, "MAP"))
{
Printf(TEXTCOLOR_RED "map: file \"%s\" not found.\n", mapname.GetChars());
return OSDCMD_OK;
}
// Check if the map is already defined.
for (int i = 0; i < 512; i++)
{
if (mapList[i].labelName.CompareNoCase(mapname) == 0)
{
ud.m_volume_number = i / MAXLEVELS;
m_level_number = i % MAXLEVELS;
goto foundone;
}
}
if (VOLUMEONE)
{
Printf(TEXTCOLOR_RED "Cannot use user maps in shareware.\n");
return OSDCMD_OK;
}
// Treat as user map
boardfilename[0] = '/';
boardfilename[1] = 0;
ud.m_volume_number = 0;
m_level_number = 7;
DefaultExtension(mapname, ".map");
strcat(boardfilename, mapname);
foundone:
if (numplayers > 1)
{
return OSDCMD_OK;
}
osdcmd_cheatsinfo_stat.cheatnum = -1;
ud.m_monsters_off = ud.monsters_off = 0;
ud.m_respawn_items = 0;
ud.m_respawn_inventory = 0;
ud.multimode = 1;
if (g_player[myconnectindex].ps->gm & MODE_GAME)
{
G_NewGame(ud.m_volume_number, m_level_number, ud.m_player_skill);
g_player[myconnectindex].ps->gm = MODE_RESTART;
}
else G_NewGame_EnterLevel();
return OSDCMD_OK;
}
// demo <demonum or demofn> [<prof>]
//
// To profile a demo ("timedemo mode"), <prof> can be given in the range 0-8,
// which will start to replay it as fast as possible, rendering <prof> frames
// for each gametic.
//
// Notes:
// * The demos should be recorded with demorec_diffs set to 0, so that the
// game state updates are actually computed.
// * Currently, the profiling can only be aborted on SDL 1.2 builds by
// pressing any key.
// * With <prof> greater than 1, interpolation should be calculated properly,
// though this has not been verified by looking at the frames.
// * When testing whether a change in the source has an effect on performance,
// the variance of the run times MUST be taken into account (that is, the
// replaying must be performed multiple times for the old and new versions,
// etc.)
static int osdcmd_demo(CCmdFuncPtr parm)
{
if (numplayers > 1)
{
Printf("Command not allowed in multiplayer\n");
return OSDCMD_OK;
}
if (g_player[myconnectindex].ps->gm & MODE_GAME)
{
Printf("demo: Must not be in a game.\n");
return OSDCMD_OK;
}
if (parm->numparms != 1 && parm->numparms != 2)
return OSDCMD_SHOWHELP;
{
int32_t prof = parm->numparms==2 ? Batoi(parm->parms[1]) : -1;
Demo_SetFirst(parm->parms[0]);
Demo_PlayFirst(clamp(prof, -1, 8)+1, 0);
}
return OSDCMD_OK;
}
static int osdcmd_activatecheat(CCmdFuncPtr parm)
{
if (parm->numparms != 1)
return OSDCMD_SHOWHELP;
if (numplayers == 1 && g_player[myconnectindex].ps->gm & MODE_GAME)
osdcmd_cheatsinfo_stat.cheatnum = Batoi(parm->parms[0]);
else
Printf("activatecheat: Not in a single-player game.\n");
return OSDCMD_OK;
}
static int osdcmd_god(CCmdFuncPtr UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
if (numplayers == 1 && g_player[myconnectindex].ps->gm & MODE_GAME)
osdcmd_cheatsinfo_stat.cheatnum = CHEAT_CORNHOLIO;
else
Printf("god: Not in a single-player game.\n");
return OSDCMD_OK;
}
static int osdcmd_noclip(CCmdFuncPtr UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
if (numplayers == 1 && g_player[myconnectindex].ps->gm & MODE_GAME)
{
osdcmd_cheatsinfo_stat.cheatnum = CHEAT_CLIP;
}
else
{
Printf("noclip: Not in a single-player game.\n");
}
return OSDCMD_OK;
}
int osdcmd_restartmap(CCmdFuncPtr UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
if (g_player[myconnectindex].ps->gm & MODE_GAME && ud.multimode == 1)
g_player[myconnectindex].ps->gm = MODE_RESTART;
return OSDCMD_OK;
}
static int osdcmd_spawn(CCmdFuncPtr parm)
{
int32_t picnum = 0;
uint16_t cstat=0;
char pal=0;
int16_t ang=0;
int16_t set=0, idx;
vec3_t vect;
if (numplayers > 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME))
{
Printf("spawn: Can't spawn sprites in multiplayer games or demos\n");
return OSDCMD_OK;
}
switch (parm->numparms)
{
case 7: // x,y,z
vect.x = Batol(parm->parms[4]);
vect.y = Batol(parm->parms[5]);
vect.z = Batol(parm->parms[6]);
set |= 8;
fallthrough__;
case 4: // ang
ang = Batol(parm->parms[3]) & 2047;
set |= 4;
fallthrough__;
case 3: // cstat
cstat = (uint16_t)Batol(parm->parms[2]);
set |= 2;
fallthrough__;
case 2: // pal
pal = (uint8_t)Batol(parm->parms[1]);
set |= 1;
fallthrough__;
case 1: // tile number
if (isdigit(parm->parms[0][0]))
{
picnum = Batol(parm->parms[0]);
}
else
{
int32_t i;
int32_t j;
for (j=0; j<2; j++)
{
for (i=0; i<g_labelCnt; i++)
{
if ((j == 0 && !Bstrcmp(label+(i<<6), parm->parms[0])) ||
(j == 1 && !Bstrcasecmp(label+(i<<6), parm->parms[0])))
{
picnum = labelcode[i];
break;
}
}
if (i < g_labelCnt)
break;
}
if (i==g_labelCnt)
{
Printf("spawn: Invalid tile label given\n");
return OSDCMD_OK;
}
}
if ((uint32_t)picnum >= MAXUSERTILES)
{
Printf("spawn: Invalid tile number\n");
return OSDCMD_OK;
}
break;
default:
return OSDCMD_SHOWHELP;
}
idx = A_Spawn(g_player[myconnectindex].ps->i, picnum);
if (set & 1) sprite[idx].pal = (uint8_t)pal;
if (set & 2) sprite[idx].cstat = (int16_t)cstat;
if (set & 4) sprite[idx].ang = ang;
if (set & 8)
{
if (setsprite(idx, &vect) < 0)
{
Printf("spawn: Sprite can't be spawned into null space\n");
A_DeleteSprite(idx);
}
}
return OSDCMD_OK;
}
static int osdcmd_give(CCmdFuncPtr parm)
{
int32_t i;
if (numplayers != 1 || (g_player[myconnectindex].ps->gm & MODE_GAME) == 0 ||
g_player[myconnectindex].ps->dead_flag != 0)
{
Printf("give: Cannot give while dead or not in a single-player game.\n");
return OSDCMD_OK;
}
if (parm->numparms != 1) return OSDCMD_SHOWHELP;
if (!Bstrcasecmp(parm->parms[0], "all"))
{
osdcmd_cheatsinfo_stat.cheatnum = CHEAT_STUFF;
return OSDCMD_OK;
}
else if (!Bstrcasecmp(parm->parms[0], "health"))
{
sprite[g_player[myconnectindex].ps->i].extra = g_player[myconnectindex].ps->max_player_health<<1;
return OSDCMD_OK;
}
else if (!Bstrcasecmp(parm->parms[0], "weapons"))
{
osdcmd_cheatsinfo_stat.cheatnum = CHEAT_WEAPONS;
return OSDCMD_OK;
}
else if (!Bstrcasecmp(parm->parms[0], "ammo"))
{
for (i=MAX_WEAPONS-(VOLUMEONE?6:1)-1; i>=PISTOL_WEAPON; i--)
P_AddAmmo(g_player[myconnectindex].ps,i,g_player[myconnectindex].ps->max_ammo_amount[i]);
return OSDCMD_OK;
}
else if (!Bstrcasecmp(parm->parms[0], "armor"))
{
g_player[myconnectindex].ps->inv_amount[GET_SHIELD] = 100;
return OSDCMD_OK;
}
else if (!Bstrcasecmp(parm->parms[0], "keys"))
{
osdcmd_cheatsinfo_stat.cheatnum = CHEAT_KEYS;
return OSDCMD_OK;
}
else if (!Bstrcasecmp(parm->parms[0], "inventory"))
{
osdcmd_cheatsinfo_stat.cheatnum = CHEAT_INVENTORY;
return OSDCMD_OK;
}
return OSDCMD_SHOWHELP;
}
#if !defined NETCODE_DISABLE
static int osdcmd_disconnect(CCmdFuncPtr UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
// NUKE-TODO:
if (g_player[myconnectindex].ps->gm&MODE_MENU)
g_netDisconnect = 1;
return OSDCMD_OK;
}
static int osdcmd_connect(CCmdFuncPtr parm)
{
if (parm->numparms != 1)
return OSDCMD_SHOWHELP;
Net_Connect(parm->parms[0]);
G_BackToMenu();
return OSDCMD_OK;
}
static int osdcmd_password(CCmdFuncPtr parm)
{
if (parm->numparms < 1)
{
Bmemset(g_netPassword, 0, sizeof(g_netPassword));
return OSDCMD_OK;
}
Bstrncpy(g_netPassword, (parm->raw) + 9, sizeof(g_netPassword)-1);
return OSDCMD_OK;
}
int osdcmd_listplayers(CCmdFuncPtr parm);
#endif
static int osdcmd_printtimes(CCmdFuncPtr UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
char buf[32];
int32_t maxlen = 0;
int32_t haveac=0;
for (int i=0; i<MAXTILES; i++)
if (g_actorCalls[i])
{
if (!haveac)
{
haveac = 1;
Printf("\nactor times: tile, total calls, total time [ms], {min,mean,max} time/call [us]\n");
}
buf[0] = 0;
for (int ii=0; ii<g_labelCnt; ii++)
{
if (labelcode[ii] == i && labeltype[ii] & LABEL_ACTOR)
{
Bstrcpy(buf, label+(ii<<6));
break;
}
}
if (!buf[0]) Bsprintf(buf, "%d", i);
Printf("%17s, %8d, %9.3f, %9.3f, %9.3f, %9.3f,\n",
buf, g_actorCalls[i], g_actorTotalMs[i],
1000*g_actorMinMs[i],
1000*g_actorTotalMs[i]/g_actorCalls[i],
1000*g_actorMaxMs[i]);
}
return OSDCMD_OK;
}
int32_t registerosdcommands(void)
{
C_RegisterFunction("map","map <mapname>: loads the given map", osdcmd_map);
if (!VOLUMEONE)
{
C_RegisterFunction("demo","demo <demofile or demonum>: starts the given demo", osdcmd_demo);
}
C_RegisterFunction("levelwarp","levelwarp <e> <m>: warp to episode 'e' and map 'm'", osdcmd_levelwarp);
#if !defined NETCODE_DISABLE
C_RegisterFunction("connect","connect: connects to a multiplayer game", osdcmd_connect);
C_RegisterFunction("disconnect","disconnect: disconnects from the local multiplayer game", osdcmd_disconnect);
#endif
C_RegisterFunction("give","give <all|health|weapons|ammo|armor|keys|inventory>: gives requested item", osdcmd_give);
C_RegisterFunction("god","god: toggles god mode", osdcmd_god);
C_RegisterFunction("activatecheat","activatecheat <id>: activates a cheat code", osdcmd_activatecheat);
#ifdef DEBUGGINGAIDS
C_RegisterFunction("inittimer","debug", osdcmd_inittimer);
#endif
#if !defined NETCODE_DISABLE
#if 0
C_RegisterFunction("kick","kick <id>: kicks a multiplayer client. See listplayers.", osdcmd_kick);
C_RegisterFunction("kickban","kickban <id>: kicks a multiplayer client and prevents them from reconnecting. See listplayers.", osdcmd_kickban);
#endif
C_RegisterFunction("listplayers","listplayers: lists currently connected multiplayer clients", osdcmd_listplayers);
#endif
C_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip);
#if !defined NETCODE_DISABLE
C_RegisterFunction("password","password: sets multiplayer game password", osdcmd_password);
#endif
C_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes);
C_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap);
C_RegisterFunction("spawn","spawn <picnum> [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",osdcmd_spawn);
return 0;
}
END_DUKE_NS

48
source/duke/src/osdcmds.h Normal file
View file

@ -0,0 +1,48 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef osdcmds_h_
#define osdcmds_h_
BEGIN_DUKE_NS
struct osdcmd_cheatsinfo {
int32_t cheatnum; // -1 = none, else = see DoCheats()
int32_t volume,level;
};
extern struct osdcmd_cheatsinfo osdcmd_cheatsinfo_stat;
int32_t registerosdcommands(void);
// key bindings stuff
typedef struct {
const char *name;
int32_t id;
} keydef_t;
extern const char *const ConsoleButtons[];
END_DUKE_NS
#endif // osdcmds_h_

9592
source/duke/src/player.cpp Normal file

File diff suppressed because it is too large Load diff

385
source/duke/src/player.h Normal file
View file

@ -0,0 +1,385 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef player_h_
#define player_h_
#include "inv.h"
#include "namesdyn.h"
#include "fix16.h"
#include "net.h"
BEGIN_DUKE_NS
extern int32_t g_mostConcurrentPlayers;
#define MOVEFIFOSIZ 256
#define NAM_GRENADE_LIFETIME 120
#define NAM_GRENADE_LIFETIME_VAR 30
#define HORIZ_MIN -99
#define HORIZ_MAX 299
#define AUTO_AIM_ANGLE 48
#define PHEIGHT_DUKE (38<<8)
#define PHEIGHT_RR (40<<8);
extern int32_t PHEIGHT;
#define TRIPBOMB_TRIPWIRE 0x00000001
#define TRIPBOMB_TIMER 0x00000002
#define PIPEBOMB_REMOTE 0x00000001
#define PIPEBOMB_TIMER 0x00000002
#define WEAPON_POS_LOWER -9
#define WEAPON_POS_RAISE 10
#define WEAPON_POS_START 6
#define MAX_WEAPON_RECS 256
enum weaponflags_t {
WEAPON_SPAWNTYPE1 = 0x00000000, // just spawn
WEAPON_HOLSTER_CLEARS_CLIP = 0x00000001, // 'holstering' clears the current clip
WEAPON_GLOWS = 0x00000002, // weapon 'glows' (shrinker and grower)
WEAPON_AUTOMATIC = 0x00000004, // automatic fire (continues while 'fire' is held down
WEAPON_FIREEVERYOTHER = 0x00000008, // during 'hold time' fire every frame
WEAPON_FIREEVERYTHIRD = 0x00000010, // during 'hold time' fire every third frame
WEAPON_RANDOMRESTART = 0x00000020, // restart for automatic is 'randomized' by RND 3
WEAPON_AMMOPERSHOT = 0x00000040, // uses ammo for each shot (for automatic)
WEAPON_BOMB_TRIGGER = 0x00000080, // weapon is the 'bomb' trigger
WEAPON_NOVISIBLE = 0x00000100, // weapon use does not cause user to become 'visible'
WEAPON_THROWIT = 0x00000200, // weapon 'throws' the 'shoots' item...
WEAPON_CHECKATRELOAD = 0x00000400, // check weapon availability at 'reload' time
WEAPON_STANDSTILL = 0x00000800, // player stops jumping before actual fire (like tripbomb in duke)
WEAPON_SPAWNTYPE2 = 0x00001000, // spawn like shotgun shells
WEAPON_SPAWNTYPE3 = 0x00002000, // spawn like chaingun shells
};
enum gamemode_t {
MODE_MENU = 0x00000001,
MODE_DEMO = 0x00000002,
MODE_GAME = 0x00000004,
MODE_EOL = 0x00000008,
MODE_TYPE = 0x00000010,
MODE_RESTART = 0x00000020,
MODE_SENDTOWHOM = 0x00000040,
};
// Player Actions.
enum playeraction_t {
pstanding = 0x00000001,
pwalking = 0x00000002,
prunning = 0x00000004,
pducking = 0x00000008,
pfalling = 0x00000010,
pjumping = 0x00000020,
phigher = 0x00000040,
pwalkingback = 0x00000080,
prunningback = 0x00000100,
pkicking = 0x00000200,
pshrunk = 0x00000400,
pjetpack = 0x00000800,
ponsteroids = 0x00001000,
ponground = 0x00002000,
palive = 0x00004000,
pdead = 0x00008000,
pfacing = 0x00010000
};
typedef struct {
vec3_t pos;
int16_t ang, sect;
} playerspawn_t;
typedef struct {
int16_t got_access, last_extra, inv_amount[GET_MAX], curr_weapon, holoduke_on;
int16_t last_weapon, weapon_pos, kickback_pic;
int16_t ammo_amount[MAX_WEAPONS], frag[MAXPLAYERS];
uint32_t gotweapon;
char inven_icon, jetpack_on, heat_on;
} DukeStatus_t;
typedef struct {
uint32_t bits;
int16_t fvel, svel;
fix16_t q16avel, q16horz;
int8_t extbits;
} input_t;
#pragma pack(push,1)
// XXX: r1625 changed a lot types here, among others
// * int32_t --> int16_t
// * int16_t --> int8_t
// * char --> int8_t
// Need to carefully think about implications!
// TODO: rearrange this if the opportunity arises!
typedef struct {
vec3_t pos, opos, vel, npos;
vec2_t bobpos, fric;
fix16_t q16horiz, q16horizoff, oq16horiz, oq16horizoff;
fix16_t q16ang, oq16ang, q16angvel;
int32_t truefz, truecz, player_par;
int32_t randomflamex, exitx, exity;
int32_t runspeed, max_player_health, max_shield_amount;
int32_t autostep, autostep_sbw;
uint32_t interface_toggle_flag;
uint16_t max_actors_killed, actors_killed;
uint32_t gotweapon;
uint16_t zoom;
int16_t loogiex[64], loogiey[64], sbs, sound_pitch;
int16_t cursectnum, last_extra, subweapon;
int16_t max_ammo_amount[MAX_WEAPONS], ammo_amount[MAX_WEAPONS], inv_amount[GET_MAX];
int16_t wackedbyactor, pyoff, opyoff;
fix16_t q16look_ang;
int16_t newowner, jumping_counter, airleft;
int16_t fta, ftq, access_wallnum, access_spritenum;
int16_t got_access, weapon_ang, visibility;
int16_t somethingonplayer, on_crane, i, one_parallax_sectnum;
int16_t random_club_frame, one_eighty_count;
int16_t dummyplayersprite, extra_extra8;
int16_t actorsqu, timebeforeexit, customexitsound, last_pissed_time;
fix16_t one_eighty_target;
int16_t weaprecs[MAX_WEAPON_RECS], weapon_sway, crack_time, bobcounter;
int16_t dead_flag;
fix16_t oq16rotscrnang, q16rotscrnang; // JBF 20031220: added orotscrnang
int16_t holoduke_on, pycount;
int16_t transporter_hold/*, clipdist*/;
uint8_t max_secret_rooms, secret_rooms;
// XXX: 255 values for frag(gedself) seems too small.
uint8_t frag, fraggedself, quick_kick, last_quick_kick;
uint8_t return_to_center, reloading, weapreccnt;
uint8_t aim_mode, auto_aim, weaponswitch, movement_lock, team;
uint8_t tipincs, hbomb_hold_delay, frag_ps, kickback_pic;
uint8_t gm, on_warping_sector, footprintcount, hurt_delay;
uint8_t hbomb_on, jumping_toggle, rapid_fire_hold, on_ground;
uint8_t inven_icon, buttonpalette, over_shoulder_on, show_empty_weapon;
uint8_t jetpack_on, spritebridge, lastrandomspot;
uint8_t scuba_on, footprintpal, heat_on, invdisptime;
uint8_t holster_weapon, falling_counter, footprintshade;
uint8_t refresh_inventory, last_full_weapon;
uint8_t toggle_key_flag, knuckle_incs, knee_incs, access_incs;
uint8_t walking_snd_toggle, palookup, hard_landing, fist_incs;
int8_t numloogs, loogcnt, scream_voice;
int8_t last_weapon, cheat_phase, weapon_pos, wantweaponfire, curr_weapon;
uint8_t palette;
palette_t pals;
int8_t last_used_weapon;
int16_t recoil;
int32_t stairs;
int32_t hbomb_offset;
int16_t hbomb_time;
uint8_t shotgun_state[2];
uint8_t make_noise;
int32_t noise_x, noise_y, noise_radius;
uint8_t keys[5];
int16_t yehaa_timer;
int16_t drink_amt, eat_amt, drink_ang, eat_ang;
int32_t drink_timer, eat_timer;
int16_t level_end_timer;
int16_t moto_speed, moto_drink;
uint8_t on_motorcycle, on_boat, moto_underwater, not_on_water, moto_on_ground;
uint8_t moto_do_bump, moto_bump_fast, moto_on_oil, moto_on_mud;
int16_t moto_bump, moto_bump_target, moto_turb;
int16_t drug_stat[3];
int32_t drug_aspect;
uint8_t drug_mode, lotag800kill, sea_sick_stat;
int32_t drug_timer;
int32_t sea_sick;
uint8_t hurt_delay2, nocheat;
double tilt_status;
int32_t dhat60f, dhat613, dhat617, dhat61b, dhat61f;
int8_t crouch_toggle;
int8_t padding_[3];
} DukePlayer_t;
typedef struct
{
DukePlayer_t *ps;
input_t *input;
bool horizRecenter;
float horizAngleAdjust;
int8_t horizSkew;
bool lookLeft;
bool lookRight;
double lastInputTicks;
int32_t movefifoend, syncvalhead, myminlag;
int32_t pcolor, pteam;
// NOTE: wchoice[HANDREMOTE_WEAPON .. MAX_WEAPONS-1] unused
uint8_t frags[MAXPLAYERS], wchoice[MAX_WEAPONS];
char vote, gotvote, playerreadyflag, playerquitflag, connected;
char user_name[32];
char syncval[SYNCFIFOSIZ][MAXSYNCBYTES];
} playerdata_t;
#pragma pack(pop)
typedef struct
{
// NOTE: the member names must be identical to aplWeapon* suffixes.
int32_t WorksLike; // What the original works like
int32_t Clip; // number of items in magazine
int32_t Reload; // delay to reload (include fire)
int32_t FireDelay; // delay to fire
int32_t TotalTime; // The total time the weapon is cycling before next fire.
int32_t HoldDelay; // delay after release fire button to fire (0 for none)
int32_t Flags; // Flags for weapon
int32_t Shoots; // what the weapon shoots
int32_t SpawnTime; // the frame at which to spawn an item
int32_t Spawn; // the item to spawn
int32_t ShotsPerBurst; // number of shots per 'burst' (one ammo per 'burst')
int32_t InitialSound; // Sound made when weapon starts firing. zero for no sound
int32_t FireSound; // Sound made when firing (each time for automatic)
int32_t Sound2Time; // Alternate sound time
int32_t Sound2Sound; // Alternate sound sound ID
int32_t FlashColor; // Muzzle flash color
} weapondata_t;
# define PWEAPON(Player, Weapon, Wmember) (aplWeapon ## Wmember [Weapon][Player])
extern intptr_t *aplWeaponClip[MAX_WEAPONS]; // number of items in clip
extern intptr_t *aplWeaponReload[MAX_WEAPONS]; // delay to reload (include fire)
extern intptr_t *aplWeaponFireDelay[MAX_WEAPONS]; // delay to fire
extern intptr_t *aplWeaponHoldDelay[MAX_WEAPONS]; // delay after release fire button to fire (0 for none)
extern intptr_t *aplWeaponTotalTime[MAX_WEAPONS]; // The total time the weapon is cycling before next fire.
extern intptr_t *aplWeaponFlags[MAX_WEAPONS]; // Flags for weapon
extern intptr_t *aplWeaponShoots[MAX_WEAPONS]; // what the weapon shoots
extern intptr_t *aplWeaponSpawnTime[MAX_WEAPONS]; // the frame at which to spawn an item
extern intptr_t *aplWeaponSpawn[MAX_WEAPONS]; // the item to spawn
extern intptr_t *aplWeaponShotsPerBurst[MAX_WEAPONS]; // number of shots per 'burst' (one ammo per 'burst'
extern intptr_t *aplWeaponWorksLike[MAX_WEAPONS]; // What original the weapon works like
extern intptr_t *aplWeaponInitialSound[MAX_WEAPONS]; // Sound made when initialy firing. zero for no sound
extern intptr_t *aplWeaponFireSound[MAX_WEAPONS]; // Sound made when firing (each time for automatic)
extern intptr_t *aplWeaponSound2Time[MAX_WEAPONS]; // Alternate sound time
extern intptr_t *aplWeaponSound2Sound[MAX_WEAPONS]; // Alternate sound sound ID
extern intptr_t *aplWeaponFlashColor[MAX_WEAPONS]; // Color for polymer muzzle flash
typedef struct {
int32_t cur, count; // "cur" is the only member that is *used*
int32_t gunposx, lookhalfang; // weapon_xoffset, ps->look_ang>>1
int32_t gunposy, lookhoriz; // gun_pos, looking_arc
int32_t shade;
} hudweapon_t;
extern input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
extern playerspawn_t g_playerSpawnPoints[MAXPLAYERS];
extern playerdata_t *const g_player;
extern int16_t WeaponPickupSprites[MAX_WEAPONS];
extern hudweapon_t hudweap;
extern int32_t g_levelTextTime;
extern int32_t g_numObituaries;
extern int32_t g_numSelfObituaries;
extern int32_t mouseyaxismode;
extern int32_t ticrandomseed;
#define SHOOT_HARDCODED_ZVEL INT32_MIN
int A_Shoot(int spriteNum, int projecTile);
static inline void P_PalFrom(DukePlayer_t *pPlayer, uint8_t f, uint8_t r, uint8_t g, uint8_t b)
{
pPlayer->pals.f = f;
pPlayer->pals.r = r;
pPlayer->pals.g = g;
pPlayer->pals.b = b;
}
void P_AddKills(DukePlayer_t * pPlayer, uint16_t kills);
int32_t A_GetHitscanRange(int spriteNum);
void P_GetInput(int playerNum);
void P_GetInputMotorcycle(int playerNum);
void P_GetInputBoat(int playerNum);
void sub_299C0(void);
void P_DHGetInput(int const playerNum);
void P_AddAmmo(DukePlayer_t * pPlayer, int weaponNum, int addAmount);
void P_AddWeapon(DukePlayer_t *pPlayer, int weaponNum);
void P_CheckWeapon(DukePlayer_t *pPlayer);
void P_DisplayScuba(void);
void P_DisplayWeapon(void);
void P_DropWeapon(int playerNum);
int P_FindOtherPlayer(int playerNum, int32_t *pDist);
void P_FragPlayer(int playerNum);
#ifdef YAX_ENABLE
void getzsofslope_player(int sectNum, int playerX, int playerY, int32_t *pCeilZ, int32_t *pFloorZ);
#endif
void P_UpdatePosWhenViewingCam(DukePlayer_t *pPlayer);
void P_ProcessInput(int playerNum);
void P_DHProcessInput(int playerNum);
void P_QuickKill(DukePlayer_t *pPlayer);
void P_SelectNextInvItem(DukePlayer_t *pPlayer);
void P_UpdateScreenPal(DukePlayer_t *pPlayer);
void P_EndLevel(void);
void P_CheckWeaponI(int playerNum);
int P_GetHudPal(const DukePlayer_t *pPlayer);
int P_GetKneePal(const DukePlayer_t *pPlayer);
int P_GetKneePal(const DukePlayer_t *pPlayer, int hudPal);
int P_GetOverheadPal(const DukePlayer_t *pPlayer);
void P_MadeNoise(int playerNum);
int P_HasKey(int sectNum, int playerNum);
// Get the player index given an APLAYER sprite pointer.
static inline int P_GetP(const void *pSprite)
{
#if 0 // unprotected player index retrieval
return spr->yvel;
#elif defined NETCODE_DISABLE
UNREFERENCED_PARAMETER(pSprite); // for NDEBUG build
// NOTE: In the no-netcode build, there's no point to pass player indices
// at all since there is ever only one player. However, merely returning 0
// would mean making this build less strict than the normal one.
Bassert(((const uspritetype *)pSprite)->yvel == 0);
return 0;
#else
int playerNum = ((const uspritetype *)pSprite)->yvel;
// [JM] Check against MAXPLAYERS as opposed to g_mostConcurrentPlayers
// to prevent CON for disconnected/fake players from executing as playernum 0.
if ((unsigned)playerNum >= MAXPLAYERS)
playerNum = 0;
return playerNum;
#endif
}
// Get the player index given an APLAYER sprite index.
static inline int P_Get(int32_t spriteNum) { return P_GetP((const uspritetype *)&sprite[spriteNum]); }
END_DUKE_NS
#endif

1197
source/duke/src/playmve.cpp Normal file

File diff suppressed because it is too large Load diff

100
source/duke/src/playmve.h Normal file
View file

@ -0,0 +1,100 @@
/*
* InterplayDecoder
* Copyright (C) 2020 sirlemonhead
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* This code is based on interplayvideo.c, dpcm.c and ipmovie.c from the FFmpeg project which can be obtained
* from http://www.ffmpeg.org/. Below is the license from interplayvideo.c
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Interplay MVE Video Decoder
* Copyright (C) 2003 The FFmpeg project
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#ifndef playmve_h_
#define playmve_h_
#include "baselayer.h"
#include "build.h"
#include "compat.h"
#include "pragmas.h"
bool playmve(const char* filename);
#define kMVETile (MAXTILES-1)
#define kMVEPal 5
#define CHUNK_PREAMBLE_SIZE 4
#define OPCODE_PREAMBLE_SIZE 4
#define CHUNK_INIT_AUDIO 0x0000
#define CHUNK_AUDIO_ONLY 0x0001
#define CHUNK_INIT_VIDEO 0x0002
#define CHUNK_VIDEO 0x0003
#define CHUNK_SHUTDOWN 0x0004
#define CHUNK_END 0x0005
/* these last types are used internally */
#define CHUNK_DONE 0xFFFC
#define CHUNK_NOMEM 0xFFFD
#define CHUNK_EOF 0xFFFE
#define CHUNK_BAD 0xFFFF
#define OPCODE_END_OF_STREAM 0x00
#define OPCODE_END_OF_CHUNK 0x01
#define OPCODE_CREATE_TIMER 0x02
#define OPCODE_INIT_AUDIO_BUFFERS 0x03
#define OPCODE_START_STOP_AUDIO 0x04
#define OPCODE_INIT_VIDEO_BUFFERS 0x05
#define OPCODE_UNKNOWN_06 0x06
#define OPCODE_SEND_BUFFER 0x07
#define OPCODE_AUDIO_FRAME 0x08
#define OPCODE_SILENCE_FRAME 0x09
#define OPCODE_INIT_VIDEO_MODE 0x0A
#define OPCODE_CREATE_GRADIENT 0x0B
#define OPCODE_SET_PALETTE 0x0C
#define OPCODE_SET_PALETTE_COMPRESSED 0x0D
#define OPCODE_UNKNOWN_0E 0x0E
#define OPCODE_SET_DECODING_MAP 0x0F
#define OPCODE_UNKNOWN_10 0x10
#define OPCODE_VIDEO_DATA 0x11
#define OPCODE_UNKNOWN_12 0x12
#define OPCODE_UNKNOWN_13 0x13
#define OPCODE_UNKNOWN_14 0x14
#define OPCODE_UNKNOWN_15 0x15
#define PALETTE_COUNT 256
#endif

2526
source/duke/src/premap.cpp Normal file

File diff suppressed because it is too large Load diff

52
source/duke/src/premap.h Normal file
View file

@ -0,0 +1,52 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef premap_h_
#define premap_h_
BEGIN_DUKE_NS
extern int16_t g_ambientLotag[64];
extern int16_t g_ambientHitag[64];
extern int32_t g_levelTextTime;
extern int32_t voting,vote_map,vote_episode;
int G_EnterLevel(int gameMode);
int G_FindLevelByFile(const char *fileName);
void G_CacheMapData(void);
void G_FreeMapState(int levelNum);
void G_NewGame(int volumeNum, int levelNum, int skillNum);
void G_ResetTimers(uint8_t keepgtics);
void G_UpdateScreenArea(void);
void P_RandomSpawnPoint(int playerNum);
void P_ResetInventory(int playerNum);
void P_ResetPlayer(int playerNum);
void P_ResetStatus(int playerNum);
void P_ResetWeapons(int playerNum);
void G_ClearFIFO(void);
void G_ResetInterpolations(void);
extern int32_t fragbarheight(void);
void G_SetFog(int fogtype);
void G_InitRRRASkies(void);
END_DUKE_NS
#endif

97
source/duke/src/quotes.h Normal file
View file

@ -0,0 +1,97 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2011 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef quotes_h_
#define quotes_h_
#include "quotemgr.h"
#define OBITQUOTEINDEX (MAXQUOTES-128)
#define SUICIDEQUOTEINDEX (MAXQUOTES-32)
#define QUOTE_SHOW_MAP_OFF 1
#define QUOTE_ACTIVATED 2
#define QUOTE_MEDKIT 3
#define QUOTE_LOCKED 4
#define QUOTE_CHEAT_EVERYTHING 5
#define QUOTE_BOOTS 6
#define QUOTE_WASTED 7
#define QUOTE_UNLOCKED 8
#define QUOTE_FOUND_SECRET 9
#define QUOTE_SQUISHED 10
#define QUOTE_USED_STEROIDS 12
#define QUOTE_DEAD 13
#define QUOTE_DEACTIVATED 15
#define QUOTE_CHEAT_GODMODE_ON 17
#define QUOTE_CHEAT_GODMODE_OFF 18
#define QUOTE_CROSSHAIR_OFF 21
#define QUOTE_CHEATS_DISABLED 22
#define QUOTE_MESSAGES_ON 23
#define QUOTE_MESSAGES_OFF 24
#define QUOTE_MUSIC 26
#define QUOTE_CHEAT_STEROIDS 37
#define QUOTE_F1HELP 40
#define QUOTE_MOUSE_AIMING_OFF 44
#define QUOTE_HOLODUKE_ON 47
#define QUOTE_HOLODUKE_OFF 48
#define QUOTE_HOLODUKE_NOT_FOUND 49
#define QUOTE_JETPACK_NOT_FOUND 50
#define QUOTE_JETPACK_ON 52
#define QUOTE_JETPACK_OFF 53
#define QUOTE_NEED_BLUE_KEY 70
#define QUOTE_NEED_RED_KEY 71
#define QUOTE_NEED_YELLOW_KEY 72
#define QUOTE_WEAPON_LOWERED 73
#define QUOTE_WEAPON_RAISED 74
#define QUOTE_BOOTS_ON 75
#define QUOTE_SCUBA_ON 76
#define QUOTE_CHEAT_ALLEN 79
#define QUOTE_MIGHTY_FOOT 80
#define QUOTE_WEAPON_MODE_OFF 82
#define QUOTE_MAP_FOLLOW_OFF 83
#define QUOTE_RUN_MODE_OFF 85
#define QUOTE_JETPACK 88
#define QUOTE_SCUBA 89
#define QUOTE_STEROIDS 90
#define QUOTE_HOLODUKE 91
#define QUOTE_CHEAT_TODD 99
#define QUOTE_CHEAT_UNLOCK 100
#define QUOTE_NVG 101
#define QUOTE_WEREGONNAFRYYOURASS 102
#define QUOTE_SCREEN_SAVED 103
#define QUOTE_CHEAT_BETA 105
#define QUOTE_NVG_OFF 107
#define QUOTE_VIEW_MODE_OFF 109
#define QUOTE_SHOW_MAP_ON 111
#define QUOTE_CHEAT_NOCLIP 113
#define QUOTE_SAVE_BAD_VERSION 114
#define QUOTE_RESERVED 115
#define QUOTE_RESERVED2 116
#define QUOTE_RESERVED3 117
#define QUOTE_SAVE_DEAD 118
#define QUOTE_CHEAT_ALL_WEAPONS 119
#define QUOTE_CHEAT_ALL_INV 120
#define QUOTE_CHEAT_ALL_KEYS 121
#define QUOTE_RESERVED4 122
#define QUOTE_SAVE_BAD_PLAYERS 124
#endif

4476
source/duke/src/rrdh.cpp Normal file

File diff suppressed because it is too large Load diff

110
source/duke/src/rrdh.h Normal file
View file

@ -0,0 +1,110 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
Copyright (C) 2020 Nuke.YKT
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
BEGIN_DUKE_NS
int rrdh_random(void);
int ghcons_isanimalescapewall(short w);
int ghcons_isanimalescapesect(short s);
int ghtrophy_isakill(short a1);
int sub_535EC(void);
void ghdeploy_bias(short a1);
int ghcons_findnewspot(short a1);
void ghtrax_leavedroppings(short a1);
void ghtrax_leavetrax(short a1);
int ghtrax_isplrupwind(short a1, short a2);
int ghsound_pfiredgunnear(spritetype* a1, short a2);
int ghsound_pmadesound(spritetype* a1, short a2);
int ghsound_pmadecall(spritetype* a1, short a2);
void sub_5A250(int a1);
void sub_53304(void);
void sub_54DE0(void);
void ghtrophy_loadbestscores(void);
void sub_5A02C(void);
void sub_579A0(void);
void ghsound_ambientlooppoll(void);
int sub_51B68(void);
void sub_5469C(vec2_t const origin, int a1);
void ghstatbr_registerkillinfo(short a1, int a2, int a3);
char sub_54B80(void);
void ghpistol_fire(short snum);
void ghbow_fire(short snum);
void ghrifle_fire(short snum);
void ghshtgn_fire(short snum);
void ghsound_footstepsound(short a1, int a2);
void ghsound_plrtouchedsprite(short a1, short a2);
void ghdeploy_plrtouchedsprite(short a1, short a2);
int sub_57A40(int a1);
void sub_59C20(void);
void sub_52BA8(void);
int sub_57A60(int a1);
void sub_54A2C(void);
void sub_55F8C(void);
void sub_566F0(void);
void sub_558F4(void);
void sub_56AB8(void);
void sub_573C0(void);
void sub_59314(void);
void sub_55184(void);
void sub_57B24(void);
void sub_58388(void);
void sub_59B50(void);
void sub_59F80(int a1);
void sub_535DC(void);
void sub_57AC0(void);
void sub_566E8(void);
void sub_55F68(void);
void sub_558D0(void);
void sub_56AB0(void);
void sub_56780(void);
void sub_56020(void);
void sub_55988(void);
void sub_56B3C(void);
void sub_56724(void);
void sub_55FCC(void);
void sub_55934(void);
void sub_56AE4(void);
void ghdeploy_drop(int a1, int a2);
int sub_57AA0(int a1);
void ghtarget_hit(short a1, int a2);
void gharrow_spawnarrow(short snum);
void sub_58A30(int a1);
int sub_59B44(void);
void ghtarget_setanimal(short a1);
void ghpistol_render(short);
void ghrifle_render(short, int);
void ghshtgn_render(short);
void ghbow_render(short);
void sub_56EA8(void);
void ghtarget_move(void);
void gharrow_move(void);
void ghdeploy_move(void);
void sub_5524C(void);
void sub_519E8(int a1);
void sub_57B38(long cposx, long cposy, long czoom, short cang);
END_DUKE_NS

1633
source/duke/src/savegame.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,85 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef savegame_h_
#define savegame_h_
#include "game.h"
BEGIN_DUKE_NS
# define SV_MAJOR_VER 1
#define SV_MINOR_VER 7
#pragma pack(push,1)
struct savehead_t
{
char headerstr[11];
uint8_t majorver, minorver, ptrsize;
uint16_t bytever;
// 16 bytes
uint32_t userbytever;
uint32_t scriptcrc;
uint8_t recdiffsp;
// 4 bytes
int32_t reccnt, snapsiz;
// 8 bytes
uint8_t numplayers, volnum, levnum, skill;
// 286 bytes
uint8_t getPtrSize() const { return ptrsize; }
};
#pragma pack(pop)
int32_t sv_updatestate(int32_t frominit);
int32_t sv_readdiff(FileReader& fil);
uint32_t sv_writediff(FileWriter *fil);
int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h);
int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h);
int32_t sv_saveandmakesnapshot(FileWriter &fil, int8_t spot, bool isAutoSave = false);
void sv_freemem();
// XXX: The 'bitptr' decl really belongs into gamedef.h, but we don't want to
// pull all of it in savegame.c?
extern char *bitptr;
enum
{
P2I_BACK_BIT = 1,
P2I_ONLYNON0_BIT = 2,
P2I_FWD = 0,
P2I_BACK = 1,
P2I_FWD_NON0 = 0+2,
P2I_BACK_NON0 = 1+2,
};
void G_Util_PtrToIdx(void *ptr, int32_t count, const void *base, int32_t mode);
void G_Util_PtrToIdx2(void *ptr, int32_t count, size_t stride, const void *base, int32_t const mode);
END_DUKE_NS
#endif

1541
source/duke/src/sbar.cpp Normal file

File diff suppressed because it is too large Load diff

39
source/duke/src/sbar.h Normal file
View file

@ -0,0 +1,39 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
BEGIN_DUKE_NS
static FORCE_INLINE int32_t sbarsc(int32_t sc)
{
return scale(sc, ud.statusbarscale, 100);
}
int32_t sbarx16(int32_t x);
int32_t sbarxr16(int32_t x);
int32_t sbary16(int32_t y);
void G_DrawInventory(const DukePlayer_t *p);
void G_DrawStatusBar(int32_t snum);
END_DUKE_NS

2851
source/duke/src/screens.cpp Normal file

File diff suppressed because it is too large Load diff

44
source/duke/src/screens.h Normal file
View file

@ -0,0 +1,44 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
BEGIN_DUKE_NS
extern void G_DisplayExtraScreens(void);
extern void G_DisplayLogo(void);
extern void G_DoOrderScreen(void);
#ifdef DEBUGGINGAIDS
typedef struct {
uint32_t lastgtic;
uint32_t lastnumins, numins;
int32_t numonscreen;
} sprstat_t;
extern sprstat_t g_spriteStat;
#endif
extern int32_t dr_yxaspect, dr_viewingrange;
extern int32_t g_noLogoAnim, g_noLogo;
extern void G_FadePalette(int32_t r, int32_t g, int32_t b, int32_t e);
END_DUKE_NS

5312
source/duke/src/sector.cpp Normal file

File diff suppressed because it is too large Load diff

183
source/duke/src/sector.h Normal file
View file

@ -0,0 +1,183 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef sector_h_
#define sector_h_
#include "actors.h" // actor_t
#include "gamevars.h"
#include "macros.h"
#include "namesdyn.h" // for G_GetForcefieldPicnum()
#include "player.h" // playerspawn_t
BEGIN_DUKE_NS
#define MAXCYCLERS 1024
#define MAXANIMATES 1024
#define MAXANIMWALLS 512
#define MAXANIMPOINTS 2048
#define VIEWSCREEN_ACTIVE_DISTANCE 8192
extern uint8_t g_shadedSector[MAXSECTORS];
typedef struct {
int16_t wallnum, tag;
} animwalltype;
typedef struct {
// this needs to have a copy of everything related to the map/actor state
// see savegame.c
int32_t g_animateGoal[MAXANIMATES], g_animateVel[MAXANIMATES], g_animateCnt;
intptr_t g_animatePtr[MAXANIMATES];
int32_t lockclock;
vec2_t origins[MAXANIMPOINTS];
int32_t randomseed, g_globalRandom;
int32_t pskyidx;
int16_t SpriteDeletionQueue[1024],g_spriteDeleteQueuePos;
int16_t g_animateSect[MAXANIMATES];
int16_t g_cyclers[MAXCYCLERS][6];
int16_t g_mirrorWall[64], g_mirrorSector[64], g_mirrorCount;
int16_t g_animWallCnt;
int16_t g_cloudCnt,g_cloudSect[256],g_cloudX,g_cloudY;
int16_t g_cyclerCnt;
int32_t numsprites;
int16_t tailspritefree;
int16_t headspritesect[MAXSECTORS+1];
int16_t headspritestat[MAXSTATUS+1];
int16_t nextspritesect[MAXSPRITES];
int16_t nextspritestat[MAXSPRITES];
int16_t numsectors;
int16_t numwalls;
int16_t prevspritesect[MAXSPRITES];
int16_t prevspritestat[MAXSPRITES];
uint16_t g_earthquakeTime;
int8_t g_playerSpawnCnt;
FixedBitArray<MAXSECTORS> show2dsector;
actor_t actor[MAXSPRITES];
playerspawn_t g_playerSpawnPoints[MAXPLAYERS];
animwalltype animwall[MAXANIMWALLS];
usectortype sector[MAXSECTORS];
spriteext_t spriteext[MAXSPRITES];
uspritetype sprite[MAXSPRITES];
uwalltype wall[MAXWALLS];
#ifndef NEW_MAP_FORMAT
wallext_t wallext[MAXWALLS];
#endif
intptr_t *vars[MAXGAMEVARS];
#ifdef YAX_ENABLE
int32_t numyaxbunches;
# if !defined NEW_MAP_FORMAT
int16_t yax_bunchnum[MAXSECTORS][2];
int16_t yax_nextwall[MAXWALLS][2];
# endif
#endif
} mapstate_t;
typedef struct {
mapstate_t *savedstate;
} map_t;
void G_ActivateBySector(int sect,int spriteNum);
int S_FindMusicSFX(int sectNum, int *sndptr);
void A_CallSound2(int soundNum, int playerNum);
int A_CallSound(int sectNum,int spriteNum);
int A_CheckHitSprite(int spriteNum,int16_t *hitSprite);
void A_DamageObject(int spriteNum,int dmgSrc);
void A_DamageWall(int spr,int dawallnum,const vec3_t *pos,int weaponNum);
int __fastcall A_FindPlayer(const spritetype *pSprite,int32_t *dist);
void G_AlignWarpElevators(void);
int CheckDoorTile(int tileNum);
int CheckBlockDoorTile(int tileNum);
void G_AnimateCamSprite(int smoothRatio);
void G_AnimateWalls(void);
int G_ActivateWarpElevators(int s,int warpDir);
int G_CheckActivatorMotion(int lotag);
void G_DoSectorAnimations(void);
void G_OperateActivators(int lotag, int playerNum);
void G_OperateForceFields(int spriteNum,int wallTag);
void G_OperateMasterSwitches(int lotag);
void G_OperateRespawns(int lotag);
void G_OperateSectors(int sectNum,int spriteNum);
void P_HandleSharedKeys(int playerNum);
int GetAnimationGoal(const int32_t *animPtr);
int isanearoperator(int lotag);
int isanunderoperator(int lotag);
int P_ActivateSwitch(int playerNum, int wallOrSprite, int nSwitchType);
void P_CheckSectors(int playerNum);
void Sect_DamageCeiling(int sectNum);
int SetAnimation(int sectNum,int32_t *animPtr,int goalVal,int animVel);
void G_DoFurniture(int wallNum, int sectNum, int playerNum);
void G_DoTorch(void);
void G_DoJailDoor(void);
void G_MoveMineCart(void);
void G_Thunder(void);
#define FORCEFIELD_CSTAT (64+16+4+1)
// Returns W_FORCEFIELD if wall has a forcefield overpicnum, its overpicnum else.
static inline int G_GetForcefieldPicnum(int wallNum)
{
int tileNum = wall[wallNum].overpicnum;
if (tileNum == W_FORCEFIELD + 1 || tileNum == W_FORCEFIELD + 2)
tileNum = W_FORCEFIELD;
return tileNum;
}
// Returns the interpolated position of the camera that the player is looking
// through (using a viewscreen). <i> should be the player's ->newowner member.
static inline vec3_t G_GetCameraPosition(int32_t i, int32_t smoothratio)
{
const spritetype *const cs = &sprite[i];
const actor_t *const ca = &actor[i];
vec3_t cam = { ca->bpos.x + mulscale16(cs->x - ca->bpos.x, smoothratio),
ca->bpos.y + mulscale16(cs->y - ca->bpos.y, smoothratio),
ca->bpos.z + mulscale16(cs->z - ca->bpos.z, smoothratio)
};
return cam;
}
EXTERN_INLINE_HEADER int32_t G_CheckPlayerInSector(int32_t sect);
#if defined sector_c_ || !defined DISABLE_INLINING
EXTERN_INLINE int32_t G_CheckPlayerInSector(int32_t sect)
{
int32_t i;
for (TRAVERSE_CONNECT(i))
if ((unsigned)g_player[i].ps->i < MAXSPRITES && sprite[g_player[i].ps->i].sectnum == sect)
return i;
return -1;
}
#endif
END_DUKE_NS
#endif

418
source/duke/src/soundefs.h Normal file
View file

@ -0,0 +1,418 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#define KICK_HIT 0
#define PISTOL_RICOCHET 1
#define PISTOL_BODYHIT 2
#define PISTOL_FIRE 3
#define EJECT_CLIP 4
#define INSERT_CLIP 5
#define CHAINGUN_FIRE 6
#define RPG_SHOOT 7
#define POOLBALLHIT 8
#define RPG_EXPLODE 9
#define CAT_FIRE 10
#define SHRINKER_FIRE 11
#define ACTOR_SHRINKING 12
#define PIPEBOMB_BOUNCE 13
#define PIPEBOMB_EXPLODE 14
#define LASERTRIP_ONWALL 15
#define LASERTRIP_ARMING 16
#define LASERTRIP_EXPLODE 17
#define VENT_BUST 18
#define GLASS_BREAKING 19
#define GLASS_HEAVYBREAK 20
#define SHORT_CIRCUIT 21
#define ITEM_SPLASH 22
#define DUKE_BREATHING 23
#define DUKE_EXHALING 24
#define DUKE_GASP 25
#define SLIM_RECOG 26
// #define ENDSEQVOL3SND1 27
#define DUKE_URINATE 28
#define ENDSEQVOL3SND2 29
#define ENDSEQVOL3SND3 30
#define DUKE_PASSWIND 32
#define DUKE_CRACK 33
#define SLIM_ATTACK 34
#define SOMETHINGHITFORCE 35
#define DUKE_DRINKING 36
#define DUKE_KILLED1 37
#define DUKE_GRUNT 38
#define DUKE_HARTBEAT 39
#define DUKE_ONWATER 40
#define DUKE_DEAD 41
#define DUKE_LAND 42
#define DUKE_WALKINDUCTS 43
#define DUKE_GLAD 44
#define DUKE_YES 45
#define DUKE_HEHE 46
#define DUKE_SHUCKS 47
#define DUKE_UNDERWATER 48
#define DUKE_JETPACK_ON 49
#define DUKE_JETPACK_IDLE 50
#define DUKE_JETPACK_OFF 51
#define LIZTROOP_GROWL 52
#define LIZTROOP_TALK1 53
#define LIZTROOP_TALK2 54
#define LIZTROOP_TALK3 55
#define DUKETALKTOBOSS 56
#define LIZCAPT_GROWL 57
#define LIZCAPT_TALK1 58
#define LIZCAPT_TALK2 59
#define LIZCAPT_TALK3 60
#define LIZARD_BEG 61
#define LIZARD_PAIN 62
#define LIZARD_DEATH 63
#define LIZARD_SPIT 64
#define DRONE1_HISSRATTLE 65
#define DRONE1_HISSSCREECH 66
#define DUKE_TIP2 67
#define FLESH_BURNING 68
#define SQUISHED 69
#define TELEPORTER 70
#define ELEVATOR_ON 71
#define DUKE_KILLED3 72
#define ELEVATOR_OFF 73
#define DOOR_OPERATE1 74
#define SUBWAY 75
#define SWITCH_ON 76
#define FAN 77
#define DUKE_GETWEAPON3 78
#define FLUSH_TOILET 79
#define HOVER_CRAFT 80
#define EARTHQUAKE 81
#define INTRUDER_ALERT 82
#define END_OF_LEVEL_WARN 83
#define ENGINE_OPERATING 84
#define REACTOR_ON 85
#define COMPUTER_AMBIENCE 86
#define GEARS_GRINDING 87
#define BUBBLE_AMBIENCE 88
#define MACHINE_AMBIENCE 89
#define SEWER_AMBIENCE 90
#define WIND_AMBIENCE 91
#define SOMETHING_DRIPPING 92
#define STEAM_HISSING 93
#define THEATER_BREATH 94
#define BAR_MUSIC 95
#define BOS1_ROAM 96
#define BOS1_RECOG 97
#define BOS1_ATTACK1 98
#define BOS1_PAIN 99
#define BOS1_DYING 100
#define BOS2_ROAM 101
#define BOS2_RECOG 102
#define BOS2_ATTACK 103
#define BOS2_PAIN 104
#define BOS2_DYING 105
#define GETATOMICHEALTH 106
#define DUKE_GETWEAPON2 107
#define BOS3_DYING 108
#define SHOTGUN_FIRE 109
#define PRED_ROAM 110
#define PRED_RECOG 111
#define PRED_ATTACK 112
#define PRED_PAIN 113
#define PRED_DYING 114
#define CAPT_ROAM 115
#define CAPT_ATTACK 116
#define CAPT_RECOG 117
#define CAPT_PAIN 118
#define CAPT_DYING 119
#define PIG_ROAM 120
#define PIG_RECOG 121
#define PIG_ATTACK 122
#define PIG_PAIN 123
#define PIG_DYING 124
#define RECO_ROAM 125
#define RECO_RECOG 126
#define RECO_ATTACK 127
#define RECO_PAIN 128
#define RECO_DYING 129
#define DRON_ROAM 130
#define DRON_RECOG 131
#define DRON_ATTACK1 132
#define DRON_PAIN 133
#define DRON_DYING 134
#define COMM_ROAM 135
#define COMM_RECOG 136
#define COMM_ATTACK 137
#define COMM_PAIN 138
#define COMM_DYING 139
#define OCTA_ROAM 140
#define OCTA_RECOG 141
#define OCTA_ATTACK1 142
#define OCTA_PAIN 143
#define OCTA_DYING 144
#define TURR_ROAM 145
#define TURR_RECOG 146
#define TURR_ATTACK 147
#define DUMPSTER_MOVE 148
#define SLIM_DYING 149
#define BOS3_ROAM 150
#define BOS3_RECOG 151
#define BOS3_ATTACK1 152
#define BOS3_PAIN 153
#define BOS1_ATTACK2 154
#define COMM_SPIN 155
#define BOS1_WALK 156
#define DRON_ATTACK2 157
#define THUD 158
#define OCTA_ATTACK2 159
#define WIERDSHOT_FLY 160
#define TURR_PAIN 161
#define TURR_DYING 162
#define SLIM_ROAM 163
#define LADY_SCREAM 164
#define DOOR_OPERATE2 165
#define DOOR_OPERATE3 166
#define DOOR_OPERATE4 167
#define BORNTOBEWILDSND 168
#define SHOTGUN_COCK 169
#define GENERIC_AMBIENCE1 170
#define GENERIC_AMBIENCE2 171
#define GENERIC_AMBIENCE3 172
#define GENERIC_AMBIENCE4 173
#define GENERIC_AMBIENCE5 174
#define GENERIC_AMBIENCE6 175
#define BOS3_ATTACK2 176
#define GENERIC_AMBIENCE17 177
#define GENERIC_AMBIENCE18 178
#define GENERIC_AMBIENCE19 179
#define GENERIC_AMBIENCE20 180
#define GENERIC_AMBIENCE21 181
#define GENERIC_AMBIENCE22 182
#define SECRETLEVELSND 183
#define GENERIC_AMBIENCE8 184
#define GENERIC_AMBIENCE9 185
#define GENERIC_AMBIENCE10 186
#define GENERIC_AMBIENCE11 187
#define GENERIC_AMBIENCE12 188
#define GENERIC_AMBIENCE13 189
#define GENERIC_AMBIENCE14 190
#define GENERIC_AMBIENCE15 192
#define GENERIC_AMBIENCE16 193
#define FIRE_CRACKLE 194
#define BONUS_SPEECH1 195
#define BONUS_SPEECH2 196
#define BONUS_SPEECH3 197
#define PIG_CAPTURE_DUKE 198
#define BONUS_SPEECH4 199
#define DUKE_LAND_HURT 200
#define DUKE_HIT_STRIPPER1 201
#define DUKE_TIP1 202
#define DUKE_KILLED2 203
#define PRED_ROAM2 204
#define PIG_ROAM2 205
#define DUKE_GETWEAPON1 206
#define DUKE_SEARCH2 207
#define DUKE_CRACK2 208
#define DUKE_SEARCH 209
#define DUKE_GET 210
#define DUKE_LONGTERM_PAIN 211
#define MONITOR_ACTIVE 212
#define NITEVISION_ONOFF 213
#define DUKE_HIT_STRIPPER2 214
#define DUKE_CRACK_FIRST 215
#define DUKE_USEMEDKIT 216
#define DUKE_TAKEPILLS 217
#define DUKE_PISSRELIEF 218
#define SELECT_WEAPON 219
#define WATER_GURGLE 220
#define DUKE_GETWEAPON4 221
#define JIBBED_ACTOR1 222
#define JIBBED_ACTOR2 223
#define JIBBED_ACTOR3 224
#define JIBBED_ACTOR4 225
#define JIBBED_ACTOR5 226
#define JIBBED_ACTOR6 227
#define JIBBED_ACTOR7 228
#define DUKE_GOTHEALTHATLOW 229
#define BOSSTALKTODUKE 230
#define WAR_AMBIENCE1 231
#define WAR_AMBIENCE2 232
#define WAR_AMBIENCE3 233
#define WAR_AMBIENCE4 234
#define WAR_AMBIENCE5 235
#define WAR_AMBIENCE6 236
#define WAR_AMBIENCE7 237
#define WAR_AMBIENCE8 238
#define WAR_AMBIENCE9 239
#define WAR_AMBIENCE10 240
#define ALIEN_TALK1 241
#define ALIEN_TALK2 242
#define EXITMENUSOUND 243
#define FLY_BY 244
#define DUKE_SCREAM 245
#define SHRINKER_HIT 246
#define RATTY 247
#define INTO_MENU 248
#define BONUSMUSIC 249
#define DUKE_BOOBY 250
#define DUKE_TALKTOBOSSFALL 251
#define DUKE_LOOKINTOMIRROR 252
#define PIG_ROAM3 253
#define KILLME 254
#define DRON_JETSND 255
#define SPACE_DOOR1 256
#define SPACE_DOOR2 257
#define SPACE_DOOR3 258
#define SPACE_DOOR4 259
#define SPACE_DOOR5 260
#define ALIEN_ELEVATOR1 261
#define VAULT_DOOR 262
#define JIBBED_ACTOR13 263
#define DUKE_GETWEAPON6 264
#define JIBBED_ACTOR8 265
#define JIBBED_ACTOR9 266
#define JIBBED_ACTOR10 267
#define JIBBED_ACTOR11 268
#define JIBBED_ACTOR12 269
#define DUKE_KILLED4 270
#define DUKE_KILLED5 271
#define ALIEN_SWITCH1 272
#define DUKE_STEPONFECES 273
#define DUKE_LONGTERM_PAIN2 274
#define DUKE_LONGTERM_PAIN3 275
#define DUKE_LONGTERM_PAIN4 276
#define COMPANB2 277
#define KTIT 278
#define HELICOP_IDLE 279
#define STEPNIT 280
#define SPACE_AMBIENCE1 281
#define SPACE_AMBIENCE2 282
#define SLIM_HATCH 283
#define RIPHEADNECK 284
#define FOUNDJONES 285
#define ALIEN_DOOR1 286
#define ALIEN_DOOR2 287
#define ENDSEQVOL3SND4 288
#define ENDSEQVOL3SND5 289
#define ENDSEQVOL3SND6 290
#define ENDSEQVOL3SND7 291
#define ENDSEQVOL3SND8 292
#define ENDSEQVOL3SND9 293
#define WHIPYOURASS 294
#define ENDSEQVOL2SND1 295
#define ENDSEQVOL2SND2 296
#define ENDSEQVOL2SND3 297
#define ENDSEQVOL2SND4 298
#define ENDSEQVOL2SND5 299
#define ENDSEQVOL2SND6 300
#define ENDSEQVOL2SND7 301
#define GENERIC_AMBIENCE23 302
#define SOMETHINGFROZE 303
#define DUKE_LONGTERM_PAIN5 304
#define DUKE_LONGTERM_PAIN6 305
#define DUKE_LONGTERM_PAIN7 306
#define DUKE_LONGTERM_PAIN8 307
#define WIND_REPEAT 308
#define MYENEMY_ROAM 309
#define MYENEMY_HURT 310
#define MYENEMY_DEAD 311
#define MYENEMY_SHOOT 312
#define STORE_MUSIC 313
#define STORE_MUSIC_BROKE 314
#define ACTOR_GROWING 315
#define NEWBEAST_ROAM 316
#define NEWBEAST_RECOG 317
#define NEWBEAST_ATTACK 318
#define NEWBEAST_PAIN 319
#define NEWBEAST_DYING 320
#define NEWBEAST_SPIT 321
#define VOL4_1 322
#define SUPERMARKET 323
#define MOUSEANNOY 324
#define BOOKEM 325
#define SUPERMARKETCRY 326
#define DESTRUCT 327
#define EATFOOD 328
#define MAKEMYDAY 329
#define WITNESSSTAND 330
#define VACATIONSPEECH 331
#define YIPPEE1 332
#define YOHOO1 333
#define YOHOO2 334
#define DOLPHINSND 335
#define TOUGHGALSND1 336
#define TOUGHGALSND2 337
#define TOUGHGALSND3 338
#define TOUGHGALSND4 339
#define TANK_ROAM 340
#define BOS4_ROAM 341
#define BOS4_RECOG 342
#define BOS4_ATTACK 343
#define BOS4_PAIN 344
#define BOS4_DYING 345
#define NEWBEAST_ATTACKMISS 346
#define VOL4_2 347
#define COOKINGDEEPFRIER 348
#define WHINING_DOG 349
#define DEAD_DOG 350
#define LIGHTNING_SLAP 351
#define THUNDER 352
#define HAPPYMOUSESND1 353
#define HAPPYMOUSESND2 354
#define HAPPYMOUSESND3 355
#define HAPPYMOUSESND4 356
#define ALARM 357
#define RAIN 358
#define DTAG_GREENRUN 359
#define DTAG_BROWNRUN 360
#define DTAG_GREENSCORE 361
#define DTAG_BROWNSCORE 362
#define INTRO4_1 363
#define INTRO4_2 364
#define INTRO4_3 365
#define INTRO4_4 366
#define INTRO4_5 367
#define INTRO4_6 368
#define SCREECH 369
#define BOSS4_DEADSPEECH 370
#define BOSS4_FIRSTSEE 371
#define PARTY_SPEECH 372
#define POSTAL_SPEECH 373
#define TGSPEECH 374
#define DOGROOMSPEECH 375
#define SMACKED 376
#define MDEVSPEECH 377
#define AREA51SPEECH 378
#define JEEPSOUND 379
#define BIGDOORSLAM 380
#define BOS4_LAY 381
#define WAVESOUND 382
#define ILLBEBACK 383
#define VOL4ENDSND1 384
#define VOL4ENDSND2 385
#define EXPANDERHIT 386
#define SNAKESPEECH 387
#define EXPANDERSHOOT 388
#define GETBACKTOWORK 389
#define JIBBED_ACTOR14 390
#define JIBBED_ACTOR15 391
#define INTRO4_B 392
#define BIGBANG 393
#define HORNSND 394
#define BELLSND 395
#define GOAWAY 396
#define JOKE 397

619
source/duke/src/sounds.cpp Normal file
View file

@ -0,0 +1,619 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
Copyright (C) 2019 Christoph Oelckers
This is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "compat.h"
#include "duke3d.h"
#include "raze_music.h"
#include "mapinfo.h"
#include "raze_sound.h"
BEGIN_DUKE_NS
class DukeSoundEngine : public SoundEngine
{
// client specific parts of the sound engine go in this class.
void CalcPosVel(int type, const void* source, const float pt[3], int channum, int chanflags, FSoundID chanSound, FVector3* pos, FVector3* vel, FSoundChan* chan) override;
TArray<uint8_t> ReadSound(int lumpnum) override;
public:
DukeSoundEngine()
{
S_Rolloff.RolloffType = ROLLOFF_Doom; // Seems like Duke uses the same rolloff type as Doom.
S_Rolloff.MinDistance = 144; // was originally 576 which looks like a bug and sounds like crap.
S_Rolloff.MaxDistance = 1088;
}
void StopChannel(FSoundChan* chan) override
{
if (chan && chan->SysChannel != NULL && !(chan->ChanFlags & CHANF_EVICTED) && chan->SourceType == SOURCE_Actor)
{
chan->Source = NULL;
chan->SourceType = SOURCE_Unattached;
}
SoundEngine::StopChannel(chan);
}
};
void S_InitSound()
{
soundEngine = new DukeSoundEngine;
}
//==========================================================================
//
//
//
//==========================================================================
TArray<uint8_t> DukeSoundEngine::ReadSound(int lumpnum)
{
auto wlump = fileSystem.OpenFileReader(lumpnum);
return wlump.Read();
}
//==========================================================================
//
//
//
//==========================================================================
void cacheAllSounds(void)
{
auto& sfx = soundEngine->GetSounds();
int i = 0;
for(auto &snd : sfx)
{
soundEngine->CacheSound(&snd);
}
}
//==========================================================================
//
//
//
//==========================================================================
static inline int S_GetPitch(int num)
{
auto const* snd = soundEngine->GetUserData(num+1);
if (!snd) return 0;
int const range = abs(snd[kPitchEnd] - snd[kPitchStart]);
return (range == 0) ? snd[kPitchStart] : min(snd[kPitchStart], snd[kPitchEnd]) + rand() % range;
}
float S_ConvertPitch(int lpitch)
{
return pow(2, lpitch / 1200.); // I hope I got this right that ASS uses a linear scale where 1200 is a full octave.
}
int S_GetUserFlags(int num)
{
if (!soundEngine->isValidSoundId(num+1)) return 0;
auto const* snd = soundEngine->GetUserData(num + 1);
if (!snd) return 0;
return snd[kFlags];
}
//==========================================================================
//
//
//
//==========================================================================
int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpitch, int priority, int type, int distance, float volume)
{
if ((unsigned)index >= MAXSOUNDS)
return -1;
auto& S_sfx = soundEngine->GetSounds();
index++;
unsigned oldindex = S_sfx.Size();
if (index >= S_sfx.Size())
{
S_sfx.Resize(index + 1);
for (; oldindex <= index; oldindex++)
{
S_sfx[oldindex].Clear();
}
}
auto sfx = &S_sfx[index];
bool alreadydefined = !sfx->bTentative;
sfx->UserData.Resize(kMaxUserData);
auto sndinf = sfx->UserData.Data();
sndinf[kFlags] = type & ~SF_ONEINST_INTERNAL;
if (sndinf[kFlags] & SF_LOOP)
sndinf[kFlags] |= SF_ONEINST_INTERNAL;
sfx->lumpnum = S_LookupSound(filename);
sndinf[kPitchStart] = clamp(minpitch, INT16_MIN, INT16_MAX);
sndinf[kPitchEnd] = clamp(maxpitch, INT16_MIN, INT16_MAX);
sndinf[kPriority] = priority & 255;
sndinf[kVolAdjust] = clamp(distance, INT16_MIN, INT16_MAX);
sfx->Volume = volume;
sfx->NearLimit = 6;
sfx->bTentative = false;
sfx->name = filename;
return 0;
}
//==========================================================================
//
//
//
//==========================================================================
static int S_CalcDistAndAng(int spriteNum, int soundNum, int sectNum,
const vec3_t *cam, const vec3_t *pos, int *distPtr, FVector3 *sndPos)
{
// There's a lot of hackery going on here that could be mapped to rolloff and attenuation parameters.
// However, ultimately rolloff would also just reposition the sound source so this can remain as it is.
int orgsndist = 0, sndang = 0, sndist = 0, explosion = 0;
auto const* snd = soundEngine->GetUserData(soundNum + 1);
int userflags = snd ? snd[kFlags] : 0;
int dist_adjust = snd ? snd[kVolAdjust] : 0;
if (PN(spriteNum) != APLAYER || P_Get(spriteNum) != screenpeek)
{
orgsndist = sndist = FindDistance3D(cam->x - pos->x, cam->y - pos->y, (cam->z - pos->z));
if ((userflags & (SF_GLOBAL | SF_DTAG)) != SF_GLOBAL && S_IsAmbientSFX(spriteNum) && (sector[SECT(spriteNum)].lotag & 0xff) < 9) // ST_9_SLIDING_ST_DOOR
sndist = divscale14(sndist, SHT(spriteNum) + 1);
}
sndist += dist_adjust;
if (sndist < 0)
sndist = 0;
if (sectNum > -1 && sndist && PN(spriteNum) != MUSICANDSFX
&& !cansee(cam->x, cam->y, cam->z - (24 << 8), sectNum, SX(spriteNum), SY(spriteNum), SZ(spriteNum) - (24 << 8), SECT(spriteNum)))
sndist += sndist>>(RR?2:5);
// Here the sound distance was clamped to a minimum of 144*4.
// It's better to handle rolloff in the backend instead of whacking the sound origin here.
// That way the lower end can be made customizable instead of losing all precision right here at the source.
if (sndist < 0) sndist = 0;
if (distPtr)
{
*distPtr = sndist;
}
if (sndPos)
{
FVector3 sndorg = GetSoundPos(pos);
FVector3 campos = GetSoundPos(cam);
// Now calculate the virtual position in sound system coordinates.
FVector3 sndvec = sndorg - campos;
if (orgsndist > 0)
{
float scale = float(sndist) / orgsndist; // adjust by what was calculated above;
*sndPos = campos + sndvec * scale;
}
else *sndPos = campos;
}
return false;
}
//==========================================================================
//
//
//
//==========================================================================
void S_GetCamera(vec3_t** c, int32_t* ca, int32_t* cs)
{
if (ud.camerasprite == -1)
{
if (ud.overhead_on != 2)
{
if (c) *c = &CAMERA(pos);
if (cs) *cs = CAMERA(sect);
if (ca) *ca = fix16_to_int(CAMERA(q16ang));
}
else
{
auto pPlayer = g_player[screenpeek].ps;
if (c) *c = &pPlayer->pos;
if (cs) *cs = pPlayer->cursectnum;
if (ca) *ca = fix16_to_int(pPlayer->q16ang);
}
}
else
{
if (c) *c = &sprite[ud.camerasprite].pos;
if (cs) *cs = sprite[ud.camerasprite].sectnum;
if (ca) *ca = sprite[ud.camerasprite].ang;
}
}
//=========================================================================
//
// CalcPosVel
//
// The game specific part of the sound updater.
//
//=========================================================================
void DukeSoundEngine::CalcPosVel(int type, const void* source, const float pt[3], int channum, int chanflags, FSoundID chanSound, FVector3* pos, FVector3* vel, FSoundChan* chan)
{
if (pos != nullptr)
{
vec3_t* campos;
int32_t camsect;
S_GetCamera(&campos, nullptr, &camsect);
if (vel) vel->Zero();
if (type == SOURCE_Unattached)
{
pos->X = pt[0];
pos->Y = pt[1];
pos->Z = pt[2];
}
else if (type == SOURCE_Actor)
{
auto actor = (spritetype*)source;
assert(actor != nullptr);
if (actor != nullptr)
{
S_CalcDistAndAng(int(actor - sprite), chanSound - 1, camsect, campos, &actor->pos, nullptr, pos);
/*
if (vel) // DN3D does not properly maintain this.
{
vel->X = float(actor->Vel.X * TICRATE);
vel->Y = float(actor->Vel.Z * TICRATE);
vel->Z = float(actor->Vel.Y * TICRATE);
}
*/
}
}
if ((chanflags & CHANF_LISTENERZ) && campos != nullptr && type != SOURCE_None)
{
pos->Y = campos->z / 256.f;
}
}
}
//==========================================================================
//
//
//
//==========================================================================
void S_Update(void)
{
SoundListener listener;
vec3_t* c;
int32_t ca, cs;
auto& gm = g_player[myconnectindex].ps->gm;
if (RR && !Mus_IsPlaying() && (gm && gm & MODE_GAME))
S_PlayRRMusic();
S_GetCamera(&c, &ca, &cs);
if (c != nullptr)
{
listener.angle = -(float)ca * pi::pi() / 1024; // Build uses a period of 2048.
listener.velocity.Zero();
listener.position = GetSoundPos(c);
listener.underwater = false;
// This should probably use a real environment instead of the pitch hacking in S_PlaySound3D.
// listenactor->waterlevel == 3;
//assert(primaryLevel->Zones.Size() > listenactor->Sector->ZoneNumber);
listener.Environment = 0;// primaryLevel->Zones[listenactor->Sector->ZoneNumber].Environment;
listener.valid = true;
}
else
{
listener.angle = 0;
listener.position.Zero();
listener.velocity.Zero();
listener.underwater = false;
listener.Environment = nullptr;
listener.valid = false;
}
listener.ListenerObject = ud.camerasprite == -1 ? nullptr : &sprite[ud.camerasprite];
soundEngine->SetListener(listener);
soundEngine->UpdateSounds((int)totalclock);
}
//==========================================================================
//
//
//
//==========================================================================
int S_PlaySound3D(int sndnum, int spriteNum, const vec3_t* pos, int channel, EChanFlags flags)
{
auto const pPlayer = g_player[myconnectindex].ps;
if (!soundEngine->isValidSoundId(sndnum+1) || !SoundEnabled() || (unsigned)spriteNum >= MAXSPRITES || (pPlayer->gm & MODE_MENU) ||
(pPlayer->timebeforeexit > 0 && pPlayer->timebeforeexit <= GAMETICSPERSEC * 3)) return -1;
int userflags = S_GetUserFlags(sndnum);
if ((!(snd_speech & 1) && (userflags & SF_TALK)) || ((userflags & SF_ADULT) && adult_lockout))
return -1;
// Duke talk
if (userflags & SF_TALK)
{
if ((g_netServer || ud.multimode > 1) && PN(spriteNum) == APLAYER && P_Get(spriteNum) != screenpeek) // other player sound
{
if ((snd_speech & 4) != 4)
return -1;
}
else if ((snd_speech & 1) != 1)
return -1;
bool foundone = soundEngine->EnumerateChannels([&](FSoundChan* chan)
{
auto sid = chan->OrgID;
auto flags = S_GetUserFlags(sid - 1);
return !!(flags & SF_TALK);
});
// don't play if any Duke talk sounds are already playing
if (foundone) return -1;
}
else if ((userflags & (SF_DTAG | SF_GLOBAL)) == SF_DTAG) // Duke-Tag sound
{
return S_PlaySound(sndnum);
}
int32_t sndist;
FVector3 sndpos; // this is in sound engine space.
vec3_t* campos;
int32_t camsect;
S_GetCamera(&campos, nullptr, &camsect);
S_CalcDistAndAng(spriteNum, sndnum, camsect, campos, pos, &sndist, &sndpos);
int pitch = S_GetPitch(sndnum);
auto const pOther = g_player[screenpeek].ps;
if (pOther->sound_pitch)
pitch += pOther->sound_pitch;
bool explosionp = ((userflags & (SF_GLOBAL | SF_DTAG)) == (SF_GLOBAL | SF_DTAG)) || ((sndnum == PIPEBOMB_EXPLODE || sndnum == LASERTRIP_EXPLODE || sndnum == RPG_EXPLODE));
if (explosionp)
{
if (pOther->cursectnum > -1 && sector[pOther->cursectnum].lotag == ST_2_UNDERWATER)
pitch -= 1024;
}
else
{
if (sndist > 32767 && PN(spriteNum) != MUSICANDSFX && (userflags & (SF_LOOP | SF_MSFX)) == 0)
return -1;
if (pOther->cursectnum > -1 && sector[pOther->cursectnum].lotag == ST_2_UNDERWATER
&& (userflags & SF_TALK) == 0)
pitch = -768;
}
bool is_playing = soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, sndnum+1);
if (is_playing && PN(spriteNum) != MUSICANDSFX)
S_StopEnvSound(sndnum, spriteNum);
int const repeatp = (userflags & SF_LOOP);
if (repeatp && (userflags & SF_ONEINST_INTERNAL) && is_playing)
{
return -1;
}
// These explosion sounds originally used some distance hackery to make them louder but due to how the rolloff was set up they always played at full volume as a result.
// I think it is better to lower their attenuation so that they are louder than the rest but still fade in the distance.
// For the original effect, attenuation needs to be set to ATTN_NONE here.
float attenuation;
if (explosionp) attenuation = 0.5f;
else attenuation = (userflags & (SF_GLOBAL | SF_DTAG)) == SF_GLOBAL ? ATTN_NONE : ATTN_NORM;
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
auto chan = soundEngine->StartSound(SOURCE_Actor, &sprite[spriteNum], &sndpos, CHAN_AUTO, flags, sndnum+1, attenuation == ATTN_NONE? 0.8f : 1.f, attenuation, nullptr, S_ConvertPitch(pitch));
return chan ? 0 : -1;
}
//==========================================================================
//
//
//
//==========================================================================
int S_PlaySound(int sndnum, int channel, EChanFlags flags)
{
if (!soundEngine->isValidSoundId(sndnum+1) || !SoundEnabled()) return -1;
int userflags = S_GetUserFlags(sndnum);
if ((!(snd_speech & 1) && (userflags & SF_TALK)) || ((userflags & SF_ADULT) && adult_lockout))
return -1;
int const pitch = S_GetPitch(sndnum);
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, sndnum + 1, 0.8f, ATTN_NONE, nullptr, S_ConvertPitch(pitch));
return chan ? 0 : -1;
}
//==========================================================================
//
//
//
//==========================================================================
int A_PlaySound(int soundNum, int spriteNum, int channel, EChanFlags flags)
{
return (unsigned)spriteNum >= MAXSPRITES ? S_PlaySound(soundNum, channel, flags) :
S_PlaySound3D(soundNum, spriteNum, &sprite[spriteNum].pos, channel, flags);
}
void S_StopEnvSound(int sndNum, int sprNum, int channel)
{
if (sprNum < -1 || sprNum >= MAXSPRITES) return;
if (sprNum == -1) soundEngine->StopSoundID(sndNum+1);
else
{
if (channel == -1) soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], -1, sndNum + 1);
else soundEngine->StopSound(SOURCE_Actor, &sprite[sprNum], channel, -1);
// StopSound kills the actor reference so this cannot be delayed until ChannelEnded gets called. At that point the actor may also not be valid anymore.
if (S_IsAmbientSFX(sprNum) && sector[SECT(sprNum)].lotag < 3) // ST_2_UNDERWATER
actor[sprNum].t_data[0] = 0;
}
}
void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset)
{
if (spriteNum < -1 || spriteNum >= MAXSPRITES) return;
double expitch = pow(2, pitchoffset / 1200.); // I hope I got this right that ASS uses a linear scale where 1200 is a full octave.
if (spriteNum == -1)
{
soundEngine->ChangeSoundPitch(SOURCE_Unattached, nullptr, CHAN_AUTO, expitch, soundNum+1);
}
else
{
soundEngine->ChangeSoundPitch(SOURCE_Actor, &sprite[spriteNum], CHAN_AUTO, expitch, soundNum+1);
}
}
//==========================================================================
//
//
//
//==========================================================================
int A_CheckSoundPlaying(int spriteNum, int soundNum, int channel)
{
if (spriteNum == -1) return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum+1);
if ((unsigned)spriteNum >= MAXSPRITES) return false;
return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, &sprite[spriteNum], channel, soundNum+1);
}
// Check if actor <i> is playing any sound.
int A_CheckAnySoundPlaying(int spriteNum)
{
if ((unsigned)spriteNum >= MAXSPRITES) return false;
return soundEngine->IsSourcePlayingSomething(SOURCE_Actor, &sprite[spriteNum], CHAN_AUTO, 0);
}
int S_CheckSoundPlaying(int soundNum)
{
return soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundNum+1);
}
//==========================================================================
//
//
//
//==========================================================================
void S_MenuSound(void)
{
static int SoundNum;
int const menusnds[] = {
LASERTRIP_EXPLODE, DUKE_GRUNT, DUKE_LAND_HURT, CHAINGUN_FIRE, SQUISHED, KICK_HIT,
PISTOL_RICOCHET, PISTOL_BODYHIT, PISTOL_FIRE, SHOTGUN_FIRE, BOS1_WALK, RPG_EXPLODE,
PIPEBOMB_BOUNCE, PIPEBOMB_EXPLODE, NITEVISION_ONOFF, RPG_SHOOT, SELECT_WEAPON,
};
int s = RR ? 390 : menusnds[SoundNum++ % ARRAY_SIZE(menusnds)];
if (s != -1)
S_PlaySound(s, CHAN_AUTO, CHANF_UI);
}
//==========================================================================
//
// Music
//
//==========================================================================
static bool cd_disabled = false; // This is in case mus_redbook is enabled but no tracks found so that the regular music system can be switched on.
static void S_SetMusicIndex(unsigned int m)
{
ud.music_episode = m / MAXLEVELS;
ud.music_level = m % MAXLEVELS;
}
void S_PlayLevelMusicOrNothing(unsigned int m)
{
auto& mr = m == USERMAPMUSICFAKESLOT ? userMapRecord : mapList[m];
if (RR && mr.music.IsEmpty() && mus_redbook && !cd_disabled) return;
Mus_Play(mr.labelName, mr.music, true);
S_SetMusicIndex(m);
}
int S_TryPlaySpecialMusic(unsigned int m)
{
if (RR) return 0; // Can only be MUS_LOADING, RR does not use it.
auto& musicfn = mapList[m].music;
if (musicfn.IsNotEmpty())
{
if (!Mus_Play(nullptr, musicfn, true))
{
S_SetMusicIndex(m);
return 0;
}
}
return 1;
}
void S_PlaySpecialMusicOrNothing(unsigned int m)
{
if (S_TryPlaySpecialMusic(m))
{
S_SetMusicIndex(m);
}
}
void S_PlayRRMusic(int newTrack)
{
if (!RR || !mus_redbook || cd_disabled || currentLevel->music.IsNotEmpty())
return;
Mus_Stop();
for (int i = 0; i < 10; i++)
{
g_cdTrack = newTrack != -1 ? newTrack : g_cdTrack + 1;
if (newTrack != 10 && (g_cdTrack > 9 || g_cdTrack < 2))
g_cdTrack = 2;
FStringf filename("track%02d.ogg", g_cdTrack);
if (Mus_Play(nullptr, filename, false)) return;
}
// If none of the tracks managed to start, disable the CD music for this session so that regular music can play if defined.
cd_disabled = true;
}
END_DUKE_NS

80
source/duke/src/sounds.h Normal file
View file

@ -0,0 +1,80 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2010 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
//****************************************************************************
//
// sounds.h
//
//****************************************************************************
#ifndef sounds_public_h_
#define sounds_public_h_
#include "sounds_common.h"
#include "raze_sound.h"
#include "raze_music.h"
BEGIN_DUKE_NS
#define MAXSOUNDS 4096
#define LOUDESTVOLUME 111
enum esound_t
{
kPitchStart,
kPitchEnd,
kVolAdjust,
kPriority,
kFlags,
kMaxUserData
};
int A_CheckSoundPlaying(int spriteNum, int soundNum, int channel = 0);
int A_PlaySound(int soundNum, int spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0);
int A_CheckAnySoundPlaying(int spriteNum);
int S_CheckSoundPlaying(int soundNum);
inline int S_CheckSoundPlaying(int sprnum, int soundNum) { return S_CheckSoundPlaying(soundNum); }
inline void S_ClearSoundLocks(void) {}
void cacheAllSounds(void);
void S_MenuSound(void);
void S_PlayLevelMusicOrNothing(unsigned int);
int S_TryPlaySpecialMusic(unsigned int);
void S_PlaySpecialMusicOrNothing(unsigned int);
void S_ContinueLevelMusic(void);
int S_PlaySound(int num, int channel = CHAN_AUTO, EChanFlags flags = 0);
int S_PlaySound3D(int num, int spriteNum, const vec3_t *pos, int channel = CHAN_AUTO, EChanFlags flags = 0);
void S_StopEnvSound(int sndNum,int sprNum, int flags = -1);
void S_Update(void);
void S_ChangeSoundPitch(int soundNum, int spriteNum, int pitchoffset);
int S_GetUserFlags(int sndnum);
int S_DefineSound(unsigned index, const char* filename, int ps, int pe, int pr, int m, int vo, float vol);
void S_InitSound();
void S_PlayRRMusic(int newTrack = -1);
static inline bool S_IsAmbientSFX(int spriteNum)
{
return (sprite[spriteNum].picnum == MUSICANDSFX && sprite[spriteNum].lotag < 999);
}
END_DUKE_NS
#endif

View file

@ -0,0 +1,38 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#ifndef EDUKE32_SOUNDS_COMMON_H
#define EDUKE32_SOUNDS_COMMON_H
// Sound flags
enum {
SF_LOOP = 1,
SF_MSFX = 2,
SF_TALK = 4,
SF_ADULT = 8,
SF_GLOBAL = 16,
SF_ONEINST_INTERNAL = 32,
SF_DTAG = 128,
};
#endif

View file

@ -0,0 +1,386 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "compat.h"
#include "build.h"
#include "namesdyn.h"
#include "sounds.h"
#include "soundsdyn.h"
#include "global.h"
BEGIN_DUKE_NS
#ifdef DYNSOUNDREMAP_ENABLE
# define DVPTR(x) &x
#else
# define DVPTR(x) NULL
#endif
int16_t DynamicSoundMap[MAXSOUNDS];
struct sdynitem
{
const char *str;
int32_t *dynvalptr;
const int16_t staticval;
};
static struct sdynitem g_dynSoundList[] =
{
{ "KICK_HIT", DVPTR(KICK_HIT), KICK_HIT__STATIC },
{ "PISTOL_RICOCHET", DVPTR(PISTOL_RICOCHET), PISTOL_RICOCHET__STATIC },
{ "PISTOL_BODYHIT", DVPTR(PISTOL_BODYHIT), PISTOL_BODYHIT__STATIC },
{ "PISTOL_FIRE", DVPTR(PISTOL_FIRE), PISTOL_FIRE__STATIC },
{ "EJECT_CLIP", DVPTR(EJECT_CLIP), EJECT_CLIP__STATIC },
{ "INSERT_CLIP", DVPTR(INSERT_CLIP), INSERT_CLIP__STATIC },
{ "CHAINGUN_FIRE", DVPTR(CHAINGUN_FIRE), CHAINGUN_FIRE__STATIC },
{ "RPG_SHOOT", DVPTR(RPG_SHOOT), RPG_SHOOT__STATIC },
{ "POOLBALLHIT", DVPTR(POOLBALLHIT), POOLBALLHIT__STATIC },
{ "RPG_EXPLODE", DVPTR(RPG_EXPLODE), RPG_EXPLODE__STATIC },
{ "CAT_FIRE", DVPTR(CAT_FIRE), CAT_FIRE__STATIC },
{ "SHRINKER_FIRE", DVPTR(SHRINKER_FIRE), SHRINKER_FIRE__STATIC },
{ "PIPEBOMB_BOUNCE", DVPTR(PIPEBOMB_BOUNCE), PIPEBOMB_BOUNCE__STATIC },
{ "PIPEBOMB_EXPLODE", DVPTR(PIPEBOMB_EXPLODE), PIPEBOMB_EXPLODE__STATIC },
{ "LASERTRIP_ONWALL", DVPTR(LASERTRIP_ONWALL), LASERTRIP_ONWALL__STATIC },
{ "LASERTRIP_ARMING", DVPTR(LASERTRIP_ARMING), LASERTRIP_ARMING__STATIC },
{ "LASERTRIP_EXPLODE", DVPTR(LASERTRIP_EXPLODE), LASERTRIP_EXPLODE__STATIC },
{ "VENT_BUST", DVPTR(VENT_BUST), VENT_BUST__STATIC },
{ "GLASS_BREAKING", DVPTR(GLASS_BREAKING), GLASS_BREAKING__STATIC },
{ "GLASS_HEAVYBREAK", DVPTR(GLASS_HEAVYBREAK), GLASS_HEAVYBREAK__STATIC },
{ "SHORT_CIRCUIT", DVPTR(SHORT_CIRCUIT), SHORT_CIRCUIT__STATIC },
{ "ITEM_SPLASH", DVPTR(ITEM_SPLASH), ITEM_SPLASH__STATIC },
{ "DUKE_GASP", DVPTR(DUKE_GASP), DUKE_GASP__STATIC },
{ "SLIM_RECOG", DVPTR(SLIM_RECOG), SLIM_RECOG__STATIC },
{ "DUKE_URINATE", DVPTR(DUKE_URINATE), DUKE_URINATE__STATIC },
{ "ENDSEQVOL3SND2", DVPTR(ENDSEQVOL3SND2), ENDSEQVOL3SND2__STATIC },
{ "ENDSEQVOL3SND3", DVPTR(ENDSEQVOL3SND3), ENDSEQVOL3SND3__STATIC },
{ "DUKE_CRACK", DVPTR(DUKE_CRACK), DUKE_CRACK__STATIC },
{ "SLIM_ATTACK", DVPTR(SLIM_ATTACK), SLIM_ATTACK__STATIC },
{ "SOMETHINGHITFORCE", DVPTR(SOMETHINGHITFORCE), SOMETHINGHITFORCE__STATIC },
{ "DUKE_DRINKING", DVPTR(DUKE_DRINKING), DUKE_DRINKING__STATIC },
{ "DUKE_GRUNT", DVPTR(DUKE_GRUNT), DUKE_GRUNT__STATIC },
{ "DUKE_HARTBEAT", DVPTR(DUKE_HARTBEAT), DUKE_HARTBEAT__STATIC },
{ "DUKE_ONWATER", DVPTR(DUKE_ONWATER), DUKE_ONWATER__STATIC },
{ "DUKE_LAND", DVPTR(DUKE_LAND), DUKE_LAND__STATIC },
{ "DUKE_WALKINDUCTS", DVPTR(DUKE_WALKINDUCTS), DUKE_WALKINDUCTS__STATIC },
{ "DUKE_UNDERWATER", DVPTR(DUKE_UNDERWATER), DUKE_UNDERWATER__STATIC },
{ "DUKE_JETPACK_ON", DVPTR(DUKE_JETPACK_ON), DUKE_JETPACK_ON__STATIC },
{ "DUKE_JETPACK_IDLE", DVPTR(DUKE_JETPACK_IDLE), DUKE_JETPACK_IDLE__STATIC },
{ "DUKE_JETPACK_OFF", DVPTR(DUKE_JETPACK_OFF), DUKE_JETPACK_OFF__STATIC },
{ "DUKETALKTOBOSS", DVPTR(DUKETALKTOBOSS), DUKETALKTOBOSS__STATIC },
{ "SQUISHED", DVPTR(SQUISHED), SQUISHED__STATIC },
{ "TELEPORTER", DVPTR(TELEPORTER), TELEPORTER__STATIC },
{ "ELEVATOR_ON", DVPTR(ELEVATOR_ON), ELEVATOR_ON__STATIC },
{ "ELEVATOR_OFF", DVPTR(ELEVATOR_OFF), ELEVATOR_OFF__STATIC },
{ "SUBWAY", DVPTR(SUBWAY), SUBWAY__STATIC },
{ "SWITCH_ON", DVPTR(SWITCH_ON), SWITCH_ON__STATIC },
{ "FLUSH_TOILET", DVPTR(FLUSH_TOILET), FLUSH_TOILET__STATIC },
{ "EARTHQUAKE", DVPTR(EARTHQUAKE), EARTHQUAKE__STATIC },
{ "END_OF_LEVEL_WARN", DVPTR(END_OF_LEVEL_WARN), END_OF_LEVEL_WARN__STATIC },
{ "WIND_AMBIENCE", DVPTR(WIND_AMBIENCE), WIND_AMBIENCE__STATIC },
{ "SOMETHING_DRIPPING", DVPTR(SOMETHING_DRIPPING), SOMETHING_DRIPPING__STATIC },
{ "BOS1_RECOG", DVPTR(BOS1_RECOG), BOS1_RECOG__STATIC },
{ "BOS2_RECOG", DVPTR(BOS2_RECOG), BOS2_RECOG__STATIC },
{ "DUKE_GETWEAPON2", DVPTR(DUKE_GETWEAPON2), DUKE_GETWEAPON2__STATIC },
{ "SHOTGUN_FIRE", DVPTR(SHOTGUN_FIRE), SHOTGUN_FIRE__STATIC },
{ "PRED_RECOG", DVPTR(PRED_RECOG), PRED_RECOG__STATIC },
{ "CAPT_RECOG", DVPTR(CAPT_RECOG), CAPT_RECOG__STATIC },
{ "PIG_RECOG", DVPTR(PIG_RECOG), PIG_RECOG__STATIC },
{ "RECO_ROAM", DVPTR(RECO_ROAM), RECO_ROAM__STATIC },
{ "RECO_RECOG", DVPTR(RECO_RECOG), RECO_RECOG__STATIC },
{ "RECO_ATTACK", DVPTR(RECO_ATTACK), RECO_ATTACK__STATIC },
{ "RECO_PAIN", DVPTR(RECO_PAIN), RECO_PAIN__STATIC },
{ "DRON_RECOG", DVPTR(DRON_RECOG), DRON_RECOG__STATIC },
{ "COMM_RECOG", DVPTR(COMM_RECOG), COMM_RECOG__STATIC },
{ "OCTA_RECOG", DVPTR(OCTA_RECOG), OCTA_RECOG__STATIC },
{ "TURR_RECOG", DVPTR(TURR_RECOG), TURR_RECOG__STATIC },
{ "SLIM_DYING", DVPTR(SLIM_DYING), SLIM_DYING__STATIC },
{ "BOS3_RECOG", DVPTR(BOS3_RECOG), BOS3_RECOG__STATIC },
{ "BOS1_WALK", DVPTR(BOS1_WALK), BOS1_WALK__STATIC },
{ "THUD", DVPTR(THUD), THUD__STATIC },
{ "WIERDSHOT_FLY", DVPTR(WIERDSHOT_FLY), WIERDSHOT_FLY__STATIC },
{ "SLIM_ROAM", DVPTR(SLIM_ROAM), SLIM_ROAM__STATIC },
{ "SHOTGUN_COCK", DVPTR(SHOTGUN_COCK), SHOTGUN_COCK__STATIC },
{ "GENERIC_AMBIENCE17", DVPTR(GENERIC_AMBIENCE17), GENERIC_AMBIENCE17__STATIC },
{ "BONUS_SPEECH1", DVPTR(BONUS_SPEECH1), BONUS_SPEECH1__STATIC },
{ "BONUS_SPEECH2", DVPTR(BONUS_SPEECH2), BONUS_SPEECH2__STATIC },
{ "BONUS_SPEECH3", DVPTR(BONUS_SPEECH3), BONUS_SPEECH3__STATIC },
{ "BONUS_SPEECH4", DVPTR(BONUS_SPEECH4), BONUS_SPEECH4__STATIC },
{ "DUKE_LAND_HURT", DVPTR(DUKE_LAND_HURT), DUKE_LAND_HURT__STATIC },
{ "DUKE_SEARCH2", DVPTR(DUKE_SEARCH2), DUKE_SEARCH2__STATIC },
{ "DUKE_CRACK2", DVPTR(DUKE_CRACK2), DUKE_CRACK2__STATIC },
{ "DUKE_SEARCH", DVPTR(DUKE_SEARCH), DUKE_SEARCH__STATIC },
{ "DUKE_GET", DVPTR(DUKE_GET), DUKE_GET__STATIC },
{ "DUKE_LONGTERM_PAIN", DVPTR(DUKE_LONGTERM_PAIN), DUKE_LONGTERM_PAIN__STATIC },
{ "MONITOR_ACTIVE", DVPTR(MONITOR_ACTIVE), MONITOR_ACTIVE__STATIC },
{ "NITEVISION_ONOFF", DVPTR(NITEVISION_ONOFF), NITEVISION_ONOFF__STATIC },
{ "DUKE_CRACK_FIRST", DVPTR(DUKE_CRACK_FIRST), DUKE_CRACK_FIRST__STATIC },
{ "DUKE_USEMEDKIT", DVPTR(DUKE_USEMEDKIT), DUKE_USEMEDKIT__STATIC },
{ "DUKE_TAKEPILLS", DVPTR(DUKE_TAKEPILLS), DUKE_TAKEPILLS__STATIC },
{ "DUKE_PISSRELIEF", DVPTR(DUKE_PISSRELIEF), DUKE_PISSRELIEF__STATIC },
{ "SELECT_WEAPON", DVPTR(SELECT_WEAPON), SELECT_WEAPON__STATIC },
{ "JIBBED_ACTOR5", DVPTR(JIBBED_ACTOR5), JIBBED_ACTOR5__STATIC },
{ "JIBBED_ACTOR6", DVPTR(JIBBED_ACTOR6), JIBBED_ACTOR6__STATIC },
{ "DUKE_GOTHEALTHATLOW", DVPTR(DUKE_GOTHEALTHATLOW), DUKE_GOTHEALTHATLOW__STATIC },
{ "BOSSTALKTODUKE", DVPTR(BOSSTALKTODUKE), BOSSTALKTODUKE__STATIC },
{ "WAR_AMBIENCE2", DVPTR(WAR_AMBIENCE2), WAR_AMBIENCE2__STATIC },
{ "EXITMENUSOUND", DVPTR(EXITMENUSOUND), EXITMENUSOUND__STATIC },
{ "FLY_BY", DVPTR(FLY_BY), FLY_BY__STATIC },
{ "DUKE_SCREAM", DVPTR(DUKE_SCREAM), DUKE_SCREAM__STATIC },
{ "SHRINKER_HIT", DVPTR(SHRINKER_HIT), SHRINKER_HIT__STATIC },
{ "RATTY", DVPTR(RATTY), RATTY__STATIC },
{ "BONUSMUSIC", DVPTR(BONUSMUSIC), BONUSMUSIC__STATIC },
{ "DUKE_GETWEAPON6", DVPTR(DUKE_GETWEAPON6), DUKE_GETWEAPON6__STATIC },
{ "ALIEN_SWITCH1", DVPTR(ALIEN_SWITCH1), ALIEN_SWITCH1__STATIC },
{ "RIPHEADNECK", DVPTR(RIPHEADNECK), RIPHEADNECK__STATIC },
{ "ENDSEQVOL3SND4", DVPTR(ENDSEQVOL3SND4), ENDSEQVOL3SND4__STATIC },
{ "ENDSEQVOL3SND5", DVPTR(ENDSEQVOL3SND5), ENDSEQVOL3SND5__STATIC },
{ "ENDSEQVOL3SND6", DVPTR(ENDSEQVOL3SND6), ENDSEQVOL3SND6__STATIC },
{ "ENDSEQVOL3SND7", DVPTR(ENDSEQVOL3SND7), ENDSEQVOL3SND7__STATIC },
{ "ENDSEQVOL3SND8", DVPTR(ENDSEQVOL3SND8), ENDSEQVOL3SND8__STATIC },
{ "ENDSEQVOL3SND9", DVPTR(ENDSEQVOL3SND9), ENDSEQVOL3SND9__STATIC },
{ "WHIPYOURASS", DVPTR(WHIPYOURASS), WHIPYOURASS__STATIC },
{ "ENDSEQVOL2SND1", DVPTR(ENDSEQVOL2SND1), ENDSEQVOL2SND1__STATIC },
{ "ENDSEQVOL2SND2", DVPTR(ENDSEQVOL2SND2), ENDSEQVOL2SND2__STATIC },
{ "ENDSEQVOL2SND3", DVPTR(ENDSEQVOL2SND3), ENDSEQVOL2SND3__STATIC },
{ "ENDSEQVOL2SND4", DVPTR(ENDSEQVOL2SND4), ENDSEQVOL2SND4__STATIC },
{ "ENDSEQVOL2SND5", DVPTR(ENDSEQVOL2SND5), ENDSEQVOL2SND5__STATIC },
{ "ENDSEQVOL2SND6", DVPTR(ENDSEQVOL2SND6), ENDSEQVOL2SND6__STATIC },
{ "ENDSEQVOL2SND7", DVPTR(ENDSEQVOL2SND7), ENDSEQVOL2SND7__STATIC },
{ "SOMETHINGFROZE", DVPTR(SOMETHINGFROZE), SOMETHINGFROZE__STATIC },
{ "WIND_REPEAT", DVPTR(WIND_REPEAT), WIND_REPEAT__STATIC },
{ "BOS4_RECOG", DVPTR(BOS4_RECOG), BOS4_RECOG__STATIC },
{ "LIGHTNING_SLAP", DVPTR(LIGHTNING_SLAP), LIGHTNING_SLAP__STATIC },
{ "THUNDER", DVPTR(THUNDER), THUNDER__STATIC },
{ "INTRO4_1", DVPTR(INTRO4_1), INTRO4_1__STATIC },
{ "INTRO4_2", DVPTR(INTRO4_2), INTRO4_2__STATIC },
{ "INTRO4_3", DVPTR(INTRO4_3), INTRO4_3__STATIC },
{ "INTRO4_4", DVPTR(INTRO4_4), INTRO4_4__STATIC },
{ "INTRO4_5", DVPTR(INTRO4_5), INTRO4_5__STATIC },
{ "INTRO4_6", DVPTR(INTRO4_6), INTRO4_6__STATIC },
{ "BOSS4_DEADSPEECH", DVPTR(BOSS4_DEADSPEECH), BOSS4_DEADSPEECH__STATIC },
{ "BOSS4_FIRSTSEE", DVPTR(BOSS4_FIRSTSEE), BOSS4_FIRSTSEE__STATIC },
{ "VOL4ENDSND1", DVPTR(VOL4ENDSND1), VOL4ENDSND1__STATIC },
{ "VOL4ENDSND2", DVPTR(VOL4ENDSND2), VOL4ENDSND2__STATIC },
{ "EXPANDERSHOOT", DVPTR(EXPANDERSHOOT), EXPANDERSHOOT__STATIC },
{ "INTRO4_B", DVPTR(INTRO4_B), INTRO4_B__STATIC },
{ "BIGBANG", DVPTR(BIGBANG), BIGBANG__STATIC },
{ NULL, NULL, -1 },
};
#ifdef DYNSOUNDREMAP_ENABLE
int32_t KICK_HIT = KICK_HIT__STATIC;
int32_t PISTOL_RICOCHET = PISTOL_RICOCHET__STATIC;
int32_t PISTOL_BODYHIT = PISTOL_BODYHIT__STATIC;
int32_t PISTOL_FIRE = PISTOL_FIRE__STATIC;
int32_t EJECT_CLIP = EJECT_CLIP__STATIC;
int32_t INSERT_CLIP = INSERT_CLIP__STATIC;
int32_t CHAINGUN_FIRE = CHAINGUN_FIRE__STATIC;
int32_t RPG_SHOOT = RPG_SHOOT__STATIC;
int32_t POOLBALLHIT = POOLBALLHIT__STATIC;
int32_t RPG_EXPLODE = RPG_EXPLODE__STATIC;
int32_t CAT_FIRE = CAT_FIRE__STATIC;
int32_t SHRINKER_FIRE = SHRINKER_FIRE__STATIC;
int32_t PIPEBOMB_BOUNCE = PIPEBOMB_BOUNCE__STATIC;
int32_t PIPEBOMB_EXPLODE = PIPEBOMB_EXPLODE__STATIC;
int32_t LASERTRIP_ONWALL = LASERTRIP_ONWALL__STATIC;
int32_t LASERTRIP_ARMING = LASERTRIP_ARMING__STATIC;
int32_t LASERTRIP_EXPLODE = LASERTRIP_EXPLODE__STATIC;
int32_t VENT_BUST = VENT_BUST__STATIC;
int32_t GLASS_BREAKING = GLASS_BREAKING__STATIC;
int32_t GLASS_HEAVYBREAK = GLASS_HEAVYBREAK__STATIC;
int32_t SHORT_CIRCUIT = SHORT_CIRCUIT__STATIC;
int32_t ITEM_SPLASH = ITEM_SPLASH__STATIC;
int32_t DUKE_GASP = DUKE_GASP__STATIC;
int32_t SLIM_RECOG = SLIM_RECOG__STATIC;
int32_t DUKE_URINATE = DUKE_URINATE__STATIC;
int32_t ENDSEQVOL3SND2 = ENDSEQVOL3SND2__STATIC;
int32_t ENDSEQVOL3SND3 = ENDSEQVOL3SND3__STATIC;
int32_t DUKE_CRACK = DUKE_CRACK__STATIC;
int32_t SLIM_ATTACK = SLIM_ATTACK__STATIC;
int32_t SOMETHINGHITFORCE = SOMETHINGHITFORCE__STATIC;
int32_t DUKE_DRINKING = DUKE_DRINKING__STATIC;
int32_t DUKE_GRUNT = DUKE_GRUNT__STATIC;
int32_t DUKE_HARTBEAT = DUKE_HARTBEAT__STATIC;
int32_t DUKE_ONWATER = DUKE_ONWATER__STATIC;
int32_t DUKE_LAND = DUKE_LAND__STATIC;
int32_t DUKE_WALKINDUCTS = DUKE_WALKINDUCTS__STATIC;
int32_t DUKE_UNDERWATER = DUKE_UNDERWATER__STATIC;
int32_t DUKE_JETPACK_ON = DUKE_JETPACK_ON__STATIC;
int32_t DUKE_JETPACK_IDLE = DUKE_JETPACK_IDLE__STATIC;
int32_t DUKE_JETPACK_OFF = DUKE_JETPACK_OFF__STATIC;
int32_t DUKETALKTOBOSS = DUKETALKTOBOSS__STATIC;
int32_t SQUISHED = SQUISHED__STATIC;
int32_t TELEPORTER = TELEPORTER__STATIC;
int32_t ELEVATOR_ON = ELEVATOR_ON__STATIC;
int32_t ELEVATOR_OFF = ELEVATOR_OFF__STATIC;
int32_t SUBWAY = SUBWAY__STATIC;
int32_t SWITCH_ON = SWITCH_ON__STATIC;
int32_t FLUSH_TOILET = FLUSH_TOILET__STATIC;
int32_t EARTHQUAKE = EARTHQUAKE__STATIC;
int32_t END_OF_LEVEL_WARN = END_OF_LEVEL_WARN__STATIC;
int32_t WIND_AMBIENCE = WIND_AMBIENCE__STATIC;
int32_t SOMETHING_DRIPPING = SOMETHING_DRIPPING__STATIC;
int32_t BOS1_RECOG = BOS1_RECOG__STATIC;
int32_t BOS2_RECOG = BOS2_RECOG__STATIC;
int32_t DUKE_GETWEAPON2 = DUKE_GETWEAPON2__STATIC;
int32_t SHOTGUN_FIRE = SHOTGUN_FIRE__STATIC;
int32_t PRED_RECOG = PRED_RECOG__STATIC;
int32_t CAPT_RECOG = CAPT_RECOG__STATIC;
int32_t PIG_RECOG = PIG_RECOG__STATIC;
int32_t RECO_ROAM = RECO_ROAM__STATIC;
int32_t RECO_RECOG = RECO_RECOG__STATIC;
int32_t RECO_ATTACK = RECO_ATTACK__STATIC;
int32_t RECO_PAIN = RECO_PAIN__STATIC;
int32_t DRON_RECOG = DRON_RECOG__STATIC;
int32_t COMM_RECOG = COMM_RECOG__STATIC;
int32_t OCTA_RECOG = OCTA_RECOG__STATIC;
int32_t TURR_RECOG = TURR_RECOG__STATIC;
int32_t SLIM_DYING = SLIM_DYING__STATIC;
int32_t BOS3_RECOG = BOS3_RECOG__STATIC;
int32_t BOS1_WALK = BOS1_WALK__STATIC;
int32_t THUD = THUD__STATIC;
int32_t WIERDSHOT_FLY = WIERDSHOT_FLY__STATIC;
int32_t SLIM_ROAM = SLIM_ROAM__STATIC;
int32_t SHOTGUN_COCK = SHOTGUN_COCK__STATIC;
int32_t GENERIC_AMBIENCE17 = GENERIC_AMBIENCE17__STATIC;
int32_t BONUS_SPEECH1 = BONUS_SPEECH1__STATIC;
int32_t BONUS_SPEECH2 = BONUS_SPEECH2__STATIC;
int32_t BONUS_SPEECH3 = BONUS_SPEECH3__STATIC;
int32_t BONUS_SPEECH4 = BONUS_SPEECH4__STATIC;
int32_t DUKE_LAND_HURT = DUKE_LAND_HURT__STATIC;
int32_t DUKE_SEARCH2 = DUKE_SEARCH2__STATIC;
int32_t DUKE_CRACK2 = DUKE_CRACK2__STATIC;
int32_t DUKE_SEARCH = DUKE_SEARCH__STATIC;
int32_t DUKE_GET = DUKE_GET__STATIC;
int32_t DUKE_LONGTERM_PAIN = DUKE_LONGTERM_PAIN__STATIC;
int32_t MONITOR_ACTIVE = MONITOR_ACTIVE__STATIC;
int32_t NITEVISION_ONOFF = NITEVISION_ONOFF__STATIC;
int32_t DUKE_CRACK_FIRST = DUKE_CRACK_FIRST__STATIC;
int32_t DUKE_USEMEDKIT = DUKE_USEMEDKIT__STATIC;
int32_t DUKE_TAKEPILLS = DUKE_TAKEPILLS__STATIC;
int32_t DUKE_PISSRELIEF = DUKE_PISSRELIEF__STATIC;
int32_t SELECT_WEAPON = SELECT_WEAPON__STATIC;
int32_t JIBBED_ACTOR5 = JIBBED_ACTOR5__STATIC;
int32_t JIBBED_ACTOR6 = JIBBED_ACTOR6__STATIC;
int32_t DUKE_GOTHEALTHATLOW = DUKE_GOTHEALTHATLOW__STATIC;
int32_t BOSSTALKTODUKE = BOSSTALKTODUKE__STATIC;
int32_t WAR_AMBIENCE2 = WAR_AMBIENCE2__STATIC;
int32_t EXITMENUSOUND = EXITMENUSOUND__STATIC;
int32_t FLY_BY = FLY_BY__STATIC;
int32_t DUKE_SCREAM = DUKE_SCREAM__STATIC;
int32_t SHRINKER_HIT = SHRINKER_HIT__STATIC;
int32_t RATTY = RATTY__STATIC;
int32_t BONUSMUSIC = BONUSMUSIC__STATIC;
int32_t DUKE_GETWEAPON6 = DUKE_GETWEAPON6__STATIC;
int32_t ALIEN_SWITCH1 = ALIEN_SWITCH1__STATIC;
int32_t RIPHEADNECK = RIPHEADNECK__STATIC;
int32_t ENDSEQVOL3SND4 = ENDSEQVOL3SND4__STATIC;
int32_t ENDSEQVOL3SND5 = ENDSEQVOL3SND5__STATIC;
int32_t ENDSEQVOL3SND6 = ENDSEQVOL3SND6__STATIC;
int32_t ENDSEQVOL3SND7 = ENDSEQVOL3SND7__STATIC;
int32_t ENDSEQVOL3SND8 = ENDSEQVOL3SND8__STATIC;
int32_t ENDSEQVOL3SND9 = ENDSEQVOL3SND9__STATIC;
int32_t WHIPYOURASS = WHIPYOURASS__STATIC;
int32_t ENDSEQVOL2SND1 = ENDSEQVOL2SND1__STATIC;
int32_t ENDSEQVOL2SND2 = ENDSEQVOL2SND2__STATIC;
int32_t ENDSEQVOL2SND3 = ENDSEQVOL2SND3__STATIC;
int32_t ENDSEQVOL2SND4 = ENDSEQVOL2SND4__STATIC;
int32_t ENDSEQVOL2SND5 = ENDSEQVOL2SND5__STATIC;
int32_t ENDSEQVOL2SND6 = ENDSEQVOL2SND6__STATIC;
int32_t ENDSEQVOL2SND7 = ENDSEQVOL2SND7__STATIC;
int32_t SOMETHINGFROZE = SOMETHINGFROZE__STATIC;
int32_t WIND_REPEAT = WIND_REPEAT__STATIC;
int32_t BOS4_RECOG = BOS4_RECOG__STATIC;
int32_t LIGHTNING_SLAP = LIGHTNING_SLAP__STATIC;
int32_t THUNDER = THUNDER__STATIC;
int32_t INTRO4_1 = INTRO4_1__STATIC;
int32_t INTRO4_2 = INTRO4_2__STATIC;
int32_t INTRO4_3 = INTRO4_3__STATIC;
int32_t INTRO4_4 = INTRO4_4__STATIC;
int32_t INTRO4_5 = INTRO4_5__STATIC;
int32_t INTRO4_6 = INTRO4_6__STATIC;
int32_t BOSS4_DEADSPEECH = BOSS4_DEADSPEECH__STATIC;
int32_t BOSS4_FIRSTSEE = BOSS4_FIRSTSEE__STATIC;
int32_t VOL4ENDSND1 = VOL4ENDSND1__STATIC;
int32_t VOL4ENDSND2 = VOL4ENDSND2__STATIC;
int32_t EXPANDERSHOOT = EXPANDERSHOOT__STATIC;
int32_t INTRO4_B = INTRO4_B__STATIC;
int32_t BIGBANG = BIGBANG__STATIC;
static hashtable_t h_names = {512, NULL};
void G_ProcessDynamicSoundMapping(const char *szLabel, int32_t lValue)
{
int32_t i;
if ((unsigned)lValue >= MAXSOUNDS || !szLabel)
return;
i = hash_find(&h_names,szLabel);
if (i>=0)
{
struct sdynitem *di = &g_dynSoundList[i];
#ifdef DEBUGGINGAIDS
if (g_scriptDebug && di->staticval != lValue)
Printf("REMAP %s (%d) --> %d\n", di->str, di->staticval, lValue);
#endif
*di->dynvalptr = lValue;
}
}
void initsoundhashnames(void)
{
int32_t i;
hash_init(&h_names);
for (i=0; g_dynSoundList[i].staticval >= 0; i++)
hash_add(&h_names, g_dynSoundList[i].str, i, 0);
}
void freesoundhashnames(void)
{
hash_free(&h_names);
}
#endif
// This is run after all CON define's have been processed to set up the
// dynamic->static sound mapping.
void G_InitDynamicSounds(void)
{
int32_t i;
Bmemset(DynamicSoundMap, 0, sizeof(DynamicSoundMap));
for (i=0; g_dynSoundList[i].staticval >= 0; i++)
#ifdef DYNSOUNDREMAP_ENABLE
DynamicSoundMap[*(g_dynSoundList[i].dynvalptr)] = g_dynSoundList[i].staticval;
#else
DynamicSoundMap[g_dynSoundList[i].staticval] = g_dynSoundList[i].staticval;
#endif
}
END_DUKE_NS

332
source/duke/src/soundsdyn.h Normal file
View file

@ -0,0 +1,332 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2013 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
BEGIN_DUKE_NS
#define DYNSOUNDREMAP_ENABLE
#define KICK_HIT__STATIC 0
#define PISTOL_RICOCHET__STATIC 1
#define PISTOL_BODYHIT__STATIC 2
#define PISTOL_FIRE__STATIC 3
#define EJECT_CLIP__STATIC 4
#define INSERT_CLIP__STATIC 5
#define CHAINGUN_FIRE__STATIC 6
#define RPG_SHOOT__STATIC 7
#define POOLBALLHIT__STATIC 8
#define RPG_EXPLODE__STATIC 9
#define CAT_FIRE__STATIC 10
#define SHRINKER_FIRE__STATIC 11
#define PIPEBOMB_BOUNCE__STATIC 13
#define PIPEBOMB_EXPLODE__STATIC 14
#define LASERTRIP_ONWALL__STATIC 15
#define LASERTRIP_ARMING__STATIC 16
#define LASERTRIP_EXPLODE__STATIC 17
#define VENT_BUST__STATIC 18
#define GLASS_BREAKING__STATIC 19
#define GLASS_HEAVYBREAK__STATIC 20
#define SHORT_CIRCUIT__STATIC 21
#define ITEM_SPLASH__STATIC 22
#define DUKE_GASP__STATIC 25
#define SLIM_RECOG__STATIC 26
#define DUKE_URINATE__STATIC 28
#define ENDSEQVOL3SND2__STATIC 29
#define ENDSEQVOL3SND3__STATIC 30
#define DUKE_CRACK__STATIC 33
#define SLIM_ATTACK__STATIC 34
#define SOMETHINGHITFORCE__STATIC 35
#define DUKE_DRINKING__STATIC 36
#define DUKE_GRUNT__STATIC 38
#define DUKE_HARTBEAT__STATIC 39
#define DUKE_ONWATER__STATIC 40
#define DUKE_LAND__STATIC 42
#define DUKE_WALKINDUCTS__STATIC 43
#define DUKE_UNDERWATER__STATIC 48
#define DUKE_JETPACK_ON__STATIC 49
#define DUKE_JETPACK_IDLE__STATIC 50
#define DUKE_JETPACK_OFF__STATIC 51
#define DUKETALKTOBOSS__STATIC 56
#define SQUISHED__STATIC 69
#define TELEPORTER__STATIC 70
#define ELEVATOR_ON__STATIC 71
#define ELEVATOR_OFF__STATIC 73
#define SUBWAY__STATIC 75
#define SWITCH_ON__STATIC 76
#define FLUSH_TOILET__STATIC 79
#define EARTHQUAKE__STATIC 81
#define END_OF_LEVEL_WARN__STATIC 83
#define WIND_AMBIENCE__STATIC 91
#define SOMETHING_DRIPPING__STATIC 92
#define BOS1_RECOG__STATIC 97
#define BOS2_RECOG__STATIC 102
#define DUKE_GETWEAPON2__STATIC 107
#define SHOTGUN_FIRE__STATIC 109
#define PRED_RECOG__STATIC 111
#define CAPT_RECOG__STATIC 117
#define PIG_RECOG__STATIC 121
#define RECO_ROAM__STATIC 125
#define RECO_RECOG__STATIC 126
#define RECO_ATTACK__STATIC 127
#define RECO_PAIN__STATIC 128
#define DRON_RECOG__STATIC 131
#define COMM_RECOG__STATIC 136
#define OCTA_RECOG__STATIC 141
#define TURR_RECOG__STATIC 146
#define SLIM_DYING__STATIC 149
#define BOS3_RECOG__STATIC 151
#define BOS1_WALK__STATIC 156
#define THUD__STATIC 158
#define WIERDSHOT_FLY__STATIC 160
#define SLIM_ROAM__STATIC 163
#define SHOTGUN_COCK__STATIC 169
#define GENERIC_AMBIENCE17__STATIC 177
#define BONUS_SPEECH1__STATIC 195
#define BONUS_SPEECH2__STATIC 196
#define BONUS_SPEECH3__STATIC 197
#define BONUS_SPEECH4__STATIC 199
#define DUKE_LAND_HURT__STATIC 200
#define DUKE_SEARCH2__STATIC 207
#define DUKE_CRACK2__STATIC 208
#define DUKE_SEARCH__STATIC 209
#define DUKE_GET__STATIC 210
#define DUKE_LONGTERM_PAIN__STATIC 211
#define MONITOR_ACTIVE__STATIC 212
#define NITEVISION_ONOFF__STATIC 213
#define DUKE_CRACK_FIRST__STATIC 215
#define DUKE_USEMEDKIT__STATIC 216
#define DUKE_TAKEPILLS__STATIC 217
#define DUKE_PISSRELIEF__STATIC 218
#define SELECT_WEAPON__STATIC 219
#define JIBBED_ACTOR5__STATIC 226
#define JIBBED_ACTOR6__STATIC 227
#define DUKE_GOTHEALTHATLOW__STATIC 229
#define BOSSTALKTODUKE__STATIC 230
#define WAR_AMBIENCE2__STATIC 232
#define EXITMENUSOUND__STATIC 243
#define FLY_BY__STATIC 244
#define DUKE_SCREAM__STATIC 245
#define SHRINKER_HIT__STATIC 246
#define RATTY__STATIC 247
#define BONUSMUSIC__STATIC 249
#define DUKE_GETWEAPON6__STATIC 264
#define ALIEN_SWITCH1__STATIC 272
#define RIPHEADNECK__STATIC 284
#define ENDSEQVOL3SND4__STATIC 288
#define ENDSEQVOL3SND5__STATIC 289
#define ENDSEQVOL3SND6__STATIC 290
#define ENDSEQVOL3SND7__STATIC 291
#define ENDSEQVOL3SND8__STATIC 292
#define ENDSEQVOL3SND9__STATIC 293
#define WHIPYOURASS__STATIC 294
#define ENDSEQVOL2SND1__STATIC 295
#define ENDSEQVOL2SND2__STATIC 296
#define ENDSEQVOL2SND3__STATIC 297
#define ENDSEQVOL2SND4__STATIC 298
#define ENDSEQVOL2SND5__STATIC 299
#define ENDSEQVOL2SND6__STATIC 300
#define ENDSEQVOL2SND7__STATIC 301
#define SOMETHINGFROZE__STATIC 303
#define WIND_REPEAT__STATIC 308
#define BOS4_RECOG__STATIC 342
#define LIGHTNING_SLAP__STATIC 351
#define THUNDER__STATIC 352
#define INTRO4_1__STATIC 363
#define INTRO4_2__STATIC 364
#define INTRO4_3__STATIC 365
#define INTRO4_4__STATIC 366
#define INTRO4_5__STATIC 367
#define INTRO4_6__STATIC 368
#define BOSS4_DEADSPEECH__STATIC 370
#define BOSS4_FIRSTSEE__STATIC 371
#define VOL4ENDSND1__STATIC 384
#define VOL4ENDSND2__STATIC 385
#define EXPANDERSHOOT__STATIC 388
#define INTRO4_B__STATIC 392
#define BIGBANG__STATIC 393
extern int16_t DynamicSoundMap[MAXSOUNDS];
void G_InitDynamicSounds(void);
#ifdef DYNSOUNDREMAP_ENABLE
void G_ProcessDynamicSoundMapping(const char *szLabel, int32_t lValue);
void initsoundhashnames(void);
void freesoundhashnames(void);
extern int32_t KICK_HIT;
extern int32_t PISTOL_RICOCHET;
extern int32_t PISTOL_BODYHIT;
extern int32_t PISTOL_FIRE;
extern int32_t EJECT_CLIP;
extern int32_t INSERT_CLIP;
extern int32_t CHAINGUN_FIRE;
extern int32_t RPG_SHOOT;
extern int32_t POOLBALLHIT;
extern int32_t RPG_EXPLODE;
extern int32_t CAT_FIRE;
extern int32_t SHRINKER_FIRE;
extern int32_t PIPEBOMB_BOUNCE;
extern int32_t PIPEBOMB_EXPLODE;
extern int32_t LASERTRIP_ONWALL;
extern int32_t LASERTRIP_ARMING;
extern int32_t LASERTRIP_EXPLODE;
extern int32_t VENT_BUST;
extern int32_t GLASS_BREAKING;
extern int32_t GLASS_HEAVYBREAK;
extern int32_t SHORT_CIRCUIT;
extern int32_t ITEM_SPLASH;
extern int32_t DUKE_GASP;
extern int32_t SLIM_RECOG;
extern int32_t DUKE_URINATE;
extern int32_t ENDSEQVOL3SND2;
extern int32_t ENDSEQVOL3SND3;
extern int32_t DUKE_CRACK;
extern int32_t SLIM_ATTACK;
extern int32_t SOMETHINGHITFORCE;
extern int32_t DUKE_DRINKING;
extern int32_t DUKE_GRUNT;
extern int32_t DUKE_HARTBEAT;
extern int32_t DUKE_ONWATER;
extern int32_t DUKE_LAND;
extern int32_t DUKE_WALKINDUCTS;
extern int32_t DUKE_UNDERWATER;
extern int32_t DUKE_JETPACK_ON;
extern int32_t DUKE_JETPACK_IDLE;
extern int32_t DUKE_JETPACK_OFF;
extern int32_t DUKETALKTOBOSS;
extern int32_t SQUISHED;
extern int32_t TELEPORTER;
extern int32_t ELEVATOR_ON;
extern int32_t ELEVATOR_OFF;
extern int32_t SUBWAY;
extern int32_t SWITCH_ON;
extern int32_t FLUSH_TOILET;
extern int32_t EARTHQUAKE;
extern int32_t END_OF_LEVEL_WARN;
extern int32_t WIND_AMBIENCE;
extern int32_t SOMETHING_DRIPPING;
extern int32_t BOS1_RECOG;
extern int32_t BOS2_RECOG;
extern int32_t DUKE_GETWEAPON2;
extern int32_t SHOTGUN_FIRE;
extern int32_t PRED_RECOG;
extern int32_t CAPT_RECOG;
extern int32_t PIG_RECOG;
extern int32_t RECO_ROAM;
extern int32_t RECO_RECOG;
extern int32_t RECO_ATTACK;
extern int32_t RECO_PAIN;
extern int32_t DRON_RECOG;
extern int32_t COMM_RECOG;
extern int32_t OCTA_RECOG;
extern int32_t TURR_RECOG;
extern int32_t SLIM_DYING;
extern int32_t BOS3_RECOG;
extern int32_t BOS1_WALK;
extern int32_t THUD;
extern int32_t WIERDSHOT_FLY;
extern int32_t SLIM_ROAM;
extern int32_t SHOTGUN_COCK;
extern int32_t GENERIC_AMBIENCE17;
extern int32_t BONUS_SPEECH1;
extern int32_t BONUS_SPEECH2;
extern int32_t BONUS_SPEECH3;
extern int32_t BONUS_SPEECH4;
extern int32_t DUKE_LAND_HURT;
extern int32_t DUKE_SEARCH2;
extern int32_t DUKE_CRACK2;
extern int32_t DUKE_SEARCH;
extern int32_t DUKE_GET;
extern int32_t DUKE_LONGTERM_PAIN;
extern int32_t MONITOR_ACTIVE;
extern int32_t NITEVISION_ONOFF;
extern int32_t DUKE_CRACK_FIRST;
extern int32_t DUKE_USEMEDKIT;
extern int32_t DUKE_TAKEPILLS;
extern int32_t DUKE_PISSRELIEF;
extern int32_t SELECT_WEAPON;
extern int32_t JIBBED_ACTOR5;
extern int32_t JIBBED_ACTOR6;
extern int32_t DUKE_GOTHEALTHATLOW;
extern int32_t BOSSTALKTODUKE;
extern int32_t WAR_AMBIENCE2;
extern int32_t EXITMENUSOUND;
extern int32_t FLY_BY;
extern int32_t DUKE_SCREAM;
extern int32_t SHRINKER_HIT;
extern int32_t RATTY;
extern int32_t BONUSMUSIC;
extern int32_t DUKE_GETWEAPON6;
extern int32_t ALIEN_SWITCH1;
extern int32_t RIPHEADNECK;
extern int32_t ENDSEQVOL3SND4;
extern int32_t ENDSEQVOL3SND5;
extern int32_t ENDSEQVOL3SND6;
extern int32_t ENDSEQVOL3SND7;
extern int32_t ENDSEQVOL3SND8;
extern int32_t ENDSEQVOL3SND9;
extern int32_t WHIPYOURASS;
extern int32_t ENDSEQVOL2SND1;
extern int32_t ENDSEQVOL2SND2;
extern int32_t ENDSEQVOL2SND3;
extern int32_t ENDSEQVOL2SND4;
extern int32_t ENDSEQVOL2SND5;
extern int32_t ENDSEQVOL2SND6;
extern int32_t ENDSEQVOL2SND7;
extern int32_t SOMETHINGFROZE;
extern int32_t WIND_REPEAT;
extern int32_t BOS4_RECOG;
extern int32_t LIGHTNING_SLAP;
extern int32_t THUNDER;
extern int32_t INTRO4_1;
extern int32_t INTRO4_2;
extern int32_t INTRO4_3;
extern int32_t INTRO4_4;
extern int32_t INTRO4_5;
extern int32_t INTRO4_6;
extern int32_t BOSS4_DEADSPEECH;
extern int32_t BOSS4_FIRSTSEE;
extern int32_t VOL4ENDSND1;
extern int32_t VOL4ENDSND2;
extern int32_t EXPANDERSHOOT;
extern int32_t INTRO4_B;
extern int32_t BIGBANG;
#define DYNAMICSOUNDMAP(Soundnum) (DynamicSoundMap[Soundnum])
#else /* if !defined DYNSOUNDREMAP_ENABLE */
#define G_ProcessDynamicSoundMapping(x, y) ((void)(0))
#define initsoundhashnames() ((void)0)
#define freesoundhashnames() ((void)0)
#include "soundefs.h"
#define DYNAMICSOUNDMAP(Soundnum) (Soundnum)
#endif
END_DUKE_NS

374
source/duke/src/text.cpp Normal file
View file

@ -0,0 +1,374 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "duke3d.h"
#include "compat.h"
#include "sbar.h"
#include "menus.h"
#include "gstrings.h"
BEGIN_DUKE_NS
// assign the character's tilenum
int GameInterface::GetStringTile(int font, const char* t, int f)
{
if (f & TEXT_DIGITALNUMBER)
return *t - '0' + font; // copied from digitalnumber
else if (f & (TEXT_BIGALPHANUM|TEXT_GRAYFONT))
{
int32_t offset = (f & TEXT_GRAYFONT) ? 26 : 0;
if (*t >= '0' && *t <= '9')
return *t - '0' + font + ((f & TEXT_GRAYFONT) ? 26 : -10);
else if (*t >= 'a' && *t <= 'z')
return *t - 'a' + font + ((f & TEXT_GRAYFONT) ? -26 : 26);
else if (*t >= 'A' && *t <= 'Z')
return *t - 'A' + font;
else switch (*t)
{
case '_':
case '-':
return font - (11 + offset);
break;
case '.':
return font + (BIGPERIOD - (BIGALPHANUM + offset));
break;
case ',':
return font + (BIGCOMMA - (BIGALPHANUM + offset));
break;
case '!':
return font + (BIGX_ - (BIGALPHANUM + offset));
break;
case '?':
return font + (BIGQ - (BIGALPHANUM + offset));
break;
case ';':
return font + (BIGSEMI - (BIGALPHANUM + offset));
break;
case ':':
return font + (BIGCOLIN - (BIGALPHANUM + offset));
break;
case '\\':
case '/':
return font + (68 - offset); // 3008-2940
break;
case '%':
return font + (69 - offset); // 3009-2940
break;
case '`':
case '\"': // could be better hacked in
case '\'':
return font + (BIGAPPOS - (BIGALPHANUM + offset));
break;
default: // unknown character
fallthrough__;
case '\t':
case ' ':
case '\n':
case '\x7F':
return font;
break;
}
}
else
return *t - '!' + font; // uses ASCII order
}
vec2_t gametext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f)
{
return G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, s, p, o|2|8|16|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1);
}
void gametext_simple(int32_t x, int32_t y, const char *t)
{
G_ScreenText(MF_Bluefont.tilenum, x, y, MF_Bluefont.zoom, 0, 0, t, 0, MF_Bluefont.pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags, 0, 0, xdim-1, ydim-1);
}
vec2_t mpgametext(int32_t x, int32_t y, const char *t, int32_t s, int32_t o, int32_t a, int32_t f)
{
return G_ScreenText(MF_Bluefont.tilenum, x, y, textsc(MF_Bluefont.zoom), 0, 0, t, s, MF_Bluefont.pal, o|2|8|16|ROTATESPRITE_FULL16, a, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1);
}
vec2_t mpgametextsize(const char *t, int32_t f)
{
return G_ScreenTextSize(MF_Bluefont.tilenum, 0, 0, textsc(MF_Bluefont.zoom), 0, t, 2|8|16|ROTATESPRITE_FULL16, MF_Bluefont.emptychar.x, MF_Bluefont.emptychar.y, MF_Bluefont.between.x, MF_Bluefont.between.y, MF_Bluefont.textflags|f, 0, 0, xdim-1, ydim-1);
}
// minitext_yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords,
// (sb&ROTATESPRITE_MAX) only.
int32_t minitext_yofs = 0;
int32_t minitext_lowercase = 0;
int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb)
{
vec2_t dim;
int32_t z = MF_Minifont.zoom;
if (t == NULL)
{
Printf("minitext: NULL text!\n");
return 0;
}
if (!(sb & ROTATESPRITE_FULL16))
{
x<<=16;
y<<=16;
}
if (sb & ROTATESPRITE_MAX)
{
if (sb & RS_ALIGN_R)
x = sbarxr16(x);
else
x = sbarx16(x);
y = minitext_yofs+sbary16(y);
z = sbarsc(z);
}
sb &= (ROTATESPRITE_MAX-1)|RS_CENTERORIGIN;
dim = G_ScreenText(MF_Minifont.tilenum, x, y, z, 0, 0, t, s, p, sb|ROTATESPRITE_FULL16, 0, MF_Minifont.emptychar.x, MF_Minifont.emptychar.y, MF_Minifont.between.x, MF_Minifont.between.y, MF_Minifont.textflags, 0, 0, xdim-1, ydim-1);
x += dim.x;
if (!(sb & ROTATESPRITE_FULL16))
x >>= 16;
return x;
}
void menutext_(int32_t x, int32_t y, int32_t s, char const *t, int32_t o, int32_t f)
{
if (RR) f |= TEXT_RRMENUTEXTHACK;
G_ScreenText(MF_Redfont.tilenum, x, y - (12<<16), MF_Redfont.zoom, 0, 0, t, s, MF_Redfont.pal, o|ROTATESPRITE_FULL16, 0, MF_Redfont.emptychar.x, MF_Redfont.emptychar.y, MF_Redfont.between.x, MF_Redfont.between.y, f|MF_Redfont.textflags|TEXT_LITERALESCAPE, 0, 0, xdim-1, ydim-1);
}
void captionmenutext(int32_t x, int32_t y, char const *t)
{
G_ScreenText(MF_Redfont.tilenum, x, y - (12<<16), MF_Redfont.zoom, 0, 0, t, 0, ud.menutitle_pal, 2|8|16|ROTATESPRITE_FULL16, 0, MF_Redfont.emptychar.x, MF_Redfont.emptychar.y, MF_Redfont.between.x, MF_Redfont.between.y, MF_Redfont.textflags|TEXT_LITERALESCAPE|TEXT_XCENTER|TEXT_YCENTER, 0, 0, xdim-1, ydim-1);
}
int32_t user_quote_time[MAXUSERQUOTES];
static char user_quote[MAXUSERQUOTES][178];
void G_AddUserQuote(const char* daquote)
{
int32_t i;
if (hud_messages == 0) return;
Printf(PRINT_MEDIUM | PRINT_NOTIFY, "%s\n", daquote);
if (hud_messages == 1)
{
for (i = MAXUSERQUOTES - 1; i > 0; i--)
{
Bstrcpy(user_quote[i], user_quote[i - 1]);
user_quote_time[i] = user_quote_time[i - 1];
}
Bstrcpy(user_quote[0], daquote);
user_quote_time[0] = hud_messagetime;
pub = NUMPAGES;
}
}
int32_t textsc(int32_t sc)
{
return scale(sc, hud_textscale, 400);
}
#define FTAOPAQUETIME 30
// alpha increments of 8 --> 256 / 8 = 32 --> round up to power of 2 --> 32 --> divide by 2 --> 16 alphatabs required
static inline int32_t textsh(uint32_t t)
{
return (hud_glowingquotes && ((videoGetRenderMode() == REND_CLASSIC && numalphatabs < 15) || t >= FTAOPAQUETIME))
? sintable[(t << 7) & 2047] >> 11
: (sintable[(FTAOPAQUETIME << 7) & 2047] >> 11);
}
// orientation flags depending on time that a quote has still to be displayed
static inline int32_t texto(int32_t t)
{
if (videoGetRenderMode() != REND_CLASSIC || numalphatabs >= 15 || t > 4)
return 0;
if (t > 2)
return 1;
return 1|32;
}
static inline int32_t texta(int32_t t)
{
return 255 - clamp(t<<3, 0, 255);
}
static FORCE_INLINE int32_t text_ypos(void)
{
if (hud_position == 1 && ud.screen_size == 4 && ud.althud == 1)
return 32<<16;
#ifdef GEKKO
return 16<<16;
#elif defined EDUKE32_TOUCH_DEVICES
return 24<<16;
#else
return 1<<16;
#endif
}
static FString text_quote; // To put text into the quote display that does not come from the quote array. (Is it really necessary to implement everything as a hack??? :( )
// this handles both multiplayer and item pickup message type text
// both are passed on to gametext
void G_PrintGameQuotes(int32_t snum)
{
const DukePlayer_t *const ps = g_player[snum].ps;
const int32_t reserved_quote = (ps->ftq >= QUOTE_RESERVED && ps->ftq <= QUOTE_RESERVED3);
// NOTE: QUOTE_RESERVED4 is not included.
int32_t const ybase = (fragbarheight()<<16) + text_ypos();
int32_t height = 0;
int32_t k = ps->fta;
// primary quote
do
{
if (k <= 1)
break;
int32_t y = ybase;
if (reserved_quote)
{
#ifdef SPLITSCREEN_MOD_HACKS
if (!g_fakeMultiMode)
y = 140<<16;
else
y = 70<<16;
#else
y = 140<<16;
#endif
}
int32_t pal = 0;
int32_t x = 160<<16;
#ifdef SPLITSCREEN_MOD_HACKS
if (g_fakeMultiMode)
{
pal = g_player[snum].pcolor;
const int32_t sidebyside = ud.screen_size != 0;
if (sidebyside)
x = snum == 1 ? 240<<16 : 80<<16;
else if (snum == 1)
y += 100<<16;
}
#endif
if (text_quote.IsNotEmpty() && ps->ftq == -32768) height = gametext_(x, y, text_quote, textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16);
else height = gametext_(x, y, quoteMgr.GetQuote(ps->ftq), textsh(k), pal, texto(k), texta(k), TEXT_XCENTER).y + (1 << 16);
}
while (0);
// userquotes
int32_t y = ybase;
if (k > 1 && !reserved_quote)
y += k <= 8 ? (height * (k-1))>>3 : height;
for (size_t i = MAXUSERQUOTES-1; i < MAXUSERQUOTES; --i)
{
k = user_quote_time[i];
if (k <= 0)
continue;
// int32_t const sh = hud_glowingquotes ? sintable[((totalclock+(i<<2))<<5)&2047]>>11 : 0;
height = mpgametext(mpgametext_x, y, user_quote[i], textsh(k), texto(k), texta(k), TEXT_LINEWRAP).y + textsc(1<<16);
y += k <= 4 ? (height * (k-1))>>2 : height;
}
}
void P_DoQuote(int32_t q, DukePlayer_t *p)
{
int32_t cq = 0;
if (hud_messages == 0 || q < 0 || !(p->gm & MODE_GAME))
return;
if (q & MAXQUOTES)
{
cq = 1;
q &= ~MAXQUOTES;
}
if (p->fta > 0 && q != QUOTE_RESERVED && q != QUOTE_RESERVED2)
if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return;
if (p->ftq != q)
{
auto qu = quoteMgr.GetQuote(q);
if (p == g_player[screenpeek].ps && qu[0] != '\0')
Printf((cq ? PRINT_LOW : PRINT_MEDIUM) | PRINT_NOTIFY, "%s\n", qu);
}
if (hud_messages == 1)
{
p->ftq = q;
p->fta = 100;
pub = NUMPAGES;
pus = NUMPAGES;
}
}
void GameInterface::DoPrintMessage(int prio, const char* t)
{
auto p = g_player[myconnectindex].ps; // text quotes always belong to the local player.
int32_t cq = 0;
if (hud_messages == 0 || !(p->gm & MODE_GAME))
return;
if (p->fta > 0)
if (p->ftq == QUOTE_RESERVED || p->ftq == QUOTE_RESERVED2) return;
if (p == g_player[screenpeek].ps)
Printf(prio|PRINT_NOTIFY, cq ? TEXTCOLOR_TAN "%s\n" : "%s\n", t);
if (hud_messages == 1)
{
p->fta = 100;
p->ftq = -32768;
text_quote = t;
pub = NUMPAGES;
pus = NUMPAGES;
}
}
END_DUKE_NS

62
source/duke/src/text.h Normal file
View file

@ -0,0 +1,62 @@
//-------------------------------------------------------------------------
/*
Copyright (C) 2016 EDuke32 developers and contributors
This file is part of EDuke32.
EDuke32 is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#pragma once
#include "menus.h"
#include "screentext.h"
BEGIN_DUKE_NS
#define MAXUSERQUOTES 6
extern int32_t user_quote_time[MAXUSERQUOTES];
extern int32_t minitext_lowercase;
extern int32_t minitext_yofs;
extern int32_t minitext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t sb);
extern void menutext_(int32_t x, int32_t y, int32_t s, char const *t, int32_t o, int32_t f);
extern void captionmenutext(int32_t x, int32_t y, char const *t);
extern vec2_t gametext_(int32_t x, int32_t y, const char *t, int32_t s, int32_t p, int32_t o, int32_t a, int32_t f);
extern void gametext_simple(int32_t x, int32_t y, const char *t);
#define mpgametext_x (5<<16)
extern vec2_t mpgametext(int32_t x, int32_t y, char const * t, int32_t s, int32_t o, int32_t a, int32_t f);
extern vec2_t mpgametextsize(char const * t, int32_t f);
extern int32_t textsc(int32_t sc);
#define minitextshade(x, y, t, s, p, sb) minitext_(x,y,t,s,p,sb)
#define minitext(x, y, t, p, sb) minitext_(x,y,t,0,p,sb)
#define menutext(x, y, t) menutext_((x)<<16, (y)<<16, 0, (t), 10|16, 0)
#define menutext_centeralign(x, y, t) menutext_((x), (y), 0, (t), 10|16, TEXT_XCENTER|TEXT_YCENTER)
#define menutext_center(y, t) menutext_(160<<16, (y)<<16, 0, (t), 10|16, TEXT_XCENTER)
#define gametext(x, y, t) gametext_simple((x)<<16, (y)<<16, (t))
#define gametext_widenumber(x, y, t) gametext_((x)<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 1024, 0, TEXT_GAMETEXTNUMHACK)
#define gametext_number(x, y, t) gametext_((x)<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_GAMETEXTNUMHACK)
#define gametext_pal(x, y, t, p) gametext_((x)<<16, (y)<<16, (t), 0, (p), 0, 0, 0)
#define gametext_center(y, t) gametext_(160<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_XCENTER)
#define gametext_center_number(y, t) gametext_(160<<16, (y)<<16, (t), 0, MF_Bluefont.pal, 0, 0, TEXT_XCENTER|TEXT_GAMETEXTNUMHACK)
#define gametext_center_shade(y, t, s) gametext_(160<<16, (y)<<16, (t), (s), MF_Bluefont.pal, 0, 0, TEXT_XCENTER)
#define gametext_center_shade_pal(y, t, s, p) gametext_(160<<16, (y)<<16, (t), (s), (p), 0, 0, TEXT_XCENTER)
END_DUKE_NS

View file

@ -33,7 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "v_text.h"
#include "printf.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#if KRANDDEBUG
@ -8944,4 +8944,4 @@ void G_MoveWorld(void)
g_moveWorldTime = (1-0.033)*g_moveWorldTime + 0.033*(timerGetHiTicks()-worldTime);
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "player.h"
# include "namesdyn.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#define MAXSLEEPDIST 16384
#define SLEEPTIME 1536
@ -466,7 +466,7 @@ EXTERN_INLINE int A_CheckEnemySprite(void const * const pSprite)
return A_CheckEnemyTile(((uspriteptr_t) pSprite)->picnum);
}
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -39,7 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# include "animvpx.h"
#endif
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
dukeanim_t* g_animPtr;
@ -533,4 +533,4 @@ end_anim:
return !running;
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "tarray.h"
#include "zstring.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
struct animsound_t {
uint16_t frame = 0;
@ -53,6 +53,6 @@ extern dukeanim_t * Anim_Create(const char *fn);
int32_t Anim_Play(const char *fn);
void Anim_Init(void);
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "mapinfo.h"
#include "c_dispatch.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
char CheatStrings [NUMCHEATS][MAXCHEATLEN] =
{
@ -745,4 +745,4 @@ void G_DoCheats(void)
}
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#pragma once
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#define MAXCHEATLEN 20
#define MAXCHEATDESC 64
@ -95,4 +95,4 @@ enum CheatCodeFunctions
NUMCHEATFUNCS,
};
END_DUKE_NS
END_EDUKE_NS

View file

@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "printf.h"
#include "c_dispatch.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
int32_t g_fakeMultiMode = 0;
@ -97,4 +97,4 @@ void G_CheckCommandLine()
}
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -25,7 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "compat.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
extern void G_CheckCommandLine();
@ -34,6 +34,6 @@ extern void G_ShowDebugHelp(void);
extern int32_t g_fakeMultiMode;
END_DUKE_NS
END_EDUKE_NS
#endif // cmdline_h__

View file

@ -17,7 +17,7 @@
#include "common.h"
#include "common_game.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
// Set up new-style multi-psky handling.
@ -138,4 +138,4 @@ void G_LoadLookups(void)
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -9,7 +9,7 @@
#include "gamecontrol.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#define DUKE (g_gameType & GAMEFLAG_DUKE)
@ -67,5 +67,5 @@ static inline void Duke_ApplySpritePropertiesToTSprite(tspriteptr_t tspr, usprit
void Duke_CommonCleanup(void);
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "baselayer.h"
#include "cmdline.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
@ -68,4 +68,4 @@ int CONFIG_ReadSetup(void)
return 0;
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -25,10 +25,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gamecontrol.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
int CONFIG_ReadSetup(void);
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -41,7 +41,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "menus.h"
#include "../../glbackend/glbackend.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#define MENU_MARGIN_REGULAR 40
#define MENU_MARGIN_WIDE 32
@ -754,7 +754,7 @@ void GameInterface::QuitToTitle()
G_CloseDemoWrite();
artClearMapArt();
}
END_DUKE_NS
END_EDUKE_NS
//----------------------------------------------------------------------------
//

View file

@ -32,7 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "menu.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
char g_firstDemoFile[BMAX_PATH];
@ -933,4 +933,4 @@ nextdemo_nomenu:
return 1;
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "compat.h"
#include "filesystem.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#define DEMOFN_FMT "edemo%03d.edm"
#define MAXDEMOS 1000
@ -58,6 +58,6 @@ int32_t krd_print(const char *filename);
void krd_enable(int32_t which);
#endif
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -131,7 +131,7 @@ EDUKE32_STATIC_ASSERT(7 <= MAXTILES-MAXUSERTILES);
#include "soundsdyn.h"
#include "text.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
// Order is that of EDuke32 by necessity because it exposes the key binds to scripting by index instead of by name.
enum GameFunction_t
@ -247,6 +247,6 @@ struct GameInterface : ::GameInterface
};
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -2,7 +2,7 @@
#ifndef EDUKE32_EVENTS_DEFS_H_
#define EDUKE32_EVENTS_DEFS_H_
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
// the order of these can't be changed or else compatibility with EDuke 2.0 mods will break
// KEEPINSYNC with EventNames[]
@ -167,6 +167,6 @@ enum GameEvent_t {
MAXEVENTS
};
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -65,7 +65,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# define GAME_STATIC static
#endif
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
int32_t g_quitDeadline = 0;
@ -6253,4 +6253,4 @@ void GameInterface::UpdateScreenSize()
return new GameInterface;
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -37,7 +37,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "palette.h"
#include "cmdlib.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#ifndef ONLY_USERDEFS
@ -432,6 +432,6 @@ static inline int G_GetMusicIdx(const char *str)
#endif
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -44,7 +44,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
void C_CON_SetButtonAlias(int num, const char* text);
void C_CON_ClearButtonAlias(int num);
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#define LINE_NUMBER (g_lineNumber << 12)
@ -6113,4 +6113,4 @@ void C_ReportError(int error)
}
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -33,7 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "events_defs.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
enum
{
@ -1352,6 +1352,6 @@ enum ScriptKeywords_t
#undef ENUM_TRANSFORM
#undef COMMA
END_DUKE_NS
END_EDUKE_NS
#endif // gamedef_h_

View file

@ -53,7 +53,7 @@ FString C_CON_GetBoundKeyForLastInput(int gameFunc);
const char* C_CON_GetButtonFunc(int num);
const char* KB_ScanCodeToString(int scancode); // convert scancode into a string
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#if KRANDDEBUG
# define GAMEEXEC_INLINE
@ -6657,4 +6657,4 @@ void VM_DrawTileSmall(int32_t x, int32_t y, int32_t tilenum, int32_t shade, int3
VM_DrawTileGeneric(x, y, 32768, tilenum, shade, orientation, tilePal);
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "sector.h" // mapstate_t
#include "zstring.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
int32_t VM_ExecuteEvent(int const nEventID, int const spriteNum, int const playerNum, int const nDist, int32_t const nReturn);
int32_t VM_ExecuteEvent(int const nEventID, int const spriteNum, int const playerNum, int const nDist);
@ -121,6 +121,6 @@ int G_StartTrack(int levelNum);
void VM_UpdateAnim(int const spriteNum, int32_t * const pData);
void VM_GetZRange(int const spriteNum, int32_t * const ceilhit, int32_t * const florhit, int const wallDist);
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gameexec.h"
#include "global.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#define LABEL_SETUP_UNMATCHED(struct, memb, name, idx) \
{ \
@ -1969,4 +1969,4 @@ void VM_InitHashTables(void)
}
//#undef STRUCT_HASH_SETUP
END_DUKE_NS
END_EDUKE_NS

View file

@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "compat.h"
#include "hash.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
int32_t __fastcall VM_GetUserdef(int32_t labelNum, int const lParm2);
void __fastcall VM_SetUserdef(int const labelNum, int const lParm2, int32_t const newValue);
@ -85,7 +85,7 @@ static hashtable_t *const vmStructHashTablePtrs[] = {
&h_actor, &h_input, &h_paldata, &h_player, &h_projectile, &h_sector, &h_tiledata, &h_tsprite, &h_userdef, &h_wall,
};
END_DUKE_NS
END_EDUKE_NS
#endif // gamestructures_h__

View file

@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "menu.h"
#include "gamestructures.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
gamevar_t aGameVars[MAXGAMEVARS];
gamearray_t aGameArrays[MAXGAMEARRAYS];
int32_t g_gameVarCount = 0;
@ -1417,4 +1417,4 @@ void Gv_RefreshPointers(void)
aGameArrays[Gv_GetArrayIndex("tilesizx")].pValues = (intptr_t *)tileWidth;
aGameArrays[Gv_GetArrayIndex("tilesizy")].pValues = (intptr_t *)tileHeight;
}
END_DUKE_NS
END_EDUKE_NS

View file

@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "gamedef.h"
#include "filesystem.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#define MAXGAMEVARS 2048 // must be a power of two
@ -283,6 +283,6 @@ VM_GAMEVAR_OPERATOR(Gv_ShiftVarR, >>=)
#undef VM_GAMEVAR_OPERATOR
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "global.h"
#include "duke3d.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
user_defs ud;
@ -124,4 +124,4 @@ int16_t g_blimpSpawnItems[15] =
char CheatKeys[2] = { sc_D, sc_N };
END_DUKE_NS
END_EDUKE_NS

View file

@ -32,7 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "sounds.h"
#include "menu.h"
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
#ifdef global_c_
#define G_EXTERN
@ -205,7 +205,7 @@ EXTERN_INLINE void G_RestoreInterpolations(void) //Stick at end of drawscreen
#endif
END_DUKE_NS
END_EDUKE_NS
#endif

View file

@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#pragma once
BEGIN_DUKE_NS
BEGIN_EDUKE_NS
enum dukeinv_t
{
@ -76,4 +76,4 @@ enum dukeweapon_t
MAX_WEAPONS
};
END_DUKE_NS
END_EDUKE_NS

Some files were not shown because too many files have changed in this diff Show more