From ee4d060b1f802c7ec4820b00dfd136ca67881189 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sun, 3 Jul 2011 22:51:28 +0000 Subject: [PATCH] * New m32script commands: - sethighlightsector - updatehighlightsector - collectsectors <> <> 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 --- polymer/eduke32/build/include/editor.h | 1 + polymer/eduke32/build/src/build.c | 40 ++++++---- polymer/eduke32/samples/a.m32 | 32 +++++++- polymer/eduke32/source/astub.c | 95 +++++++++++++++++------ polymer/eduke32/source/m32def.c | 38 +++++++-- polymer/eduke32/source/m32def.h | 4 + polymer/eduke32/source/m32exec.c | 103 ++++++++++++++++++++++++- polymer/eduke32/source/savegame.c | 5 +- 8 files changed, 265 insertions(+), 53 deletions(-) diff --git a/polymer/eduke32/build/include/editor.h b/polymer/eduke32/build/include/editor.h index 911072139..3c2065e0e 100644 --- a/polymer/eduke32/build/include/editor.h +++ b/polymer/eduke32/build/include/editor.h @@ -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, diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index e8d9a76d2..2eabb3e5d 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -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; i0 && 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; } diff --git a/polymer/eduke32/samples/a.m32 b/polymer/eduke32/samples/a.m32 index dbf6bbd6c..64c1cc9c2 100644 --- a/polymer/eduke32/samples/a.m32 +++ b/polymer/eduke32/samples/a.m32 @@ -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 diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index 44bbbdcb5..1dd8772cf 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -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; inumparms; 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=0 && wall[j].nextsector=0 && nw=0 && nw=0 && wall[j].nextsector=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<= 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 diff --git a/polymer/eduke32/source/m32def.c b/polymer/eduke32/source/m32def.c index 55a858209..35fe15311 100644 --- a/polymer/eduke32/source/m32def.c +++ b/polymer/eduke32/source/m32def.c @@ -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: // ,,,z,, 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 // rayintersect x y z vx vy vz x y x y 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 + C_GetManyVars(2); + return 0; + case CON_ADDLOGVAR: // syntax: addlogvar // 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. diff --git a/polymer/eduke32/source/m32def.h b/polymer/eduke32/source/m32def.h index 3cc7fbac7..0210b6d03 100644 --- a/polymer/eduke32/source/m32def.h +++ b/polymer/eduke32/source/m32def.h @@ -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, diff --git a/polymer/eduke32/source/m32exec.c b/polymer/eduke32/source/m32exec.c index 0439e78a8..22a535b67 100644 --- a/polymer/eduke32/source/m32exec.c +++ b/polymer/eduke32/source/m32exec.c @@ -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= 0 && wall[j].nextsector>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++; { diff --git a/polymer/eduke32/source/savegame.c b/polymer/eduke32/source/savegame.c index b2f543d42..d1e3e2da3 100644 --- a/polymer/eduke32/source/savegame.c +++ b/polymer/eduke32/source/savegame.c @@ -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; }