* New m32script commands:

- sethighlightsector <sectnum> <on?>
 - updatehighlightsector
 - collectsectors <<array_to_collect_sectnums>> <initial_sector> <<num_collected_sectors>> <sector_filtering_state>

The latter does a breadth-first search starting from an initial sector and collects nextsectors only when the filtering state, given a sectnum as RETURN input, writes a nonzero value into RETURN. As a usage example, a.m32 includes the state 'collect_teleporting_sectors', that collects all sectors containing an SE7 and highlights them afterwards. This way, it should be possible to retrofit old maps with TROR by distributing small scripts that do most of the work (right now, joining has to be done by hand, though).


* corruption checker: for the 'nextwall inconsistent with nextsector' corruption, suggest an alternative fix by searching fitting nextwalls and changing the nextwall of the corrupt wall (as opposed to the nextsector). It will display with a leading '?' in the listing, and can be demanded by suffixing 'corruptcheck tryfix' with it. For example,

corruptcheck tryfix 9-21 ?

would fix some corruptions in Billy Boy's cranium.map without introducing drawing errors.


* fix demo playback (tueidj figured this out)


git-svn-id: https://svn.eduke32.com/eduke32@1927 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-07-03 22:51:28 +00:00
parent 43ecbb1019
commit ee4d060b1f
8 changed files with 265 additions and 53 deletions

View file

@ -231,6 +231,7 @@ void getpoint(int32_t searchxe, int32_t searchye, int32_t *x, int32_t *y);
int32_t getpointhighlight(int32_t xplc, int32_t yplc, int32_t point);
void update_highlight(void);
void update_highlightsector(void);
void ovh_whiteoutgrab(int32_t restoreredwalls);
int32_t inside_editor_curpos(int16_t sectnum);
int32_t inside_editor(const vec3_t *pos, int32_t searchx, int32_t searchy, int32_t zoom,

View file

@ -1559,7 +1559,7 @@ static int32_t restore_highlighted_map(mapinfofull_t *mapinfo)
static int32_t newnumwalls=-1;
static void ovh_whiteoutgrab(void)
void ovh_whiteoutgrab(int32_t restoreredwalls)
{
int32_t i, j, k, startwall, endwall;
#if 0
@ -1567,6 +1567,14 @@ static void ovh_whiteoutgrab(void)
int16_t cb, fb;
#endif
if (restoreredwalls)
{
// restore onextwalls first
for (i=0; i<numsectors; i++)
for (WALLS_OF_SECTOR(i, j))
checksectorpointer(j, i);
}
for (i=0; i<MAXWALLS; i++)
onextwall[i] = -1;
@ -2533,7 +2541,7 @@ void overheadeditor(void)
lastpm16time = -1;
update_highlightsector();
ovh_whiteoutgrab();
ovh_whiteoutgrab(0);
highlightcnt = -1;
Bmemset(show2dwall, 0, sizeof(show2dwall)); //Clear all highlights
@ -4021,7 +4029,7 @@ end_yax: ;
}
update_highlightsector();
ovh_whiteoutgrab();
ovh_whiteoutgrab(0);
}
}
}
@ -4559,7 +4567,7 @@ end_point_dragging:
// tempxyar: int32_t [MAXWALLS][2]
int32_t numouterwalls[2] = {0,0}, numowals;
static int16_t outerwall[2][MAXWALLS];
const walltype *wal0, *wal1;
const walltype *wal0, *wal1, *wal0p2, *wal1p2;
// join sector ceilings/floors to a new bunch
if (numyaxbunches==YAX_MAXBUNCHES)
@ -4635,7 +4643,8 @@ end_point_dragging:
if (numouterwalls[0] != numouterwalls[1])
{
message("Number of outer walls must be equal for both components");
message("Number of outer walls must be equal for both components"
" (have %d and %d)", numouterwalls[0], numouterwalls[1]);
if (numouterwalls[0]>0 && numouterwalls[1]>0)
delayerr = 1;
else
@ -4652,6 +4661,9 @@ end_point_dragging:
wal0 = &wall[outerwall[0][k]];
wal1 = &wall[outerwall[1][k]];
wal0p2 = &wall[wal0->point2];
wal1p2 = &wall[wal1->point2];
if (k==0)
{
dx = wal1->x - wal0->x;
@ -4659,18 +4671,18 @@ end_point_dragging:
}
if (wal1->x - wal0->x != dx || wal1->y - wal0->y != dy ||
wall[wal1->point2].x - wall[wal0->point2].x != dx ||
wall[wal1->point2].y - wall[wal0->point2].y != dy)
wal1p2->x - wal0p2->x != dx || wal1p2->y - wal0p2->y != dy)
{
pos.x = wal0->x;
pos.y = wal0->y;
pos.x = wal0->x + (wal0p2->x - wal0->x)/4;
pos.y = wal0->y + (wal0p2->y - wal0->y)/4;
pos.z = getflorzofslope(sectorofwall(wal0-wall), pos.x, pos.y);
message("Outer wall coordinates must coincide for both components");
OSD_Printf("wal0:%d (%d,%d)--(%d,%d)\n",(int)(wal0-wall), wal0->x,wal0->y,
wall[wal0->point2].x,wall[wal0->point2].y);
OSD_Printf("wal1:%d (%d,%d)--(%d,%d)\n",(int)(wal1-wall), wal1->x,wal1->y,
wall[wal1->point2].x,wall[wal1->point2].y);
if (!delayerr)
message("Outer wall coordinates must coincide for both components");
OSD_Printf("wal0:%d (%d,%d)--(%d,%d)\n",(int)(wal0-wall),
wal0->x,wal0->y, wal0p2->x,wal0p2->y);
OSD_Printf("wal1:%d (%d,%d)--(%d,%d)\n",(int)(wal1-wall),
wal1->x,wal1->y, wal1p2->x,wal1p2->y);
goto end_join_sectors;
}

View file

@ -58,6 +58,9 @@ gamevar dang 0 0
gamevar tmp 0 0
gamevar cnt 0 0
gamevar sec 0 0
gamevar wal 0 0
gamevar drawcol 9 0
@ -478,7 +481,32 @@ onevent EVENT_ENTER3DMODE
state setas
endevent
////// sector collecting stuff
gamearray collectedsectors MAXSECTORS
defstate try_nextsector
var nexts
set nexts RETURN
set RETURN 0
for i spritesofsector nexts
{
ife .picnum SECTOREFFECTOR ife .lotag 7
{
set RETURN 1
break
}
}
ends
defstate collect_teleporting_sectors // (sec)
var numsects
collectsectors collectedsectors sec numsects try_nextsector
for i range numsects
sethighlightsector collectedsectors[i] 1
ends
////// show LOCATORS
defstate cmp_by_lotag // comparator subroutine for sorting
set RETURN sprite[SV2].lotag
sub RETURN sprite[SV1].lotag
@ -1036,9 +1064,6 @@ defstate js // jump to current sprite
updatecursectnum
ends
var sec 0 0
var wal 0 0
defstate jumptowal // (wal)
ifge wal 0 ifl wal numwalls nullop else return
set posx wall[wal].x
@ -1160,7 +1185,6 @@ defstate chselshade
}
ends
////////// USER AREA //////////
// key settings

View file

@ -121,7 +121,7 @@ int32_t showambiencesounds=2;
int32_t autocorruptcheck = 0;
static int32_t corruptchecktimer;
static int32_t curcorruptthing=-1;
static int32_t curcorruptthing=-1, corrupt_tryfix_alt=0;
int32_t corruptlevel=0, numcorruptthings=0, corruptthings[MAXCORRUPTTHINGS];
@ -8003,8 +8003,8 @@ static void Keys2d(void)
case CORRUPT_WALL:
i = k&(MAXWALLS-1);
j = 1;
x = wall[i].x;
y = wall[i].y;
x = wall[i].x + (wall[wall[i].point2].x-wall[i].x)/2;
y = wall[i].y + (wall[wall[i].point2].y-wall[i].y)/2;
z = getflorzofslope(sectorofwall(i), x, y);
break;
case CORRUPT_SPRITE:
@ -8197,10 +8197,10 @@ static void Keys2d(void)
j = getnumber16("Wall: ", 0, numwalls-1, 0+8);
if (j < 0)
break;
pos.x = wall[j].x;
pos.y = wall[j].y;
pos.z = sector[sectorofwall(j)].floorz;
printmessage16("Current pos now on wall %d's point", j);
pos.x = wall[j].x + (wall[wall[j].point2].x-wall[j].x)/2;
pos.y = wall[j].y + (wall[wall[j].point2].y-wall[j].y)/2;
pos.z = getflorzofslope(sectorofwall(j), pos.x, pos.y);
printmessage16("Current pos now on wall %d's midpoint", j);
}
break;
case 2:
@ -8902,17 +8902,21 @@ static int32_t osdcmd_vars_pk(const osdfuncparm_t *parm)
{
int32_t tryfix = parm->numparms>=1 && !Bstrcasecmp(parm->parms[0], "tryfix");
if (parm->numparms == 1 || tryfix)
if (parm->numparms >= 1 || tryfix)
{
if (!Bstrcasecmp(parm->parms[0], "now"))
{
if (CheckMapCorruption(1, 0)==0)
int32_t printfromlevel = 1;
if (parm->numparms > 1)
printfromlevel = clamp(atoi_safe(parm->parms[1]), 1, 5);
if (CheckMapCorruption(printfromlevel, 0)==0)
OSD_Printf("All OK.\n");
return OSDCMD_OK;
}
else if (tryfix)
{
uint64_t whicherrs = parm->numparms==1 ? 0xffffffffffffffffull : 0;
corrupt_tryfix_alt = 0;
if (whicherrs==0)
{
@ -8920,6 +8924,12 @@ static int32_t osdcmd_vars_pk(const osdfuncparm_t *parm)
char *endptr;
for (i=1; i<parm->numparms; i++)
{
if (i==parm->numparms-1 && !Bstrcmp(parm->parms[i], "?"))
{
corrupt_tryfix_alt = 1;
break;
}
n = (int32_t)Bstrtol(parm->parms[i], &endptr, 10);
if (endptr != parm->parms[i])
{
@ -8945,7 +8955,7 @@ static int32_t osdcmd_vars_pk(const osdfuncparm_t *parm)
}
}
CheckMapCorruption(3, whicherrs);
CheckMapCorruption(whicherrs?5:3, whicherrs);
return OSDCMD_OK;
}
else if (isdigit(parm->parms[0][0]))
@ -9115,6 +9125,13 @@ static int32_t osdcmd_do(const osdfuncparm_t *parm)
vm.updatehighlight = 0;
}
if (vm.updatehighlightsector)
{
update_highlightsector();
ovh_whiteoutgrab(1);
vm.updatehighlightsector = 0;
}
if (!(vm.flags&VMFLAG_ERROR))
{
int32_t idx, dosave=1;
@ -11162,25 +11179,61 @@ static int32_t walls_are_consistent(int32_t nw, int32_t j)
static void suggest_nextsector_correction(int32_t nw, int32_t j)
{
// wall j's nextsector is inconsistent with its nextwall... what shall we do?
if (nw>=0 && nw<numwalls)
{
// maybe nextwall is right?
// maybe wall[j].nextwall's nextwall is right?
if (wall[nw].nextwall==j && walls_are_consistent(nw, j))
OSD_Printf(" suggest setting wall[%d].nextsector to %d\n",
j, sectorofwall_noquick(nw));
}
// alternative
if (wall[j].nextsector>=0 && wall[j].nextsector<numsectors)
{
int32_t w, startwall, endwall;
for (WALLS_OF_SECTOR(wall[j].nextsector, w))
{
// XXX: need clearing some others?
if (walls_are_consistent(w, j))
{
OSD_Printf(" ? suggest setting wall[%d].nextwall to %d\n",
j, w);
break;
}
}
}
}
static void do_nextsector_correction(int32_t nw, int32_t j)
{
if (nw>=0 && nw<numwalls)
if (wall[nw].nextwall==j && walls_are_consistent(nw, j))
if (!corrupt_tryfix_alt)
{
if (nw>=0 && nw<numwalls)
if (wall[nw].nextwall==j && walls_are_consistent(nw, j))
{
int32_t newns = sectorofwall_noquick(nw);
wall[j].nextsector = newns;
OSD_Printf(CCHK_CORRECTED "auto-correction: set wall[%d].nextsector=%d\n",
j, newns);
}
}
else
{
if (wall[j].nextsector>=0 && wall[j].nextsector<numsectors)
{
int32_t newns = sectorofwall_noquick(nw);
wall[j].nextsector = newns;
OSD_Printf(CCHK_CORRECTED "auto-correction: set wall[%d].nextsector=%d\n",
j, newns);
int32_t w, startwall, endwall;
for (WALLS_OF_SECTOR(wall[j].nextsector, w))
if (walls_are_consistent(w, j))
{
wall[j].nextwall = w;
OSD_Printf(CCHK_CORRECTED "auto-correction: set wall[%d].nextwall=%d\n",
j, w);
break;
}
}
}
}
int32_t CheckMapCorruption(int32_t printfromlev, uint64_t tryfixing)
@ -11409,18 +11462,14 @@ int32_t CheckMapCorruption(int32_t printfromlev, uint64_t tryfixing)
{
if (nw<sector[ns].wallptr || nw>=sector[ns].wallptr+sector[ns].wallnum)
{
CORRUPTCHK_PRINT(4, CORRUPT_WALL|j, "WALL[%d].NEXTWALL=%d out of .NEXTSECTOR=%d's bounds",
j, nw, ns);
CORRUPTCHK_PRINT(4, CORRUPT_WALL|j, "WALL[%d].NEXTWALL=%d out of .NEXTSECTOR=%d's bounds [%d .. %d]",
j, nw, ns, sector[ns].wallptr, sector[ns].wallptr+sector[ns].wallnum-1);
if (onumct < MAXCORRUPTTHINGS)
{
if (tryfixing & (1ull<<onumct))
do_nextsector_correction(nw, j);
else if (4 >= printfromlev)
{
OSD_Printf(" sector %d's walls: [%d .. %d]\n", ns,
sector[ns].wallptr, sector[ns].wallptr+sector[ns].wallnum-1);
suggest_nextsector_correction(nw, j);
}
}
}
#if 0

View file

@ -242,6 +242,7 @@ const char *keyw[] =
"a2xy",
"ah2xyz",
"collectsectors",
"sort",
"for", // *
@ -339,7 +340,9 @@ const char *keyw[] =
"getclosestcol",
"updatehighlight",
"updatehighlightsector",
"sethighlight",
"sethighlightsector",
"addlogvar",
"addlog",
"debug",
@ -1950,6 +1953,7 @@ static int32_t C_ParseCommand(void)
return 0;
case CON_COLLECTSECTORS:
case CON_SORT:
if (C_GetNextLabelName(1))
return 1;
@ -1963,16 +1967,30 @@ static int32_t C_ParseCommand(void)
C_ReportError(ERROR_ARRAYREADONLY);
g_numCompilerErrors++;
}
if (aGameArrays[i].dwFlags & GAMEARRAY_TYPE_MASK)
{
C_CUSTOMERROR("Array for %s must be user-defined.",
tw==CON_SORT?"sorting":"collecting sectors");
g_numCompilerErrors++;
}
}
else
{
C_ReportError(ERROR_NOTAGAMEARRAY);
g_numCompilerErrors++;
}
C_SkipComments();
C_GetNextVar(); // element count to sort
if (C_GetKeyword() >= 0)
C_SkipComments();
// element count to sort (SORT) / starting sector (COLLECTSECTORS):
C_GetNextVar();
if (tw==CON_COLLECTSECTORS)
{
// the variable to store the number of collected sectors
C_GetNextVarType(GV_WRITABLE);
}
else if (C_GetKeyword() >= 0)
{
// default sorting state that compares values numerically
*g_scriptPtr++ = -1;
@ -3036,15 +3054,15 @@ repeatcase:
break;
case CON_CALCHYPOTENUSE:
C_GetNextVarType(GAMEVAR_READONLY);
C_GetNextVarType(GV_WRITABLE);
C_GetManyVars(2);
break;
case CON_CLIPMOVE:
// <retvar>,<x>,<y>,z,<sectnum>, xvect,yvect,walldist,floordist,ceildist,clipmask
C_GetManyVarsType(GAMEVAR_READONLY,3);
C_GetManyVarsType(GV_WRITABLE,3);
C_GetNextVar();
C_GetNextVarType(GAMEVAR_READONLY);
C_GetNextVarType(GV_WRITABLE);
C_GetManyVars(6);
break;
@ -3053,7 +3071,7 @@ repeatcase:
// lineintersect x y z x y z x y x y <intx> <inty> <intz> <ret>
// rayintersect x y z vx vy vz x y x y <intx> <inty> <intz> <ret>
C_GetManyVars(10);
C_GetManyVarsType(GAMEVAR_READONLY,4);
C_GetManyVarsType(GV_WRITABLE,4);
break;
case CON_HITSCAN:
@ -3127,6 +3145,11 @@ repeatcase:
C_GetManyVars(3);
return 0;
case CON_SETHIGHLIGHTSECTOR:
// sethighlightsector <index> <set_or_unset>
C_GetManyVars(2);
return 0;
case CON_ADDLOGVAR:
// syntax: addlogvar <var>
// prints the line number in the log file.
@ -3134,6 +3157,7 @@ repeatcase:
return 0;
case CON_UPDATEHIGHLIGHT:
case CON_UPDATEHIGHLIGHTSECTOR:
case CON_ADDLOG:
// syntax: addlog
// prints the line number in the log file.

View file

@ -98,6 +98,7 @@ typedef struct {
spritetype *g_sp;
uint32_t flags; //g_errorFlag, g_returnFlag;
uint32_t updatehighlight;
uint32_t updatehighlightsector;
} vmstate_t;
#define VMFLAG_RETURN 1
@ -363,6 +364,7 @@ enum ScriptKeywords_t
CON_A2XY,
CON_AH2XYZ,
CON_COLLECTSECTORS,
CON_SORT,
CON_FOR,
@ -473,7 +475,9 @@ enum ScriptKeywords_t
// stuff
CON_UPDATEHIGHLIGHT,
CON_UPDATEHIGHLIGHTSECTOR,
CON_SETHIGHLIGHT,
CON_SETHIGHLIGHTSECTOR,
CON_ADDLOGVAR,
CON_ADDLOG,
CON_DEBUG,

View file

@ -42,6 +42,7 @@ vmstate_t vm_default =
0,
NULL,
0,
0,
0
};
@ -193,6 +194,13 @@ void VM_OnEvent(register int32_t iEventID, register int32_t iActor)
vm.updatehighlight = 0;
}
if (vm.updatehighlightsector)
{
update_highlightsector();
ovh_whiteoutgrab(1);
vm.updatehighlightsector = 0;
}
// restore old values...
Bmemcpy(&vm, &vm_backup, sizeof(vmstate_t));
insptr = oinsptr;
@ -1160,6 +1168,58 @@ skip_check:
continue;
}
case CON_COLLECTSECTORS:
insptr++;
{
int32_t aridx=*insptr++, startsectnum=Gv_GetVarX(*insptr++);
int32_t numsectsVar=*insptr++, state=*insptr++;
int32_t o_g_st=vm.g_st, arsize = aGameArrays[aridx].size;
instype *end=insptr;
int32_t sectcnt, numsects=0;
int16_t *sectlist = aGameArrays[aridx].vals; // actually an int32_t array
int32_t *sectlist32 = (int32_t *)sectlist;
int32_t j, startwall, endwall, ns;
static uint8_t sectbitmap[MAXSECTORS>>3];
X_ERROR_INVALIDSECT(startsectnum);
if (arsize < numsectors)
{
M32_ERROR("Array size must be at least numsectors (=%d) for collecting!",
numsectors);
continue;
}
// collect!
bfirst_search_init(sectlist, sectbitmap, &numsects, MAXSECTORS, startsectnum);
for (sectcnt=0; sectcnt<numsects; sectcnt++)
for (WALLS_OF_SECTOR(sectlist[sectcnt], j))
if ((ns=wall[j].nextsector) >= 0 && wall[j].nextsector<numsectors)
{
if (sectbitmap[ns>>3]&(1<<(ns&7)))
continue;
vm.g_st = 1+MAXEVENTS+state;
insptr = script + statesinfo[state].ofs;
g_iReturnVar = ns;
VM_Execute(0);
if (g_iReturnVar)
bfirst_search_try(sectlist, sectbitmap, &numsects, wall[j].nextsector);
}
// short->int sector list
for (j=numsects-1; j>=0; j--)
sectlist32[j] = sectlist[j];
Gv_SetVarX(numsectsVar, numsects);
g_iReturnVar = 0;
// restore some VM state
vm.g_st = o_g_st;
insptr = end;
}
continue;
case CON_SORT:
insptr++;
{
@ -2099,11 +2159,22 @@ badindex:
update_highlight();
continue;
case CON_UPDATEHIGHLIGHTSECTOR:
insptr++;
update_highlightsector();
continue;
case CON_SETHIGHLIGHT:
insptr++;
{
int32_t what=Gv_GetVarX(*insptr++), index=Gv_GetVarX(*insptr++), doset = Gv_GetVarX(*insptr++);
if (highlightsectorcnt >= 0)
{
M32_ERROR("sector highlight active or pending, cannot highlight sprites/walls");
continue;
}
if (what&16384)
{
index &= ~16384;
@ -2118,10 +2189,13 @@ badindex:
else
show2dsprite[index>>3] &= ~(1<<(index&7));
}
else if (index < 0 || index>=numwalls)
else
{
M32_ERROR("Invalid wall index %d", index);
continue;
if (index < 0 || index>=numwalls)
{
M32_ERROR("Invalid wall index %d", index);
continue;
}
if (doset)
show2dwall[index>>3] |= (1<<(index&7));
@ -2134,6 +2208,29 @@ badindex:
continue;
}
case CON_SETHIGHLIGHTSECTOR:
insptr++;
{
int32_t index=Gv_GetVarX(*insptr++), doset = Gv_GetVarX(*insptr++);
if (highlightcnt >= 0)
{
M32_ERROR("sprite/wall highlight active or pending, cannot highlight sectors");
continue;
}
X_ERROR_INVALIDSECT(index);
if (doset)
hlsectorbitmap[index>>3] |= (1<<(index&7));
else
hlsectorbitmap[index>>3] &= ~(1<<(index&7));
vm.updatehighlightsector = 1;
continue;
}
case CON_GETTIMEDATE:
insptr++;
{

View file

@ -1221,9 +1221,10 @@ static void cmpspecdata(const dataspec_t *spec, uint8_t **dumpvar, uint8_t **dif
if ((sp->flags&(DS_NOCHK|DS_STRING|DS_CMP)))
continue;
if (sp->flags&(DS_LOADFN|DS_SAVEFN) && (sp->flags&(DS_PROTECTFN))==0)
if (sp->flags&(DS_LOADFN|DS_SAVEFN))
{
(*(void ( *)())sp->ptr)();
if ((sp->flags&(DS_PROTECTFN))==0)
(*(void ( *)())sp->ptr)();
continue;
}