- 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)); }
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
ang,
height,
@ -1655,18 +1659,15 @@ typedef void ANIM_CALLBACK (ANIMp, void *);
typedef ANIM_CALLBACK *ANIM_CALLBACKp;
typedef void *ANIM_DATAp;
struct ANIMstruct
enum
{
int *ptr, goal;
int vel;
short vel_adj;
ANIM_CALLBACKp callback;
ANIM_DATAp callbackdata;
ANIM_Floorz,
ANIM_SopZ,
ANIM_Spritez,
ANIM_Userz,
ANIM_SUdepth,
};
extern ANIM Anim[MAXANIM];
extern short AnimCnt;
typedef struct TRACK_POINT
{
@ -1880,6 +1881,39 @@ struct SECTOR_OBJECTstruct
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
@ -1955,11 +1989,10 @@ void PlayerUpdateKills(PLAYERp pp, short value);
void RefreshInfoLine(PLAYERp pp);
void DoAnim(int numtics);
void AnimDelete(int *animptr);
short AnimGetGoal(int *animptr);
short AnimSet(int *animptr, 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, ANIM_DATAp data);
void AnimDelete(int animtype, int animindex);
short AnimGetGoal(int animtype, int animindex);
short AnimSet(int animtype, int animindex, int thegoal, int thevel);
short AnimSetCallback(short anim_ndx, ANIM_CALLBACKp call, SECTOR_OBJECTp data);
short AnimSetVelAdj(short anim_ndx, short vel_adj);
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()
{
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.
fil = WriteSavegameChunk("snapshot.sw");
auto fil = WriteSavegameChunk("snapshot.sw");
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);
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(&Player[myconnectindex].input,sizeof(Player[myconnectindex].input),1,fil);
// 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;
return true;
}
@ -1440,8 +1263,6 @@ bool GameInterface::LoadGame()
PANEL_SPRITEp psp,next;
Saveable_Init();
auto filr = ReadSavegameChunk("snapshot.sw");
if (!filr.isOpen()) return false;
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();
{

View file

@ -686,7 +686,7 @@ DoSpringBoardDown(void)
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;
@ -2845,7 +2845,7 @@ DoAnim(int numtics)
for (i = AnimCnt - 1; i >= 0; i--)
{
animval = *Anim[i].ptr;
animval = Anim[i].Addr();
// if LESS THAN goal
if (animval < Anim[i].goal)
@ -2871,7 +2871,7 @@ DoAnim(int numtics)
animval = Anim[i].goal;
}
*Anim[i].ptr = animval;
Anim[i].Addr() =animval;
// EQUAL this entry has finished
if (animval == Anim[i].goal)
@ -2920,14 +2920,14 @@ AnimClear(void)
}
short
AnimGetGoal(int *animptr)
AnimGetGoal(int animtype, int animindex)
{
int i, j;
j = -1;
for (i = 0; i < AnimCnt; i++)
{
if (animptr == Anim[i].ptr)
if (animtype == Anim[i].animtype && animindex == Anim[i].index)
{
j = i;
break;
@ -2938,14 +2938,14 @@ AnimGetGoal(int *animptr)
}
void
AnimDelete(int *animptr)
AnimDelete(int animtype, int animindex)
{
int i, j;
j = -1;
for (i = 0; i < AnimCnt; i++)
{
if (animptr == Anim[i].ptr)
if (animtype == Anim[i].animtype && animindex == Anim[i].index)
{
j = i;
break;
@ -2968,7 +2968,7 @@ AnimDelete(int *animptr)
short
AnimSet(int *animptr, fixed_t thegoal, int thevel)
AnimSet(int animtype, int animindex, fixed_t thegoal, int thevel)
{
int i, j;
@ -2979,14 +2979,15 @@ AnimSet(int *animptr, fixed_t thegoal, int thevel)
// look for existing animation and reset it
for (i = 0; i < AnimCnt; i++)
{
if (animptr == Anim[i].ptr)
if (animtype == Anim[i].animtype && animindex == Anim[i].index)
{
j = i;
break;
}
}
Anim[j].ptr = animptr;
Anim[j].animtype = animtype;
Anim[j].index = animindex;
Anim[j].goal = thegoal;
Anim[j].vel = Z(thevel);
Anim[j].vel_adj = 0;
@ -3000,7 +3001,7 @@ AnimSet(int *animptr, fixed_t thegoal, int thevel)
}
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);

View file

@ -648,8 +648,8 @@ KillSprite(int16_t SpriteNum)
// for attached sprites that are getable make sure they don't have
// any Anims attached
AnimDelete(&u->sz);
AnimDelete(&sp->z);
AnimDelete(ANIM_Userz, SpriteNum);
AnimDelete(ANIM_Spritez, SpriteNum);
StopInterpolation(SpriteNum, Interp_Sprite_Z);
//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))
{
i = AnimGetGoal(&sop->zmid);
i = AnimGetGoal (ANIM_SopZ, int(sop - SectorObject));
if (i < 0)
RESET(sop->flags, SOBJ_MOVE_VERTICAL);
}
@ -2204,7 +2204,7 @@ MoveZ(SECTOR_OBJECTp sop)
{
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);
@ -2213,7 +2213,7 @@ MoveZ(SECTOR_OBJECTp sop)
{
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);
@ -2248,7 +2248,7 @@ void CallbackSOsink(ANIMp ap, void *data)
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];
break;
@ -2301,7 +2301,7 @@ void CallbackSOsink(ANIMp ap, void *data)
// Added a depth_fract to the struct so I could do a
// 16.16 Fixed point representation to change the depth
// 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);
found = true;
break;
@ -2322,7 +2322,7 @@ void CallbackSOsink(ANIMp ap, void *data)
continue;
// 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);
}
@ -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))
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);
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)
{
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;
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;
// 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
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))
{
// only modify zmid for sprite_objects
AnimSet(&sop->zmid, dz, sop->z_rate);
AnimSet(ANIM_SopZ, int(sop - SectorObject), dz, sop->z_rate);
}
else
{
// churn through sectors setting their new z values
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);
}
}
}