A lot of CON rewrites/optimizations. Converts projectile system to dynamic allocation, saving a bunch of memory (something like sizeof(projectile_t) * MAXTILES * 2). This commit also contains changes that reduce overhead for CON commands that take a lot of parameters, by way of adding a Gv_GetManyVars() to replace long strings of subsequent calls to Gv_GetVarX().

Savegame version has been bumped due to the projectile changes. There is no way this commit doesn't cause at least one bug, so DONT_BUILD. ;)

git-svn-id: https://svn.eduke32.com/eduke32@5080 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2015-03-24 00:40:55 +00:00
parent 9cb68410a0
commit c9ce545ab8
15 changed files with 818 additions and 587 deletions

View File

@ -240,7 +240,8 @@ typedef struct {
int32_t cacherange; // formerly SpriteCache
// todo: make this a pointer and allocate at runtime
projectile_t defproj;
projectile_t *proj;
projectile_t *defproj;
} tiledata_t;

View File

@ -55,10 +55,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// increase by 3, because atomic GRP adds 1, and Shareware adds 2
#ifdef LUNATIC
// Lunatic
# define BYTEVERSION_JF 297
# define BYTEVERSION_JF 300
#else
// Non-Lua build
# define BYTEVERSION_JF 297
# define BYTEVERSION_JF 300
#endif
//#define BYTEVERSION_13 27

View File

@ -1703,7 +1703,7 @@ static void G_DrawWeapAmounts(const DukePlayer_t *p,int32_t x,int32_t y,int32_t
}
// yofs: in hud_scale-independent, (<<16)-scaled, 0-200-normalized y coords.
static void G_DrawDigiNum_(int32_t x, int32_t yofs, int32_t y, int32_t n, char s, int32_t cs)
static inline void G_DrawDigiNum_(int32_t x, int32_t yofs, int32_t y, int32_t n, char s, int32_t cs)
{
if (!(cs & ROTATESPRITE_FULL16))
{

View File

@ -2316,73 +2316,92 @@ LUNATIC_EXTERN int32_t C_SetDefName(const char *name)
return (g_defNamePtr==NULL);
}
defaultprojectile_t DefaultProjectile;
int32_t g_numProjectiles = 0;
EDUKE32_STATIC_ASSERT(sizeof(projectile_t) == sizeof(DefaultProjectile));
LUNATIC_EXTERN void C_DefineProjectile(int32_t j, int32_t what, int32_t val)
{
if (g_tile[j].proj == NULL)
{
g_tile[j].proj = (projectile_t *) Xmalloc(sizeof(projectile_t));
*g_tile[j].proj = *(projectile_t *)&DefaultProjectile;
g_numProjectiles += 2;
}
projectile_t * const proj = g_tile[j].proj;
switch (what)
{
case PROJ_WORKSLIKE:
g_tile[j].defproj.workslike = ProjectileData[j].workslike = val; break;
proj->workslike = val; break;
case PROJ_SPAWNS:
g_tile[j].defproj.spawns = ProjectileData[j].spawns = val; break;
proj->spawns = val; break;
case PROJ_SXREPEAT:
g_tile[j].defproj.sxrepeat = ProjectileData[j].sxrepeat = val; break;
proj->sxrepeat = val; break;
case PROJ_SYREPEAT:
g_tile[j].defproj.syrepeat = ProjectileData[j].syrepeat = val; break;
proj->syrepeat = val; break;
case PROJ_SOUND:
g_tile[j].defproj.sound = ProjectileData[j].sound = val; break;
proj->sound = val; break;
case PROJ_ISOUND:
g_tile[j].defproj.isound = ProjectileData[j].isound = val; break;
proj->isound = val; break;
case PROJ_VEL:
g_tile[j].defproj.vel = ProjectileData[j].vel = val; break;
proj->vel = val; break;
case PROJ_EXTRA:
g_tile[j].defproj.extra = ProjectileData[j].extra = val; break;
proj->extra = val; break;
case PROJ_DECAL:
g_tile[j].defproj.decal = ProjectileData[j].decal = val; break;
proj->decal = val; break;
case PROJ_TRAIL:
g_tile[j].defproj.trail = ProjectileData[j].trail = val; break;
proj->trail = val; break;
case PROJ_TXREPEAT:
g_tile[j].defproj.txrepeat = ProjectileData[j].txrepeat = val; break;
proj->txrepeat = val; break;
case PROJ_TYREPEAT:
g_tile[j].defproj.tyrepeat = ProjectileData[j].tyrepeat = val; break;
proj->tyrepeat = val; break;
case PROJ_TOFFSET:
g_tile[j].defproj.toffset = ProjectileData[j].toffset = val; break;
proj->toffset = val; break;
case PROJ_TNUM:
g_tile[j].defproj.tnum = ProjectileData[j].tnum = val; break;
proj->tnum = val; break;
case PROJ_DROP:
g_tile[j].defproj.drop = ProjectileData[j].drop = val; break;
proj->drop = val; break;
case PROJ_CSTAT:
g_tile[j].defproj.cstat = ProjectileData[j].cstat = val; break;
proj->cstat = val; break;
case PROJ_CLIPDIST:
g_tile[j].defproj.clipdist = ProjectileData[j].clipdist = val; break;
proj->clipdist = val; break;
case PROJ_SHADE:
g_tile[j].defproj.shade = ProjectileData[j].shade = val; break;
proj->shade = val; break;
case PROJ_XREPEAT:
g_tile[j].defproj.xrepeat = ProjectileData[j].xrepeat = val; break;
proj->xrepeat = val; break;
case PROJ_YREPEAT:
g_tile[j].defproj.yrepeat = ProjectileData[j].yrepeat = val; break;
proj->yrepeat = val; break;
case PROJ_PAL:
g_tile[j].defproj.pal = ProjectileData[j].pal = val; break;
proj->pal = val; break;
case PROJ_EXTRA_RAND:
g_tile[j].defproj.extra_rand = ProjectileData[j].extra_rand = val; break;
proj->extra_rand = val; break;
case PROJ_HITRADIUS:
g_tile[j].defproj.hitradius = ProjectileData[j].hitradius = val; break;
proj->hitradius = val; break;
case PROJ_MOVECNT:
g_tile[j].defproj.movecnt = ProjectileData[j].movecnt = val; break;
proj->movecnt = val; break;
case PROJ_OFFSET:
g_tile[j].defproj.offset = ProjectileData[j].offset = val; break;
proj->offset = val; break;
case PROJ_BOUNCES:
g_tile[j].defproj.bounces = ProjectileData[j].bounces = val; break;
proj->bounces = val; break;
case PROJ_BSOUND:
g_tile[j].defproj.bsound = ProjectileData[j].bsound = val; break;
proj->bsound = val; break;
case PROJ_RANGE:
g_tile[j].defproj.range = ProjectileData[j].range = val; break;
proj->range = val; break;
case PROJ_FLASH_COLOR:
g_tile[j].defproj.flashcolor = ProjectileData[j].flashcolor = val; break;
proj->flashcolor = val; break;
case PROJ_USERDATA:
g_tile[j].defproj.userdata = ProjectileData[j].userdata = val; break;
proj->userdata = val; break;
default: break;
}
if (g_tile[j].defproj == NULL)
g_tile[j].defproj = (projectile_t *)Xmalloc(sizeof(projectile_t));
*g_tile[j].defproj = *proj;
g_tile[j].flags |= SFLAG_PROJECTILE;
}
@ -6258,38 +6277,22 @@ static void C_AddDefaultDefinitions(void)
void C_InitProjectiles(void)
{
int32_t i;
typedef struct
defaultprojectile_t const Projectile =
{
int32_t workslike, cstat; // 8b
int32_t hitradius, range, flashcolor; // 12b
int16_t spawns, sound, isound, vel; // 8b
int16_t decal, trail, tnum, drop; // 8b
int16_t offset, bounces, bsound; // 6b
int16_t toffset; // 2b
int16_t extra, extra_rand; // 4b
int8_t sxrepeat, syrepeat, txrepeat, tyrepeat; // 4b
int8_t shade, xrepeat, yrepeat, pal; // 4b
int8_t movecnt; // 1b
uint8_t clipdist; // 1b
int8_t filler[2]; // 2b
int32_t userdata; // 4b
} defaultprojectile_t;
defaultprojectile_t DefaultProjectile =
{
1, -1, 2048, 0, 0, (int16_t)SMALLSMOKE, -1, -1, 600, (int16_t)BULLETHOLE, -1, 0, 0, 448,
(int16_t)g_numFreezeBounces, (int16_t)PIPEBOMB_BOUNCE, 1, 100, -1, -1, -1, -1, -1, -96, 18, 18,
0, 1, 32, {0,0}, 0,
1, -1, 2048, 0, 0, (int16_t) SMALLSMOKE, -1, -1, 600, (int16_t) BULLETHOLE, -1, 0, 0, 448,
(int16_t) g_numFreezeBounces, (int16_t) PIPEBOMB_BOUNCE, 1, 100, -1, -1, -1, -1, -1, -96, 18, 18,
0, 1, 32, { 0, 0 }, 0,
};
EDUKE32_STATIC_ASSERT(sizeof(projectile_t) == sizeof(DefaultProjectile));
DefaultProjectile = Projectile;
for (i=MAXTILES-1; i>=0; i--)
for (int i=MAXTILES-1; i>=0; i--)
{
Bmemcpy(&ProjectileData[i], &DefaultProjectile, sizeof(projectile_t));
Bmemcpy(&g_tile[i].defproj, &DefaultProjectile, sizeof(projectile_t));
if (g_tile[i].proj)
*g_tile[i].proj = *(projectile_t *)&DefaultProjectile;
if (g_tile[i].defproj)
*g_tile[i].defproj = *(projectile_t *)&DefaultProjectile;
}
}

View File

@ -94,10 +94,30 @@ extern const memberlabel_t InputLabels[];
extern const memberlabel_t TsprLabels[];
#endif
typedef struct
{
int32_t workslike, cstat; // 8b
int32_t hitradius, range, flashcolor; // 12b
int16_t spawns, sound, isound, vel; // 8b
int16_t decal, trail, tnum, drop; // 8b
int16_t offset, bounces, bsound; // 6b
int16_t toffset; // 2b
int16_t extra, extra_rand; // 4b
int8_t sxrepeat, syrepeat, txrepeat, tyrepeat; // 4b
int8_t shade, xrepeat, yrepeat, pal; // 4b
int8_t movecnt; // 1b
uint8_t clipdist; // 1b
int8_t filler[2]; // 2b
int32_t userdata; // 4b
} defaultprojectile_t;
extern defaultprojectile_t DefaultProjectile;
int32_t C_AllocQuote(int32_t qnum);
void C_InitQuotes(void);
void C_InitProjectiles(void);
extern int32_t g_numProjectiles;
typedef struct {
int g_i, g_p, g_x;
int32_t *g_t;

File diff suppressed because it is too large Load Diff

View File

@ -100,7 +100,7 @@ void G_GetTimeDate(int32_t *vals);
int32_t G_StartTrack(int32_t level);
int32_t A_Dodge(spritetype *s);
#ifdef LUNATIC
void G_ShowView(int32_t x, int32_t y, int32_t z, int32_t a, int32_t horiz, int32_t sect,
void G_ShowView(vec3_t vec, int32_t a, int32_t horiz, int32_t sect,
int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t unbiasedp);
void P_AddWeaponMaybeSwitchI(int32_t snum, int32_t weap);
void VM_FallSprite(int32_t i);

View File

@ -1239,6 +1239,8 @@ badtspr:
static void __fastcall VM_AccessProjectile(int32_t iSet, int32_t lVar1, int32_t lLabelID, int32_t lVar2)
{
projectile_t * const proj = g_tile[lVar1].proj;
if (EDUKE32_PREDICT_FALSE((unsigned)lVar1 >= MAXTILES))
goto badtile;
@ -1248,72 +1250,72 @@ static void __fastcall VM_AccessProjectile(int32_t iSet, int32_t lVar1, int32_t
switch (lLabelID)
{
case PROJ_WORKSLIKE: ProjectileData[lVar1].workslike = iSet; break;
case PROJ_SPAWNS: ProjectileData[lVar1].spawns = iSet; break;
case PROJ_SXREPEAT: ProjectileData[lVar1].sxrepeat = iSet; break;
case PROJ_SYREPEAT: ProjectileData[lVar1].syrepeat = iSet; break;
case PROJ_SOUND: ProjectileData[lVar1].sound = iSet; break;
case PROJ_ISOUND: ProjectileData[lVar1].isound = iSet; break;
case PROJ_VEL: ProjectileData[lVar1].vel = iSet; break;
case PROJ_EXTRA: ProjectileData[lVar1].extra = iSet; break;
case PROJ_DECAL: ProjectileData[lVar1].decal = iSet; break;
case PROJ_TRAIL: ProjectileData[lVar1].trail = iSet; break;
case PROJ_TXREPEAT: ProjectileData[lVar1].txrepeat = iSet; break;
case PROJ_TYREPEAT: ProjectileData[lVar1].tyrepeat = iSet; break;
case PROJ_TOFFSET: ProjectileData[lVar1].toffset = iSet; break;
case PROJ_TNUM: ProjectileData[lVar1].tnum = iSet; break;
case PROJ_DROP: ProjectileData[lVar1].drop = iSet; break;
case PROJ_CSTAT: ProjectileData[lVar1].cstat = iSet; break;
case PROJ_CLIPDIST: ProjectileData[lVar1].clipdist = iSet; break;
case PROJ_SHADE: ProjectileData[lVar1].shade = iSet; break;
case PROJ_XREPEAT: ProjectileData[lVar1].xrepeat = iSet; break;
case PROJ_YREPEAT: ProjectileData[lVar1].yrepeat = iSet; break;
case PROJ_PAL: ProjectileData[lVar1].pal = iSet; break;
case PROJ_EXTRA_RAND: ProjectileData[lVar1].extra_rand = iSet; break;
case PROJ_HITRADIUS: ProjectileData[lVar1].hitradius = iSet; break;
case PROJ_MOVECNT: ProjectileData[lVar1].movecnt = iSet; break;
case PROJ_OFFSET: ProjectileData[lVar1].offset = iSet; break;
case PROJ_BOUNCES: ProjectileData[lVar1].bounces = iSet; break;
case PROJ_BSOUND: ProjectileData[lVar1].bsound = iSet; break;
case PROJ_RANGE: ProjectileData[lVar1].range = iSet; break;
case PROJ_FLASH_COLOR: ProjectileData[lVar1].flashcolor = iSet; break;
case PROJ_USERDATA: ProjectileData[lVar1].userdata = iSet; break;
case PROJ_WORKSLIKE: proj->workslike = iSet; break;
case PROJ_SPAWNS: proj->spawns = iSet; break;
case PROJ_SXREPEAT: proj->sxrepeat = iSet; break;
case PROJ_SYREPEAT: proj->syrepeat = iSet; break;
case PROJ_SOUND: proj->sound = iSet; break;
case PROJ_ISOUND: proj->isound = iSet; break;
case PROJ_VEL: proj->vel = iSet; break;
case PROJ_EXTRA: proj->extra = iSet; break;
case PROJ_DECAL: proj->decal = iSet; break;
case PROJ_TRAIL: proj->trail = iSet; break;
case PROJ_TXREPEAT: proj->txrepeat = iSet; break;
case PROJ_TYREPEAT: proj->tyrepeat = iSet; break;
case PROJ_TOFFSET: proj->toffset = iSet; break;
case PROJ_TNUM: proj->tnum = iSet; break;
case PROJ_DROP: proj->drop = iSet; break;
case PROJ_CSTAT: proj->cstat = iSet; break;
case PROJ_CLIPDIST: proj->clipdist = iSet; break;
case PROJ_SHADE: proj->shade = iSet; break;
case PROJ_XREPEAT: proj->xrepeat = iSet; break;
case PROJ_YREPEAT: proj->yrepeat = iSet; break;
case PROJ_PAL: proj->pal = iSet; break;
case PROJ_EXTRA_RAND: proj->extra_rand = iSet; break;
case PROJ_HITRADIUS: proj->hitradius = iSet; break;
case PROJ_MOVECNT: proj->movecnt = iSet; break;
case PROJ_OFFSET: proj->offset = iSet; break;
case PROJ_BOUNCES: proj->bounces = iSet; break;
case PROJ_BSOUND: proj->bsound = iSet; break;
case PROJ_RANGE: proj->range = iSet; break;
case PROJ_FLASH_COLOR: proj->flashcolor = iSet; break;
case PROJ_USERDATA: proj->userdata = iSet; break;
}
}
else
{
switch (lLabelID)
{
case PROJ_WORKSLIKE: iSet = ProjectileData[lVar1].workslike; break;
case PROJ_SPAWNS: iSet = ProjectileData[lVar1].spawns; break;
case PROJ_SXREPEAT: iSet = ProjectileData[lVar1].sxrepeat; break;
case PROJ_SYREPEAT: iSet = ProjectileData[lVar1].syrepeat; break;
case PROJ_SOUND: iSet = ProjectileData[lVar1].sound; break;
case PROJ_ISOUND: iSet = ProjectileData[lVar1].isound; break;
case PROJ_VEL: iSet = ProjectileData[lVar1].vel; break;
case PROJ_EXTRA: iSet = ProjectileData[lVar1].extra; break;
case PROJ_DECAL: iSet = ProjectileData[lVar1].decal; break;
case PROJ_TRAIL: iSet = ProjectileData[lVar1].trail; break;
case PROJ_TXREPEAT: iSet = ProjectileData[lVar1].txrepeat; break;
case PROJ_TYREPEAT: iSet = ProjectileData[lVar1].tyrepeat; break;
case PROJ_TOFFSET: iSet = ProjectileData[lVar1].toffset; break;
case PROJ_TNUM: iSet = ProjectileData[lVar1].tnum; break;
case PROJ_DROP: iSet = ProjectileData[lVar1].drop; break;
case PROJ_CSTAT: iSet = ProjectileData[lVar1].cstat; break;
case PROJ_CLIPDIST: iSet = ProjectileData[lVar1].clipdist; break;
case PROJ_SHADE: iSet = ProjectileData[lVar1].shade; break;
case PROJ_XREPEAT: iSet = ProjectileData[lVar1].xrepeat; break;
case PROJ_YREPEAT: iSet = ProjectileData[lVar1].yrepeat; break;
case PROJ_PAL: iSet = ProjectileData[lVar1].pal; break;
case PROJ_EXTRA_RAND: iSet = ProjectileData[lVar1].extra_rand; break;
case PROJ_HITRADIUS: iSet = ProjectileData[lVar1].hitradius; break;
case PROJ_MOVECNT: iSet = ProjectileData[lVar1].movecnt; break;
case PROJ_OFFSET: iSet = ProjectileData[lVar1].offset; break;
case PROJ_BOUNCES: iSet = ProjectileData[lVar1].bounces; break;
case PROJ_BSOUND: iSet = ProjectileData[lVar1].bsound; break;
case PROJ_RANGE: iSet = ProjectileData[lVar1].range; break;
case PROJ_FLASH_COLOR: iSet = ProjectileData[lVar1].flashcolor; break;
case PROJ_USERDATA: iSet = ProjectileData[lVar1].userdata; break;
case PROJ_WORKSLIKE: iSet = proj->workslike; break;
case PROJ_SPAWNS: iSet = proj->spawns; break;
case PROJ_SXREPEAT: iSet = proj->sxrepeat; break;
case PROJ_SYREPEAT: iSet = proj->syrepeat; break;
case PROJ_SOUND: iSet = proj->sound; break;
case PROJ_ISOUND: iSet = proj->isound; break;
case PROJ_VEL: iSet = proj->vel; break;
case PROJ_EXTRA: iSet = proj->extra; break;
case PROJ_DECAL: iSet = proj->decal; break;
case PROJ_TRAIL: iSet = proj->trail; break;
case PROJ_TXREPEAT: iSet = proj->txrepeat; break;
case PROJ_TYREPEAT: iSet = proj->tyrepeat; break;
case PROJ_TOFFSET: iSet = proj->toffset; break;
case PROJ_TNUM: iSet = proj->tnum; break;
case PROJ_DROP: iSet = proj->drop; break;
case PROJ_CSTAT: iSet = proj->cstat; break;
case PROJ_CLIPDIST: iSet = proj->clipdist; break;
case PROJ_SHADE: iSet = proj->shade; break;
case PROJ_XREPEAT: iSet = proj->xrepeat; break;
case PROJ_YREPEAT: iSet = proj->yrepeat; break;
case PROJ_PAL: iSet = proj->pal; break;
case PROJ_EXTRA_RAND: iSet = proj->extra_rand; break;
case PROJ_HITRADIUS: iSet = proj->hitradius; break;
case PROJ_MOVECNT: iSet = proj->movecnt; break;
case PROJ_OFFSET: iSet = proj->offset; break;
case PROJ_BOUNCES: iSet = proj->bounces; break;
case PROJ_BSOUND: iSet = proj->bsound; break;
case PROJ_RANGE: iSet = proj->range; break;
case PROJ_FLASH_COLOR: iSet = proj->flashcolor; break;
case PROJ_USERDATA: iSet = proj->userdata; break;
default: iSet = -1; break;
}
@ -1323,7 +1325,7 @@ static void __fastcall VM_AccessProjectile(int32_t iSet, int32_t lVar1, int32_t
return;
badtile:
CON_ERRPRINTF("invalid tile (%d)\n", lVar1);
CON_ERRPRINTF("invalid projectile (%d)\n", lVar1);
insptr += (lVar2 == MAXGAMEVARS);
return;
}

View File

@ -752,10 +752,9 @@ badwall:
void __fastcall Gv_SetVar(int32_t const id, int32_t const lValue, int32_t const iActor, int32_t const iPlayer)
{
if (EDUKE32_PREDICT_FALSE((unsigned)id >= (unsigned)g_gameVarCount)) goto badvarid;
int const f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
int f;
f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
if (EDUKE32_PREDICT_FALSE((unsigned)id >= (unsigned)g_gameVarCount)) goto badvarid;
if (!f) aGameVars[id].val.lValue=lValue;
else if (f == GAMEVAR_PERPLAYER)
@ -809,6 +808,116 @@ static const char *gvxerrs[] = {
"Gv_GetVarX(): invalid array index",
};
int32_t __fastcall Gv_GetSpecialVarX(int32_t id)
{
int rv = -1;
if (id & (MAXGAMEVARS << 2)) // array
{
int const index = Gv_GetVarX(*insptr++);
id &= (MAXGAMEVARS - 1); // ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1));
int const siz = (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE) ?
Gv_GetVarX(aGameArrays[id].size) : aGameArrays[id].size;
if (EDUKE32_PREDICT_FALSE((unsigned) index >= (unsigned) siz))
{
CON_ERRPRINTF("%s %s[%d]\n", gvxerrs[GVX_BADINDEX], aGameArrays[id].szLabel, index);
return -1;
}
switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK)
{
case 0: rv = (aGameArrays[id].plValues)[index]; break;
case GAMEARRAY_OFINT: rv = ((int32_t *) aGameArrays[id].plValues)[index]; break;
case GAMEARRAY_OFSHORT: rv = ((int16_t *) aGameArrays[id].plValues)[index]; break;
case GAMEARRAY_OFCHAR: rv = ((uint8_t *) aGameArrays[id].plValues)[index]; break;
}
}
else if (id & (MAXGAMEVARS << 3)) // struct shortcut vars
{
int indexvar = *insptr;
int index = Gv_GetVarX(*insptr++);
switch ((id & (MAXGAMEVARS - 1)) - g_iSpriteVarID)
{
case 0: // if (id == g_iSpriteVarID)
{
int const label = *insptr++;
/*OSD_Printf("%d %d %d\n",__LINE__,index,label);*/
indexvar = (EDUKE32_PREDICT_FALSE(ActorLabels[label].flags & LABEL_HASPARM2)) ?
Gv_GetVarX(*insptr++) : 0;
if (EDUKE32_PREDICT_FALSE((unsigned) index >= MAXSPRITES))
{
id = index;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSPRITE], id);
return -1;
}
rv = VM_AccessSpriteX(index, label, indexvar);
break;
}
case 3: // else if (id == g_iPlayerVarID)
{
int const label = *insptr++;
if (indexvar == g_iThisActorID)
index = vm.g_p;
indexvar = (EDUKE32_PREDICT_FALSE(PlayerLabels[label].flags & LABEL_HASPARM2)) ?
Gv_GetVarX(*insptr++) : 0;
if (EDUKE32_PREDICT_FALSE((unsigned) index >= MAXPLAYERS))
{
id = index;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], id);
return -1;
}
rv = VM_AccessPlayerX(index, label, indexvar);
break;
}
case 4: // else if (id == g_iActorVarID)
rv = Gv_GetVar(*insptr++, index, vm.g_p);
break;
case 1: // else if (id == g_iSectorVarID)
if (indexvar == g_iThisActorID)
index = sprite[vm.g_i].sectnum;
if (EDUKE32_PREDICT_FALSE((unsigned) index >= MAXSECTORS))
{
id = index;
insptr++;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSECTOR], id);
return -1;
}
rv = VM_AccessSectorX(index, *insptr++);
break;
case 2: // else if (id == g_iWallVarID)
if (EDUKE32_PREDICT_FALSE((unsigned) index >= MAXWALLS))
{
id = index;
insptr++;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADWALL], id);
return -1;
}
rv = VM_AccessWallX(index, *insptr++);
break;
default: EDUKE32_UNREACHABLE_SECTION(return -1);
}
}
return rv;
}
int32_t __fastcall Gv_GetVarX(int32_t id)
{
if (id == g_iThisActorID)
@ -821,7 +930,7 @@ int32_t __fastcall Gv_GetVarX(int32_t id)
int rv = -1;
if (EDUKE32_PREDICT_FALSE(id >= g_gameVarCount && negateResult == 0))
goto nastyhacks;
rv = Gv_GetSpecialVarX(id);
else
{
id &= MAXGAMEVARS-1;
@ -847,121 +956,70 @@ int32_t __fastcall Gv_GetVarX(int32_t id)
rv = (*((uint8_t *) aGameVars[id].val.lValue)); break;
}
return (rv ^ -negateResult) + negateResult;
}
nastyhacks:
if (id & (MAXGAMEVARS << 2)) // array
{
int const index = Gv_GetVarX(*insptr++);
id &= (MAXGAMEVARS - 1); // ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1));
int const siz = (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE) ?
Gv_GetVarX(aGameArrays[id].size) : aGameArrays[id].size;
if (EDUKE32_PREDICT_FALSE((unsigned)index >= (unsigned)siz))
{
CON_ERRPRINTF("%s %s[%d]\n", gvxerrs[GVX_BADINDEX], aGameArrays[id].szLabel, index);
return -1;
}
switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK)
{
case 0: rv = (aGameArrays[id].plValues)[index]; break;
case GAMEARRAY_OFINT: rv = ((int32_t *)aGameArrays[id].plValues)[index]; break;
case GAMEARRAY_OFSHORT: rv = ((int16_t *)aGameArrays[id].plValues)[index]; break;
case GAMEARRAY_OFCHAR: rv = ((uint8_t *)aGameArrays[id].plValues)[index]; break;
}
}
else if (id & (MAXGAMEVARS << 3)) // struct shortcut vars
{
int indexvar = *insptr;
int index = Gv_GetVarX(*insptr++);
switch ((id & (MAXGAMEVARS - 1)) - g_iSpriteVarID)
{
case 0: // if (id == g_iSpriteVarID)
{
int const label = *insptr++;
/*OSD_Printf("%d %d %d\n",__LINE__,index,label);*/
indexvar = (EDUKE32_PREDICT_FALSE(ActorLabels[label].flags & LABEL_HASPARM2)) ?
Gv_GetVarX(*insptr++) : 0;
if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXSPRITES))
{
id = index;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSPRITE], id);
return -1;
}
rv = VM_AccessSpriteX(index, label, indexvar);
break;
}
case 3: // else if (id == g_iPlayerVarID)
{
int const label = *insptr++;
if (indexvar == g_iThisActorID)
index = vm.g_p;
indexvar = (EDUKE32_PREDICT_FALSE(PlayerLabels[label].flags & LABEL_HASPARM2)) ?
Gv_GetVarX(*insptr++) : 0;
if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXPLAYERS))
{
id = index;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], id);
return -1;
}
rv = VM_AccessPlayerX(index, label, indexvar);
break;
}
case 4: // else if (id == g_iActorVarID)
rv = Gv_GetVar(*insptr++, index, vm.g_p);
break;
case 1: // else if (id == g_iSectorVarID)
if (indexvar == g_iThisActorID)
index = sprite[vm.g_i].sectnum;
if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXSECTORS))
{
id = index;
insptr++;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSECTOR], id);
return -1;
}
rv = VM_AccessSectorX(index, *insptr++);
break;
case 2: // else if (id == g_iWallVarID)
if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXWALLS))
{
id = index;
insptr++;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADWALL], id);
return -1;
}
rv = VM_AccessWallX(index, *insptr++);
break;
default: EDUKE32_UNREACHABLE_SECTION(return -1);
}
}
return (rv ^ -negateResult) + negateResult;
perr:
id = vm.g_p;
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], id);
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], vm.g_p);
return -1;
}
void __fastcall Gv_GetManyVars(int32_t const count, int32_t * const rv)
{
for (int j = 0; j < count; ++j)
{
int id = *insptr++;
if (id == g_iThisActorID)
{
rv[j] = vm.g_i;
continue;
}
if (id == MAXGAMEVARS)
{
rv[j] = *insptr++;
continue;
}
int const negateResult = !!(id & (MAXGAMEVARS << 1));
if (EDUKE32_PREDICT_FALSE(id >= g_gameVarCount && negateResult == 0))
{
rv[j] = Gv_GetSpecialVarX(id);
continue;
}
id &= MAXGAMEVARS - 1;
int const f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK);
int val = aGameVars[id].val.lValue;
if (f == GAMEVAR_PERPLAYER)
{
if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p >= MAXPLAYERS))
goto perr;
val = aGameVars[id].val.plValues[vm.g_p];
}
else if (f == GAMEVAR_PERACTOR)
val = aGameVars[id].val.plValues[vm.g_i];
else
switch (f)
{
case GAMEVAR_INTPTR: val = (*((int32_t *)aGameVars[id].val.lValue)); break;
case GAMEVAR_SHORTPTR: val = (*((int16_t *)aGameVars[id].val.lValue)); break;
case GAMEVAR_CHARPTR: val = (*((uint8_t *)aGameVars[id].val.lValue)); break;
}
rv[j] = (val ^ -negateResult) + negateResult;
continue;
perr:
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], vm.g_p);
}
}
void __fastcall Gv_SetVarX(int32_t const id, int32_t const lValue)
{
int const f = aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
@ -1090,7 +1148,8 @@ void Gv_ResetSystemDefaults(void)
#endif
for (int i = 0; i <= MAXTILES - 1; i++)
Bmemcpy(&ProjectileData[i], &g_tile[i].defproj, sizeof(projectile_t));
if (g_tile[i].defproj)
*g_tile[i].proj = *g_tile[i].defproj;
#ifndef LUNATIC
int i;

View File

@ -103,6 +103,7 @@ extern int32_t g_gameArrayCount;
int32_t __fastcall Gv_GetVar(int32_t id, int32_t iActor, int32_t iPlayer);
void __fastcall Gv_SetVar(int32_t const id, int32_t const lValue, int32_t const iActor, int32_t const iPlayer);
int32_t __fastcall Gv_GetVarX(int32_t id);
void __fastcall Gv_GetManyVars(int32_t const count, int32_t * const rv);
void __fastcall Gv_SetVarX(int32_t const id, int32_t const lValue);
int32_t Gv_GetVarByLabel(const char *szGameLabel,int32_t const lDefault,int32_t const iActor,int32_t const iPlayer);

View File

@ -128,7 +128,6 @@ G_EXTERN playerspawn_t g_playerSpawnPoints[MAXPLAYERS];
G_EXTERN input_t inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
#pragma pack(pop)
G_EXTERN projectile_t ProjectileData[MAXTILES];
G_EXTERN projectile_t SpriteProjectile[MAXSPRITES];
G_EXTERN sound_t g_sounds[MAXSOUNDS];
G_EXTERN uint32_t everyothertime;

View File

@ -1041,7 +1041,9 @@ function _showview(x, y, z, a, horiz, sect, x1, y1, x2, y2, unbiasedp)
error("invalid coordinates "..str, 2)
end
CF.G_ShowView(x, y, z, a, horiz, sect, x1, y1, x2, y2, unbiasedp);
local pos = vec3(x, y, z)
CF.G_ShowView(pos, a, horiz, sect, x1, y1, x2, y2, unbiasedp);
end

View File

@ -368,7 +368,7 @@ extern int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s
extern void A_AddToDeleteQueue(int32_t i);
extern int32_t A_PlaySound(uint32_t num, int32_t i);
extern void A_DeleteSprite(int32_t s);
extern void G_ShowView(int32_t x, int32_t y, int32_t z, int32_t a, int32_t horiz, int32_t sect,
extern void G_ShowView(vec3_t vec, int32_t a, int32_t horiz, int32_t sect,
int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t unbiasedp);
extern void G_GameExit(const char *msg);
#ifdef __cplusplus
@ -420,7 +420,7 @@ DEFINE_VOID_CFUNC(A_AddToDeleteQueue, ONE_ARG)
DEFINE_RET_CFUNC(A_PlaySound, TWO_ARGS)
DEFINE_VOID_CFUNC(A_DeleteSprite, ONE_ARG)
DEFINE_VOID_CFUNC(G_ShowView, LARG(1), LARG(2), LARG(3), LARG(4), LARG(5), LARG(6),
LARG(7), LARG(8), LARG(9), LARG(10), LARG(11))
LARG(7), LARG(8), LARG(9))
#define CFUNC_REG(Name) { #Name, Name##_CF }

View File

@ -136,6 +136,11 @@ static void A_DoWaterTracers(int32_t x1,int32_t y1,int32_t z1,int32_t x2,int32_t
}
}
static inline projectile_t * Proj_GetProjectile(int tile)
{
return ((unsigned)tile < MAXTILES && g_tile[tile].proj) ? g_tile[tile].proj : (projectile_t *) &DefaultProjectile;
}
static void A_HitscanProjTrail(const vec3_t *sv, const vec3_t *dv, int32_t ang, int32_t atwith)
{
int32_t n, j, i;
@ -143,7 +148,7 @@ static void A_HitscanProjTrail(const vec3_t *sv, const vec3_t *dv, int32_t ang,
vec3_t srcvect;
vec3_t destvect;
const projectile_t *const proj = &ProjectileData[atwith];
const projectile_t *const proj = Proj_GetProjectile(atwith);
Bmemcpy(&destvect, dv, sizeof(vec3_t));
@ -212,7 +217,7 @@ static int32_t A_FindTargetSprite(const spritetype *s, int32_t aang, int32_t atw
if (g_player[snum].ps->auto_aim == 2)
{
if (A_CheckSpriteTileFlags(atwith,SFLAG_PROJECTILE) && (ProjectileData[atwith].workslike & PROJECTILE_RPG))
if (A_CheckSpriteTileFlags(atwith,SFLAG_PROJECTILE) && (Proj_GetProjectile(atwith)->workslike & PROJECTILE_RPG))
return -1;
switch (DYNAMICTILEMAP(atwith))
@ -390,7 +395,8 @@ static int32_t GetAutoAimAngle(int32_t i, int32_t p, int32_t atwith,
static void Proj_MaybeSpawn(int32_t k, int32_t atwith, const hitdata_t *hit)
{
// atwith < 0 is for hard-coded projectiles
int32_t spawntile = atwith < 0 ? -atwith : ProjectileData[atwith].spawns;
projectile_t * const proj = Proj_GetProjectile(atwith);
int32_t spawntile = atwith < 0 ? -atwith : proj->spawns;
if (spawntile >= 0)
{
@ -398,10 +404,10 @@ static void Proj_MaybeSpawn(int32_t k, int32_t atwith, const hitdata_t *hit)
if (atwith >= 0)
{
if (ProjectileData[atwith].sxrepeat > 4)
sprite[wh].xrepeat = ProjectileData[atwith].sxrepeat;
if (ProjectileData[atwith].syrepeat > 4)
sprite[wh].yrepeat = ProjectileData[atwith].syrepeat;
if (proj->sxrepeat > 4)
sprite[wh].xrepeat = proj->sxrepeat;
if (proj->syrepeat > 4)
sprite[wh].yrepeat = proj->syrepeat;
}
A_SetHitData(wh, hit);
@ -424,9 +430,10 @@ static int32_t Proj_InsertShotspark(const hitdata_t *hit, int32_t i, int32_t atw
static int32_t Proj_GetExtra(int32_t atwith)
{
int32_t extra = ProjectileData[atwith].extra;
if (ProjectileData[atwith].extra_rand > 0)
extra += (krand()%ProjectileData[atwith].extra_rand);
projectile_t * const proj = Proj_GetProjectile(atwith);
int32_t extra = proj->extra;
if (proj->extra_rand > 0)
extra += (krand() % proj->extra_rand);
return extra;
}
@ -566,7 +573,7 @@ static int32_t Proj_DoHitscan(int32_t i, int32_t cstatmask,
static void Proj_DoRandDecalSize(int32_t spritenum, int32_t atwith)
{
const projectile_t *const proj = &ProjectileData[atwith];
const projectile_t *const proj = Proj_GetProjectile(atwith);
if (proj->workslike & PROJECTILE_RANDDECALSIZE)
{
@ -811,7 +818,7 @@ static void Proj_HandleKnee(hitdata_t *hit, int32_t i, int32_t p, int32_t atwith
if (proj != NULL)
{
// Custom projectiles.
SpriteProjectile[j].workslike = ProjectileData[sprite[j].picnum].workslike;
SpriteProjectile[j].workslike = Proj_GetProjectile(sprite[j].picnum)->workslike;
sprite[j].extra = proj->extra;
}
@ -858,7 +865,7 @@ static void Proj_HandleKnee(hitdata_t *hit, int32_t i, int32_t p, int32_t atwith
static int32_t A_ShootCustom(const int32_t i, const int32_t atwith, int16_t sa, vec3_t * const srcvect)
{
/* Custom projectiles */
projectile_t *const proj = &ProjectileData[atwith];
projectile_t *const proj = Proj_GetProjectile(atwith);
int32_t j, k = -1, l;
int32_t vel, zvel = 0;
hitdata_t hit;
@ -999,10 +1006,7 @@ static int32_t A_ShootCustom(const int32_t i, const int32_t atwith, int16_t sa,
if (proj->clipdist != 255) sprite[j].clipdist = proj->clipdist;
else sprite[j].clipdist = 40;
{
int32_t picnum = sprite[j].picnum; // why?
Bmemcpy(&SpriteProjectile[j], &ProjectileData[picnum], sizeof(projectile_t));
}
SpriteProjectile[j] = *Proj_GetProjectile(sprite[j].picnum);
return j;

View File

@ -959,6 +959,12 @@ static void sv_quoteredefload();
static void sv_postquoteredef();
static void sv_restsave();
static void sv_restload();
static void sv_preprojectilesave();
static void sv_postprojectilesave();
static void sv_preprojectileload();
static void sv_postprojectileload();
static projectile_t *ProjectileData;
#define SVARDATALEN \
((sizeof(g_player[0].user_name)+sizeof(g_player[0].pcolor)+sizeof(g_player[0].pteam) \
@ -1062,7 +1068,6 @@ static const dataspec_t svgm_secwsp[] =
{ DS_NOCHK, &g_mirrorSector[0], sizeof(g_mirrorSector[0]), ARRAY_SIZE(g_mirrorSector) },
// projectiles
{ 0, &SpriteProjectile[0], sizeof(projectile_t), MAXSPRITES },
{ 0, &ProjectileData[0], sizeof(projectile_t), MAXTILES },
{ 0, &everyothertime, sizeof(everyothertime), 1 },
{ DS_END, 0, 0, 0 }
};
@ -1078,6 +1083,11 @@ static const dataspec_t svgm_script[] =
{ DS_SAVEFN|DS_NOCHK, (void *)&sv_prescriptsave_once, 0, 1 },
#endif
{ DS_NOCHK, &g_tile[0], sizeof(tiledata_t), MAXTILES },
{ DS_SAVEFN, (void *) &sv_preprojectilesave, 0, 1 },
{ DS_LOADFN, (void *) &sv_preprojectileload, 0, 1 },
{ DS_DYNAMIC|DS_CNT(g_numProjectiles), &ProjectileData, sizeof(projectile_t), (intptr_t)&g_numProjectiles },
{ DS_SAVEFN, (void *) &sv_postprojectilesave, 0, 1 },
{ DS_LOADFN, (void *) &sv_postprojectileload, 0, 1 },
#if !defined LUNATIC
{ DS_LOADFN|DS_NOCHK, (void *)&sv_prescriptload_once, 0, 1 },
{ DS_DYNAMIC|DS_CNT(g_scriptSize)|DS_NOCHK, &script, sizeof(script[0]), (intptr_t)&g_scriptSize },
@ -1711,6 +1721,59 @@ static void sv_quoteload()
}
}
}
static void sv_preprojectilesave()
{
ProjectileData = (projectile_t *) Xrealloc(ProjectileData, sizeof(projectile_t) * g_numProjectiles);
int onumprojectiles = g_numProjectiles;
g_numProjectiles = 0;
for (int i=0; i<MAXTILES; i++)
{
if (g_tile[i].proj)
{
Bmemcpy(&ProjectileData[g_numProjectiles], g_tile[i].proj, sizeof(projectile_t));
Bmemcpy(&ProjectileData[g_numProjectiles+1], g_tile[i].defproj, sizeof(projectile_t));
g_numProjectiles += 2;
}
}
Bassert(g_numProjectiles == onumprojectiles);
}
static void sv_postprojectilesave()
{
// DO_FREE_AND_NULL(ProjectileData);
}
static void sv_preprojectileload()
{
ProjectileData = (projectile_t *) Xrealloc(ProjectileData, sizeof(projectile_t) * g_numProjectiles);
}
static void sv_postprojectileload()
{
int onumprojectiles = g_numProjectiles;
g_numProjectiles = 0;
for (int i=0; i<MAXTILES; i++)
{
if (g_tile[i].proj)
{
g_tile[i].proj = (projectile_t *) Xmalloc(sizeof(projectile_t));
g_tile[i].defproj = (projectile_t *) Xmalloc(sizeof(projectile_t));
Bmemcpy(g_tile[i].proj, &ProjectileData[g_numProjectiles], sizeof(projectile_t));
Bmemcpy(g_tile[i].defproj, &ProjectileData[g_numProjectiles+1], sizeof(projectile_t));
g_numProjectiles += 2;
}
}
Bassert(g_numProjectiles == onumprojectiles);
// DO_FREE_AND_NULL(ProjectileData);
}
static void sv_prequoteredef()
{
// "+1" needed for dfwrite which doesn't handle the src==NULL && cnt==0 case