Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • better-player-states
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-1258
  • fix-1277
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • gitlab-ci
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-debug-library
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • master
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
141 results
Show changes
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -313,6 +313,7 @@ typedef struct mobj_s
UINT32 renderflags; // render flags
INT32 blendmode; // blend mode
fixed_t alpha; // alpha
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale, old_spritexscale2, old_spriteyscale2;
......@@ -456,6 +457,7 @@ typedef struct precipmobj_s
UINT32 renderflags; // render flags
INT32 blendmode; // blend mode
fixed_t alpha; // alpha
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale, old_spritexscale2, old_spriteyscale2;
......@@ -537,6 +539,8 @@ boolean P_SceneryZMovement(mobj_t *mo);
void P_PlayerZMovement(mobj_t *mo);
void P_EmeraldManager(void);
mobj_t *P_FindNewPosition(UINT32 oldposition);
extern INT32 modulothing;
#define MAXHUNTEMERALDS 64
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2006 by James Haley
// Copyright (C) 2006-2023 by Sonic Team Junior.
// Copyright (C) 2006-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -878,15 +878,15 @@ static void Polyobj_carryThings(polyobj_t *po, fixed_t dx, fixed_t dy)
{
mobj_t *mo;
blocknode_t *block;
blocknode_t *next = NULL;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
continue;
block = blocklinks[y * bmapwidth + x];
for (; block; block = block->mnext)
for (block = blocklinks[y * bmapwidth + x]; block != NULL; block = next)
{
mo = block->mobj;
next = block->mnext;
if (mo->lastlook == pomovecount)
continue;
......@@ -927,11 +927,11 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line)
if (!(po->flags & POF_SOLID))
return hitflags;
// adjust linedef bounding box to blockmap, extend by MAXRADIUS
linebox[BOXLEFT] = (unsigned)(line->bbox[BOXLEFT] - bmaporgx - MAXRADIUS) >> MAPBLOCKSHIFT;
linebox[BOXRIGHT] = (unsigned)(line->bbox[BOXRIGHT] - bmaporgx + MAXRADIUS) >> MAPBLOCKSHIFT;
linebox[BOXBOTTOM] = (unsigned)(line->bbox[BOXBOTTOM] - bmaporgy - MAXRADIUS) >> MAPBLOCKSHIFT;
linebox[BOXTOP] = (unsigned)(line->bbox[BOXTOP] - bmaporgy + MAXRADIUS) >> MAPBLOCKSHIFT;
// adjust linedef bounding box to blockmap
linebox[BOXLEFT] = (unsigned)(line->bbox[BOXLEFT] - bmaporgx) >> MAPBLOCKSHIFT;
linebox[BOXRIGHT] = (unsigned)(line->bbox[BOXRIGHT] - bmaporgx) >> MAPBLOCKSHIFT;
linebox[BOXBOTTOM] = (unsigned)(line->bbox[BOXBOTTOM] - bmaporgy) >> MAPBLOCKSHIFT;
linebox[BOXTOP] = (unsigned)(line->bbox[BOXTOP] - bmaporgy) >> MAPBLOCKSHIFT;
// check all mobj blockmap cells the line contacts
for (y = linebox[BOXBOTTOM]; y <= linebox[BOXTOP]; ++y)
......@@ -942,9 +942,11 @@ static INT32 Polyobj_clipThings(polyobj_t *po, line_t *line)
{
mobj_t *mo = NULL;
blocknode_t *block = blocklinks[y * bmapwidth + x];
blocknode_t *next = NULL;
for (; block; block = block->mnext)
for (; block != NULL; block = next)
{
next = block->mnext;
mo = block->mobj;
// Don't scroll objects that aren't affected by gravity
......@@ -1115,15 +1117,15 @@ static void Polyobj_rotateThings(polyobj_t *po, vector2_t origin, angle_t delta,
{
mobj_t *mo;
blocknode_t *block;
blocknode_t *next = NULL;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
continue;
block = blocklinks[y * bmapwidth + x];
for (; block; block = block->mnext)
for (block = blocklinks[y * bmapwidth + x]; block != NULL; block = next)
{
mo = block->mobj;
next = block->mnext;
if (mo->lastlook == pomovecount)
continue;
......@@ -1316,7 +1318,7 @@ void Polyobj_InitLevel(void)
// the mobj_t pointers on a queue for use below.
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo = (mobj_t *)th;
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -39,7 +39,7 @@
#define FF_FRAMEMASK 0xff
/// \brief Frame flags - SPR2: Super sprite2
#define FF_SPR2SUPER 0x80
#define FF_SPR2SUPER SPR2F_SUPER //TODO: 2.3: remove this backwards compat hack
/// \brief Frame flags - SPR2: A change of state at the end of Sprite2 animation
#define FF_SPR2ENDSTATE 0x100
/// \brief Frame flags - SPR2: 50% of starting in middle of Sprite2 animation
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -35,9 +35,249 @@
#include "p_polyobj.h"
#include "lua_script.h"
#include "p_slopes.h"
#include "hu_stuff.h"
savedata_t savedata;
UINT8 *save_p;
#define ALLOC_SIZE(p, z) \
if ((p)->pos + (z) > (p)->size) \
{ \
while ((p)->pos + (z) > (p)->size) \
(p)->size <<= 1; \
(p)->buf = realloc((p)->buf, (p)->size); \
}
void P_WriteUINT8(save_t *p, UINT8 v)
{
ALLOC_SIZE(p, sizeof(v));
memcpy(&p->buf[p->pos], &v, sizeof(v));
p->pos += sizeof(v);
}
void P_WriteSINT8(save_t *p, SINT8 v)
{
ALLOC_SIZE(p, sizeof(v));
memcpy(&p->buf[p->pos], &v, sizeof(v));
p->pos += sizeof(v);
}
void P_WriteUINT16(save_t *p, UINT16 v)
{
ALLOC_SIZE(p, sizeof(v));
memcpy(&p->buf[p->pos], &v, sizeof(v));
p->pos += sizeof(v);
}
void P_WriteINT16(save_t *p, INT16 v)
{
ALLOC_SIZE(p, sizeof(v));
memcpy(&p->buf[p->pos], &v, sizeof(v));
p->pos += sizeof(v);
}
void P_WriteUINT32(save_t *p, UINT32 v)
{
ALLOC_SIZE(p, sizeof(v));
memcpy(&p->buf[p->pos], &v, sizeof(v));
p->pos += sizeof(v);
}
void P_WriteINT32(save_t *p, INT32 v)
{
ALLOC_SIZE(p, sizeof(v));
memcpy(&p->buf[p->pos], &v, sizeof(v));
p->pos += sizeof(v);
}
void P_WriteChar(save_t *p, char v)
{
ALLOC_SIZE(p, sizeof(v));
memcpy(&p->buf[p->pos], &v, sizeof(v));
p->pos += sizeof(v);
}
void P_WriteFixed(save_t *p, fixed_t v)
{
ALLOC_SIZE(p, sizeof(v));
memcpy(&p->buf[p->pos], &v, sizeof(v));
p->pos += sizeof(v);
}
void P_WriteAngle(save_t *p, angle_t v)
{
ALLOC_SIZE(p, sizeof(v));
memcpy(&p->buf[p->pos], &v, sizeof(v));
p->pos += sizeof(v);
}
void P_WriteStringN(save_t *p, char const *s, size_t n)
{
size_t i;
for (i = 0; i < n && s[i] != '\0'; i++)
P_WriteChar(p, s[i]);
if (i < n)
P_WriteChar(p, '\0');
}
void P_WriteStringL(save_t *p, char const *s, size_t n)
{
size_t i;
for (i = 0; i < n - 1 && s[i] != '\0'; i++)
P_WriteChar(p, s[i]);
P_WriteChar(p, '\0');
}
void P_WriteString(save_t *p, char const *s)
{
size_t i;
for (i = 0; s[i] != '\0'; i++)
P_WriteChar(p, s[i]);
P_WriteChar(p, '\0');
}
void P_WriteMem(save_t *p, void const *s, size_t n)
{
ALLOC_SIZE(p, n);
memcpy(&p->buf[p->pos], s, n);
p->pos += n;
}
void P_SkipStringN(save_t *p, size_t n)
{
size_t i;
for (i = 0; p->pos < p->size && i < n && P_ReadChar(p) != '\0'; i++);
}
void P_SkipStringL(save_t *p, size_t n)
{
P_SkipStringN(p, n);
}
void P_SkipString(save_t *p)
{
P_SkipStringN(p, SIZE_MAX);
}
UINT8 P_ReadUINT8(save_t *p)
{
UINT8 v;
if (p->pos + sizeof(v) > p->size)
return 0;
memcpy(&v, &p->buf[p->pos], sizeof(v));
p->pos += sizeof(v);
return v;
}
SINT8 P_ReadSINT8(save_t *p)
{
SINT8 v;
if (p->pos + sizeof(v) > p->size)
return 0;
memcpy(&v, &p->buf[p->pos], sizeof(v));
p->pos += sizeof(v);
return v;
}
UINT16 P_ReadUINT16(save_t *p)
{
UINT16 v;
if (p->pos + sizeof(v) > p->size)
return 0;
memcpy(&v, &p->buf[p->pos], sizeof(v));
p->pos += sizeof(v);
return v;
}
INT16 P_ReadINT16(save_t *p)
{
INT16 v;
if (p->pos + sizeof(v) > p->size)
return 0;
memcpy(&v, &p->buf[p->pos], sizeof(v));
p->pos += sizeof(v);
return v;
}
UINT32 P_ReadUINT32(save_t *p)
{
UINT32 v;
if (p->pos + sizeof(v) > p->size)
return 0;
memcpy(&v, &p->buf[p->pos], sizeof(v));
p->pos += sizeof(v);
return v;
}
INT32 P_ReadINT32(save_t *p)
{
INT32 v;
if (p->pos + sizeof(v) > p->size)
return 0;
memcpy(&v, &p->buf[p->pos], sizeof(v));
p->pos += sizeof(v);
return v;
}
char P_ReadChar(save_t *p)
{
char v;
if (p->pos + sizeof(v) > p->size)
return 0;
memcpy(&v, &p->buf[p->pos], sizeof(v));
p->pos += sizeof(v);
return v;
}
fixed_t P_ReadFixed(save_t *p)
{
fixed_t v;
if (p->pos + sizeof(v) > p->size)
return 0;
memcpy(&v, &p->buf[p->pos], sizeof(v));
p->pos += sizeof(v);
return v;
}
angle_t P_ReadAngle(save_t *p)
{
angle_t v;
if (p->pos + sizeof(v) > p->size)
return 0;
memcpy(&v, &p->buf[p->pos], sizeof(v));
p->pos += sizeof(v);
return v;
}
void P_ReadStringN(save_t *p, char *s, size_t n)
{
size_t i;
for (i = 0; p->pos < p->size && i < n && (s[i] = P_ReadChar(p)) != '\0'; i++);
s[i] = '\0';
}
void P_ReadStringL(save_t *p, char *s, size_t n)
{
P_ReadStringN(p, s, n - 1);
}
void P_ReadString(save_t *p, char *s)
{
P_ReadStringN(p, s, SIZE_MAX);
}
void P_ReadMem(save_t *p, void *s, size_t n)
{
if (p->pos + n > p->size)
return;
memcpy(s, &p->buf[p->pos], n);
p->pos += n;
}
// Block UINT32s to attempt to ensure that the correct data is
// being sent and received
......@@ -62,7 +302,19 @@ typedef enum
DRONE = 0x80,
} player_saveflags;
static inline void P_ArchivePlayer(void)
static inline UINT32 SavePlayer(const player_t *player)
{
if (player) return (UINT32)(player - players);
return 0xFFFFFFFF;
}
static inline player_t *LoadPlayer(UINT32 player)
{
if (player >= MAXPLAYERS) return NULL;
return &players[player];
}
static inline void P_ArchivePlayer(save_t *save_p)
{
const player_t *player = &players[consoleplayer];
SINT8 pllives = player->lives;
......@@ -72,32 +324,32 @@ static inline void P_ArchivePlayer(void)
#ifdef NEWSKINSAVES
// Write a specific value into the old skininfo location.
// If we read something other than this, it's an older save file that used skin numbers.
WRITEUINT16(save_p, NEWSKINSAVES);
P_WriteUINT16(save_p, NEWSKINSAVES);
#endif
// Write skin names, so that loading skins in different orders
// doesn't change who the save file is for!
WRITESTRINGN(save_p, skins[player->skin]->name, SKINNAMESIZE);
P_WriteStringN(save_p, skins[player->skin]->name, SKINNAMESIZE);
if (botskin != 0)
{
WRITESTRINGN(save_p, skins[botskin-1]->name, SKINNAMESIZE);
P_WriteStringN(save_p, skins[botskin-1]->name, SKINNAMESIZE);
}
else
{
WRITESTRINGN(save_p, "\0", SKINNAMESIZE);
P_WriteStringN(save_p, "\0", SKINNAMESIZE);
}
WRITEUINT8(save_p, numgameovers);
WRITESINT8(save_p, pllives);
WRITEUINT32(save_p, player->score);
WRITEINT32(save_p, player->continues);
P_WriteUINT8(save_p, numgameovers);
P_WriteSINT8(save_p, pllives);
P_WriteUINT32(save_p, player->score);
P_WriteINT32(save_p, player->continues);
}
static inline void P_UnArchivePlayer(void)
static inline void P_UnArchivePlayer(save_t *save_p)
{
#ifdef NEWSKINSAVES
INT16 backwardsCompat = READUINT16(save_p);
INT16 backwardsCompat = P_ReadUINT16(save_p);
if (backwardsCompat != NEWSKINSAVES)
{
......@@ -111,30 +363,30 @@ static inline void P_UnArchivePlayer(void)
char ourSkinName[SKINNAMESIZE+1];
char botSkinName[SKINNAMESIZE+1];
READSTRINGN(save_p, ourSkinName, SKINNAMESIZE);
P_ReadStringN(save_p, ourSkinName, SKINNAMESIZE);
savedata.skin = R_SkinAvailable(ourSkinName);
READSTRINGN(save_p, botSkinName, SKINNAMESIZE);
P_ReadStringN(save_p, botSkinName, SKINNAMESIZE);
savedata.botskin = R_SkinAvailable(botSkinName) + 1;
}
savedata.numgameovers = READUINT8(save_p);
savedata.lives = READSINT8(save_p);
savedata.score = READUINT32(save_p);
savedata.continues = READINT32(save_p);
savedata.numgameovers = P_ReadUINT8(save_p);
savedata.lives = P_ReadSINT8(save_p);
savedata.score = P_ReadUINT32(save_p);
savedata.continues = P_ReadINT32(save_p);
}
static void P_NetArchivePlayers(void)
static void P_NetArchivePlayers(save_t *save_p)
{
INT32 i, j;
UINT16 flags;
// size_t q;
WRITEUINT32(save_p, ARCHIVEBLOCK_PLAYERS);
P_WriteUINT32(save_p, ARCHIVEBLOCK_PLAYERS);
for (i = 0; i < MAXPLAYERS; i++)
{
WRITESINT8(save_p, (SINT8)adminplayers[i]);
P_WriteSINT8(save_p, (SINT8)adminplayers[i]);
if (!playeringame[i])
continue;
......@@ -143,142 +395,143 @@ static void P_NetArchivePlayers(void)
// no longer send ticcmds
WRITESTRINGN(save_p, player_names[i], MAXPLAYERNAME);
WRITEINT16(save_p, players[i].angleturn);
WRITEINT16(save_p, players[i].oldrelangleturn);
WRITEANGLE(save_p, players[i].aiming);
WRITEANGLE(save_p, players[i].drawangle);
WRITEANGLE(save_p, players[i].viewrollangle);
WRITEANGLE(save_p, players[i].awayviewaiming);
WRITEINT32(save_p, players[i].awayviewtics);
WRITEINT16(save_p, players[i].rings);
WRITEINT16(save_p, players[i].spheres);
WRITESINT8(save_p, players[i].pity);
WRITEINT32(save_p, players[i].currentweapon);
WRITEINT32(save_p, players[i].ringweapons);
WRITEUINT16(save_p, players[i].ammoremoval);
WRITEUINT32(save_p, players[i].ammoremovaltimer);
WRITEINT32(save_p, players[i].ammoremovaltimer);
P_WriteStringN(save_p, player_names[i], MAXPLAYERNAME);
P_WriteINT16(save_p, players[i].angleturn);
P_WriteINT16(save_p, players[i].oldrelangleturn);
P_WriteAngle(save_p, players[i].aiming);
P_WriteAngle(save_p, players[i].drawangle);
P_WriteAngle(save_p, players[i].viewrollangle);
P_WriteAngle(save_p, players[i].awayviewaiming);
P_WriteINT32(save_p, players[i].awayviewtics);
P_WriteINT16(save_p, players[i].rings);
P_WriteINT16(save_p, players[i].spheres);
P_WriteSINT8(save_p, players[i].pity);
P_WriteINT32(save_p, players[i].currentweapon);
P_WriteINT32(save_p, players[i].ringweapons);
P_WriteUINT16(save_p, players[i].ammoremoval);
P_WriteUINT32(save_p, players[i].ammoremovaltimer);
P_WriteINT32(save_p, players[i].ammoremovaltimer);
for (j = 0; j < NUMPOWERS; j++)
WRITEUINT16(save_p, players[i].powers[j]);
WRITEUINT8(save_p, players[i].playerstate);
WRITEUINT32(save_p, players[i].pflags);
WRITEUINT8(save_p, players[i].panim);
WRITEUINT8(save_p, players[i].stronganim);
WRITEUINT8(save_p, players[i].spectator);
WRITEUINT8(save_p, players[i].muted);
WRITEUINT16(save_p, players[i].flashpal);
WRITEUINT16(save_p, players[i].flashcount);
WRITEUINT16(save_p, players[i].skincolor);
WRITEINT32(save_p, players[i].skin);
WRITEUINT32(save_p, players[i].availabilities);
WRITEUINT32(save_p, players[i].score);
WRITEUINT32(save_p, players[i].recordscore);
WRITEFIXED(save_p, players[i].dashspeed);
WRITESINT8(save_p, players[i].lives);
WRITESINT8(save_p, players[i].continues);
WRITESINT8(save_p, players[i].xtralife);
WRITEUINT8(save_p, players[i].gotcontinue);
WRITEFIXED(save_p, players[i].speed);
WRITEUINT8(save_p, players[i].secondjump);
WRITEUINT8(save_p, players[i].fly1);
WRITEUINT8(save_p, players[i].scoreadd);
WRITEUINT32(save_p, players[i].glidetime);
WRITEUINT8(save_p, players[i].climbing);
WRITEINT32(save_p, players[i].deadtimer);
WRITEUINT32(save_p, players[i].exiting);
WRITEUINT8(save_p, players[i].homing);
WRITEUINT32(save_p, players[i].dashmode);
WRITEUINT32(save_p, players[i].skidtime);
P_WriteUINT16(save_p, players[i].powers[j]);
P_WriteUINT8(save_p, players[i].playerstate);
P_WriteUINT32(save_p, players[i].pflags);
P_WriteUINT8(save_p, players[i].panim);
P_WriteUINT8(save_p, players[i].stronganim);
P_WriteUINT8(save_p, players[i].spectator);
P_WriteUINT8(save_p, players[i].muted);
P_WriteUINT16(save_p, players[i].flashpal);
P_WriteUINT16(save_p, players[i].flashcount);
P_WriteUINT16(save_p, players[i].skincolor);
P_WriteINT32(save_p, players[i].skin);
P_WriteUINT32(save_p, players[i].availabilities);
P_WriteUINT32(save_p, players[i].score);
P_WriteUINT32(save_p, players[i].recordscore);
P_WriteFixed(save_p, players[i].dashspeed);
P_WriteSINT8(save_p, players[i].lives);
P_WriteSINT8(save_p, players[i].continues);
P_WriteSINT8(save_p, players[i].xtralife);
P_WriteUINT8(save_p, players[i].gotcontinue);
P_WriteFixed(save_p, players[i].speed);
P_WriteUINT8(save_p, players[i].secondjump);
P_WriteUINT8(save_p, players[i].fly1);
P_WriteUINT8(save_p, players[i].scoreadd);
P_WriteUINT32(save_p, players[i].glidetime);
P_WriteUINT8(save_p, players[i].climbing);
P_WriteINT32(save_p, players[i].deadtimer);
P_WriteUINT32(save_p, players[i].exiting);
P_WriteUINT8(save_p, players[i].homing);
P_WriteUINT32(save_p, players[i].dashmode);
P_WriteUINT32(save_p, players[i].skidtime);
//////////
// Bots //
//////////
WRITEUINT8(save_p, players[i].bot);
WRITEUINT8(save_p, players[i].botmem.lastForward);
WRITEUINT8(save_p, players[i].botmem.lastBlocked);
WRITEUINT8(save_p, players[i].botmem.catchup_tics);
WRITEUINT8(save_p, players[i].botmem.thinkstate);
WRITEUINT8(save_p, players[i].removing);
P_WriteUINT8(save_p, players[i].bot);
P_WriteUINT32(save_p, SavePlayer(players[i].botleader));
P_WriteUINT8(save_p, players[i].botmem.lastForward);
P_WriteUINT8(save_p, players[i].botmem.lastBlocked);
P_WriteUINT8(save_p, players[i].botmem.catchup_tics);
P_WriteUINT8(save_p, players[i].botmem.thinkstate);
P_WriteUINT8(save_p, players[i].removing);
WRITEUINT8(save_p, players[i].blocked);
WRITEUINT16(save_p, players[i].lastbuttons);
P_WriteUINT8(save_p, players[i].blocked);
P_WriteUINT16(save_p, players[i].lastbuttons);
////////////////////////////
// Conveyor Belt Movement //
////////////////////////////
WRITEFIXED(save_p, players[i].cmomx); // Conveyor momx
WRITEFIXED(save_p, players[i].cmomy); // Conveyor momy
WRITEFIXED(save_p, players[i].rmomx); // "Real" momx (momx - cmomx)
WRITEFIXED(save_p, players[i].rmomy); // "Real" momy (momy - cmomy)
P_WriteFixed(save_p, players[i].cmomx); // Conveyor momx
P_WriteFixed(save_p, players[i].cmomy); // Conveyor momy
P_WriteFixed(save_p, players[i].rmomx); // "Real" momx (momx - cmomx)
P_WriteFixed(save_p, players[i].rmomy); // "Real" momy (momy - cmomy)
/////////////////////
// Race Mode Stuff //
/////////////////////
WRITEINT16(save_p, players[i].numboxes);
WRITEINT16(save_p, players[i].totalring);
WRITEUINT32(save_p, players[i].realtime);
WRITEUINT8(save_p, players[i].laps);
P_WriteINT16(save_p, players[i].numboxes);
P_WriteINT16(save_p, players[i].totalring);
P_WriteUINT32(save_p, players[i].realtime);
P_WriteUINT8(save_p, players[i].laps);
////////////////////
// CTF Mode Stuff //
////////////////////
WRITEINT32(save_p, players[i].ctfteam);
WRITEUINT16(save_p, players[i].gotflag);
WRITEINT32(save_p, players[i].weapondelay);
WRITEINT32(save_p, players[i].tossdelay);
WRITEUINT32(save_p, players[i].starposttime);
WRITEINT16(save_p, players[i].starpostx);
WRITEINT16(save_p, players[i].starposty);
WRITEINT16(save_p, players[i].starpostz);
WRITEINT32(save_p, players[i].starpostnum);
WRITEANGLE(save_p, players[i].starpostangle);
WRITEFIXED(save_p, players[i].starpostscale);
WRITEANGLE(save_p, players[i].angle_pos);
WRITEANGLE(save_p, players[i].old_angle_pos);
WRITEINT32(save_p, players[i].flyangle);
WRITEUINT32(save_p, players[i].drilltimer);
WRITEINT32(save_p, players[i].linkcount);
WRITEUINT32(save_p, players[i].linktimer);
WRITEINT32(save_p, players[i].anotherflyangle);
WRITEUINT32(save_p, players[i].nightstime);
WRITEUINT32(save_p, players[i].bumpertime);
WRITEINT32(save_p, players[i].drillmeter);
WRITEUINT8(save_p, players[i].drilldelay);
WRITEUINT8(save_p, players[i].bonustime);
WRITEFIXED(save_p, players[i].oldscale);
WRITEUINT8(save_p, players[i].mare);
WRITEUINT8(save_p, players[i].marelap);
WRITEUINT8(save_p, players[i].marebonuslap);
WRITEUINT32(save_p, players[i].marebegunat);
WRITEUINT32(save_p, players[i].lastmaretime);
WRITEUINT32(save_p, players[i].startedtime);
WRITEUINT32(save_p, players[i].finishedtime);
WRITEUINT32(save_p, players[i].lapbegunat);
WRITEUINT32(save_p, players[i].lapstartedtime);
WRITEINT16(save_p, players[i].finishedspheres);
WRITEINT16(save_p, players[i].finishedrings);
WRITEUINT32(save_p, players[i].marescore);
WRITEUINT32(save_p, players[i].lastmarescore);
WRITEUINT32(save_p, players[i].totalmarescore);
WRITEUINT8(save_p, players[i].lastmare);
WRITEUINT8(save_p, players[i].lastmarelap);
WRITEUINT8(save_p, players[i].lastmarebonuslap);
WRITEUINT8(save_p, players[i].totalmarelap);
WRITEUINT8(save_p, players[i].totalmarebonuslap);
WRITEINT32(save_p, players[i].maxlink);
WRITEUINT8(save_p, players[i].texttimer);
WRITEUINT8(save_p, players[i].textvar);
P_WriteINT32(save_p, players[i].ctfteam);
P_WriteUINT16(save_p, players[i].gotflag);
P_WriteINT32(save_p, players[i].weapondelay);
P_WriteINT32(save_p, players[i].tossdelay);
P_WriteUINT32(save_p, players[i].starposttime);
P_WriteINT16(save_p, players[i].starpostx);
P_WriteINT16(save_p, players[i].starposty);
P_WriteINT16(save_p, players[i].starpostz);
P_WriteINT32(save_p, players[i].starpostnum);
P_WriteAngle(save_p, players[i].starpostangle);
P_WriteFixed(save_p, players[i].starpostscale);
P_WriteAngle(save_p, players[i].angle_pos);
P_WriteAngle(save_p, players[i].old_angle_pos);
P_WriteINT32(save_p, players[i].flyangle);
P_WriteUINT32(save_p, players[i].drilltimer);
P_WriteINT32(save_p, players[i].linkcount);
P_WriteUINT32(save_p, players[i].linktimer);
P_WriteINT32(save_p, players[i].anotherflyangle);
P_WriteUINT32(save_p, players[i].nightstime);
P_WriteUINT32(save_p, players[i].bumpertime);
P_WriteINT32(save_p, players[i].drillmeter);
P_WriteUINT8(save_p, players[i].drilldelay);
P_WriteUINT8(save_p, players[i].bonustime);
P_WriteFixed(save_p, players[i].oldscale);
P_WriteUINT8(save_p, players[i].mare);
P_WriteUINT8(save_p, players[i].marelap);
P_WriteUINT8(save_p, players[i].marebonuslap);
P_WriteUINT32(save_p, players[i].marebegunat);
P_WriteUINT32(save_p, players[i].lastmaretime);
P_WriteUINT32(save_p, players[i].startedtime);
P_WriteUINT32(save_p, players[i].finishedtime);
P_WriteUINT32(save_p, players[i].lapbegunat);
P_WriteUINT32(save_p, players[i].lapstartedtime);
P_WriteINT16(save_p, players[i].finishedspheres);
P_WriteINT16(save_p, players[i].finishedrings);
P_WriteUINT32(save_p, players[i].marescore);
P_WriteUINT32(save_p, players[i].lastmarescore);
P_WriteUINT32(save_p, players[i].totalmarescore);
P_WriteUINT8(save_p, players[i].lastmare);
P_WriteUINT8(save_p, players[i].lastmarelap);
P_WriteUINT8(save_p, players[i].lastmarebonuslap);
P_WriteUINT8(save_p, players[i].totalmarelap);
P_WriteUINT8(save_p, players[i].totalmarebonuslap);
P_WriteINT32(save_p, players[i].maxlink);
P_WriteUINT8(save_p, players[i].texttimer);
P_WriteUINT8(save_p, players[i].textvar);
if (players[i].capsule)
flags |= CAPSULE;
......@@ -298,73 +551,73 @@ static void P_NetArchivePlayers(void)
if (players[i].drone)
flags |= DRONE;
WRITEINT16(save_p, players[i].lastsidehit);
WRITEINT16(save_p, players[i].lastlinehit);
P_WriteINT16(save_p, players[i].lastsidehit);
P_WriteINT16(save_p, players[i].lastlinehit);
WRITEUINT32(save_p, players[i].losstime);
P_WriteUINT32(save_p, players[i].losstime);
WRITEUINT8(save_p, players[i].timeshit);
P_WriteUINT8(save_p, players[i].timeshit);
WRITEINT32(save_p, players[i].onconveyor);
P_WriteINT32(save_p, players[i].onconveyor);
WRITEUINT32(save_p, players[i].jointime);
WRITEUINT32(save_p, players[i].quittime);
P_WriteUINT32(save_p, players[i].jointime);
P_WriteUINT32(save_p, players[i].quittime);
WRITEUINT16(save_p, flags);
P_WriteUINT16(save_p, flags);
if (flags & CAPSULE)
WRITEUINT32(save_p, players[i].capsule->mobjnum);
P_WriteUINT32(save_p, players[i].capsule->mobjnum);
if (flags & FIRSTAXIS)
WRITEUINT32(save_p, players[i].axis1->mobjnum);
P_WriteUINT32(save_p, players[i].axis1->mobjnum);
if (flags & SECONDAXIS)
WRITEUINT32(save_p, players[i].axis2->mobjnum);
P_WriteUINT32(save_p, players[i].axis2->mobjnum);
if (flags & AWAYVIEW)
WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum);
P_WriteUINT32(save_p, players[i].awayviewmobj->mobjnum);
if (flags & FOLLOW)
WRITEUINT32(save_p, players[i].followmobj->mobjnum);
P_WriteUINT32(save_p, players[i].followmobj->mobjnum);
if (flags & DRONE)
WRITEUINT32(save_p, players[i].drone->mobjnum);
WRITEFIXED(save_p, players[i].camerascale);
WRITEFIXED(save_p, players[i].shieldscale);
WRITEUINT8(save_p, players[i].charability);
WRITEUINT8(save_p, players[i].charability2);
WRITEUINT32(save_p, players[i].charflags);
WRITEUINT32(save_p, (UINT32)players[i].thokitem);
WRITEUINT32(save_p, (UINT32)players[i].spinitem);
WRITEUINT32(save_p, (UINT32)players[i].revitem);
WRITEUINT32(save_p, (UINT32)players[i].followitem);
WRITEFIXED(save_p, players[i].actionspd);
WRITEFIXED(save_p, players[i].mindash);
WRITEFIXED(save_p, players[i].maxdash);
WRITEFIXED(save_p, players[i].normalspeed);
WRITEFIXED(save_p, players[i].runspeed);
WRITEUINT8(save_p, players[i].thrustfactor);
WRITEUINT8(save_p, players[i].accelstart);
WRITEUINT8(save_p, players[i].acceleration);
WRITEFIXED(save_p, players[i].jumpfactor);
WRITEFIXED(save_p, players[i].height);
WRITEFIXED(save_p, players[i].spinheight);
}
}
static void P_NetUnArchivePlayers(void)
P_WriteUINT32(save_p, players[i].drone->mobjnum);
P_WriteFixed(save_p, players[i].camerascale);
P_WriteFixed(save_p, players[i].shieldscale);
P_WriteUINT8(save_p, players[i].charability);
P_WriteUINT8(save_p, players[i].charability2);
P_WriteUINT32(save_p, players[i].charflags);
P_WriteUINT32(save_p, (UINT32)players[i].thokitem);
P_WriteUINT32(save_p, (UINT32)players[i].spinitem);
P_WriteUINT32(save_p, (UINT32)players[i].revitem);
P_WriteUINT32(save_p, (UINT32)players[i].followitem);
P_WriteFixed(save_p, players[i].actionspd);
P_WriteFixed(save_p, players[i].mindash);
P_WriteFixed(save_p, players[i].maxdash);
P_WriteFixed(save_p, players[i].normalspeed);
P_WriteFixed(save_p, players[i].runspeed);
P_WriteUINT8(save_p, players[i].thrustfactor);
P_WriteUINT8(save_p, players[i].accelstart);
P_WriteUINT8(save_p, players[i].acceleration);
P_WriteFixed(save_p, players[i].jumpfactor);
P_WriteFixed(save_p, players[i].height);
P_WriteFixed(save_p, players[i].spinheight);
}
}
static void P_NetUnArchivePlayers(save_t *save_p)
{
INT32 i, j;
UINT16 flags;
if (READUINT32(save_p) != ARCHIVEBLOCK_PLAYERS)
if (P_ReadUINT32(save_p) != ARCHIVEBLOCK_PLAYERS)
I_Error("Bad $$$.sav at archive block Players");
for (i = 0; i < MAXPLAYERS; i++)
{
adminplayers[i] = (INT32)READSINT8(save_p);
adminplayers[i] = (INT32)P_ReadSINT8(save_p);
// Do NOT memset player struct to 0
// other areas may initialize data elsewhere
......@@ -374,198 +627,199 @@ static void P_NetUnArchivePlayers(void)
// NOTE: sending tics should (hopefully) no longer be necessary
READSTRINGN(save_p, player_names[i], MAXPLAYERNAME);
players[i].angleturn = READINT16(save_p);
players[i].oldrelangleturn = READINT16(save_p);
players[i].aiming = READANGLE(save_p);
players[i].drawangle = READANGLE(save_p);
players[i].viewrollangle = READANGLE(save_p);
players[i].awayviewaiming = READANGLE(save_p);
players[i].awayviewtics = READINT32(save_p);
players[i].rings = READINT16(save_p);
players[i].spheres = READINT16(save_p);
players[i].pity = READSINT8(save_p);
players[i].currentweapon = READINT32(save_p);
players[i].ringweapons = READINT32(save_p);
players[i].ammoremoval = READUINT16(save_p);
players[i].ammoremovaltimer = READUINT32(save_p);
players[i].ammoremovalweapon = READINT32(save_p);
P_ReadStringN(save_p, player_names[i], MAXPLAYERNAME);
players[i].angleturn = P_ReadINT16(save_p);
players[i].oldrelangleturn = P_ReadINT16(save_p);
players[i].aiming = P_ReadAngle(save_p);
players[i].drawangle = P_ReadAngle(save_p);
players[i].viewrollangle = P_ReadAngle(save_p);
players[i].awayviewaiming = P_ReadAngle(save_p);
players[i].awayviewtics = P_ReadINT32(save_p);
players[i].rings = P_ReadINT16(save_p);
players[i].spheres = P_ReadINT16(save_p);
players[i].pity = P_ReadSINT8(save_p);
players[i].currentweapon = P_ReadINT32(save_p);
players[i].ringweapons = P_ReadINT32(save_p);
players[i].ammoremoval = P_ReadUINT16(save_p);
players[i].ammoremovaltimer = P_ReadUINT32(save_p);
players[i].ammoremovalweapon = P_ReadINT32(save_p);
for (j = 0; j < NUMPOWERS; j++)
players[i].powers[j] = READUINT16(save_p);
players[i].playerstate = READUINT8(save_p);
players[i].pflags = READUINT32(save_p);
players[i].panim = READUINT8(save_p);
players[i].stronganim = READUINT8(save_p);
players[i].spectator = READUINT8(save_p);
players[i].muted = READUINT8(save_p);
players[i].flashpal = READUINT16(save_p);
players[i].flashcount = READUINT16(save_p);
players[i].skincolor = READUINT16(save_p);
players[i].skin = READINT32(save_p);
players[i].availabilities = READUINT32(save_p);
players[i].score = READUINT32(save_p);
players[i].recordscore = READUINT32(save_p);
players[i].dashspeed = READFIXED(save_p); // dashing speed
players[i].lives = READSINT8(save_p);
players[i].continues = READSINT8(save_p); // continues that player has acquired
players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter
players[i].gotcontinue = READUINT8(save_p); // got continue from stage
players[i].speed = READFIXED(save_p); // Player's speed (distance formula of MOMX and MOMY values)
players[i].secondjump = READUINT8(save_p);
players[i].fly1 = READUINT8(save_p); // Tails flying
players[i].scoreadd = READUINT8(save_p); // Used for multiple enemy attack bonus
players[i].glidetime = READUINT32(save_p); // Glide counter for thrust
players[i].climbing = READUINT8(save_p); // Climbing on the wall
players[i].deadtimer = READINT32(save_p); // End game if game over lasts too long
players[i].exiting = READUINT32(save_p); // Exitlevel timer
players[i].homing = READUINT8(save_p); // Are you homing?
players[i].dashmode = READUINT32(save_p); // counter for dashmode ability
players[i].skidtime = READUINT32(save_p); // Skid timer
players[i].powers[j] = P_ReadUINT16(save_p);
players[i].playerstate = P_ReadUINT8(save_p);
players[i].pflags = P_ReadUINT32(save_p);
players[i].panim = P_ReadUINT8(save_p);
players[i].stronganim = P_ReadUINT8(save_p);
players[i].spectator = P_ReadUINT8(save_p);
players[i].muted = P_ReadUINT8(save_p);
players[i].flashpal = P_ReadUINT16(save_p);
players[i].flashcount = P_ReadUINT16(save_p);
players[i].skincolor = P_ReadUINT16(save_p);
players[i].skin = P_ReadINT32(save_p);
players[i].availabilities = P_ReadUINT32(save_p);
players[i].score = P_ReadUINT32(save_p);
players[i].recordscore = P_ReadUINT32(save_p);
players[i].dashspeed = P_ReadFixed(save_p); // dashing speed
players[i].lives = P_ReadSINT8(save_p);
players[i].continues = P_ReadSINT8(save_p); // continues that player has acquired
players[i].xtralife = P_ReadSINT8(save_p); // Ring Extra Life counter
players[i].gotcontinue = P_ReadUINT8(save_p); // got continue from stage
players[i].speed = P_ReadFixed(save_p); // Player's speed (distance formula of MOMX and MOMY values)
players[i].secondjump = P_ReadUINT8(save_p);
players[i].fly1 = P_ReadUINT8(save_p); // Tails flying
players[i].scoreadd = P_ReadUINT8(save_p); // Used for multiple enemy attack bonus
players[i].glidetime = P_ReadUINT32(save_p); // Glide counter for thrust
players[i].climbing = P_ReadUINT8(save_p); // Climbing on the wall
players[i].deadtimer = P_ReadINT32(save_p); // End game if game over lasts too long
players[i].exiting = P_ReadUINT32(save_p); // Exitlevel timer
players[i].homing = P_ReadUINT8(save_p); // Are you homing?
players[i].dashmode = P_ReadUINT32(save_p); // counter for dashmode ability
players[i].skidtime = P_ReadUINT32(save_p); // Skid timer
//////////
// Bots //
//////////
players[i].bot = READUINT8(save_p);
players[i].bot = P_ReadUINT8(save_p);
players[i].botleader = LoadPlayer(P_ReadUINT32(save_p));
players[i].botmem.lastForward = READUINT8(save_p);
players[i].botmem.lastBlocked = READUINT8(save_p);
players[i].botmem.catchup_tics = READUINT8(save_p);
players[i].botmem.thinkstate = READUINT8(save_p);
players[i].removing = READUINT8(save_p);
players[i].botmem.lastForward = P_ReadUINT8(save_p);
players[i].botmem.lastBlocked = P_ReadUINT8(save_p);
players[i].botmem.catchup_tics = P_ReadUINT8(save_p);
players[i].botmem.thinkstate = P_ReadUINT8(save_p);
players[i].removing = P_ReadUINT8(save_p);
players[i].blocked = READUINT8(save_p);
players[i].lastbuttons = READUINT16(save_p);
players[i].blocked = P_ReadUINT8(save_p);
players[i].lastbuttons = P_ReadUINT16(save_p);
////////////////////////////
// Conveyor Belt Movement //
////////////////////////////
players[i].cmomx = READFIXED(save_p); // Conveyor momx
players[i].cmomy = READFIXED(save_p); // Conveyor momy
players[i].rmomx = READFIXED(save_p); // "Real" momx (momx - cmomx)
players[i].rmomy = READFIXED(save_p); // "Real" momy (momy - cmomy)
players[i].cmomx = P_ReadFixed(save_p); // Conveyor momx
players[i].cmomy = P_ReadFixed(save_p); // Conveyor momy
players[i].rmomx = P_ReadFixed(save_p); // "Real" momx (momx - cmomx)
players[i].rmomy = P_ReadFixed(save_p); // "Real" momy (momy - cmomy)
/////////////////////
// Race Mode Stuff //
/////////////////////
players[i].numboxes = READINT16(save_p); // Number of item boxes obtained for Race Mode
players[i].totalring = READINT16(save_p); // Total number of rings obtained for Race Mode
players[i].realtime = READUINT32(save_p); // integer replacement for leveltime
players[i].laps = READUINT8(save_p); // Number of laps (optional)
players[i].numboxes = P_ReadINT16(save_p); // Number of item boxes obtained for Race Mode
players[i].totalring = P_ReadINT16(save_p); // Total number of rings obtained for Race Mode
players[i].realtime = P_ReadUINT32(save_p); // integer replacement for leveltime
players[i].laps = P_ReadUINT8(save_p); // Number of laps (optional)
////////////////////
// CTF Mode Stuff //
////////////////////
players[i].ctfteam = READINT32(save_p); // 1 == Red, 2 == Blue
players[i].gotflag = READUINT16(save_p); // 1 == Red, 2 == Blue Do you have the flag?
players[i].weapondelay = READINT32(save_p);
players[i].tossdelay = READINT32(save_p);
players[i].starposttime = READUINT32(save_p);
players[i].starpostx = READINT16(save_p);
players[i].starposty = READINT16(save_p);
players[i].starpostz = READINT16(save_p);
players[i].starpostnum = READINT32(save_p);
players[i].starpostangle = READANGLE(save_p);
players[i].starpostscale = READFIXED(save_p);
players[i].angle_pos = READANGLE(save_p);
players[i].old_angle_pos = READANGLE(save_p);
players[i].flyangle = READINT32(save_p);
players[i].drilltimer = READUINT32(save_p);
players[i].linkcount = READINT32(save_p);
players[i].linktimer = READUINT32(save_p);
players[i].anotherflyangle = READINT32(save_p);
players[i].nightstime = READUINT32(save_p);
players[i].bumpertime = READUINT32(save_p);
players[i].drillmeter = READINT32(save_p);
players[i].drilldelay = READUINT8(save_p);
players[i].bonustime = (boolean)READUINT8(save_p);
players[i].oldscale = READFIXED(save_p);
players[i].mare = READUINT8(save_p);
players[i].marelap = READUINT8(save_p);
players[i].marebonuslap = READUINT8(save_p);
players[i].marebegunat = READUINT32(save_p);
players[i].lastmaretime = READUINT32(save_p);
players[i].startedtime = READUINT32(save_p);
players[i].finishedtime = READUINT32(save_p);
players[i].lapbegunat = READUINT32(save_p);
players[i].lapstartedtime = READUINT32(save_p);
players[i].finishedspheres = READINT16(save_p);
players[i].finishedrings = READINT16(save_p);
players[i].marescore = READUINT32(save_p);
players[i].lastmarescore = READUINT32(save_p);
players[i].totalmarescore = READUINT32(save_p);
players[i].lastmare = READUINT8(save_p);
players[i].lastmarelap = READUINT8(save_p);
players[i].lastmarebonuslap = READUINT8(save_p);
players[i].totalmarelap = READUINT8(save_p);
players[i].totalmarebonuslap = READUINT8(save_p);
players[i].maxlink = READINT32(save_p);
players[i].texttimer = READUINT8(save_p);
players[i].textvar = READUINT8(save_p);
players[i].lastsidehit = READINT16(save_p);
players[i].lastlinehit = READINT16(save_p);
players[i].losstime = READUINT32(save_p);
players[i].timeshit = READUINT8(save_p);
players[i].onconveyor = READINT32(save_p);
players[i].jointime = READUINT32(save_p);
players[i].quittime = READUINT32(save_p);
flags = READUINT16(save_p);
players[i].ctfteam = P_ReadINT32(save_p); // 1 == Red, 2 == Blue
players[i].gotflag = P_ReadUINT16(save_p); // 1 == Red, 2 == Blue Do you have the flag?
players[i].weapondelay = P_ReadINT32(save_p);
players[i].tossdelay = P_ReadINT32(save_p);
players[i].starposttime = P_ReadUINT32(save_p);
players[i].starpostx = P_ReadINT16(save_p);
players[i].starposty = P_ReadINT16(save_p);
players[i].starpostz = P_ReadINT16(save_p);
players[i].starpostnum = P_ReadINT32(save_p);
players[i].starpostangle = P_ReadAngle(save_p);
players[i].starpostscale = P_ReadFixed(save_p);
players[i].angle_pos = P_ReadAngle(save_p);
players[i].old_angle_pos = P_ReadAngle(save_p);
players[i].flyangle = P_ReadINT32(save_p);
players[i].drilltimer = P_ReadUINT32(save_p);
players[i].linkcount = P_ReadINT32(save_p);
players[i].linktimer = P_ReadUINT32(save_p);
players[i].anotherflyangle = P_ReadINT32(save_p);
players[i].nightstime = P_ReadUINT32(save_p);
players[i].bumpertime = P_ReadUINT32(save_p);
players[i].drillmeter = P_ReadINT32(save_p);
players[i].drilldelay = P_ReadUINT8(save_p);
players[i].bonustime = (boolean)P_ReadUINT8(save_p);
players[i].oldscale = P_ReadFixed(save_p);
players[i].mare = P_ReadUINT8(save_p);
players[i].marelap = P_ReadUINT8(save_p);
players[i].marebonuslap = P_ReadUINT8(save_p);
players[i].marebegunat = P_ReadUINT32(save_p);
players[i].lastmaretime = P_ReadUINT32(save_p);
players[i].startedtime = P_ReadUINT32(save_p);
players[i].finishedtime = P_ReadUINT32(save_p);
players[i].lapbegunat = P_ReadUINT32(save_p);
players[i].lapstartedtime = P_ReadUINT32(save_p);
players[i].finishedspheres = P_ReadINT16(save_p);
players[i].finishedrings = P_ReadINT16(save_p);
players[i].marescore = P_ReadUINT32(save_p);
players[i].lastmarescore = P_ReadUINT32(save_p);
players[i].totalmarescore = P_ReadUINT32(save_p);
players[i].lastmare = P_ReadUINT8(save_p);
players[i].lastmarelap = P_ReadUINT8(save_p);
players[i].lastmarebonuslap = P_ReadUINT8(save_p);
players[i].totalmarelap = P_ReadUINT8(save_p);
players[i].totalmarebonuslap = P_ReadUINT8(save_p);
players[i].maxlink = P_ReadINT32(save_p);
players[i].texttimer = P_ReadUINT8(save_p);
players[i].textvar = P_ReadUINT8(save_p);
players[i].lastsidehit = P_ReadINT16(save_p);
players[i].lastlinehit = P_ReadINT16(save_p);
players[i].losstime = P_ReadUINT32(save_p);
players[i].timeshit = P_ReadUINT8(save_p);
players[i].onconveyor = P_ReadINT32(save_p);
players[i].jointime = P_ReadUINT32(save_p);
players[i].quittime = P_ReadUINT32(save_p);
flags = P_ReadUINT16(save_p);
if (flags & CAPSULE)
players[i].capsule = (mobj_t *)(size_t)READUINT32(save_p);
players[i].capsule = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (flags & FIRSTAXIS)
players[i].axis1 = (mobj_t *)(size_t)READUINT32(save_p);
players[i].axis1 = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (flags & SECONDAXIS)
players[i].axis2 = (mobj_t *)(size_t)READUINT32(save_p);
players[i].axis2 = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (flags & AWAYVIEW)
players[i].awayviewmobj = (mobj_t *)(size_t)READUINT32(save_p);
players[i].awayviewmobj = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (flags & FOLLOW)
players[i].followmobj = (mobj_t *)(size_t)READUINT32(save_p);
players[i].followmobj = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (flags & DRONE)
players[i].drone = (mobj_t *)(size_t)READUINT32(save_p);
players[i].drone = (mobj_t *)(size_t)P_ReadUINT32(save_p);
players[i].camerascale = READFIXED(save_p);
players[i].shieldscale = READFIXED(save_p);
players[i].camerascale = P_ReadFixed(save_p);
players[i].shieldscale = P_ReadFixed(save_p);
//SetPlayerSkinByNum(i, players[i].skin);
players[i].charability = READUINT8(save_p);
players[i].charability2 = READUINT8(save_p);
players[i].charflags = READUINT32(save_p);
players[i].thokitem = (mobjtype_t)READUINT32(save_p);
players[i].spinitem = (mobjtype_t)READUINT32(save_p);
players[i].revitem = (mobjtype_t)READUINT32(save_p);
players[i].followitem = (mobjtype_t)READUINT32(save_p);
players[i].actionspd = READFIXED(save_p);
players[i].mindash = READFIXED(save_p);
players[i].maxdash = READFIXED(save_p);
players[i].normalspeed = READFIXED(save_p);
players[i].runspeed = READFIXED(save_p);
players[i].thrustfactor = READUINT8(save_p);
players[i].accelstart = READUINT8(save_p);
players[i].acceleration = READUINT8(save_p);
players[i].jumpfactor = READFIXED(save_p);
players[i].height = READFIXED(save_p);
players[i].spinheight = READFIXED(save_p);
players[i].charability = P_ReadUINT8(save_p);
players[i].charability2 = P_ReadUINT8(save_p);
players[i].charflags = P_ReadUINT32(save_p);
players[i].thokitem = P_ReadUINT32(save_p);
players[i].spinitem = P_ReadUINT32(save_p);
players[i].revitem = P_ReadUINT32(save_p);
players[i].followitem = P_ReadUINT32(save_p);
players[i].actionspd = P_ReadFixed(save_p);
players[i].mindash = P_ReadFixed(save_p);
players[i].maxdash = P_ReadFixed(save_p);
players[i].normalspeed = P_ReadFixed(save_p);
players[i].runspeed = P_ReadFixed(save_p);
players[i].thrustfactor = P_ReadUINT8(save_p);
players[i].accelstart = P_ReadUINT8(save_p);
players[i].acceleration = P_ReadUINT8(save_p);
players[i].jumpfactor = P_ReadFixed(save_p);
players[i].height = P_ReadFixed(save_p);
players[i].spinheight = P_ReadFixed(save_p);
players[i].viewheight = 41*players[i].height/48; // scale cannot be factored in at this point
}
......@@ -668,12 +922,12 @@ static void ClearNetColormaps(void)
net_colormaps = NULL;
}
static void P_NetArchiveColormaps(void)
static void P_NetArchiveColormaps(save_t *save_p)
{
// We save and then we clean up our colormap mess
extracolormap_t *exc, *exc_next;
UINT32 i = 0;
WRITEUINT32(save_p, num_net_colormaps); // save for safety
P_WriteUINT32(save_p, num_net_colormaps); // save for safety
for (exc = net_colormaps; i < num_net_colormaps; i++, exc = exc_next)
{
......@@ -682,15 +936,15 @@ static void P_NetArchiveColormaps(void)
if (!exc)
exc = R_CreateDefaultColormap(false);
WRITEUINT8(save_p, exc->fadestart);
WRITEUINT8(save_p, exc->fadeend);
WRITEUINT8(save_p, exc->flags);
P_WriteUINT8(save_p, exc->fadestart);
P_WriteUINT8(save_p, exc->fadeend);
P_WriteUINT8(save_p, exc->flags);
WRITEINT32(save_p, exc->rgba);
WRITEINT32(save_p, exc->fadergba);
P_WriteINT32(save_p, exc->rgba);
P_WriteINT32(save_p, exc->fadergba);
#ifdef EXTRACOLORMAPLUMPS
WRITESTRINGN(save_p, exc->lumpname, 9);
P_WriteStringN(save_p, exc->lumpname, 9);
#endif
exc_next = exc->next;
......@@ -702,7 +956,7 @@ static void P_NetArchiveColormaps(void)
net_colormaps = NULL;
}
static void P_NetUnArchiveColormaps(void)
static void P_NetUnArchiveColormaps(save_t *save_p)
{
// When we reach this point, we already populated our list with
// dummy colormaps. Now that we are loading the color data,
......@@ -710,7 +964,7 @@ static void P_NetUnArchiveColormaps(void)
extracolormap_t *exc, *existing_exc, *exc_next = NULL;
UINT32 i = 0;
num_net_colormaps = READUINT32(save_p);
num_net_colormaps = P_ReadUINT32(save_p);
for (exc = net_colormaps; i < num_net_colormaps; i++, exc = exc_next)
{
......@@ -720,15 +974,15 @@ static void P_NetUnArchiveColormaps(void)
char lumpname[9];
#endif
fadestart = READUINT8(save_p);
fadeend = READUINT8(save_p);
flags = READUINT8(save_p);
fadestart = P_ReadUINT8(save_p);
fadeend = P_ReadUINT8(save_p);
flags = P_ReadUINT8(save_p);
rgba = READINT32(save_p);
fadergba = READINT32(save_p);
rgba = P_ReadINT32(save_p);
fadergba = P_ReadINT32(save_p);
#ifdef EXTRACOLORMAPLUMPS
READSTRINGN(save_p, lumpname, 9);
P_ReadStringN(save_p, lumpname, 9);
if (lumpname[0])
{
......@@ -804,29 +1058,29 @@ static void P_NetUnArchiveColormaps(void)
net_colormaps = NULL;
}
static void P_NetArchiveWaypoints(void)
static void P_NetArchiveWaypoints(save_t *save_p)
{
INT32 i, j;
for (i = 0; i < NUMWAYPOINTSEQUENCES; i++)
{
WRITEUINT16(save_p, numwaypoints[i]);
P_WriteUINT16(save_p, numwaypoints[i]);
for (j = 0; j < numwaypoints[i]; j++)
WRITEUINT32(save_p, waypoints[i][j] ? waypoints[i][j]->mobjnum : 0);
P_WriteUINT32(save_p, waypoints[i][j] ? waypoints[i][j]->mobjnum : 0);
}
}
static void P_NetUnArchiveWaypoints(void)
static void P_NetUnArchiveWaypoints(save_t *save_p)
{
INT32 i, j;
UINT32 mobjnum;
for (i = 0; i < NUMWAYPOINTSEQUENCES; i++)
{
numwaypoints[i] = READUINT16(save_p);
numwaypoints[i] = P_ReadUINT16(save_p);
for (j = 0; j < numwaypoints[i]; j++)
{
mobjnum = READUINT32(save_p);
mobjnum = P_ReadUINT32(save_p);
waypoints[i][j] = (mobjnum == 0) ? NULL : P_FindNewPosition(mobjnum);
}
}
......@@ -919,7 +1173,11 @@ enum
LD_SDMIDLIGHT = 1<<19,
LD_SDBOTLIGHT = 1<<20,
LD_SDREPEATCNT = 1<<21,
LD_SDFLAGS = 1<<22
LD_SDFLAGS = 1<<22,
LD_SDLIGHTABS = 1<<23,
LD_SDTOPLIGHTABS = 1<<24,
LD_SDMIDLIGHTABS = 1<<25,
LD_SDBOTLIGHTABS = 1<<26
};
static boolean P_AreArgsEqual(const line_t *li, const line_t *spawnli)
......@@ -969,7 +1227,7 @@ static boolean CheckFFloorDiff(const sector_t *ss)
// Special case: save the stats of all modified ffloors along with their ffloor "number"s
// we don't bother with ffloors that haven't changed, that would just add to savegame even more than is really needed
static void ArchiveFFloors(const sector_t *ss)
static void ArchiveFFloors(save_t *save_p, const sector_t *ss)
{
size_t j = 0; // ss->ffloors is saved as ffloor #0, ss->ffloors->next is #1, etc
ffloor_t *rover;
......@@ -984,19 +1242,19 @@ static void ArchiveFFloors(const sector_t *ss)
if (fflr_diff)
{
WRITEUINT16(save_p, j); // save ffloor "number"
WRITEUINT8(save_p, fflr_diff);
P_WriteUINT16(save_p, j); // save ffloor "number"
P_WriteUINT8(save_p, fflr_diff);
if (fflr_diff & FD_FLAGS)
WRITEUINT32(save_p, rover->fofflags);
P_WriteUINT32(save_p, rover->fofflags);
if (fflr_diff & FD_ALPHA)
WRITEINT16(save_p, rover->alpha);
P_WriteINT16(save_p, rover->alpha);
}
j++;
}
WRITEUINT16(save_p, 0xffff);
P_WriteUINT16(save_p, 0xffff);
}
static void UnArchiveFFloors(const sector_t *ss)
static void UnArchiveFFloors(save_t *save_p, const sector_t *ss)
{
UINT16 j = 0; // number of current ffloor in loop
UINT16 fflr_i; // saved ffloor "number" of next modified ffloor
......@@ -1007,7 +1265,7 @@ static void UnArchiveFFloors(const sector_t *ss)
if (!rover) // it is assumed sectors[i].ffloors actually exists, but just in case...
I_Error("Sector does not have any ffloors!");
fflr_i = READUINT16(save_p); // get first modified ffloor's number ready
fflr_i = P_ReadUINT16(save_p); // get first modified ffloor's number ready
for (;;) // for some reason the usual for (rover = x; ...) thing doesn't work here?
{
if (fflr_i == 0xffff) // end of modified ffloors list, let's stop already
......@@ -1022,21 +1280,21 @@ static void UnArchiveFFloors(const sector_t *ss)
continue;
}
fflr_diff = READUINT8(save_p);
fflr_diff = P_ReadUINT8(save_p);
if (fflr_diff & FD_FLAGS)
rover->fofflags = READUINT32(save_p);
rover->fofflags = P_ReadUINT32(save_p);
if (fflr_diff & FD_ALPHA)
rover->alpha = READINT16(save_p);
rover->alpha = P_ReadINT16(save_p);
fflr_i = READUINT16(save_p); // get next ffloor "number" ready
fflr_i = P_ReadUINT16(save_p); // get next ffloor "number" ready
j++;
rover = rover->next;
}
}
static void ArchiveSectors(void)
static void ArchiveSectors(save_t *save_p)
{
size_t i, j;
const sector_t *ss = sectors;
......@@ -1130,102 +1388,102 @@ static void ArchiveSectors(void)
if (diff)
{
WRITEUINT32(save_p, i);
WRITEUINT8(save_p, diff);
P_WriteUINT32(save_p, i);
P_WriteUINT8(save_p, diff);
if (diff & SD_DIFF2)
WRITEUINT8(save_p, diff2);
P_WriteUINT8(save_p, diff2);
if (diff2 & SD_DIFF3)
WRITEUINT8(save_p, diff3);
P_WriteUINT8(save_p, diff3);
if (diff3 & SD_DIFF4)
WRITEUINT8(save_p, diff4);
P_WriteUINT8(save_p, diff4);
if (diff4 & SD_DIFF5)
WRITEUINT8(save_p, diff5);
P_WriteUINT8(save_p, diff5);
if (diff & SD_FLOORHT)
WRITEFIXED(save_p, ss->floorheight);
P_WriteFixed(save_p, ss->floorheight);
if (diff & SD_CEILHT)
WRITEFIXED(save_p, ss->ceilingheight);
P_WriteFixed(save_p, ss->ceilingheight);
if (diff & SD_FLOORPIC)
WRITEMEM(save_p, levelflats[ss->floorpic].name, 8);
P_WriteMem(save_p, levelflats[ss->floorpic].name, 8);
if (diff & SD_CEILPIC)
WRITEMEM(save_p, levelflats[ss->ceilingpic].name, 8);
P_WriteMem(save_p, levelflats[ss->ceilingpic].name, 8);
if (diff & SD_LIGHT)
WRITEINT16(save_p, ss->lightlevel);
P_WriteINT16(save_p, ss->lightlevel);
if (diff & SD_SPECIAL)
WRITEINT16(save_p, ss->special);
P_WriteINT16(save_p, ss->special);
if (diff2 & SD_FXOFFS)
WRITEFIXED(save_p, ss->floorxoffset);
P_WriteFixed(save_p, ss->floorxoffset);
if (diff2 & SD_FYOFFS)
WRITEFIXED(save_p, ss->flooryoffset);
P_WriteFixed(save_p, ss->flooryoffset);
if (diff2 & SD_CXOFFS)
WRITEFIXED(save_p, ss->ceilingxoffset);
P_WriteFixed(save_p, ss->ceilingxoffset);
if (diff2 & SD_CYOFFS)
WRITEFIXED(save_p, ss->ceilingyoffset);
P_WriteFixed(save_p, ss->ceilingyoffset);
if (diff2 & SD_FLOORANG)
WRITEANGLE(save_p, ss->floorangle);
P_WriteAngle(save_p, ss->floorangle);
if (diff2 & SD_CEILANG)
WRITEANGLE(save_p, ss->ceilingangle);
P_WriteAngle(save_p, ss->ceilingangle);
if (diff2 & SD_TAG)
{
WRITEUINT32(save_p, ss->tags.count);
P_WriteUINT32(save_p, ss->tags.count);
for (j = 0; j < ss->tags.count; j++)
WRITEINT16(save_p, ss->tags.tags[j]);
P_WriteINT16(save_p, ss->tags.tags[j]);
}
if (diff3 & SD_COLORMAP)
WRITEUINT32(save_p, CheckAddNetColormapToList(ss->extra_colormap));
P_WriteUINT32(save_p, CheckAddNetColormapToList(ss->extra_colormap));
// returns existing index if already added, or appends to net_colormaps and returns new index
if (diff3 & SD_CRUMBLESTATE)
WRITEINT32(save_p, ss->crumblestate);
P_WriteINT32(save_p, ss->crumblestate);
if (diff3 & SD_FLOORLIGHT)
{
WRITEINT16(save_p, ss->floorlightlevel);
WRITEUINT8(save_p, ss->floorlightabsolute);
P_WriteINT16(save_p, ss->floorlightlevel);
P_WriteUINT8(save_p, ss->floorlightabsolute);
}
if (diff3 & SD_CEILLIGHT)
{
WRITEINT16(save_p, ss->ceilinglightlevel);
WRITEUINT8(save_p, ss->ceilinglightabsolute);
P_WriteINT16(save_p, ss->ceilinglightlevel);
P_WriteUINT8(save_p, ss->ceilinglightabsolute);
}
if (diff3 & SD_FLAG)
WRITEUINT32(save_p, ss->flags);
P_WriteUINT32(save_p, ss->flags);
if (diff3 & SD_SPECIALFLAG)
WRITEUINT32(save_p, ss->specialflags);
P_WriteUINT32(save_p, ss->specialflags);
if (diff4 & SD_DAMAGETYPE)
WRITEUINT8(save_p, ss->damagetype);
P_WriteUINT8(save_p, ss->damagetype);
if (diff4 & SD_TRIGGERTAG)
WRITEINT16(save_p, ss->triggertag);
P_WriteINT16(save_p, ss->triggertag);
if (diff4 & SD_TRIGGERER)
WRITEUINT8(save_p, ss->triggerer);
P_WriteUINT8(save_p, ss->triggerer);
if (diff4 & SD_FXSCALE)
WRITEFIXED(save_p, ss->floorxscale);
P_WriteFixed(save_p, ss->floorxscale);
if (diff4 & SD_FYSCALE)
WRITEFIXED(save_p, ss->flooryscale);
P_WriteFixed(save_p, ss->flooryscale);
if (diff4 & SD_CXSCALE)
WRITEFIXED(save_p, ss->ceilingxscale);
P_WriteFixed(save_p, ss->ceilingxscale);
if (diff4 & SD_CYSCALE)
WRITEFIXED(save_p, ss->ceilingyscale);
P_WriteFixed(save_p, ss->ceilingyscale);
if (diff5 & SD_GRAVITY)
WRITEFIXED(save_p, ss->gravity);
P_WriteFixed(save_p, ss->gravity);
if (diff5 & SD_FLOORPORTAL)
WRITEUINT32(save_p, ss->portal_floor);
P_WriteUINT32(save_p, ss->portal_floor);
if (diff5 & SD_CEILPORTAL)
WRITEUINT32(save_p, ss->portal_ceiling);
P_WriteUINT32(save_p, ss->portal_ceiling);
if (diff & SD_FFLOORS)
ArchiveFFloors(ss);
ArchiveFFloors(save_p, ss);
}
}
WRITEUINT32(save_p, 0xffffffff);
P_WriteUINT32(save_p, 0xffffffff);
}
static void UnArchiveSectors(void)
static void UnArchiveSectors(save_t *save_p)
{
UINT32 i;
UINT16 j;
UINT8 diff, diff2, diff3, diff4, diff5;
for (;;)
{
i = READUINT32(save_p);
i = P_ReadUINT32(save_p);
if (i == 0xffffffff)
break;
......@@ -1233,58 +1491,58 @@ static void UnArchiveSectors(void)
if (i > numsectors)
I_Error("Invalid sector number %u from server (expected end at %s)", i, sizeu1(numsectors));
diff = READUINT8(save_p);
diff = P_ReadUINT8(save_p);
if (diff & SD_DIFF2)
diff2 = READUINT8(save_p);
diff2 = P_ReadUINT8(save_p);
else
diff2 = 0;
if (diff2 & SD_DIFF3)
diff3 = READUINT8(save_p);
diff3 = P_ReadUINT8(save_p);
else
diff3 = 0;
if (diff3 & SD_DIFF4)
diff4 = READUINT8(save_p);
diff4 = P_ReadUINT8(save_p);
else
diff4 = 0;
if (diff4 & SD_DIFF5)
diff5 = READUINT8(save_p);
diff5 = P_ReadUINT8(save_p);
else
diff5 = 0;
if (diff & SD_FLOORHT)
sectors[i].floorheight = READFIXED(save_p);
sectors[i].floorheight = P_ReadFixed(save_p);
if (diff & SD_CEILHT)
sectors[i].ceilingheight = READFIXED(save_p);
sectors[i].ceilingheight = P_ReadFixed(save_p);
if (diff & SD_FLOORPIC)
{
sectors[i].floorpic = P_AddLevelFlatRuntime((char *)save_p);
save_p += 8;
sectors[i].floorpic = P_AddLevelFlatRuntime((char *)&save_p->buf[save_p->pos]);
save_p->pos += 8;
}
if (diff & SD_CEILPIC)
{
sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)save_p);
save_p += 8;
sectors[i].ceilingpic = P_AddLevelFlatRuntime((char *)&save_p->buf[save_p->pos]);
save_p->pos += 8;
}
if (diff & SD_LIGHT)
sectors[i].lightlevel = READINT16(save_p);
sectors[i].lightlevel = P_ReadINT16(save_p);
if (diff & SD_SPECIAL)
sectors[i].special = READINT16(save_p);
sectors[i].special = P_ReadINT16(save_p);
if (diff2 & SD_FXOFFS)
sectors[i].floorxoffset = READFIXED(save_p);
sectors[i].floorxoffset = P_ReadFixed(save_p);
if (diff2 & SD_FYOFFS)
sectors[i].flooryoffset = READFIXED(save_p);
sectors[i].flooryoffset = P_ReadFixed(save_p);
if (diff2 & SD_CXOFFS)
sectors[i].ceilingxoffset = READFIXED(save_p);
sectors[i].ceilingxoffset = P_ReadFixed(save_p);
if (diff2 & SD_CYOFFS)
sectors[i].ceilingyoffset = READFIXED(save_p);
sectors[i].ceilingyoffset = P_ReadFixed(save_p);
if (diff2 & SD_FLOORANG)
sectors[i].floorangle = READANGLE(save_p);
sectors[i].floorangle = P_ReadAngle(save_p);
if (diff2 & SD_CEILANG)
sectors[i].ceilingangle = READANGLE(save_p);
sectors[i].ceilingangle = P_ReadAngle(save_p);
if (diff2 & SD_TAG)
{
size_t ncount = READUINT32(save_p);
size_t ncount = P_ReadUINT32(save_p);
// Remove entries from global lists.
for (j = 0; j < sectors[i].tags.count; j++)
......@@ -1298,7 +1556,7 @@ static void UnArchiveSectors(void)
}
for (j = 0; j < ncount; j++)
sectors[i].tags.tags[j] = READINT16(save_p);
sectors[i].tags.tags[j] = P_ReadINT16(save_p);
// Add new entries.
for (j = 0; j < sectors[i].tags.count; j++)
......@@ -1307,49 +1565,49 @@ static void UnArchiveSectors(void)
if (diff3 & SD_COLORMAP)
sectors[i].extra_colormap = GetNetColormapFromList(READUINT32(save_p));
sectors[i].extra_colormap = GetNetColormapFromList(P_ReadUINT32(save_p));
if (diff3 & SD_CRUMBLESTATE)
sectors[i].crumblestate = READINT32(save_p);
sectors[i].crumblestate = P_ReadINT32(save_p);
if (diff3 & SD_FLOORLIGHT)
{
sectors[i].floorlightlevel = READINT16(save_p);
sectors[i].floorlightabsolute = READUINT8(save_p);
sectors[i].floorlightlevel = P_ReadINT16(save_p);
sectors[i].floorlightabsolute = P_ReadUINT8(save_p);
}
if (diff3 & SD_CEILLIGHT)
{
sectors[i].ceilinglightlevel = READINT16(save_p);
sectors[i].ceilinglightabsolute = READUINT8(save_p);
sectors[i].ceilinglightlevel = P_ReadINT16(save_p);
sectors[i].ceilinglightabsolute = P_ReadUINT8(save_p);
}
if (diff3 & SD_FLAG)
{
sectors[i].flags = READUINT32(save_p);
sectors[i].flags = P_ReadUINT32(save_p);
CheckForReverseGravity |= (sectors[i].flags & MSF_GRAVITYFLIP);
}
if (diff3 & SD_SPECIALFLAG)
sectors[i].specialflags = READUINT32(save_p);
sectors[i].specialflags = P_ReadUINT32(save_p);
if (diff4 & SD_DAMAGETYPE)
sectors[i].damagetype = READUINT8(save_p);
sectors[i].damagetype = P_ReadUINT8(save_p);
if (diff4 & SD_TRIGGERTAG)
sectors[i].triggertag = READINT16(save_p);
sectors[i].triggertag = P_ReadINT16(save_p);
if (diff4 & SD_TRIGGERER)
sectors[i].triggerer = READUINT8(save_p);
sectors[i].triggerer = P_ReadUINT8(save_p);
if (diff4 & SD_FXSCALE)
sectors[i].floorxscale = READFIXED(save_p);
sectors[i].floorxscale = P_ReadFixed(save_p);
if (diff4 & SD_FYSCALE)
sectors[i].flooryscale = READFIXED(save_p);
sectors[i].flooryscale = P_ReadFixed(save_p);
if (diff4 & SD_CXSCALE)
sectors[i].ceilingxscale = READFIXED(save_p);
sectors[i].ceilingxscale = P_ReadFixed(save_p);
if (diff4 & SD_CYSCALE)
sectors[i].ceilingyscale = READFIXED(save_p);
sectors[i].ceilingyscale = P_ReadFixed(save_p);
if (diff5 & SD_GRAVITY)
sectors[i].gravity = READFIXED(save_p);
sectors[i].gravity = P_ReadFixed(save_p);
if (diff5 & SD_FLOORPORTAL)
sectors[i].portal_floor = READUINT32(save_p);
sectors[i].portal_floor = P_ReadUINT32(save_p);
if (diff5 & SD_CEILPORTAL)
sectors[i].portal_ceiling = READUINT32(save_p);
sectors[i].portal_ceiling = P_ReadUINT32(save_p);
if (diff & SD_FFLOORS)
UnArchiveFFloors(&sectors[i]);
UnArchiveFFloors(save_p, &sectors[i]);
}
}
......@@ -1393,52 +1651,84 @@ static UINT32 GetSideDiff(const side_t *si, const side_t *spawnsi)
diff |= LD_SDBOTSCALEY;
if (si->repeatcnt != spawnsi->repeatcnt)
diff |= LD_SDREPEATCNT;
if (si->light != spawnsi->light)
diff |= LD_SDLIGHT;
if (si->light_top != spawnsi->light_top)
diff |= LD_SDTOPLIGHT;
if (si->light_mid != spawnsi->light_mid)
diff |= LD_SDMIDLIGHT;
if (si->light_bottom != spawnsi->light_bottom)
diff |= LD_SDBOTLIGHT;
if (si->lightabsolute != spawnsi->lightabsolute)
diff |= LD_SDLIGHTABS;
if (si->lightabsolute_top != spawnsi->lightabsolute_top)
diff |= LD_SDTOPLIGHTABS;
if (si->lightabsolute_mid != spawnsi->lightabsolute_mid)
diff |= LD_SDMIDLIGHTABS;
if (si->lightabsolute_bottom != spawnsi->lightabsolute_bottom)
diff |= LD_SDBOTLIGHTABS;
return diff;
}
static void ArchiveSide(const side_t *si, UINT32 diff)
static void ArchiveSide(save_t *save_p, const side_t *si, UINT32 diff)
{
WRITEUINT32(save_p, diff);
P_WriteUINT32(save_p, diff);
if (diff & LD_SDTEXOFFX)
WRITEFIXED(save_p, si->textureoffset);
P_WriteFixed(save_p, si->textureoffset);
if (diff & LD_SDTEXOFFY)
WRITEFIXED(save_p, si->rowoffset);
P_WriteFixed(save_p, si->rowoffset);
if (diff & LD_SDTOPTEX)
WRITEINT32(save_p, si->toptexture);
P_WriteINT32(save_p, si->toptexture);
if (diff & LD_SDBOTTEX)
WRITEINT32(save_p, si->bottomtexture);
P_WriteINT32(save_p, si->bottomtexture);
if (diff & LD_SDMIDTEX)
WRITEINT32(save_p, si->midtexture);
P_WriteINT32(save_p, si->midtexture);
if (diff & LD_SDTOPOFFX)
WRITEFIXED(save_p, si->offsetx_top);
P_WriteFixed(save_p, si->offsetx_top);
if (diff & LD_SDMIDOFFX)
WRITEFIXED(save_p, si->offsetx_mid);
P_WriteFixed(save_p, si->offsetx_mid);
if (diff & LD_SDBOTOFFX)
WRITEFIXED(save_p, si->offsetx_bottom);
P_WriteFixed(save_p, si->offsetx_bottom);
if (diff & LD_SDTOPOFFY)
WRITEFIXED(save_p, si->offsety_top);
P_WriteFixed(save_p, si->offsety_top);
if (diff & LD_SDMIDOFFY)
WRITEFIXED(save_p, si->offsety_mid);
P_WriteFixed(save_p, si->offsety_mid);
if (diff & LD_SDBOTOFFY)
WRITEFIXED(save_p, si->offsety_bottom);
P_WriteFixed(save_p, si->offsety_bottom);
if (diff & LD_SDTOPSCALEX)
WRITEFIXED(save_p, si->scalex_top);
P_WriteFixed(save_p, si->scalex_top);
if (diff & LD_SDMIDSCALEX)
WRITEFIXED(save_p, si->scalex_mid);
P_WriteFixed(save_p, si->scalex_mid);
if (diff & LD_SDBOTSCALEX)
WRITEFIXED(save_p, si->scalex_bottom);
P_WriteFixed(save_p, si->scalex_bottom);
if (diff & LD_SDTOPSCALEY)
WRITEFIXED(save_p, si->scaley_top);
P_WriteFixed(save_p, si->scaley_top);
if (diff & LD_SDMIDSCALEY)
WRITEFIXED(save_p, si->scaley_mid);
P_WriteFixed(save_p, si->scaley_mid);
if (diff & LD_SDBOTSCALEY)
WRITEFIXED(save_p, si->scaley_bottom);
P_WriteFixed(save_p, si->scaley_bottom);
if (diff & LD_SDREPEATCNT)
WRITEINT16(save_p, si->repeatcnt);
}
static void ArchiveLines(void)
P_WriteINT16(save_p, si->repeatcnt);
if (diff & LD_SDLIGHT)
P_WriteINT16(save_p, si->light);
if (diff & LD_SDTOPLIGHT)
P_WriteINT16(save_p, si->light_top);
if (diff & LD_SDMIDLIGHT)
P_WriteINT16(save_p, si->light_mid);
if (diff & LD_SDBOTLIGHT)
P_WriteINT16(save_p, si->light_bottom);
if (diff & LD_SDLIGHTABS)
P_WriteUINT8(save_p, si->lightabsolute);
if (diff & LD_SDTOPLIGHTABS)
P_WriteUINT8(save_p, si->lightabsolute_top);
if (diff & LD_SDMIDLIGHTABS)
P_WriteUINT8(save_p, si->lightabsolute_mid);
if (diff & LD_SDBOTLIGHTABS)
P_WriteUINT8(save_p, si->lightabsolute_bottom);
}
static void ArchiveLines(save_t *save_p)
{
size_t i;
const line_t *li = lines;
......@@ -1488,21 +1778,21 @@ static void ArchiveLines(void)
if (diff)
{
WRITEUINT32(save_p, i);
WRITEUINT8(save_p, diff);
P_WriteUINT32(save_p, i);
P_WriteUINT8(save_p, diff);
if (diff & LD_DIFF2)
WRITEUINT8(save_p, diff2);
P_WriteUINT8(save_p, diff2);
if (diff & LD_FLAG)
WRITEINT16(save_p, li->flags);
P_WriteINT16(save_p, li->flags);
if (diff & LD_SPECIAL)
WRITEINT16(save_p, li->special);
P_WriteINT16(save_p, li->special);
if (diff & LD_CLLCOUNT)
WRITEINT16(save_p, li->callcount);
P_WriteINT16(save_p, li->callcount);
if (diff & LD_ARGS)
{
UINT8 j;
for (j = 0; j < NUMLINEARGS; j++)
WRITEINT32(save_p, li->args[j]);
P_WriteINT32(save_p, li->args[j]);
}
if (diff & LD_STRINGARGS)
{
......@@ -1513,72 +1803,88 @@ static void ArchiveLines(void)
if (!li->stringargs[j])
{
WRITEINT32(save_p, 0);
P_WriteINT32(save_p, 0);
continue;
}
len = strlen(li->stringargs[j]);
WRITEINT32(save_p, len);
P_WriteINT32(save_p, len);
for (k = 0; k < len; k++)
WRITECHAR(save_p, li->stringargs[j][k]);
P_WriteChar(save_p, li->stringargs[j][k]);
}
}
if (diff & LD_SIDE1)
ArchiveSide(&sides[li->sidenum[0]], side1diff);
ArchiveSide(save_p, &sides[li->sidenum[0]], side1diff);
if (diff & LD_SIDE2)
ArchiveSide(&sides[li->sidenum[1]], side2diff);
ArchiveSide(save_p, &sides[li->sidenum[1]], side2diff);
if (diff2 & LD_EXECUTORDELAY)
WRITEINT32(save_p, li->executordelay);
P_WriteINT32(save_p, li->executordelay);
if (diff2 & LD_TRANSFPORTAL)
WRITEUINT32(save_p, li->secportal);
P_WriteUINT32(save_p, li->secportal);
}
}
WRITEUINT32(save_p, 0xffffffff);
P_WriteUINT32(save_p, 0xffffffff);
}
static void UnArchiveSide(side_t *si)
static void UnArchiveSide(save_t *save_p, side_t *si)
{
UINT32 diff = READUINT32(save_p);
UINT32 diff = P_ReadUINT32(save_p);
if (diff & LD_SDTEXOFFX)
si->textureoffset = READFIXED(save_p);
si->textureoffset = P_ReadFixed(save_p);
if (diff & LD_SDTEXOFFY)
si->rowoffset = READFIXED(save_p);
si->rowoffset = P_ReadFixed(save_p);
if (diff & LD_SDTOPTEX)
si->toptexture = READINT32(save_p);
si->toptexture = P_ReadINT32(save_p);
if (diff & LD_SDBOTTEX)
si->bottomtexture = READINT32(save_p);
si->bottomtexture = P_ReadINT32(save_p);
if (diff & LD_SDMIDTEX)
si->midtexture = READINT32(save_p);
si->midtexture = P_ReadINT32(save_p);
if (diff & LD_SDTOPOFFX)
si->offsetx_top = READFIXED(save_p);
si->offsetx_top = P_ReadFixed(save_p);
if (diff & LD_SDMIDOFFX)
si->offsetx_mid = READFIXED(save_p);
si->offsetx_mid = P_ReadFixed(save_p);
if (diff & LD_SDBOTOFFX)
si->offsetx_bottom = READFIXED(save_p);
si->offsetx_bottom = P_ReadFixed(save_p);
if (diff & LD_SDTOPOFFY)
si->offsety_top = READFIXED(save_p);
si->offsety_top = P_ReadFixed(save_p);
if (diff & LD_SDMIDOFFY)
si->offsety_mid = READFIXED(save_p);
si->offsety_mid = P_ReadFixed(save_p);
if (diff & LD_SDBOTOFFY)
si->offsety_bottom = READFIXED(save_p);
si->offsety_bottom = P_ReadFixed(save_p);
if (diff & LD_SDTOPSCALEX)
si->scalex_top = READFIXED(save_p);
si->scalex_top = P_ReadFixed(save_p);
if (diff & LD_SDMIDSCALEX)
si->scalex_mid = READFIXED(save_p);
si->scalex_mid = P_ReadFixed(save_p);
if (diff & LD_SDBOTSCALEX)
si->scalex_bottom = READFIXED(save_p);
si->scalex_bottom = P_ReadFixed(save_p);
if (diff & LD_SDTOPSCALEY)
si->scaley_top = READFIXED(save_p);
si->scaley_top = P_ReadFixed(save_p);
if (diff & LD_SDMIDSCALEY)
si->scaley_mid = READFIXED(save_p);
si->scaley_mid = P_ReadFixed(save_p);
if (diff & LD_SDBOTSCALEY)
si->scaley_bottom = READFIXED(save_p);
si->scaley_bottom = P_ReadFixed(save_p);
if (diff & LD_SDREPEATCNT)
si->repeatcnt = READINT16(save_p);
}
static void UnArchiveLines(void)
si->repeatcnt = P_ReadINT16(save_p);
if (diff & LD_SDLIGHT)
si->light = P_ReadINT16(save_p);
if (diff & LD_SDTOPLIGHT)
si->light_top = P_ReadINT16(save_p);
if (diff & LD_SDMIDLIGHT)
si->light_mid = P_ReadINT16(save_p);
if (diff & LD_SDBOTLIGHT)
si->light_bottom = P_ReadINT16(save_p);
if (diff & LD_SDLIGHTABS)
si->lightabsolute = P_ReadUINT8(save_p);
if (diff & LD_SDTOPLIGHTABS)
si->lightabsolute_top = P_ReadUINT8(save_p);
if (diff & LD_SDMIDLIGHTABS)
si->lightabsolute_mid = P_ReadUINT8(save_p);
if (diff & LD_SDBOTLIGHTABS)
si->lightabsolute_bottom = P_ReadUINT8(save_p);
}
static void UnArchiveLines(save_t *save_p)
{
UINT32 i;
line_t *li;
......@@ -1586,38 +1892,38 @@ static void UnArchiveLines(void)
for (;;)
{
i = READUINT32(save_p);
i = P_ReadUINT32(save_p);
if (i == 0xffffffff)
break;
if (i > numlines)
I_Error("Invalid line number %u from server", i);
diff = READUINT8(save_p);
diff = P_ReadUINT8(save_p);
if (diff & LD_DIFF2)
diff2 = READUINT8(save_p);
diff2 = P_ReadUINT8(save_p);
else
diff2 = 0;
li = &lines[i];
if (diff & LD_FLAG)
li->flags = READINT16(save_p);
li->flags = P_ReadINT16(save_p);
if (diff & LD_SPECIAL)
li->special = READINT16(save_p);
li->special = P_ReadINT16(save_p);
if (diff & LD_CLLCOUNT)
li->callcount = READINT16(save_p);
li->callcount = P_ReadINT16(save_p);
if (diff & LD_ARGS)
{
UINT8 j;
for (j = 0; j < NUMLINEARGS; j++)
li->args[j] = READINT32(save_p);
li->args[j] = P_ReadINT32(save_p);
}
if (diff & LD_STRINGARGS)
{
UINT8 j;
for (j = 0; j < NUMLINESTRINGARGS; j++)
{
size_t len = READINT32(save_p);
size_t len = P_ReadINT32(save_p);
size_t k;
if (!len)
......@@ -1629,38 +1935,38 @@ static void UnArchiveLines(void)
li->stringargs[j] = Z_Realloc(li->stringargs[j], len + 1, PU_LEVEL, NULL);
for (k = 0; k < len; k++)
li->stringargs[j][k] = READCHAR(save_p);
li->stringargs[j][k] = P_ReadChar(save_p);
li->stringargs[j][len] = '\0';
}
}
if (diff & LD_SIDE1)
UnArchiveSide(&sides[li->sidenum[0]]);
UnArchiveSide(save_p, &sides[li->sidenum[0]]);
if (diff & LD_SIDE2)
UnArchiveSide(&sides[li->sidenum[1]]);
UnArchiveSide(save_p, &sides[li->sidenum[1]]);
if (diff2 & LD_EXECUTORDELAY)
li->executordelay = READINT32(save_p);
li->executordelay = P_ReadINT32(save_p);
if (diff2 & LD_TRANSFPORTAL)
li->secportal = READUINT32(save_p);
li->secportal = P_ReadUINT32(save_p);
}
}
static void P_NetArchiveWorld(void)
static void P_NetArchiveWorld(save_t *save_p)
{
// initialize colormap vars because paranoia
ClearNetColormaps();
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
P_WriteUINT32(save_p, ARCHIVEBLOCK_WORLD);
ArchiveSectors();
ArchiveLines();
ArchiveSectors(save_p);
ArchiveLines(save_p);
R_ClearTextureNumCache(false);
}
static void P_NetUnArchiveWorld(void)
static void P_NetUnArchiveWorld(save_t *save_p)
{
UINT16 i;
if (READUINT32(save_p) != ARCHIVEBLOCK_WORLD)
if (P_ReadUINT32(save_p) != ARCHIVEBLOCK_WORLD)
I_Error("Bad $$$.sav at archive block World");
// initialize colormap vars because paranoia
......@@ -1674,8 +1980,8 @@ static void P_NetUnArchiveWorld(void)
num_ffloors++;
}
UnArchiveSectors();
UnArchiveLines();
UnArchiveSectors(save_p);
UnArchiveLines(save_p);
}
//
......@@ -1746,7 +2052,8 @@ typedef enum
MD2_DISPOFFSET = 1<<23,
MD2_DRAWONLYFORPLAYER = 1<<24,
MD2_DONTDRAWFORVIEWMOBJ = 1<<25,
MD2_TRANSLATION = 1<<26
MD2_TRANSLATION = 1<<26,
MD2_ALPHA = 1<<27
} mobj_diff2_t;
typedef enum
......@@ -1813,19 +2120,13 @@ static UINT32 SaveLine(const line_t *line)
return 0xFFFFFFFF;
}
static inline UINT32 SavePlayer(const player_t *player)
{
if (player) return (UINT32)(player - players);
return 0xFFFFFFFF;
}
static UINT32 SaveSlope(const pslope_t *slope)
{
if (slope) return (UINT32)(slope->id);
return 0xFFFFFFFF;
}
static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
static void SaveMobjThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const mobj_t *mobj = (const mobj_t *)th;
UINT32 diff;
......@@ -1989,6 +2290,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_DONTDRAWFORVIEWMOBJ;
if (mobj->dispoffset != mobj->info->dispoffset)
diff2 |= MD2_DISPOFFSET;
if (mobj->alpha != FRACUNIT)
diff2 |= MD2_ALPHA;
if (diff2 != 0)
diff |= MD_MORE;
......@@ -1997,28 +2300,28 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
if (mobj->type == MT_HOOPCENTER)
diff = MD_SPAWNPOINT;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, diff);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, diff);
if (diff & MD_MORE)
WRITEUINT32(save_p, diff2);
P_WriteUINT32(save_p, diff2);
// save pointer, at load time we will search this pointer to reinitilize pointers
WRITEUINT32(save_p, (size_t)mobj);
P_WriteUINT32(save_p, (size_t)mobj);
WRITEFIXED(save_p, mobj->z); // Force this so 3dfloor problems don't arise.
WRITEFIXED(save_p, mobj->floorz);
WRITEFIXED(save_p, mobj->ceilingz);
P_WriteFixed(save_p, mobj->z); // Force this so 3dfloor problems don't arise.
P_WriteFixed(save_p, mobj->floorz);
P_WriteFixed(save_p, mobj->ceilingz);
if (diff2 & MD2_FLOORROVER)
{
WRITEUINT32(save_p, SaveSector(mobj->floorrover->target));
WRITEUINT16(save_p, P_GetFFloorID(mobj->floorrover));
P_WriteUINT32(save_p, SaveSector(mobj->floorrover->target));
P_WriteUINT16(save_p, P_GetFFloorID(mobj->floorrover));
}
if (diff2 & MD2_CEILINGROVER)
{
WRITEUINT32(save_p, SaveSector(mobj->ceilingrover->target));
WRITEUINT16(save_p, P_GetFFloorID(mobj->ceilingrover));
P_WriteUINT32(save_p, SaveSector(mobj->ceilingrover->target));
P_WriteUINT16(save_p, P_GetFFloorID(mobj->ceilingrover));
}
if (diff & MD_SPAWNPOINT)
......@@ -2027,647 +2330,649 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
for (z = 0; z < nummapthings; z++)
if (&mapthings[z] == mobj->spawnpoint)
WRITEUINT16(save_p, z);
P_WriteUINT16(save_p, z);
if (mobj->type == MT_HOOPCENTER)
return;
}
if (diff & MD_TYPE)
WRITEUINT32(save_p, mobj->type);
P_WriteUINT32(save_p, mobj->type);
if (diff & MD_POS)
{
WRITEFIXED(save_p, mobj->x);
WRITEFIXED(save_p, mobj->y);
WRITEANGLE(save_p, mobj->angle);
WRITEANGLE(save_p, mobj->pitch);
WRITEANGLE(save_p, mobj->roll);
P_WriteFixed(save_p, mobj->x);
P_WriteFixed(save_p, mobj->y);
P_WriteAngle(save_p, mobj->angle);
P_WriteAngle(save_p, mobj->pitch);
P_WriteAngle(save_p, mobj->roll);
}
if (diff & MD_MOM)
{
WRITEFIXED(save_p, mobj->momx);
WRITEFIXED(save_p, mobj->momy);
WRITEFIXED(save_p, mobj->momz);
WRITEFIXED(save_p, mobj->pmomz);
P_WriteFixed(save_p, mobj->momx);
P_WriteFixed(save_p, mobj->momy);
P_WriteFixed(save_p, mobj->momz);
P_WriteFixed(save_p, mobj->pmomz);
}
if (diff & MD_RADIUS)
WRITEFIXED(save_p, mobj->radius);
P_WriteFixed(save_p, mobj->radius);
if (diff & MD_HEIGHT)
WRITEFIXED(save_p, mobj->height);
P_WriteFixed(save_p, mobj->height);
if (diff & MD_FLAGS)
WRITEUINT32(save_p, mobj->flags);
P_WriteUINT32(save_p, mobj->flags);
if (diff & MD_FLAGS2)
WRITEUINT32(save_p, mobj->flags2);
P_WriteUINT32(save_p, mobj->flags2);
if (diff & MD_HEALTH)
WRITEINT32(save_p, mobj->health);
P_WriteINT32(save_p, mobj->health);
if (diff & MD_RTIME)
WRITEINT32(save_p, mobj->reactiontime);
P_WriteINT32(save_p, mobj->reactiontime);
if (diff & MD_STATE)
WRITEUINT16(save_p, mobj->state-states);
P_WriteUINT16(save_p, mobj->state-states);
if (diff & MD_TICS)
WRITEINT32(save_p, mobj->tics);
P_WriteINT32(save_p, mobj->tics);
if (diff & MD_SPRITE) {
WRITEUINT16(save_p, mobj->sprite);
P_WriteUINT16(save_p, mobj->sprite);
if (mobj->sprite == SPR_PLAY)
WRITEUINT16(save_p, mobj->sprite2);
P_WriteUINT16(save_p, mobj->sprite2);
}
if (diff & MD_FRAME)
{
WRITEUINT32(save_p, mobj->frame);
WRITEUINT16(save_p, mobj->anim_duration);
P_WriteUINT32(save_p, mobj->frame);
P_WriteUINT16(save_p, mobj->anim_duration);
}
if (diff & MD_EFLAGS)
WRITEUINT16(save_p, mobj->eflags);
P_WriteUINT16(save_p, mobj->eflags);
if (diff & MD_PLAYER)
WRITEUINT8(save_p, mobj->player-players);
P_WriteUINT8(save_p, mobj->player-players);
if (diff & MD_MOVEDIR)
WRITEANGLE(save_p, mobj->movedir);
P_WriteAngle(save_p, mobj->movedir);
if (diff & MD_MOVECOUNT)
WRITEINT32(save_p, mobj->movecount);
P_WriteINT32(save_p, mobj->movecount);
if (diff & MD_THRESHOLD)
WRITEINT32(save_p, mobj->threshold);
P_WriteINT32(save_p, mobj->threshold);
if (diff & MD_LASTLOOK)
WRITEINT32(save_p, mobj->lastlook);
P_WriteINT32(save_p, mobj->lastlook);
if (diff & MD_TARGET)
WRITEUINT32(save_p, mobj->target->mobjnum);
P_WriteUINT32(save_p, mobj->target->mobjnum);
if (diff & MD_TRACER)
WRITEUINT32(save_p, mobj->tracer->mobjnum);
P_WriteUINT32(save_p, mobj->tracer->mobjnum);
if (diff & MD_FRICTION)
WRITEFIXED(save_p, mobj->friction);
P_WriteFixed(save_p, mobj->friction);
if (diff & MD_MOVEFACTOR)
WRITEFIXED(save_p, mobj->movefactor);
P_WriteFixed(save_p, mobj->movefactor);
if (diff & MD_FUSE)
WRITEINT32(save_p, mobj->fuse);
P_WriteINT32(save_p, mobj->fuse);
if (diff & MD_WATERTOP)
WRITEFIXED(save_p, mobj->watertop);
P_WriteFixed(save_p, mobj->watertop);
if (diff & MD_WATERBOTTOM)
WRITEFIXED(save_p, mobj->waterbottom);
P_WriteFixed(save_p, mobj->waterbottom);
if (diff & MD_SCALE)
WRITEFIXED(save_p, mobj->scale);
P_WriteFixed(save_p, mobj->scale);
if (diff & MD_DSCALE)
WRITEFIXED(save_p, mobj->destscale);
P_WriteFixed(save_p, mobj->destscale);
if (diff2 & MD2_SCALESPEED)
WRITEFIXED(save_p, mobj->scalespeed);
P_WriteFixed(save_p, mobj->scalespeed);
if (diff2 & MD2_CUSVAL)
WRITEINT32(save_p, mobj->cusval);
P_WriteINT32(save_p, mobj->cusval);
if (diff2 & MD2_CVMEM)
WRITEINT32(save_p, mobj->cvmem);
P_WriteINT32(save_p, mobj->cvmem);
if (diff2 & MD2_SKIN)
WRITEUINT8(save_p, (UINT8)(((skin_t *)mobj->skin)->skinnum));
P_WriteUINT8(save_p, (UINT8)(((skin_t *)mobj->skin)->skinnum));
if (diff2 & MD2_COLOR)
WRITEUINT16(save_p, mobj->color);
P_WriteUINT16(save_p, mobj->color);
if (diff2 & MD2_EXTVAL1)
WRITEINT32(save_p, mobj->extravalue1);
P_WriteINT32(save_p, mobj->extravalue1);
if (diff2 & MD2_EXTVAL2)
WRITEINT32(save_p, mobj->extravalue2);
P_WriteINT32(save_p, mobj->extravalue2);
if (diff2 & MD2_HNEXT)
WRITEUINT32(save_p, mobj->hnext->mobjnum);
P_WriteUINT32(save_p, mobj->hnext->mobjnum);
if (diff2 & MD2_HPREV)
WRITEUINT32(save_p, mobj->hprev->mobjnum);
P_WriteUINT32(save_p, mobj->hprev->mobjnum);
if (diff2 & MD2_SLOPE)
WRITEUINT16(save_p, mobj->standingslope->id);
P_WriteUINT16(save_p, mobj->standingslope->id);
if (diff2 & MD2_COLORIZED)
WRITEUINT8(save_p, mobj->colorized);
P_WriteUINT8(save_p, mobj->colorized);
if (diff2 & MD2_MIRRORED)
WRITEUINT8(save_p, mobj->mirrored);
P_WriteUINT8(save_p, mobj->mirrored);
if (diff2 & MD2_SPRITEROLL)
WRITEANGLE(save_p, mobj->spriteroll);
P_WriteAngle(save_p, mobj->spriteroll);
if (diff2 & MD2_SHADOWSCALE)
WRITEFIXED(save_p, mobj->shadowscale);
P_WriteFixed(save_p, mobj->shadowscale);
if (diff2 & MD2_RENDERFLAGS)
WRITEUINT32(save_p, mobj->renderflags);
P_WriteUINT32(save_p, mobj->renderflags);
if (diff2 & MD2_BLENDMODE)
WRITEINT32(save_p, mobj->blendmode);
P_WriteINT32(save_p, mobj->blendmode);
if (diff2 & MD2_SPRITEXSCALE)
WRITEFIXED(save_p, mobj->spritexscale);
P_WriteFixed(save_p, mobj->spritexscale);
if (diff2 & MD2_SPRITEYSCALE)
WRITEFIXED(save_p, mobj->spriteyscale);
P_WriteFixed(save_p, mobj->spriteyscale);
if (diff2 & MD2_SPRITEXOFFSET)
WRITEFIXED(save_p, mobj->spritexoffset);
P_WriteFixed(save_p, mobj->spritexoffset);
if (diff2 & MD2_SPRITEYOFFSET)
WRITEFIXED(save_p, mobj->spriteyoffset);
P_WriteFixed(save_p, mobj->spriteyoffset);
if (diff2 & MD2_FLOORSPRITESLOPE)
{
pslope_t *slope = mobj->floorspriteslope;
WRITEFIXED(save_p, slope->zdelta);
WRITEANGLE(save_p, slope->zangle);
WRITEANGLE(save_p, slope->xydirection);
P_WriteFixed(save_p, slope->zdelta);
P_WriteAngle(save_p, slope->zangle);
P_WriteAngle(save_p, slope->xydirection);
WRITEFIXED(save_p, slope->o.x);
WRITEFIXED(save_p, slope->o.y);
WRITEFIXED(save_p, slope->o.z);
P_WriteFixed(save_p, slope->o.x);
P_WriteFixed(save_p, slope->o.y);
P_WriteFixed(save_p, slope->o.z);
WRITEFIXED(save_p, slope->d.x);
WRITEFIXED(save_p, slope->d.y);
P_WriteFixed(save_p, slope->d.x);
P_WriteFixed(save_p, slope->d.y);
WRITEFIXED(save_p, slope->normal.x);
WRITEFIXED(save_p, slope->normal.y);
WRITEFIXED(save_p, slope->normal.z);
P_WriteFixed(save_p, slope->normal.x);
P_WriteFixed(save_p, slope->normal.y);
P_WriteFixed(save_p, slope->normal.z);
}
if (diff2 & MD2_DRAWONLYFORPLAYER)
WRITEUINT8(save_p, mobj->drawonlyforplayer-players);
P_WriteUINT8(save_p, mobj->drawonlyforplayer-players);
if (diff2 & MD2_DONTDRAWFORVIEWMOBJ)
WRITEUINT32(save_p, mobj->dontdrawforviewmobj->mobjnum);
P_WriteUINT32(save_p, mobj->dontdrawforviewmobj->mobjnum);
if (diff2 & MD2_DISPOFFSET)
WRITEINT32(save_p, mobj->dispoffset);
P_WriteINT32(save_p, mobj->dispoffset);
if (diff2 & MD2_TRANSLATION)
WRITEUINT16(save_p, mobj->translation);
P_WriteUINT16(save_p, mobj->translation);
if (diff2 & MD2_ALPHA)
P_WriteFixed(save_p, mobj->alpha);
WRITEUINT32(save_p, mobj->mobjnum);
P_WriteUINT32(save_p, mobj->mobjnum);
}
static void SaveNoEnemiesThinker(const thinker_t *th, const UINT8 type)
static void SaveNoEnemiesThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const noenemies_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
}
static void SaveBounceCheeseThinker(const thinker_t *th, const UINT8 type)
static void SaveBounceCheeseThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const bouncecheese_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->speed);
WRITEFIXED(save_p, ht->distance);
WRITEFIXED(save_p, ht->floorwasheight);
WRITEFIXED(save_p, ht->ceilingwasheight);
WRITECHAR(save_p, ht->low);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteFixed(save_p, ht->speed);
P_WriteFixed(save_p, ht->distance);
P_WriteFixed(save_p, ht->floorwasheight);
P_WriteFixed(save_p, ht->ceilingwasheight);
P_WriteChar(save_p, ht->low);
}
static void SaveContinuousFallThinker(const thinker_t *th, const UINT8 type)
static void SaveContinuousFallThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const continuousfall_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->speed);
WRITEINT32(save_p, ht->direction);
WRITEFIXED(save_p, ht->floorstartheight);
WRITEFIXED(save_p, ht->ceilingstartheight);
WRITEFIXED(save_p, ht->destheight);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteFixed(save_p, ht->speed);
P_WriteINT32(save_p, ht->direction);
P_WriteFixed(save_p, ht->floorstartheight);
P_WriteFixed(save_p, ht->ceilingstartheight);
P_WriteFixed(save_p, ht->destheight);
}
static void SaveMarioBlockThinker(const thinker_t *th, const UINT8 type)
static void SaveMarioBlockThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const mariothink_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->speed);
WRITEINT32(save_p, ht->direction);
WRITEFIXED(save_p, ht->floorstartheight);
WRITEFIXED(save_p, ht->ceilingstartheight);
WRITEINT16(save_p, ht->tag);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteFixed(save_p, ht->speed);
P_WriteINT32(save_p, ht->direction);
P_WriteFixed(save_p, ht->floorstartheight);
P_WriteFixed(save_p, ht->ceilingstartheight);
P_WriteINT16(save_p, ht->tag);
}
static void SaveMarioCheckThinker(const thinker_t *th, const UINT8 type)
static void SaveMarioCheckThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const mariocheck_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT32(save_p, SaveSector(ht->sector));
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
P_WriteUINT32(save_p, SaveSector(ht->sector));
}
static void SaveThwompThinker(const thinker_t *th, const UINT8 type)
static void SaveThwompThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const thwomp_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->crushspeed);
WRITEFIXED(save_p, ht->retractspeed);
WRITEINT32(save_p, ht->direction);
WRITEFIXED(save_p, ht->floorstartheight);
WRITEFIXED(save_p, ht->ceilingstartheight);
WRITEINT32(save_p, ht->delay);
WRITEINT16(save_p, ht->tag);
WRITEUINT16(save_p, ht->sound);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteFixed(save_p, ht->crushspeed);
P_WriteFixed(save_p, ht->retractspeed);
P_WriteINT32(save_p, ht->direction);
P_WriteFixed(save_p, ht->floorstartheight);
P_WriteFixed(save_p, ht->ceilingstartheight);
P_WriteINT32(save_p, ht->delay);
P_WriteINT16(save_p, ht->tag);
P_WriteUINT16(save_p, ht->sound);
}
static void SaveFloatThinker(const thinker_t *th, const UINT8 type)
static void SaveFloatThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const floatthink_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT16(save_p, ht->tag);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteINT16(save_p, ht->tag);
}
static void SaveEachTimeThinker(const thinker_t *th, const UINT8 type)
static void SaveEachTimeThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const eachtime_t *ht = (const void *)th;
size_t i;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
for (i = 0; i < MAXPLAYERS; i++)
{
WRITECHAR(save_p, ht->playersInArea[i]);
P_WriteChar(save_p, ht->playersInArea[i]);
}
WRITECHAR(save_p, ht->triggerOnExit);
P_WriteChar(save_p, ht->triggerOnExit);
}
static void SaveRaiseThinker(const thinker_t *th, const UINT8 type)
static void SaveRaiseThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const raise_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT16(save_p, ht->tag);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->ceilingbottom);
WRITEFIXED(save_p, ht->ceilingtop);
WRITEFIXED(save_p, ht->basespeed);
WRITEFIXED(save_p, ht->extraspeed);
WRITEUINT8(save_p, ht->shaketimer);
WRITEUINT8(save_p, ht->flags);
P_WriteUINT8(save_p, type);
P_WriteINT16(save_p, ht->tag);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteFixed(save_p, ht->ceilingbottom);
P_WriteFixed(save_p, ht->ceilingtop);
P_WriteFixed(save_p, ht->basespeed);
P_WriteFixed(save_p, ht->extraspeed);
P_WriteUINT8(save_p, ht->shaketimer);
P_WriteUINT8(save_p, ht->flags);
}
static void SaveCeilingThinker(const thinker_t *th, const UINT8 type)
static void SaveCeilingThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const ceiling_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT8(save_p, ht->type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEFIXED(save_p, ht->bottomheight);
WRITEFIXED(save_p, ht->topheight);
WRITEFIXED(save_p, ht->speed);
WRITEFIXED(save_p, ht->delay);
WRITEFIXED(save_p, ht->delaytimer);
WRITEUINT8(save_p, ht->crush);
WRITEINT32(save_p, ht->texture);
WRITEINT32(save_p, ht->direction);
WRITEINT16(save_p, ht->tag);
WRITEFIXED(save_p, ht->origspeed);
WRITEFIXED(save_p, ht->sourceline);
}
static void SaveFloormoveThinker(const thinker_t *th, const UINT8 type)
P_WriteUINT8(save_p, type);
P_WriteUINT8(save_p, ht->type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteFixed(save_p, ht->bottomheight);
P_WriteFixed(save_p, ht->topheight);
P_WriteFixed(save_p, ht->speed);
P_WriteFixed(save_p, ht->delay);
P_WriteFixed(save_p, ht->delaytimer);
P_WriteUINT8(save_p, ht->crush);
P_WriteINT32(save_p, ht->texture);
P_WriteINT32(save_p, ht->direction);
P_WriteINT16(save_p, ht->tag);
P_WriteFixed(save_p, ht->origspeed);
P_WriteFixed(save_p, ht->sourceline);
}
static void SaveFloormoveThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const floormove_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT8(save_p, ht->type);
WRITEUINT8(save_p, ht->crush);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT32(save_p, ht->direction);
WRITEINT32(save_p, ht->texture);
WRITEFIXED(save_p, ht->floordestheight);
WRITEFIXED(save_p, ht->speed);
WRITEFIXED(save_p, ht->origspeed);
WRITEFIXED(save_p, ht->delay);
WRITEFIXED(save_p, ht->delaytimer);
WRITEINT16(save_p, ht->tag);
WRITEFIXED(save_p, ht->sourceline);
}
static void SaveLightflashThinker(const thinker_t *th, const UINT8 type)
P_WriteUINT8(save_p, type);
P_WriteUINT8(save_p, ht->type);
P_WriteUINT8(save_p, ht->crush);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteINT32(save_p, ht->direction);
P_WriteINT32(save_p, ht->texture);
P_WriteFixed(save_p, ht->floordestheight);
P_WriteFixed(save_p, ht->speed);
P_WriteFixed(save_p, ht->origspeed);
P_WriteFixed(save_p, ht->delay);
P_WriteFixed(save_p, ht->delaytimer);
P_WriteINT16(save_p, ht->tag);
P_WriteFixed(save_p, ht->sourceline);
}
static void SaveLightflashThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const lightflash_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT32(save_p, ht->maxlight);
WRITEINT32(save_p, ht->minlight);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteINT32(save_p, ht->maxlight);
P_WriteINT32(save_p, ht->minlight);
}
static void SaveStrobeThinker(const thinker_t *th, const UINT8 type)
static void SaveStrobeThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const strobe_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT32(save_p, ht->count);
WRITEINT16(save_p, ht->minlight);
WRITEINT16(save_p, ht->maxlight);
WRITEINT32(save_p, ht->darktime);
WRITEINT32(save_p, ht->brighttime);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteINT32(save_p, ht->count);
P_WriteINT16(save_p, ht->minlight);
P_WriteINT16(save_p, ht->maxlight);
P_WriteINT32(save_p, ht->darktime);
P_WriteINT32(save_p, ht->brighttime);
}
static void SaveGlowThinker(const thinker_t *th, const UINT8 type)
static void SaveGlowThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const glow_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT16(save_p, ht->minlight);
WRITEINT16(save_p, ht->maxlight);
WRITEINT16(save_p, ht->direction);
WRITEINT16(save_p, ht->speed);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteINT16(save_p, ht->minlight);
P_WriteINT16(save_p, ht->maxlight);
P_WriteINT16(save_p, ht->direction);
P_WriteINT16(save_p, ht->speed);
}
static inline void SaveFireflickerThinker(const thinker_t *th, const UINT8 type)
static inline void SaveFireflickerThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const fireflicker_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT32(save_p, ht->count);
WRITEINT32(save_p, ht->resetcount);
WRITEINT16(save_p, ht->maxlight);
WRITEINT16(save_p, ht->minlight);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteINT32(save_p, ht->count);
P_WriteINT32(save_p, ht->resetcount);
P_WriteINT16(save_p, ht->maxlight);
P_WriteINT16(save_p, ht->minlight);
}
static void SaveElevatorThinker(const thinker_t *th, const UINT8 type)
static void SaveElevatorThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const elevator_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT8(save_p, ht->type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEUINT32(save_p, SaveSector(ht->actionsector));
WRITEINT32(save_p, ht->direction);
WRITEFIXED(save_p, ht->floordestheight);
WRITEFIXED(save_p, ht->ceilingdestheight);
WRITEFIXED(save_p, ht->speed);
WRITEFIXED(save_p, ht->origspeed);
WRITEFIXED(save_p, ht->low);
WRITEFIXED(save_p, ht->high);
WRITEFIXED(save_p, ht->distance);
WRITEFIXED(save_p, ht->delay);
WRITEFIXED(save_p, ht->delaytimer);
WRITEFIXED(save_p, ht->floorwasheight);
WRITEFIXED(save_p, ht->ceilingwasheight);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
}
static void SaveCrumbleThinker(const thinker_t *th, const UINT8 type)
P_WriteUINT8(save_p, type);
P_WriteUINT8(save_p, ht->type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteUINT32(save_p, SaveSector(ht->actionsector));
P_WriteINT32(save_p, ht->direction);
P_WriteFixed(save_p, ht->floordestheight);
P_WriteFixed(save_p, ht->ceilingdestheight);
P_WriteFixed(save_p, ht->speed);
P_WriteFixed(save_p, ht->origspeed);
P_WriteFixed(save_p, ht->low);
P_WriteFixed(save_p, ht->high);
P_WriteFixed(save_p, ht->distance);
P_WriteFixed(save_p, ht->delay);
P_WriteFixed(save_p, ht->delaytimer);
P_WriteFixed(save_p, ht->floorwasheight);
P_WriteFixed(save_p, ht->ceilingwasheight);
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
}
static void SaveCrumbleThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const crumble_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEUINT32(save_p, SaveSector(ht->actionsector));
WRITEUINT32(save_p, SavePlayer(ht->player)); // was dummy
WRITEINT32(save_p, ht->direction);
WRITEINT32(save_p, ht->origalpha);
WRITEINT32(save_p, ht->timer);
WRITEFIXED(save_p, ht->speed);
WRITEFIXED(save_p, ht->floorwasheight);
WRITEFIXED(save_p, ht->ceilingwasheight);
WRITEUINT8(save_p, ht->flags);
}
static inline void SaveScrollThinker(const thinker_t *th, const UINT8 type)
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteUINT32(save_p, SaveSector(ht->actionsector));
P_WriteUINT32(save_p, SavePlayer(ht->player)); // was dummy
P_WriteINT32(save_p, ht->direction);
P_WriteINT32(save_p, ht->origalpha);
P_WriteINT32(save_p, ht->timer);
P_WriteFixed(save_p, ht->speed);
P_WriteFixed(save_p, ht->floorwasheight);
P_WriteFixed(save_p, ht->ceilingwasheight);
P_WriteUINT8(save_p, ht->flags);
}
static inline void SaveScrollThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const scroll_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEFIXED(save_p, ht->dx);
WRITEFIXED(save_p, ht->dy);
WRITEINT32(save_p, ht->affectee);
WRITEINT32(save_p, ht->control);
WRITEFIXED(save_p, ht->last_height);
WRITEFIXED(save_p, ht->vdx);
WRITEFIXED(save_p, ht->vdy);
WRITEINT32(save_p, ht->accel);
WRITEINT32(save_p, ht->exclusive);
WRITEUINT8(save_p, ht->type);
P_WriteUINT8(save_p, type);
P_WriteFixed(save_p, ht->dx);
P_WriteFixed(save_p, ht->dy);
P_WriteINT32(save_p, ht->affectee);
P_WriteINT32(save_p, ht->control);
P_WriteFixed(save_p, ht->last_height);
P_WriteFixed(save_p, ht->vdx);
P_WriteFixed(save_p, ht->vdy);
P_WriteINT32(save_p, ht->accel);
P_WriteINT32(save_p, ht->exclusive);
P_WriteUINT8(save_p, ht->type);
}
static inline void SaveFrictionThinker(const thinker_t *th, const UINT8 type)
static inline void SaveFrictionThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const friction_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->friction);
WRITEINT32(save_p, ht->movefactor);
WRITEINT32(save_p, ht->affectee);
WRITEINT32(save_p, ht->referrer);
WRITEUINT8(save_p, ht->roverfriction);
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->friction);
P_WriteINT32(save_p, ht->movefactor);
P_WriteINT32(save_p, ht->affectee);
P_WriteINT32(save_p, ht->referrer);
P_WriteUINT8(save_p, ht->roverfriction);
}
static inline void SavePusherThinker(const thinker_t *th, const UINT8 type)
static inline void SavePusherThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const pusher_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT8(save_p, ht->type);
WRITEFIXED(save_p, ht->x_mag);
WRITEFIXED(save_p, ht->y_mag);
WRITEFIXED(save_p, ht->z_mag);
WRITEINT32(save_p, ht->affectee);
WRITEUINT8(save_p, ht->roverpusher);
WRITEINT32(save_p, ht->referrer);
WRITEINT32(save_p, ht->exclusive);
WRITEINT32(save_p, ht->slider);
P_WriteUINT8(save_p, type);
P_WriteUINT8(save_p, ht->type);
P_WriteFixed(save_p, ht->x_mag);
P_WriteFixed(save_p, ht->y_mag);
P_WriteFixed(save_p, ht->z_mag);
P_WriteINT32(save_p, ht->affectee);
P_WriteUINT8(save_p, ht->roverpusher);
P_WriteINT32(save_p, ht->referrer);
P_WriteINT32(save_p, ht->exclusive);
P_WriteINT32(save_p, ht->slider);
}
static void SaveLaserThinker(const thinker_t *th, const UINT8 type)
static void SaveLaserThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const laserthink_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT16(save_p, ht->tag);
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT8(save_p, ht->nobosses);
P_WriteUINT8(save_p, type);
P_WriteINT16(save_p, ht->tag);
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
P_WriteUINT8(save_p, ht->nobosses);
}
static void SaveLightlevelThinker(const thinker_t *th, const UINT8 type)
static void SaveLightlevelThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const lightlevel_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT16(save_p, ht->sourcelevel);
WRITEINT16(save_p, ht->destlevel);
WRITEFIXED(save_p, ht->fixedcurlevel);
WRITEFIXED(save_p, ht->fixedpertic);
WRITEINT32(save_p, ht->timer);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteINT16(save_p, ht->sourcelevel);
P_WriteINT16(save_p, ht->destlevel);
P_WriteFixed(save_p, ht->fixedcurlevel);
P_WriteFixed(save_p, ht->fixedpertic);
P_WriteINT32(save_p, ht->timer);
}
static void SaveExecutorThinker(const thinker_t *th, const UINT8 type)
static void SaveExecutorThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const executor_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveLine(ht->line));
WRITEUINT32(save_p, SaveMobjnum(ht->caller));
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEINT32(save_p, ht->timer);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveLine(ht->line));
P_WriteUINT32(save_p, SaveMobjnum(ht->caller));
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteINT32(save_p, ht->timer);
}
static void SaveDisappearThinker(const thinker_t *th, const UINT8 type)
static void SaveDisappearThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const disappear_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, ht->appeartime);
WRITEUINT32(save_p, ht->disappeartime);
WRITEUINT32(save_p, ht->offset);
WRITEUINT32(save_p, ht->timer);
WRITEINT32(save_p, ht->affectee);
WRITEINT32(save_p, ht->sourceline);
WRITEINT32(save_p, ht->exists);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, ht->appeartime);
P_WriteUINT32(save_p, ht->disappeartime);
P_WriteUINT32(save_p, ht->offset);
P_WriteUINT32(save_p, ht->timer);
P_WriteINT32(save_p, ht->affectee);
P_WriteINT32(save_p, ht->sourceline);
P_WriteINT32(save_p, ht->exists);
}
static void SaveFadeThinker(const thinker_t *th, const UINT8 type)
static void SaveFadeThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const fade_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc));
WRITEUINT32(save_p, ht->sectornum);
WRITEUINT32(save_p, ht->ffloornum);
WRITEINT32(save_p, ht->alpha);
WRITEINT16(save_p, ht->sourcevalue);
WRITEINT16(save_p, ht->destvalue);
WRITEINT16(save_p, ht->destlightlevel);
WRITEINT16(save_p, ht->speed);
WRITEUINT8(save_p, (UINT8)ht->ticbased);
WRITEINT32(save_p, ht->timer);
WRITEUINT8(save_p, ht->doexists);
WRITEUINT8(save_p, ht->dotranslucent);
WRITEUINT8(save_p, ht->dolighting);
WRITEUINT8(save_p, ht->docolormap);
WRITEUINT8(save_p, ht->docollision);
WRITEUINT8(save_p, ht->doghostfade);
WRITEUINT8(save_p, ht->exactalpha);
}
static void SaveFadeColormapThinker(const thinker_t *th, const UINT8 type)
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc));
P_WriteUINT32(save_p, ht->sectornum);
P_WriteUINT32(save_p, ht->ffloornum);
P_WriteINT32(save_p, ht->alpha);
P_WriteINT16(save_p, ht->sourcevalue);
P_WriteINT16(save_p, ht->destvalue);
P_WriteINT16(save_p, ht->destlightlevel);
P_WriteINT16(save_p, ht->speed);
P_WriteUINT8(save_p, (UINT8)ht->ticbased);
P_WriteINT32(save_p, ht->timer);
P_WriteUINT8(save_p, ht->doexists);
P_WriteUINT8(save_p, ht->dotranslucent);
P_WriteUINT8(save_p, ht->dolighting);
P_WriteUINT8(save_p, ht->docolormap);
P_WriteUINT8(save_p, ht->docollision);
P_WriteUINT8(save_p, ht->doghostfade);
P_WriteUINT8(save_p, ht->exactalpha);
}
static void SaveFadeColormapThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const fadecolormap_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSector(ht->sector));
WRITEUINT32(save_p, CheckAddNetColormapToList(ht->source_exc));
WRITEUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc));
WRITEUINT8(save_p, (UINT8)ht->ticbased);
WRITEINT32(save_p, ht->duration);
WRITEINT32(save_p, ht->timer);
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveSector(ht->sector));
P_WriteUINT32(save_p, CheckAddNetColormapToList(ht->source_exc));
P_WriteUINT32(save_p, CheckAddNetColormapToList(ht->dest_exc));
P_WriteUINT8(save_p, (UINT8)ht->ticbased);
P_WriteINT32(save_p, ht->duration);
P_WriteINT32(save_p, ht->timer);
}
static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type)
static void SavePlaneDisplaceThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const planedisplace_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->affectee);
WRITEINT32(save_p, ht->control);
WRITEFIXED(save_p, ht->last_height);
WRITEFIXED(save_p, ht->speed);
WRITEUINT8(save_p, ht->type);
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->affectee);
P_WriteINT32(save_p, ht->control);
P_WriteFixed(save_p, ht->last_height);
P_WriteFixed(save_p, ht->speed);
P_WriteUINT8(save_p, ht->type);
}
static inline void SaveDynamicLineSlopeThinker(const thinker_t *th, const UINT8 type)
static inline void SaveDynamicLineSlopeThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const dynlineplanethink_t* ht = (const void*)th;
WRITEUINT8(save_p, type);
WRITEUINT8(save_p, ht->type);
WRITEUINT32(save_p, SaveSlope(ht->slope));
WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEFIXED(save_p, ht->extent);
P_WriteUINT8(save_p, type);
P_WriteUINT8(save_p, ht->type);
P_WriteUINT32(save_p, SaveSlope(ht->slope));
P_WriteUINT32(save_p, SaveLine(ht->sourceline));
P_WriteFixed(save_p, ht->extent);
}
static inline void SaveDynamicVertexSlopeThinker(const thinker_t *th, const UINT8 type)
static inline void SaveDynamicVertexSlopeThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
size_t i;
const dynvertexplanethink_t* ht = (const void*)th;
WRITEUINT8(save_p, type);
WRITEUINT32(save_p, SaveSlope(ht->slope));
P_WriteUINT8(save_p, type);
P_WriteUINT32(save_p, SaveSlope(ht->slope));
for (i = 0; i < 3; i++)
WRITEUINT32(save_p, SaveSector(ht->secs[i]));
WRITEMEM(save_p, ht->vex, sizeof(ht->vex));
WRITEMEM(save_p, ht->origsecheights, sizeof(ht->origsecheights));
WRITEMEM(save_p, ht->origvecheights, sizeof(ht->origvecheights));
WRITEUINT8(save_p, ht->relative);
P_WriteUINT32(save_p, SaveSector(ht->secs[i]));
P_WriteMem(save_p, ht->vex, sizeof(ht->vex));
P_WriteMem(save_p, ht->origsecheights, sizeof(ht->origsecheights));
P_WriteMem(save_p, ht->origvecheights, sizeof(ht->origvecheights));
P_WriteUINT8(save_p, ht->relative);
}
static inline void SavePolyrotatetThinker(const thinker_t *th, const UINT8 type)
static inline void SavePolyrotatetThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const polyrotate_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->polyObjNum);
WRITEINT32(save_p, ht->speed);
WRITEINT32(save_p, ht->distance);
WRITEUINT8(save_p, ht->turnobjs);
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->polyObjNum);
P_WriteINT32(save_p, ht->speed);
P_WriteINT32(save_p, ht->distance);
P_WriteUINT8(save_p, ht->turnobjs);
}
static void SavePolymoveThinker(const thinker_t *th, const UINT8 type)
static void SavePolymoveThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const polymove_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->polyObjNum);
WRITEINT32(save_p, ht->speed);
WRITEFIXED(save_p, ht->momx);
WRITEFIXED(save_p, ht->momy);
WRITEINT32(save_p, ht->distance);
WRITEANGLE(save_p, ht->angle);
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->polyObjNum);
P_WriteINT32(save_p, ht->speed);
P_WriteFixed(save_p, ht->momx);
P_WriteFixed(save_p, ht->momy);
P_WriteINT32(save_p, ht->distance);
P_WriteAngle(save_p, ht->angle);
}
static void SavePolywaypointThinker(const thinker_t *th, UINT8 type)
static void SavePolywaypointThinker(save_t *save_p, const thinker_t *th, UINT8 type)
{
const polywaypoint_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->polyObjNum);
WRITEINT32(save_p, ht->speed);
WRITEINT32(save_p, ht->sequence);
WRITEINT32(save_p, ht->pointnum);
WRITEINT32(save_p, ht->direction);
WRITEUINT8(save_p, ht->returnbehavior);
WRITEUINT8(save_p, ht->continuous);
WRITEUINT8(save_p, ht->stophere);
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->polyObjNum);
P_WriteINT32(save_p, ht->speed);
P_WriteINT32(save_p, ht->sequence);
P_WriteINT32(save_p, ht->pointnum);
P_WriteINT32(save_p, ht->direction);
P_WriteUINT8(save_p, ht->returnbehavior);
P_WriteUINT8(save_p, ht->continuous);
P_WriteUINT8(save_p, ht->stophere);
}
static void SavePolyslidedoorThinker(const thinker_t *th, const UINT8 type)
static void SavePolyslidedoorThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const polyslidedoor_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->polyObjNum);
WRITEINT32(save_p, ht->delay);
WRITEINT32(save_p, ht->delayCount);
WRITEINT32(save_p, ht->initSpeed);
WRITEINT32(save_p, ht->speed);
WRITEINT32(save_p, ht->initDistance);
WRITEINT32(save_p, ht->distance);
WRITEUINT32(save_p, ht->initAngle);
WRITEUINT32(save_p, ht->angle);
WRITEUINT32(save_p, ht->revAngle);
WRITEFIXED(save_p, ht->momx);
WRITEFIXED(save_p, ht->momy);
WRITEUINT8(save_p, ht->closing);
}
static void SavePolyswingdoorThinker(const thinker_t *th, const UINT8 type)
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->polyObjNum);
P_WriteINT32(save_p, ht->delay);
P_WriteINT32(save_p, ht->delayCount);
P_WriteINT32(save_p, ht->initSpeed);
P_WriteINT32(save_p, ht->speed);
P_WriteINT32(save_p, ht->initDistance);
P_WriteINT32(save_p, ht->distance);
P_WriteUINT32(save_p, ht->initAngle);
P_WriteUINT32(save_p, ht->angle);
P_WriteUINT32(save_p, ht->revAngle);
P_WriteFixed(save_p, ht->momx);
P_WriteFixed(save_p, ht->momy);
P_WriteUINT8(save_p, ht->closing);
}
static void SavePolyswingdoorThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const polyswingdoor_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->polyObjNum);
WRITEINT32(save_p, ht->delay);
WRITEINT32(save_p, ht->delayCount);
WRITEINT32(save_p, ht->initSpeed);
WRITEINT32(save_p, ht->speed);
WRITEINT32(save_p, ht->initDistance);
WRITEINT32(save_p, ht->distance);
WRITEUINT8(save_p, ht->closing);
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->polyObjNum);
P_WriteINT32(save_p, ht->delay);
P_WriteINT32(save_p, ht->delayCount);
P_WriteINT32(save_p, ht->initSpeed);
P_WriteINT32(save_p, ht->speed);
P_WriteINT32(save_p, ht->initDistance);
P_WriteINT32(save_p, ht->distance);
P_WriteUINT8(save_p, ht->closing);
}
static void SavePolydisplaceThinker(const thinker_t *th, const UINT8 type)
static void SavePolydisplaceThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const polydisplace_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->polyObjNum);
WRITEUINT32(save_p, SaveSector(ht->controlSector));
WRITEFIXED(save_p, ht->dx);
WRITEFIXED(save_p, ht->dy);
WRITEFIXED(save_p, ht->oldHeights);
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->polyObjNum);
P_WriteUINT32(save_p, SaveSector(ht->controlSector));
P_WriteFixed(save_p, ht->dx);
P_WriteFixed(save_p, ht->dy);
P_WriteFixed(save_p, ht->oldHeights);
}
static void SavePolyrotdisplaceThinker(const thinker_t *th, const UINT8 type)
static void SavePolyrotdisplaceThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const polyrotdisplace_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->polyObjNum);
WRITEUINT32(save_p, SaveSector(ht->controlSector));
WRITEFIXED(save_p, ht->rotscale);
WRITEUINT8(save_p, ht->turnobjs);
WRITEFIXED(save_p, ht->oldHeights);
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->polyObjNum);
P_WriteUINT32(save_p, SaveSector(ht->controlSector));
P_WriteFixed(save_p, ht->rotscale);
P_WriteUINT8(save_p, ht->turnobjs);
P_WriteFixed(save_p, ht->oldHeights);
}
static void SavePolyfadeThinker(const thinker_t *th, const UINT8 type)
static void SavePolyfadeThinker(save_t *save_p, const thinker_t *th, const UINT8 type)
{
const polyfade_t *ht = (const void *)th;
WRITEUINT8(save_p, type);
WRITEINT32(save_p, ht->polyObjNum);
WRITEINT32(save_p, ht->sourcevalue);
WRITEINT32(save_p, ht->destvalue);
WRITEUINT8(save_p, (UINT8)ht->docollision);
WRITEUINT8(save_p, (UINT8)ht->doghostfade);
WRITEUINT8(save_p, (UINT8)ht->ticbased);
WRITEINT32(save_p, ht->duration);
WRITEINT32(save_p, ht->timer);
P_WriteUINT8(save_p, type);
P_WriteINT32(save_p, ht->polyObjNum);
P_WriteINT32(save_p, ht->sourcevalue);
P_WriteINT32(save_p, ht->destvalue);
P_WriteUINT8(save_p, (UINT8)ht->docollision);
P_WriteUINT8(save_p, (UINT8)ht->doghostfade);
P_WriteUINT8(save_p, (UINT8)ht->ticbased);
P_WriteINT32(save_p, ht->duration);
P_WriteINT32(save_p, ht->timer);
}
static void P_NetArchiveThinkers(void)
static void P_NetArchiveThinkers(save_t *save_p)
{
const thinker_t *th;
UINT32 i;
WRITEUINT32(save_p, ARCHIVEBLOCK_THINKERS);
P_WriteUINT32(save_p, ARCHIVEBLOCK_THINKERS);
for (i = 0; i < NUM_THINKERLISTS; i++)
{
......@@ -2675,13 +2980,12 @@ static void P_NetArchiveThinkers(void)
// save off the current thinkers
for (th = thlist[i].next; th != &thlist[i]; th = th->next)
{
if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed
|| th->function.acp1 == (actionf_p1)P_NullPrecipThinker))
if (!(th->removing || th->function.acp1 == (actionf_p1)P_NullPrecipThinker))
numsaved++;
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
{
SaveMobjThinker(th, tc_mobj);
SaveMobjThinker(save_p, th, tc_mobj);
continue;
}
#ifdef PARANOIA
......@@ -2689,213 +2993,213 @@ static void P_NetArchiveThinkers(void)
#endif
else if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
{
SaveCeilingThinker(th, tc_ceiling);
SaveCeilingThinker(save_p, th, tc_ceiling);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_CrushCeiling)
{
SaveCeilingThinker(th, tc_crushceiling);
SaveCeilingThinker(save_p, th, tc_crushceiling);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_MoveFloor)
{
SaveFloormoveThinker(th, tc_floor);
SaveFloormoveThinker(save_p, th, tc_floor);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_LightningFlash)
{
SaveLightflashThinker(th, tc_flash);
SaveLightflashThinker(save_p, th, tc_flash);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_StrobeFlash)
{
SaveStrobeThinker(th, tc_strobe);
SaveStrobeThinker(save_p, th, tc_strobe);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_Glow)
{
SaveGlowThinker(th, tc_glow);
SaveGlowThinker(save_p, th, tc_glow);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_FireFlicker)
{
SaveFireflickerThinker(th, tc_fireflicker);
SaveFireflickerThinker(save_p, th, tc_fireflicker);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_MoveElevator)
{
SaveElevatorThinker(th, tc_elevator);
SaveElevatorThinker(save_p, th, tc_elevator);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_ContinuousFalling)
{
SaveContinuousFallThinker(th, tc_continuousfalling);
SaveContinuousFallThinker(save_p, th, tc_continuousfalling);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_ThwompSector)
{
SaveThwompThinker(th, tc_thwomp);
SaveThwompThinker(save_p, th, tc_thwomp);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_NoEnemiesSector)
{
SaveNoEnemiesThinker(th, tc_noenemies);
SaveNoEnemiesThinker(save_p, th, tc_noenemies);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_EachTimeThinker)
{
SaveEachTimeThinker(th, tc_eachtime);
SaveEachTimeThinker(save_p, th, tc_eachtime);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_RaiseSector)
{
SaveRaiseThinker(th, tc_raisesector);
SaveRaiseThinker(save_p, th, tc_raisesector);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_CameraScanner)
{
SaveElevatorThinker(th, tc_camerascanner);
SaveElevatorThinker(save_p, th, tc_camerascanner);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_Scroll)
{
SaveScrollThinker(th, tc_scroll);
SaveScrollThinker(save_p, th, tc_scroll);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_Friction)
{
SaveFrictionThinker(th, tc_friction);
SaveFrictionThinker(save_p, th, tc_friction);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_Pusher)
{
SavePusherThinker(th, tc_pusher);
SavePusherThinker(save_p, th, tc_pusher);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_BounceCheese)
{
SaveBounceCheeseThinker(th, tc_bouncecheese);
SaveBounceCheeseThinker(save_p, th, tc_bouncecheese);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_StartCrumble)
{
SaveCrumbleThinker(th, tc_startcrumble);
SaveCrumbleThinker(save_p, th, tc_startcrumble);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_MarioBlock)
{
SaveMarioBlockThinker(th, tc_marioblock);
SaveMarioBlockThinker(save_p, th, tc_marioblock);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
{
SaveMarioCheckThinker(th, tc_marioblockchecker);
SaveMarioCheckThinker(save_p, th, tc_marioblockchecker);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_FloatSector)
{
SaveFloatThinker(th, tc_floatsector);
SaveFloatThinker(save_p, th, tc_floatsector);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_LaserFlash)
{
SaveLaserThinker(th, tc_laserflash);
SaveLaserThinker(save_p, th, tc_laserflash);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_LightFade)
{
SaveLightlevelThinker(th, tc_lightfade);
SaveLightlevelThinker(save_p, th, tc_lightfade);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_ExecutorDelay)
{
SaveExecutorThinker(th, tc_executor);
SaveExecutorThinker(save_p, th, tc_executor);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_Disappear)
{
SaveDisappearThinker(th, tc_disappear);
SaveDisappearThinker(save_p, th, tc_disappear);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_Fade)
{
SaveFadeThinker(th, tc_fade);
SaveFadeThinker(save_p, th, tc_fade);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_FadeColormap)
{
SaveFadeColormapThinker(th, tc_fadecolormap);
SaveFadeColormapThinker(save_p, th, tc_fadecolormap);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace)
{
SavePlaneDisplaceThinker(th, tc_planedisplace);
SavePlaneDisplaceThinker(save_p, th, tc_planedisplace);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate)
{
SavePolyrotatetThinker(th, tc_polyrotate);
SavePolyrotatetThinker(save_p, th, tc_polyrotate);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PolyObjMove)
{
SavePolymoveThinker(th, tc_polymove);
SavePolymoveThinker(save_p, th, tc_polymove);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PolyObjWaypoint)
{
SavePolywaypointThinker(th, tc_polywaypoint);
SavePolywaypointThinker(save_p, th, tc_polywaypoint);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PolyDoorSlide)
{
SavePolyslidedoorThinker(th, tc_polyslidedoor);
SavePolyslidedoorThinker(save_p, th, tc_polyslidedoor);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PolyDoorSwing)
{
SavePolyswingdoorThinker(th, tc_polyswingdoor);
SavePolyswingdoorThinker(save_p, th, tc_polyswingdoor);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PolyObjFlag)
{
SavePolymoveThinker(th, tc_polyflag);
SavePolymoveThinker(save_p, th, tc_polyflag);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PolyObjDisplace)
{
SavePolydisplaceThinker(th, tc_polydisplace);
SavePolydisplaceThinker(save_p, th, tc_polydisplace);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PolyObjRotDisplace)
{
SavePolyrotdisplaceThinker(th, tc_polyrotdisplace);
SavePolyrotdisplaceThinker(save_p, th, tc_polyrotdisplace);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_PolyObjFade)
{
SavePolyfadeThinker(th, tc_polyfade);
SavePolyfadeThinker(save_p, th, tc_polyfade);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeLine)
{
SaveDynamicLineSlopeThinker(th, tc_dynslopeline);
SaveDynamicLineSlopeThinker(save_p, th, tc_dynslopeline);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_DynamicSlopeVert)
{
SaveDynamicVertexSlopeThinker(th, tc_dynslopevert);
SaveDynamicVertexSlopeThinker(save_p, th, tc_dynslopevert);
continue;
}
#ifdef PARANOIA
else
I_Assert(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed); // wait garbage collection
I_Assert(th->removing); // wait garbage collection
#endif
}
CONS_Debug(DBG_NETPLAY, "%u thinkers saved in list %d\n", numsaved, i);
WRITEUINT8(save_p, tc_end);
P_WriteUINT8(save_p, tc_end);
}
}
......@@ -2910,7 +3214,7 @@ mobj_t *P_FindNewPosition(UINT32 oldposition)
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mobj = (mobj_t *)th;
......@@ -2941,12 +3245,6 @@ static line_t *LoadLine(UINT32 line)
return &lines[line];
}
static inline player_t *LoadPlayer(UINT32 player)
{
if (player >= MAXPLAYERS) return NULL;
return &players[player];
}
static inline pslope_t *LoadSlope(UINT32 slopeid)
{
pslope_t *p = slopelist;
......@@ -2959,7 +3257,7 @@ static inline pslope_t *LoadSlope(UINT32 slopeid)
return NULL;
}
static thinker_t* LoadMobjThinker(actionf_p1 thinker)
static thinker_t* LoadMobjThinker(save_t *save_p, actionf_p1 thinker)
{
thinker_t *next;
mobj_t *mobj;
......@@ -2969,35 +3267,35 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
fixed_t z, floorz, ceilingz;
ffloor_t *floorrover = NULL, *ceilingrover = NULL;
diff = READUINT32(save_p);
diff = P_ReadUINT32(save_p);
if (diff & MD_MORE)
diff2 = READUINT32(save_p);
diff2 = P_ReadUINT32(save_p);
else
diff2 = 0;
next = (void *)(size_t)READUINT32(save_p);
next = (void *)(size_t)P_ReadUINT32(save_p);
z = READFIXED(save_p); // Force this so 3dfloor problems don't arise.
floorz = READFIXED(save_p);
ceilingz = READFIXED(save_p);
z = P_ReadFixed(save_p); // Force this so 3dfloor problems don't arise.
floorz = P_ReadFixed(save_p);
ceilingz = P_ReadFixed(save_p);
if (diff2 & MD2_FLOORROVER)
{
sector_t *sec = LoadSector(READUINT32(save_p));
UINT16 id = READUINT16(save_p);
sector_t *sec = LoadSector(P_ReadUINT32(save_p));
UINT16 id = P_ReadUINT16(save_p);
floorrover = P_GetFFloorByID(sec, id);
}
if (diff2 & MD2_CEILINGROVER)
{
sector_t *sec = LoadSector(READUINT32(save_p));
UINT16 id = READUINT16(save_p);
sector_t *sec = LoadSector(P_ReadUINT32(save_p));
UINT16 id = P_ReadUINT16(save_p);
ceilingrover = P_GetFFloorByID(sec, id);
}
if (diff & MD_SPAWNPOINT)
{
UINT16 spawnpointnum = READUINT16(save_p);
UINT16 spawnpointnum = P_ReadUINT16(save_p);
if (mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case
{
......@@ -3023,7 +3321,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->ceilingrover = ceilingrover;
if (diff & MD_TYPE)
mobj->type = READUINT32(save_p);
mobj->type = P_ReadUINT32(save_p);
else
{
for (i = 0; i < NUMMOBJTYPES; i++)
......@@ -3042,11 +3340,11 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->info = &mobjinfo[mobj->type];
if (diff & MD_POS)
{
mobj->x = READFIXED(save_p);
mobj->y = READFIXED(save_p);
mobj->angle = READANGLE(save_p);
mobj->pitch = READANGLE(save_p);
mobj->roll = READANGLE(save_p);
mobj->x = P_ReadFixed(save_p);
mobj->y = P_ReadFixed(save_p);
mobj->angle = P_ReadAngle(save_p);
mobj->pitch = P_ReadAngle(save_p);
mobj->roll = P_ReadAngle(save_p);
}
else
{
......@@ -3058,47 +3356,47 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
}
if (diff & MD_MOM)
{
mobj->momx = READFIXED(save_p);
mobj->momy = READFIXED(save_p);
mobj->momz = READFIXED(save_p);
mobj->pmomz = READFIXED(save_p);
mobj->momx = P_ReadFixed(save_p);
mobj->momy = P_ReadFixed(save_p);
mobj->momz = P_ReadFixed(save_p);
mobj->pmomz = P_ReadFixed(save_p);
} // otherwise they're zero, and the memset took care of it
if (diff & MD_RADIUS)
mobj->radius = READFIXED(save_p);
mobj->radius = P_ReadFixed(save_p);
else
mobj->radius = mobj->info->radius;
if (diff & MD_HEIGHT)
mobj->height = READFIXED(save_p);
mobj->height = P_ReadFixed(save_p);
else
mobj->height = mobj->info->height;
if (diff & MD_FLAGS)
mobj->flags = READUINT32(save_p);
mobj->flags = P_ReadUINT32(save_p);
else
mobj->flags = mobj->info->flags;
if (diff & MD_FLAGS2)
mobj->flags2 = READUINT32(save_p);
mobj->flags2 = P_ReadUINT32(save_p);
if (diff & MD_HEALTH)
mobj->health = READINT32(save_p);
mobj->health = P_ReadINT32(save_p);
else
mobj->health = mobj->info->spawnhealth;
if (diff & MD_RTIME)
mobj->reactiontime = READINT32(save_p);
mobj->reactiontime = P_ReadINT32(save_p);
else
mobj->reactiontime = mobj->info->reactiontime;
if (diff & MD_STATE)
mobj->state = &states[READUINT16(save_p)];
mobj->state = &states[P_ReadUINT16(save_p)];
else
mobj->state = &states[mobj->info->spawnstate];
if (diff & MD_TICS)
mobj->tics = READINT32(save_p);
mobj->tics = P_ReadINT32(save_p);
else
mobj->tics = mobj->state->tics;
if (diff & MD_SPRITE) {
mobj->sprite = READUINT16(save_p);
mobj->sprite = P_ReadUINT16(save_p);
if (mobj->sprite == SPR_PLAY)
mobj->sprite2 = READUINT16(save_p);
mobj->sprite2 = P_ReadUINT16(save_p);
}
else {
mobj->sprite = mobj->state->sprite;
......@@ -3107,8 +3405,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
}
if (diff & MD_FRAME)
{
mobj->frame = READUINT32(save_p);
mobj->anim_duration = READUINT16(save_p);
mobj->frame = P_ReadUINT32(save_p);
mobj->anim_duration = P_ReadUINT16(save_p);
}
else
{
......@@ -3116,128 +3414,132 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->anim_duration = (UINT16)mobj->state->var2;
}
if (diff & MD_EFLAGS)
mobj->eflags = READUINT16(save_p);
mobj->eflags = P_ReadUINT16(save_p);
if (diff & MD_PLAYER)
{
i = READUINT8(save_p);
i = P_ReadUINT8(save_p);
mobj->player = &players[i];
mobj->player->mo = mobj;
}
if (diff & MD_MOVEDIR)
mobj->movedir = READANGLE(save_p);
mobj->movedir = P_ReadAngle(save_p);
if (diff & MD_MOVECOUNT)
mobj->movecount = READINT32(save_p);
mobj->movecount = P_ReadINT32(save_p);
if (diff & MD_THRESHOLD)
mobj->threshold = READINT32(save_p);
mobj->threshold = P_ReadINT32(save_p);
if (diff & MD_LASTLOOK)
mobj->lastlook = READINT32(save_p);
mobj->lastlook = P_ReadINT32(save_p);
else
mobj->lastlook = -1;
if (diff & MD_TARGET)
mobj->target = (mobj_t *)(size_t)READUINT32(save_p);
mobj->target = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (diff & MD_TRACER)
mobj->tracer = (mobj_t *)(size_t)READUINT32(save_p);
mobj->tracer = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (diff & MD_FRICTION)
mobj->friction = READFIXED(save_p);
mobj->friction = P_ReadFixed(save_p);
else
mobj->friction = ORIG_FRICTION;
if (diff & MD_MOVEFACTOR)
mobj->movefactor = READFIXED(save_p);
mobj->movefactor = P_ReadFixed(save_p);
else
mobj->movefactor = FRACUNIT;
if (diff & MD_FUSE)
mobj->fuse = READINT32(save_p);
mobj->fuse = P_ReadINT32(save_p);
if (diff & MD_WATERTOP)
mobj->watertop = READFIXED(save_p);
mobj->watertop = P_ReadFixed(save_p);
if (diff & MD_WATERBOTTOM)
mobj->waterbottom = READFIXED(save_p);
mobj->waterbottom = P_ReadFixed(save_p);
if (diff & MD_SCALE)
mobj->scale = READFIXED(save_p);
mobj->scale = P_ReadFixed(save_p);
else
mobj->scale = FRACUNIT;
if (diff & MD_DSCALE)
mobj->destscale = READFIXED(save_p);
mobj->destscale = P_ReadFixed(save_p);
else
mobj->destscale = mobj->scale;
if (diff2 & MD2_SCALESPEED)
mobj->scalespeed = READFIXED(save_p);
mobj->scalespeed = P_ReadFixed(save_p);
else
mobj->scalespeed = FRACUNIT/12;
if (diff2 & MD2_CUSVAL)
mobj->cusval = READINT32(save_p);
mobj->cusval = P_ReadINT32(save_p);
if (diff2 & MD2_CVMEM)
mobj->cvmem = READINT32(save_p);
mobj->cvmem = P_ReadINT32(save_p);
if (diff2 & MD2_SKIN)
mobj->skin = skins[READUINT8(save_p)];
mobj->skin = skins[P_ReadUINT8(save_p)];
if (diff2 & MD2_COLOR)
mobj->color = READUINT16(save_p);
mobj->color = P_ReadUINT16(save_p);
if (diff2 & MD2_EXTVAL1)
mobj->extravalue1 = READINT32(save_p);
mobj->extravalue1 = P_ReadINT32(save_p);
if (diff2 & MD2_EXTVAL2)
mobj->extravalue2 = READINT32(save_p);
mobj->extravalue2 = P_ReadINT32(save_p);
if (diff2 & MD2_HNEXT)
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
mobj->hnext = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
mobj->hprev = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (diff2 & MD2_SLOPE)
mobj->standingslope = P_SlopeById(READUINT16(save_p));
mobj->standingslope = P_SlopeById(P_ReadUINT16(save_p));
if (diff2 & MD2_COLORIZED)
mobj->colorized = READUINT8(save_p);
mobj->colorized = P_ReadUINT8(save_p);
if (diff2 & MD2_MIRRORED)
mobj->mirrored = READUINT8(save_p);
mobj->mirrored = P_ReadUINT8(save_p);
if (diff2 & MD2_SPRITEROLL)
mobj->spriteroll = READANGLE(save_p);
mobj->spriteroll = P_ReadAngle(save_p);
if (diff2 & MD2_SHADOWSCALE)
mobj->shadowscale = READFIXED(save_p);
mobj->shadowscale = P_ReadFixed(save_p);
if (diff2 & MD2_RENDERFLAGS)
mobj->renderflags = READUINT32(save_p);
mobj->renderflags = P_ReadUINT32(save_p);
if (diff2 & MD2_BLENDMODE)
mobj->blendmode = READINT32(save_p);
mobj->blendmode = P_ReadINT32(save_p);
else
mobj->blendmode = AST_TRANSLUCENT;
if (diff2 & MD2_SPRITEXSCALE)
mobj->spritexscale = READFIXED(save_p);
mobj->spritexscale = P_ReadFixed(save_p);
else
mobj->spritexscale = FRACUNIT;
if (diff2 & MD2_SPRITEYSCALE)
mobj->spriteyscale = READFIXED(save_p);
mobj->spriteyscale = P_ReadFixed(save_p);
else
mobj->spriteyscale = FRACUNIT;
if (diff2 & MD2_SPRITEXOFFSET)
mobj->spritexoffset = READFIXED(save_p);
mobj->spritexoffset = P_ReadFixed(save_p);
if (diff2 & MD2_SPRITEYOFFSET)
mobj->spriteyoffset = READFIXED(save_p);
mobj->spriteyoffset = P_ReadFixed(save_p);
if (diff2 & MD2_FLOORSPRITESLOPE)
{
pslope_t *slope = (pslope_t *)P_CreateFloorSpriteSlope(mobj);
slope->zdelta = READFIXED(save_p);
slope->zangle = READANGLE(save_p);
slope->xydirection = READANGLE(save_p);
slope->zdelta = P_ReadFixed(save_p);
slope->zangle = P_ReadAngle(save_p);
slope->xydirection = P_ReadAngle(save_p);
slope->o.x = READFIXED(save_p);
slope->o.y = READFIXED(save_p);
slope->o.z = READFIXED(save_p);
slope->o.x = P_ReadFixed(save_p);
slope->o.y = P_ReadFixed(save_p);
slope->o.z = P_ReadFixed(save_p);
slope->d.x = READFIXED(save_p);
slope->d.y = READFIXED(save_p);
slope->d.x = P_ReadFixed(save_p);
slope->d.y = P_ReadFixed(save_p);
slope->normal.x = READFIXED(save_p);
slope->normal.y = READFIXED(save_p);
slope->normal.z = READFIXED(save_p);
slope->normal.x = P_ReadFixed(save_p);
slope->normal.y = P_ReadFixed(save_p);
slope->normal.z = P_ReadFixed(save_p);
slope->moved = true;
}
if (diff2 & MD2_DRAWONLYFORPLAYER)
mobj->drawonlyforplayer = &players[READUINT8(save_p)];
mobj->drawonlyforplayer = &players[P_ReadUINT8(save_p)];
if (diff2 & MD2_DONTDRAWFORVIEWMOBJ)
mobj->dontdrawforviewmobj = (mobj_t *)(size_t)READUINT32(save_p);
mobj->dontdrawforviewmobj = (mobj_t *)(size_t)P_ReadUINT32(save_p);
if (diff2 & MD2_DISPOFFSET)
mobj->dispoffset = READINT32(save_p);
mobj->dispoffset = P_ReadINT32(save_p);
else
mobj->dispoffset = mobj->info->dispoffset;
if (diff2 & MD2_TRANSLATION)
mobj->translation = READUINT16(save_p);
mobj->translation = P_ReadUINT16(save_p);
if (diff2 & MD2_ALPHA)
mobj->alpha = P_ReadFixed(save_p);
else
mobj->alpha = FRACUNIT;
if (diff & MD_REDFLAG)
{
......@@ -3253,7 +3555,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
// set sprev, snext, bprev, bnext, subsector
P_SetThingPosition(mobj);
mobj->mobjnum = READUINT32(save_p);
mobj->mobjnum = P_ReadUINT32(save_p);
if (mobj->player)
{
......@@ -3282,25 +3584,25 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
return &mobj->thinker;
}
static thinker_t* LoadNoEnemiesThinker(actionf_p1 thinker)
static thinker_t* LoadNoEnemiesThinker(save_t *save_p, actionf_p1 thinker)
{
noenemies_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
return &ht->thinker;
}
static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker)
static thinker_t* LoadBounceCheeseThinker(save_t *save_p, actionf_p1 thinker)
{
bouncecheese_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
ht->sector = LoadSector(READUINT32(save_p));
ht->speed = READFIXED(save_p);
ht->distance = READFIXED(save_p);
ht->floorwasheight = READFIXED(save_p);
ht->ceilingwasheight = READFIXED(save_p);
ht->low = READCHAR(save_p);
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->speed = P_ReadFixed(save_p);
ht->distance = P_ReadFixed(save_p);
ht->floorwasheight = P_ReadFixed(save_p);
ht->ceilingwasheight = P_ReadFixed(save_p);
ht->low = P_ReadChar(save_p);
if (ht->sector)
ht->sector->ceilingdata = ht;
......@@ -3308,16 +3610,16 @@ static thinker_t* LoadBounceCheeseThinker(actionf_p1 thinker)
return &ht->thinker;
}
static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker)
static thinker_t* LoadContinuousFallThinker(save_t *save_p, actionf_p1 thinker)
{
continuousfall_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->speed = READFIXED(save_p);
ht->direction = READINT32(save_p);
ht->floorstartheight = READFIXED(save_p);
ht->ceilingstartheight = READFIXED(save_p);
ht->destheight = READFIXED(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->speed = P_ReadFixed(save_p);
ht->direction = P_ReadINT32(save_p);
ht->floorstartheight = P_ReadFixed(save_p);
ht->ceilingstartheight = P_ReadFixed(save_p);
ht->destheight = P_ReadFixed(save_p);
if (ht->sector)
{
......@@ -3328,16 +3630,16 @@ static thinker_t* LoadContinuousFallThinker(actionf_p1 thinker)
return &ht->thinker;
}
static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker)
static thinker_t* LoadMarioBlockThinker(save_t *save_p, actionf_p1 thinker)
{
mariothink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->speed = READFIXED(save_p);
ht->direction = READINT32(save_p);
ht->floorstartheight = READFIXED(save_p);
ht->ceilingstartheight = READFIXED(save_p);
ht->tag = READINT16(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->speed = P_ReadFixed(save_p);
ht->direction = P_ReadINT32(save_p);
ht->floorstartheight = P_ReadFixed(save_p);
ht->ceilingstartheight = P_ReadFixed(save_p);
ht->tag = P_ReadINT16(save_p);
if (ht->sector)
{
......@@ -3348,29 +3650,29 @@ static thinker_t* LoadMarioBlockThinker(actionf_p1 thinker)
return &ht->thinker;
}
static thinker_t* LoadMarioCheckThinker(actionf_p1 thinker)
static thinker_t* LoadMarioCheckThinker(save_t *save_p, actionf_p1 thinker)
{
mariocheck_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
ht->sector = LoadSector(READUINT32(save_p));
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
ht->sector = LoadSector(P_ReadUINT32(save_p));
return &ht->thinker;
}
static thinker_t* LoadThwompThinker(actionf_p1 thinker)
static thinker_t* LoadThwompThinker(save_t *save_p, actionf_p1 thinker)
{
thwomp_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
ht->sector = LoadSector(READUINT32(save_p));
ht->crushspeed = READFIXED(save_p);
ht->retractspeed = READFIXED(save_p);
ht->direction = READINT32(save_p);
ht->floorstartheight = READFIXED(save_p);
ht->ceilingstartheight = READFIXED(save_p);
ht->delay = READINT32(save_p);
ht->tag = READINT16(save_p);
ht->sound = READUINT16(save_p);
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->crushspeed = P_ReadFixed(save_p);
ht->retractspeed = P_ReadFixed(save_p);
ht->direction = P_ReadINT32(save_p);
ht->floorstartheight = P_ReadFixed(save_p);
ht->ceilingstartheight = P_ReadFixed(save_p);
ht->delay = P_ReadINT32(save_p);
ht->tag = P_ReadINT16(save_p);
ht->sound = P_ReadUINT16(save_p);
if (ht->sector)
{
......@@ -3381,163 +3683,163 @@ static thinker_t* LoadThwompThinker(actionf_p1 thinker)
return &ht->thinker;
}
static thinker_t* LoadFloatThinker(actionf_p1 thinker)
static thinker_t* LoadFloatThinker(save_t *save_p, actionf_p1 thinker)
{
floatthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
ht->sector = LoadSector(READUINT32(save_p));
ht->tag = READINT16(save_p);
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->tag = P_ReadINT16(save_p);
return &ht->thinker;
}
static thinker_t* LoadEachTimeThinker(actionf_p1 thinker)
static thinker_t* LoadEachTimeThinker(save_t *save_p, actionf_p1 thinker)
{
size_t i;
eachtime_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
for (i = 0; i < MAXPLAYERS; i++)
{
ht->playersInArea[i] = READCHAR(save_p);
ht->playersInArea[i] = P_ReadChar(save_p);
}
ht->triggerOnExit = READCHAR(save_p);
ht->triggerOnExit = P_ReadChar(save_p);
return &ht->thinker;
}
static thinker_t* LoadRaiseThinker(actionf_p1 thinker)
static thinker_t* LoadRaiseThinker(save_t *save_p, actionf_p1 thinker)
{
raise_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->tag = READINT16(save_p);
ht->sector = LoadSector(READUINT32(save_p));
ht->ceilingbottom = READFIXED(save_p);
ht->ceilingtop = READFIXED(save_p);
ht->basespeed = READFIXED(save_p);
ht->extraspeed = READFIXED(save_p);
ht->shaketimer = READUINT8(save_p);
ht->flags = READUINT8(save_p);
ht->tag = P_ReadINT16(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->ceilingbottom = P_ReadFixed(save_p);
ht->ceilingtop = P_ReadFixed(save_p);
ht->basespeed = P_ReadFixed(save_p);
ht->extraspeed = P_ReadFixed(save_p);
ht->shaketimer = P_ReadUINT8(save_p);
ht->flags = P_ReadUINT8(save_p);
return &ht->thinker;
}
static thinker_t* LoadCeilingThinker(actionf_p1 thinker)
static thinker_t* LoadCeilingThinker(save_t *save_p, actionf_p1 thinker)
{
ceiling_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->type = READUINT8(save_p);
ht->sector = LoadSector(READUINT32(save_p));
ht->bottomheight = READFIXED(save_p);
ht->topheight = READFIXED(save_p);
ht->speed = READFIXED(save_p);
ht->delay = READFIXED(save_p);
ht->delaytimer = READFIXED(save_p);
ht->crush = READUINT8(save_p);
ht->texture = READINT32(save_p);
ht->direction = READINT32(save_p);
ht->tag = READINT16(save_p);
ht->origspeed = READFIXED(save_p);
ht->sourceline = READFIXED(save_p);
ht->type = P_ReadUINT8(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->bottomheight = P_ReadFixed(save_p);
ht->topheight = P_ReadFixed(save_p);
ht->speed = P_ReadFixed(save_p);
ht->delay = P_ReadFixed(save_p);
ht->delaytimer = P_ReadFixed(save_p);
ht->crush = P_ReadUINT8(save_p);
ht->texture = P_ReadINT32(save_p);
ht->direction = P_ReadINT32(save_p);
ht->tag = P_ReadINT16(save_p);
ht->origspeed = P_ReadFixed(save_p);
ht->sourceline = P_ReadFixed(save_p);
if (ht->sector)
ht->sector->ceilingdata = ht;
return &ht->thinker;
}
static thinker_t* LoadFloormoveThinker(actionf_p1 thinker)
static thinker_t* LoadFloormoveThinker(save_t *save_p, actionf_p1 thinker)
{
floormove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->type = READUINT8(save_p);
ht->crush = READUINT8(save_p);
ht->sector = LoadSector(READUINT32(save_p));
ht->direction = READINT32(save_p);
ht->texture = READINT32(save_p);
ht->floordestheight = READFIXED(save_p);
ht->speed = READFIXED(save_p);
ht->origspeed = READFIXED(save_p);
ht->delay = READFIXED(save_p);
ht->delaytimer = READFIXED(save_p);
ht->tag = READINT16(save_p);
ht->sourceline = READFIXED(save_p);
ht->type = P_ReadUINT8(save_p);
ht->crush = P_ReadUINT8(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->direction = P_ReadINT32(save_p);
ht->texture = P_ReadINT32(save_p);
ht->floordestheight = P_ReadFixed(save_p);
ht->speed = P_ReadFixed(save_p);
ht->origspeed = P_ReadFixed(save_p);
ht->delay = P_ReadFixed(save_p);
ht->delaytimer = P_ReadFixed(save_p);
ht->tag = P_ReadINT16(save_p);
ht->sourceline = P_ReadFixed(save_p);
if (ht->sector)
ht->sector->floordata = ht;
return &ht->thinker;
}
static thinker_t* LoadLightflashThinker(actionf_p1 thinker)
static thinker_t* LoadLightflashThinker(save_t *save_p, actionf_p1 thinker)
{
lightflash_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->maxlight = READINT32(save_p);
ht->minlight = READINT32(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->maxlight = P_ReadINT32(save_p);
ht->minlight = P_ReadINT32(save_p);
if (ht->sector)
ht->sector->lightingdata = ht;
return &ht->thinker;
}
static thinker_t* LoadStrobeThinker(actionf_p1 thinker)
static thinker_t* LoadStrobeThinker(save_t *save_p, actionf_p1 thinker)
{
strobe_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->count = READINT32(save_p);
ht->minlight = READINT16(save_p);
ht->maxlight = READINT16(save_p);
ht->darktime = READINT32(save_p);
ht->brighttime = READINT32(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->count = P_ReadINT32(save_p);
ht->minlight = P_ReadINT16(save_p);
ht->maxlight = P_ReadINT16(save_p);
ht->darktime = P_ReadINT32(save_p);
ht->brighttime = P_ReadINT32(save_p);
if (ht->sector)
ht->sector->lightingdata = ht;
return &ht->thinker;
}
static thinker_t* LoadGlowThinker(actionf_p1 thinker)
static thinker_t* LoadGlowThinker(save_t *save_p, actionf_p1 thinker)
{
glow_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->minlight = READINT16(save_p);
ht->maxlight = READINT16(save_p);
ht->direction = READINT16(save_p);
ht->speed = READINT16(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->minlight = P_ReadINT16(save_p);
ht->maxlight = P_ReadINT16(save_p);
ht->direction = P_ReadINT16(save_p);
ht->speed = P_ReadINT16(save_p);
if (ht->sector)
ht->sector->lightingdata = ht;
return &ht->thinker;
}
static thinker_t* LoadFireflickerThinker(actionf_p1 thinker)
static thinker_t* LoadFireflickerThinker(save_t *save_p, actionf_p1 thinker)
{
fireflicker_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->count = READINT32(save_p);
ht->resetcount = READINT32(save_p);
ht->maxlight = READINT16(save_p);
ht->minlight = READINT16(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->count = P_ReadINT32(save_p);
ht->resetcount = P_ReadINT32(save_p);
ht->maxlight = P_ReadINT16(save_p);
ht->minlight = P_ReadINT16(save_p);
if (ht->sector)
ht->sector->lightingdata = ht;
return &ht->thinker;
}
static thinker_t* LoadElevatorThinker(actionf_p1 thinker, boolean setplanedata)
static thinker_t* LoadElevatorThinker(save_t *save_p, actionf_p1 thinker, boolean setplanedata)
{
elevator_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->type = READUINT8(save_p);
ht->sector = LoadSector(READUINT32(save_p));
ht->actionsector = LoadSector(READUINT32(save_p));
ht->direction = READINT32(save_p);
ht->floordestheight = READFIXED(save_p);
ht->ceilingdestheight = READFIXED(save_p);
ht->speed = READFIXED(save_p);
ht->origspeed = READFIXED(save_p);
ht->low = READFIXED(save_p);
ht->high = READFIXED(save_p);
ht->distance = READFIXED(save_p);
ht->delay = READFIXED(save_p);
ht->delaytimer = READFIXED(save_p);
ht->floorwasheight = READFIXED(save_p);
ht->ceilingwasheight = READFIXED(save_p);
ht->sourceline = LoadLine(READUINT32(save_p));
ht->type = P_ReadUINT8(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->actionsector = LoadSector(P_ReadUINT32(save_p));
ht->direction = P_ReadINT32(save_p);
ht->floordestheight = P_ReadFixed(save_p);
ht->ceilingdestheight = P_ReadFixed(save_p);
ht->speed = P_ReadFixed(save_p);
ht->origspeed = P_ReadFixed(save_p);
ht->low = P_ReadFixed(save_p);
ht->high = P_ReadFixed(save_p);
ht->distance = P_ReadFixed(save_p);
ht->delay = P_ReadFixed(save_p);
ht->delaytimer = P_ReadFixed(save_p);
ht->floorwasheight = P_ReadFixed(save_p);
ht->ceilingwasheight = P_ReadFixed(save_p);
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
if (ht->sector && setplanedata)
{
......@@ -3548,21 +3850,21 @@ static thinker_t* LoadElevatorThinker(actionf_p1 thinker, boolean setplanedata)
return &ht->thinker;
}
static thinker_t* LoadCrumbleThinker(actionf_p1 thinker)
static thinker_t* LoadCrumbleThinker(save_t *save_p, actionf_p1 thinker)
{
crumble_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sourceline = LoadLine(READUINT32(save_p));
ht->sector = LoadSector(READUINT32(save_p));
ht->actionsector = LoadSector(READUINT32(save_p));
ht->player = LoadPlayer(READUINT32(save_p));
ht->direction = READINT32(save_p);
ht->origalpha = READINT32(save_p);
ht->timer = READINT32(save_p);
ht->speed = READFIXED(save_p);
ht->floorwasheight = READFIXED(save_p);
ht->ceilingwasheight = READFIXED(save_p);
ht->flags = READUINT8(save_p);
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->actionsector = LoadSector(P_ReadUINT32(save_p));
ht->player = LoadPlayer(P_ReadUINT32(save_p));
ht->direction = P_ReadINT32(save_p);
ht->origalpha = P_ReadINT32(save_p);
ht->timer = P_ReadINT32(save_p);
ht->speed = P_ReadFixed(save_p);
ht->floorwasheight = P_ReadFixed(save_p);
ht->ceilingwasheight = P_ReadFixed(save_p);
ht->flags = P_ReadUINT8(save_p);
if (ht->sector)
ht->sector->floordata = ht;
......@@ -3570,123 +3872,123 @@ static thinker_t* LoadCrumbleThinker(actionf_p1 thinker)
return &ht->thinker;
}
static thinker_t* LoadScrollThinker(actionf_p1 thinker)
static thinker_t* LoadScrollThinker(save_t *save_p, actionf_p1 thinker)
{
scroll_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->dx = READFIXED(save_p);
ht->dy = READFIXED(save_p);
ht->affectee = READINT32(save_p);
ht->control = READINT32(save_p);
ht->last_height = READFIXED(save_p);
ht->vdx = READFIXED(save_p);
ht->vdy = READFIXED(save_p);
ht->accel = READINT32(save_p);
ht->exclusive = READINT32(save_p);
ht->type = READUINT8(save_p);
ht->dx = P_ReadFixed(save_p);
ht->dy = P_ReadFixed(save_p);
ht->affectee = P_ReadINT32(save_p);
ht->control = P_ReadINT32(save_p);
ht->last_height = P_ReadFixed(save_p);
ht->vdx = P_ReadFixed(save_p);
ht->vdy = P_ReadFixed(save_p);
ht->accel = P_ReadINT32(save_p);
ht->exclusive = P_ReadINT32(save_p);
ht->type = P_ReadUINT8(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadFrictionThinker(actionf_p1 thinker)
static inline thinker_t* LoadFrictionThinker(save_t *save_p, actionf_p1 thinker)
{
friction_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->friction = READINT32(save_p);
ht->movefactor = READINT32(save_p);
ht->affectee = READINT32(save_p);
ht->referrer = READINT32(save_p);
ht->roverfriction = READUINT8(save_p);
ht->friction = P_ReadINT32(save_p);
ht->movefactor = P_ReadINT32(save_p);
ht->affectee = P_ReadINT32(save_p);
ht->referrer = P_ReadINT32(save_p);
ht->roverfriction = P_ReadUINT8(save_p);
return &ht->thinker;
}
static thinker_t* LoadPusherThinker(actionf_p1 thinker)
static thinker_t* LoadPusherThinker(save_t *save_p, actionf_p1 thinker)
{
pusher_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->type = READUINT8(save_p);
ht->x_mag = READFIXED(save_p);
ht->y_mag = READFIXED(save_p);
ht->z_mag = READFIXED(save_p);
ht->affectee = READINT32(save_p);
ht->roverpusher = READUINT8(save_p);
ht->referrer = READINT32(save_p);
ht->exclusive = READINT32(save_p);
ht->slider = READINT32(save_p);
ht->type = P_ReadUINT8(save_p);
ht->x_mag = P_ReadFixed(save_p);
ht->y_mag = P_ReadFixed(save_p);
ht->z_mag = P_ReadFixed(save_p);
ht->affectee = P_ReadINT32(save_p);
ht->roverpusher = P_ReadUINT8(save_p);
ht->referrer = P_ReadINT32(save_p);
ht->exclusive = P_ReadINT32(save_p);
ht->slider = P_ReadINT32(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadLaserThinker(actionf_p1 thinker)
static inline thinker_t* LoadLaserThinker(save_t *save_p, actionf_p1 thinker)
{
laserthink_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->tag = READINT16(save_p);
ht->sourceline = LoadLine(READUINT32(save_p));
ht->nobosses = READUINT8(save_p);
ht->tag = P_ReadINT16(save_p);
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
ht->nobosses = P_ReadUINT8(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadLightlevelThinker(actionf_p1 thinker)
static inline thinker_t* LoadLightlevelThinker(save_t *save_p, actionf_p1 thinker)
{
lightlevel_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->sourcelevel = READINT16(save_p);
ht->destlevel = READINT16(save_p);
ht->fixedcurlevel = READFIXED(save_p);
ht->fixedpertic = READFIXED(save_p);
ht->timer = READINT32(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->sourcelevel = P_ReadINT16(save_p);
ht->destlevel = P_ReadINT16(save_p);
ht->fixedcurlevel = P_ReadFixed(save_p);
ht->fixedpertic = P_ReadFixed(save_p);
ht->timer = P_ReadINT32(save_p);
if (ht->sector)
ht->sector->lightingdata = ht;
return &ht->thinker;
}
static inline thinker_t* LoadExecutorThinker(actionf_p1 thinker)
static inline thinker_t* LoadExecutorThinker(save_t *save_p, actionf_p1 thinker)
{
executor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->line = LoadLine(READUINT32(save_p));
ht->caller = LoadMobj(READUINT32(save_p));
ht->sector = LoadSector(READUINT32(save_p));
ht->timer = READINT32(save_p);
ht->line = LoadLine(P_ReadUINT32(save_p));
ht->caller = LoadMobj(P_ReadUINT32(save_p));
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->timer = P_ReadINT32(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadDisappearThinker(actionf_p1 thinker)
static inline thinker_t* LoadDisappearThinker(save_t *save_p, actionf_p1 thinker)
{
disappear_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->appeartime = READUINT32(save_p);
ht->disappeartime = READUINT32(save_p);
ht->offset = READUINT32(save_p);
ht->timer = READUINT32(save_p);
ht->affectee = READINT32(save_p);
ht->sourceline = READINT32(save_p);
ht->exists = READINT32(save_p);
ht->appeartime = P_ReadUINT32(save_p);
ht->disappeartime = P_ReadUINT32(save_p);
ht->offset = P_ReadUINT32(save_p);
ht->timer = P_ReadUINT32(save_p);
ht->affectee = P_ReadINT32(save_p);
ht->sourceline = P_ReadINT32(save_p);
ht->exists = P_ReadINT32(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadFadeThinker(actionf_p1 thinker)
static inline thinker_t* LoadFadeThinker(save_t *save_p, actionf_p1 thinker)
{
sector_t *ss;
fade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->dest_exc = GetNetColormapFromList(READUINT32(save_p));
ht->sectornum = READUINT32(save_p);
ht->ffloornum = READUINT32(save_p);
ht->alpha = READINT32(save_p);
ht->sourcevalue = READINT16(save_p);
ht->destvalue = READINT16(save_p);
ht->destlightlevel = READINT16(save_p);
ht->speed = READINT16(save_p);
ht->ticbased = (boolean)READUINT8(save_p);
ht->timer = READINT32(save_p);
ht->doexists = READUINT8(save_p);
ht->dotranslucent = READUINT8(save_p);
ht->dolighting = READUINT8(save_p);
ht->docolormap = READUINT8(save_p);
ht->docollision = READUINT8(save_p);
ht->doghostfade = READUINT8(save_p);
ht->exactalpha = READUINT8(save_p);
ht->dest_exc = GetNetColormapFromList(P_ReadUINT32(save_p));
ht->sectornum = P_ReadUINT32(save_p);
ht->ffloornum = P_ReadUINT32(save_p);
ht->alpha = P_ReadINT32(save_p);
ht->sourcevalue = P_ReadINT16(save_p);
ht->destvalue = P_ReadINT16(save_p);
ht->destlightlevel = P_ReadINT16(save_p);
ht->speed = P_ReadINT16(save_p);
ht->ticbased = (boolean)P_ReadUINT8(save_p);
ht->timer = P_ReadINT32(save_p);
ht->doexists = P_ReadUINT8(save_p);
ht->dotranslucent = P_ReadUINT8(save_p);
ht->dolighting = P_ReadUINT8(save_p);
ht->docolormap = P_ReadUINT8(save_p);
ht->docollision = P_ReadUINT8(save_p);
ht->doghostfade = P_ReadUINT8(save_p);
ht->exactalpha = P_ReadUINT8(save_p);
ss = LoadSector(ht->sectornum);
if (ss)
......@@ -3707,176 +4009,176 @@ static inline thinker_t* LoadFadeThinker(actionf_p1 thinker)
return &ht->thinker;
}
static inline thinker_t* LoadFadeColormapThinker(actionf_p1 thinker)
static inline thinker_t* LoadFadeColormapThinker(save_t *save_p, actionf_p1 thinker)
{
fadecolormap_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->sector = LoadSector(READUINT32(save_p));
ht->source_exc = GetNetColormapFromList(READUINT32(save_p));
ht->dest_exc = GetNetColormapFromList(READUINT32(save_p));
ht->ticbased = (boolean)READUINT8(save_p);
ht->duration = READINT32(save_p);
ht->timer = READINT32(save_p);
ht->sector = LoadSector(P_ReadUINT32(save_p));
ht->source_exc = GetNetColormapFromList(P_ReadUINT32(save_p));
ht->dest_exc = GetNetColormapFromList(P_ReadUINT32(save_p));
ht->ticbased = (boolean)P_ReadUINT8(save_p);
ht->duration = P_ReadINT32(save_p);
ht->timer = P_ReadINT32(save_p);
if (ht->sector)
ht->sector->fadecolormapdata = ht;
return &ht->thinker;
}
static inline thinker_t* LoadPlaneDisplaceThinker(actionf_p1 thinker)
static inline thinker_t* LoadPlaneDisplaceThinker(save_t *save_p, actionf_p1 thinker)
{
planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->affectee = READINT32(save_p);
ht->control = READINT32(save_p);
ht->last_height = READFIXED(save_p);
ht->speed = READFIXED(save_p);
ht->type = READUINT8(save_p);
ht->affectee = P_ReadINT32(save_p);
ht->control = P_ReadINT32(save_p);
ht->last_height = P_ReadFixed(save_p);
ht->speed = P_ReadFixed(save_p);
ht->type = P_ReadUINT8(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadDynamicLineSlopeThinker(actionf_p1 thinker)
static inline thinker_t* LoadDynamicLineSlopeThinker(save_t *save_p, actionf_p1 thinker)
{
dynlineplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->type = READUINT8(save_p);
ht->slope = LoadSlope(READUINT32(save_p));
ht->sourceline = LoadLine(READUINT32(save_p));
ht->extent = READFIXED(save_p);
ht->type = P_ReadUINT8(save_p);
ht->slope = LoadSlope(P_ReadUINT32(save_p));
ht->sourceline = LoadLine(P_ReadUINT32(save_p));
ht->extent = P_ReadFixed(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadDynamicVertexSlopeThinker(actionf_p1 thinker)
static inline thinker_t* LoadDynamicVertexSlopeThinker(save_t *save_p, actionf_p1 thinker)
{
size_t i;
dynvertexplanethink_t* ht = Z_Malloc(sizeof(*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->slope = LoadSlope(READUINT32(save_p));
ht->slope = LoadSlope(P_ReadUINT32(save_p));
for (i = 0; i < 3; i++)
ht->secs[i] = LoadSector(READUINT32(save_p));
READMEM(save_p, ht->vex, sizeof(ht->vex));
READMEM(save_p, ht->origsecheights, sizeof(ht->origsecheights));
READMEM(save_p, ht->origvecheights, sizeof(ht->origvecheights));
ht->relative = READUINT8(save_p);
ht->secs[i] = LoadSector(P_ReadUINT32(save_p));
P_ReadMem(save_p, ht->vex, sizeof(ht->vex));
P_ReadMem(save_p, ht->origsecheights, sizeof(ht->origsecheights));
P_ReadMem(save_p, ht->origvecheights, sizeof(ht->origvecheights));
ht->relative = P_ReadUINT8(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadPolyrotatetThinker(actionf_p1 thinker)
static inline thinker_t* LoadPolyrotatetThinker(save_t *save_p, actionf_p1 thinker)
{
polyrotate_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->polyObjNum = READINT32(save_p);
ht->speed = READINT32(save_p);
ht->distance = READINT32(save_p);
ht->turnobjs = READUINT8(save_p);
ht->polyObjNum = P_ReadINT32(save_p);
ht->speed = P_ReadINT32(save_p);
ht->distance = P_ReadINT32(save_p);
ht->turnobjs = P_ReadUINT8(save_p);
return &ht->thinker;
}
static thinker_t* LoadPolymoveThinker(actionf_p1 thinker)
static thinker_t* LoadPolymoveThinker(save_t *save_p, actionf_p1 thinker)
{
polymove_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->polyObjNum = READINT32(save_p);
ht->speed = READINT32(save_p);
ht->momx = READFIXED(save_p);
ht->momy = READFIXED(save_p);
ht->distance = READINT32(save_p);
ht->angle = READANGLE(save_p);
ht->polyObjNum = P_ReadINT32(save_p);
ht->speed = P_ReadINT32(save_p);
ht->momx = P_ReadFixed(save_p);
ht->momy = P_ReadFixed(save_p);
ht->distance = P_ReadINT32(save_p);
ht->angle = P_ReadAngle(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker)
static inline thinker_t* LoadPolywaypointThinker(save_t *save_p, actionf_p1 thinker)
{
polywaypoint_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->polyObjNum = READINT32(save_p);
ht->speed = READINT32(save_p);
ht->sequence = READINT32(save_p);
ht->pointnum = READINT32(save_p);
ht->direction = READINT32(save_p);
ht->returnbehavior = READUINT8(save_p);
ht->continuous = READUINT8(save_p);
ht->stophere = READUINT8(save_p);
ht->polyObjNum = P_ReadINT32(save_p);
ht->speed = P_ReadINT32(save_p);
ht->sequence = P_ReadINT32(save_p);
ht->pointnum = P_ReadINT32(save_p);
ht->direction = P_ReadINT32(save_p);
ht->returnbehavior = P_ReadUINT8(save_p);
ht->continuous = P_ReadUINT8(save_p);
ht->stophere = P_ReadUINT8(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadPolyslidedoorThinker(actionf_p1 thinker)
static inline thinker_t* LoadPolyslidedoorThinker(save_t *save_p, actionf_p1 thinker)
{
polyslidedoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->polyObjNum = READINT32(save_p);
ht->delay = READINT32(save_p);
ht->delayCount = READINT32(save_p);
ht->initSpeed = READINT32(save_p);
ht->speed = READINT32(save_p);
ht->initDistance = READINT32(save_p);
ht->distance = READINT32(save_p);
ht->initAngle = READUINT32(save_p);
ht->angle = READUINT32(save_p);
ht->revAngle = READUINT32(save_p);
ht->momx = READFIXED(save_p);
ht->momy = READFIXED(save_p);
ht->closing = READUINT8(save_p);
ht->polyObjNum = P_ReadINT32(save_p);
ht->delay = P_ReadINT32(save_p);
ht->delayCount = P_ReadINT32(save_p);
ht->initSpeed = P_ReadINT32(save_p);
ht->speed = P_ReadINT32(save_p);
ht->initDistance = P_ReadINT32(save_p);
ht->distance = P_ReadINT32(save_p);
ht->initAngle = P_ReadUINT32(save_p);
ht->angle = P_ReadUINT32(save_p);
ht->revAngle = P_ReadUINT32(save_p);
ht->momx = P_ReadFixed(save_p);
ht->momy = P_ReadFixed(save_p);
ht->closing = P_ReadUINT8(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadPolyswingdoorThinker(actionf_p1 thinker)
static inline thinker_t* LoadPolyswingdoorThinker(save_t *save_p, actionf_p1 thinker)
{
polyswingdoor_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->polyObjNum = READINT32(save_p);
ht->delay = READINT32(save_p);
ht->delayCount = READINT32(save_p);
ht->initSpeed = READINT32(save_p);
ht->speed = READINT32(save_p);
ht->initDistance = READINT32(save_p);
ht->distance = READINT32(save_p);
ht->closing = READUINT8(save_p);
ht->polyObjNum = P_ReadINT32(save_p);
ht->delay = P_ReadINT32(save_p);
ht->delayCount = P_ReadINT32(save_p);
ht->initSpeed = P_ReadINT32(save_p);
ht->speed = P_ReadINT32(save_p);
ht->initDistance = P_ReadINT32(save_p);
ht->distance = P_ReadINT32(save_p);
ht->closing = P_ReadUINT8(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadPolydisplaceThinker(actionf_p1 thinker)
static inline thinker_t* LoadPolydisplaceThinker(save_t *save_p, actionf_p1 thinker)
{
polydisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->polyObjNum = READINT32(save_p);
ht->controlSector = LoadSector(READUINT32(save_p));
ht->dx = READFIXED(save_p);
ht->dy = READFIXED(save_p);
ht->oldHeights = READFIXED(save_p);
ht->polyObjNum = P_ReadINT32(save_p);
ht->controlSector = LoadSector(P_ReadUINT32(save_p));
ht->dx = P_ReadFixed(save_p);
ht->dy = P_ReadFixed(save_p);
ht->oldHeights = P_ReadFixed(save_p);
return &ht->thinker;
}
static inline thinker_t* LoadPolyrotdisplaceThinker(actionf_p1 thinker)
static inline thinker_t* LoadPolyrotdisplaceThinker(save_t *save_p, actionf_p1 thinker)
{
polyrotdisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->polyObjNum = READINT32(save_p);
ht->controlSector = LoadSector(READUINT32(save_p));
ht->rotscale = READFIXED(save_p);
ht->turnobjs = READUINT8(save_p);
ht->oldHeights = READFIXED(save_p);
ht->polyObjNum = P_ReadINT32(save_p);
ht->controlSector = LoadSector(P_ReadUINT32(save_p));
ht->rotscale = P_ReadFixed(save_p);
ht->turnobjs = P_ReadUINT8(save_p);
ht->oldHeights = P_ReadFixed(save_p);
return &ht->thinker;
}
static thinker_t* LoadPolyfadeThinker(actionf_p1 thinker)
static thinker_t* LoadPolyfadeThinker(save_t *save_p, actionf_p1 thinker)
{
polyfade_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL);
ht->thinker.function.acp1 = thinker;
ht->polyObjNum = READINT32(save_p);
ht->sourcevalue = READINT32(save_p);
ht->destvalue = READINT32(save_p);
ht->docollision = (boolean)READUINT8(save_p);
ht->doghostfade = (boolean)READUINT8(save_p);
ht->ticbased = (boolean)READUINT8(save_p);
ht->duration = READINT32(save_p);
ht->timer = READINT32(save_p);
ht->polyObjNum = P_ReadINT32(save_p);
ht->sourcevalue = P_ReadINT32(save_p);
ht->destvalue = P_ReadINT32(save_p);
ht->docollision = (boolean)P_ReadUINT8(save_p);
ht->doghostfade = (boolean)P_ReadUINT8(save_p);
ht->ticbased = (boolean)P_ReadUINT8(save_p);
ht->duration = P_ReadINT32(save_p);
ht->timer = P_ReadINT32(save_p);
return &ht->thinker;
}
static void P_NetUnArchiveThinkers(void)
static void P_NetUnArchiveThinkers(save_t *save_p)
{
thinker_t *currentthinker;
thinker_t *next;
......@@ -3885,7 +4187,7 @@ static void P_NetUnArchiveThinkers(void)
UINT32 i;
UINT32 numloaded = 0;
if (READUINT32(save_p) != ARCHIVEBLOCK_THINKERS)
if (P_ReadUINT32(save_p) != ARCHIVEBLOCK_THINKERS)
I_Error("Bad $$$.sav at archive block Thinkers");
// remove all the current thinkers
......@@ -3923,7 +4225,7 @@ static void P_NetUnArchiveThinkers(void)
for (;;)
{
thinker_t* th = NULL;
tclass = READUINT8(save_p);
tclass = P_ReadUINT8(save_p);
if (tclass == tc_end)
break; // leave the saved thinker reading loop
......@@ -3932,167 +4234,167 @@ static void P_NetUnArchiveThinkers(void)
switch (tclass)
{
case tc_mobj:
th = LoadMobjThinker((actionf_p1)P_MobjThinker);
th = LoadMobjThinker(save_p, (actionf_p1)P_MobjThinker);
break;
case tc_ceiling:
th = LoadCeilingThinker((actionf_p1)T_MoveCeiling);
th = LoadCeilingThinker(save_p, (actionf_p1)T_MoveCeiling);
break;
case tc_crushceiling:
th = LoadCeilingThinker((actionf_p1)T_CrushCeiling);
th = LoadCeilingThinker(save_p, (actionf_p1)T_CrushCeiling);
break;
case tc_floor:
th = LoadFloormoveThinker((actionf_p1)T_MoveFloor);
th = LoadFloormoveThinker(save_p, (actionf_p1)T_MoveFloor);
break;
case tc_flash:
th = LoadLightflashThinker((actionf_p1)T_LightningFlash);
th = LoadLightflashThinker(save_p, (actionf_p1)T_LightningFlash);
break;
case tc_strobe:
th = LoadStrobeThinker((actionf_p1)T_StrobeFlash);
th = LoadStrobeThinker(save_p, (actionf_p1)T_StrobeFlash);
break;
case tc_glow:
th = LoadGlowThinker((actionf_p1)T_Glow);
th = LoadGlowThinker(save_p, (actionf_p1)T_Glow);
break;
case tc_fireflicker:
th = LoadFireflickerThinker((actionf_p1)T_FireFlicker);
th = LoadFireflickerThinker(save_p, (actionf_p1)T_FireFlicker);
break;
case tc_elevator:
th = LoadElevatorThinker((actionf_p1)T_MoveElevator, true);
th = LoadElevatorThinker(save_p, (actionf_p1)T_MoveElevator, true);
break;
case tc_continuousfalling:
th = LoadContinuousFallThinker((actionf_p1)T_ContinuousFalling);
th = LoadContinuousFallThinker(save_p, (actionf_p1)T_ContinuousFalling);
break;
case tc_thwomp:
th = LoadThwompThinker((actionf_p1)T_ThwompSector);
th = LoadThwompThinker(save_p, (actionf_p1)T_ThwompSector);
break;
case tc_noenemies:
th = LoadNoEnemiesThinker((actionf_p1)T_NoEnemiesSector);
th = LoadNoEnemiesThinker(save_p, (actionf_p1)T_NoEnemiesSector);
break;
case tc_eachtime:
th = LoadEachTimeThinker((actionf_p1)T_EachTimeThinker);
th = LoadEachTimeThinker(save_p, (actionf_p1)T_EachTimeThinker);
break;
case tc_raisesector:
th = LoadRaiseThinker((actionf_p1)T_RaiseSector);
th = LoadRaiseThinker(save_p, (actionf_p1)T_RaiseSector);
break;
case tc_camerascanner:
th = LoadElevatorThinker((actionf_p1)T_CameraScanner, false);
th = LoadElevatorThinker(save_p, (actionf_p1)T_CameraScanner, false);
break;
case tc_bouncecheese:
th = LoadBounceCheeseThinker((actionf_p1)T_BounceCheese);
th = LoadBounceCheeseThinker(save_p, (actionf_p1)T_BounceCheese);
break;
case tc_startcrumble:
th = LoadCrumbleThinker((actionf_p1)T_StartCrumble);
th = LoadCrumbleThinker(save_p, (actionf_p1)T_StartCrumble);
break;
case tc_marioblock:
th = LoadMarioBlockThinker((actionf_p1)T_MarioBlock);
th = LoadMarioBlockThinker(save_p, (actionf_p1)T_MarioBlock);
break;
case tc_marioblockchecker:
th = LoadMarioCheckThinker((actionf_p1)T_MarioBlockChecker);
th = LoadMarioCheckThinker(save_p, (actionf_p1)T_MarioBlockChecker);
break;
case tc_floatsector:
th = LoadFloatThinker((actionf_p1)T_FloatSector);
th = LoadFloatThinker(save_p, (actionf_p1)T_FloatSector);
break;
case tc_laserflash:
th = LoadLaserThinker((actionf_p1)T_LaserFlash);
th = LoadLaserThinker(save_p, (actionf_p1)T_LaserFlash);
break;
case tc_lightfade:
th = LoadLightlevelThinker((actionf_p1)T_LightFade);
th = LoadLightlevelThinker(save_p, (actionf_p1)T_LightFade);
break;
case tc_executor:
th = LoadExecutorThinker((actionf_p1)T_ExecutorDelay);
th = LoadExecutorThinker(save_p, (actionf_p1)T_ExecutorDelay);
restoreNum = true;
break;
case tc_disappear:
th = LoadDisappearThinker((actionf_p1)T_Disappear);
th = LoadDisappearThinker(save_p, (actionf_p1)T_Disappear);
break;
case tc_fade:
th = LoadFadeThinker((actionf_p1)T_Fade);
th = LoadFadeThinker(save_p, (actionf_p1)T_Fade);
break;
case tc_fadecolormap:
th = LoadFadeColormapThinker((actionf_p1)T_FadeColormap);
th = LoadFadeColormapThinker(save_p, (actionf_p1)T_FadeColormap);
break;
case tc_planedisplace:
th = LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace);
th = LoadPlaneDisplaceThinker(save_p, (actionf_p1)T_PlaneDisplace);
break;
case tc_polyrotate:
th = LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate);
th = LoadPolyrotatetThinker(save_p, (actionf_p1)T_PolyObjRotate);
break;
case tc_polymove:
th = LoadPolymoveThinker((actionf_p1)T_PolyObjMove);
th = LoadPolymoveThinker(save_p, (actionf_p1)T_PolyObjMove);
break;
case tc_polywaypoint:
th = LoadPolywaypointThinker((actionf_p1)T_PolyObjWaypoint);
th = LoadPolywaypointThinker(save_p, (actionf_p1)T_PolyObjWaypoint);
break;
case tc_polyslidedoor:
th = LoadPolyslidedoorThinker((actionf_p1)T_PolyDoorSlide);
th = LoadPolyslidedoorThinker(save_p, (actionf_p1)T_PolyDoorSlide);
break;
case tc_polyswingdoor:
th = LoadPolyswingdoorThinker((actionf_p1)T_PolyDoorSwing);
th = LoadPolyswingdoorThinker(save_p, (actionf_p1)T_PolyDoorSwing);
break;
case tc_polyflag:
th = LoadPolymoveThinker((actionf_p1)T_PolyObjFlag);
th = LoadPolymoveThinker(save_p, (actionf_p1)T_PolyObjFlag);
break;
case tc_polydisplace:
th = LoadPolydisplaceThinker((actionf_p1)T_PolyObjDisplace);
th = LoadPolydisplaceThinker(save_p, (actionf_p1)T_PolyObjDisplace);
break;
case tc_polyrotdisplace:
th = LoadPolyrotdisplaceThinker((actionf_p1)T_PolyObjRotDisplace);
th = LoadPolyrotdisplaceThinker(save_p, (actionf_p1)T_PolyObjRotDisplace);
break;
case tc_polyfade:
th = LoadPolyfadeThinker((actionf_p1)T_PolyObjFade);
th = LoadPolyfadeThinker(save_p, (actionf_p1)T_PolyObjFade);
break;
case tc_dynslopeline:
th = LoadDynamicLineSlopeThinker((actionf_p1)T_DynamicSlopeLine);
th = LoadDynamicLineSlopeThinker(save_p, (actionf_p1)T_DynamicSlopeLine);
break;
case tc_dynslopevert:
th = LoadDynamicVertexSlopeThinker((actionf_p1)T_DynamicSlopeVert);
th = LoadDynamicVertexSlopeThinker(save_p, (actionf_p1)T_DynamicSlopeVert);
break;
case tc_scroll:
th = LoadScrollThinker((actionf_p1)T_Scroll);
th = LoadScrollThinker(save_p, (actionf_p1)T_Scroll);
break;
case tc_friction:
th = LoadFrictionThinker((actionf_p1)T_Friction);
th = LoadFrictionThinker(save_p, (actionf_p1)T_Friction);
break;
case tc_pusher:
th = LoadPusherThinker((actionf_p1)T_Pusher);
th = LoadPusherThinker(save_p, (actionf_p1)T_Pusher);
break;
default:
......@@ -4132,29 +4434,29 @@ static void P_NetUnArchiveThinkers(void)
#define PD_FLAGS 0x01
#define PD_TRANS 0x02
static inline void P_ArchivePolyObj(polyobj_t *po)
static inline void P_ArchivePolyObj(save_t *save_p, polyobj_t *po)
{
UINT8 diff = 0;
WRITEINT32(save_p, po->id);
WRITEANGLE(save_p, po->angle);
P_WriteINT32(save_p, po->id);
P_WriteAngle(save_p, po->angle);
WRITEFIXED(save_p, po->spawnSpot.x);
WRITEFIXED(save_p, po->spawnSpot.y);
P_WriteFixed(save_p, po->spawnSpot.x);
P_WriteFixed(save_p, po->spawnSpot.y);
if (po->flags != po->spawnflags)
diff |= PD_FLAGS;
if (po->translucency != po->spawntrans)
diff |= PD_TRANS;
WRITEUINT8(save_p, diff);
P_WriteUINT8(save_p, diff);
if (diff & PD_FLAGS)
WRITEINT32(save_p, po->flags);
P_WriteINT32(save_p, po->flags);
if (diff & PD_TRANS)
WRITEINT32(save_p, po->translucency);
P_WriteINT32(save_p, po->translucency);
}
static inline void P_UnArchivePolyObj(polyobj_t *po)
static inline void P_UnArchivePolyObj(save_t *save_p, polyobj_t *po)
{
INT32 id;
UINT32 angle;
......@@ -4166,19 +4468,19 @@ static inline void P_UnArchivePolyObj(polyobj_t *po)
// when they first start to run.
po->thinker = NULL;
id = READINT32(save_p);
id = P_ReadINT32(save_p);
angle = READANGLE(save_p);
angle = P_ReadAngle(save_p);
x = READFIXED(save_p);
y = READFIXED(save_p);
x = P_ReadFixed(save_p);
y = P_ReadFixed(save_p);
diff = READUINT8(save_p);
diff = P_ReadUINT8(save_p);
if (diff & PD_FLAGS)
po->flags = READINT32(save_p);
po->flags = P_ReadINT32(save_p);
if (diff & PD_TRANS)
po->translucency = READINT32(save_p);
po->translucency = P_ReadINT32(save_p);
// if the object is bad or isn't in the id hash, we can do nothing more
// with it, so return now
......@@ -4189,33 +4491,33 @@ static inline void P_UnArchivePolyObj(polyobj_t *po)
Polyobj_MoveOnLoad(po, angle, x, y);
}
static inline void P_ArchivePolyObjects(void)
static inline void P_ArchivePolyObjects(save_t *save_p)
{
INT32 i;
WRITEUINT32(save_p, ARCHIVEBLOCK_POBJS);
P_WriteUINT32(save_p, ARCHIVEBLOCK_POBJS);
// save number of polyobjects
WRITEINT32(save_p, numPolyObjects);
P_WriteINT32(save_p, numPolyObjects);
for (i = 0; i < numPolyObjects; ++i)
P_ArchivePolyObj(&PolyObjects[i]);
P_ArchivePolyObj(save_p, &PolyObjects[i]);
}
static inline void P_UnArchivePolyObjects(void)
static inline void P_UnArchivePolyObjects(save_t *save_p)
{
INT32 i, numSavedPolys;
if (READUINT32(save_p) != ARCHIVEBLOCK_POBJS)
if (P_ReadUINT32(save_p) != ARCHIVEBLOCK_POBJS)
I_Error("Bad $$$.sav at archive block Pobjs");
numSavedPolys = READINT32(save_p);
numSavedPolys = P_ReadINT32(save_p);
if (numSavedPolys != numPolyObjects)
I_Error("P_UnArchivePolyObjects: polyobj count inconsistency\n");
for (i = 0; i < numSavedPolys; ++i)
P_UnArchivePolyObj(&PolyObjects[i]);
P_UnArchivePolyObj(save_p, &PolyObjects[i]);
}
static inline void P_FinishMobjs(void)
......@@ -4227,7 +4529,7 @@ static inline void P_FinishMobjs(void)
for (currentthinker = thlist[THINK_MOBJ].next; currentthinker != &thlist[THINK_MOBJ];
currentthinker = currentthinker->next)
{
if (currentthinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (currentthinker->removing)
continue;
mobj = (mobj_t *)currentthinker;
......@@ -4245,7 +4547,7 @@ static void P_RelinkPointers(void)
for (currentthinker = thlist[THINK_MOBJ].next; currentthinker != &thlist[THINK_MOBJ];
currentthinker = currentthinker->next)
{
if (currentthinker->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (currentthinker->removing)
continue;
mobj = (mobj_t *)currentthinker;
......@@ -4333,11 +4635,11 @@ static void P_RelinkPointers(void)
}
}
static inline void P_NetArchiveSpecials(void)
static inline void P_NetArchiveSpecials(save_t *save_p)
{
size_t i, z;
WRITEUINT32(save_p, ARCHIVEBLOCK_SPECIALS);
P_WriteUINT32(save_p, ARCHIVEBLOCK_SPECIALS);
// itemrespawn queue for deathmatch
i = iquetail;
......@@ -4347,53 +4649,54 @@ static inline void P_NetArchiveSpecials(void)
{
if (&mapthings[z] == itemrespawnque[i])
{
WRITEUINT32(save_p, z);
P_WriteUINT32(save_p, z);
break;
}
}
WRITEUINT32(save_p, itemrespawntime[i]);
P_WriteUINT32(save_p, itemrespawntime[i]);
i = (i + 1) & (ITEMQUESIZE-1);
}
// end delimiter
WRITEUINT32(save_p, 0xffffffff);
P_WriteUINT32(save_p, 0xffffffff);
// Sky number
WRITEINT32(save_p, globallevelskynum);
P_WriteINT32(save_p, globallevelskynum);
// Current global weather type
WRITEUINT8(save_p, globalweather);
P_WriteUINT8(save_p, globalweather);
if (metalplayback) // Is metal sonic running?
{
WRITEUINT8(save_p, 0x01);
G_SaveMetal(&save_p);
UINT8 *p = &save_p->buf[save_p->pos+1];
P_WriteUINT8(save_p, 0x01);
G_SaveMetal(&p);
}
else
WRITEUINT8(save_p, 0x00);
P_WriteUINT8(save_p, 0x00);
}
static void P_NetUnArchiveSpecials(void)
static void P_NetUnArchiveSpecials(save_t *save_p)
{
size_t i;
INT32 j;
if (READUINT32(save_p) != ARCHIVEBLOCK_SPECIALS)
if (P_ReadUINT32(save_p) != ARCHIVEBLOCK_SPECIALS)
I_Error("Bad $$$.sav at archive block Specials");
// BP: added save itemrespawn queue for deathmatch
iquetail = iquehead = 0;
while ((i = READUINT32(save_p)) != 0xffffffff)
while ((i = P_ReadUINT32(save_p)) != 0xffffffff)
{
itemrespawnque[iquehead] = &mapthings[i];
itemrespawntime[iquehead++] = READINT32(save_p);
itemrespawntime[iquehead++] = P_ReadINT32(save_p);
}
j = READINT32(save_p);
j = P_ReadINT32(save_p);
if (j != globallevelskynum)
P_SetupLevelSky(j, true);
globalweather = READUINT8(save_p);
globalweather = P_ReadUINT8(save_p);
if (globalweather)
{
......@@ -4408,14 +4711,17 @@ static void P_NetUnArchiveSpecials(void)
P_SwitchWeather(globalweather);
}
if (READUINT8(save_p) == 0x01) // metal sonic
G_LoadMetal(&save_p);
if (P_ReadUINT8(save_p) == 0x01) // metal sonic
{
UINT8 *p = &save_p->buf[save_p->pos];
G_LoadMetal(&p);
}
}
// =======================================================================
// Misc
// =======================================================================
static inline void P_ArchiveMisc(INT16 mapnum)
static inline void P_ArchiveMisc(save_t *save_p, INT16 mapnum)
{
//lastmapsaved = mapnum;
lastmaploaded = mapnum;
......@@ -4423,16 +4729,16 @@ static inline void P_ArchiveMisc(INT16 mapnum)
if (gamecomplete)
mapnum |= 8192;
WRITEINT16(save_p, mapnum);
WRITEUINT16(save_p, emeralds+357);
WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder));
P_WriteINT16(save_p, mapnum);
P_WriteUINT16(save_p, emeralds+357);
P_WriteStringN(save_p, timeattackfolder, sizeof(timeattackfolder));
}
static inline void P_UnArchiveSPGame(INT16 mapoverride)
static inline void P_UnArchiveSPGame(save_t *save_p, INT16 mapoverride)
{
char testname[sizeof(timeattackfolder)];
gamemap = READINT16(save_p);
gamemap = P_ReadINT16(save_p);
if (mapoverride != 0)
{
......@@ -4453,9 +4759,9 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
tokenlist = 0;
token = 0;
savedata.emeralds = READUINT16(save_p)-357;
savedata.emeralds = P_ReadUINT16(save_p)-357;
READSTRINGN(save_p, testname, sizeof(testname));
P_ReadStringN(save_p, testname, sizeof(testname));
if (strcmp(testname, timeattackfolder))
{
......@@ -4469,100 +4775,108 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
playeringame[consoleplayer] = true;
}
static void P_NetArchiveMisc(boolean resending)
static void P_NetArchiveMisc(save_t *save_p, boolean resending)
{
INT32 i;
WRITEUINT32(save_p, ARCHIVEBLOCK_MISC);
P_WriteUINT32(save_p, ARCHIVEBLOCK_MISC);
if (resending)
WRITEUINT32(save_p, gametic);
WRITEINT16(save_p, gamemap);
P_WriteUINT32(save_p, gametic);
P_WriteINT16(save_p, gamemap);
if (gamestate != GS_LEVEL)
WRITEINT16(save_p, GS_WAITINGPLAYERS); // nice hack to put people back into waitingplayers
P_WriteINT16(save_p, GS_WAITINGPLAYERS); // nice hack to put people back into waitingplayers
else
WRITEINT16(save_p, gamestate);
WRITEINT16(save_p, gametype);
P_WriteINT16(save_p, gamestate);
P_WriteINT16(save_p, gametype);
{
UINT32 pig = 0;
for (i = 0; i < MAXPLAYERS; i++)
pig |= (playeringame[i] != 0)<<i;
WRITEUINT32(save_p, pig);
P_WriteUINT32(save_p, pig);
}
WRITEUINT32(save_p, P_GetRandSeed());
P_WriteUINT32(save_p, P_GetRandSeed());
WRITEUINT32(save_p, tokenlist);
P_WriteUINT32(save_p, tokenlist);
WRITEUINT32(save_p, leveltime);
WRITEUINT32(save_p, ssspheres);
WRITEINT16(save_p, lastmap);
WRITEUINT16(save_p, bossdisabled);
P_WriteUINT32(save_p, leveltime);
P_WriteUINT32(save_p, ssspheres);
P_WriteINT16(save_p, lastmap);
P_WriteUINT16(save_p, bossdisabled);
WRITEUINT16(save_p, emeralds);
P_WriteUINT16(save_p, emeralds);
{
UINT8 globools = 0;
if (stagefailed)
globools |= 1;
if (stoppedclock)
globools |= (1<<1);
WRITEUINT8(save_p, globools);
P_WriteUINT8(save_p, globools);
}
WRITEUINT32(save_p, token);
WRITEINT32(save_p, sstimer);
WRITEUINT32(save_p, bluescore);
WRITEUINT32(save_p, redscore);
P_WriteUINT32(save_p, token);
P_WriteINT32(save_p, sstimer);
P_WriteUINT32(save_p, bluescore);
P_WriteUINT32(save_p, redscore);
P_WriteUINT16(save_p, skincolor_redteam);
P_WriteUINT16(save_p, skincolor_blueteam);
P_WriteUINT16(save_p, skincolor_redring);
P_WriteUINT16(save_p, skincolor_bluering);
WRITEUINT16(save_p, skincolor_redteam);
WRITEUINT16(save_p, skincolor_blueteam);
WRITEUINT16(save_p, skincolor_redring);
WRITEUINT16(save_p, skincolor_bluering);
P_WriteINT32(save_p, nummaprings);
WRITEINT32(save_p, modulothing);
P_WriteINT32(save_p, modulothing);
WRITEINT16(save_p, autobalance);
WRITEINT16(save_p, teamscramble);
P_WriteINT16(save_p, autobalance);
P_WriteINT16(save_p, teamscramble);
for (i = 0; i < MAXPLAYERS; i++)
WRITEINT16(save_p, scrambleplayers[i]);
P_WriteINT16(save_p, scrambleplayers[i]);
for (i = 0; i < MAXPLAYERS; i++)
WRITEINT16(save_p, scrambleteams[i]);
P_WriteINT16(save_p, scrambleteams[i]);
WRITEINT16(save_p, scrambletotal);
WRITEINT16(save_p, scramblecount);
P_WriteINT16(save_p, scrambletotal);
P_WriteINT16(save_p, scramblecount);
WRITEUINT32(save_p, countdown);
WRITEUINT32(save_p, countdown2);
P_WriteUINT32(save_p, countdown);
P_WriteUINT32(save_p, countdown2);
WRITEFIXED(save_p, gravity);
P_WriteFixed(save_p, gravity);
WRITEUINT32(save_p, countdowntimer);
WRITEUINT8(save_p, countdowntimeup);
P_WriteUINT32(save_p, countdowntimer);
P_WriteUINT8(save_p, countdowntimeup);
WRITEUINT32(save_p, hidetime);
P_WriteUINT32(save_p, hidetime);
// Is it paused?
if (paused)
WRITEUINT8(save_p, 0x2f);
P_WriteUINT8(save_p, 0x2f);
else
WRITEUINT8(save_p, 0x2e);
P_WriteUINT8(save_p, 0x2e);
for (i = 0; i < MAXPLAYERS; i++)
{
P_WriteUINT8(save_p, spam_tokens[i]);
P_WriteUINT32(save_p, spam_tics[i]);
}
}
static inline boolean P_NetUnArchiveMisc(boolean reloading)
static inline boolean P_NetUnArchiveMisc(save_t *save_p, boolean reloading)
{
INT32 i;
if (READUINT32(save_p) != ARCHIVEBLOCK_MISC)
if (P_ReadUINT32(save_p) != ARCHIVEBLOCK_MISC)
I_Error("Bad $$$.sav at archive block Misc");
if (reloading)
gametic = READUINT32(save_p);
gametic = P_ReadUINT32(save_p);
gamemap = READINT16(save_p);
gamemap = P_ReadINT16(save_p);
// gamemap changed; we assume that its map header is always valid,
// so make it so
......@@ -4573,12 +4887,12 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
// normally sets this flag
mapmusflags |= MUSIC_RELOADRESET;
G_SetGamestate(READINT16(save_p));
G_SetGamestate(P_ReadINT16(save_p));
gametype = READINT16(save_p);
gametype = P_ReadINT16(save_p);
{
UINT32 pig = READUINT32(save_p);
UINT32 pig = P_ReadUINT32(save_p);
for (i = 0; i < MAXPLAYERS; i++)
{
playeringame[i] = (pig & (1<<i)) != 0;
......@@ -4586,9 +4900,9 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
}
}
P_SetRandSeed(READUINT32(save_p));
P_SetRandSeed(P_ReadUINT32(save_p));
tokenlist = READUINT32(save_p);
tokenlist = P_ReadUINT32(save_p);
if (!P_LoadLevel(true, reloading))
{
......@@ -4597,83 +4911,91 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
}
// get the time
leveltime = READUINT32(save_p);
ssspheres = READUINT32(save_p);
lastmap = READINT16(save_p);
bossdisabled = READUINT16(save_p);
leveltime = P_ReadUINT32(save_p);
ssspheres = P_ReadUINT32(save_p);
lastmap = P_ReadINT16(save_p);
bossdisabled = P_ReadUINT16(save_p);
emeralds = READUINT16(save_p);
emeralds = P_ReadUINT16(save_p);
{
UINT8 globools = READUINT8(save_p);
UINT8 globools = P_ReadUINT8(save_p);
stagefailed = !!(globools & 1);
stoppedclock = !!(globools & (1<<1));
}
token = READUINT32(save_p);
sstimer = READINT32(save_p);
bluescore = READUINT32(save_p);
redscore = READUINT32(save_p);
token = P_ReadUINT32(save_p);
sstimer = P_ReadINT32(save_p);
bluescore = P_ReadUINT32(save_p);
redscore = P_ReadUINT32(save_p);
skincolor_redteam = P_ReadUINT16(save_p);
skincolor_blueteam = P_ReadUINT16(save_p);
skincolor_redring = P_ReadUINT16(save_p);
skincolor_bluering = P_ReadUINT16(save_p);
skincolor_redteam = READUINT16(save_p);
skincolor_blueteam = READUINT16(save_p);
skincolor_redring = READUINT16(save_p);
skincolor_bluering = READUINT16(save_p);
nummaprings = P_ReadINT32(save_p);
modulothing = READINT32(save_p);
modulothing = P_ReadINT32(save_p);
autobalance = READINT16(save_p);
teamscramble = READINT16(save_p);
autobalance = P_ReadINT16(save_p);
teamscramble = P_ReadINT16(save_p);
for (i = 0; i < MAXPLAYERS; i++)
scrambleplayers[i] = READINT16(save_p);
scrambleplayers[i] = P_ReadINT16(save_p);
for (i = 0; i < MAXPLAYERS; i++)
scrambleteams[i] = READINT16(save_p);
scrambleteams[i] = P_ReadINT16(save_p);
scrambletotal = READINT16(save_p);
scramblecount = READINT16(save_p);
scrambletotal = P_ReadINT16(save_p);
scramblecount = P_ReadINT16(save_p);
countdown = READUINT32(save_p);
countdown2 = READUINT32(save_p);
countdown = P_ReadUINT32(save_p);
countdown2 = P_ReadUINT32(save_p);
gravity = READFIXED(save_p);
gravity = P_ReadFixed(save_p);
countdowntimer = (tic_t)READUINT32(save_p);
countdowntimeup = (boolean)READUINT8(save_p);
countdowntimer = (tic_t)P_ReadUINT32(save_p);
countdowntimeup = (boolean)P_ReadUINT8(save_p);
hidetime = READUINT32(save_p);
hidetime = P_ReadUINT32(save_p);
// Is it paused?
if (READUINT8(save_p) == 0x2f)
if (P_ReadUINT8(save_p) == 0x2f)
paused = true;
for (i = 0; i < MAXPLAYERS; i++)
{
spam_tokens[i] = P_ReadUINT8(save_p);
spam_tics[i] = P_ReadUINT32(save_p);
}
return true;
}
static inline void P_NetArchiveEmblems(void)
static inline void P_NetArchiveEmblems(save_t *save_p)
{
gamedata_t *data = serverGamedata;
INT32 i, j;
UINT8 btemp;
INT32 curmare;
WRITEUINT32(save_p, ARCHIVEBLOCK_EMBLEMS);
P_WriteUINT32(save_p, ARCHIVEBLOCK_EMBLEMS);
// These should be synchronized before savegame loading by the wad files being the same anyway,
// but just in case, for now, we'll leave them here for testing. It would be very bad if they mismatch.
WRITEUINT8(save_p, (UINT8)savemoddata);
WRITEINT32(save_p, numemblems);
WRITEINT32(save_p, numextraemblems);
P_WriteUINT8(save_p, (UINT8)savemoddata);
P_WriteINT32(save_p, numemblems);
P_WriteINT32(save_p, numextraemblems);
// The rest of this is lifted straight from G_SaveGameData in g_game.c
// TODO: Optimize this to only send information about emblems, unlocks, etc. which actually exist
// There is no need to go all the way up to MAXEMBLEMS when wads are guaranteed to be the same.
WRITEUINT32(save_p, data->totalplaytime);
P_WriteUINT32(save_p, data->totalplaytime);
// TODO put another cipher on these things? meh, I don't care...
for (i = 0; i < NUMMAPS; i++)
WRITEUINT8(save_p, (data->mapvisited[i] & MV_MAX));
P_WriteUINT8(save_p, (data->mapvisited[i] & MV_MAX));
// To save space, use one bit per collected/achieved/unlocked flag
for (i = 0; i < MAXEMBLEMS;)
......@@ -4681,7 +5003,7 @@ static inline void P_NetArchiveEmblems(void)
btemp = 0;
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
btemp |= (data->collected[j+i] << j);
WRITEUINT8(save_p, btemp);
P_WriteUINT8(save_p, btemp);
i += j;
}
for (i = 0; i < MAXEXTRAEMBLEMS;)
......@@ -4689,7 +5011,7 @@ static inline void P_NetArchiveEmblems(void)
btemp = 0;
for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j)
btemp |= (data->extraCollected[j+i] << j);
WRITEUINT8(save_p, btemp);
P_WriteUINT8(save_p, btemp);
i += j;
}
for (i = 0; i < MAXUNLOCKABLES;)
......@@ -4697,7 +5019,7 @@ static inline void P_NetArchiveEmblems(void)
btemp = 0;
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
btemp |= (data->unlocked[j+i] << j);
WRITEUINT8(save_p, btemp);
P_WriteUINT8(save_p, btemp);
i += j;
}
for (i = 0; i < MAXCONDITIONSETS;)
......@@ -4705,28 +5027,28 @@ static inline void P_NetArchiveEmblems(void)
btemp = 0;
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
btemp |= (data->achieved[j+i] << j);
WRITEUINT8(save_p, btemp);
P_WriteUINT8(save_p, btemp);
i += j;
}
WRITEUINT32(save_p, data->timesBeaten);
WRITEUINT32(save_p, data->timesBeatenWithEmeralds);
WRITEUINT32(save_p, data->timesBeatenUltimate);
P_WriteUINT32(save_p, data->timesBeaten);
P_WriteUINT32(save_p, data->timesBeatenWithEmeralds);
P_WriteUINT32(save_p, data->timesBeatenUltimate);
// Main records
for (i = 0; i < NUMMAPS; i++)
{
if (data->mainrecords[i])
{
WRITEUINT32(save_p, data->mainrecords[i]->score);
WRITEUINT32(save_p, data->mainrecords[i]->time);
WRITEUINT16(save_p, data->mainrecords[i]->rings);
P_WriteUINT32(save_p, data->mainrecords[i]->score);
P_WriteUINT32(save_p, data->mainrecords[i]->time);
P_WriteUINT16(save_p, data->mainrecords[i]->rings);
}
else
{
WRITEUINT32(save_p, 0);
WRITEUINT32(save_p, 0);
WRITEUINT16(save_p, 0);
P_WriteUINT32(save_p, 0);
P_WriteUINT32(save_p, 0);
P_WriteUINT16(save_p, 0);
}
}
......@@ -4735,43 +5057,43 @@ static inline void P_NetArchiveEmblems(void)
{
if (!data->nightsrecords[i] || !data->nightsrecords[i]->nummares)
{
WRITEUINT8(save_p, 0);
P_WriteUINT8(save_p, 0);
continue;
}
WRITEUINT8(save_p, data->nightsrecords[i]->nummares);
P_WriteUINT8(save_p, data->nightsrecords[i]->nummares);
for (curmare = 0; curmare < (data->nightsrecords[i]->nummares + 1); ++curmare)
{
WRITEUINT32(save_p, data->nightsrecords[i]->score[curmare]);
WRITEUINT8(save_p, data->nightsrecords[i]->grade[curmare]);
WRITEUINT32(save_p, data->nightsrecords[i]->time[curmare]);
P_WriteUINT32(save_p, data->nightsrecords[i]->score[curmare]);
P_WriteUINT8(save_p, data->nightsrecords[i]->grade[curmare]);
P_WriteUINT32(save_p, data->nightsrecords[i]->time[curmare]);
}
}
// Mid-map stuff
WRITEUINT32(save_p, unlocktriggers);
P_WriteUINT32(save_p, unlocktriggers);
for (i = 0; i < MAXPLAYERS; i++)
{
if (!ntemprecords[i].nummares)
{
WRITEUINT8(save_p, 0);
P_WriteUINT8(save_p, 0);
continue;
}
WRITEUINT8(save_p, ntemprecords[i].nummares);
P_WriteUINT8(save_p, ntemprecords[i].nummares);
for (curmare = 0; curmare < (ntemprecords[i].nummares + 1); ++curmare)
{
WRITEUINT32(save_p, ntemprecords[i].score[curmare]);
WRITEUINT8(save_p, ntemprecords[i].grade[curmare]);
WRITEUINT32(save_p, ntemprecords[i].time[curmare]);
P_WriteUINT32(save_p, ntemprecords[i].score[curmare]);
P_WriteUINT8(save_p, ntemprecords[i].grade[curmare]);
P_WriteUINT32(save_p, ntemprecords[i].time[curmare]);
}
}
}
static inline void P_NetUnArchiveEmblems(void)
static inline void P_NetUnArchiveEmblems(save_t *save_p)
{
gamedata_t *data = serverGamedata;
INT32 i, j;
......@@ -4782,14 +5104,14 @@ static inline void P_NetUnArchiveEmblems(void)
UINT8 recmares;
INT32 curmare;
if (READUINT32(save_p) != ARCHIVEBLOCK_EMBLEMS)
if (P_ReadUINT32(save_p) != ARCHIVEBLOCK_EMBLEMS)
I_Error("Bad $$$.sav at archive block Emblems");
savemoddata = (boolean)READUINT8(save_p); // this one is actually necessary because savemoddata stays false otherwise for some reason.
savemoddata = (boolean)P_ReadUINT8(save_p); // this one is actually necessary because savemoddata stays false otherwise for some reason.
if (numemblems != READINT32(save_p))
if (numemblems != P_ReadINT32(save_p))
I_Error("Bad $$$.sav dearchiving Emblems (numemblems mismatch)");
if (numextraemblems != READINT32(save_p))
if (numextraemblems != P_ReadINT32(save_p))
I_Error("Bad $$$.sav dearchiving Emblems (numextraemblems mismatch)");
// This shouldn't happen, but if something really fucked up happens and you transfer
......@@ -4804,53 +5126,53 @@ static inline void P_NetUnArchiveEmblems(void)
// TODO: Optimize this to only read information about emblems, unlocks, etc. which actually exist
// There is no need to go all the way up to MAXEMBLEMS when wads are guaranteed to be the same.
data->totalplaytime = READUINT32(save_p);
data->totalplaytime = P_ReadUINT32(save_p);
// TODO put another cipher on these things? meh, I don't care...
for (i = 0; i < NUMMAPS; i++)
if ((data->mapvisited[i] = READUINT8(save_p)) > MV_MAX)
if ((data->mapvisited[i] = P_ReadUINT8(save_p)) > MV_MAX)
I_Error("Bad $$$.sav dearchiving Emblems (invalid visit flags)");
// To save space, use one bit per collected/achieved/unlocked flag
for (i = 0; i < MAXEMBLEMS;)
{
rtemp = READUINT8(save_p);
rtemp = P_ReadUINT8(save_p);
for (j = 0; j < 8 && j+i < MAXEMBLEMS; ++j)
data->collected[j+i] = ((rtemp >> j) & 1);
i += j;
}
for (i = 0; i < MAXEXTRAEMBLEMS;)
{
rtemp = READUINT8(save_p);
rtemp = P_ReadUINT8(save_p);
for (j = 0; j < 8 && j+i < MAXEXTRAEMBLEMS; ++j)
data->extraCollected[j+i] = ((rtemp >> j) & 1);
i += j;
}
for (i = 0; i < MAXUNLOCKABLES;)
{
rtemp = READUINT8(save_p);
rtemp = P_ReadUINT8(save_p);
for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j)
data->unlocked[j+i] = ((rtemp >> j) & 1);
i += j;
}
for (i = 0; i < MAXCONDITIONSETS;)
{
rtemp = READUINT8(save_p);
rtemp = P_ReadUINT8(save_p);
for (j = 0; j < 8 && j+i < MAXCONDITIONSETS; ++j)
data->achieved[j+i] = ((rtemp >> j) & 1);
i += j;
}
data->timesBeaten = READUINT32(save_p);
data->timesBeatenWithEmeralds = READUINT32(save_p);
data->timesBeatenUltimate = READUINT32(save_p);
data->timesBeaten = P_ReadUINT32(save_p);
data->timesBeatenWithEmeralds = P_ReadUINT32(save_p);
data->timesBeatenUltimate = P_ReadUINT32(save_p);
// Main records
for (i = 0; i < NUMMAPS; ++i)
{
recscore = READUINT32(save_p);
rectime = (tic_t)READUINT32(save_p);
recrings = READUINT16(save_p);
recscore = P_ReadUINT32(save_p);
rectime = (tic_t)P_ReadUINT32(save_p);
recrings = P_ReadUINT16(save_p);
if (recrings > 10000 || recscore > MAXSCORE)
I_Error("Bad $$$.sav dearchiving Emblems (invalid score)");
......@@ -4867,16 +5189,16 @@ static inline void P_NetUnArchiveEmblems(void)
// Nights records
for (i = 0; i < NUMMAPS; ++i)
{
if ((recmares = READUINT8(save_p)) == 0)
if ((recmares = P_ReadUINT8(save_p)) == 0)
continue;
G_AllocNightsRecordData((INT16)i, data);
for (curmare = 0; curmare < (recmares+1); ++curmare)
{
data->nightsrecords[i]->score[curmare] = READUINT32(save_p);
data->nightsrecords[i]->grade[curmare] = READUINT8(save_p);
data->nightsrecords[i]->time[curmare] = (tic_t)READUINT32(save_p);
data->nightsrecords[i]->score[curmare] = P_ReadUINT32(save_p);
data->nightsrecords[i]->grade[curmare] = P_ReadUINT8(save_p);
data->nightsrecords[i]->time[curmare] = (tic_t)P_ReadUINT32(save_p);
if (data->nightsrecords[i]->grade[curmare] > GRADE_S)
{
......@@ -4888,18 +5210,18 @@ static inline void P_NetUnArchiveEmblems(void)
}
// Mid-map stuff
unlocktriggers = READUINT32(save_p);
unlocktriggers = P_ReadUINT32(save_p);
for (i = 0; i < MAXPLAYERS; ++i)
{
if ((recmares = READUINT8(save_p)) == 0)
if ((recmares = P_ReadUINT8(save_p)) == 0)
continue;
for (curmare = 0; curmare < (recmares+1); ++curmare)
{
ntemprecords[i].score[curmare] = READUINT32(save_p);
ntemprecords[i].grade[curmare] = READUINT8(save_p);
ntemprecords[i].time[curmare] = (tic_t)READUINT32(save_p);
ntemprecords[i].score[curmare] = P_ReadUINT32(save_p);
ntemprecords[i].grade[curmare] = P_ReadUINT8(save_p);
ntemprecords[i].time[curmare] = (tic_t)P_ReadUINT32(save_p);
if (ntemprecords[i].grade[curmare] > GRADE_S)
{
......@@ -4911,37 +5233,37 @@ static inline void P_NetUnArchiveEmblems(void)
}
}
static void P_NetArchiveSectorPortals(void)
static void P_NetArchiveSectorPortals(save_t *save_p)
{
WRITEUINT32(save_p, ARCHIVEBLOCK_SECPORTALS);
P_WriteUINT32(save_p, ARCHIVEBLOCK_SECPORTALS);
WRITEUINT32(save_p, secportalcount);
P_WriteUINT32(save_p, secportalcount);
for (size_t i = 0; i < secportalcount; i++)
{
UINT8 type = secportals[i].type;
WRITEUINT8(save_p, type);
WRITEFIXED(save_p, secportals[i].origin.x);
WRITEFIXED(save_p, secportals[i].origin.y);
P_WriteUINT8(save_p, type);
P_WriteUINT8(save_p, secportals[i].ceiling ? 1 : 0);
P_WriteUINT32(save_p, SaveSector(secportals[i].target));
switch (type)
{
case SECPORTAL_LINE:
WRITEUINT32(save_p, SaveLine(secportals[i].line.start));
WRITEUINT32(save_p, SaveLine(secportals[i].line.dest));
P_WriteUINT32(save_p, SaveLine(secportals[i].line.start));
P_WriteUINT32(save_p, SaveLine(secportals[i].line.dest));
break;
case SECPORTAL_PLANE:
case SECPORTAL_HORIZON:
case SECPORTAL_FLOOR:
case SECPORTAL_CEILING:
WRITEUINT32(save_p, SaveSector(secportals[i].sector));
P_WriteUINT32(save_p, SaveSector(secportals[i].sector));
break;
case SECPORTAL_OBJECT:
if (secportals[i].mobj && !P_MobjWasRemoved(secportals[i].mobj))
SaveMobjnum(secportals[i].mobj);
if (!P_MobjWasRemoved(secportals[i].mobj))
P_WriteUINT32(save_p, SaveMobjnum(secportals[i].mobj));
else
WRITEUINT32(save_p, 0);
P_WriteUINT32(save_p, 0);
break;
default:
break;
......@@ -4949,15 +5271,15 @@ static void P_NetArchiveSectorPortals(void)
}
}
static void P_NetUnArchiveSectorPortals(void)
static void P_NetUnArchiveSectorPortals(save_t *save_p)
{
if (READUINT32(save_p) != ARCHIVEBLOCK_SECPORTALS)
if (P_ReadUINT32(save_p) != ARCHIVEBLOCK_SECPORTALS)
I_Error("Bad $$$.sav at archive block Secportals");
Z_Free(secportals);
P_InitSectorPortals();
UINT32 count = READUINT32(save_p);
UINT32 count = P_ReadUINT32(save_p);
for (UINT32 i = 0; i < count; i++)
{
......@@ -4965,24 +5287,24 @@ static void P_NetUnArchiveSectorPortals(void)
sectorportal_t *secportal = &secportals[id];
secportal->type = READUINT8(save_p);
secportal->origin.x = READFIXED(save_p);
secportal->origin.y = READFIXED(save_p);
secportal->type = P_ReadUINT8(save_p);
secportal->ceiling = (P_ReadUINT8(save_p) != 0) ? true : false;
secportal->target = LoadSector(P_ReadUINT32(save_p));
switch (secportal->type)
{
case SECPORTAL_LINE:
secportal->line.start = LoadLine(READUINT32(save_p));
secportal->line.dest = LoadLine(READUINT32(save_p));
secportal->line.start = LoadLine(P_ReadUINT32(save_p));
secportal->line.dest = LoadLine(P_ReadUINT32(save_p));
break;
case SECPORTAL_PLANE:
case SECPORTAL_HORIZON:
case SECPORTAL_FLOOR:
case SECPORTAL_CEILING:
secportal->sector = LoadSector(READUINT32(save_p));
secportal->sector = LoadSector(P_ReadUINT32(save_p));
break;
case SECPORTAL_OBJECT:
id = READUINT32(save_p);
id = P_ReadUINT32(save_p);
secportal->mobj = (id == 0) ? NULL : P_FindNewPosition(id);
break;
default:
......@@ -4991,7 +5313,7 @@ static void P_NetUnArchiveSectorPortals(void)
}
}
static inline void P_ArchiveLuabanksAndConsistency(void)
static inline void P_ArchiveLuabanksAndConsistency(save_t *save_p)
{
UINT8 i, banksinuse = NUM_LUABANKS;
......@@ -5000,30 +5322,30 @@ static inline void P_ArchiveLuabanksAndConsistency(void)
if (banksinuse)
{
WRITEUINT8(save_p, 0xb7); // luabanks marker
WRITEUINT8(save_p, banksinuse);
P_WriteUINT8(save_p, 0xb7); // luabanks marker
P_WriteUINT8(save_p, banksinuse);
for (i = 0; i < banksinuse; i++)
WRITEINT32(save_p, luabanks[i]);
P_WriteINT32(save_p, luabanks[i]);
}
WRITEUINT8(save_p, 0x1d); // consistency marker
P_WriteUINT8(save_p, 0x1d); // consistency marker
}
static inline boolean P_UnArchiveLuabanksAndConsistency(void)
static inline boolean P_UnArchiveLuabanksAndConsistency(save_t *save_p)
{
switch (READUINT8(save_p))
switch (P_ReadUINT8(save_p))
{
case 0xb7: // luabanks marker
{
UINT8 i, banksinuse = READUINT8(save_p);
UINT8 i, banksinuse = P_ReadUINT8(save_p);
if (banksinuse > NUM_LUABANKS)
{
CONS_Alert(CONS_ERROR, M_GetText("Corrupt Luabanks! (Too many banks in use)\n"));
return false;
}
for (i = 0; i < banksinuse; i++)
luabanks[i] = READINT32(save_p);
if (READUINT8(save_p) != 0x1d) // consistency marker
luabanks[i] = P_ReadINT32(save_p);
if (P_ReadUINT8(save_p) != 0x1d) // consistency marker
{
CONS_Alert(CONS_ERROR, M_GetText("Corrupt Luabanks! (Failed consistency check)\n"));
return false;
......@@ -5039,27 +5361,27 @@ static inline boolean P_UnArchiveLuabanksAndConsistency(void)
return true;
}
void P_SaveGame(INT16 mapnum)
void P_SaveGame(save_t *save_p, INT16 mapnum)
{
P_ArchiveMisc(mapnum);
P_ArchivePlayer();
P_ArchiveLuabanksAndConsistency();
P_ArchiveMisc(save_p, mapnum);
P_ArchivePlayer(save_p);
P_ArchiveLuabanksAndConsistency(save_p);
}
void P_SaveNetGame(boolean resending)
void P_SaveNetGame(save_t *save_p, boolean resending)
{
thinker_t *th;
mobj_t *mobj;
INT32 i = 1; // don't start from 0, it'd be confused with a blank pointer otherwise
CV_SaveNetVars(&save_p);
P_NetArchiveMisc(resending);
P_NetArchiveEmblems();
CV_SaveNetVars(save_p);
P_NetArchiveMisc(save_p, resending);
P_NetArchiveEmblems(save_p);
// Assign the mobjnumber for pointer tracking
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mobj = (mobj_t *)th;
......@@ -5068,32 +5390,32 @@ void P_SaveNetGame(boolean resending)
mobj->mobjnum = i++;
}
P_NetArchivePlayers();
P_NetArchivePlayers(save_p);
if (gamestate == GS_LEVEL)
{
P_NetArchiveWorld();
P_ArchivePolyObjects();
P_NetArchiveThinkers();
P_NetArchiveSpecials();
P_NetArchiveColormaps();
P_NetArchiveWaypoints();
P_NetArchiveSectorPortals();
P_NetArchiveWorld(save_p);
P_ArchivePolyObjects(save_p);
P_NetArchiveThinkers(save_p);
P_NetArchiveSpecials(save_p);
P_NetArchiveColormaps(save_p);
P_NetArchiveWaypoints(save_p);
P_NetArchiveSectorPortals(save_p);
}
LUA_Archive();
LUA_Archive(save_p);
P_ArchiveLuabanksAndConsistency();
P_ArchiveLuabanksAndConsistency(save_p);
}
boolean P_LoadGame(INT16 mapoverride)
boolean P_LoadGame(save_t *save_p, INT16 mapoverride)
{
if (gamestate == GS_INTERMISSION)
Y_EndIntermission();
G_SetGamestate(GS_NULL); // should be changed in P_UnArchiveMisc
P_UnArchiveSPGame(mapoverride);
P_UnArchivePlayer();
P_UnArchiveSPGame(save_p, mapoverride);
P_UnArchivePlayer(save_p);
if (!P_UnArchiveLuabanksAndConsistency())
if (!P_UnArchiveLuabanksAndConsistency(save_p))
return false;
// Only do this after confirming savegame is ok
......@@ -5103,26 +5425,26 @@ boolean P_LoadGame(INT16 mapoverride)
return true;
}
boolean P_LoadNetGame(boolean reloading)
boolean P_LoadNetGame(save_t *save_p, boolean reloading)
{
CV_LoadNetVars(&save_p);
if (!P_NetUnArchiveMisc(reloading))
CV_LoadNetVars(save_p);
if (!P_NetUnArchiveMisc(save_p, reloading))
return false;
P_NetUnArchiveEmblems();
P_NetUnArchivePlayers();
P_NetUnArchiveEmblems(save_p);
P_NetUnArchivePlayers(save_p);
if (gamestate == GS_LEVEL)
{
P_NetUnArchiveWorld();
P_UnArchivePolyObjects();
P_NetUnArchiveThinkers();
P_NetUnArchiveSpecials();
P_NetUnArchiveColormaps();
P_NetUnArchiveWaypoints();
P_NetUnArchiveSectorPortals();
P_NetUnArchiveWorld(save_p);
P_UnArchivePolyObjects(save_p);
P_NetUnArchiveThinkers(save_p);
P_NetUnArchiveSpecials(save_p);
P_NetUnArchiveColormaps(save_p);
P_NetUnArchiveWaypoints(save_p);
P_NetUnArchiveSectorPortals(save_p);
P_RelinkPointers();
P_FinishMobjs();
}
LUA_UnArchive();
LUA_UnArchive(save_p);
// This is stupid and hacky, but maybe it'll work!
P_SetRandSeed(P_GetInitSeed());
......@@ -5133,5 +5455,5 @@ boolean P_LoadNetGame(boolean reloading)
// precipitation when loading a netgame save. Instead, precip has to be spawned here.
// This is done in P_NetUnArchiveSpecials now.
return P_UnArchiveLuabanksAndConsistency();
return P_UnArchiveLuabanksAndConsistency(save_p);
}
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -18,17 +18,24 @@
#pragma interface
#endif
#include "tables.h"
#define NEWSKINSAVES (INT16_MAX) // TODO: 2.3: Delete (Purely for backwards compatibility)
// Persistent storage/archiving.
// These are the load / save game routines.
void P_SaveGame(INT16 mapnum);
void P_SaveNetGame(boolean resending);
boolean P_LoadGame(INT16 mapoverride);
boolean P_LoadNetGame(boolean reloading);
typedef struct
{
unsigned char *buf;
size_t size;
size_t pos;
} save_t;
mobj_t *P_FindNewPosition(UINT32 oldposition);
void P_SaveGame(save_t *save_p, INT16 mapnum);
void P_SaveNetGame(save_t *save_p, boolean resending);
boolean P_LoadGame(save_t *save_p, INT16 mapoverride);
boolean P_LoadNetGame(save_t *save_p, boolean reloading);
typedef struct
{
......@@ -42,6 +49,37 @@ typedef struct
} savedata_t;
extern savedata_t savedata;
extern UINT8 *save_p;
void P_WriteUINT8(save_t *p, UINT8 v);
void P_WriteSINT8(save_t *p, SINT8 v);
void P_WriteUINT16(save_t *p, UINT16 v);
void P_WriteINT16(save_t *p, INT16 v);
void P_WriteUINT32(save_t *p, UINT32 v);
void P_WriteINT32(save_t *p, INT32 v);
void P_WriteChar(save_t *p, char v);
void P_WriteFixed(save_t *p, fixed_t v);
void P_WriteAngle(save_t *p, angle_t v);
void P_WriteStringN(save_t *p, char const *s, size_t n);
void P_WriteStringL(save_t *p, char const *s, size_t n);
void P_WriteString(save_t *p, char const *s);
void P_WriteMem(save_t *p, void const *s, size_t n);
void P_SkipStringN(save_t *p, size_t n);
void P_SkipStringL(save_t *p, size_t n);
void P_SkipString(save_t *p);
UINT8 P_ReadUINT8(save_t *p);
SINT8 P_ReadSINT8(save_t *p);
UINT16 P_ReadUINT16(save_t *p);
INT16 P_ReadINT16(save_t *p);
UINT32 P_ReadUINT32(save_t *p);
INT32 P_ReadINT32(save_t *p);
char P_ReadChar(save_t *p);
fixed_t P_ReadFixed(save_t *p);
angle_t P_ReadAngle(save_t *p);
void P_ReadStringN(save_t *p, char *s, size_t n);
void P_ReadStringL(save_t *p, char *s, size_t n);
void P_ReadString(save_t *p, char *s);
void P_ReadMem(save_t *p, void *s, size_t n);
#endif
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -11,6 +11,9 @@
/// \file p_setup.c
/// \brief Do all the WAD I/O, get map description, set up initial state and misc. LUTs
#include <errno.h>
#include "doomdef.h"
#include "d_main.h"
#include "byteptr.h"
......@@ -609,15 +612,15 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
levelflat->type = LEVELFLAT_TEXTURE;
// Look for a flat
int texturenum = R_CheckFlatNumForName(levelflat->name);
int texturenum = R_CheckTextureNumForName(levelflat->name, TEXTURETYPE_FLAT);
if (texturenum < 0)
{
// If we can't find a flat, try looking for a texture!
texturenum = R_CheckTextureNumForName(levelflat->name);
texturenum = R_CheckTextureNumForName(levelflat->name, TEXTURETYPE_TEXTURE);
if (texturenum < 0)
{
// Use "not found" texture
texturenum = R_CheckTextureNumForName("REDWALL");
texturenum = R_CheckTextureNumForName("REDWALL", TEXTURETYPE_TEXTURE);
// Give up?
if (texturenum < 0)
......@@ -692,7 +695,7 @@ void P_ReloadRings(void)
// scan the thinkers to find rings/spheres/hoops to unset
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo = (mobj_t *)th;
......@@ -750,7 +753,7 @@ void P_SwitchSpheresBonusMode(boolean bonustime)
// scan the thinkers to find spheres to switch
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo = (mobj_t *)th;
......@@ -831,13 +834,15 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
static void P_SpawnEmeraldHunt(void)
{
INT32 emer[3], num[MAXHUNTEMERALDS], i, randomkey;
INT32 emer[3], num[MAXHUNTEMERALDS], i, amount, randomkey;
fixed_t x, y, z;
for (i = 0; i < numhuntemeralds; i++)
num[i] = i;
for (i = 0; i < 3; i++)
amount = min(numhuntemeralds, 3);
for (i = 0; i < amount; i++)
{
// generate random index, shuffle afterwards
randomkey = P_RandomKey(numhuntemeralds--);
......@@ -1075,6 +1080,7 @@ static void P_LoadSectors(UINT8 *data)
ss->triggerer = TO_PLAYER;
ss->friction = ORIG_FRICTION;
ss->customargs = NULL;
P_InitializeSector(ss);
}
......@@ -1113,6 +1119,8 @@ static void P_InitializeLinedef(line_t *ld)
ld->callcount = 0;
ld->secportal = UINT32_MAX;
ld->midtexslope = NULL;
// cph 2006/09/30 - fix sidedef errors right away.
// cph 2002/07/20 - these errors are fatal if not fixed, so apply them
for (j = 0; j < 2; j++)
......@@ -1195,6 +1203,8 @@ static void P_LoadLinedefs(UINT8 *data)
if (ld->sidenum[1] == 0xffff)
ld->sidenum[1] = NO_SIDEDEF;
ld->customargs = NULL;
P_InitializeLinedef(ld);
}
}
......@@ -1363,6 +1373,11 @@ static void P_LoadSidedefs(UINT8 *data)
sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT;
sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT;
sd->light = sd->light_top = sd->light_mid = sd->light_bottom = 0;
sd->lightabsolute = sd->lightabsolute_top = sd->lightabsolute_mid = sd->lightabsolute_bottom = false;
sd->customargs = NULL;
P_SetSidedefSector(i, (UINT16)SHORT(msd->sector));
// Special info stored in texture fields!
......@@ -1546,15 +1561,46 @@ static void P_LoadThings(UINT8 *data)
mt->z = mt->options >> ZSHIFT;
mt->mobj = NULL;
mt->customargs = NULL;
}
}
// Stores positions for relevant map data spread through a TEXTMAP.
UINT32 mapthingsPos[UINT16_MAX];
UINT32 linesPos[UINT16_MAX];
UINT32 sidesPos[UINT16_MAX];
UINT32 vertexesPos[UINT16_MAX];
UINT32 sectorsPos[UINT16_MAX];
typedef struct textmap_block_s
{
UINT32 *pos;
size_t capacity;
} textmap_block_t;
static textmap_block_t mapthingBlocks;
static textmap_block_t linedefBlocks;
static textmap_block_t sidedefBlocks;
static textmap_block_t vertexBlocks;
static textmap_block_t sectorBlocks;
static void TextmapStorePos(textmap_block_t *blocks, size_t *count)
{
size_t locCount = (*count) + 1;
if (blocks->pos == NULL)
{
// Initial capacity (half of the former one.)
blocks->capacity = UINT16_MAX / 2;
Z_Calloc(sizeof(blocks->pos) * blocks->capacity, PU_LEVEL, &blocks->pos);
}
else if (locCount >= blocks->capacity)
{
// If we hit the list's capacity, make space for 1024 more blocks
blocks->capacity += 1024;
Z_Realloc(blocks->pos, sizeof(blocks->pos) * blocks->capacity, PU_LEVEL, &blocks->pos);
}
blocks->pos[locCount - 1] = M_TokenizerGetEndPos();
(*count) = locCount;
}
// Determine total amount of map data in TEXTMAP.
static boolean TextmapCount(size_t size)
......@@ -1598,15 +1644,15 @@ static boolean TextmapCount(size_t size)
brackets++;
// Check for valid fields.
else if (fastcmp(tkn, "thing"))
mapthingsPos[nummapthings++] = M_TokenizerGetEndPos();
TextmapStorePos(&mapthingBlocks, &nummapthings);
else if (fastcmp(tkn, "linedef"))
linesPos[numlines++] = M_TokenizerGetEndPos();
TextmapStorePos(&linedefBlocks, &numlines);
else if (fastcmp(tkn, "sidedef"))
sidesPos[numsides++] = M_TokenizerGetEndPos();
TextmapStorePos(&sidedefBlocks, &numsides);
else if (fastcmp(tkn, "vertex"))
vertexesPos[numvertexes++] = M_TokenizerGetEndPos();
TextmapStorePos(&vertexBlocks, &numvertexes);
else if (fastcmp(tkn, "sector"))
sectorsPos[numsectors++] = M_TokenizerGetEndPos();
TextmapStorePos(&sectorBlocks, &numsectors);
else
CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn);
}
......@@ -1620,6 +1666,89 @@ static boolean TextmapCount(size_t size)
return true;
}
static void ParseTextmapCustomFields(const char* param, const char* val, customargs_t** headptr)
{
if (val[0] == '\0')
return;
//
// GET latest node
//
customargs_t* newnode = Z_Malloc(sizeof(customargs_t), PU_LEVEL, NULL);
if (!newnode)
return;
newnode->next = NULL;
if (*headptr == NULL) {
*headptr = newnode;
}
else {
customargs_t* curr = *headptr;
while (curr->next != NULL) {
curr = curr->next;
}
curr->next = newnode;
}
//
// Setup
//
newnode->name = Z_Malloc(strlen(param + 5) + 1, PU_LEVEL, NULL);
M_Memcpy(newnode->name, param + 5, strlen(param + 5) + 1);
if (fastcmp(val, "true"))
{
newnode->type = UDMF_TYPE_BOOLEAN;
newnode->value.vbool = true;
}
else if (fastcmp(val, "false"))
{
newnode->type = UDMF_TYPE_BOOLEAN;
newnode->value.vbool = false;
}
else
{
char* endptr;
long lval;
float fval;
// Eval integer
errno = 0;
lval = strtol(val, &endptr, 10);
if (*endptr == '\0' && endptr != val && errno == 0) {
newnode->type = UDMF_TYPE_NUMERIC;
newnode->value.vint = lval;
return;
}
// Eval float
errno = 0;
fval = strtof(val, &endptr);
if (*endptr == '\0' && endptr != val && errno == 0) {
newnode->type = UDMF_TYPE_FIXED;
newnode->value.vfloat = FLOAT_TO_FIXED(fval);
return;
}
// Just string
newnode->type = UDMF_TYPE_STRING;
newnode->value.vstring = Z_Malloc(strlen(val) + 1, PU_LEVEL, NULL);
M_Memcpy(newnode->value.vstring, val, strlen(val) + 1);
}
}
static void ParseTextmapVertexParameter(UINT32 i, const char *param, const char *val)
{
if (fastcmp(param, "x"))
......@@ -1719,6 +1848,8 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
sectors[i].floorangle = FixedAngle(FLOAT_TO_FIXED(atof(val)));
else if (fastcmp(param, "rotationceiling"))
sectors[i].ceilingangle = FixedAngle(FLOAT_TO_FIXED(atof(val)));
else if (fastncmp(param, "user_", 5) && strlen(param) > 5)
ParseTextmapCustomFields(param, val, &sectors[i].customargs);
else if (fastcmp(param, "floorplane_a"))
{
textmap_planefloor.defined |= PD_A;
......@@ -1943,6 +2074,24 @@ static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char
P_SetSidedefSector(i, atol(val));
else if (fastcmp(param, "repeatcnt"))
sides[i].repeatcnt = atol(val);
else if (fastcmp(param, "light"))
sides[i].light = atol(val);
else if (fastcmp(param, "light_top"))
sides[i].light_top = atol(val);
else if (fastcmp(param, "light_mid"))
sides[i].light_mid = atol(val);
else if (fastcmp(param, "light_bottom"))
sides[i].light_bottom = atol(val);
else if (fastcmp(param, "lightabsolute") && fastcmp("true", val))
sides[i].lightabsolute = true;
else if (fastcmp(param, "lightabsolute_top") && fastcmp("true", val))
sides[i].lightabsolute_top = true;
else if (fastcmp(param, "lightabsolute_mid") && fastcmp("true", val))
sides[i].lightabsolute_mid = true;
else if (fastcmp(param, "lightabsolute_bottom") && fastcmp("true", val))
sides[i].lightabsolute_bottom = true;
else if (fastncmp(param, "user_", 5) && strlen(param) > 5)
ParseTextmapCustomFields(param, val, &sides[i].customargs);
}
static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char *val)
......@@ -2037,6 +2186,9 @@ static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char
lines[i].flags |= ML_BOUNCY;
else if (fastcmp(param, "transfer") && fastcmp("true", val))
lines[i].flags |= ML_TFERLINE;
else if (fastncmp(param, "user_", 5) && strlen(param) > 5)
ParseTextmapCustomFields(param, val, &lines[i].customargs);
}
static void ParseTextmapThingParameter(UINT32 i, const char *param, const char *val)
......@@ -2096,6 +2248,8 @@ static void ParseTextmapThingParameter(UINT32 i, const char *param, const char *
return;
mapthings[i].args[argnum] = atol(val);
}
else if (fastncmp(param, "user_", 5) && strlen(param) > 5)
ParseTextmapCustomFields(param, val, &mapthings[i].customargs);
}
/** From a given position table, run a specified parser function through a {}-encapsuled text.
......@@ -2670,6 +2824,22 @@ static void P_WriteTextmap(void)
fprintf(f, "texturemiddle = \"%.*s\";\n", 8, textures[wsides[i].midtexture]->name);
if (wsides[i].repeatcnt != 0)
fprintf(f, "repeatcnt = %d;\n", wsides[i].repeatcnt);
if (wsides[i].light != 0)
fprintf(f, "light = %d;\n", wsides[i].light);
if (wsides[i].light_top != 0)
fprintf(f, "light_top = %d;\n", wsides[i].light_top);
if (wsides[i].light_mid != 0)
fprintf(f, "light_mid = %d;\n", wsides[i].light_mid);
if (wsides[i].light_bottom != 0)
fprintf(f, "light_bottom = %d;\n", wsides[i].light_bottom);
if (wsides[i].lightabsolute)
fprintf(f, "lightabsolute = true;\n");
if (wsides[i].lightabsolute_top)
fprintf(f, "lightabsolute_top = true;\n");
if (wsides[i].lightabsolute_mid)
fprintf(f, "lightabsolute_mid = true;\n");
if (wsides[i].lightabsolute_bottom)
fprintf(f, "lightabsolute_bottom = true;\n");
fprintf(f, "}\n");
fprintf(f, "\n");
}
......@@ -2926,7 +3096,7 @@ static void P_LoadTextmap(void)
side_t *sd;
mapthing_t *mt;
CONS_Alert(CONS_NOTICE, "UDMF support is still a work-in-progress; its specs and features are prone to change until it is fully implemented.\n");
//CONS_Alert(CONS_NOTICE, "UDMF support is still a work-in-progress; its specs and features are prone to change until it is fully implemented.\n");
/// Given the UDMF specs, some fields are given a default value.
/// If an element's field has a default value set, it is omitted
......@@ -2940,7 +3110,7 @@ static void P_LoadTextmap(void)
vt->floorzset = vt->ceilingzset = false;
vt->floorz = vt->ceilingz = 0;
TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter);
TextmapParse(vertexBlocks.pos[i], i, ParseTextmapVertexParameter);
if (vt->x == INT32_MAX)
I_Error("P_LoadTextmap: vertex %s has no x value set!\n", sizeu1(i));
......@@ -2984,6 +3154,7 @@ static void P_LoadTextmap(void)
sc->triggerer = TO_PLAYER;
sc->friction = ORIG_FRICTION;
sc->customargs = NULL;
textmap_colormap.used = false;
textmap_colormap.lightcolor = 0;
......@@ -2997,7 +3168,7 @@ static void P_LoadTextmap(void)
textmap_planefloor.defined = 0;
textmap_planeceiling.defined = 0;
TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter);
TextmapParse(sectorBlocks.pos[i], i, ParseTextmapSectorParameter);
P_InitializeSector(sc);
if (textmap_colormap.used)
......@@ -3045,8 +3216,9 @@ static void P_LoadTextmap(void)
ld->executordelay = 0;
ld->sidenum[0] = NO_SIDEDEF;
ld->sidenum[1] = NO_SIDEDEF;
ld->customargs = NULL;
TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter);
TextmapParse(linedefBlocks.pos[i], i, ParseTextmapLinedefParameter);
if (!ld->v1)
I_Error("P_LoadTextmap: linedef %s has no v1 value set!\n", sizeu1(i));
......@@ -3072,8 +3244,11 @@ static void P_LoadTextmap(void)
sd->bottomtexture = R_TextureNumForName("-");
sd->sector = NULL;
sd->repeatcnt = 0;
sd->light = sd->light_top = sd->light_mid = sd->light_bottom = 0;
sd->lightabsolute = sd->lightabsolute_top = sd->lightabsolute_mid = sd->lightabsolute_bottom = false;
sd->customargs = NULL;
TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter);
TextmapParse(sidedefBlocks.pos[i], i, ParseTextmapSidedefParameter);
if (!sd->sector)
I_Error("P_LoadTextmap: sidedef %s has no sector value set!\n", sizeu1(i));
......@@ -3096,8 +3271,9 @@ static void P_LoadTextmap(void)
memset(mt->args, 0, NUMMAPTHINGARGS*sizeof(*mt->args));
memset(mt->stringargs, 0x00, NUMMAPTHINGSTRINGARGS*sizeof(*mt->stringargs));
mt->mobj = NULL;
mt->customargs = NULL;
TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter);
TextmapParse(mapthingBlocks.pos[i], i, ParseTextmapThingParameter);
}
}
......@@ -3415,13 +3591,13 @@ typedef enum {
} nodetype_t;
// Find out the BSP format.
static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata, char signature[4 + 1])
{
boolean supported[NUMNODETYPES] = {0};
nodetype_t nodetype = NT_UNSUPPORTED;
char signature[4 + 1];
*nodedata = NULL;
signature[0] = signature[4] = '\0';
if (udmf)
{
......@@ -3430,7 +3606,7 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
if (virtznodes && virtznodes->size)
{
*nodedata = virtznodes->data;
supported[NT_XGLN] = supported[NT_XGL3] = true;
supported[NT_XGLN] = supported[NT_XGL2] = supported[NT_XGL3] = true;
}
}
else
......@@ -3452,9 +3628,9 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
virtssectors = vres_Find(virt, "SSECTORS");
if (virtssectors && virtssectors->size)
{ // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature.
{ // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump (it is confusing, yeah), and has a signature.
*nodedata = virtssectors->data;
supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL3] = true;
supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL2] = supported[NT_XGL3] = true;
}
else
{ // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature.
......@@ -3474,19 +3650,42 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata)
}
M_Memcpy(signature, *nodedata, 4);
signature[4] = '\0';
(*nodedata) += 4;
if (!strcmp(signature, "XNOD"))
nodetype = NT_XNOD;
else if (!strcmp(signature, "ZNOD"))
nodetype = NT_ZNOD;
else if (!strcmp(signature, "XGLN"))
nodetype = NT_XGLN;
else if (!strcmp(signature, "ZGLN"))
nodetype = NT_ZGLN;
else if (!strcmp(signature, "XGL3"))
nodetype = NT_XGL3;
// Identify node format from its starting signature.
if (memcmp(&signature[1], "NOD", 3) == 0) // ZDoom extended nodes
{
if (signature[0] == 'X')
{
nodetype = NT_XNOD; // Uncompressed
}
else if (signature[0] == 'Z')
{
nodetype = NT_ZNOD; // Compressed
}
}
else if (memcmp(&signature[1], "GL", 2) == 0) // GL nodes
{
switch (signature[0])
{
case 'X': // Uncompressed
switch (signature[3])
{
case 'N': nodetype = NT_XGLN; break; // GL nodes
case '2': nodetype = NT_XGL2; break; // Version 2 GL nodes
case '3': nodetype = NT_XGL3; break; // Version 3 GL nodes
}
break;
case 'Z': // Compressed
switch (signature[3])
{
case 'N': nodetype = NT_ZGLN; break; // GL nodes (compressed)
case '2': nodetype = NT_ZGL2; break; // Version 2 GL nodes (compressed)
case '3': nodetype = NT_ZGL3; break; // Version 3 GL nodes (compressed)
}
break;
}
}
return supported[nodetype] ? nodetype : NT_UNSUPPORTED;
}
......@@ -3498,7 +3697,6 @@ static boolean P_LoadExtraVertices(UINT8 **data)
UINT32 xtrvrtx = READUINT32((*data));
line_t* ld = lines;
vertex_t *oldpos = vertexes;
ssize_t offset;
size_t i;
if (numvertexes != origvrtx) // If native vertex count doesn't match node original vertex count, bail out (broken data?).
......@@ -3513,12 +3711,11 @@ static boolean P_LoadExtraVertices(UINT8 **data)
// If extra vertexes were generated, reallocate the vertex array and fix the pointers.
numvertexes += xtrvrtx;
vertexes = Z_Realloc(vertexes, numvertexes*sizeof(*vertexes), PU_LEVEL, NULL);
offset = (size_t)(vertexes - oldpos);
for (i = 0, ld = lines; i < numlines; i++, ld++)
{
ld->v1 += offset;
ld->v2 += offset;
ld->v1 = &vertexes[ld->v1 - oldpos];
ld->v2 = &vertexes[ld->v2 - oldpos];
}
// Read extra vertex data.
......@@ -3556,6 +3753,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype
switch (nodetype)
{
case NT_XGLN:
case NT_XGL2:
case NT_XGL3:
for (m = 0; m < (size_t)subsectors[i].numlines; m++, k++)
{
......@@ -3567,7 +3765,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype
READUINT32((*data)); // partner, can be ignored by software renderer
if (nodetype == NT_XGL3)
if (nodetype != NT_XGLN)
{
UINT32 linenum = READUINT32((*data));
if (linenum != 0xFFFFFFFF && linenum >= numlines)
......@@ -3678,8 +3876,9 @@ static void P_LoadExtendedNodes(UINT8 **data, nodetype_t nodetype)
static void P_LoadMapBSP(const virtres_t *virt)
{
char signature[4 + 1];
UINT8 *nodedata = NULL;
nodetype_t nodetype = P_GetNodetype(virt, &nodedata);
nodetype_t nodetype = P_GetNodetype(virt, &nodedata, signature);
switch (nodetype)
{
......@@ -3711,6 +3910,7 @@ static void P_LoadMapBSP(const virtres_t *virt)
}
case NT_XNOD:
case NT_XGLN:
case NT_XGL2:
case NT_XGL3:
if (!P_LoadExtraVertices(&nodedata))
return;
......@@ -3719,10 +3919,13 @@ static void P_LoadMapBSP(const virtres_t *virt)
P_LoadExtendedNodes(&nodedata, nodetype);
break;
default:
CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n");
if (isprint(signature[0]) && isprint(signature[1]) && isprint(signature[2]) && isprint(signature[3]))
{
I_Error("Unsupported BSP format '%s' detected!\n", signature);
return;
}
return;
I_Error("Unknown BSP format detected!\n");
}
}
// Split from P_LoadBlockMap for convenience
......@@ -7235,7 +7438,7 @@ void P_RespawnThings(void)
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (think->removing)
continue;
P_RemoveMobj((mobj_t *)think);
}
......@@ -7271,11 +7474,11 @@ static void P_RunLevelScript(const char *scriptname)
return;
}
COM_BufInsertText(W_CacheLumpNum(lumpnum, PU_CACHE));
COM_BufInsertTextEx(W_CacheLumpNum(lumpnum, PU_CACHE), COM_LUA);
}
else
{
COM_BufAddText(va("exec %s\n", scriptname));
COM_ExecFile(scriptname, COM_LUA, false);
}
COM_BufExecute(); // Run it!
}
......@@ -7547,7 +7750,6 @@ static void P_InitCamera(void)
CV_SetValue(&cv_analog[1], 0);
displayplayer = consoleplayer; // Start with your OWN view, please!
}
if (twodlevel)
{
......@@ -7563,6 +7765,7 @@ static void P_InitCamera(void)
CV_SetValue(&cv_analog[1], true);
}
}
}
static void P_RunSpecialStageWipe(void)
{
......@@ -7755,6 +7958,10 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
gametyperules = gametypedefaultrules[gametype];
// clear the target on map change, since the object will be invalidated
P_SetTarget(&ticcmd_ztargetfocus[0], NULL);
P_SetTarget(&ticcmd_ztargetfocus[1], NULL);
CON_Drawer(); // let the user know what we are going to do
I_FinishUpdate(); // page flip or blit buffer
......@@ -7904,6 +8111,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// Free GPU textures before freeing patches.
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
HWR_ClearAllTextures();
// Delete light table textures
HWR_ClearLightTables();
#endif
Patch_FreeTag(PU_PATCH_LOWPRIORITY);
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2009 by Stephen McGranahan.
// Copyright (C) 2015-2023 by Sonic Team Junior.
// Copyright (C) 2015-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -28,6 +28,8 @@
pslope_t *slopelist = NULL;
UINT16 slopecount = 0;
static void P_UpdateMidtextureSlopesForSector(sector_t *sector);
// Calculate line normal
void P_CalculateSlopeNormal(pslope_t *slope)
{
......@@ -180,7 +182,7 @@ void T_DynamicSlopeLine (dynlineplanethink_t* th)
pslope_t* slope = th->slope;
line_t* srcline = th->sourceline;
fixed_t zdelta;
fixed_t zdelta, oldoz = slope->o.z;
switch(th->type) {
case DP_FRONTFLOOR:
......@@ -207,11 +209,14 @@ void T_DynamicSlopeLine (dynlineplanethink_t* th)
return;
}
if (slope->zdelta != FixedDiv(zdelta, th->extent)) {
if (slope->zdelta != FixedDiv(zdelta, th->extent) || oldoz != slope->o.z) {
slope->zdelta = FixedDiv(zdelta, th->extent);
slope->zangle = R_PointToAngle2(0, 0, th->extent, -zdelta);
slope->moved = true;
P_CalculateSlopeNormal(slope);
P_UpdateMidtextureSlopesForSector(srcline->frontsector);
if (srcline->backsector)
P_UpdateMidtextureSlopesForSector(srcline->backsector);
}
}
......@@ -232,6 +237,12 @@ void T_DynamicSlopeVert (dynvertexplanethink_t* th)
}
ReconfigureViaVertexes(th->slope, th->vex[0], th->vex[1], th->vex[2]);
for (i = 0; i < 3; i++)
{
if (th->secs[i])
P_UpdateMidtextureSlopesForSector(th->secs[i]);
}
}
static inline void P_AddDynLineSlopeThinker (pslope_t* slope, dynplanetype_t type, line_t* sourceline, fixed_t extent)
......@@ -758,6 +769,111 @@ pslope_t *P_MakeSlopeViaEquationConstants(const double a, const double b, const
return ret;
}
static pslope_t *P_GetReferenceSlopeForMidtexture(line_t *line)
{
if (line->flags & ML_MIDPEG)
{
// Line has ML_MIDPEG, so use the floor slope
fixed_t frontheight = P_GetSectorFloorZAt(line->frontsector, line->v1->x, line->v1->y);
fixed_t backheight = P_GetSectorFloorZAt(line->backsector, line->v1->x, line->v1->y);
if (frontheight > backheight)
{
return line->frontsector->f_slope;
}
else
{
return line->backsector->f_slope;
}
}
else
{
// Line does not have ML_MIDPEG, so use the ceiling slope
fixed_t frontheight = P_GetSectorCeilingZAt(line->frontsector, line->v1->x, line->v1->y);
fixed_t backheight = P_GetSectorCeilingZAt(line->backsector, line->v1->x, line->v1->y);
if (frontheight < backheight)
{
return line->frontsector->c_slope;
}
else
{
return line->backsector->c_slope;
}
}
return NULL;
}
// Updates a slope for a solid midtexture based on the slope of the sector it's in.
static void P_UpdateSolidMidtextureSlope(line_t *line, pslope_t *ref)
{
pslope_t *slope = line->midtexslope;
if (ref == NULL)
return;
// Set origin
vector3_t origin;
origin.x = line->v1->x;
origin.y = line->v1->y;
origin.z = P_GetSlopeZAt(ref, origin.x, origin.y);
FV3_Copy(&slope->o, &origin);
// Get where the line ends
vector3_t point;
point.x = line->v2->x;
point.y = line->v2->y;
point.z = P_GetSlopeZAt(ref, point.x, point.y);
// Get length of the line
fixed_t extent = R_PointToDist2(0, 0, line->dx, line->dy);
// Precalculate variables
slope->zdelta = FixedDiv(origin.z - point.z, extent);
slope->zangle = R_PointToAngle2(0, origin.z, extent, point.z);
slope->xydirection = line->angle;
// Precalculate the direction
vector2_t dir;
dir.x = FixedMul(FINECOSINE(slope->zangle >> ANGLETOFINESHIFT), FINECOSINE((slope->xydirection+ANGLE_180) >> ANGLETOFINESHIFT));
dir.y = FixedMul(FINECOSINE(slope->zangle >> ANGLETOFINESHIFT), FINESINE((slope->xydirection+ANGLE_180) >> ANGLETOFINESHIFT));
FV2_Copy(&slope->d, &dir);
P_CalculateSlopeNormal(slope);
// Calling P_CalculateSlopeVectors is not necessary.
slope->moved = true;
}
// Goes through every line in the sector and updates the midtexture slope if it is present
static void P_UpdateMidtextureSlopesForSector(sector_t *sector)
{
for (size_t i = 0; i < sector->linecount; i++)
{
if (sector->lines[i]->midtexslope != NULL)
P_UpdateSolidMidtextureSlope(sector->lines[i], P_GetReferenceSlopeForMidtexture(sector->lines[i]));
}
}
// Creates a solid midtexture slope for the line if possible
static void P_CreateSolidMidtextureSlope(line_t *line)
{
if (line->backsector == NULL) // Ignore single-sided lines (of course)
return;
if ((line->flags & ML_MIDSOLID) == 0) // Ignore if the midtexture is not solid
return;
pslope_t *ref = P_GetReferenceSlopeForMidtexture(line);
if (ref)
{
line->midtexslope = Slope_Add(ref->flags & SL_NOPHYSICS);
P_UpdateSolidMidtextureSlope(line, ref);
}
}
/// Initializes and reads the slopes from the map data.
void P_SpawnSlopes(const boolean fromsave) {
size_t i;
......@@ -785,14 +901,21 @@ void P_SpawnSlopes(const boolean fromsave) {
/// Copies slopes from tagged sectors via line specials.
/// \note Doesn't actually copy, but instead they share the same pointers.
// Also, creates midtexture slopes.
for (i = 0; i < numlines; i++)
switch (lines[i].special)
{
line_t *line = &lines[i];
switch (line->special)
{
case 720:
P_CopySectorSlope(&lines[i]);
P_CopySectorSlope(line);
default:
break;
}
P_CreateSolidMidtextureSlope(line);
}
}
/// Initializes slopes.
......@@ -810,10 +933,10 @@ void P_InitSlopes(void)
// Returns the height of the sloped plane at (x, y) as a fixed_t
fixed_t P_GetSlopeZAt(const pslope_t *slope, fixed_t x, fixed_t y)
{
fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) +
FixedMul(y - slope->o.y, slope->d.y);
fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) / 2 +
FixedMul(y - slope->o.y, slope->d.y) / 2;
return slope->o.z + FixedMul(dist, slope->zdelta);
return slope->o.z + FixedMul(dist, slope->zdelta) * 2;
}
// Like P_GetSlopeZAt but falls back to z if slope is NULL
......@@ -923,15 +1046,37 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope)
{
vector3_t slopemom, axis;
angle_t ang;
angle_t advanceAng = ANG15;
const boolean upwards = (slope->zangle < ANGLE_180);
if (slope->flags & SL_NOPHYSICS)
return 0;
// If there's physics, time for launching.
// Doesn't kill the vertical momentum as much as P_SlopeLaunch does.
ang = slope->zangle + ANG15*((slope->zangle > 0) ? 1 : -1);
if (ang > ANGLE_90 && ang < ANGLE_180)
ang = ((slope->zangle > 0) ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards
ang = slope->zangle;
// for the time being, let's pretend the slope inclines upwards only
if (!upwards)
{
ang += ANGLE_180;
}
// angles past 90 degrees need to shrink to get closer to 90 degrees
if (ang > ANGLE_90)
{
advanceAng = InvAngle(advanceAng);
}
// now we set the actual final angle
if ((ang > ANGLE_90) != (ang + advanceAng > ANGLE_90)) // does advancing the angle push it past directly upwards?
{
ang = (upwards ? ANGLE_90 : InvAngle(ANGLE_90)); // hard cap of directly upwards
}
else
{
ang = slope->zangle + advanceAng;
}
slopemom.x = mo->momx;
slopemom.y = mo->momy;
......
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2009 by Stephen McGranahan.
// Copyright (C) 2015-2023 by Sonic Team Junior.
// Copyright (C) 2015-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -135,22 +135,24 @@ void P_ParseAnimationDefintion(SINT8 istexture);
static boolean P_FindTextureForAnimation(anim_t *anim, animdef_t *animdef)
{
if (R_CheckTextureNumForName(animdef->startname) == -1)
INT32 start = R_CheckTextureNumForName(animdef->startname, TEXTURETYPE_TEXTURE);
if (start == -1)
return false;
anim->picnum = R_TextureNumForName(animdef->endname);
anim->basepic = R_TextureNumForName(animdef->startname);
anim->basepic = start;
anim->picnum = R_CheckTextureNumForName(animdef->endname, TEXTURETYPE_TEXTURE);
return true;
}
static boolean P_FindFlatForAnimation(anim_t *anim, animdef_t *animdef)
{
if (R_CheckFlatNumForName(animdef->startname) == -1)
INT32 start = R_CheckTextureNumForName(animdef->startname, TEXTURETYPE_FLAT);
if (start == -1)
return false;
anim->picnum = R_CheckFlatNumForName(animdef->endname);
anim->basepic = R_CheckFlatNumForName(animdef->startname);
anim->basepic = start;
anim->picnum = R_CheckTextureNumForName(animdef->endname, TEXTURETYPE_FLAT);
return true;
}
......@@ -2405,11 +2407,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
y = line->args[3] << FRACBITS;
z = line->args[4] << FRACBITS;
P_UnsetThingPosition(mo);
mo->x += x;
mo->y += y;
mo->z += z;
P_SetThingPosition(mo);
P_SetOrigin(mo, mo->x + x, mo->y + y, mo->z + z);
if (mo->player)
{
......@@ -2417,6 +2415,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
P_SetOrigin(bot, bot->x + x, bot->y + y, bot->z + z);
if (splitscreen && mo->player == &players[secondarydisplayplayer] && camera2.chase)
{
camera2.reset = true;
camera2.x += x;
camera2.y += y;
camera2.z += z;
......@@ -2424,6 +2423,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
}
else if (camera.chase && mo->player == &players[displayplayer])
{
camera.reset = true;
camera.x += x;
camera.y += y;
camera.z += z;
......@@ -2548,7 +2548,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
char *text = Z_Malloc(len + 1, PU_CACHE, NULL);
memcpy(text, lump, len);
text[len] = '\0';
COM_BufInsertText(text);
COM_BufInsertTextEx(text, COM_LUA);
Z_Free(text);
}
}
......@@ -3644,7 +3644,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (mo2->type != MT_EGGTRAP)
continue;
if (mo2->thinker.function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (mo2->thinker.removing)
continue;
P_KillMobj(mo2, NULL, mo, 0);
......@@ -3684,7 +3684,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
case 466: // Set level failure state
{
if (line->args[1])
if (line->args[0])
{
stagefailed = false;
CONS_Debug(DBG_GAMELOGIC, "Stage can be completed successfully!\n");
......@@ -3856,7 +3856,7 @@ void P_SetupSignExit(player_t *player)
// spin all signposts in the level then.
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (think->removing)
continue;
thing = (mobj_t *)think;
......@@ -3894,7 +3894,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag)
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (think->removing)
continue;
mo = (mobj_t *)think;
......@@ -4397,7 +4397,7 @@ static void P_ProcessEggCapsule(player_t *player, sector_t *sector)
// The chimps are my friends.. heeheeheheehehee..... - LouisJM
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
if (mo2->type != MT_EGGTRAP)
......@@ -4677,7 +4677,7 @@ static void P_ProcessZoomTube(player_t *player, mtag_t sectag, boolean end)
player->pflags &= ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SLIDING|PF_CANCARRY);
player->climbing = 0;
if (player->mo->state-states != S_PLAY_ROLL)
if (!P_IsPlayerInState(player, S_PLAY_ROLL))
{
P_SetMobjState(player->mo, S_PLAY_ROLL);
S_StartSound(player->mo, sfx_spin);
......@@ -4758,7 +4758,7 @@ static void P_ProcessRopeHang(player_t *player, mtag_t sectag)
if (player->cmd.buttons & BT_SPIN)
return;
if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate])
if (!(player->pflags & PF_SLIDING) && P_IsPlayerInState(player, S_PLAY_PAIN))
return;
if (player->exiting)
......@@ -6238,7 +6238,7 @@ static void P_DoPortalCopyFromLine(sector_t *dest_sector, int plane_type, int ta
}
}
static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num, UINT32 *result)
static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num, UINT32 *result, boolean ceiling)
{
sectorportal_t *secportal = NULL;
......@@ -6246,8 +6246,8 @@ static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num,
{
*num = P_NewSectorPortal();
secportal = &secportals[*num];
secportal->origin.x = sector->soundorg.x;
secportal->origin.y = sector->soundorg.y;
secportal->target = sector;
secportal->ceiling = ceiling;
*result = *num;
}
else
......@@ -6261,12 +6261,12 @@ static sectorportal_t *P_SectorGetPortalOrCreate(sector_t *sector, UINT32 *num,
static sectorportal_t *P_SectorGetFloorPortalOrCreate(sector_t *sector, UINT32 *result)
{
return P_SectorGetPortalOrCreate(sector, &sector->portal_floor, result);
return P_SectorGetPortalOrCreate(sector, &sector->portal_floor, result, false);
}
static sectorportal_t *P_SectorGetCeilingPortalOrCreate(sector_t *sector, UINT32 *result)
{
return P_SectorGetPortalOrCreate(sector, &sector->portal_ceiling, result);
return P_SectorGetPortalOrCreate(sector, &sector->portal_ceiling, result, true);
}
static void P_CopySectorPortalToLines(UINT32 portal_num, int sector_tag)
......@@ -8805,7 +8805,7 @@ void T_Pusher(pusher_t *p)
if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
continue;
if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics))
if (thing->player && P_IsPlayerInState(thing->player, S_PLAY_PAIN) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics))
continue;
inFOF = touching = moved = false;
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -162,7 +162,7 @@ void Command_CountMobjs_f(void)
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
if (((mobj_t *)th)->type == i)
......@@ -182,7 +182,7 @@ void Command_CountMobjs_f(void)
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
if (((mobj_t *)th)->type == i)
......@@ -348,6 +348,7 @@ void P_RemoveThinkerDelayed(thinker_t *thinker)
void P_RemoveThinker(thinker_t *thinker)
{
LUA_InvalidateUserdata(thinker);
thinker->removing = true;
thinker->function.acp1 = (actionf_p1)P_RemoveThinkerDelayed;
}
......@@ -726,6 +727,7 @@ void P_Ticker(boolean run)
{
P_MapStart();
R_UpdateMobjInterpolators();
R_UpdateLevelInterpolators();
OP_ObjectplaceMovement(&players[0]);
P_MoveChaseCamera(&players[0], &camera, false);
R_UpdateViewInterpolation();
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2025 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -47,6 +47,7 @@
#include "m_cheat.h"
// Thok camera snap (ctrl-f "chalupa")
#include "g_input.h"
#include "simple_hashmap.h"
#ifdef HW3SOUND
#include "hardware/hw3sound.h"
......@@ -435,7 +436,7 @@ UINT8 P_FindLowestMare(void)
// to find the egg capsule with the lowest mare
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -488,7 +489,7 @@ boolean P_TransferToNextMare(player_t *player)
// to find the closest axis point
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -539,7 +540,7 @@ static mobj_t *P_FindAxis(INT32 mare, INT32 axisnum)
// to find the closest axis point
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -574,7 +575,7 @@ static mobj_t *P_FindAxisTransfer(INT32 mare, INT32 axisnum, mobjtype_t type)
// to find the closest axis point
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -615,7 +616,7 @@ void P_TransferToAxis(player_t *player, INT32 axisnum)
// to find the closest axis point
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -669,7 +670,7 @@ static void P_DeNightserizePlayer(player_t *player)
player->powers[pw_carry] = CR_NIGHTSFALL;
player->powers[pw_underwater] = 0;
player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_SHIELDDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST);
player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_STARTJUMP|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST);
player->secondjump = 0;
player->homing = 0;
player->climbing = 0;
......@@ -716,7 +717,7 @@ static void P_DeNightserizePlayer(player_t *player)
// Check to see if the player should be killed.
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -802,7 +803,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
if (mapheaderinfo[gamemap-1]->nightstimer[newmare] > 0)
nighttime = mapheaderinfo[gamemap-1]->nightstimer[newmare];
player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_SHIELDDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING);
player->pflags &= ~(PF_SPINDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_SPINNING|PF_DRILLING);
player->homing = 0;
player->mo->fuse = 0;
player->speed = 0;
......@@ -968,6 +969,33 @@ pflags_t P_GetJumpFlags(player_t *player)
return PF_JUMPED;
}
// If the state is a custom state for the player's skin, retrieve its "canonical" state
// e.g. S_SKIN_BIGTHECAT_WALK => S_PLAY_WALK
statenum_t P_GetCanonicalPlayerState(player_t *player, statenum_t state)
{
skin_t *skin = skins[player->skin];
statenum_t mappedstate;
SIMPLEHASH_FIND_INT(skin->customtodefaultstate, hashentry_int32_int32_t, state, state, mappedstate)
return mappedstate;
}
boolean P_IsPlayerInState(player_t *player, statenum_t state)
{
return (P_GetCanonicalPlayerState(player, player->mo->state - states) == state);
}
boolean P_IsPlayerInSuperTransformationState(player_t *player)
{
statenum_t state = player->mo->state - states;
return (state >= S_PLAY_SUPER_TRANS1 && state <= S_PLAY_SUPER_TRANS6);
}
boolean P_IsPlayerInNightsTransformationState(player_t *player)
{
statenum_t state = player->mo->state - states;
return (state >= S_PLAY_NIGHTS_TRANS1 && state <= S_PLAY_NIGHTS_TRANS6);
}
//
// P_PlayerInPain
//
......@@ -976,11 +1004,14 @@ pflags_t P_GetJumpFlags(player_t *player)
//
boolean P_PlayerInPain(player_t *player)
{
if (P_MobjWasRemoved(player->mo))
return false;
// no silly, sliding isn't pain
if (!(player->pflags & PF_SLIDING) && player->mo->state == &states[player->mo->info->painstate] && player->powers[pw_flashing])
return true;
if (player->mo->state == &states[S_PLAY_STUN])
if (P_IsPlayerInState(player, S_PLAY_STUN))
return true;
return false;
......@@ -1004,7 +1035,7 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor)
fixed_t fallbackspeed;
P_ResetPlayer(player);
P_SetMobjState(player->mo, player->mo->info->painstate);
P_SetMobjState(player->mo, S_PLAY_PAIN);
if (player->mo->eflags & MFE_VERTICALFLIP)
player->mo->z--;
......@@ -1089,6 +1120,13 @@ void P_ResetPlayer(player_t *player)
if (player->mo->tracer && !P_MobjWasRemoved(player->mo->tracer))
{
player->mo->tracer->flags |= MF_PUSHABLE;
// goose the mom a little bit to trigger gravity to process for a tic
if (player->mo->tracer->eflags & MFE_VERTICALFLIP)
player->mo->tracer->momz -= 1;
else
player->mo->tracer->momz += 1;
P_SetTarget(&player->mo->tracer->tracer, NULL);
}
P_SetTarget(&player->mo->tracer, NULL);
......@@ -1352,6 +1390,8 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
P_PlayJingle(player, JT_SUPER);
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
player->mo->momx = player->mo->momy = player->mo->momz = player->cmomx = player->cmomy = player->rmomx = player->rmomy = 0;
// Transformation animation
......@@ -1368,11 +1408,8 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
player->powers[pw_sneakers] = 0;
}
if (G_CoopGametype())
S_StartSound(player->mo, sfx_supert); //only hear it near yourself in co-op
else
if (!G_CoopGametype())
{
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is now super.\\\\\\\\", player_names[player-players]));
......@@ -1407,7 +1444,7 @@ void P_DoSuperDetransformation(player_t *player)
if (!G_CoopGametype())
player->powers[pw_flashing] = flashingtics-1;
if (player->mo->sprite2 & SPR2F_SUPER)
if (player->mo->sprite2 & FF_SPR2SUPER)
P_SetMobjState(player->mo, player->mo->state-states);
// Inform the netgame that the champion has fallen in the heat of battle.
......@@ -1889,7 +1926,7 @@ void P_SpawnShieldOrb(player_t *player)
// blaze through the thinkers to see if an orb already exists!
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
shieldobj = (mobj_t *)th;
......@@ -2071,6 +2108,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
ghost->renderflags = mobj->renderflags;
ghost->blendmode = mobj->blendmode;
ghost->alpha = mobj->alpha;
ghost->spritexscale = mobj->spritexscale;
ghost->spriteyscale = mobj->spriteyscale;
......@@ -2372,7 +2410,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
if (dorollstuff)
{
if ((player->charability2 == CA2_SPINDASH) && !((player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_THOKKED) && !(player->charability == CA_THOK && player->secondjump)
&& (player->cmd.buttons & BT_SPIN) && (FixedHypot(player->mo->momx, player->mo->momy) > (5*player->mo->scale)))
&& (player->cmd.buttons & BT_SPIN) && (FixedHypot(player->mo->momx, player->mo->momy) >= (5*player->mo->scale)))
player->pflags = (player->pflags|PF_SPINNING) & ~PF_THOKKED;
else if (!(player->pflags & PF_STARTDASH))
player->pflags &= ~PF_SPINNING;
......@@ -2380,7 +2418,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
if (player->pflags & PF_BOUNCING)
{
if (dorollstuff && player->mo->state-states != S_PLAY_BOUNCE_LANDING)
if (dorollstuff && !P_IsPlayerInState(player, S_PLAY_BOUNCE_LANDING))
{
P_MobjCheckWater(player->mo);
player->mo->momz *= -1;
......@@ -2417,9 +2455,9 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
player->pflags &= ~PF_GLIDING;
}
else if (player->charability == CA_GLIDEANDCLIMB && player->pflags & PF_THOKKED && !(player->pflags & (PF_JUMPED|PF_SHIELDABILITY))
&& (player->mo->floorz != player->mo->watertop) && player->mo->state-states == S_PLAY_FALL)
&& (player->mo->floorz != player->mo->watertop) && P_IsPlayerInState(player, S_PLAY_FALL))
{
if (player->mo->state-states != S_PLAY_GLIDE_LANDING)
if (!P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
{
P_ResetPlayer(player);
P_SetMobjState(player->mo, S_PLAY_GLIDE_LANDING);
......@@ -2440,7 +2478,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
else if (player->charability2 == CA2_MELEE
&& ((player->panim == PA_ABILITY2) || (player->charability == CA_TWINSPIN && player->panim == PA_ABILITY && player->cmd.buttons & (BT_JUMP|BT_SPIN))))
{
if (player->mo->state-states != S_PLAY_MELEE_LANDING)
if (!P_IsPlayerInState(player, S_PLAY_MELEE_LANDING))
{
mobjtype_t type = player->revitem;
P_SetMobjState(player->mo, S_PLAY_MELEE_LANDING);
......@@ -2488,7 +2526,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
}
}
}
else if (player->charability == CA_GLIDEANDCLIMB && (player->mo->state-states == S_PLAY_GLIDE_LANDING))
else if (player->charability == CA_GLIDEANDCLIMB && (P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING)))
;
else if (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2)
;
......@@ -2511,10 +2549,10 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH)
P_SetMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= runspd
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
&& (player->panim != PA_RUN || P_IsPlayerInState(player, S_PLAY_FLOAT_RUN)))
P_SetMobjState(player->mo, S_PLAY_RUN);
else if ((player->rmomx || player->rmomy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
&& (player->panim != PA_WALK || P_IsPlayerInState(player, S_PLAY_FLOAT)))
P_SetMobjState(player->mo, S_PLAY_WALK);
else if (!player->rmomx && !player->rmomy && player->panim != PA_IDLE)
P_SetMobjState(player->mo, S_PLAY_STND);
......@@ -2524,10 +2562,10 @@ boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff)
if (player->charflags & SF_DASHMODE && player->dashmode >= DASHMODE_THRESHOLD && player->panim != PA_DASH)
P_SetMobjState(player->mo, S_PLAY_DASH);
else if (player->speed >= runspd
&& (player->panim != PA_RUN || player->mo->state-states == S_PLAY_FLOAT_RUN))
&& (player->panim != PA_RUN || P_IsPlayerInState(player, S_PLAY_FLOAT_RUN)))
P_SetMobjState(player->mo, S_PLAY_RUN);
else if ((player->mo->momx || player->mo->momy)
&& (player->panim != PA_WALK || player->mo->state-states == S_PLAY_FLOAT))
&& (player->panim != PA_WALK || P_IsPlayerInState(player, S_PLAY_FLOAT)))
P_SetMobjState(player->mo, S_PLAY_WALK);
else if (!player->mo->momx && !player->mo->momy && player->panim != PA_IDLE)
P_SetMobjState(player->mo, S_PLAY_STND);
......@@ -3300,6 +3338,7 @@ static void P_DoPlayerHeadSigns(player_t *player)
sign->frame = 2|FF_FULLBRIGHT;
}
}
}
if (!P_MobjWasRemoved(sign) && splitscreen) // Hide the sign from yourself in splitscreen - In single-screen, it wouldn't get spawned if it shouldn't be visible
{
......@@ -3338,7 +3377,6 @@ static void P_DoPlayerHeadSigns(player_t *player)
#endif
}
}
}
//
// P_DoClimbing
......@@ -3701,9 +3739,9 @@ static void P_DoClimbing(player_t *player)
climb = false;
if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz)
&& player->mo->state-states != S_PLAY_CLIMB)
&& !P_IsPlayerInState(player, S_PLAY_CLIMB))
P_SetMobjState(player->mo, S_PLAY_CLIMB);
else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING)
else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && !P_IsPlayerInState(player, S_PLAY_CLING))
P_SetMobjState(player->mo, S_PLAY_CLING);
if (!floorclimb)
......@@ -3736,9 +3774,9 @@ static void P_DoClimbing(player_t *player)
climb = false;
if (player->climbing && climb && (player->mo->momx || player->mo->momy || player->mo->momz)
&& player->mo->state-states != S_PLAY_CLIMB)
&& !P_IsPlayerInState(player, S_PLAY_CLIMB))
P_SetMobjState(player->mo, S_PLAY_CLIMB);
else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && player->mo->state-states != S_PLAY_CLING)
else if ((!(player->mo->momx || player->mo->momy || player->mo->momz) || !climb) && !P_IsPlayerInState(player, S_PLAY_CLING))
P_SetMobjState(player->mo, S_PLAY_CLING);
if (cmd->buttons & BT_SPIN && !(player->pflags & PF_JUMPSTASIS))
......@@ -4115,7 +4153,7 @@ static void P_DoTeeter(player_t *player)
teeteryl = teeteryh = player->mo->y;
couldteeter = false;
solidteeter = teeter;
if (!P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_CheckSolidsTeeter))
if (!P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_CheckSolidsTeeter, tmthing))
goto teeterdone; // we've found something that stops us teetering at all
teeterdone:
teeter = solidteeter;
......@@ -4200,7 +4238,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
if (player->pflags & PF_ATTACKDOWN || player->climbing || (G_TagGametype() && !(player->pflags & PF_TAGIT)))
return;
// Fire a fireball if we have the Fire Flower powerup!
if (((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER) && !(player->weapondelay))
{
player->pflags |= PF_ATTACKDOWN;
......@@ -4212,7 +4249,6 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
return;
}
// No ringslinging outside of ringslinger!
if (!G_RingSlingerGametype() || player->weapondelay)
return;
......@@ -4391,7 +4427,34 @@ static void P_DoSuperStuff(player_t *player)
// If you're super and not Sonic, de-superize!
if (!(ALL7EMERALDS(emeralds) && player->charflags & SF_SUPER))
{
P_DoSuperDetransformation(player);
player->powers[pw_super] = 0;
P_SetMobjState(player->mo, S_PLAY_STND);
if (P_IsLocalPlayer(player))
{
music_stack_noposition = true; // HACK: Do not reposition next music
music_stack_fadeout = MUSICRATE/2; // HACK: Fade out current music
}
P_RestoreMusic(player);
P_SpawnShieldOrb(player);
// Restore color
if ((player->powers[pw_shield] & SH_STACK) == SH_FIREFLOWER)
{
player->mo->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
}
else
{
player->mo->color = P_GetPlayerColor(player);
G_GhostAddColor(GHC_NORMAL);
}
if (!G_CoopGametype())
{
HU_SetCEchoFlags(0);
HU_SetCEchoDuration(5);
HU_DoCEcho(va("%s\\is no longer super.\\\\\\\\", player_names[player-players]));
}
return;
}
......@@ -4401,7 +4464,7 @@ static void P_DoSuperStuff(player_t *player)
G_GhostAddColor(GHC_SUPER);
if (player->mo->state == &states[S_PLAY_SUPER_TRANS6]) // stop here for now
if (P_IsPlayerInState(player, S_PLAY_SUPER_TRANS6)) // stop here for now
return;
// Deplete one ring every second while super
......@@ -4418,37 +4481,28 @@ static void P_DoSuperStuff(player_t *player)
// Ran out of rings while super!
if (player->rings <= 0 || player->exiting)
{
P_DoSuperDetransformation(player);
}
}
}
//
// P_SuperReady
//
// Returns true if player is ready to transform or detransform
// Returns true if player is ready to turn super, duh
//
boolean P_SuperReady(player_t *player, boolean transform)
boolean P_SuperReady(player_t *player)
{
if (!transform &&
(player->powers[pw_super] < TICRATE*3/2
|| !G_CoopGametype())) // No turning back in competitive!
return false;
else if (transform
&& (player->powers[pw_super]
|| !ALL7EMERALDS(emeralds)
|| !(player->rings >= 50)))
return false;
if (player->mo
if (!player->powers[pw_super]
&& !player->powers[pw_invulnerability]
&& !player->powers[pw_tailsfly]
&& !player->powers[pw_carry]
&& (player->charflags & SF_SUPER)
&& !P_PlayerInPain(player)
&& !player->climbing
&& !(player->pflags & (PF_JUMPSTASIS|PF_THOKKED|PF_STARTDASH|PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY))
&& ((player->pflags & PF_JUMPED) || (P_IsObjectOnGround(player->mo) && (player->panim == PA_IDLE || player->panim == PA_EDGE
|| player->panim == PA_WALK || player->panim == PA_RUN || (player->charflags & SF_DASHMODE && player->panim == PA_DASH))))
&& !(maptol & TOL_NIGHTS))
&& (player->pflags & PF_JUMPED)
&& !(player->powers[pw_shield] & SH_NOSTACK)
&& !(maptol & TOL_NIGHTS)
&& ALL7EMERALDS(emeralds)
&& (player->rings >= 50))
return true;
return false;
......@@ -4546,6 +4600,13 @@ void P_DoJump(player_t *player, boolean soundandstate, boolean allowflip)
player->mo->momz += player->mo->tracer->momz;
if (!P_IsObjectOnGround(player->mo->tracer))
P_SetObjectMomZ(player->mo->tracer, -9*FRACUNIT, true);
// goose the mom a little bit to trigger gravity to process for a tic
if (player->mo->tracer->eflags & MFE_VERTICALFLIP)
player->mo->tracer->momz -= 1;
else
player->mo->tracer->momz += 1;
player->mo->tracer->flags |= MF_PUSHABLE;
P_SetTarget(&player->mo->tracer->tracer, NULL);
}
......@@ -4686,7 +4747,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
{
boolean canstand = true; // can we stand on the ground? (mostly relevant for slopes)
if (player->pflags & PF_STASIS
&& (player->pflags & PF_JUMPSTASIS || player->mo->state-states != S_PLAY_GLIDE_LANDING))
&& (player->pflags & PF_JUMPSTASIS || !P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING)))
return;
if (cmd->buttons & BT_SPIN)
......@@ -4706,7 +4767,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
{
case CA2_SPINDASH: // Spinning and Spindashing
// Start revving
if ((cmd->buttons & BT_SPIN) && (player->speed < FixedMul(5<<FRACBITS, player->mo->scale) || player->mo->state - states == S_PLAY_GLIDE_LANDING)
if ((cmd->buttons & BT_SPIN) && (player->speed < FixedMul(5<<FRACBITS, player->mo->scale) || P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
&& !player->mo->momz && onground && !(player->pflags & (PF_SPINDOWN|PF_SPINNING))
&& canstand)
{
......@@ -4721,7 +4782,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
// Revving
else if ((cmd->buttons & BT_SPIN) && (player->pflags & PF_STARTDASH))
{
if (player->speed > 5*player->mo->scale)
if (player->speed >= 5*player->mo->scale)
{
player->pflags &= ~PF_STARTDASH;
P_SetMobjState(player->mo, S_PLAY_ROLL);
......@@ -4761,9 +4822,8 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
if (!player->spectator)
S_StartSound(player->mo, sfx_spin);
}
else
// Catapult the player from a spindash rev!
if (onground && !(player->pflags & PF_SPINDOWN) && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING))
else if (onground && !(player->pflags & PF_SPINDOWN) && (player->pflags & PF_STARTDASH) && (player->pflags & PF_SPINNING))
{
player->pflags &= ~PF_STARTDASH;
if (player->powers[pw_carry] == CR_BRAKGOOP)
......@@ -4996,7 +5056,7 @@ void P_DoBubbleBounce(player_t *player)
//
void P_DoAbilityBounce(player_t *player, boolean changemomz)
{
if (player->mo->state-states == S_PLAY_BOUNCE_LANDING)
if (P_IsPlayerInState(player, S_PLAY_BOUNCE_LANDING))
return;
if (changemomz)
......@@ -5095,7 +5155,7 @@ void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range)
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -5147,7 +5207,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
{
mobj_t *lockonshield = NULL;
if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SHIELDDOWN)
if ((player->powers[pw_shield] & SH_NOSTACK) && !player->powers[pw_super] && !(player->pflags & PF_SPINDOWN)
&& ((!(player->pflags & PF_THOKKED) || (((player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP || (player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT) && player->secondjump == UINT8_MAX) ))) // thokked is optional if you're bubblewrapped / 3dblasted
{
if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ATTRACT && !(player->charflags & SF_NOSHIELDABILITY))
......@@ -5177,7 +5237,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
}
}
}
if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SHIELD && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Shield button effects
if ((!(player->charflags & SF_NOSHIELDABILITY)) && (cmd->buttons & BT_SPIN && !LUA_HookPlayer(player, HOOK(ShieldSpecial)))) // Spin button effects
{
// Force stop
if ((player->powers[pw_shield] & ~(SH_FORCEHP|SH_STACK)) == SH_FORCE)
......@@ -5266,7 +5326,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock
//
// Handles player jumping
//
static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd, boolean spinshieldhack)
static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
{
mobj_t *lockonthok = NULL, *visual = NULL;
......@@ -5299,13 +5359,12 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd, boolean spinshieldhac
;
else if (P_PlayerShieldThink(player, cmd, lockonthok, visual))
;
else if (cmd->buttons & BT_SPIN)
else if ((cmd->buttons & BT_SPIN))
{
if (spinshieldhack && !(player->pflags & PF_SPINDOWN) && P_SuperReady(player, true)
&& !player->powers[pw_invulnerability] && !(player->powers[pw_shield] & SH_NOSTACK)) // These two checks are no longer in P_SuperReady
if (!(player->pflags & PF_SPINDOWN) && P_SuperReady(player))
{
// If you're using two-button play, can turn Super and aren't already,
// and you don't have a shield, then turn Super!
// If you can turn super and aren't already,
// and you don't have a shield, do it!
P_DoSuperTransformation(player, false);
}
else if (!LUA_HookPlayer(player, HOOK(JumpSpinSpecial)))
......@@ -5408,6 +5467,12 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd, boolean spinshieldhac
}
else if (player->pflags & PF_SLIDING || ((gametyperules & GTR_TEAMFLAGS) && player->gotflag) || player->pflags & PF_SHIELDABILITY)
;
/*else if (P_SuperReady(player))
{
// If you can turn super and aren't already,
// and you don't have a shield, do it!
P_DoSuperTransformation(player, false);
}*/
else if (player->pflags & PF_JUMPED)
{
if (!LUA_HookPlayer(player, HOOK(AbilitySpecial)))
......@@ -6072,7 +6137,7 @@ static void P_3dMovement(player_t *player)
// When sliding, don't allow forward/back
if (player->pflags & PF_SLIDING)
cmd->forwardmove = 0;
else if (onground && player->mo->state == states+S_PLAY_PAIN)
else if (onground && P_IsPlayerInState(player, S_PLAY_PAIN))
P_SetMobjState(player->mo, S_PLAY_WALK);
player->aiming = cmd->aiming<<FRACBITS;
......@@ -6125,7 +6190,7 @@ static void P_3dMovement(player_t *player)
{
if (player->pflags & PF_BOUNCING)
{
if (player->mo->state-states == S_PLAY_BOUNCE_LANDING)
if (P_IsPlayerInState(player, S_PLAY_BOUNCE_LANDING))
{
thrustfactor = player->thrustfactor*8;
acceleration = player->accelstart/8 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration/8;
......@@ -6462,7 +6527,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
// Find next waypoint
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -6498,7 +6563,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
{
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -6527,7 +6592,7 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
{
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -6878,10 +6943,10 @@ static void P_DoNiGHTSCapsule(player_t *player)
{
if (player->mo->momx || player->mo->momy || player->mo->momz)
{
if (player->mo->state != &states[S_PLAY_NIGHTS_PULL])
if (!P_IsPlayerInState(player, S_PLAY_NIGHTS_PULL))
P_SetMobjState(player->mo, S_PLAY_NIGHTS_PULL);
}
else if (player->mo->state != &states[S_PLAY_NIGHTS_ATTACK])
else if (!P_IsPlayerInState(player, S_PLAY_NIGHTS_ATTACK))
{
S_StartSound(player->mo, sfx_spin);
P_SetMobjState(player->mo, S_PLAY_NIGHTS_ATTACK);
......@@ -6897,7 +6962,7 @@ static void P_DoNiGHTSCapsule(player_t *player)
if (!(player->charflags & SF_NONIGHTSROTATION))
{
if ((player->mo->state == &states[S_PLAY_NIGHTS_PULL])
if ((P_IsPlayerInState(player, S_PLAY_NIGHTS_PULL))
&& (player->mo->sprite2 == SPR2_NPUL))
player->mo->spriteroll -= ANG30;
else
......@@ -7212,15 +7277,11 @@ static void P_NiGHTSMovement(player_t *player)
if (playeringame[i] /*&& players[i].powers[pw_carry] == CR_NIGHTSMODE*/
&& (players[i].capsule && players[i].capsule->reactiontime))
capsule = true;
if (!capsule
&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
&& !player->exiting)
if (!capsule && !P_IsPlayerInNightsTransformationState(player) && !player->exiting)
player->nightstime--;
}
else if (!(gametyperules & GTR_RACE)
&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
&& !P_IsPlayerInNightsTransformationState(player)
&& !(player->capsule && player->capsule->reactiontime)
&& !player->exiting)
player->nightstime--;
......@@ -7259,7 +7320,7 @@ static void P_NiGHTSMovement(player_t *player)
// to find the closest axis point
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -7360,8 +7421,7 @@ static void P_NiGHTSMovement(player_t *player)
return;
}
if (player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6])
if (P_IsPlayerInNightsTransformationState(player))
{
player->mo->momx = player->mo->momy = player->mo->momz = 0;
player->mo->spriteroll = 0;
......@@ -7380,14 +7440,14 @@ static void P_NiGHTSMovement(player_t *player)
#if 0//def ROTSPRITE
if (!(player->charflags & SF_NONIGHTSROTATION) && player->mo->momz)
{
if (player->mo->state != &states[S_PLAY_NIGHTS_DRILL])
if (!P_IsPlayerInState(player, S_PLAY_NIGHTS_DRILL))
P_SetMobjState(player->mo, S_PLAY_NIGHTS_DRILL);
player->mo->spriteroll = ANGLE_90;
}
else
#endif
{
if (player->mo->state != &states[S_PLAY_NIGHTS_FLOAT])
if (!P_IsPlayerInState(player, S_PLAY_NIGHTS_FLOAT))
P_SetMobjState(player->mo, S_PLAY_NIGHTS_FLOAT);
player->drawangle += ANGLE_22h;
}
......@@ -8019,7 +8079,7 @@ static void P_SkidStuff(player_t *player)
// Spawn a particle every 3 tics.
if (!(player->skidtime % 3))
{
if (player->mo->state-states == S_PLAY_GLIDE_LANDING)
if (P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
P_SpawnSkidDust(player, player->mo->radius, true);
else
P_SpawnSkidDust(player, 0, false);
......@@ -8039,7 +8099,7 @@ static void P_SkidStuff(player_t *player)
// If your push angle is more than this close to a full 180 degrees, trigger a skid.
if (dang > ANGLE_157h)
{
if (player->mo->state-states != S_PLAY_SKID)
if (!P_IsPlayerInState(player, S_PLAY_SKID))
P_SetMobjState(player->mo, S_PLAY_SKID);
player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS;
S_StartSound(player->mo, sfx_skid);
......@@ -8060,11 +8120,10 @@ void P_MovePlayer(player_t *player)
{
ticcmd_t *cmd;
INT32 i;
boolean spinshieldhack = false; // Hack: Is Spin and Shield bound to the same button (pressed on the same tic)?
fixed_t runspd;
if (player->mo->state >= &states[S_PLAY_SUPER_TRANS1] && player->mo->state <= &states[S_PLAY_SUPER_TRANS6])
if (P_IsPlayerInSuperTransformationState(player))
{
player->mo->momx = player->mo->momy = player->mo->momz = 0;
return;
......@@ -8085,7 +8144,7 @@ void P_MovePlayer(player_t *player)
if ((player->powers[pw_carry] == CR_BRAKGOOP)
|| (player->pflags & PF_GLIDING && player->skidtime)
|| (player->charability2 == CA2_GUNSLINGER && player->panim == PA_ABILITY2)
|| (player->charability2 == CA2_MELEE && player->mo->state-states == S_PLAY_MELEE_LANDING))
|| (player->charability2 == CA2_MELEE && P_IsPlayerInState(player, S_PLAY_MELEE_LANDING)))
player->pflags |= PF_FULLSTASIS;
else if (player->powers[pw_nocontrol])
{
......@@ -8094,7 +8153,7 @@ void P_MovePlayer(player_t *player)
player->pflags |= PF_JUMPSTASIS;
}
if (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)
if (player->charability == CA_GLIDEANDCLIMB && P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
{
player->pflags |= PF_STASIS;
}
......@@ -8159,7 +8218,7 @@ void P_MovePlayer(player_t *player)
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -8312,9 +8371,9 @@ void P_MovePlayer(player_t *player)
// Correct floating when ending up on the ground.
if (onground)
{
if (player->mo->state-states == S_PLAY_FLOAT)
if (P_IsPlayerInState(player, S_PLAY_FLOAT))
P_SetMobjState(player->mo, S_PLAY_WALK);
else if (player->mo->state-states == S_PLAY_FLOAT_RUN)
else if (P_IsPlayerInState(player, S_PLAY_FLOAT_RUN))
P_SetMobjState(player->mo, S_PLAY_RUN);
}
......@@ -8380,7 +8439,7 @@ void P_MovePlayer(player_t *player)
fixed_t glidespeed = player->actionspd;
fixed_t momx = mo->momx - player->cmomx, momy = mo->momy - player->cmomy;
angle_t angle, moveangle = R_PointToAngle2(0, 0, momx, momy);
boolean swimming = mo->state - states == S_PLAY_SWIM;
boolean swimming = P_IsPlayerInState(player, S_PLAY_SWIM);
boolean in2d = mo->flags2 & MF2_TWOD || twodlevel;
if (player->powers[pw_super] || player->powers[pw_sneakers])
......@@ -8527,7 +8586,7 @@ void P_MovePlayer(player_t *player)
}
}
}
else if (player->mo->state-states == S_PLAY_BOUNCE)
else if (P_IsPlayerInState(player, S_PLAY_BOUNCE))
P_SetMobjState(player->mo, S_PLAY_FALL);
// If you're running fast enough, you can create splashes as you run in shallow water.
......@@ -8571,7 +8630,7 @@ void P_MovePlayer(player_t *player)
if (!(player->charability == CA_FLY || player->charability == CA_SWIM)) // why are you flying when you cannot fly?!
{
if (player->powers[pw_tailsfly]
|| player->mo->state-states == S_PLAY_FLY_TIRED)
|| P_IsPlayerInState(player, S_PLAY_FLY_TIRED))
{
if (onground)
P_SetMobjState(player->mo, S_PLAY_WALK);
......@@ -8639,11 +8698,11 @@ void P_MovePlayer(player_t *player)
else
{
// Tails-gets-tired Stuff
if (player->panim == PA_ABILITY && player->mo->state-states != S_PLAY_FLY_TIRED)
if (player->panim == PA_ABILITY && !P_IsPlayerInState(player, S_PLAY_FLY_TIRED))
P_SetMobjState(player->mo, S_PLAY_FLY_TIRED);
if (player->charability == CA_FLY && (leveltime % 10 == 0)
&& player->mo->state-states == S_PLAY_FLY_TIRED
&& P_IsPlayerInState(player, S_PLAY_FLY_TIRED)
&& !(player->mo->eflags & MFE_UNDERWATER)
&& !player->spectator)
S_StartSound(player->mo, sfx_pudpud);
......@@ -8682,13 +8741,10 @@ void P_MovePlayer(player_t *player)
&& !(player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)))
P_ElementalFire(player, false);
if ((cmd->buttons & (BT_SPIN|BT_SHIELD)) == (BT_SPIN|BT_SHIELD) && !(player->pflags & (PF_SPINDOWN|PF_SHIELDDOWN)))
spinshieldhack = true; // Spin and Shield is bound to the same button (pressed on the same tic), so enable two-button play (Jump and Spin+Shield)
P_DoSpinAbility(player, cmd);
// jumping
P_DoJumpStuff(player, cmd, spinshieldhack);
P_DoJumpStuff(player, cmd);
// If you're not spinning, you'd better not be spindashing!
if (!(player->pflags & PF_SPINNING) && player->powers[pw_carry] != CR_NIGHTSMODE)
......@@ -8741,7 +8797,7 @@ void P_MovePlayer(player_t *player)
}
// Otherwise, face the direction you're travelling.
else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_DASH || player->panim == PA_ROLL || player->panim == PA_JUMP
|| (player->panim == PA_ABILITY && player->mo->state-states == S_PLAY_GLIDE))
|| (player->panim == PA_ABILITY && P_IsPlayerInState(player, S_PLAY_GLIDE)))
player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
// Update the local angle control.
......@@ -8776,25 +8832,10 @@ void P_MovePlayer(player_t *player)
P_PlayerFlagBurst(player, true);
}
// Check for fire and shield buttons
// check for fire
if (!player->exiting)
{
P_DoFiring(player, cmd);
// Shield button behavior
// Check P_PlayerShieldThink for actual shields!
if ((cmd->buttons & BT_SHIELD) && !(player->pflags & PF_SHIELDDOWN) && !spinshieldhack)
{
// Transform into super if we can!
if (P_SuperReady(player, true))
P_DoSuperTransformation(player, false);
// Detransform from super if we can!
else if (P_SuperReady(player, false))
P_DoSuperDetransformation(player);
}
}
{
boolean atspinheight = false;
fixed_t oldheight = player->mo->height;
......@@ -8812,6 +8853,8 @@ void P_MovePlayer(player_t *player)
player->mo->height = P_GetPlayerSpinHeight(player);
atspinheight = true;
}
else if (player->powers[pw_carry] == CR_PLAYER || player->powers[pw_carry] == CR_PTERABYTE) // You're slightly shorter while being carried
player->mo->height = FixedDiv(P_GetPlayerHeight(player), FixedDiv(14*FRACUNIT,10*FRACUNIT));
else
player->mo->height = P_GetPlayerHeight(player);
......@@ -9015,7 +9058,7 @@ static void P_DoRopeHang(player_t *player)
return;
}
if (player->mo->state-states != S_PLAY_RIDE)
if (!P_IsPlayerInState(player, S_PLAY_RIDE))
P_SetMobjState(player->mo, S_PLAY_RIDE);
// If not allowed to move, we're done here.
......@@ -9142,7 +9185,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius)
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (think->removing)
continue;
mo = (mobj_t *)think;
......@@ -9240,7 +9283,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction,
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (think->removing)
continue;
mo = (mobj_t *)think;
......@@ -9359,7 +9402,7 @@ mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet)
for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next)
{
if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (think->removing)
continue;
mo = (mobj_t *)think;
......@@ -9505,7 +9548,7 @@ void P_FindEmerald(void)
// to find all emeralds
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -9813,7 +9856,7 @@ static CV_PossibleValue_t campos_cons_t[] = { {INT32_MIN, "MIN"}, {INT32_MAX, "M
consvar_t cv_cam_dist = CVAR_INIT ("cam_curdist", "160", CV_FLOAT|CV_ALLOWLUA, campos_cons_t, NULL);
consvar_t cv_cam_height = CVAR_INIT ("cam_curheight", "25", CV_FLOAT|CV_ALLOWLUA, campos_cons_t, NULL);
consvar_t cv_cam_still = CVAR_INIT ("cam_still", "Off", CV_ALLOWLUA, CV_OnOff, NULL);
consvar_t cv_cam_speed = CVAR_INIT ("cam_speed", "0.3", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL);
consvar_t cv_cam_speed = CVAR_INIT ("cam_speed", "0.4", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL);
consvar_t cv_cam_rotate = CVAR_INIT ("cam_rotate", "0", CV_CALL|CV_NOINIT|CV_ALLOWLUA, CV_CamRotate, CV_CamRotate_OnChange);
consvar_t cv_cam_rotspeed = CVAR_INIT ("cam_rotspeed", "10", CV_SAVE|CV_ALLOWLUA, rotation_cons_t, NULL);
consvar_t cv_cam_turnmultiplier = CVAR_INIT ("cam_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, multiplier_cons_t, NULL);
......@@ -9822,7 +9865,7 @@ consvar_t cv_cam_adjust = CVAR_INIT ("cam_adjust", "On", CV_SAVE|CV_ALLOWLUA, CV
consvar_t cv_cam2_dist = CVAR_INIT ("cam2_curdist", "160", CV_FLOAT|CV_ALLOWLUA, campos_cons_t, NULL);
consvar_t cv_cam2_height = CVAR_INIT ("cam2_curheight", "25", CV_FLOAT|CV_ALLOWLUA, campos_cons_t, NULL);
consvar_t cv_cam2_still = CVAR_INIT ("cam2_still", "Off", CV_ALLOWLUA, CV_OnOff, NULL);
consvar_t cv_cam2_speed = CVAR_INIT ("cam2_speed", "0.3", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL);
consvar_t cv_cam2_speed = CVAR_INIT ("cam2_speed", "0.4", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, CV_CamSpeed, NULL);
consvar_t cv_cam2_rotate = CVAR_INIT ("cam2_rotate", "0", CV_CALL|CV_NOINIT|CV_ALLOWLUA, CV_CamRotate, CV_CamRotate2_OnChange);
consvar_t cv_cam2_rotspeed = CVAR_INIT ("cam2_rotspeed", "10", CV_SAVE|CV_ALLOWLUA, rotation_cons_t, NULL);
consvar_t cv_cam2_turnmultiplier = CVAR_INIT ("cam2_turnmultiplier", "0.75", CV_FLOAT|CV_SAVE|CV_ALLOWLUA, multiplier_cons_t, NULL);
......@@ -9952,9 +9995,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
&& !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value)
&& !(twodlevel || (mo->flags2 & MF2_TWOD)))
sign = mo->target;
else if ((player->powers[pw_carry] == CR_NIGHTSMODE)
&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1]
&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6]))
else if (player->powers[pw_carry] == CR_NIGHTSMODE && !P_IsPlayerInNightsTransformationState(player))
{
P_CalcChasePostImg(player, thiscam);
return true;
......@@ -9965,15 +10006,42 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || tutorialmode))
{
if (player->spectator) // force cam off for spectators
return true;
if (player->spectator || !thiscam->chase)
{
// set the values to the player's values so they can still be used
thiscam->x = player->mo->x;
thiscam->y = player->mo->y;
thiscam->z = player->viewz;
thiscam->momx = player->mo->momx;
thiscam->momy = player->mo->momy;
thiscam->momz = player->mo->momz;
if (!cv_chasecam.value && thiscam == &camera)
return true;
if (thiscam == &camera)
{
// when not spectating, use local angles
if (&players[displayplayer] == &players[consoleplayer]) {
thiscam->angle = localangle;
thiscam->aiming = localaiming;
}
else
{
thiscam->angle = players[displayplayer].cmd.angleturn << 16;
thiscam->aiming = players[displayplayer].cmd.aiming << 16;
}
}
else if (thiscam == &camera2)
{
// i dont think secondarydisplayplayer changes, so we should be fine.
thiscam->angle = localangle2;
thiscam->aiming = localaiming2;
}
if (!cv_chasecam2.value && thiscam == &camera2)
thiscam->subsector = player->mo->subsector;
thiscam->floorz = player->mo->floorz;
thiscam->ceilingz = player->mo->ceilingz;
return true;
}
}
if (!thiscam->chase && !resetcalled)
{
......@@ -10906,7 +10974,7 @@ static mobj_t *P_GetAxis(INT32 num)
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mobj = (mobj_t *)th;
......@@ -11271,7 +11339,7 @@ static void P_MinecartThink(player_t *player)
}
}
if (player->mo->state-states != S_PLAY_STND)
if (!P_IsPlayerInState(player, S_PLAY_STND))
{
P_SetMobjState(player->mo, S_PLAY_STND);
player->mo->tics = -1;
......@@ -11349,12 +11417,12 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
}
else if (player->panim == PA_PAIN)
backwards /= 16;
else if (player->mo->state-states == S_PLAY_GASP)
else if (P_IsPlayerInState(player, S_PLAY_GASP))
{
backwards /= 16;
zoffs += 12*FRACUNIT;
}
else if (player->mo->state-states == S_PLAY_EDGE)
else if (P_IsPlayerInState(player, S_PLAY_EDGE))
{
backwards /= 16;
zoffs = 3*FRACUNIT;
......@@ -11383,13 +11451,13 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
}
else if (player->panim == PA_SPRING || player->panim == PA_JUMP)
chosenstate = S_TAILSOVERLAY_MINUS60DEGREES;
else if (player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE)
else if (player->panim == PA_FALL || P_IsPlayerInState(player, S_PLAY_RIDE))
chosenstate = S_TAILSOVERLAY_PLUS60DEGREES;
else if (player->panim == PA_PAIN)
chosenstate = S_TAILSOVERLAY_PAIN;
else if (player->mo->state-states == S_PLAY_GASP)
else if (P_IsPlayerInState(player, S_PLAY_GASP))
chosenstate = S_TAILSOVERLAY_GASP;
else if (player->mo->state-states == S_PLAY_EDGE)
else if (P_IsPlayerInState(player, S_PLAY_EDGE))
chosenstate = S_TAILSOVERLAY_EDGE;
else if (player->panim == PA_DASH)
chosenstate = S_TAILSOVERLAY_DASH;
......@@ -11397,7 +11465,7 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
chosenstate = S_TAILSOVERLAY_RUN;
else if (player->panim == PA_WALK)
{
if (!smilesonground || player->mo->state-states == S_PLAY_SKID)
if (!smilesonground || P_IsPlayerInState(player, S_PLAY_SKID))
chosenstate = S_TAILSOVERLAY_PLUS30DEGREES;
else if (player->speed >= FixedMul(player->runspeed/2, player->mo->scale))
chosenstate = S_TAILSOVERLAY_0DEGREES;
......@@ -11439,7 +11507,7 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
#endif
// animation...
if (player->panim == PA_SPRING || player->panim == PA_FALL || player->mo->state-states == S_PLAY_RIDE)
if (player->panim == PA_SPRING || player->panim == PA_FALL || P_IsPlayerInState(player, S_PLAY_RIDE))
{
if (FixedDiv(abs(player->mo->momz), player->mo->scale) < 20<<FRACBITS)
ticnum = 2;
......@@ -11448,7 +11516,7 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
}
else if (player->panim == PA_PAIN)
ticnum = 2;
else if (player->mo->state-states == S_PLAY_GASP)
else if (P_IsPlayerInState(player, S_PLAY_GASP))
tails->tics = -1;
else if (player->mo->sprite2 == SPR2_TIRE)
ticnum = (doswim ? 2 : 4);
......@@ -11495,6 +11563,18 @@ void P_DoTailsOverlay(player_t *player, mobj_t *tails)
}
// Metal Sonic's jet fume
//
// The follow object's state is set to its spawn state when deactivated.
// When the player is on a moving animation, the follow object goes to its see state.
// When dash mode is entered, the follow object switches to its melee state.
//
// If MF2_FRET is set, the jet fume will flash during dash mode.
// MF2_AMBUSH can be used to enable Metal Sonic's skidding animation.
// MF2_JUSTATTACKED will enable the color cycling.
// If the follow item is MT_METALJETFUME, the above two effects are automatically applied.
//
// MF2_STRONGBOX is internally used to track if the jet fume is in its deactivated state or not.
// MF2_BOSSNOTRAP is internally used to instantly reset the jet fume's scale to its intended scale.
void P_DoMetalJetFume(player_t *player, mobj_t *fume)
{
static const UINT8 FUME_SKINCOLORS[] =
......@@ -11521,17 +11601,30 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume)
fixed_t heightoffset = ((mo->eflags & MFE_VERTICALFLIP) ? mo->height - (P_GetPlayerHeight(player) >> 1) : (P_GetPlayerHeight(player) >> 1));
panim_t panim = player->panim;
tic_t dashmode = min(player->dashmode, DASHMODE_MAX);
boolean ismetaljetfume = fume->type == MT_METALJETFUME;
boolean notmoving = panim != PA_WALK && panim != PA_RUN && panim != PA_DASH;
boolean underwater = mo->eflags & MFE_UNDERWATER;
statenum_t stat = fume->state-states;
boolean resetinterp = false;
if (panim != PA_WALK && panim != PA_RUN && panim != PA_DASH) // turn invisible when not in a coherent movement state
if (notmoving) // deactivate when not in a coherent movement state
{
if ((fume->flags2 & MF2_STRONGBOX) == 0)
{
if (stat != fume->info->spawnstate)
P_SetMobjState(fume, fume->info->spawnstate);
fume->flags2 |= MF2_STRONGBOX;
}
if (P_MobjWasRemoved(fume) || ismetaljetfume)
return;
}
// Rotate on skid animation if follow item is MT_METALJETFUME, or if MF2_AMBUSH is set
if (player->mo->sprite2 == SPR2_SKID)
{
if ((ismetaljetfume && (player->charflags & SF_JETFUME)) || (fume->flags2 & MF2_AMBUSH))
angle += ANGLE_90;
}
if (underwater) // No fume underwater; spawn bubbles instead!
{
fume->movedir += FixedAngle(FixedDiv(2 * player->speed, 3 * mo->scale));
......@@ -11567,54 +11660,82 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume)
if (panim == PA_WALK)
{
if (stat != fume->info->spawnstate)
if ((fume->flags2 & MF2_STRONGBOX) == 0)
{
fume->threshold = 0;
P_SetMobjState(fume, fume->info->spawnstate);
fume->threshold = 0;
fume->flags2 &= ~MF2_STRONGBOX;
}
if (P_MobjWasRemoved(fume) || ismetaljetfume)
return;
}
}
if (stat == fume->info->spawnstate) // If currently inivisble, activate!
// If currently deactivated, activate!
if (!notmoving && !underwater && (fume->flags2 & MF2_STRONGBOX))
{
P_SetMobjState(fume, (stat = fume->info->seestate));
if (P_MobjWasRemoved(fume))
return;
P_SetScale(fume, mo->scale, false);
fume->flags2 &= ~MF2_STRONGBOX;
resetinterp = true;
}
if (dashmode > DASHMODE_THRESHOLD && stat != fume->info->seestate) // If in dashmode, grow really big and flash
// If in dash mode, grow really big
if (dashmode > DASHMODE_THRESHOLD && stat != fume->info->meleestate)
{
fume->destscale = mo->scale;
fume->flags2 ^= MF2_DONTDRAW;
fume->flags2 |= mo->flags2 & MF2_DONTDRAW;
// Flash if follow item is MT_METALJETFUME, or if MF2_FRET is set
if (ismetaljetfume || (fume->flags2 & MF2_FRET))
fume->flags2 ^= MF2_DONTDRAW;
}
else // Otherwise, pick a size and color depending on speed and proximity to dashmode
{
if (dashmode == DASHMODE_THRESHOLD && dashmode > (tic_t)fume->movecount) // If just about to enter dashmode, play the startup animation again
// If just about to enter dash mode, play the startup animation again
if (dashmode == DASHMODE_THRESHOLD && dashmode > (tic_t)fume->movecount)
{
P_SetMobjState(fume, (stat = fume->info->seestate));
P_SetMobjState(fume, fume->info->meleestate);
if (P_MobjWasRemoved(fume))
return;
P_SetScale(fume, 2*mo->scale, true);
}
fume->flags2 = (fume->flags2 & ~MF2_DONTDRAW) | (mo->flags2 & MF2_DONTDRAW);
fume->destscale = (mo->scale + FixedDiv(player->speed, player->normalspeed)) / (underwater ? 6 : 3);
// Do color cycling if follow item is MT_METALJETFUME, or if MF2_JUSTATTACKED is set
if (ismetaljetfume || (fume->flags2 & MF2_JUSTATTACKED))
fume->color = FUME_SKINCOLORS[(dashmode * sizeof(FUME_SKINCOLORS)) / (DASHMODE_MAX + 1)];
if (underwater)
{
fume->frame = (fume->frame & FF_FRAMEMASK) | FF_ANIMATE | (P_RandomRange(0, 9) * FF_TRANS10);
fume->frame = (fume->frame & ~FF_TRANSMASK) | (P_RandomRange(0, 9) << FF_TRANSSHIFT);
fume->threshold = 1;
}
else if (fume->threshold)
{
fume->frame = (fume->frame & FF_FRAMEMASK) | fume->state->frame;
fume->frame = (fume->frame & FF_FRAMEMASK) | (fume->state->frame & ~FF_FRAMEMASK);
fume->threshold = 0;
}
}
fume->movecount = dashmode; // keeps track of previous dashmode value so we know whether Metal is entering or leaving it
fume->flags2 = (fume->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); // Make sure to flip in reverse gravity!
fume->eflags = (fume->eflags & ~MFE_VERTICALFLIP) | (mo->eflags & MFE_VERTICALFLIP); // Make sure to flip in reverse gravity!
// keeps track of previous dash mode value so we know whether Metal is entering or leaving it
fume->movecount = dashmode;
// Make sure to flip in reverse gravity!
fume->flags2 = (fume->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP);
fume->eflags = (fume->eflags & ~MFE_VERTICALFLIP) | (mo->eflags & MFE_VERTICALFLIP);
// Set the appropriate scale at spawn
// This is... strange, but I had to choose a flag that a follow object would not ordinarily use.
if ((fume->flags2 & MF2_BOSSNOTRAP) == 0)
{
P_SetScale(fume, fume->destscale, true);
fume->flags2 |= MF2_BOSSNOTRAP;
}
// Finally, set its position
dist = -mo->radius - FixedMul(fume->info->radius, fume->destscale - mo->scale/3);
......@@ -11624,7 +11745,8 @@ void P_DoMetalJetFume(player_t *player, mobj_t *fume)
fume->y = mo->y + P_ReturnThrustY(fume, angle, dist);
fume->z = mo->z + heightoffset - (fume->height >> 1);
P_SetThingPosition(fume);
if (resetinterp) R_ResetMobjInterpolationState(fume);
if (resetinterp)
R_ResetMobjInterpolationState(fume);
// If dash mode is high enough, spawn a trail
if (player->normalspeed >= skins[player->skin]->normalspeed*2)
......@@ -11640,6 +11762,8 @@ void P_DoFollowMobj(player_t *player, mobj_t *followmobj)
{
if (LUA_HookFollowMobj(player, followmobj) || P_MobjWasRemoved(followmobj))
{;}
else if (player->charflags & SF_JETFUME)
P_DoMetalJetFume(player, followmobj);
else
{
switch (followmobj->type)
......@@ -11988,7 +12112,7 @@ void P_PlayerThink(player_t *player)
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
if (th->removing)
continue;
mo2 = (mobj_t *)th;
......@@ -12048,7 +12172,7 @@ void P_PlayerThink(player_t *player)
ticmiss++;
P_DoRopeHang(player);
P_DoJumpStuff(player, &player->cmd, false); // P_DoRopeHang would set PF_SPINDOWN, so no spinshieldhack here
P_DoJumpStuff(player, &player->cmd);
}
else //if (player->powers[pw_carry] == CR_ZOOMTUBE)
{
......@@ -12129,6 +12253,10 @@ void P_PlayerThink(player_t *player)
case CR_DUSTDEVIL:
player->drawangle += ANG20;
break;
case CR_FAN:
if (player->pflags & PF_ANALOGMODE) // Don't impact drawangle in any special way when on a fan
player->drawangle = player->mo->angle;
break;
/* -- in case we wanted to have the camera freely movable during zoom tubes
case CR_ZOOMTUBE:*/
case CR_ROPEHANG:
......@@ -12211,10 +12339,9 @@ void P_PlayerThink(player_t *player)
diff = InvAngle(diff);
if (diff > ANG10/2)
{
statenum_t stat = player->mo->state-states;
if (stat == S_PLAY_WAIT)
if (P_IsPlayerInState(player, S_PLAY_WAIT))
P_SetMobjState(player->mo, S_PLAY_STND);
else if (stat == S_PLAY_STND && player->mo->tics != -1)
else if (P_IsPlayerInState(player, S_PLAY_STND) && player->mo->tics != -1)
player->mo->tics++;
}
}
......@@ -12239,7 +12366,7 @@ void P_PlayerThink(player_t *player)
// fake skidding! see P_SkidStuff for reference on conditionals
else if (!player->skidtime && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID) && P_AproxDistance(player->mo->momx, player->mo->momy) >= FixedMul(player->runspeed, player->mo->scale)) // modified from player->runspeed/2 'cuz the skid was just TOO frequent ngl
{
if (player->mo->state-states != S_PLAY_SKID)
if (!P_IsPlayerInState(player, S_PLAY_SKID))
P_SetMobjState(player->mo, S_PLAY_SKID);
player->mo->tics = player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS;
......@@ -12318,12 +12445,6 @@ void P_PlayerThink(player_t *player)
player->pflags &= ~PF_SPINDOWN;
}
// Check for Shield button
if (cmd->buttons & BT_SHIELD)
player->pflags |= PF_SHIELDDOWN;
else
player->pflags &= ~PF_SHIELDDOWN;
// IF PLAYER NOT HERE THEN FLASH END IF
if (player->quittime && player->powers[pw_flashing] < flashingtics - 1
&& !(G_TagGametype() && !(player->pflags & PF_TAGIT)) && !player->gotflag)
......@@ -12416,16 +12537,14 @@ void P_PlayerThink(player_t *player)
player->stronganim = 0;
//pw_super acts as a timer now
if (player->powers[pw_super]
&& (player->mo->state < &states[S_PLAY_SUPER_TRANS1]
|| player->mo->state > &states[S_PLAY_SUPER_TRANS6]))
if (player->powers[pw_super] && !P_IsPlayerInSuperTransformationState(player))
player->powers[pw_super]++;
if (player->powers[pw_carry] == CR_BRAKGOOP)
{
if (!player->powers[pw_flashing])
{
if (player->mo->state != &states[S_PLAY_STND])
if (!P_IsPlayerInState(player, S_PLAY_STND))
P_SetMobjState(player->mo, S_PLAY_STND);
else
player->mo->tics = 2;
......@@ -12474,8 +12593,6 @@ void P_PlayerThink(player_t *player)
else
player->mo->flags2 &= ~MF2_DONTDRAW;
player->pflags &= ~PF_SLIDING;
#define dashmode player->dashmode
// Dash mode - thanks be to VelocitOni
if ((player->charflags & SF_DASHMODE) && !player->gotflag && !player->powers[pw_carry] && !player->exiting && !(maptol & TOL_NIGHTS) && !metalrecording) // woo, dashmode! no nights tho.
......@@ -12552,6 +12669,12 @@ void P_PlayerThink(player_t *player)
LUA_HookPlayer(player, HOOK(PlayerThink));
// Remove PF_SLIDING *AFTER* PlayerThink hooks, because
// no one wants to add a ThinkFrame just for detecting this (i'm also very lazy)
// This is such a trivial change, I doubt it'll change anything major
// -luigi budd
player->pflags &= ~PF_SLIDING;
/*
// Colormap verification
{
......@@ -12665,7 +12788,7 @@ void P_PlayerAfterThink(player_t *player)
// camera may still move when guy is dead
//if (!netgame)
{
if (thiscam && thiscam->chase)
if (thiscam)
P_MoveChaseCamera(player, thiscam, false);
}
if (player->followmobj)
......@@ -12790,7 +12913,7 @@ void P_PlayerAfterThink(player_t *player)
S_StartSound(NULL, sfx_wepchg);
if ((player->pflags & PF_SLIDING) && ((player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)) != PF_JUMPED))
P_SetMobjState(player->mo, player->mo->info->painstate);
P_SetMobjState(player->mo, S_PLAY_PAIN);
/* if (player->powers[pw_carry] == CR_NONE && player->mo->tracer && !player->homing)
P_SetTarget(&player->mo->tracer, NULL);
......@@ -12829,9 +12952,9 @@ void P_PlayerAfterThink(player_t *player)
else
{
if (tails->player)
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*FRACUNIT), true);
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->player->drawangle, 4*tails->scale), tails->y + P_ReturnThrustY(tails, tails->player->drawangle, 4*tails->scale), true);
else
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->angle, 4*FRACUNIT), tails->y + P_ReturnThrustY(tails, tails->angle, 4*FRACUNIT), true);
P_TryMove(player->mo, tails->x + P_ReturnThrustX(tails, tails->angle, 4*tails->scale), tails->y + P_ReturnThrustY(tails, tails->angle, 4*tails->scale), true);
player->mo->momx = tails->momx;
player->mo->momy = tails->momy;
player->mo->momz = tails->momz;
......@@ -12845,12 +12968,12 @@ void P_PlayerAfterThink(player_t *player)
P_SetPlayerAngle(player, player->mo->angle);
}
if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > player->mo->radius)
if (P_AproxDistance(player->mo->x - tails->x, player->mo->y - tails->y) > tails->radius)
player->powers[pw_carry] = CR_NONE;
if (player->powers[pw_carry] == CR_PLAYER)
{
if (player->mo->state-states != S_PLAY_RIDE)
if (!P_IsPlayerInState(player, S_PLAY_RIDE))
P_SetMobjState(player->mo, S_PLAY_RIDE);
if (tails->player && (tails->skin && ((skin_t *)(tails->skin))->sprites[SPR2_SWIM].numframes) && (tails->eflags & MFE_UNDERWATER))
tails->player->powers[pw_tailsfly] = 0;
......@@ -12875,7 +12998,7 @@ void P_PlayerAfterThink(player_t *player)
player->mo->z = item->z - FixedDiv(player->mo->height, 3*FRACUNIT/2);
player->mo->momx = player->mo->momy = player->mo->momz = 0;
P_SetThingPosition(player->mo);
if (player->mo->state-states != S_PLAY_RIDE)
if (!P_IsPlayerInState(player, S_PLAY_RIDE))
P_SetMobjState(player->mo, S_PLAY_RIDE);
// Controllable missile
......@@ -13066,14 +13189,14 @@ void P_PlayerAfterThink(player_t *player)
player->mo->momy = ptera->momy;
player->mo->momz = ptera->momz;
if (P_AproxDistance(player->mo->x - ptera->x - ptera->watertop, player->mo->y - ptera->y - ptera->waterbottom) > player->mo->radius)
if (P_AproxDistance(player->mo->x - ptera->x - ptera->watertop, player->mo->y - ptera->y - ptera->waterbottom) > ptera->radius)
goto dropoff;
ptera->watertop >>= 1;
ptera->waterbottom >>= 1;
ptera->cvmem >>= 1;
if (player->mo->state-states != S_PLAY_FALL)
if (!P_IsPlayerInState(player, S_PLAY_FALL))
P_SetMobjState(player->mo, S_PLAY_FALL);
break;
......@@ -13105,10 +13228,11 @@ void P_PlayerAfterThink(player_t *player)
player->viewz = player->mo->z + player->mo->height - player->viewheight;
else
player->viewz = player->mo->z + player->viewheight;
}
if (server || addedtogame)
P_MoveChaseCamera(player, thiscam, false); // calculate the camera movement
}
}
// spectator invisibility and nogravity.
if ((netgame || multiplayer) && player->spectator)
......@@ -13143,6 +13267,7 @@ void P_PlayerAfterThink(player_t *player)
player->followmobj->colorized = true;
break;
default:
if ((player->charflags & SF_JETFUME) == 0)
player->followmobj->flags2 |= MF2_LINKDRAW;
break;
}
......@@ -13219,9 +13344,9 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player)
return false;
return ((player->pflags & (PF_SPINNING|PF_SLIDING|PF_GLIDING)) // players who are spinning, sliding, or gliding
|| (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) // players who are landing from a glide
|| (player->charability == CA_GLIDEANDCLIMB && P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING)) // players who are landing from a glide
|| ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)
&& player->dashmode >= DASHMODE_THRESHOLD && player->mo->state-states == S_PLAY_DASH) // machine players in dashmode
&& player->dashmode >= DASHMODE_THRESHOLD && P_IsPlayerInState(player, S_PLAY_DASH)) // machine players in dashmode
|| JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way
}
......@@ -13229,13 +13354,13 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player)
boolean P_PlayerShouldUseSpinHeight(player_t *player)
{
return ((player->pflags & (PF_SPINNING|PF_SLIDING|PF_GLIDING))
|| (player->mo->state == &states[player->mo->info->painstate])
|| P_IsPlayerInState(player, S_PLAY_PAIN)
|| (player->panim == PA_ROLL)
|| ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED))
|| ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && P_IsPlayerInState(player, S_PLAY_FLY_TIRED)))
&& !(player->charflags & SF_NOJUMPSPIN))
|| (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)
|| (player->charability == CA_GLIDEANDCLIMB && P_IsPlayerInState(player, S_PLAY_GLIDE_LANDING))
|| ((player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)
&& player->dashmode >= DASHMODE_THRESHOLD && player->mo->state-states == S_PLAY_DASH)
&& player->dashmode >= DASHMODE_THRESHOLD && P_IsPlayerInState(player, S_PLAY_DASH))
|| JUMPCURLED(player));
}
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -230,6 +230,18 @@ static INT32 R_DoorClosed(void)
&& (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture);
}
static UINT8 R_FloorLightLevel(sector_t *sector, INT16 base_lightlevel)
{
return max(0, min(255, sector->floorlightlevel +
((sector->floorlightabsolute) ? 0 : base_lightlevel)));
}
static UINT8 R_CeilingLightLevel(sector_t *sector, INT16 base_lightlevel)
{
return max(0, min(255, sector->ceilinglightlevel +
((sector->ceilinglightabsolute) ? 0 : base_lightlevel)));
}
//
// If player's view height is underneath fake floor, lower the
// drawn ceiling to be just under the floor height, and replace
......@@ -968,11 +980,10 @@ static void R_Subsector(size_t num)
&& ((viewz < heightcheck && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES)))
|| (viewz > heightcheck && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES))))
{
light = R_GetPlaneLight(frontsector, planecenterz,
viewz < heightcheck);
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *rover->bottomyoffs,
R_FloorLightLevel(rover->master->frontsector, *frontsector->lightlist[light].lightlevel), *rover->bottomxoffs, *rover->bottomyoffs,
*rover->bottomxscale, *rover->bottomyscale, *rover->bottomangle,
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->b_slope, NULL);
......@@ -1002,7 +1013,7 @@ static void R_Subsector(size_t num)
light = R_GetPlaneLight(frontsector, planecenterz, viewz < heightcheck);
ffloor[numffloors].plane = R_FindPlane(rover->master->frontsector, *rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs,
R_CeilingLightLevel(rover->master->frontsector, *frontsector->lightlist[light].lightlevel), *rover->topxoffs, *rover->topyoffs,
*rover->topxscale, *rover->topyscale, *rover->topangle,
*frontsector->lightlist[light].extra_colormap, rover, NULL, *rover->t_slope, NULL);
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -426,9 +426,6 @@ void R_ClearColormaps(void)
{
// Purged by PU_LEVEL, just overwrite the pointer
extra_colormaps = R_CreateDefaultColormap(true);
#ifdef HWRENDER
HWR_ClearLightTables();
#endif
}
//
......@@ -849,6 +846,15 @@ void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup)
}
}
void R_UpdateLightTable(extracolormap_t *extra_colormap, boolean uselookup)
{
R_GenerateLightTable(extra_colormap, uselookup);
#ifdef HWRENDER
extra_colormap->gl_lighttable.needs_update = true;
#endif
}
extracolormap_t *R_CreateColormapFromLinedef(char *p1, char *p2, char *p3)
{
// default values
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -90,6 +90,7 @@ typedef enum
} textmapcolormapflags_t;
void R_GenerateLightTable(extracolormap_t *extra_colormap, boolean uselookup);
void R_UpdateLightTable(extracolormap_t *extra_colormap, boolean uselookup);
lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap);
extracolormap_t * R_CreateColormapFromLinedef(char *p1, char *p2, char *p3);
extracolormap_t* R_CreateColormap(INT32 rgba, INT32 fadergba, UINT8 fadestart, UINT8 fadeend, UINT8 flags);
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -60,6 +60,8 @@ typedef UINT8 lighttable_t;
#define CMF_FADEFULLBRIGHTSPRITES 1
#define CMF_FOG 4
#define TEXTURE_255_IS_TRANSPARENT
// ExtraColormap type. Use for extra_colormaps from now on.
typedef struct extracolormap_s
{
......@@ -74,8 +76,11 @@ typedef struct extracolormap_s
lighttable_t *colormap;
#ifdef HWRENDER
// The id of the hardware lighttable. Zero means it does not exist yet.
UINT32 gl_lighttable_id;
struct {
UINT32 id; // The id of the hardware lighttable. Zero means it does not exist yet.
RGBA_t *data; // The texture data of the hardware lighttable.
boolean needs_update; // If the colormap changed recently or not.
} gl_lighttable;
#endif
#ifdef EXTRACOLORMAPLUMPS
......@@ -240,9 +245,8 @@ typedef struct sectorportal_s
struct sector_s *sector;
struct mobj_s *mobj;
};
struct {
fixed_t x, y;
} origin;
struct sector_s *target;
boolean ceiling;
} sectorportal_t;
typedef struct ffloor_s
......@@ -358,7 +362,7 @@ typedef struct pslope_s
double dzdelta;
boolean moved : 1;
boolean moved;
UINT8 flags; // Slope options
} pslope_t;
......@@ -552,6 +556,8 @@ typedef struct sector_s
// portals
UINT32 portal_floor;
UINT32 portal_ceiling;
struct customargs_s* customargs;
} sector_t;
//
......@@ -612,6 +618,9 @@ typedef struct line_s
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
UINT32 secportal; // transferred sector portal
struct pslope_s *midtexslope;
struct customargs_s *customargs;
} line_t;
typedef struct
......@@ -629,6 +638,11 @@ typedef struct
fixed_t scalex_top, scalex_mid, scalex_bottom;
fixed_t scaley_top, scaley_mid, scaley_bottom;
// per-wall lighting for UDMF
// TODO: implement per-texture lighting
INT16 light, light_top, light_mid, light_bottom;
boolean lightabsolute, lightabsolute_top, lightabsolute_mid, lightabsolute_bottom;
// Texture indices.
// We do not maintain names here.
INT32 toptexture, bottomtexture, midtexture;
......@@ -643,6 +657,7 @@ typedef struct
INT16 repeatcnt; // # of times to repeat midtexture
extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors.
struct customargs_s* customargs;
} side_t;
//
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -19,7 +19,6 @@
#include "doomstat.h"
#include "r_local.h"
#include "r_translation.h"
#include "st_stuff.h" // need ST_HEIGHT
#include "i_video.h"
#include "v_video.h"
#include "m_misc.h"
......@@ -74,7 +73,7 @@ UINT8 *dc_transmap; // one of the translucency tables
UINT8 *dc_translation;
struct r_lightlist_s *dc_lightlist = NULL;
INT32 dc_numlights = 0, dc_maxlights, dc_texheight;
INT32 dc_numlights = 0, dc_maxlights, dc_texheight, dc_postlength;
// =========================================================================
// SPAN DRAWING CODE STUFF
......
......@@ -2,7 +2,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2023 by Sonic Team Junior.
// Copyright (C) 1999-2024 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
......@@ -41,8 +41,7 @@ extern UINT8 *dc_translation;
extern struct r_lightlist_s *dc_lightlist;
extern INT32 dc_numlights, dc_maxlights;
//Fix TUTIFRUTI
extern INT32 dc_texheight;
extern INT32 dc_texheight, dc_postlength;
// -----------------------
// SPAN DRAWING CODE STUFF
......@@ -154,8 +153,12 @@ void R_VideoErase(size_t ofs, INT32 count);
// -----------------
void R_DrawColumn_8(void);
void R_DrawColumnClamped_8(void);
void R_Draw2sMultiPatchColumn_8(void);
void R_DrawShadeColumn_8(void);
void R_DrawTranslucentColumn_8(void);
void R_DrawTranslucentColumnClamped_8(void);
void R_Draw2sMultiPatchTranslucentColumn_8(void);
void R_DrawDropShadowColumn_8(void);
void R_DrawTranslatedColumn_8(void);
void R_DrawTranslatedTranslucentColumn_8(void);
......@@ -170,6 +173,7 @@ void R_DrawTiltedTranslucentSpan_8(void);
void R_DrawSplat_8(void);
void R_DrawTranslucentSplat_8(void);
void R_DrawTiltedSplat_8(void);
void R_DrawTiltedTranslucentSplat_8(void);
void R_DrawFloorSprite_8(void);
void R_DrawTranslucentFloorSprite_8(void);
......@@ -191,6 +195,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void);
void R_DrawSplat_NPO2_8(void);
void R_DrawTranslucentSplat_NPO2_8(void);
void R_DrawTiltedSplat_NPO2_8(void);
void R_DrawTiltedTranslucentSplat_NPO2_8(void);
void R_DrawFloorSprite_NPO2_8(void);
void R_DrawTranslucentFloorSprite_NPO2_8(void);
......