From 363f0b3af69b1262e108527fc29b845cebd8e443 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Fri, 8 Aug 2014 20:02:54 +0000 Subject: [PATCH] Mapster32: prototypical checker for wall loops, enabled partially. Inspired by http://forums.duke4.net/topic/7506-tror-question/page__view__findpost__p__199151 the corruption checker now checks for certain conditions of the loops of each sector. Recall that CW loops are outer and CCW loops are inner. - If a sector has no or more than one outer loop, count that as corruption (level 4 and 3, respectively). - (Disabled) For sectors with exactly one outer loop, check that all inner ones are inside it. This is currently not compiled due to an asymmetry of loopinside() for degenerate cases, similar to pre-r3898 inside(). git-svn-id: https://svn.eduke32.com/eduke32@4569 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/Makefile.deps | 1 + polymer/eduke32/build/include/editor.h | 27 ++++++++++ polymer/eduke32/build/src/build.c | 9 +--- polymer/eduke32/source/m32common.c | 69 ++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 7 deletions(-) diff --git a/polymer/eduke32/Makefile.deps b/polymer/eduke32/Makefile.deps index c3a8edb9a..ae8b73ae6 100644 --- a/polymer/eduke32/Makefile.deps +++ b/polymer/eduke32/Makefile.deps @@ -102,6 +102,7 @@ $(DUKE3D_OBJ)/m32def.$o: $(DUKE3D_SRC)/m32def.c $(m32_script_hs) $(ENGINE_INC)/c $(DUKE3D_OBJ)/m32exec.$o: $(DUKE3D_SRC)/m32exec.c $(m32_script_hs) $(DUKE3D_SRC)/sounds_mapster32.h $(DUKE3D_SRC)/sounds_common.h $(ENGINE_INC)/osd.h $(DUKE3D_SRC)/keys.h $(AUDIOLIB_ROOT)/include/fx_man.h $(DUKE3D_OBJ)/m32structures.$o: $(DUKE3D_SRC)/m32structures.c $(m32_script_hs) $(ENGINE_INC)/compat.h $(ENGINE_INC)/prlights.h $(DUKE3D_OBJ)/m32vars.$o: $(DUKE3D_SRC)/m32vars.c $(DUKE3D_SRC)/m32structures.c $(m32_script_hs) $(ENGINE_INC)/osd.h $(DUKE3D_SRC)/keys.h $(ENGINE_INC)/polymer.h +# TODO: m32common.c # misc objects $(DUKE3D_OBJ)/game_icon.$o: $(DUKE3D_RSRC)/game_icon.c diff --git a/polymer/eduke32/build/include/editor.h b/polymer/eduke32/build/include/editor.h index 90542f575..2bbc9bdca 100644 --- a/polymer/eduke32/build/include/editor.h +++ b/polymer/eduke32/build/include/editor.h @@ -216,6 +216,33 @@ extern int32_t LoadBoard(const char *filename, uint32_t flags); extern const char *SaveBoard(const char *fn, uint32_t flags); extern const char *GetSaveBoardFilename(const char *fn); +extern int32_t clockdir(int32_t wallstart); +extern int32_t loopinside(int32_t x, int32_t y, int16_t startwall); + +enum { + // NOTE: These must not be changed, see e.g. loopinside(). + CLOCKDIR_CW = 0, // outer loop + CLOCKDIR_CCW = 1, // inner loop +}; + +// has to be the starting (i.e. least index) wall of a loop! +// +// The returned value will be either +// - the starting wall of the next loop of this sector, +// - the first wall of the next sector, or +// - out of bounds (== MAXWALLS). +// Thus, it MUST be checked for a proper bound! +static inline int32_t get_nextloopstart(int32_t loopstart) +{ + int32_t i = loopstart; + + while (++i) // sic + if (wall[i].point2 == loopstart) + return i + 1; + + return MAXWALLS; +} + #define CORRUPT_SECTOR (1<<17) #define CORRUPT_WALL (1<<18) #define CORRUPT_SPRITE (1<<19) diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index a1521217f..7b736c7ba 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -203,9 +203,6 @@ int32_t g_doScreenShot; #define DOWN_BK(BuildKey) (keystatus[buildkeys[BK_##BuildKey]]) -#define CLOCKDIR_CW 0 -#define CLOCKDIR_CCW 1 - int32_t pk_turnaccel=16; int32_t pk_turndecel=12; int32_t pk_uedaccel=3; @@ -227,12 +224,10 @@ static int32_t adjustmark(int32_t *xplc, int32_t *yplc, int16_t danumwalls); static void locktogrid(int32_t *dax, int32_t *day); static int32_t checkautoinsert(int32_t dax, int32_t day, int16_t danumwalls); static void keytimerstuff(void); -static int32_t clockdir(int16_t wallstart); static void flipwalls(int16_t numwalls, int16_t newnumwalls); static int32_t insertpoint(int16_t linehighlight, int32_t dax, int32_t day, int32_t *mapwallnum); static void deletepoint(int16_t point, int32_t runi); static int32_t deletesector(int16_t sucksect); -static int16_t loopinside(int32_t x, int32_t y, int16_t startwall); static int16_t whitelinescan(int16_t sucksect, int16_t dalinehighlight); static void printcoords16(int32_t posxe, int32_t posye, int16_t ange); static void overheadeditor(void); @@ -8453,7 +8448,7 @@ static int32_t checkautoinsert(int32_t dax, int32_t day, int16_t danumwalls) // has to be the starting (i.e. least index) wall of a loop! // Returns: CLOCKDIR_CW or CLOCKDIR_CCW. -static int32_t clockdir(int32_t wallstart) +int32_t clockdir(int32_t wallstart) { int32_t tempint, x0, x1, x2, y0, y1, y2; @@ -8837,7 +8832,7 @@ static void clearministatbar16(void) // // XXX: this function suffers from asymmetry issues in degenerate cases, // similar to how inside() did before r3898. -static int32_t loopinside(int32_t x, int32_t y, int16_t startwall) +int32_t loopinside(int32_t x, int32_t y, int16_t startwall) { int32_t cnt = clockdir(startwall); int32_t i = startwall; diff --git a/polymer/eduke32/source/m32common.c b/polymer/eduke32/source/m32common.c index 43e58b712..2685284c1 100644 --- a/polymer/eduke32/source/m32common.c +++ b/polymer/eduke32/source/m32common.c @@ -571,6 +571,8 @@ int32_t map_undoredo(int32_t dir) //// //// port of a.m32's corruptchk //// +// Compile wall loop checks? 0: no, 1: partial, 2: full. +#define CCHK_LOOP_CHECKS 1 // returns value from 0 (all OK) to 5 (panic!) #define CCHK_PANIC OSDTEXT_DARKRED "PANIC!!!^O " //#define CCHKPREF OSDTEXT_RED "^O" @@ -842,6 +844,32 @@ static int32_t check_spritelist_consistency() return 0; } +#if CCHK_LOOP_CHECKS +// Return the least wall index of the outer loop of sector , or +// -1 if there is none, +// -2 if there is more than one. +static int32_t determine_outer_loop(int32_t sectnum) +{ + int32_t j, outerloopstart = -1; + + const int32_t startwall = sector[sectnum].wallptr; + const int32_t endwall = startwall + sector[sectnum].wallnum - 1; + + for (j=startwall; j<=endwall; j=get_nextloopstart(j)) + { + if (clockdir(j) == CLOCKDIR_CW) + { + if (outerloopstart == -1) + outerloopstart = j; + else if (outerloopstart >= 0) + return -2; + } + } + + return outerloopstart; +} +#endif + #define TRYFIX_NONE() (tryfixing == 0ull) #define TRYFIX_CNUM(onumct) (onumct < MAXCORRUPTTHINGS && (tryfixing & (1ull<= 4) + { + const int32_t outerloopstart = determine_outer_loop(i); + + if (outerloopstart == -1) + CORRUPTCHK_PRINT(4, CORRUPT_SECTOR|i, "SECTOR %d contains no outer (clockwise) loop", i); + else if (outerloopstart == -2) + CORRUPTCHK_PRINT(3, CORRUPT_SECTOR|i, "SECTOR %d contains more than one outer (clockwise) loops", i); +# if CCHK_LOOP_CHECKS >= 2 + else + { + // Now, check for whether every wall-point of every inner loop of + // this sector () is inside the outer one. + + for (j=w0; j<=endwall; /* will step by loops */) + { + const int32_t nextloopstart = get_nextloopstart(j); + + if (j != outerloopstart) + { + int32_t k; + + for (k=j; k