- SW: eliminated the int pointer in ANIM.

# Conflicts:
#	source/games/sw/src/save.cpp
This commit is contained in:
Christoph Oelckers 2020-12-08 20:42:52 +01:00
parent c49c5fcf1d
commit bb8309831c
5 changed files with 76 additions and 285 deletions

View file

@ -1552,7 +1552,11 @@ typedef struct SECT_USER
{ {
SECT_USER() { memset(this, 0, sizeof(*this)); } SECT_USER() { memset(this, 0, sizeof(*this)); }
int dist, flags; int dist, flags;
short depth_fract, depth; // do NOT change this, doubles as a long FIXED point number union
{
struct { short depth_fract, depth; }; // do NOT change this, doubles as a long FIXED point number
int depth_fixed;
};
short stag, // ST? tag number - for certain things it helps to know it short stag, // ST? tag number - for certain things it helps to know it
ang, ang,
height, height,
@ -1655,18 +1659,15 @@ typedef void ANIM_CALLBACK (ANIMp, void *);
typedef ANIM_CALLBACK *ANIM_CALLBACKp; typedef ANIM_CALLBACK *ANIM_CALLBACKp;
typedef void *ANIM_DATAp; typedef void *ANIM_DATAp;
struct ANIMstruct enum
{ {
int *ptr, goal; ANIM_Floorz,
int vel; ANIM_SopZ,
short vel_adj; ANIM_Spritez,
ANIM_CALLBACKp callback; ANIM_Userz,
ANIM_DATAp callbackdata; ANIM_SUdepth,
}; };
extern ANIM Anim[MAXANIM];
extern short AnimCnt;
typedef struct TRACK_POINT typedef struct TRACK_POINT
{ {
@ -1880,6 +1881,39 @@ struct SECTOR_OBJECTstruct
extern SECTOR_OBJECT SectorObject[MAX_SECTOR_OBJECTS]; extern SECTOR_OBJECT SectorObject[MAX_SECTOR_OBJECTS];
struct ANIMstruct
{
int animtype, index;
int goal;
int vel;
short vel_adj;
ANIM_CALLBACKp callback;
SECTOR_OBJECTp callbackdata; // only gets used in one place for this so having a proper type makes serialization easier.
int& Addr()
{
switch (animtype)
{
case ANIM_Floorz:
return sector[index].floorz;
case ANIM_SopZ:
return SectorObject[index].zmid;
case ANIM_Spritez:
return sprite[index].z;
case ANIM_Userz:
return User[index]->sz;
case ANIM_SUdepth:
return SectUser[index]->depth_fixed;
default:
return index;
}
}
};
extern ANIM Anim[MAXANIM];
extern short AnimCnt;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// //
// Prototypes // Prototypes
@ -1955,11 +1989,10 @@ void PlayerUpdateKills(PLAYERp pp, short value);
void RefreshInfoLine(PLAYERp pp); void RefreshInfoLine(PLAYERp pp);
void DoAnim(int numtics); void DoAnim(int numtics);
void AnimDelete(int *animptr); void AnimDelete(int animtype, int animindex);
short AnimGetGoal(int *animptr); short AnimGetGoal(int animtype, int animindex);
short AnimSet(int *animptr, int thegoal, int thevel); short AnimSet(int animtype, int animindex, int thegoal, int thevel);
//short AnimSetCallback(int *animptr, int thegoal, int thevel, ANIM_CALLBACKp call, ANIM_DATAp data); short AnimSetCallback(short anim_ndx, ANIM_CALLBACKp call, SECTOR_OBJECTp data);
short AnimSetCallback(short anim_ndx, ANIM_CALLBACKp call, ANIM_DATAp data);
short AnimSetVelAdj(short anim_ndx, short vel_adj); short AnimSetVelAdj(short anim_ndx, short vel_adj);
void EnemyDefaults(short SpriteNum, ACTOR_ACTION_SETp action, PERSONALITYp person); void EnemyDefaults(short SpriteNum, ACTOR_ACTION_SETp action, PERSONALITYp person);

View file

@ -1229,104 +1229,15 @@ void GameInterface::SerializeGameState(FSerializer& arc)
int SaveSymDataInfo(MFILE_WRITE fil, void *ptr)
{
saveddatasym sym;
if (Saveable_FindDataSym(ptr, &sym))
{
FILE *fp;
assert(false);
fp = fopen("savegame symbols missing.txt", "a");
if (fp)
{
fprintf(fp,"data %p - reference variable xdim at %p\n",ptr, &xdim);
fclose(fp);
}
return 1;
}
MWRITE(&sym, sizeof(sym), 1, fil);
return 0;
}
static int SaveSymCodeInfo_raw(MFILE_WRITE fil, void *ptr)
{
savedcodesym sym;
if (Saveable_FindCodeSym(ptr, &sym))
{
FILE *fp;
assert(false);
fp = fopen("savegame symbols missing.txt", "a");
if (fp)
{
fprintf(fp,"code %p - reference function SaveSymDataInfo at %p\n",ptr, SaveSymDataInfo);
fclose(fp);
}
return 1;
}
MWRITE(&sym, sizeof(sym), 1, fil);
return 0;
}
template <typename T>
static int SaveSymCodeInfo(MFILE_WRITE fil, T * ptr)
{
return SaveSymCodeInfo_raw(fil, (void *)ptr);
}
int LoadSymDataInfo(MFILE_READ fil, void **ptr)
{
saveddatasym sym;
MREAD(&sym, sizeof(sym), 1, fil);
return Saveable_RestoreDataSym(&sym, ptr);
}
int LoadSymCodeInfo(MFILE_READ fil, void **ptr)
{
savedcodesym sym;
MREAD(&sym, sizeof(sym), 1, fil);
return Saveable_RestoreCodeSym(&sym, ptr);
}
bool GameInterface::SaveGame() bool GameInterface::SaveGame()
{ {
MFILE_WRITE fil;
int i,j;
short ndx;
PLAYER tp;
PLAYERp pp;
SECT_USERp sectu;
USER tu;
USERp u;
ANIM tanim;
ANIMp a;
PANEL_SPRITE tpanel_sprite;
PANEL_SPRITEp psp,cur,next;
SECTOR_OBJECTp sop;
int saveisshot=0;
Saveable_Init();
// workaround until the level info here has been transitioned. // workaround until the level info here has been transitioned.
fil = WriteSavegameChunk("snapshot.sw"); auto fil = WriteSavegameChunk("snapshot.sw");
MWRITE(Track, sizeof(Track),1,fil); MWRITE(Track, sizeof(Track),1,fil);
for (i = 0; i < MAX_TRACKS; i++) for (int i = 0; i < MAX_TRACKS; i++)
{ {
ASSERT(Track[i].TrackPoint); ASSERT(Track[i].TrackPoint);
if (Track[i].NumPoints == 0) if (Track[i].NumPoints == 0)
@ -1335,95 +1246,7 @@ bool GameInterface::SaveGame()
MWRITE(Track[i].TrackPoint, Track[i].NumPoints * sizeof(TRACK_POINT),1,fil); MWRITE(Track[i].TrackPoint, Track[i].NumPoints * sizeof(TRACK_POINT),1,fil);
} }
MWRITE(&Player[myconnectindex].input,sizeof(Player[myconnectindex].input),1,fil); return true;
// do all sector manipulation structures
#if ANIM_SAVE
#if 1
MWRITE(&AnimCnt,sizeof(AnimCnt),1,fil);
for (i = 0, a = &tanim; i < AnimCnt; i++)
{
intptr_t offset;
memcpy(a,&Anim[i],sizeof(ANIM));
// maintain compatibility with sinking boat which points to user data
for (j=0; j<MAXSPRITES; j++)
{
if (User[j].Data())
{
uint8_t* bp = (uint8_t*)User[j].Data();
if ((uint8_t*)a->ptr >= bp && (uint8_t*)a->ptr < bp + sizeof(USER))
{
offset = (intptr_t)((uint8_t*)a->ptr - bp); // offset from user data
a->ptr = (int *)-2;
break;
}
}
}
if ((intptr_t)a->ptr != -2)
{
for (j=0; j<numsectors; j++)
{
if (SectUser[j].Data())
{
uint8_t* bp = (uint8_t*)SectUser[j].Data();
if ((uint8_t*)a->ptr >= bp && (uint8_t*)a->ptr < bp + sizeof(SECT_USER))
{
offset = (intptr_t)((uint8_t*)a->ptr - bp); // offset from user data
a->ptr = (int *)-3;
break;
}
}
}
}
MWRITE(a,sizeof(ANIM),1,fil);
if ((intptr_t)a->ptr == -2 || (intptr_t)a->ptr == -3)
{
MWRITE(&j, sizeof(j),1,fil);
MWRITE(&offset, sizeof(offset),1,fil);
}
else
{
saveisshot |= SaveSymDataInfo(fil, a->ptr);
assert(!saveisshot);
}
saveisshot |= SaveSymCodeInfo(fil, a->callback);
assert(!saveisshot);
saveisshot |= SaveSymDataInfo(fil, a->callbackdata);
assert(!saveisshot);
}
#else
ndx = 0;
for (i = AnimCnt - 1, a = &tanim; i >= 0; i--)
{
// write header
MWRITE(&ndx,sizeof(ndx),1,fil);
memcpy(a,&Anim[i],sizeof(ANIM));
MWRITE(a,sizeof(ANIM),1,fil);
saveisshot |= SaveSymDataInfo(fil, a->ptr);
saveisshot |= SaveSymCodeInfo(fil, a->callback);
saveisshot |= SaveSymDataInfo(fil, a->callbackdata);
ndx++;
}
// write trailer
ndx = -1;
MWRITE(&ndx,sizeof(ndx),1,fil);
#endif
#endif
return !saveisshot;
} }
@ -1440,8 +1263,6 @@ bool GameInterface::LoadGame()
PANEL_SPRITEp psp,next; PANEL_SPRITEp psp,next;
Saveable_Init();
auto filr = ReadSavegameChunk("snapshot.sw"); auto filr = ReadSavegameChunk("snapshot.sw");
if (!filr.isOpen()) return false; if (!filr.isOpen()) return false;
fil = &filr; fil = &filr;
@ -1461,70 +1282,6 @@ bool GameInterface::LoadGame()
} }
} }
MREAD(&Player[myconnectindex].input,sizeof(Player[myconnectindex].input),1,fil);
// do all sector manipulation structures
#if ANIM_SAVE
#if 1
MREAD(&AnimCnt,sizeof(AnimCnt),1,fil);
for (i = 0; i < AnimCnt; i++)
{
a = &Anim[i];
MREAD(a,sizeof(ANIM),1,fil);
if ((intptr_t)a->ptr == -2)
{
// maintain compatibility with sinking boat which points to user data
int offset;
MREAD(&j, sizeof(j),1,fil);
MREAD(&offset, sizeof(offset),1,fil);
a->ptr = (int *)(((char *)User[j].Data()) + offset);
}
else if ((intptr_t)a->ptr == -3)
{
// maintain compatibility with sinking boat which points to user data
int offset;
MREAD(&j, sizeof(j),1,fil);
MREAD(&offset, sizeof(offset),1,fil);
a->ptr = (int *)(((char *)SectUser[j].Data()) + offset);
}
else
{
saveisshot |= LoadSymDataInfo(fil, (void **)&a->ptr);
}
saveisshot |= LoadSymCodeInfo(fil, (void **)&a->callback);
saveisshot |= LoadSymDataInfo(fil, (void **)&a->callbackdata);
if (saveisshot) { MCLOSE_READ(fil); return false; }
}
#else
AnimCnt = 0;
for (i = MAXANIM - 1; i >= 0; i--)
{
a = &Anim[i];
MREAD(&ndx,sizeof(ndx),1,fil);
if (ndx == -1)
break;
AnimCnt++;
MREAD(a,sizeof(ANIM),1,fil);
saveisshot |= LoadSymDataInfo(fil, (void **)&a->ptr);
saveisshot |= LoadSymCodeInfo(fil, (void **)&a->callback);
saveisshot |= LoadSymDataInfo(fil, (void **)&a->callbackdata);
if (saveisshot) { MCLOSE_READ(fil); return false; }
}
#endif
#endif
MCLOSE_READ(fil);
DoTheCache(); DoTheCache();
{ {

View file

@ -686,7 +686,7 @@ DoSpringBoardDown(void)
destz = sector[nextsectorneighborz(sbp->Sector, sector[sbp->Sector].floorz, 1, 1)].floorz; destz = sector[nextsectorneighborz(sbp->Sector, sector[sbp->Sector].floorz, 1, 1)].floorz;
AnimSet(&sector[sbp->Sector].floorz, destz, 256); AnimSet(ANIM_Floorz, sbp->Sector, destz, 256);
sector[sbp->Sector].lotag = TAG_SPRING_BOARD; sector[sbp->Sector].lotag = TAG_SPRING_BOARD;
@ -2845,7 +2845,7 @@ DoAnim(int numtics)
for (i = AnimCnt - 1; i >= 0; i--) for (i = AnimCnt - 1; i >= 0; i--)
{ {
animval = *Anim[i].ptr; animval = Anim[i].Addr();
// if LESS THAN goal // if LESS THAN goal
if (animval < Anim[i].goal) if (animval < Anim[i].goal)
@ -2871,7 +2871,7 @@ DoAnim(int numtics)
animval = Anim[i].goal; animval = Anim[i].goal;
} }
*Anim[i].ptr = animval; Anim[i].Addr() =animval;
// EQUAL this entry has finished // EQUAL this entry has finished
if (animval == Anim[i].goal) if (animval == Anim[i].goal)
@ -2920,14 +2920,14 @@ AnimClear(void)
} }
short short
AnimGetGoal(int *animptr) AnimGetGoal(int animtype, int animindex)
{ {
int i, j; int i, j;
j = -1; j = -1;
for (i = 0; i < AnimCnt; i++) for (i = 0; i < AnimCnt; i++)
{ {
if (animptr == Anim[i].ptr) if (animtype == Anim[i].animtype && animindex == Anim[i].index)
{ {
j = i; j = i;
break; break;
@ -2938,14 +2938,14 @@ AnimGetGoal(int *animptr)
} }
void void
AnimDelete(int *animptr) AnimDelete(int animtype, int animindex)
{ {
int i, j; int i, j;
j = -1; j = -1;
for (i = 0; i < AnimCnt; i++) for (i = 0; i < AnimCnt; i++)
{ {
if (animptr == Anim[i].ptr) if (animtype == Anim[i].animtype && animindex == Anim[i].index)
{ {
j = i; j = i;
break; break;
@ -2968,7 +2968,7 @@ AnimDelete(int *animptr)
short short
AnimSet(int *animptr, fixed_t thegoal, int thevel) AnimSet(int animtype, int animindex, fixed_t thegoal, int thevel)
{ {
int i, j; int i, j;
@ -2979,14 +2979,15 @@ AnimSet(int *animptr, fixed_t thegoal, int thevel)
// look for existing animation and reset it // look for existing animation and reset it
for (i = 0; i < AnimCnt; i++) for (i = 0; i < AnimCnt; i++)
{ {
if (animptr == Anim[i].ptr) if (animtype == Anim[i].animtype && animindex == Anim[i].index)
{ {
j = i; j = i;
break; break;
} }
} }
Anim[j].ptr = animptr; Anim[j].animtype = animtype;
Anim[j].index = animindex;
Anim[j].goal = thegoal; Anim[j].goal = thegoal;
Anim[j].vel = Z(thevel); Anim[j].vel = Z(thevel);
Anim[j].vel_adj = 0; Anim[j].vel_adj = 0;
@ -3000,7 +3001,7 @@ AnimSet(int *animptr, fixed_t thegoal, int thevel)
} }
short short
AnimSetCallback(short anim_ndx, ANIM_CALLBACKp call, ANIM_DATAp data) AnimSetCallback(short anim_ndx, ANIM_CALLBACKp call, SECTOR_OBJECTp data)
{ {
ASSERT(anim_ndx < AnimCnt); ASSERT(anim_ndx < AnimCnt);

View file

@ -648,8 +648,8 @@ KillSprite(int16_t SpriteNum)
// for attached sprites that are getable make sure they don't have // for attached sprites that are getable make sure they don't have
// any Anims attached // any Anims attached
AnimDelete(&u->sz); AnimDelete(ANIM_Userz, SpriteNum);
AnimDelete(&sp->z); AnimDelete(ANIM_Spritez, SpriteNum);
StopInterpolation(SpriteNum, Interp_Sprite_Z); StopInterpolation(SpriteNum, Interp_Sprite_Z);
//if (TEST(u->Flags2, SPR2_DONT_TARGET_OWNER)) //if (TEST(u->Flags2, SPR2_DONT_TARGET_OWNER))

View file

@ -2189,7 +2189,7 @@ MoveZ(SECTOR_OBJECTp sop)
if (TEST(sop->flags, SOBJ_MOVE_VERTICAL)) if (TEST(sop->flags, SOBJ_MOVE_VERTICAL))
{ {
i = AnimGetGoal(&sop->zmid); i = AnimGetGoal (ANIM_SopZ, int(sop - SectorObject));
if (i < 0) if (i < 0)
RESET(sop->flags, SOBJ_MOVE_VERTICAL); RESET(sop->flags, SOBJ_MOVE_VERTICAL);
} }
@ -2204,7 +2204,7 @@ MoveZ(SECTOR_OBJECTp sop)
{ {
for (i = 0, sectp = &sop->sectp[0]; *sectp; sectp++, i++) for (i = 0, sectp = &sop->sectp[0]; *sectp; sectp++, i++)
{ {
AnimSet(&(*sectp)->floorz, sop->zorig_floor[i] + sop->z_tgt, sop->z_rate); AnimSet(ANIM_Floorz, int(*sectp - sector), sop->zorig_floor[i] + sop->z_tgt, sop->z_rate);
} }
RESET(sop->flags, SOBJ_ZDOWN); RESET(sop->flags, SOBJ_ZDOWN);
@ -2213,7 +2213,7 @@ MoveZ(SECTOR_OBJECTp sop)
{ {
for (i = 0, sectp = &sop->sectp[0]; *sectp; sectp++, i++) for (i = 0, sectp = &sop->sectp[0]; *sectp; sectp++, i++)
{ {
AnimSet(&(*sectp)->floorz, sop->zorig_floor[i] + sop->z_tgt, sop->z_rate); AnimSet(ANIM_Floorz, int(*sectp - sector), sop->zorig_floor[i] + sop->z_tgt, sop->z_rate);
} }
RESET(sop->flags, SOBJ_ZUP); RESET(sop->flags, SOBJ_ZUP);
@ -2248,7 +2248,7 @@ void CallbackSOsink(ANIMp ap, void *data)
for (i = 0; sop->sector[i] != -1; i++) for (i = 0; sop->sector[i] != -1; i++)
{ {
if (ap->ptr == &sector[sop->sector[i]].floorz) if (ap->animtype == ANIM_Floorz && ap->index == sop->sector[i])
{ {
dest_sector = sop->sector[i]; dest_sector = sop->sector[i];
break; break;
@ -2301,7 +2301,7 @@ void CallbackSOsink(ANIMp ap, void *data)
// Added a depth_fract to the struct so I could do a // Added a depth_fract to the struct so I could do a
// 16.16 Fixed point representation to change the depth // 16.16 Fixed point representation to change the depth
// in a more precise way // in a more precise way
ndx = AnimSet((int *)&su->depth_fract, IntToFixed(tgt_depth), (ap->vel<<8)>>8); ndx = AnimSet(ANIM_SUdepth, dest_sector, IntToFixed(tgt_depth), (ap->vel << 8) >> 8);
AnimSetVelAdj(ndx, ap->vel_adj); AnimSetVelAdj(ndx, ap->vel_adj);
found = true; found = true;
break; break;
@ -2322,7 +2322,7 @@ void CallbackSOsink(ANIMp ap, void *data)
continue; continue;
// move sprite WAY down in water // move sprite WAY down in water
ndx = AnimSet(&u->sz, -u->sz - SPRITEp_SIZE_Z(sp) - Z(100), ap->vel>>8); ndx = AnimSet(ANIM_Userz, i, -u->sz - SPRITEp_SIZE_Z(sp) - Z(100), ap->vel>>8);
AnimSetVelAdj(ndx, ap->vel_adj); AnimSetVelAdj(ndx, ap->vel_adj);
} }
@ -2579,7 +2579,7 @@ void DoTrack(SECTOR_OBJECTp sop, short locktics, int *nx, int *ny)
if (SectUser[sop->sector[i]].Data() && TEST(SectUser[sop->sector[i]]->flags, SECTFU_SO_DONT_SINK)) if (SectUser[sop->sector[i]].Data() && TEST(SectUser[sop->sector[i]]->flags, SECTFU_SO_DONT_SINK))
continue; continue;
ndx = AnimSet(&(*sectp)->floorz, sector[dest_sector].floorz, tpoint->tag_high); ndx = AnimSet(ANIM_Floorz, int(*sectp-sector), sector[dest_sector].floorz, tpoint->tag_high);
AnimSetCallback(ndx, CallbackSOsink, sop); AnimSetCallback(ndx, CallbackSOsink, sop);
AnimSetVelAdj(ndx, 6); AnimSetVelAdj(ndx, 6);
} }
@ -2600,7 +2600,7 @@ void DoTrack(SECTOR_OBJECTp sop, short locktics, int *nx, int *ny)
if (sectu && sectu->stag == SECT_SO_FORM_WHIRLPOOL) if (sectu && sectu->stag == SECT_SO_FORM_WHIRLPOOL)
{ {
AnimSet(&(*sectp)->floorz, (*sectp)->floorz + Z(sectu->height), 128); AnimSet(ANIM_Floorz, int(*sectp - sector), (*sectp)->floorz + Z(sectu->height), 128);
(*sectp)->floorshade += sectu->height/6; (*sectp)->floorshade += sectu->height/6;
RESET((*sectp)->extra, SECTFX_NO_RIDE); RESET((*sectp)->extra, SECTFX_NO_RIDE);
@ -2625,7 +2625,7 @@ void DoTrack(SECTOR_OBJECTp sop, short locktics, int *nx, int *ny)
tpoint = Track[sop->track].TrackPoint + sop->point; tpoint = Track[sop->track].TrackPoint + sop->point;
// set anim // set anim
AnimSet(&sop->zmid, tpoint->z, zr); AnimSet(ANIM_SopZ, int(sop-SectorObject), tpoint->z, zr);
// move back to current point by reversing direction // move back to current point by reversing direction
sop->dir *= -1; sop->dir *= -1;
@ -2721,14 +2721,14 @@ void DoTrack(SECTOR_OBJECTp sop, short locktics, int *nx, int *ny)
if (TEST(sop->flags, SOBJ_SPRITE_OBJ)) if (TEST(sop->flags, SOBJ_SPRITE_OBJ))
{ {
// only modify zmid for sprite_objects // only modify zmid for sprite_objects
AnimSet(&sop->zmid, dz, sop->z_rate); AnimSet(ANIM_SopZ, int(sop - SectorObject), dz, sop->z_rate);
} }
else else
{ {
// churn through sectors setting their new z values // churn through sectors setting their new z values
for (i = 0; sop->sector[i] != -1; i++) for (i = 0; sop->sector[i] != -1; i++)
{ {
AnimSet(&sector[sop->sector[i]].floorz, dz - (sector[sop->mid_sector].floorz - sector[sop->sector[i]].floorz), sop->z_rate); AnimSet(ANIM_Floorz, sop->sector[i], dz - (sector[sop->mid_sector].floorz - sector[sop->sector[i]].floorz), sop->z_rate);
} }
} }
} }