A crapload of random stuff.

* Polymer light access to m32script (light[<lightidx>].<field>). As an application, provide a state 'insertlights' that takes the currently active lights and puts them into the map as SEs (e.g. for maphack recovery).
* Prototype of a mechanism to gray out certain portion of a map, making them inactive to various, but not all, editing operations. Highlighting a set of sectors and pressing Ctrl-R will make the Z bounds be [(least ceiling z), (greatest floor z)] of all selected ones, pressing Ctrl-R when no sectors are highlighted will reset them. Not sure if it's for production use at this stage...
* The 'align walls' feature [.] now has three independently toggleable behaviours: recurse nextwalls (toggled when Ctrl is pressed), iterate point2s (disabled when Shift is pressed), and also copy pixel width (toggled when Alt is pressed).
* Make shades clamp instead of overflowing in the editor

Fixes:
* crash when carrying out certain operations on walls with xrepeat 0
* the Pause key on linux. Also make demo recording start on Shift-ScrollLock because ScrollLock alone is too easily pressed when pausing


git-svn-id: https://svn.eduke32.com/eduke32@1877 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-05-07 18:23:34 +00:00
parent bd410d8557
commit 203cf0b7b1
17 changed files with 1087 additions and 601 deletions

View file

@ -62,7 +62,9 @@ extern "C" {
#define PR_LIGHT_PRIO_LOW_GAME 5 #define PR_LIGHT_PRIO_LOW_GAME 5
////////// yax defs ////////// ////////// yax defs //////////
#define YAX_MAXBUNCHES (MAXSECTORS>>1) #define SECTORFLD(Sect,Fld, Cf) (*((Cf) ? (&sector[Sect].floor##Fld) : (&sector[Sect].ceiling##Fld)))
#define YAX_MAXBUNCHES 256
#define YAX_BIT 1024 #define YAX_BIT 1024
// "has next wall when constrained"-bit (1<<10: ceiling, 1<<11: floor) // "has next wall when constrained"-bit (1<<10: ceiling, 1<<11: floor)
#define YAX_NEXTWALLBIT(Cf) (1<<(10+Cf)) #define YAX_NEXTWALLBIT(Cf) (1<<(10+Cf))
@ -70,12 +72,13 @@ extern "C" {
#define YAX_CEILING 0 // don't change! #define YAX_CEILING 0 // don't change!
#define YAX_FLOOR 1 // don't change! #define YAX_FLOOR 1 // don't change!
#define SECTORFLD(Sect,Fld, Cf) (*((Cf) ? (&sector[Sect].floor##Fld) : (&sector[Sect].ceiling##Fld))) void yax_updategrays(int32_t posze);
#ifdef YAX_ENABLE
// more user tag hijacking: lotag/extra :/ // more user tag hijacking: lotag/extra :/
#define YAX_NEXTWALL(Wall, Cf) (*(&wall[Wall].lotag + 2*Cf)) # define YAX_NEXTWALL(Wall, Cf) (*(&wall[Wall].lotag + 2*Cf))
#define YAX_ITER_WALLS(Wal, Itervar, Cfvar) Cfvar=0, Itervar=(Wal); Itervar!=-1; \ # define YAX_ITER_WALLS(Wal, Itervar, Cfvar) Cfvar=0, Itervar=(Wal); Itervar!=-1; \
Itervar=yax_getnextwall(Itervar, Cfvar), (void)(Itervar==-1 && Cfvar==0 && (Cfvar=1) && (Itervar=yax_getnextwall((Wal), Cfvar))) Itervar=yax_getnextwall(Itervar, Cfvar), (void)(Itervar==-1 && Cfvar==0 && (Cfvar=1) && (Itervar=yax_getnextwall((Wal), Cfvar)))
int16_t yax_getbunch(int16_t i, int16_t cf); int16_t yax_getbunch(int16_t i, int16_t cf);
@ -85,14 +88,21 @@ void yax_setbunches(int16_t i, int16_t cb, int16_t fb);
int16_t yax_getnextwall(int16_t wal, int16_t cf); int16_t yax_getnextwall(int16_t wal, int16_t cf);
void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall); void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall);
void yax_update(int32_t onlyreset); void yax_update(int32_t onlyreset);
void yax_updategrays(int32_t posze);
int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, int16_t *ret_bunchnum); int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, int16_t *ret_bunchnum);
void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectnum);
#ifdef YAX_ENABLE static inline int32_t yax_waltosecmask(int32_t walclipmask)
{
// blocking: walstat&1 --> secstat&512
// hitscan: walstat&64 --> secstat&2048
return ((walclipmask&1)<<9) | ((walclipmask&64)<<5);
}
void yax_preparedrawrooms(void);
void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectnum);
# define YAX_SKIPSECTOR(i) if (graysectbitmap[(i)>>3]&(1<<((i)&7))) continue # define YAX_SKIPSECTOR(i) if (graysectbitmap[(i)>>3]&(1<<((i)&7))) continue
# define YAX_SKIPWALL(i) if (graywallbitmap[(i)>>3]&(1<<((i)&7))) continue # define YAX_SKIPWALL(i) if (graywallbitmap[(i)>>3]&(1<<((i)&7))) continue
#else #else
# define yax_preparedrawrooms()
# define yax_drawrooms(ExtAnalyzeSprites, horiz, sectnum)
# define YAX_SKIPSECTOR(i) (i)=(i) # define YAX_SKIPSECTOR(i) (i)=(i)
# define YAX_SKIPWALL(i) (i)=(i) # define YAX_SKIPWALL(i) (i)=(i)
#endif #endif
@ -128,7 +138,8 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn
// 11 = reverse transluscent masked floors // 11 = reverse transluscent masked floors
// bit 9: 1 = blocking ceiling/floor // bit 9: 1 = blocking ceiling/floor
// bit 10: 1 = YAX'ed ceiling/floor // bit 10: 1 = YAX'ed ceiling/floor
// bits 11-15: reserved // bit 11: 1 = hitscan-sensitive ceiling/floor
// bits 12-15: reserved
//40 bytes //40 bytes
typedef struct typedef struct

View file

@ -70,10 +70,8 @@ extern int32_t m32_osd_tryscript;
extern int32_t showheightindicators; extern int32_t showheightindicators;
extern int32_t showambiencesounds; extern int32_t showambiencesounds;
#ifdef YAX_ENABLE
extern uint8_t graysectbitmap[MAXSECTORS>>3]; extern uint8_t graysectbitmap[MAXSECTORS>>3];
extern uint8_t graywallbitmap[MAXWALLS>>3]; extern uint8_t graywallbitmap[MAXWALLS>>3];
#endif
// editor side view // editor side view
extern int32_t m32_sideview; extern int32_t m32_sideview;
@ -97,9 +95,10 @@ extern void bfirst_search_try(int16_t *list, uint8_t *bitmap, int32_t *eltnumptr
extern int32_t wallength(int16_t i); extern int32_t wallength(int16_t i);
extern void fixrepeats(int16_t i); extern void fixrepeats(int16_t i);
extern void fixxrepeat(int16_t i, uint32_t lenrepquot); extern uint32_t getlenbyrep(int32_t len, int32_t repeat);
extern void fixxrepeat(int16_t wallnum, uint32_t lenrepquot);
extern void AlignWallPoint2(int32_t w0); extern void AlignWallPoint2(int32_t w0);
extern int32_t AutoAlignWalls(int32_t w0, int32_t dorecurse, int32_t nrecurs); extern int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs);
extern int32_t ExtInit(void); extern int32_t ExtInit(void);
extern int32_t ExtPreInit(int32_t argc,const char **argv); extern int32_t ExtPreInit(int32_t argc,const char **argv);

View file

@ -247,16 +247,18 @@ extern int32_t halfxdim16, midydim16;
#define M32_SECTOR_VAR_ID 1 #define M32_SECTOR_VAR_ID 1
#define M32_WALL_VAR_ID 2 #define M32_WALL_VAR_ID 2
#define M32_TSPRITE_VAR_ID 3 #define M32_TSPRITE_VAR_ID 3
#define M32_LIGHT_VAR_ID 4
#define M32_THISACTOR_VAR_ID 4 #define M32_THISACTOR_VAR_ID 5
#define M32_RETURN_VAR_ID 5 #define M32_RETURN_VAR_ID 6
#define M32_LOTAG_VAR_ID 6 #define M32_LOTAG_VAR_ID 7
#define M32_HITAG_VAR_ID 7 #define M32_HITAG_VAR_ID 8
#define M32_TEXTURE_VAR_ID 8 #define M32_TEXTURE_VAR_ID 9
#define M32_LOCAL_ARRAY_ID 0 #define M32_LOCAL_ARRAY_ID 0
#define M32_PRINTERROR(Text, ...) OSD_Printf(OSD_ERROR "Line %d, %s: " Text "\n", g_errorLineNum, keyw[g_tw], ## __VA_ARGS__) #define M32_PRINTERROR(Text, ...) OSD_Printf(OSD_ERROR "Line %d, %s: " Text "\n", g_errorLineNum, keyw[g_tw], ## __VA_ARGS__)
#define M32_ERROR(Text, ...) do { M32_PRINTERROR(Text, ## __VA_ARGS__); vm.flags |= VMFLAG_ERROR; } while (0)
// how local gamevars are allocated: // how local gamevars are allocated:

View file

@ -329,11 +329,8 @@ static void M32_drawdebug(void)
if (m32_numdebuglines>0) if (m32_numdebuglines>0)
{ {
begindrawing(); begindrawing();
for (i=0; i<m32_numdebuglines; i++) for (i=0; i<m32_numdebuglines && y<ydim-8; i++, y+=8)
{
y+=8;
printext256(x,y,whitecol,0,m32_debugstr[i],xdimgame>640?0:1); printext256(x,y,whitecol,0,m32_debugstr[i],xdimgame>640?0:1);
}
enddrawing(); enddrawing();
} }
m32_numdebuglines=0; m32_numdebuglines=0;
@ -414,6 +411,9 @@ static void reset_default_mapstate(void)
numwalls = 0; numwalls = 0;
numsprites = 0; numsprites = 0;
editorzrange[0] = INT_MIN;
editorzrange[1] = INT_MAX;
initspritelists(); initspritelists();
taglab_init(); taglab_init();
@ -642,10 +642,10 @@ CANCEL:
ExtPreCheckKeys(); ExtPreCheckKeys();
yax_preparedrawrooms();
drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum); drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum);
#ifdef YAX_ENABLE
yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum); yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum);
#endif
ExtAnalyzeSprites(); ExtAnalyzeSprites();
drawmasks(); drawmasks();
@ -2229,7 +2229,7 @@ void overheadeditor(void)
int32_t tempint, tempint1, tempint2; int32_t tempint, tempint1, tempint2;
int32_t startwall=0, endwall, dax, day, x1, y1, x2, y2, x3, y3, x4, y4; int32_t startwall=0, endwall, dax, day, x1, y1, x2, y2, x3, y3, x4, y4;
int32_t highlightx1, highlighty1, highlightx2, highlighty2; int32_t highlightx1, highlighty1, highlightx2, highlighty2;
int16_t pag, suckwall=0, sucksect, split=0, bad; int16_t suckwall=0, sucksect, split=0, bad;
int16_t splitsect=0, joinsector[2]; int16_t splitsect=0, joinsector[2];
int16_t splitstartwall=0; int16_t splitstartwall=0;
int32_t mousx, mousy, bstatus; int32_t mousx, mousy, bstatus;
@ -2256,13 +2256,14 @@ void overheadeditor(void)
searchy = clamp(scale(searchy,ydim2d-STATUS2DSIZ2,ydimgame), 8, ydim2d-STATUS2DSIZ-8-1); searchy = clamp(scale(searchy,ydim2d-STATUS2DSIZ2,ydimgame), 8, ydim2d-STATUS2DSIZ-8-1);
oposz = pos.z; oposz = pos.z;
yax_updategrays(pos.z);
begindrawing(); //{{{ begindrawing(); //{{{
CLEARLINES2D(0, ydim, 0); CLEARLINES2D(0, ydim, 0);
enddrawing(); //}}} enddrawing(); //}}}
ydim16 = ydim-STATUS2DSIZ2; ydim16 = ydim-STATUS2DSIZ2;
pag = 0;
cursectorhighlight = -1; cursectorhighlight = -1;
lastpm16time = -1; lastpm16time = -1;
@ -3542,7 +3543,10 @@ end_yax: ;
} }
} }
else else
hlsectorbitmap[i>>3] |= (1<<(i&7)); {
if ((graysectbitmap[i>>3]&(1<<(i&7)))==0)
hlsectorbitmap[i>>3] |= (1<<(i&7));
}
} }
} }
@ -4263,7 +4267,11 @@ end_join_sectors:
NEXTWALL(i).nextwall = i; NEXTWALL(i).nextwall = i;
NEXTWALL(i).nextsector = numsectors; NEXTWALL(i).nextsector = numsectors;
} }
#ifdef YAX_ENABLE
yax_setbunches(numsectors, -1, -1);
yax_update(0);
yax_updategrays(pos.z);
#endif
numwalls = newnumwalls; numwalls = newnumwalls;
newnumwalls = -1; newnumwalls = -1;
numsectors++; numsectors++;
@ -5872,17 +5880,13 @@ int32_t LoadBoard(const char *filename, uint32_t flags)
if (filename != boardfilename) if (filename != boardfilename)
Bstrcpy(boardfilename, filename); Bstrcpy(boardfilename, filename);
if ((flags&1)==0)
{
highlightcnt = -1;
Bmemset(show2dwall, 0, sizeof(show2dwall)); //Clear all highlights
Bmemset(show2dsprite, 0, sizeof(show2dsprite));
}
for (i=0; i<MAXSECTORS; i++) sector[i].extra = -1; for (i=0; i<MAXSECTORS; i++) sector[i].extra = -1;
for (i=0; i<MAXWALLS; i++) wall[i].extra = -1; for (i=0; i<MAXWALLS; i++) wall[i].extra = -1;
for (i=0; i<MAXSPRITES; i++) sprite[i].extra = -1; for (i=0; i<MAXSPRITES; i++) sprite[i].extra = -1;
editorzrange[0] = INT_MIN;
editorzrange[1] = INT_MAX;
ExtPreLoadMap(); ExtPreLoadMap();
i = loadboard(boardfilename,(flags&4)|loadingflags, &pos.x,&pos.y,&pos.z,&ang,&cursectnum); i = loadboard(boardfilename,(flags&4)|loadingflags, &pos.x,&pos.y,&pos.z,&ang,&cursectnum);
if (i == -2) if (i == -2)
@ -5893,6 +5897,9 @@ int32_t LoadBoard(const char *filename, uint32_t flags)
return i; return i;
} }
highlightcnt = -1;
Bmemset(show2dwall, 0, sizeof(show2dwall)); //Clear all highlights
Bmemset(show2dsprite, 0, sizeof(show2dsprite));
if ((flags&4)==0) if ((flags&4)==0)
loadmhk(0); loadmhk(0);
@ -5915,9 +5922,6 @@ int32_t LoadBoard(const char *filename, uint32_t flags)
startposz = pos.z; startposz = pos.z;
startang = ang; startang = ang;
startsectnum = cursectnum; startsectnum = cursectnum;
#ifdef YAX_ENABLE
// yax_resetbunchnums();
#endif
return 0; return 0;
} }
@ -6220,7 +6224,7 @@ static void insertpoint(int16_t linehighlight, int32_t dax, int32_t day)
j = linehighlight; j = linehighlight;
sucksect = sectorofwall(j); sucksect = sectorofwall(j);
templenrepquot = divscale12(wallength(j), wall[j].xrepeat); templenrepquot = getlenbyrep(wallength(j), wall[j].xrepeat);
sector[sucksect].wallnum++; sector[sucksect].wallnum++;
for (i=sucksect+1; i<numsectors; i++) for (i=sucksect+1; i<numsectors; i++)
@ -6241,7 +6245,7 @@ static void insertpoint(int16_t linehighlight, int32_t dax, int32_t day)
if (wall[j].nextwall >= 0) if (wall[j].nextwall >= 0)
{ {
k = wall[j].nextwall; k = wall[j].nextwall;
templenrepquot = divscale12(wallength(k), wall[k].xrepeat); templenrepquot = getlenbyrep(wallength(k), wall[k].xrepeat);
sucksect = sectorofwall(k); sucksect = sectorofwall(k);
@ -6452,12 +6456,20 @@ void fixrepeats(int16_t i)
wall[i].xrepeat = clamp(mulscale10(dist,day), 1, 255); wall[i].xrepeat = clamp(mulscale10(dist,day), 1, 255);
} }
void fixxrepeat(int16_t i, uint32_t lenrepquot) // lenrepquot: divscale12(wallength,xrepeat) uint32_t getlenbyrep(int32_t len, int32_t repeat)
{
if (repeat <= 0)
return ((uint32_t)len)<<12;
return divscale12(len, repeat);
}
void fixxrepeat(int16_t wallnum, uint32_t lenrepquot) // lenrepquot: divscale12(wallength,xrepeat)
{ {
if (lenrepquot != 0) if (lenrepquot != 0)
{ {
uint32_t res = (((wallength(i)<<12)+(1<<11))/lenrepquot); uint32_t res = (((wallength(wallnum)<<12)+(1<<11))/lenrepquot);
wall[i].xrepeat = clamp(res, 1, 255); wall[wallnum].xrepeat = clamp(res, 1, 255);
} }
} }
@ -6726,10 +6738,10 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha
if (handleevents()) if (handleevents())
quitevent = 0; quitevent = 0;
yax_preparedrawrooms();
drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum); drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum);
#ifdef YAX_ENABLE
yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum); yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum);
#endif
ExtAnalyzeSprites(); ExtAnalyzeSprites();
drawmasks(); drawmasks();
@ -8197,11 +8209,15 @@ void AlignWallPoint2(int32_t w0)
AlignWalls(w0,GetWallBaseZ(w0), w1,GetWallBaseZ(w1), wall[w0].picnum); AlignWalls(w0,GetWallBaseZ(w0), w1,GetWallBaseZ(w1), wall[w0].picnum);
} }
// pass maxrecurs=0 for unconstrained recursion // flags:
int32_t AutoAlignWalls(int32_t w0, int32_t dorecurse, int32_t nrecurs) // 1: recurse nextwalls
// 2: iterate point2's
// 4: carry pixel width from first wall over to the rest
int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs)
{ {
int32_t z0, z1, tilenum, w1, visible, nextsec, sectnum; int32_t z0, z1, tilenum, w1, visible, nextsec, sectnum;
static int32_t numaligned; static int32_t numaligned, wall0;
static uint32_t lenrepquot;
tilenum = wall[w0].picnum; tilenum = wall[w0].picnum;
@ -8211,6 +8227,8 @@ int32_t AutoAlignWalls(int32_t w0, int32_t dorecurse, int32_t nrecurs)
Bmemset(visited, 0, sizeof(visited)); Bmemset(visited, 0, sizeof(visited));
visited[w0>>3] |= (1<<(w0&7)); visited[w0>>3] |= (1<<(w0&7));
numaligned = 0; numaligned = 0;
lenrepquot = getlenbyrep(wallength(w0), wall[w0].xrepeat);
wall0 = w0;
} }
z0 = GetWallBaseZ(w0); z0 = GetWallBaseZ(w0);
@ -8253,23 +8271,28 @@ int32_t AutoAlignWalls(int32_t w0, int32_t dorecurse, int32_t nrecurs)
if (visible) if (visible)
{ {
numaligned++; if ((flags&4) && w0!=wall0)
fixxrepeat(w0, lenrepquot);
AlignWalls(w0,z0, w1,z1, tilenum); AlignWalls(w0,z0, w1,z1, tilenum);
numaligned++;
//if wall was 1-sided, no need to recurse //if wall was 1-sided, no need to recurse
if (wall[w1].nextwall < 0) if (wall[w1].nextwall < 0)
{ {
if (!(flags&2))
break;
w0 = w1; w0 = w1;
z0 = GetWallBaseZ(w0); z0 = GetWallBaseZ(w0);
w1 = wall[w0].point2; w1 = wall[w0].point2;
continue; continue;
} }
else if (dorecurse) else if (flags&1)
AutoAlignWalls(w1, 1, nrecurs+1); AutoAlignWalls(w1, flags, nrecurs+1);
} }
} }
if (wall[w1].nextwall < 0) break; if (wall[w1].nextwall < 0 || !(flags&2))
break;
w1 = NEXTWALL(w1).point2; w1 = NEXTWALL(w1).point2;
} }

View file

@ -188,19 +188,73 @@ int16_t editstatus = 0;
////////// YAX ////////// ////////// YAX //////////
#if YAX_M32_DEBUG
extern char m32_debugstr[64][128];
extern int32_t m32_numdebuglines;
# define yaxdebug(fmt, ...) do { if (m32_numdebuglines<64) Bsprintf(m32_debugstr[m32_numdebuglines++], fmt, ##__VA_ARGS__); } while (0)
#else
# define yaxdebug(fmt, ...)
#endif
uint8_t graysectbitmap[MAXSECTORS>>3];
uint8_t graywallbitmap[MAXWALLS>>3];
#ifdef ENGINE_SCREENSHOT_DEBUG
int32_t engine_screenshot = 0;
#endif
void yax_updategrays(int32_t posze)
{
int32_t i, j, k=1;
#ifndef YAX_ENABLE
UNREFERENCED_PARAMETER(posze);
#endif
Bmemset(graysectbitmap, 0, sizeof(graysectbitmap));
Bmemset(graywallbitmap, 0, sizeof(graywallbitmap));
// update grayouts due to editorzrange
for (i=0; i<numsectors; i++)
{
#ifdef YAX_ENABLE
int16_t cb, fb;
yax_getbunches(i, &cb, &fb);
k = ((cb<0 || sector[i].ceilingz < posze) && (fb<0 || posze <= sector[i].floorz));
#endif
k &= (sector[i].ceilingz >= editorzrange[0] && sector[i].floorz <= editorzrange[1]);
if (!k) // outside bounds, gray out!
{
graysectbitmap[i>>3] |= (1<<(i&7));
for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++)
graywallbitmap[j>>3] |= (1<<(j&7));
}
}
}
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
// all references to floor/ceiling bunchnums should be through the // all references to floor/ceiling bunchnums should be through the
// get/set functions! // get/set functions!
static int32_t g_nodraw = 0;
static int32_t scansector_retfast = 0; static int32_t scansector_retfast = 0;
static int32_t scansector_collectsprites = 1;
static int32_t yax_globalcf = -1;
static int32_t yax_globallev = YAX_MAXDRAWS;
// duplicated tsprites
// [i]:
// i==MAXDRAWS: base level
// i<MAXDRAWS: MAXDRAWS-i-1 is level towards ceiling
// i>MAXDRAWS: i-MAXDRAWS-1 is level towards floor
static int16_t yax_spritesortcnt[1 + 2*YAX_MAXDRAWS];
static int16_t yax_tsprite[1 + 2*YAX_MAXDRAWS][MAXSPRITESONSCREEN];
// game-time YAX data structures // game-time YAX data structures
static int16_t yax_bunchnum[MAXSECTORS][2]; static int16_t yax_bunchnum[MAXSECTORS][2];
static int16_t yax_nextwall[MAXWALLS][2]; static int16_t yax_nextwall[MAXWALLS][2];
uint8_t graysectbitmap[MAXSECTORS>>3];
uint8_t graywallbitmap[MAXWALLS>>3];
static int32_t yax_islockededge(/*int16_t sec,*/ int16_t line, int16_t cf) static int32_t yax_islockededge(/*int16_t sec,*/ int16_t line, int16_t cf)
#if 1 #if 1
{ {
@ -223,7 +277,7 @@ static int32_t yax_islockededge(/*int16_t sec,*/ int16_t line, int16_t cf)
} }
#endif #endif
#define YAX_BUNCHNUM(Sect, Cf) (*(int16_t *)(&sector[Sect].ceilingxpanning + 8*Cf)) #define YAX_BUNCHNUM(Sect, Cf) (*(&sector[Sect].ceilingxpanning + 8*Cf))
//// bunch getters/setters //// bunch getters/setters
int16_t yax_getbunch(int16_t i, int16_t cf) int16_t yax_getbunch(int16_t i, int16_t cf)
@ -312,6 +366,7 @@ void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall)
//// in-struct --> array transfer; list construction //// in-struct --> array transfer; list construction
void yax_update(int32_t onlyreset) void yax_update(int32_t onlyreset)
{ {
// TODO: always make bunchnums consecutive
int32_t i, j, oeditstatus=editstatus; int32_t i, j, oeditstatus=editstatus;
int16_t cb, fb, tmpsect; int16_t cb, fb, tmpsect;
@ -382,34 +437,6 @@ void yax_update(int32_t onlyreset)
editstatus = oeditstatus; editstatus = oeditstatus;
} }
void yax_updategrays(int32_t posze)
{
int32_t i, j, k;
int16_t cb, fb;
Bmemset(graysectbitmap, 0, sizeof(graysectbitmap));
Bmemset(graywallbitmap, 0, sizeof(graywallbitmap));
if (numyaxbunches==0)
return;
for (i=0; i<numsectors; i++)
{
yax_getbunches(i, &cb, &fb);
if (cb<0 && fb<0)
continue;
k = ((cb<0 || sector[i].ceilingz < posze) && (fb<0 || posze <= sector[i].floorz));
if (!k) // outside bounds, gray out!
{
graysectbitmap[i>>3] |= (1<<(i&7));
for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++)
graywallbitmap[j>>3] |= (1<<(j&7));
}
}
}
int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, int16_t *ret_bunchnum) int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, int16_t *ret_bunchnum)
{ {
int16_t bunchnum = yax_getbunch(sectnum, cf); int16_t bunchnum = yax_getbunch(sectnum, cf);
@ -429,144 +456,326 @@ int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, i
return -1; return -1;
} }
static int32_t globalcf; // >0 b2 is farther away than b1
static int yax_cmpbunches(const int16_t *b1, const int16_t *b2) static int yax_cmpbunches(const int16_t *b1, const int16_t *b2)
{ {
int32_t s1,s2, w1,w2; int32_t s1,s2, w1,w2;
int64_t x1,y1, x2,y2, r; #if 1
int32_t dx1,dy1, dx2,dy2, r;
s1 = headsectbunch[globalcf][*b1]; #else
s2 = headsectbunch[globalcf][*b2]; int64_t dx1,dy1, dx2,dy2, r;
#endif
s1 = headsectbunch[yax_globalcf][*b1];
s2 = headsectbunch[yax_globalcf][*b2];
w1 = sector[s1].wallptr; w1 = sector[s1].wallptr;
w2 = sector[s2].wallptr; w2 = sector[s2].wallptr;
x1 = wall[w1].x-globalposx; y1 = wall[w1].y-globalposy; dx1 = wall[w1].x-globalposx; dy1 = wall[w1].y-globalposy;
x2 = wall[w2].x-globalposx; y2 = wall[w2].y-globalposy; dx2 = wall[w2].x-globalposx; dy2 = wall[w2].y-globalposy;
#if 1
r = (x2*x2 + y2*y2) - (x1*x1 + y1*y1); r = klabs(dx2+dy2) - klabs(dx1+dy1);
return r;
#else
r = (dx2*dx2 + dy2*dy2) - (dx1*dx1 + dy1*dy1);
if (r > 0) if (r > 0)
return 1; return 1;
return r>>63; return r>>63;
#endif
}
static int32_t yax_getbestsector(int32_t bunchnum, int32_t cf, const int16_t *ourbunch, int16_t sectnum)
{
int32_t k;
if (bunchnum==ourbunch[cf])
{
k = yax_getneighborsect(globalposx, globalposy, sectnum, cf, NULL);
if (k < 0)
k = headsectbunch[!cf][bunchnum];
return k;
}
else
{
// return headsectbunch[!cf][bunchnum];
scansector_retfast = 1;
scansector_collectsprites = 0;
for (k = headsectbunch[!cf][bunchnum]; k != -1; k = nextsectbunch[!cf][k])
{
numscans = numbunches = 0;
scansector(k);
if (numbunches > 0)
break;
}
scansector_collectsprites = 1;
scansector_retfast = 0;
return k;
}
}
static void yax_tweakpicnums(int32_t bunchnum, int32_t cf, int32_t restore)
{
static int16_t opicnum[2][MAXSECTORS];
int32_t i;
for (i=headsectbunch[cf][bunchnum]; i!=-1; i=nextsectbunch[cf][i])
if ((SECTORFLD(i,stat, cf)&(128+256))==0)
{
if (!restore)
{
opicnum[cf][i] = SECTORFLD(i,picnum, cf);
if (editstatus && showinvisibility)
SECTORFLD(i,picnum, cf) = MAXTILES-1;
else
SECTORFLD(i,picnum, cf) = 13; //FOF;
}
else
{
SECTORFLD(i,picnum, cf) = opicnum[cf][i];
}
}
}
static void yax_copytsprite(int16_t curbunchnum)
{
int16_t bunchnum;
int32_t i, spritenum, gotthrough, sectnum, cf;
int32_t sortcnt = yax_spritesortcnt[yax_globallev];
const spritetype *spr;
spritesortcnt = 0;
for (i=0; i<sortcnt; i++)
{
spritenum = yax_tsprite[yax_globallev][i];
gotthrough = spritenum&((MAXSPRITES<<1)+MAXSPRITES);
spritenum &= MAXSPRITES-1;
spr = &sprite[spritenum];
sectnum = spr->sectnum;
cf = -1;
if (gotthrough & MAXSPRITES)
cf = YAX_CEILING; // sprite got here through the ceiling of lower sector
else if (gotthrough & (MAXSPRITES<<1))
cf = YAX_FLOOR; // sprite got here through the floor of upper sector
if (cf != -1)
{
bunchnum = yax_getbunch(sectnum, cf);
if (yax_globallev != YAX_MAXDRAWS && curbunchnum != bunchnum)
continue;
sectnum = yax_getneighborsect(spr->x, spr->y, sectnum, cf, NULL);
if (sectnum < 0)
continue;
}
Bmemcpy(&tsprite[spritesortcnt], spr, sizeof(spritetype));
spriteext[spritenum].tspr = &tsprite[spritesortcnt];
tsprite[spritesortcnt].owner = spritenum;
tsprite[spritesortcnt].sectnum = sectnum; // tweak sectnum!
spritesortcnt++;
}
}
void yax_preparedrawrooms(void)
{
if (rendmode!=0 || numyaxbunches==0)
return;
g_nodraw = 1;
Bmemset(yax_spritesortcnt, 0, sizeof(yax_spritesortcnt));
} }
void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectnum) void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectnum)
{ {
static uint8_t havebunch[2][YAX_MAXBUNCHES>>3]; static uint8_t havebunch[YAX_MAXBUNCHES>>3];
static int16_t bunches[2][YAX_MAXBUNCHES]; static int16_t bunches[2][YAX_MAXBUNCHES], bestsec[2][YAX_MAXBUNCHES];
int32_t i, j, k, cf, diddraw = 0; int32_t i, j, k, lev, cf;
int32_t bnchcnt, bnchnum[2] = {0,0}; int32_t bnchcnt, bnchnum[2] = {0,0}, maxlev[2];
int16_t ourbunch[2] = {-1,-1}; int16_t ourbunch[2] = {-1,-1}, osectnum=sectnum;
int32_t bnchbeg[YAX_MAXDRAWS][2], bnchend[YAX_MAXDRAWS][2];
int32_t bbeg, numhere;
static uint8_t allgotsector[MAXSECTORS>>3]; // original (1st-draw) and accumulated ('per-level') gotsector bitmaps
static int16_t opicnum[MAXSECTORS]; static uint8_t ogotsector[MAXSECTORS>>3], lgotsector[MAXSECTORS>>3];
// int32_t t;
if (rendmode == 4 || numyaxbunches==0) if (rendmode!=0 || numyaxbunches==0)
{
#ifdef ENGINE_SCREENSHOT_DEBUG
engine_screenshot = 0;
#endif
return; return;
}
Bmemset(&havebunch[0], 0, (numsectors+7)>>3); // if we're here, there was just a drawrooms() call with g_nodraw=1
Bmemset(&havebunch[1], 0, (numsectors+7)>>3);
Bmemcpy(ogotsector, gotsector, (numsectors+7)>>3);
if (sectnum >= 0) if (sectnum >= 0)
yax_getbunches(sectnum, &ourbunch[0], &ourbunch[1]); yax_getbunches(sectnum, &ourbunch[0], &ourbunch[1]);
Bmemset(&havebunch, 0, (numyaxbunches+7)>>3);
for (i=0; i<numsectors; i++) // first scan all bunches above, then all below...
{
if (!(gotsector[i>>3]&(1<<(i&7))))
continue;
for (cf=0; cf<2; cf++)
{
j = yax_getbunch(i, cf);
if (j >= 0 && !(havebunch[cf][j>>3]&(1<<(j&7))))
{
havebunch[cf][j>>3] |= (1<<(j&7));
bunches[cf][bnchnum[cf]++] = j;
}
}
}
Bmemcpy(allgotsector, gotsector, (numsectors+7)>>3);
for (cf=0; cf<2; cf++) for (cf=0; cf<2; cf++)
{ {
globalcf = cf; yax_globalcf = cf;
qsort(bunches[cf], bnchnum[cf], sizeof(int16_t), (int(*)(const void *, const void *))&yax_cmpbunches); if (cf==1)
for (bnchcnt=0; bnchcnt<bnchnum[cf]; bnchcnt++)
{ {
j = bunches[cf][bnchcnt]; // the actual bunchnum... sectnum = osectnum;
Bmemcpy(gotsector, ogotsector, (numsectors+7)>>3);
if (j==ourbunch[cf])
{
k = yax_getneighborsect(globalposx, globalposy, sectnum, cf, NULL);
if (k < 0)
continue;
}
else
{
scansector_retfast = 1;
for (k = headsectbunch[!cf][j]; k != -1; k = nextsectbunch[!cf][k])
{
numscans = numbunches = 0;
scansector(k);
if (numbunches > 0)
break;
}
scansector_retfast = 0;
if (k < 0)
continue;
}
// tweak picnums vvv
for (i=headsectbunch[cf][j]; i!=-1; i=nextsectbunch[cf][i])
{
if ((SECTORFLD(i,stat, cf)&(128+256))==0)
{
opicnum[i] = SECTORFLD(i,picnum, cf);
if (editstatus && showinvisibility)
SECTORFLD(i,picnum, cf) = MAXTILES-1;
else
SECTORFLD(i,picnum, cf) = 13; //FOF;
}
}
// if (allgotsector[k>>3]&(1<<(k&7)))
// continue;
drawrooms(globalposx,globalposy,globalposz,globalang,horiz,k+MAXSECTORS); // +MAXSECTORS: force
ExtAnalyzeSprites();
drawmasks();
for (i=0; i<(numsectors+7)>>3; i++)
allgotsector[i] |= gotsector[i];
diddraw = 1;
} }
}
if (diddraw) for (lev=0; /*lev<YAX_MAXDRAWS*/; lev++)
{
drawrooms(globalposx,globalposy,globalposz,globalang,horiz,sectnum);
if (editstatus)
{ {
for (cf=0; cf<2; cf++) yax_globallev = YAX_MAXDRAWS + (-1 + 2*cf)*(lev+1);
for (bnchcnt=0; bnchcnt<bnchnum[cf]; bnchcnt++)
bbeg = bnchbeg[lev][cf] = bnchend[lev][cf] = bnchnum[cf];
numhere = 0;
for (i=0; i<numsectors; i++)
{
if (!(gotsector[i>>3]&(1<<(i&7))))
continue;
j = yax_getbunch(i, cf);
if (j >= 0 && !(havebunch[j>>3]&(1<<(j&7))))
{
havebunch[j>>3] |= (1<<(j&7));
bunches[cf][bnchnum[cf]++] = j;
bnchend[lev][cf]++;
numhere++;
}
}
if (numhere > 0)
{
// found bunches -- need to fake-draw
if (numhere > 1 && lev != YAX_MAXDRAWS-1)
Bmemset(lgotsector, 0, (numsectors+7)>>3);
qsort(&bunches[cf][bbeg], numhere, sizeof(int16_t),
(int(*)(const void *, const void *))&yax_cmpbunches);
for (bnchcnt=bbeg; bnchcnt < bbeg+numhere; bnchcnt++)
{ {
j = bunches[cf][bnchcnt]; // the actual bunchnum... j = bunches[cf][bnchcnt]; // the actual bunchnum...
// restore picnums ^^^ // t=getticks();
for (i=headsectbunch[cf][j]; i!=-1; i=nextsectbunch[cf][i]) k = yax_getbestsector(j, cf, ourbunch, sectnum);
if ((SECTORFLD(i,stat, cf)&(128+256))==0) bestsec[cf][bnchcnt] = k;
SECTORFLD(i,picnum, cf) = opicnum[i]; if (k < 0)
{
// initprintf("cf %d, lev %d: skipped bunch %d\n", cf, lev, j);
continue;
}
if (ourbunch[cf]==j)
{
ourbunch[cf] = yax_getbunch(k, cf);
sectnum = k;
}
if (lev != YAX_MAXDRAWS-1)
{
// +MAXSECTORS: force
drawrooms(globalposx,globalposy,globalposz,globalang,horiz,k+MAXSECTORS);
if (numhere > 1)
for (i=0; i<(numsectors+7)>>3; i++)
lgotsector[i] |= gotsector[i];
// yaxdebug("cf %d, lev %d: fake-drawn sec %d (bunch %d), %d dspr, %2d ms",
// cf, lev, k, j, yax_spritesortcnt[yax_globallev], getticks()-t);
}
} }
if (numhere > 1 && lev != YAX_MAXDRAWS-1)
Bmemcpy(gotsector, lgotsector, (numsectors+7)>>3);
}
if (numhere==0 || lev==YAX_MAXDRAWS-1)
{
// no new bunches or max level reached
maxlev[cf] = lev - (numhere==0);
break;
}
} }
} }
yax_globalcf = -1;
// now comes the real drawing!
g_nodraw = 0;
scansector_collectsprites = 0;
#if 0
begindrawing();
for (i=0; i<xdim*ydim; i++)
*((char *)frameplace + i) = i;
enddrawing();
#endif
for (cf=0; cf<2; cf++)
{
for (lev=maxlev[cf]; lev>=0; lev--)
{
yax_globallev = YAX_MAXDRAWS + (-1 + 2*cf)*(lev+1);
for (bnchcnt=bnchbeg[lev][cf]; bnchcnt<bnchend[lev][cf]; bnchcnt++)
{
j = bunches[cf][bnchcnt]; // the actual bunchnum...
k = bestsec[cf][bnchcnt]; // best start-drawing sector
// t=getticks();
yax_tweakpicnums(j, cf, 0);
if (k < 0)
continue;
drawrooms(globalposx,globalposy,globalposz,globalang,horiz,k+MAXSECTORS); // +MAXSECTORS: force
yax_copytsprite(j);
// yaxdebug("cf %d, lev %d: DRAWN sec %d (bunch %d), %d tspr, %2d ms",
// cf, lev, k, j, spritesortcnt, getticks()-t);
ExtAnalyzeSprites();
drawmasks();
}
if (lev < maxlev[cf])
for (bnchcnt=bnchbeg[lev+1][cf]; bnchcnt<bnchend[lev+1][cf]; bnchcnt++)
yax_tweakpicnums(bunches[cf][bnchcnt], cf, 1); // restore picnums
}
}
// t=getticks();
yax_globallev = YAX_MAXDRAWS;
// draw base level
drawrooms(globalposx,globalposy,globalposz,globalang,horiz,osectnum);
yax_copytsprite(-1);
scansector_collectsprites = 1;
for (cf=0; cf<2; cf++)
if (maxlev[cf] >= 0)
for (bnchcnt=bnchbeg[0][cf]; bnchcnt<bnchend[0][cf]; bnchcnt++)
yax_tweakpicnums(bunches[cf][bnchcnt], cf, 1); // restore picnums
// yaxdebug("DRAWN base level sec %d, %2d ms", osectnum, getticks()-t);
#ifdef ENGINE_SCREENSHOT_DEBUG
engine_screenshot = 0;
#endif
} }
#undef YAX_BUNCHNUM #undef YAX_BUNCHNUM
@ -1667,6 +1876,10 @@ static void scansector(int16_t sectnum)
int32_t xs, ys, x1, y1, x2, y2, xp1, yp1, xp2=0, yp2=0, tempint; int32_t xs, ys, x1, y1, x2, y2, xp1, yp1, xp2=0, yp2=0, tempint;
int16_t z, zz, startwall, endwall, numscansbefore, scanfirst, bunchfrst; int16_t z, zz, startwall, endwall, numscansbefore, scanfirst, bunchfrst;
int16_t nextsectnum; int16_t nextsectnum;
#ifdef YAX_ENABLE
int16_t cb, fb, *sortcnt;
int32_t spheight, spzofs;
#endif
if (sectnum < 0) return; if (sectnum < 0) return;
@ -1676,20 +1889,70 @@ static void scansector(int16_t sectnum)
do do
{ {
sectnum = sectorborder[--sectorbordercnt]; sectnum = sectorborder[--sectorbordercnt];
#ifdef YAX_ENABLE
if (scansector_collectsprites)
#endif
for (z=headspritesect[sectnum]; z>=0; z=nextspritesect[z]) for (z=headspritesect[sectnum]; z>=0; z=nextspritesect[z])
{ {
spr = &sprite[z]; spr = &sprite[z];
if ((((spr->cstat&0x8000) == 0) || (showinvisibility)) && if ((((spr->cstat&0x8000) == 0) || (showinvisibility)) &&
(spr->xrepeat > 0) && (spr->yrepeat > 0) && (spr->xrepeat > 0) && (spr->yrepeat > 0))
(spritesortcnt < MAXSPRITESONSCREEN))
{ {
xs = spr->x-globalposx; ys = spr->y-globalposy; xs = spr->x-globalposx; ys = spr->y-globalposy;
if ((spr->cstat&48) || (xs*cosglobalang+ys*singlobalang > 0)) if ((spr->cstat&48) || (xs*cosglobalang+ys*singlobalang > 0))
{ {
copybufbyte(spr,&tsprite[spritesortcnt],sizeof(spritetype)); #ifdef YAX_ENABLE
spriteext[z].tspr = (spritetype *)&tsprite[spritesortcnt]; if (g_nodraw==0)
tsprite[spritesortcnt++].owner = z; {
#endif
if (spritesortcnt >= MAXSPRITESONSCREEN)
break;
copybufbyte(spr,&tsprite[spritesortcnt],sizeof(spritetype));
spriteext[z].tspr = (spritetype *)&tsprite[spritesortcnt];
tsprite[spritesortcnt++].owner = z;
#ifdef YAX_ENABLE
}
else
{
sortcnt = &yax_spritesortcnt[yax_globallev];
if (*sortcnt >= MAXSPRITESONSCREEN)
break;
yax_tsprite[yax_globallev][*sortcnt] = z;
(*sortcnt)++;
// now check whether the tsprite needs duplication into another level
if ((spr->cstat&48)==32)
continue;
yax_getbunches(sectnum, &cb, &fb);
if (cb < 0 && fb < 0)
continue;
spriteheightofs(z, &spheight, &spzofs);
// TODO: get*zofslope?
if (cb>=0 && spr->z+spzofs-spheight < sector[sectnum].ceilingz)
{
sortcnt = &yax_spritesortcnt[yax_globallev-1];
if (*sortcnt < MAXSPRITESONSCREEN)
{
yax_tsprite[yax_globallev-1][*sortcnt] = z|MAXSPRITES;
(*sortcnt)++;
}
}
if (fb>=0 && spr->z+spzofs > sector[sectnum].floorz)
{
sortcnt = &yax_spritesortcnt[yax_globallev+1];
if (*sortcnt < MAXSPRITESONSCREEN)
{
yax_tsprite[yax_globallev+1][*sortcnt] = z|(MAXSPRITES<<1);
(*sortcnt)++;
}
}
}
#endif
} }
} }
} }
@ -2863,7 +3126,10 @@ static void wallscan(int32_t x1, int32_t x2, int16_t *uwal, int16_t *dwal, int32
char bad; char bad;
int32_t i, u4, d4, z; int32_t i, u4, d4, z;
#endif #endif
#ifdef YAX_ENABLE
if (g_nodraw)
return;
#endif
if (x2 >= xdim) x2 = xdim-1; if (x2 >= xdim) x2 = xdim-1;
tsizx = tilesizx[globalpicnum]; tsizx = tilesizx[globalpicnum];
@ -3605,23 +3871,28 @@ static void drawalls(int32_t bunch)
andwstat2 &= wallmost(dplc,z,sectnum,(uint8_t)1); andwstat2 &= wallmost(dplc,z,sectnum,(uint8_t)1);
} }
if ((andwstat1&3) != 3) //draw ceilings #ifdef YAX_ENABLE
if (!g_nodraw)
#endif
{ {
if ((sec->ceilingstat&3) == 2) if ((andwstat1&3) != 3) //draw ceilings
grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0); {
else if ((sec->ceilingstat&1) == 0) if ((sec->ceilingstat&3) == 2)
ceilscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0);
else else if ((sec->ceilingstat&1) == 0)
parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0,bunch); ceilscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum);
} else
if ((andwstat2&12) != 12) //draw floors parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0,bunch);
{ }
if ((sec->floorstat&3) == 2) if ((andwstat2&12) != 12) //draw floors
grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1); {
else if ((sec->floorstat&1) == 0) if ((sec->floorstat&3) == 2)
florscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1);
else else if ((sec->floorstat&1) == 0)
parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1,bunch); florscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum);
else
parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1,bunch);
}
} }
//DRAW WALLS SECTION! //DRAW WALLS SECTION!
@ -3929,7 +4200,8 @@ static void drawalls(int32_t bunch)
if (gotswall == 0) { gotswall = 1; prepwall(z,wal); } if (gotswall == 0) { gotswall = 1; prepwall(z,wal); }
wallscan(x1,x2,uplc,dplc,swall,lwall); wallscan(x1,x2,uplc,dplc,swall,lwall);
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if ((wal->cstat&YAX_NEXTWALLBIT(YAX_FLOOR)) && globalposz > sec->floorz) // TODO: slopes?
if (globalposz > sec->floorz && (x = yax_getnextwall(wallnum, YAX_FLOOR)) >= 0 && wall[x].nextwall>=0)
{ {
for (x=x1; x<=x2; x++) for (x=x1; x<=x2; x++)
if (dplc[x] > umost[x] && umost[x] <= dmost[x]) if (dplc[x] > umost[x] && umost[x] <= dmost[x])
@ -3938,7 +4210,7 @@ static void drawalls(int32_t bunch)
if (umost[x] > dmost[x]) numhits--; if (umost[x] > dmost[x]) numhits--;
} }
} }
else if ((wal->cstat&YAX_NEXTWALLBIT(YAX_CEILING)) && globalposz < sec->ceilingz) else if (globalposz < sec->ceilingz && (x = yax_getnextwall(wallnum, YAX_CEILING)) >= 0 && wall[x].nextwall>=0)
{ {
for (x=x1; x<=x2; x++) for (x=x1; x<=x2; x++)
if (uplc[x] < dmost[x] && umost[x] <= dmost[x]) if (uplc[x] < dmost[x] && umost[x] <= dmost[x])
@ -3962,6 +4234,17 @@ static void drawalls(int32_t bunch)
if (nextsectnum < 0) searchstat = 0; else searchstat = 4; if (nextsectnum < 0) searchstat = 0; else searchstat = 4;
} }
} }
#ifdef ENGINE_SCREENSHOT_DEBUG
if (engine_screenshot && !g_nodraw)
{
static char fn[BMAX_PATH];
Bsprintf(fn, "engshot%04d.png", engine_screenshot);
screencapture(fn, 0, "BUILD engine");
engine_screenshot++;
}
#endif
} }
} }
@ -7308,7 +7591,7 @@ void drawmasks(void)
} }
else if ((tspriteptr[i]->cstat&48) == 0) else if ((tspriteptr[i]->cstat&48) == 0)
{ {
killsprite: killsprite:
spritesortcnt--; //Delete face sprite if on wrong side! spritesortcnt--; //Delete face sprite if on wrong side!
if (i == spritesortcnt) continue; if (i == spritesortcnt) continue;
tspriteptr[i] = tspriteptr[spritesortcnt]; tspriteptr[i] = tspriteptr[spritesortcnt];
@ -10113,15 +10396,15 @@ restart_grand:
return 0; return 0;
} }
// 1st, 2nd, ... ceil/floor hit
// hitinfo->hitsect is >=0 because if oldhitsect's init and check above
if (SECTORFLD(hitinfo->hitsect,stat, hitscan_hitsectcf)&yax_waltosecmask(dawalclipmask))
return 0;
i = yax_getneighborsect(hitinfo->pos.x, hitinfo->pos.y, hitinfo->hitsect, i = yax_getneighborsect(hitinfo->pos.x, hitinfo->pos.y, hitinfo->hitsect,
hitscan_hitsectcf, NULL); hitscan_hitsectcf, NULL);
if (i >= 0) if (i >= 0)
{ {
// 1st, 2nd, ... ceil/floor hit
// hitinfo->hitsect is >=0 because if oldhitsect's init and check above
// TODO: check against cstat
Bmemcpy(&newsv, &hitinfo->pos, sizeof(vec3_t)); Bmemcpy(&newsv, &hitinfo->pos, sizeof(vec3_t));
sectnum = i; sectnum = i;
sv = &newsv; sv = &newsv;
@ -11212,6 +11495,20 @@ void updatesectorz(int32_t x, int32_t y, int32_t z, int16_t *sectnum)
getzsofslope(*sectnum, x, y, &cz, &fz); getzsofslope(*sectnum, x, y, &cz, &fz);
if ((z >= cz) && (z <= fz)) if ((z >= cz) && (z <= fz))
if (inside(x,y,*sectnum) != 0) return; if (inside(x,y,*sectnum) != 0) return;
#ifdef YAX_ENABLE
if (z < cz)
{
i = yax_getneighborsect(x, y, *sectnum, YAX_CEILING, NULL);
if (i >= 0 && z >= getceilzofslope(i, x, y))
{ *sectnum = i; return; }
}
if (z > fz)
{
i = yax_getneighborsect(x, y, *sectnum, YAX_FLOOR, NULL);
if (i >= 0 && z <= getflorzofslope(i, x, y))
{ *sectnum = i; return; }
}
#endif
wal = &wall[sector[*sectnum].wallptr]; wal = &wall[sector[*sectnum].wallptr];
j = sector[*sectnum].wallnum; j = sector[*sectnum].wallnum;
@ -11220,6 +11517,7 @@ void updatesectorz(int32_t x, int32_t y, int32_t z, int16_t *sectnum)
i = wal->nextsector; i = wal->nextsector;
if (i >= 0) if (i >= 0)
{ {
// YAX: TODO: check neighboring sectors here too?
getzsofslope(i, x, y, &cz, &fz); getzsofslope(i, x, y, &cz, &fz);
if ((z >= cz) && (z <= fz)) if ((z >= cz) && (z <= fz))
if (inside(x,y,(int16_t)i) == 1) if (inside(x,y,(int16_t)i) == 1)
@ -11661,7 +11959,7 @@ restart_grand:
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (numyaxbunches > 0) if (numyaxbunches > 0)
{ {
int32_t dasecclipmask = (dawalclipmask&1)<<9; // blocking: walstat&1 --> secstat&512 int32_t dasecclipmask = yax_waltosecmask(dawalclipmask);
int16_t cb, fb, didchange; int16_t cb, fb, didchange;
yax_getbunches(sectnum, &cb, &fb); yax_getbunches(sectnum, &cb, &fb);
@ -13417,11 +13715,16 @@ static void drawscreen_drawwall(int32_t i, int32_t posxe, int32_t posye, int32_t
if (!m32_sideview && (j >= 0) && (i > j)) return; if (!m32_sideview && (j >= 0) && (i > j)) return;
} }
#ifdef YAX_ENABLE #if 1
//def YAX_ENABLE
if ((graywallbitmap[i>>3] & (1<<(i&7))) || (j>=0 && (graywallbitmap[j>>3] & (1<<(j&7))))) if ((graywallbitmap[i>>3] & (1<<(i&7))) || (j>=0 && (graywallbitmap[j>>3] & (1<<(j&7)))))
{ {
if (!m32_sideview) #ifdef YAX_ENABLE
// yax'ed grayed out walls are always cleared from the overhead map.
// normal walls cleared out due to editorzrange are displayed, though
if (!m32_sideview && ((wall[i].cstat&YAX_NEXTWALLBITS) || (j>=0 && wall[j].cstat&YAX_NEXTWALLBITS)))
return; return;
#endif
col = 8; col = 8;
} }
else else

View file

@ -8,6 +8,10 @@
#define MAXNODESPERLINE 42 //Warning: This depends on MAXYSAVES & MAXYDIM! #define MAXNODESPERLINE 42 //Warning: This depends on MAXYSAVES & MAXYDIM!
#define MAXCLIPDIST 1024 #define MAXCLIPDIST 1024
#ifdef YAX_ENABLE
# define YAX_MAXDRAWS 4
#endif
extern uint8_t **basepaltableptr; extern uint8_t **basepaltableptr;
extern uint8_t basepalcount; extern uint8_t basepalcount;
extern uint8_t curbasepal; extern uint8_t curbasepal;

View file

@ -1586,6 +1586,13 @@ int32_t handleevents(void)
} }
else else
{ {
#ifdef __linux
// The pause key generates a release event right after
// the pressing one on linux. As a result, it gets unseen
// by the game most of the time.
if (code == 0x59) // pause
break;
#endif
SetKey(code, 0); SetKey(code, 0);
if (keypresscallback) if (keypresscallback)
keypresscallback(code, 0); keypresscallback(code, 0);
@ -1668,6 +1675,10 @@ int32_t handleevents(void)
} }
else else
{ {
#ifdef __linux
if (code == 0x59) // pause
break;
#endif
SetKey(code, 0); SetKey(code, 0);
if (keypresscallback) if (keypresscallback)
keypresscallback(code, 0); keypresscallback(code, 0);

View file

@ -115,6 +115,56 @@ defstate printlights
print "--ENDPRLIGHTS--" print "--ENDPRLIGHTS--"
ends ends
defstate insertlights
var sectnum
set k 0
for i activelights
{
insertsprite light[i].sector
// I is the inserted sprites' index now
set .picnum 1
set .x light[i].x
set .y light[i].y
set .z light[i].z
set .hitag light[i].range
set .xvel light[i].r
set .yvel light[i].g
set .zvel light[i].b
set .extra light[i].horiz
set .xoffset light[i].minshade
set .yoffset light[i].maxshade
set .owner light[i].tilenum
// now those that are calculated
ifge light[i].priority 4 or .cstat 512
ifge light[i].priority 2 or .cstat 2
ife light[i].radius 0
{
set .lotag 49
}
else
{
set .lotag 50
set j light[i].radius, shiftr j 1, sub j 128, inv j
clamp j -128 127
set .shade j
}
add k 1
}
qsprintf TQUOTE "* Inserted %d SE sprites based on active lights." k
print TQUOTE
ends
// convenient polymer SE light manipulation with keypad keys // convenient polymer SE light manipulation with keypad keys
// when aiming at light SE (49 or 50): // when aiming at light SE (49 or 50):
// KP 4,5,6,8: angle/horiz // KP 4,5,6,8: angle/horiz

View file

@ -409,7 +409,14 @@ int32_t A_MoveSprite(int32_t spritenum, const vec3_t *change, uint32_t cliptype)
&& &&
(osectnum == dasectnum || cansee(oldx, oldy, spr->z - bg, osectnum, spr->x, spr->y, daz - bg, dasectnum))*/ (osectnum == dasectnum || cansee(oldx, oldy, spr->z - bg, osectnum, spr->x, spr->y, daz - bg, dasectnum))*/
) )
{
spr->z = daz; spr->z = daz;
#ifdef YAX_ENABLE
if (change->z && yax_getbunch(spr->sectnum, !!change->z)>=0)
if ((SECTORFLD(spr->sectnum,stat, !!change->z)&yax_waltosecmask(cliptype))==0)
setspritez(spritenum, (vec3_t *)spr);
#endif
}
else if (retval == 0) retval = 16384+dasectnum; else if (retval == 0) retval = 16384+dasectnum;
if (retval == (16384+dasectnum)) if (retval == (16384+dasectnum))

View file

@ -298,7 +298,8 @@ static void drawgradient(void)
static void message_common1(const char *tmpstr) static void message_common1(const char *tmpstr)
{ {
Bstrcpy(getmessage,tmpstr); Bstrncpy(getmessage,tmpstr,sizeof(getmessage));
getmessage[sizeof(getmessage)-1] = 0;
getmessageleng = Bstrlen(getmessage); getmessageleng = Bstrlen(getmessage);
getmessagetimeoff = totalclock + 120*2 + getmessageleng*(120/30); getmessagetimeoff = totalclock + 120*2 + getmessageleng*(120/30);
@ -1011,8 +1012,8 @@ static uint64_t taglab_nolink_SEs = (1ull<<10)|(1ull<<27)|(1ull<<28)|(1ull<<29)|
// 16: yvel // 16: yvel
// 32: zvel // 32: zvel
// 64: owner // 64: owner
// The caller is responsible for checking bounds (usually tag>0), because // This function is only supposed to say something about the potential of a tag:
// this function is supposed to say something about the potential of a tag // it will also 'say yes' if a particular tag is zero.
int32_t taglab_linktags(int32_t spritep, int32_t num) int32_t taglab_linktags(int32_t spritep, int32_t num)
{ {
int32_t picnum; int32_t picnum;
@ -4360,12 +4361,13 @@ static void getnumberptr256(const char *namestart, void *num, int32_t bytes, int
if (handleevents()) if (handleevents())
quitevent = 0; quitevent = 0;
yax_preparedrawrooms();
drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum); drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum);
#ifdef YAX_ENABLE
yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum); yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum);
#endif
ExtAnalyzeSprites(); ExtAnalyzeSprites();
drawmasks(); drawmasks();
#ifdef POLYMER #ifdef POLYMER
if (rendmode == 4 && searchit == 2) if (rendmode == 4 && searchit == 2)
{ {
@ -4569,12 +4571,14 @@ ENDFOR1:
if (PRESSED_KEYSC(PGDN)) if (PRESSED_KEYSC(PGDN))
sprite[linebegspr].pal -= (sprite[linebegspr].pal>0); sprite[linebegspr].pal -= (sprite[linebegspr].pal>0);
yax_preparedrawrooms();
drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum); drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum);
#ifdef YAX_ENABLE
yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum); yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum);
#endif
ExtAnalyzeSprites(); ExtAnalyzeSprites();
drawmasks(); drawmasks();
#ifdef POLYMER #ifdef POLYMER
if (rendmode == 4 && searchit == 2) if (rendmode == 4 && searchit == 2)
{ {
@ -4830,6 +4834,16 @@ static void mouseaction_movesprites(int32_t *sumxvect, int32_t *sumyvect, int32_
} }
} }
static int32_t addtobyte(int8_t *byte, int32_t num)
{
int32_t onum = *byte, clamped=0;
if (onum + num != (int8_t)(onum + num))
clamped = 1;
if (!clamped)
*byte = (onum + num);
return clamped;
}
static void Keys3d(void) static void Keys3d(void)
{ {
int32_t i = 0, changedir,tsign; // ,count,nexti int32_t i = 0, changedir,tsign; // ,count,nexti
@ -5200,19 +5214,22 @@ static void Keys3d(void)
ShowFileText("sthelp.hlp", 1); ShowFileText("sthelp.hlp", 1);
} }
// . Search & fix panning to the right (3D)
if (AIMING_AT_WALL_OR_MASK && PRESSED_KEYSC(PERIOD)) if (AIMING_AT_WALL_OR_MASK && PRESSED_KEYSC(PERIOD))
{ {
int32_t naligned=AutoAlignWalls(searchwall, eitherCTRL, 0); int32_t naligned=AutoAlignWalls(searchwall, eitherCTRL|((!eitherSHIFT)<<1)|eitherALT<<2, 0);
message("Auto-aligned %d wall%s%s based on wall %d", naligned, message("Aligned %d wall%s based on wall %d%s%s%s", naligned,
naligned==1?"":"s", eitherCTRL?" recursively":"", searchwall); naligned==1?"":"s", searchwall,
eitherCTRL?", recursing nextwalls":"",
!eitherSHIFT?", iterating point2s":"",
eitherALT?", aligning xrepeats":"");
} }
tsign = 0; tsign = 0;
tsign -= PRESSED_KEYSC(COMMA); tsign -= PRESSED_KEYSC(COMMA);
tsign += PRESSED_KEYSC(PERIOD); tsign += PRESSED_KEYSC(PERIOD);
if (tsign) // , . Search & fix panning to the left/right (3D) if (tsign)
{ {
if (AIMING_AT_SPRITE) if (AIMING_AT_SPRITE)
{ {
@ -5426,18 +5443,29 @@ static void Keys3d(void)
message("Sprite %d hitscan sensitivity bit %s", searchwall, ONOFF(sprite[searchwall].cstat&256)); message("Sprite %d hitscan sensitivity bit %s", searchwall, ONOFF(sprite[searchwall].cstat&256));
asksave = 1; asksave = 1;
} }
else else if (AIMING_AT_WALL_OR_MASK || AIMING_AT_CEILING_OR_FLOOR)
{ {
wall[searchwall].cstat ^= 64; #ifdef YAX_ENABLE
if (AIMING_AT_CEILING_OR_FLOOR && yax_getbunch(searchsector, AIMING_AT_FLOOR)>=0)
if (wall[searchwall].nextwall >= 0 && !eitherSHIFT)
{ {
NEXTWALL(searchwall).cstat &= ~64; SECTORFLD(searchsector,stat, AIMING_AT_FLOOR) ^= 2048;
NEXTWALL(searchwall).cstat |= (wall[searchwall].cstat&64); message("Sector %d's %s hitscan sensitivity bit %s", searchsector, typestr[searchstat],
ONOFF(SECTORFLD(searchsector,stat, AIMING_AT_FLOOR)&2048));
asksave = 1;
} }
message("Wall %d hitscan sensitivity bit %s", searchwall, ONOFF(wall[searchwall].cstat&64)); else
#endif
{
wall[searchwall].cstat ^= 64;
asksave = 1; if (wall[searchwall].nextwall >= 0 && !eitherSHIFT)
{
NEXTWALL(searchwall).cstat &= ~64;
NEXTWALL(searchwall).cstat |= (wall[searchwall].cstat&64);
}
message("Wall %d hitscan sensitivity bit %s", searchwall, ONOFF(wall[searchwall].cstat&64));
asksave = 1;
}
} }
} }
} }
@ -5524,6 +5552,8 @@ static void Keys3d(void)
} }
else // if !eitherALT else // if !eitherALT
{ {
int32_t clamped=0;
k = (highlightsectorcnt>0 && (hlsectorbitmap[searchsector>>3]&(1<<(searchsector&7)))); k = (highlightsectorcnt>0 && (hlsectorbitmap[searchsector>>3]&(1<<(searchsector&7))));
tsign *= (1+3*eitherCTRL); tsign *= (1+3*eitherCTRL);
@ -5531,8 +5561,9 @@ static void Keys3d(void)
{ {
if (ASSERT_AIMING) if (ASSERT_AIMING)
{ {
AIMED_CF_SEL(shade) += tsign; clamped = addtobyte(&AIMED_CF_SEL(shade), tsign);
message("%s %d shade %d", Typestr[searchstat], i, AIMED_CF_SEL(shade)); message("%s %d shade %d%s", Typestr[searchstat], i, AIMED_CF_SEL(shade),
clamped ? " (clamped)":"");
} }
} }
else else
@ -5542,18 +5573,19 @@ static void Keys3d(void)
dasector = highlightsector[i]; dasector = highlightsector[i];
// sector shade // sector shade
sector[dasector].ceilingshade += tsign; clamped |= addtobyte(&sector[dasector].ceilingshade, tsign);
sector[dasector].floorshade += tsign; clamped |= addtobyte(&sector[dasector].floorshade, tsign);
// wall shade // wall shade
for (WALLS_OF_SECTOR(dasector, j)) for (WALLS_OF_SECTOR(dasector, j))
wall[j].shade += tsign; clamped |= addtobyte(&wall[j].shade, tsign);
// sprite shade // sprite shade
for (j=headspritesect[dasector]; j!=-1; j=nextspritesect[j]) for (j=headspritesect[dasector]; j!=-1; j=nextspritesect[j])
sprite[j].shade += tsign; clamped |= addtobyte(&sprite[j].shade, tsign);
} }
message("Highlighted sector shade changed by %d", tsign); message("Highlighted sector shade changed by %d%s", tsign,
clamped?" (some objects' shade clamped)":"");
} }
asksave = 1; asksave = 1;
} }
@ -5826,44 +5858,41 @@ static void Keys3d(void)
} }
else else
{ {
k = 0; k = !!(show2dsprite[searchwall>>3]&(1<<(searchwall&7)));
if (highlightcnt > 0)
for (i=0; i<highlightcnt; i++) tsign *= (updownunits << ((eitherCTRL && mouseaction)*3));
if (highlight[i] == searchwall+16384)
for (i=0; i<highlightcnt || k==0; i++)
{
if (k==0 || (highlight[i]&0xc000) == 16384)
{
int16_t sp = k==0 ? searchwall : highlight[i]&16383;
sprite[sp].z += tsign;
if (!spnoclip)
{ {
k = 1; spriteoncfz(sp, &cz, &fz);
inpclamp(&sprite[sp].z, cz, fz);
}
#ifdef YAX_ENABLE
else if (sprite[sp].sectnum >= 0)
{
int16_t cb, fb;
yax_getbunches(sprite[sp].sectnum, &cb, &fb);
if (cb >= 0 || fb >= 0)
setspritez(sp, (vec3_t *)&sprite[sp]);
}
#endif
if (k==0)
{
silentmessage("Sprite %d z = %d", searchwall, sprite[searchwall].z);
break; break;
} }
if (k == 0)
{
sprite[searchwall].z += tsign * (updownunits << ((eitherCTRL && mouseaction)*3));
if (!spnoclip)
{
spriteoncfz(searchwall, &cz, &fz);
inpclamp(&sprite[searchwall].z, cz, fz);
} }
silentmessage("Sprite %d z = %d", searchwall, sprite[searchwall].z); if (k==1)
silentmessage("Sprites %s by %d units", tsign<0 ? "raised" : "lowered", tsign);
}
else
{
for (i=0; i<highlightcnt; i++)
if ((highlight[i]&0xc000) == 16384)
{
int16_t sp = highlight[i]&16383;
sprite[sp].z += tsign * updownunits;
if (!spnoclip)
{
spriteoncfz(searchwall, &cz, &fz);
inpclamp(&sprite[searchwall].z, cz, fz);
}
}
silentmessage("Sprites %s by %d units", tsign<0 ? "raised" : "lowered", updownunits);
} }
} }
} }
@ -6431,8 +6460,6 @@ static void Keys3d(void)
#endif #endif
{ {
int32_t newslope = clamp(AIMED_CEILINGFLOOR(heinum) + tsign*i, -BHEINUM_MAX, BHEINUM_MAX); int32_t newslope = clamp(AIMED_CEILINGFLOOR(heinum) + tsign*i, -BHEINUM_MAX, BHEINUM_MAX);
if (!(AIMED_CEILINGFLOOR(stat)&2))
AIMED_CEILINGFLOOR(heinum) = 0;
setslope(searchsector, AIMING_AT_FLOOR, newslope); setslope(searchsector, AIMING_AT_FLOOR, newslope);
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
@ -6813,7 +6840,7 @@ static void Keys3d(void)
tempxrepeat = max(1, tempxrepeat); tempxrepeat = max(1, tempxrepeat);
tempyrepeat = AIMED_SEL_WALL(yrepeat); tempyrepeat = AIMED_SEL_WALL(yrepeat);
tempcstat = AIMED_SEL_WALL(cstat) & ~YAX_NEXTWALLBITS; tempcstat = AIMED_SEL_WALL(cstat) & ~YAX_NEXTWALLBITS;
templenrepquot = divscale12(wallength(searchwall), tempxrepeat); templenrepquot = getlenbyrep(wallength(searchwall), tempxrepeat);
} }
else if (AIMING_AT_CEILING_OR_FLOOR) else if (AIMING_AT_CEILING_OR_FLOOR)
{ {
@ -7209,12 +7236,11 @@ paste_ceiling_or_floor:
AIMED_CEILINGFLOOR(heinum) = 0; AIMED_CEILINGFLOOR(heinum) = 0;
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (j >= 0) if (j >= 0)
for (i=0; i<numsectors; i++) for (i=headsectbunch[!AIMING_AT_FLOOR][j]; i != -1; i=nextsectbunch[!AIMING_AT_FLOOR][i])
if (yax_getbunch(i, !AIMING_AT_FLOOR) == j) {
{ SECTORFLD(i,stat, !AIMING_AT_FLOOR) &= ~2;
SECTORFLD(i,stat, !AIMING_AT_FLOOR) &= ~2; SECTORFLD(i,heinum, !AIMING_AT_FLOOR) = 0;
SECTORFLD(i,heinum, !AIMING_AT_FLOOR) = 0; }
}
#endif #endif
} }
else if (AIMING_AT_SPRITE) else if (AIMING_AT_SPRITE)
@ -7491,7 +7517,7 @@ static void Keys2d(void)
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (/*!m32_sideview &&*/ numyaxbunches>0) if (/*!m32_sideview &&*/ numyaxbunches>0)
{ {
int32_t zsign=0, bestzdiff=INT32_MAX, hiz=0, loz=0, bottomp=0; int32_t zsign=0;
if (PRESSED_KEYSC(PGDN) || (eitherCTRL && PRESSED_KEYSC(DOWN))) if (PRESSED_KEYSC(PGDN) || (eitherCTRL && PRESSED_KEYSC(DOWN)))
zsign = 1; zsign = 1;
@ -7500,9 +7526,11 @@ static void Keys2d(void)
if (zsign) if (zsign)
{ {
int32_t bestzdiff=INT32_MAX, hiz=0, loz=0, bottomp=0;
for (i=0; i<numsectors; i++) for (i=0; i<numsectors; i++)
{ {
if (yax_getbunch(i, YAX_FLOOR) < 0) if (yax_getbunch(i, YAX_FLOOR) < 0 /*&& yax_getbunch(i, YAX_CEILING) < 0*/)
continue; continue;
loz = min(loz, sector[i].floorz); loz = min(loz, sector[i].floorz);
@ -7522,18 +7550,46 @@ static void Keys2d(void)
bestzdiff = pos.z - loz; bestzdiff = pos.z - loz;
} }
if (bestzdiff != INT32_MAX) pos.z += zsign*bestzdiff;
{ yax_updategrays(pos.z);
pos.z += zsign*bestzdiff;
yax_updategrays(pos.z);
printmessage16("Z position: %d%s", pos.z, printmessage16("Z position: %d%s", pos.z,
bottomp ? " (bottom)":(pos.z==loz ? " (top)":"")); bottomp ? " (bottom)":(pos.z==loz ? " (top)":""));
} updatesectorz(pos.x, pos.y, pos.z, &cursectnum);
} }
} }
#endif #endif
// Ctrl-R set editor z range to hightlightsectors' c/f bounds
if (eitherCTRL && PRESSED_KEYSC(R))
{
if (highlightsectorcnt <= 0)
{
editorzrange[0] = INT32_MIN;
editorzrange[1] = INT32_MAX;
printmessage16("Reset Z range");
}
else
{
int32_t damin=INT_MAX, damax=INT_MIN;
for (i=0; i<highlightsectorcnt; i++)
{
damin = min(damin, sector[highlightsector[i]].ceilingz);
damax = max(damax, sector[highlightsector[i]].floorz);
}
if (damin < damax)
{
editorzrange[0] = damin;
editorzrange[1] = damax;
printmessage16("Set Z range to highlighted sector bounds (%d..%d)",
editorzrange[0], editorzrange[1]);
}
}
yax_updategrays(pos.z);
}
#if 0 #if 0
if (keystatus[KEYSC_QUOTE] && PRESSED_KEYSC(Z)) // ' z if (keystatus[KEYSC_QUOTE] && PRESSED_KEYSC(Z)) // ' z
{ {
@ -10873,9 +10929,14 @@ void ExtCheckKeys(void)
if (PRESSED_KEYSC(F12)) //F12 if (PRESSED_KEYSC(F12)) //F12
{ {
#ifdef ENGINE_SCREENSHOT_DEBUG
extern int32_t engine_screenshot;
engine_screenshot = 1;
#else
Bsprintf(tempbuf, "Mapster32 %s", ExtGetVer()); Bsprintf(tempbuf, "Mapster32 %s", ExtGetVer());
screencapture("captxxxx.tga", keystatus[KEYSC_LSHIFT]|keystatus[KEYSC_RSHIFT], tempbuf); screencapture("captxxxx.tga", eitherSHIFT, tempbuf);
message("Saved screenshot %04d", capturecount-1); message("Saved screenshot %04d", capturecount-1);
#endif
} }
} }

View file

@ -3212,8 +3212,8 @@ void G_SE40(int32_t smoothratio)
} }
} }
#ifdef YAX_ENABLE
static int32_t g_yax_smoothratio; static int32_t g_yax_smoothratio;
#ifdef YAX_ENABLE
static void G_AnalyzeSprites(void) static void G_AnalyzeSprites(void)
{ {
G_DoSpriteAnimations(ud.camera.x,ud.camera.y,ud.cameraang,g_yax_smoothratio); G_DoSpriteAnimations(ud.camera.x,ud.camera.y,ud.cameraang,g_yax_smoothratio);
@ -3277,11 +3277,11 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio)
if (getrendermode() == 4) if (getrendermode() == 4)
polymer_setanimatesprites(G_DoSpriteAnimations, s->x, s->y, ud.cameraang, smoothratio); polymer_setanimatesprites(G_DoSpriteAnimations, s->x, s->y, ud.cameraang, smoothratio);
#endif #endif
yax_preparedrawrooms();
drawrooms(s->x,s->y,s->z-(4<<8),ud.cameraang,s->yvel,s->sectnum); drawrooms(s->x,s->y,s->z-(4<<8),ud.cameraang,s->yvel,s->sectnum);
g_yax_smoothratio = smoothratio;
yax_drawrooms(G_AnalyzeSprites, s->yvel, s->sectnum);
G_DoSpriteAnimations(s->x,s->y,ud.cameraang,smoothratio); G_DoSpriteAnimations(s->x,s->y,ud.cameraang,smoothratio);
drawmasks(); drawmasks();
} }
else else
@ -3418,8 +3418,14 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio)
if (ud.camerasect >= 0) if (ud.camerasect >= 0)
{ {
getzsofslope(ud.camerasect,ud.camera.x,ud.camera.y,&cz,&fz); getzsofslope(ud.camerasect,ud.camera.x,ud.camera.y,&cz,&fz);
if (ud.camera.z < cz+(4<<8)) ud.camera.z = cz+(4<<8); #ifdef YAX_ENABLE
if (ud.camera.z > fz-(4<<8)) ud.camera.z = fz-(4<<8); if (yax_getbunch(ud.camerasect, YAX_CEILING) < 0)
#endif
if (ud.camera.z < cz+(4<<8)) ud.camera.z = cz+(4<<8);
#ifdef YAX_ENABLE
if (yax_getbunch(ud.camerasect, YAX_FLOOR) < 0)
#endif
if (ud.camera.z > fz-(4<<8)) ud.camera.z = fz-(4<<8);
} }
if (ud.camerahoriz > HORIZ_MAX) ud.camerahoriz = HORIZ_MAX; if (ud.camerahoriz > HORIZ_MAX) ud.camerahoriz = HORIZ_MAX;
@ -3470,11 +3476,11 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio)
polymer_setanimatesprites(G_DoSpriteAnimations, ud.camera.x,ud.camera.y,ud.cameraang,smoothratio); polymer_setanimatesprites(G_DoSpriteAnimations, ud.camera.x,ud.camera.y,ud.cameraang,smoothratio);
#endif #endif
yax_preparedrawrooms();
drawrooms(ud.camera.x,ud.camera.y,ud.camera.z,ud.cameraang,ud.camerahoriz,ud.camerasect); drawrooms(ud.camera.x,ud.camera.y,ud.camera.z,ud.cameraang,ud.camerahoriz,ud.camerasect);
#ifdef YAX_ENABLE
g_yax_smoothratio = smoothratio; g_yax_smoothratio = smoothratio;
yax_drawrooms(G_AnalyzeSprites, ud.camerahoriz, ud.camerasect); yax_drawrooms(G_AnalyzeSprites, ud.camerahoriz, ud.camerasect);
#endif
// dupe the sprites touching the portal to the other sector // dupe the sprites touching the portal to the other sector
if (ror_sprite != -1) if (ror_sprite != -1)
@ -7242,7 +7248,8 @@ void G_HandleLocalKeys(void)
switch (ud.recstat) switch (ud.recstat)
{ {
case 0: case 0:
G_OpenDemoWrite(); if (SHIFTS_IS_PRESSED)
G_OpenDemoWrite();
break; break;
case 1: case 1:
G_CloseDemoWrite(); G_CloseDemoWrite();

View file

@ -310,7 +310,9 @@ void A_Fall(int32_t iActor)
{ {
spritetype *s = &sprite[iActor]; spritetype *s = &sprite[iActor];
int32_t hz,lz,c = g_spriteGravity; int32_t hz,lz,c = g_spriteGravity;
#ifdef YAX_ENABLE
int16_t fbunch;
#endif
if (G_CheckForSpaceFloor(s->sectnum)) if (G_CheckForSpaceFloor(s->sectnum))
c = 0; c = 0;
else else
@ -334,12 +336,27 @@ void A_Fall(int32_t iActor)
actor[iActor].floorz = sector[s->sectnum].floorz; actor[iActor].floorz = sector[s->sectnum].floorz;
} }
if (s->z < actor[iActor].floorz-(ZOFFSET)) #ifdef YAX_ENABLE
if (sector[s->sectnum].floorstat&512)
fbunch = -1;
else
fbunch = yax_getbunch(s->sectnum, YAX_FLOOR);
#endif
if (s->z < actor[iActor].floorz-(ZOFFSET)
#ifdef YAX_ENABLE
|| (fbunch >= 0)
#endif
)
{ {
if (sector[s->sectnum].lotag == 2 && s->zvel > 3122) if (sector[s->sectnum].lotag == 2 && s->zvel > 3122)
s->zvel = 3144; s->zvel = 3144;
s->z += s->zvel = min(6144, s->zvel+c); s->z += s->zvel = min(6144, s->zvel+c);
} }
#ifdef YAX_ENABLE
if (fbunch >= 0)
setspritez(iActor, (vec3_t *)s);
if (fbunch < 0)
#endif
if (s->z >= actor[iActor].floorz-(ZOFFSET)) if (s->z >= actor[iActor].floorz-(ZOFFSET))
{ {
s->z = actor[iActor].floorz - ZOFFSET; s->z = actor[iActor].floorz - ZOFFSET;
@ -1106,7 +1123,12 @@ skip_check:
if (vm.g_sp->z < (actor[vm.g_i].floorz-ZOFFSET)) if (vm.g_sp->z < (actor[vm.g_i].floorz-ZOFFSET))
{ {
vm.g_sp->z += vm.g_sp->zvel = min(6144, vm.g_sp->zvel+j); vm.g_sp->z += vm.g_sp->zvel = min(6144, vm.g_sp->zvel+j);
#ifdef YAX_ENABLE
j = yax_getbunch(vm.g_sp->sectnum, YAX_FLOOR);
if (j >= 0 && (sector[vm.g_sp->sectnum].floorstat&512)==0)
setspritez(vm.g_i, (vec3_t *)vm.g_sp);
else
#endif
if (vm.g_sp->z > (actor[vm.g_i].floorz - ZOFFSET)) if (vm.g_sp->z > (actor[vm.g_i].floorz - ZOFFSET))
vm.g_sp->z = (actor[vm.g_i].floorz - ZOFFSET); vm.g_sp->z = (actor[vm.g_i].floorz - ZOFFSET);
continue; continue;

View file

@ -189,16 +189,6 @@ const char *keyw[] =
"jump", "jump",
"{", "{",
"}", "}",
#if 0
"setsector",
"getsector",
"setwall",
"getwall",
"setsprite",
"getsprite",
"gettspr",
"settspr",
#endif
"gamearray", "gamearray",
"setarray", "setarray",
"getarraysize", "getarraysize",
@ -503,7 +493,29 @@ const memberlabel_t SpriteLabels[]=
{ "extra", SPRITE_EXTRA, 0, 0, 0 }, { "extra", SPRITE_EXTRA, 0, 0, 0 },
// aliases // aliases
{ "filler", SPRITE_DETAIL, 1, 0, 0 }, { "filler", SPRITE_DETAIL, 1, 0, 0 },
{ "", -1, 0, 0, 0 } // END OF LIST
};
const memberlabel_t LightLabels[]=
{
{ "x", LIGHT_X, 0, -BXY_MAX, BXY_MAX },
{ "y", LIGHT_Y, 0, -BXY_MAX, BXY_MAX },
{ "z", LIGHT_Z, 0, 0, 0 },
{ "horiz", LIGHT_HORIZ, 0, 0, 0 },
{ "range", LIGHT_RANGE, 0, 0, 0 },
{ "angle", LIGHT_ANGLE, 0, 0, 0 },
{ "faderadius", LIGHT_FADERADIUS, 0, 0, 0 },
{ "radius", LIGHT_RADIUS, 0, 0, 0 },
{ "sector", LIGHT_SECTOR, 0, 0, 0 },
{ "r", LIGHT_R, 0, 0, 255 },
{ "g", LIGHT_G, 0, 0, 255 },
{ "b", LIGHT_B, 0, 0, 255 },
{ "priority", LIGHT_PRIORITY, 0, 0, PR_MAXLIGHTPRIORITY-1 },
{ "tilenum", LIGHT_TILENUM, 0, 0, MAXTILES-1 },
{ "minshade", LIGHT_MINSHADE, 0, -128, 127 },
{ "maxshade", LIGHT_MAXSHADE, 0, -128, 127 },
//
{ "active", LIGHT_ACTIVE, 0, 0, 1 },
{ "", -1, 0, 0, 0 } // END OF LIST { "", -1, 0, 0, 0 } // END OF LIST
}; };
@ -512,6 +524,7 @@ const tokenmap_t iter_tokens[] =
{ "allsprites", ITER_ALLSPRITES }, { "allsprites", ITER_ALLSPRITES },
{ "allsectors", ITER_ALLSECTORS }, { "allsectors", ITER_ALLSECTORS },
{ "allwalls", ITER_ALLWALLS }, { "allwalls", ITER_ALLWALLS },
{ "activelights", ITER_ACTIVELIGHTS },
{ "selsprites", ITER_SELSPRITES }, { "selsprites", ITER_SELSPRITES },
{ "selsectors", ITER_SELSECTORS }, { "selsectors", ITER_SELSECTORS },
{ "selwalls", ITER_SELWALLS }, { "selwalls", ITER_SELWALLS },
@ -523,6 +536,7 @@ const tokenmap_t iter_tokens[] =
// vvv alternatives go here vvv // vvv alternatives go here vvv
{ "selspr", ITER_SELSPRITES }, { "selspr", ITER_SELSPRITES },
{ "selsec", ITER_SELSECTORS }, { "selsec", ITER_SELSECTORS },
{ "lights", ITER_ACTIVELIGHTS },
{ "sprofsec", ITER_SPRITESOFSECTOR }, { "sprofsec", ITER_SPRITESOFSECTOR },
{ "walofsec", ITER_WALLSOFSECTOR }, { "walofsec", ITER_WALLSOFSECTOR },
{ "", -1 } // END OF LIST { "", -1 } // END OF LIST
@ -541,6 +555,7 @@ static hashtable_t h_iter = { ITER_END, NULL };
static hashtable_t h_sector = { SECTOR_END>>1, NULL }; static hashtable_t h_sector = { SECTOR_END>>1, NULL };
static hashtable_t h_wall = { WALL_END>>1, NULL }; static hashtable_t h_wall = { WALL_END>>1, NULL };
static hashtable_t h_sprite = { SPRITE_END>>1, NULL }; static hashtable_t h_sprite = { SPRITE_END>>1, NULL };
static hashtable_t h_light = { SPRITE_END>>1, NULL };
static void C_InitHashes() static void C_InitHashes()
@ -574,6 +589,10 @@ static void C_InitHashes()
hash_add(&h_sprite,SpriteLabels[i].name,i, 0); hash_add(&h_sprite,SpriteLabels[i].name,i, 0);
// hash_add(&h_sprite,"filler", SPRITE_DETAIL, 0); // hash_add(&h_sprite,"filler", SPRITE_DETAIL, 0);
hash_init(&h_light);
for (i=0; LightLabels[i].lId >=0; i++)
hash_add(&h_light,LightLabels[i].name,i, 0);
hash_init(&h_iter); hash_init(&h_iter);
for (i=0; iter_tokens[i].val >=0; i++) for (i=0; iter_tokens[i].val >=0; i++)
hash_add(&h_iter, iter_tokens[i].token, iter_tokens[i].val, 0); hash_add(&h_iter, iter_tokens[i].token, iter_tokens[i].val, 0);
@ -926,7 +945,7 @@ static int32_t parse_integer_literal(int32_t *num)
{ {
long lnum; long lnum;
errno = 0; errno = 0;
lnum = strtol(textptr, NULL, 10); lnum = Bstrtol(textptr, NULL, 10);
if (errno || (sizeof(long)>4 && (lnum<INT_MIN || lnum>INT_MAX))) if (errno || (sizeof(long)>4 && (lnum<INT_MIN || lnum>INT_MAX)))
{ {
C_CUSTOMERROR("integer literal exceeds bitwidth."); C_CUSTOMERROR("integer literal exceeds bitwidth.");
@ -1084,6 +1103,9 @@ static void C_GetNextVarType(int32_t type)
if (*textptr == '[') //read of array as a gamevar if (*textptr == '[') //read of array as a gamevar
{ {
int32_t lLabelID = -1, aridx; int32_t lLabelID = -1, aridx;
#ifdef POLYMER
int32_t lightp = 0;
#endif
textptr++; textptr++;
flags |= M32_FLAG_ARRAY; flags |= M32_FLAG_ARRAY;
@ -1100,12 +1122,18 @@ static void C_GetNextVarType(int32_t type)
{ {
id = GetGamevarID(tlabel, 0); id = GetGamevarID(tlabel, 0);
if (id < 0 || id >= 4) if (id < 0 || id >= 5)
{ {
C_CUSTOMERROR("symbol `%s' is neither an array name nor one of `(t)sprite', `sector' or `wall'.", tlabel); C_CUSTOMERROR("symbol `%s' is neither an array name nor one of `(t)sprite', `sector', `wall' or `light'.", tlabel);
return; return;
} }
if (id==4)
{
id = 3; // smuggle lights into tspr
lightp = 1;
}
flags &= ~M32_FLAG_ARRAY; // not an array flags &= ~M32_FLAG_ARRAY; // not an array
flags |= M32_FLAG_STRUCT; flags |= M32_FLAG_STRUCT;
} }
@ -1175,7 +1203,9 @@ static void C_GetNextVarType(int32_t type)
if (*textptr != '.') if (*textptr != '.')
{ {
static const char *types[4] = {"sprite","sector","wall","tsprite"}; const char *types[4] = {"sprite","sector","wall","tsprite"};
if (lightp)
types[3] = "light";
C_CUSTOMERROR("syntax error. Expected `.<label>' after `%s[...]'", types[id&3]); C_CUSTOMERROR("syntax error. Expected `.<label>' after `%s[...]'", types[id&3]);
return; return;
} }
@ -1186,7 +1216,9 @@ static void C_GetNextVarType(int32_t type)
C_GetNextLabelName(0); C_GetNextLabelName(0);
/*initprintf("found xxx label of '%s'\n", label+(g_numLabels*MAXLABELLEN));*/ /*initprintf("found xxx label of '%s'\n", label+(g_numLabels*MAXLABELLEN));*/
if (id==M32_SPRITE_VAR_ID || id==M32_TSPRITE_VAR_ID) if (lightp)
lLabelID = C_GetLabelNameID(LightLabels, &h_light, Bstrtolower(tlabel));
else if (id==M32_SPRITE_VAR_ID || id==M32_TSPRITE_VAR_ID)
lLabelID = C_GetLabelNameID(SpriteLabels, &h_sprite, Bstrtolower(tlabel)); lLabelID = C_GetLabelNameID(SpriteLabels, &h_sprite, Bstrtolower(tlabel));
else if (id==M32_SECTOR_VAR_ID) else if (id==M32_SECTOR_VAR_ID)
lLabelID = C_GetLabelNameID(SectorLabels, &h_sector, Bstrtolower(tlabel)); lLabelID = C_GetLabelNameID(SectorLabels, &h_sector, Bstrtolower(tlabel));
@ -2413,84 +2445,6 @@ repeatcase:
return 1; return 1;
// *** more basic commands // *** more basic commands
#if 0
case CON_SETSECTOR:
case CON_GETSECTOR:
case CON_SETWALL:
case CON_GETWALL:
case CON_SETSPRITE:
case CON_GETSPRITE:
case CON_SETTSPR:
case CON_GETTSPR:
{
int32_t lLabelID;
// syntax getsector[<var>].x <VAR>
// gets the value of sector[<var>].xxx into <VAR>
if ((tw==CON_GETTSPR || tw==CON_SETTSPR) && cs.currentEvent != EVENT_ANALYZESPRITES)
{
C_ReportError(WARNING_OUTSIDEDRAWSPRITE);
g_numCompilerWarnings++;
}
// now get name of .xxx
while (*textptr != '[')
textptr++;
if (*textptr == '[')
textptr++;
// get the ID of the DEF
cs.labelsOnly = 1;
C_GetNextVar();
cs.labelsOnly = 0;
// now get name of .xxx
while (*textptr != '.')
{
if (!*textptr || *textptr == 0xa)
break;
textptr++;
}
if (*textptr!='.')
{
C_CUSTOMERROR("syntax error. Expected `.<label>' after `%s[...]'", keyw[tw]);
return 0;
}
textptr++;
/// now pointing at 'xxx'
C_GetNextLabelName(0);
//printf("found xxx label of '%s'\n", label+(g_numLabels*MAXLABELLEN));
if (tw==CON_GETSECTOR || tw==CON_SETSECTOR)
lLabelID = C_GetLabelNameID(SectorLabels, &h_sector, Bstrtolower(tlabel));
else if (tw==CON_GETWALL || tw==CON_SETWALL)
lLabelID = C_GetLabelNameID(WallLabels, &h_wall, Bstrtolower(tlabel));
else // if (tw==CON_GETSPRITE || tw==CON_SETSPRITE || tw==CON_GETTSPR || tw==CON_SETTSPR)
lLabelID = C_GetLabelNameID(SpriteLabels, &h_sprite, Bstrtolower(tlabel));
if (lLabelID == -1)
{
g_numCompilerErrors++;
C_ReportError(ERROR_SYMBOLNOTRECOGNIZED);
return 0;
}
*g_scriptPtr++ = lLabelID;
// now at target VAR...
// get the ID of the DEF
if (tw==CON_GETSECTOR || tw==CON_GETWALL || tw==CON_GETSPRITE || tw==CON_GETTSPR)
C_GetNextVarType(GV_WRITABLE);
else
C_GetNextVar();
break;
}
#endif
case CON_GAMEVAR: case CON_GAMEVAR:
// syntax: gamevar <var1> <initial value> <flags> // syntax: gamevar <var1> <initial value> <flags>

View file

@ -79,6 +79,7 @@ typedef struct
extern const memberlabel_t SectorLabels[]; extern const memberlabel_t SectorLabels[];
extern const memberlabel_t WallLabels[]; extern const memberlabel_t WallLabels[];
extern const memberlabel_t SpriteLabels[]; extern const memberlabel_t SpriteLabels[];
extern const memberlabel_t LightLabels[];
typedef struct { typedef struct {
@ -202,29 +203,48 @@ enum WallLabel_t
enum SpriteLabel_t enum SpriteLabel_t
{ {
SPRITE_X, SPRITE_X, // 0
SPRITE_Y, SPRITE_Y,
SPRITE_Z, SPRITE_Z,
SPRITE_CSTAT, SPRITE_CSTAT,
SPRITE_PICNUM, SPRITE_PICNUM,
SPRITE_SHADE, SPRITE_SHADE, // 5
SPRITE_PAL, SPRITE_PAL,
SPRITE_CLIPDIST, SPRITE_CLIPDIST,
SPRITE_DETAIL, SPRITE_DETAIL,
SPRITE_XREPEAT, SPRITE_XREPEAT,
SPRITE_YREPEAT, SPRITE_YREPEAT, // 10
SPRITE_XOFFSET, SPRITE_XOFFSET,
SPRITE_YOFFSET, SPRITE_YOFFSET,
SPRITE_SECTNUM, SPRITE_SECTNUM,
SPRITE_STATNUM, SPRITE_STATNUM,
SPRITE_ANG, SPRITE_ANG, // 15
SPRITE_OWNER, SPRITE_OWNER,
SPRITE_XVEL, SPRITE_XVEL,
SPRITE_YVEL, SPRITE_YVEL,
SPRITE_ZVEL, SPRITE_ZVEL,
SPRITE_LOTAG, SPRITE_LOTAG, // 20
SPRITE_HITAG, SPRITE_HITAG,
SPRITE_EXTRA, SPRITE_EXTRA,
LIGHT_X, // must be first here
LIGHT_Y,
LIGHT_Z, // 25
LIGHT_HORIZ,
LIGHT_RANGE,
LIGHT_ANGLE,
LIGHT_FADERADIUS,
LIGHT_RADIUS, // 30
LIGHT_SECTOR,
LIGHT_R,
LIGHT_G,
LIGHT_B,
LIGHT_PRIORITY, // 35
LIGHT_TILENUM,
LIGHT_MINSHADE,
LIGHT_MAXSHADE,
LIGHT_ACTIVE,
SPRITE_END SPRITE_END
}; };
@ -233,6 +253,7 @@ enum IterationTypes_t
ITER_ALLSPRITES, ITER_ALLSPRITES,
ITER_ALLSECTORS, ITER_ALLSECTORS,
ITER_ALLWALLS, ITER_ALLWALLS,
ITER_ACTIVELIGHTS,
ITER_SELSPRITES, ITER_SELSPRITES,
ITER_SELSECTORS, ITER_SELSECTORS,
ITER_SELWALLS, ITER_SELWALLS,

View file

@ -261,46 +261,40 @@ static int32_t X_DoSort(const int32_t *lv, const int32_t *rv)
if ((vm.g_i < 0 || vm.g_i>=MAXSPRITES) && \ if ((vm.g_i < 0 || vm.g_i>=MAXSPRITES) && \
(vm.g_st!=0 || searchstat!=3 || (vm.g_i=searchwall, vm.g_sp=&sprite[vm.g_i], 0))) \ (vm.g_st!=0 || searchstat!=3 || (vm.g_i=searchwall, vm.g_sp=&sprite[vm.g_i], 0))) \
{ \ { \
M32_PRINTERROR("Current sprite index invalid!"); \ M32_ERROR("Current sprite index invalid!"); \
vm.flags |= VMFLAG_ERROR; \
continue; \ continue; \
} }
#define X_ERROR_INVALIDSPRI(dasprite) \ #define X_ERROR_INVALIDSPRI(dasprite) \
if (dasprite < 0 || dasprite>=MAXSPRITES) \ if (dasprite < 0 || dasprite>=MAXSPRITES) \
{ \ { \
M32_PRINTERROR("Invalid sprite index %d!", dasprite); \ M32_ERROR("Invalid sprite index %d!", dasprite); \
vm.flags |= VMFLAG_ERROR; \
continue; \ continue; \
} }
#define X_ERROR_INVALIDSECT(dasect) \ #define X_ERROR_INVALIDSECT(dasect) \
if (dasect < 0 || dasect>=numsectors) \ if (dasect < 0 || dasect>=numsectors) \
{ \ { \
M32_PRINTERROR("Invalid sector index %d!", dasect); \ M32_ERROR("Invalid sector index %d!", dasect); \
vm.flags |= VMFLAG_ERROR; \
continue; \ continue; \
} }
#define X_ERROR_INVALIDSP() \ #define X_ERROR_INVALIDSP() \
if (!vm.g_sp && (vm.g_st!=0 || searchstat!=3 || (vm.g_sp=&sprite[searchwall], 0))) \ if (!vm.g_sp && (vm.g_st!=0 || searchstat!=3 || (vm.g_sp=&sprite[searchwall], 0))) \
{ \ { \
M32_PRINTERROR("Current sprite invalid!"); \ M32_ERROR("Current sprite invalid!"); \
vm.flags |= VMFLAG_ERROR; \
continue; \ continue; \
} }
#define X_ERROR_INVALIDQUOTE(q, array) \ #define X_ERROR_INVALIDQUOTE(q, array) \
if (q<0 || q>=MAXQUOTES) \ if (q<0 || q>=MAXQUOTES) \
{ \ { \
M32_PRINTERROR("Invalid quote number %d!", q); \ M32_ERROR("Invalid quote number %d!", q); \
vm.flags |= VMFLAG_ERROR; \
continue; \ continue; \
} \ } \
else if (array[q] == NULL) \ else if (array[q] == NULL) \
{ \ { \
M32_PRINTERROR("Null quote %d!", q); \ M32_ERROR("Null quote %d!", q); \
vm.flags |= VMFLAG_ERROR; \
continue; \ continue; \
} \ } \
@ -479,8 +473,7 @@ skip_check:
int32_t j = Gv_GetVarX(*insptr++); int32_t j = Gv_GetVarX(*insptr++);
if (j<0 || j>=(g_scriptPtr-script)) if (j<0 || j>=(g_scriptPtr-script))
{ {
M32_PRINTERROR("script index out of bounds (%d)", j); M32_ERROR("script index out of bounds (%d)", j);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
insptr = (instype *)(j+script); insptr = (instype *)(j+script);
@ -495,72 +488,6 @@ skip_check:
VM_Execute(0); VM_Execute(0);
continue; continue;
#if 0
// *** more basic commands
case CON_SETSECTOR:
case CON_GETSECTOR:
insptr++;
{
// syntax [gs]etsector[<var>].x <VAR>
// <varid> <xxxid> <varid>
int32_t lVar1=*insptr++, lLabelID=*insptr++, lVar2=*insptr++;
VM_AccessSector((tw==CON_SETSECTOR)|2, lVar1, lLabelID, lVar2);
continue;
}
case CON_SETWALL:
case CON_GETWALL:
insptr++;
{
// syntax [gs]etwall[<var>].x <VAR>
// <varid> <xxxid> <varid>
int32_t lVar1=*insptr++, lLabelID=*insptr++, lVar2=*insptr++;
VM_AccessWall((tw==CON_SETWALL)|2, lVar1, lLabelID, lVar2);
continue;
}
case CON_SETSPRITE:
case CON_GETSPRITE:
insptr++;
{
// syntax [gs]etsprite[<var>].x <VAR>
// <varid> <xxxid> <varid>
int32_t lVar1=*insptr++, lLabelID=*insptr++, lVar2=*insptr++;
VM_AccessSprite((tw==CON_SETSPRITE)|2, lVar1, lLabelID, lVar2);
continue;
}
case CON_SETTSPR:
case CON_GETTSPR:
insptr++;
{
// syntax [gs]ettspr[<var>].x <VAR>
// <varid> <xxxid> <varid>
int32_t lVar1=*insptr++, lLabelID=*insptr++, lVar2=*insptr++;
VM_AccessTsprite((tw==CON_SETTSPR)|2|4, lVar1, lLabelID, lVar2);
continue;
}
case CON_SETSPRITE:
insptr++;
{
// syntax [gs]etsprite[<var>].x <VAR>
// <varid> <xxxid> <varid>
int32_t lVar1=*insptr++, lLabelID=*insptr++, lVar2=*insptr++;
VM_SetSprite(lVar1, lLabelID, lVar2);
continue;
}
case CON_GETSPRITE:
insptr++;
{
// syntax [gs]etsprite[<var>].x <VAR>
// <varid> <xxxid> <varid>
int32_t lVar1=*insptr++, lLabelID=*insptr++, lVar2=*insptr++;
VM_GetSprite(lVar1, lLabelID, lVar2);
continue;
}
#endif
// *** arrays // *** arrays
case CON_SETARRAY: case CON_SETARRAY:
insptr++; insptr++;
@ -571,18 +498,15 @@ skip_check:
if (j<0 || j >= g_gameArrayCount) if (j<0 || j >= g_gameArrayCount)
{ {
M32_PRINTERROR("Tried to set invalid array ID (%d)", j); M32_ERROR("Tried to set invalid array ID (%d)", j);
vm.flags |= VMFLAG_ERROR;
} }
if (aGameArrays[j].dwFlags & GAMEARRAY_READONLY) if (aGameArrays[j].dwFlags & GAMEARRAY_READONLY)
{ {
M32_PRINTERROR("Tried to set on read-only array `%s'", aGameArrays[j].szLabel); M32_ERROR("Tried to set on read-only array `%s'", aGameArrays[j].szLabel);
vm.flags |= VMFLAG_ERROR;
} }
if (index >= aGameArrays[j].size || index < 0) if (index >= aGameArrays[j].size || index < 0)
{ {
M32_PRINTERROR("Array index %d out of bounds", index); M32_ERROR("Array index %d out of bounds", index);
vm.flags |= VMFLAG_ERROR;
} }
if (vm.flags&VMFLAG_ERROR) continue; if (vm.flags&VMFLAG_ERROR) continue;
((int32_t *)aGameArrays[j].vals)[index]=value; // REM: other array types not implemented, since they're read-only ((int32_t *)aGameArrays[j].vals)[index]=value; // REM: other array types not implemented, since they're read-only
@ -606,8 +530,7 @@ skip_check:
if (asize<=0 || asize>65536) if (asize<=0 || asize>65536)
{ {
M32_PRINTERROR("Invalid array size %d (must be between 1 and 65536)", asize); M32_ERROR("Invalid array size %d (must be between 1 and 65536)", asize);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
@ -616,8 +539,7 @@ skip_check:
if (aGameArrays[j].vals == NULL) if (aGameArrays[j].vals == NULL)
{ {
aGameArrays[j].size = 0; aGameArrays[j].size = 0;
M32_PRINTERROR("Out of memory!"); M32_ERROR("Out of memory!");
vm.flags |= VMFLAG_ERROR;
return 1; return 1;
} }
aGameArrays[j].size = asize; aGameArrays[j].size = asize;
@ -636,18 +558,15 @@ skip_check:
if (si<0 || si>=g_gameArrayCount) if (si<0 || si>=g_gameArrayCount)
{ {
M32_PRINTERROR("Invalid array %d!", si); M32_ERROR("Invalid array %d!", si);
vm.flags |= VMFLAG_ERROR;
} }
if (di<0 || di>=g_gameArrayCount) if (di<0 || di>=g_gameArrayCount)
{ {
M32_PRINTERROR("Invalid array %d!", di); M32_ERROR("Invalid array %d!", di);
vm.flags |= VMFLAG_ERROR;
} }
if (aGameArrays[di].dwFlags & GAMEARRAY_READONLY) if (aGameArrays[di].dwFlags & GAMEARRAY_READONLY)
{ {
M32_PRINTERROR("Array %d is read-only!", di); M32_ERROR("Array %d is read-only!", di);
vm.flags |= VMFLAG_ERROR;
} }
if (vm.flags&VMFLAG_ERROR) continue; if (vm.flags&VMFLAG_ERROR) continue;
@ -715,7 +634,7 @@ skip_check:
insptr++; insptr++;
if (*(insptr+1) == 0) if (*(insptr+1) == 0)
{ {
M32_PRINTERROR("Divide by zero."); M32_ERROR("Divide by zero.");
insptr += 2; insptr += 2;
continue; continue;
} }
@ -727,7 +646,7 @@ skip_check:
insptr++; insptr++;
if (*(insptr+1) == 0) if (*(insptr+1) == 0)
{ {
M32_PRINTERROR("Mod by zero."); M32_ERROR("Mod by zero.");
insptr += 2; insptr += 2;
continue; continue;
} }
@ -785,7 +704,7 @@ skip_check:
if (l2==0) if (l2==0)
{ {
M32_PRINTERROR("Divide by zero."); M32_ERROR("Divide by zero.");
continue; continue;
} }
Gv_SetVarX(j, Gv_GetVarX(j)/l2); Gv_SetVarX(j, Gv_GetVarX(j)/l2);
@ -800,7 +719,7 @@ skip_check:
if (l2==0) if (l2==0)
{ {
M32_PRINTERROR("Mod by zero."); M32_ERROR("Mod by zero.");
continue; continue;
} }
@ -962,13 +881,11 @@ skip_check:
if (xvar < 0 || xvar >= MAXSPRITES || sprite[xvar].statnum==MAXSTATUS) if (xvar < 0 || xvar >= MAXSPRITES || sprite[xvar].statnum==MAXSTATUS)
{ {
M32_PRINTERROR("invalid sprite %d", xvar); M32_ERROR("invalid sprite %d", xvar);
vm.flags |= VMFLAG_ERROR;
} }
if (yvar < 0 || yvar >= MAXSPRITES || sprite[yvar].statnum==MAXSTATUS) if (yvar < 0 || yvar >= MAXSPRITES || sprite[yvar].statnum==MAXSTATUS)
{ {
M32_PRINTERROR("invalid sprite %d", yvar); M32_ERROR("invalid sprite %d", yvar);
vm.flags |= VMFLAG_ERROR;
} }
if (vm.flags&VMFLAG_ERROR) continue; if (vm.flags&VMFLAG_ERROR) continue;
@ -1255,8 +1172,7 @@ skip_check:
if (count<=0) continue; if (count<=0) continue;
if (count > aGameArrays[aridx].size) if (count > aGameArrays[aridx].size)
{ {
M32_PRINTERROR("Count of elements to sort (%d) exceeds array size (%d)!", count,aGameArrays[aridx].size); M32_ERROR("Count of elements to sort (%d) exceeds array size (%d)!", count,aGameArrays[aridx].size);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
@ -1317,6 +1233,22 @@ skip_check:
VM_Execute(1); VM_Execute(1);
} }
break; break;
case ITER_ACTIVELIGHTS:
#ifdef POLYMER
for (jj=0; jj<PR_MAXLIGHTS; jj++)
{
if (!prlights[jj].flags.active)
continue;
Gv_SetVarX(var, jj);
insptr = beg;
VM_Execute(1);
}
#else
M32_ERROR("Polymer not compiled in, iteration over lights forbidden.");
#endif
break;
case ITER_SELSPRITES: case ITER_SELSPRITES:
for (ii=0; ii<highlightcnt && !vm.flags; ii++) for (ii=0; ii<highlightcnt && !vm.flags; ii++)
{ {
@ -1406,8 +1338,7 @@ skip_check:
} }
break; break;
default: default:
M32_PRINTERROR("Unknown iteration type %d!", how); M32_ERROR("Unknown iteration type %d!", how);
vm.flags |= VMFLAG_ERROR;
continue; continue;
badindex: badindex:
OSD_Printf(OSD_ERROR "Line %d, %s %s: index %d out of range!\n",g_errorLineNum,keyw[g_tw], OSD_Printf(OSD_ERROR "Line %d, %s %s: index %d out of range!\n",g_errorLineNum,keyw[g_tw],
@ -1506,8 +1437,7 @@ badindex:
int32_t key=Gv_GetVarX(*insptr); int32_t key=Gv_GetVarX(*insptr);
if (key<0 || key >= (int32_t)(sizeof(keystatus)/sizeof(keystatus[0]))) if (key<0 || key >= (int32_t)(sizeof(keystatus)/sizeof(keystatus[0])))
{ {
M32_PRINTERROR("Invalid key %d!", key); M32_ERROR("Invalid key %d!", key);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
@ -1552,8 +1482,7 @@ badindex:
if (index<0 || (id==M32_SPRITE_VAR_ID && index>=MAXSPRITES) || (id==M32_WALL_VAR_ID && index>=numwalls)) if (index<0 || (id==M32_SPRITE_VAR_ID && index>=MAXSPRITES) || (id==M32_WALL_VAR_ID && index>=numwalls))
{ {
M32_PRINTERROR("%s index %d out of range!", id==M32_SPRITE_VAR_ID?"Sprite":"Wall", index); M32_ERROR("%s index %d out of range!", id==M32_SPRITE_VAR_ID?"Sprite":"Wall", index);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
@ -1635,8 +1564,7 @@ badindex:
res = inside(x, y, sectnum); res = inside(x, y, sectnum);
if (res == -1) if (res == -1)
{ {
M32_PRINTERROR("Sector index %d out of range!", sectnum); M32_ERROR("Sector index %d out of range!", sectnum);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
insptr--; insptr--;
@ -1675,8 +1603,7 @@ badindex:
X_ERROR_INVALIDSECT(dasectnum); X_ERROR_INVALIDSECT(dasectnum);
if (numsprites >= MAXSPRITES) if (numsprites >= MAXSPRITES)
{ {
M32_PRINTERROR("Maximum number of sprites reached."); M32_ERROR("Maximum number of sprites reached.");
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
@ -1695,14 +1622,12 @@ badindex:
if (ospritenum<0 || ospritenum>=MAXSPRITES || sprite[ospritenum].statnum==MAXSTATUS) if (ospritenum<0 || ospritenum>=MAXSPRITES || sprite[ospritenum].statnum==MAXSTATUS)
{ {
M32_PRINTERROR("Tried to duplicate nonexistent sprite %d", ospritenum); M32_ERROR("Tried to duplicate nonexistent sprite %d", ospritenum);
vm.flags |= VMFLAG_ERROR;
} }
if ((tw==CON_DUPSPRITE && numsprites >= MAXSPRITES) || if ((tw==CON_DUPSPRITE && numsprites >= MAXSPRITES) ||
(tw==CON_DUPSPRITE && spritesortcnt >= MAXSPRITESONSCREEN)) (tw==CON_DUPSPRITE && spritesortcnt >= MAXSPRITESONSCREEN))
{ {
M32_PRINTERROR("Maximum number of sprites reached."); M32_ERROR("Maximum number of sprites reached.");
vm.flags |= VMFLAG_ERROR;
} }
if (vm.flags&VMFLAG_ERROR) continue; if (vm.flags&VMFLAG_ERROR) continue;
@ -1712,8 +1637,7 @@ badindex:
if (nspritenum < 0) if (nspritenum < 0)
{ {
M32_PRINTERROR("Internal error."); M32_ERROR("Internal error.");
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
@ -1753,8 +1677,7 @@ badindex:
if (dapoint<0 || dapoint>=numwalls) if (dapoint<0 || dapoint>=numwalls)
{ {
M32_PRINTERROR("Invalid wall %d", dapoint); M32_ERROR("Invalid wall %d", dapoint);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
@ -2026,8 +1949,7 @@ badindex:
int32_t j=Gv_GetVarX(*insptr++); int32_t j=Gv_GetVarX(*insptr++);
if (j < 0 || j > MAXSTATUS) if (j < 0 || j > MAXSTATUS)
{ {
M32_PRINTERROR("invalid status list %d", j); M32_ERROR("invalid status list %d", j);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
Gv_SetVarX(i,headspritestat[j]); Gv_SetVarX(i,headspritestat[j]);
@ -2096,13 +2018,11 @@ badindex:
if (lVar1<0 || lVar1>=MAXSPRITES || sprite[lVar1].statnum==MAXSTATUS) if (lVar1<0 || lVar1>=MAXSPRITES || sprite[lVar1].statnum==MAXSTATUS)
{ {
M32_PRINTERROR("Invalid sprite %d", lVar1); M32_ERROR("Invalid sprite %d", lVar1);
vm.flags |= VMFLAG_ERROR;
} }
if (lVar2<0 || lVar2>=MAXSPRITES || sprite[lVar2].statnum==MAXSTATUS) if (lVar2<0 || lVar2>=MAXSPRITES || sprite[lVar2].statnum==MAXSTATUS)
{ {
M32_PRINTERROR("Invalid sprite %d", lVar2); M32_ERROR("Invalid sprite %d", lVar2);
vm.flags |= VMFLAG_ERROR;
} }
if (vm.flags&VMFLAG_ERROR) res=0; if (vm.flags&VMFLAG_ERROR) res=0;
@ -2123,8 +2043,7 @@ badindex:
X_ERROR_INVALIDSPRI(i); X_ERROR_INVALIDSPRI(i);
if (j<0 || j >= (tw==CON_CHANGESPRITESTAT?MAXSTATUS:numsectors)) if (j<0 || j >= (tw==CON_CHANGESPRITESTAT?MAXSTATUS:numsectors))
{ {
M32_PRINTERROR("Invalid %s: %d", tw==CON_CHANGESPRITESTAT?"statnum":"sector", j); M32_ERROR("Invalid %s: %d", tw==CON_CHANGESPRITESTAT?"statnum":"sector", j);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
@ -2148,8 +2067,7 @@ badindex:
if (wallnum<0 || wallnum>=numwalls) if (wallnum<0 || wallnum>=numwalls)
{ {
M32_PRINTERROR("Invalid wall %d", wallnum); M32_ERROR("Invalid wall %d", wallnum);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
dragpoint(wallnum,newx,newy); dragpoint(wallnum,newx,newy);
@ -2196,8 +2114,7 @@ badindex:
index &= ~16384; index &= ~16384;
if (index < 0 || index>=MAXSPRITES || sprite[index].statnum==MAXSTATUS) if (index < 0 || index>=MAXSPRITES || sprite[index].statnum==MAXSTATUS)
{ {
M32_PRINTERROR("Invalid sprite index %d", index); M32_ERROR("Invalid sprite index %d", index);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }
@ -2208,8 +2125,7 @@ badindex:
} }
else if (index < 0 || index>=numwalls) else if (index < 0 || index>=numwalls)
{ {
M32_PRINTERROR("Invalid wall index %d", index); M32_ERROR("Invalid wall index %d", index);
vm.flags |= VMFLAG_ERROR;
continue; continue;
if (doset) if (doset)
@ -2262,9 +2178,6 @@ badindex:
if (code & (0xFFFFFFFF-(MAXGAMEVARS-1))) if (code & (0xFFFFFFFF-(MAXGAMEVARS-1)))
{ {
char pp1[4][8] = {"sprite","sector","wall","tsprite"};
const memberlabel_t *pp2[4] = {SpriteLabels, SectorLabels, WallLabels, SpriteLabels};
if ((code&M32_VARTYPE_MASK)==M32_FLAG_ARRAY || (code&M32_VARTYPE_MASK)==M32_FLAG_STRUCT) if ((code&M32_VARTYPE_MASK)==M32_FLAG_ARRAY || (code&M32_VARTYPE_MASK)==M32_FLAG_STRUCT)
{ {
if (code&M32_FLAG_CONSTANT) if (code&M32_FLAG_CONSTANT)
@ -2297,8 +2210,20 @@ badindex:
aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel:"???", buf2); aGameArrays[code&(MAXGAMEARRAYS-1)].szLabel:"???", buf2);
break; break;
case M32_FLAG_STRUCT: case M32_FLAG_STRUCT:
Bsprintf(buf, "%s[%s].%s", pp1[code&3], buf2, pp2[code&3][(code>>2)&31].name); {
break; int32_t memberid=(code>>2)&63, lightp = (memberid >= LIGHT_X);
const char *pp1[4] = {"sprite","sector","wall","tsprite"};
const memberlabel_t *pp2[4] = {SpriteLabels, SectorLabels, WallLabels, SpriteLabels};
if (lightp)
{
pp1[3] = "light";
pp2[3] = LightLabels;
memberid -= LIGHT_X;
}
Bsprintf(buf, "%s[%s].%s", pp1[code&3], buf2, pp2[code&3][memberid].name);
}
break;
case M32_FLAG_VAR: case M32_FLAG_VAR:
Bsprintf(buf, "???"); Bsprintf(buf, "???");
break; break;
@ -2512,7 +2437,7 @@ badindex:
case CON_QGETSYSSTR: case CON_QGETSYSSTR:
if (ScriptQuotes[i] == NULL) if (ScriptQuotes[i] == NULL)
{ {
M32_PRINTERROR("null quote %d %d", i,j); M32_ERROR("null quote %d %d", i,j);
break; break;
} }
switch (j) switch (j)
@ -2524,7 +2449,7 @@ badindex:
Bstrcpy(ScriptQuotes[i], "Mapster32"VERSION BUILDDATE); Bstrcpy(ScriptQuotes[i], "Mapster32"VERSION BUILDDATE);
break; break;
default: default:
M32_PRINTERROR("unknown str ID %d %d", i,j); M32_ERROR("unknown str ID %d %d", i,j);
} }
break; break;
#endif #endif
@ -2944,8 +2869,7 @@ dodefault:
int32_t j=Gv_GetVarX(*insptr); int32_t j=Gv_GetVarX(*insptr);
if (j<0 || j>=MAXSOUNDS) if (j<0 || j>=MAXSOUNDS)
{ {
M32_PRINTERROR("Invalid sound %d", j); M32_ERROR("Invalid sound %d", j);
vm.flags |= VMFLAG_ERROR;
insptr++; insptr++;
continue; continue;
} }
@ -2985,8 +2909,7 @@ dodefault:
int32_t j=Gv_GetVarX(*insptr++), var=*insptr++; int32_t j=Gv_GetVarX(*insptr++), var=*insptr++;
if (j<0 || j>=MAXSOUNDS) if (j<0 || j>=MAXSOUNDS)
{ {
M32_PRINTERROR("Invalid sound %d", j); M32_ERROR("Invalid sound %d", j);
vm.flags |= VMFLAG_ERROR;
insptr++; insptr++;
continue; continue;
} }
@ -3005,8 +2928,7 @@ dodefault:
if (j<0 || j>=MAXSOUNDS) if (j<0 || j>=MAXSOUNDS)
{ {
M32_PRINTERROR("Invalid sound %d", j); M32_ERROR("Invalid sound %d", j);
vm.flags |= VMFLAG_ERROR;
continue; continue;
} }

View file

@ -26,7 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "compat.h" #include "compat.h"
#include "m32script.h" #include "m32script.h"
#include "m32def.h" #include "m32def.h"
#ifdef POLYMER
# include "prlights.h"
#endif
// how: bitfield: 1=set? 2=vars? 4=use spriteext[].tspr? (otherwise use tsprite[]) // how: bitfield: 1=set? 2=vars? 4=use spriteext[].tspr? (otherwise use tsprite[])
#define ACCESS_SET 1 #define ACCESS_SET 1
@ -121,10 +123,10 @@ static int32_t __fastcall VM_AccessWall(int32_t how, int32_t lVar1, int32_t lLab
} }
badwall: badwall:
M32_PRINTERROR("Invalid wall %d", i); M32_ERROR("Invalid wall %d", i);
return -1; return -1;
readonly: readonly:
M32_PRINTERROR("Wall structure member `%s' is read-only.", WallLabels[lLabelID].name); M32_ERROR("Wall structure member `%s' is read-only.", WallLabels[lLabelID].name);
return -1; return -1;
} }
@ -238,10 +240,10 @@ static int32_t __fastcall VM_AccessSector(int32_t how, int32_t lVar1, int32_t lL
} }
badsector: badsector:
M32_PRINTERROR("Invalid sector %d", i); M32_ERROR("Invalid sector %d", i);
return -1; return -1;
readonly: readonly:
M32_PRINTERROR("Sector structure member `%s' is read-only.", SectorLabels[lLabelID].name); M32_ERROR("Sector structure member `%s' is read-only.", SectorLabels[lLabelID].name);
return -1; return -1;
} }
@ -254,7 +256,7 @@ static int32_t __fastcall VM_AccessSprite(int32_t how, int32_t lVar1, int32_t lL
if ((how&ACCESS_USEVARS) && lVar1 != M32_THISACTOR_VAR_ID) if ((how&ACCESS_USEVARS) && lVar1 != M32_THISACTOR_VAR_ID)
i = Gv_GetVarX(lVar1); i = Gv_GetVarX(lVar1);
if (i < 0 || i >= MAXSPRITES) if ((unsigned)i >= MAXSPRITES)
goto badsprite; goto badsprite;
if (how&ACCESS_SET) if (how&ACCESS_SET)
@ -346,42 +348,93 @@ static int32_t __fastcall VM_AccessSprite(int32_t how, int32_t lVar1, int32_t lL
return lValue; return lValue;
} }
badsprite: badsprite:
M32_PRINTERROR("tried to set %s on invalid target sprite (%d)", SpriteLabels[lLabelID].name, i); M32_ERROR("tried to set %s on invalid target sprite (%d)", SpriteLabels[lLabelID].name, i);
return -1; return -1;
readonly: readonly:
M32_PRINTERROR("sprite structure member `%s' is read-only.", SpriteLabels[lLabelID].name); M32_ERROR("sprite structure member `%s' is read-only.", SpriteLabels[lLabelID].name);
return -1; return -1;
} }
// how: bitfield: 1=set? 2=vars? 4=use spriteext[].tspr? (otherwise use tsprite[]) // how: bitfield: 1=set? 2=vars? 4=use spriteext[].tspr? (otherwise use tsprite[])
static int32_t __fastcall VM_AccessTsprite(int32_t how, int32_t lVar1, int32_t lLabelID, int32_t lVar2) static int32_t __fastcall VM_AccessTsprite(int32_t how, int32_t lVar1, int32_t lLabelID, int32_t lVar2)
{ {
int32_t lValue; int32_t lValue, lightp = (lLabelID >= LIGHT_X);
int32_t i = (how&ACCESS_USEVARS) ? vm.g_i : lVar1; int32_t i = (how&ACCESS_USEVARS) ? vm.g_i : lVar1;
spritetype *datspr; spritetype *datspr = NULL;
const memberlabel_t *dalabel = lightp ? &LightLabels[lLabelID-LIGHT_X] : SpriteLabels;
if ((how&ACCESS_USEVARS) && lVar1 != M32_THISACTOR_VAR_ID) if ((how&ACCESS_USEVARS) && lVar1 != M32_THISACTOR_VAR_ID)
i = Gv_GetVarX(lVar1); i = Gv_GetVarX(lVar1);
if (how&ACCESS_SPRITEEXT) if (!lightp)
{ {
if (i < 0 || i >= MAXSPRITES) if (how&ACCESS_SPRITEEXT)
goto badsprite; {
datspr = spriteext[i].tspr; if ((unsigned)i >= MAXSPRITES)
if (!datspr) goto badsprite;
goto badtspr; datspr = spriteext[i].tspr;
if (!datspr)
goto badtspr;
}
else
{
if (i<0 || i>=spritesortcnt)
goto badsprite;
datspr = &tsprite[i];
}
} }
else else
{ {
if (i<0 || i>=spritesortcnt) // access Polymer light
goto badsprite; #ifndef POLYMER
datspr = &tsprite[i]; M32_ERROR("Polymer not compiled in, accessing lights is invalid.");
return -1;
#else
if ((how&ACCESS_USEVARS) && lVar1 == M32_THISACTOR_VAR_ID)
{
if ((unsigned)i >= MAXSPRITES)
goto badsprite;
M32_ERROR("Polymer light access via current sprite not implemented.");
return -1;
}
else
{
// check whether rendmode==4 ?
if ((unsigned)i >= PR_MAXLIGHTS)
{
M32_ERROR("invalid light index (%d)", i);
return -1;
}
if (lLabelID != LIGHT_ACTIVE && !prlights[i].flags.active)
{
M32_ERROR("light with index %d is inactive!", i);
return -1;
}
}
#endif
} }
if (how&ACCESS_SET) if (how&ACCESS_SET)
{ {
int32_t damin, damax;
if (!m32_script_expertmode && (dalabel->flags & 1))
goto readonly;
lValue = (how&ACCESS_USEVARS) ? Gv_GetVarX(lVar2) : lVar2; lValue = (how&ACCESS_USEVARS) ? Gv_GetVarX(lVar2) : lVar2;
damin = dalabel->min;
damax = dalabel->max;
if (!m32_script_expertmode && (damin|damax))
{
if (lValue < damin)
lValue = damin;
if (lValue > damax)
lValue = damax;
}
switch (lLabelID) switch (lLabelID)
{ {
case SPRITE_X: datspr->x=lValue; break; case SPRITE_X: datspr->x=lValue; break;
@ -411,6 +464,25 @@ static int32_t __fastcall VM_AccessTsprite(int32_t how, int32_t lVar1, int32_t l
case SPRITE_LOTAG: datspr->lotag=lValue; break; case SPRITE_LOTAG: datspr->lotag=lValue; break;
case SPRITE_HITAG: datspr->hitag=lValue; break; case SPRITE_HITAG: datspr->hitag=lValue; break;
case SPRITE_EXTRA: datspr->extra=lValue; break; case SPRITE_EXTRA: datspr->extra=lValue; break;
#ifdef POLYMER
// lights
case LIGHT_X: prlights[i].x = lValue; break;
case LIGHT_Y: prlights[i].y = lValue; break;
case LIGHT_Z: prlights[i].z = lValue; break;
case LIGHT_HORIZ: prlights[i].horiz = lValue; break;
case LIGHT_RANGE: prlights[i].range = lValue; break;
case LIGHT_ANGLE: prlights[i].angle = lValue; break;
case LIGHT_FADERADIUS: prlights[i].faderadius = lValue; break;
case LIGHT_RADIUS: prlights[i].radius = lValue; break;
case LIGHT_SECTOR: prlights[i].sector = lValue; break;
case LIGHT_R: prlights[i].color[0] = lValue; break;
case LIGHT_G: prlights[i].color[1] = lValue; break;
case LIGHT_B: prlights[i].color[2] = lValue; break;
case LIGHT_PRIORITY: prlights[i].priority = lValue; break;
case LIGHT_TILENUM: prlights[i].tilenum = lValue; break;
case LIGHT_MINSHADE: prlights[i].minshade = lValue; break;
case LIGHT_MAXSHADE: prlights[i].maxshade = lValue; break;
#endif
default: default:
return -1; return -1;
} }
@ -444,6 +516,26 @@ static int32_t __fastcall VM_AccessTsprite(int32_t how, int32_t lVar1, int32_t l
case SPRITE_LOTAG: lValue=datspr->lotag; break; case SPRITE_LOTAG: lValue=datspr->lotag; break;
case SPRITE_HITAG: lValue=datspr->hitag; break; case SPRITE_HITAG: lValue=datspr->hitag; break;
case SPRITE_EXTRA: lValue=datspr->extra; break; case SPRITE_EXTRA: lValue=datspr->extra; break;
#ifdef POLYMER
// lights
case LIGHT_X: lValue = prlights[i].x; break;
case LIGHT_Y: lValue = prlights[i].y; break;
case LIGHT_Z: lValue = prlights[i].z; break;
case LIGHT_HORIZ: lValue = prlights[i].horiz; break;
case LIGHT_RANGE: lValue = prlights[i].range; break;
case LIGHT_ANGLE: lValue = prlights[i].angle; break;
case LIGHT_FADERADIUS: lValue = prlights[i].faderadius; break;
case LIGHT_RADIUS: lValue = prlights[i].radius; break;
case LIGHT_SECTOR: lValue = prlights[i].sector; break;
case LIGHT_R: lValue = prlights[i].color[0]; break;
case LIGHT_G: lValue = prlights[i].color[1]; break;
case LIGHT_B: lValue = prlights[i].color[2]; break;
case LIGHT_PRIORITY: lValue = prlights[i].priority; break;
case LIGHT_TILENUM: lValue = prlights[i].tilenum; break;
case LIGHT_MINSHADE: lValue = prlights[i].minshade; break;
case LIGHT_MAXSHADE: lValue = prlights[i].maxshade; break;
case LIGHT_ACTIVE: lValue = !!prlights[i].flags.active; break;
#endif
default: default:
return -1; return -1;
} }
@ -455,10 +547,13 @@ static int32_t __fastcall VM_AccessTsprite(int32_t how, int32_t lVar1, int32_t l
} }
badsprite: badsprite:
M32_PRINTERROR("invalid target sprite (%d)", i); M32_ERROR("invalid target sprite (%d)", i);
return -1; return -1;
badtspr: badtspr:
M32_PRINTERROR("Internal bug, tsprite is unavailable"); M32_ERROR("Internal bug, tsprite is unavailable");
return -1;
readonly:
M32_ERROR("structure member `%s' is read-only.", dalabel->name);
return -1; return -1;
} }

View file

@ -241,8 +241,7 @@ int32_t __fastcall Gv_GetVarN(register int32_t id) // 'N' for "no side-effects"
case GAMEVAR_CHARPTR: case GAMEVAR_CHARPTR:
return *((uint8_t *)aGameVars[id].val.lValue); return *((uint8_t *)aGameVars[id].val.lValue);
default: default:
M32_PRINTERROR("Gv_GetVarN(): WTF??"); M32_ERROR("Gv_GetVarN(): WTF??");
vm.flags |= VMFLAG_ERROR;
return -1; return -1;
} }
@ -254,8 +253,7 @@ int32_t __fastcall Gv_GetVarN(register int32_t id) // 'N' for "no side-effects"
} }
default: default:
M32_PRINTERROR("Gv_GetVarN(): invalid var code %0x08x", id); M32_ERROR("Gv_GetVarN(): invalid var code %0x08x", id);
vm.flags |= VMFLAG_ERROR;
return -1; return -1;
} }
} }
@ -278,8 +276,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
case 2: case 2:
return (labelval[(id>>16)&0xffff] ^ -negateResult) + negateResult; return (labelval[(id>>16)&0xffff] ^ -negateResult) + negateResult;
default: default:
M32_PRINTERROR("Gv_GetVarX() (constant): WTF??"); M32_ERROR("Gv_GetVarX() (constant): WTF??");
vm.flags |= VMFLAG_ERROR;
return -1; return -1;
} }
} }
@ -305,7 +302,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
if (index < 0 || index >= siz) if (index < 0 || index >= siz)
{ {
M32_PRINTERROR("Gv_GetVarX(): invalid array index (%s[%d])", aGameArrays[id].szLabel, index); M32_ERROR("Gv_GetVarX(): invalid array index (%s[%d])", aGameArrays[id].szLabel, index);
return -1; return -1;
} }
@ -319,8 +316,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
case GAMEARRAY_OFCHAR: case GAMEARRAY_OFCHAR:
return (((uint8_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult; return (((uint8_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult;
default: default:
M32_PRINTERROR("Gv_GetVarX() (array): WTF??"); M32_ERROR("Gv_GetVarX() (array): WTF??");
vm.flags |= VMFLAG_ERROR;
return -1; return -1;
} }
} }
@ -332,7 +328,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
if (!(id&M32_FLAG_CONSTANTINDEX)) if (!(id&M32_FLAG_CONSTANTINDEX))
index = Gv_GetVarN(index); index = Gv_GetVarN(index);
memberid = (id>>2)&31; memberid = (id>>2)&63;
switch (id&3) switch (id&3)
{ {
@ -370,8 +366,7 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
case GAMEVAR_CHARPTR: case GAMEVAR_CHARPTR:
return (*((uint8_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult; return (*((uint8_t *)aGameVars[id].val.lValue) ^ -negateResult) + negateResult;
default: default:
M32_PRINTERROR("Gv_GetVarX(): WTF??"); M32_ERROR("Gv_GetVarX(): WTF??");
vm.flags |= VMFLAG_ERROR;
return -1; return -1;
} }
} }
@ -408,8 +403,7 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
if (index < 0 || index >= siz) if (index < 0 || index >= siz)
{ {
M32_PRINTERROR("Gv_SetVarX(): invalid array index %s[%d], size=%d", aGameArrays[id].szLabel, index, siz); M32_ERROR("Gv_SetVarX(): invalid array index %s[%d], size=%d", aGameArrays[id].szLabel, index, siz);
vm.flags |= VMFLAG_ERROR;
return; return;
} }
@ -426,8 +420,7 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
((uint8_t *)aGameArrays[id].vals)[index] = (uint8_t)lValue; ((uint8_t *)aGameArrays[id].vals)[index] = (uint8_t)lValue;
return; return;
default: default:
M32_PRINTERROR("Gv_SetVarX() (array): WTF??"); M32_ERROR("Gv_SetVarX() (array): WTF??");
vm.flags |= VMFLAG_ERROR;
return; return;
} }
return; return;
@ -440,7 +433,7 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
if (!(id&M32_FLAG_CONSTANTINDEX)) if (!(id&M32_FLAG_CONSTANTINDEX))
index = Gv_GetVarN(index); index = Gv_GetVarN(index);
memberid = (id>>2)&31; memberid = (id>>2)&63;
switch (id&3) switch (id&3)
{ {
@ -476,8 +469,7 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
float fval = *(float *)&ival; float fval = *(float *)&ival;
if (fval!=fval || fval<-3.4e38 || fval > 3.4e38) if (fval!=fval || fval<-3.4e38 || fval > 3.4e38)
{ {
M32_PRINTERROR("Gv_SetVarX(): tried to set float var to NaN or infinity"); M32_ERROR("Gv_SetVarX(): tried to set float var to NaN or infinity");
vm.flags |= VMFLAG_ERROR;
return; return;
} }
} }
@ -491,8 +483,7 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
*((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue; *((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue;
return; return;
default: default:
M32_PRINTERROR("Gv_SetVarX(): WTF??"); M32_ERROR("Gv_SetVarX(): WTF??");
vm.flags |= VMFLAG_ERROR;
return; return;
} }
} }
@ -534,8 +525,11 @@ static void Gv_AddSystemVars(void)
Gv_NewVar("sector", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL); Gv_NewVar("sector", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
Gv_NewVar("wall", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL); Gv_NewVar("wall", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
Gv_NewVar("tsprite", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL); Gv_NewVar("tsprite", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
Gv_NewVar("light", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
// these too have to be in here and in order! // these too have to be in here and in order!
// keep in sync with m32script.h: IDs of special vars
Gv_NewVar("I", 0, GAMEVAR_READONLY | GAMEVAR_SYSTEM); // THISACTOR Gv_NewVar("I", 0, GAMEVAR_READONLY | GAMEVAR_SYSTEM); // THISACTOR
Gv_NewVar("RETURN", (intptr_t)&g_iReturnVar, GAMEVAR_INTPTR | GAMEVAR_SYSTEM); Gv_NewVar("RETURN", (intptr_t)&g_iReturnVar, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
Gv_NewVar("LOTAG", 0, GAMEVAR_SYSTEM); Gv_NewVar("LOTAG", 0, GAMEVAR_SYSTEM);