From 1d2e932d715cf6f74691b555d2c155a08a5e8d39 Mon Sep 17 00:00:00 2001 From: Evan Ramos Date: Tue, 4 Jun 2024 03:55:52 -0500 Subject: [PATCH 1/6] Duke3D: Fix `-s` command line parameter with values >= 5 when valid Fixes terminx/eduke32#306 --- source/duke3d/src/cmdline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/duke3d/src/cmdline.cpp b/source/duke3d/src/cmdline.cpp index f7aceee247..27ee2f9061 100644 --- a/source/duke3d/src/cmdline.cpp +++ b/source/duke3d/src/cmdline.cpp @@ -697,7 +697,7 @@ void G_CheckCommandLine(int32_t argc, char const * const * argv) break; case 's': c++; - ud.m_player_skill = ud.player_skill = (Batoi(c)%5); + ud.m_player_skill = ud.player_skill = clamp(Batoi(c), 0, g_maxDefinedSkill); if (ud.m_player_skill == 4) ud.m_respawn_monsters = ud.respawn_monsters = 1; break; From 86e58764dd3bc881490a4abea735e364dd75f37a Mon Sep 17 00:00:00 2001 From: Evan Ramos Date: Tue, 4 Jun 2024 04:48:52 -0500 Subject: [PATCH 2/6] SW: Fix GRP checksumming log messages --- source/sw/src/grpscan.cpp | 51 ++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/source/sw/src/grpscan.cpp b/source/sw/src/grpscan.cpp index 30900c53dd..49da28045b 100644 --- a/source/sw/src/grpscan.cpp +++ b/source/sw/src/grpscan.cpp @@ -164,6 +164,10 @@ static void ProcessGroups(BUILDVFS_FIND_REC *srch, native_t maxsize) char *fn; struct Bstat st; + static constexpr int ReadSize = 65536; + + auto buf = (uint8_t *)Xmalloc(ReadSize); + for (sidx = srch; sidx; sidx = sidx->next) { for (fg = grpcache; fg; fg = fg->next) @@ -173,15 +177,20 @@ static void ProcessGroups(BUILDVFS_FIND_REC *srch, native_t maxsize) if (fg) { - if (findfrompath(sidx->name, &fn)) continue; // failed to resolve the filename - if (Bstat(fn, &st)) { Xfree(fn); continue; } // failed to stat the file + if (findfrompath(sidx->name, &fn)) continue; // failed to resolve the filename + if (Bstat(fn, &st)) + { + Xfree(fn); + continue; + } // failed to stat the file Xfree(fn); - if (fg->size == st.st_size && fg->mtime == st.st_mtime) + if (st.st_size && fg->size == (int32_t)st.st_size && fg->mtime == (int32_t)st.st_mtime) { - struct internalgrpfile const * const grptype = FindGrpInfo(fg->crcval, fg->size); + auto const grptype = FindGrpInfo(fg->crcval, fg->size); + if (grptype) { - auto grp = (struct grpfile *)Xcalloc(1, sizeof(struct grpfile)); + auto const grp = (struct grpfile *)Xcalloc(1, sizeof(struct grpfile)); grp->filename = Xstrdup(sidx->name); grp->type = grptype; grp->next = foundgrps; @@ -200,29 +209,30 @@ static void ProcessGroups(BUILDVFS_FIND_REC *srch, native_t maxsize) } { - int b, fh; - unsigned int crcval = 0; - unsigned char buf[16*512]; + int32_t b, fh; + int32_t crcval = 0; fh = openfrompath(sidx->name, BO_RDONLY|BO_BINARY, BS_IREAD); if (fh < 0) continue; - if (fstat(fh, &st)) continue; - if (st.st_size > maxsize) continue; + if (Bfstat(fh, &st)) continue; + if (!st.st_size || st.st_size > maxsize) continue; - buildprintf(" Checksumming %s...", sidx->name); + DLOG_F(INFO, " Checksumming %s...", sidx->name); do { - b = read(fh, buf, sizeof(buf)); + b = read(fh, buf, ReadSize); if (b > 0) crcval = Bcrc32(buf, b, crcval); } - while (b == sizeof(buf)); + while (b == ReadSize); close(fh); - buildputs(" Done\n"); - struct internalgrpfile const * const grptype = FindGrpInfo(crcval, st.st_size); + LOG_F(INFO, " %s has checksum 0x%08x", sidx->name, crcval); + + auto const grptype = FindGrpInfo(crcval, st.st_size); + if (grptype) { - auto grp = (struct grpfile *)Xcalloc(1, sizeof(struct grpfile)); + auto const grp = (struct grpfile *)Xcalloc(1, sizeof(struct grpfile)); grp->filename = Xstrdup(sidx->name); grp->type = grptype; grp->next = foundgrps; @@ -230,7 +240,7 @@ static void ProcessGroups(BUILDVFS_FIND_REC *srch, native_t maxsize) } fgg = (struct grpcache *)Xcalloc(1, sizeof(struct grpcache)); - strncpy(fgg->name, sidx->name, BMAX_PATH); + Bstrncpyz(fgg->name, sidx->name, BMAX_PATH); fgg->size = st.st_size; fgg->mtime = st.st_mtime; fgg->crcval = crcval; @@ -238,6 +248,8 @@ static void ProcessGroups(BUILDVFS_FIND_REC *srch, native_t maxsize) usedgrpcache = fgg; } } + + Xfree(buf); } int ScanGroups(void) @@ -288,8 +300,7 @@ int ScanGroups(void) if (usedgrpcache) { - FILE *fp; - fp = fopen(GRPCACHEFILE, "wt"); + buildvfs_FILE fp = buildvfs_fopen_write(GRPCACHEFILE); if (fp) { for (fg = usedgrpcache; fg; fg=fgg) @@ -298,7 +309,7 @@ int ScanGroups(void) fprintf(fp, "\"%s\" %d %d %d\n", fg->name, fg->size, fg->mtime, fg->crcval); Xfree(fg); } - fclose(fp); + buildvfs_fclose(fp); } } From f6f261d8f0410b2bae3979b341c4521ae985ff86 Mon Sep 17 00:00:00 2001 From: Evan Ramos Date: Tue, 4 Jun 2024 05:14:11 -0500 Subject: [PATCH 3/6] Defs: Apply minor cosmetic cleanup to voxel token code --- source/build/src/defs.cpp | 17 ++++++++++------- source/build/src/engine.cpp | 6 +++--- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index c28605b3e5..0b8069de9b 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -1937,7 +1937,7 @@ static int32_t defsparser(scriptfile *script) }; if (EDUKE32_PREDICT_FALSE(scriptfile_getstring(script,&fn))) - break; //voxel filename + break; if (scriptfile_getbraces(script,&voxelend)) break; @@ -1946,14 +1946,14 @@ static int32_t defsparser(scriptfile *script) if (EDUKE32_PREDICT_FALSE(nextvoxid == MAXVOXELS)) { - LOG_F(ERROR, "definevoxel: maximum number of voxels (%d) already defined.", MAXVOXELS); + LOG_F(ERROR, "voxel: maximum number of voxels (%d) already defined.", MAXVOXELS); script->textptr = voxelend + 1; break; } if (EDUKE32_PREDICT_FALSE(qloadkvx(nextvoxid, fn))) { - LOG_F(ERROR, "definevoxel: failed loading %s",fn); + LOG_F(ERROR, "voxel: failed loading %s",fn); script->textptr = voxelend + 1; break; } @@ -1971,13 +1971,14 @@ static int32_t defsparser(scriptfile *script) break; tiletovox[tilex] = lastvoxid; + break; - case T_TILE0: + case T_TILE0: // 1st tile # scriptfile_getsymbol(script,&tile0); - break; //1st tile # + break; - case T_TILE1: + case T_TILE1: // last tile number (inclusive) scriptfile_getsymbol(script,&tile1); if (check_tile_range("voxel", &tile0, &tile1, script, voxeltokptr)) @@ -1985,7 +1986,8 @@ static int32_t defsparser(scriptfile *script) for (tilex=tile0; tilex<=tile1; tilex++) tiletovox[tilex] = lastvoxid; - break; //last tile number (inclusive) + + break; case T_SCALE: { @@ -2007,6 +2009,7 @@ static int32_t defsparser(scriptfile *script) // end downstream } } + lastvoxid = -1; } break; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index bfaa021817..4dae83d14b 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -12122,7 +12122,7 @@ uint8_t maxvoxcol; void getVoxelColorMap(char* davoxptr, uint8_t *bitmap) { - Bmemset(bitmap, -1, 32); + Bmemset(bitmap, -1, bitmap_size(256)); maxvoxcol = 0; int32_t *longptr = (int32_t *)davoxptr; @@ -12244,7 +12244,7 @@ int32_t qloadkvx(int32_t voxindex, const char *filename) klseek(fil, 0, SEEK_SET); - auto bitmap = (uint8_t*)Balloca(32); + uint8_t bitmap[bitmap_size(256)]; int32_t lastsiz=0; for (int i=0; i= MAXVOXELS) return; #ifdef USE_OPENGL From 9f400ac1868c7c0401f81ade5a7a2595c83c60c9 Mon Sep 17 00:00:00 2001 From: Evan Ramos Date: Tue, 4 Jun 2024 06:49:02 -0500 Subject: [PATCH 4/6] Engine: Factor a new vox_clearid() out from vox_undefine() --- source/build/include/build.h | 1 + source/build/src/engine.cpp | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source/build/include/build.h b/source/build/include/build.h index 5a5253d529..d42b6b336d 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -1251,6 +1251,7 @@ void artConvertRGB(palette_t *pic, uint8_t const *buf, int32_t bufsizx, int32 void tileUpdatePicSiz(int32_t picnum); int32_t qloadkvx(int32_t voxindex, const char *filename); +void vox_clearid(int32_t const); void vox_undefine(int32_t const); intptr_t tileCreate(int16_t tilenume, int32_t xsiz, int32_t ysiz); void tileCopySection(int32_t tilenume1, int32_t sx1, int32_t sy1, int32_t xsiz, int32_t ysiz, int32_t tilenume2, int32_t sx2, int32_t sy2); diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 4dae83d14b..c7790161aa 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -12293,9 +12293,8 @@ int32_t qloadkvx(int32_t voxindex, const char *filename) return 0; } -void vox_undefine(int32_t const tile) +void vox_clearid(int32_t const voxindex) { - ssize_t voxindex = tiletovox[tile]; if ((unsigned)voxindex >= MAXVOXELS) return; @@ -12316,11 +12315,16 @@ void vox_undefine(int32_t const tile) } voxscale[voxindex] = 65536; voxflags[voxindex] = 0; - tiletovox[tile] = -1; // TODO: nextvoxid } +void vox_undefine(int32_t const tile) +{ + vox_clearid(tiletovox[tile]); + tiletovox[tile] = -1; +} + // // inside // From b6748815d0cc74879b203ca6d71dd5ea19048a1e Mon Sep 17 00:00:00 2001 From: Evan Ramos Date: Tue, 4 Jun 2024 04:03:30 -0500 Subject: [PATCH 5/6] Defs: Factor out ifmatch/ifcrc handling into TileMatchChecker class --- source/build/src/defs.cpp | 139 +++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 61 deletions(-) diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 0b8069de9b..6ca199415d 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -318,6 +318,80 @@ static int32_t Defs_ImportTileFromTexture(char const * const fn, int32_t const t return 0; } +class TileMatchChecker +{ + int32_t tile_crc32{}; + vec2_t tile_size{}; + bool have_crc32{}; + bool have_size{}; + +public: + void parse_ifcrc(scriptfile * script) + { + scriptfile_getsymbol(script, &tile_crc32); + have_crc32 = true; + } + + void parse_ifmatch(scriptfile * script) + { + char *ifmatchend; + + static const tokenlist ifmatchtokens[] = + { + { "crc32", T_CRC32 }, + { "size", T_SIZE }, + }; + + if (scriptfile_getbraces(script, &ifmatchend)) return; + while (script->textptr < ifmatchend) + { + int32_t token = getatoken(script, ifmatchtokens, ARRAY_SIZE(ifmatchtokens)); + switch (token) + { + case T_CRC32: + scriptfile_getsymbol(script, &tile_crc32); + have_crc32 = true; + break; + case T_SIZE: + scriptfile_getsymbol(script, &tile_size.x); + scriptfile_getsymbol(script, &tile_size.y); + have_size = true; + break; + default: + break; + } + } + } + + bool is_different(const char * tokenname, int32_t tile) const + { + bool different_crc32 = have_crc32; + bool different_size = have_size; + + if (have_crc32) + { + int32_t const orig_crc32 = tileGetCRC32(tile); + if (orig_crc32 == tile_crc32) + different_crc32 = false; + else + DLOG_F(WARNING, "%s: CRC32 of tile %d doesn't match! CRC32: 0x%08X, Expected: 0x%08X", + tokenname, tile, orig_crc32, tile_crc32); + } + + if (have_size) + { + vec2_16_t const orig_size = tileGetSize(tile); + if (orig_size.x == tile_size.x && orig_size.y == tile_size.y) + different_size = false; + else + DLOG_F(WARNING, "%s: size of tile %d doesn't match! Size: (%d, %d), Expected: (%d, %d)", + tokenname, tile, orig_size.x, orig_size.y, tile_size.x, tile_size.y); + } + + return different_crc32 || different_size; + } +}; + #undef USE_DEF_PROGRESS #if defined _WIN32 || defined HAVE_GTK2 # define USE_DEF_PROGRESS @@ -812,10 +886,7 @@ static int32_t defsparser(scriptfile *script) int32_t havexoffset = 0, haveyoffset = 0; int32_t xoffset = 0, yoffset = 0; int32_t istexture = 0; - int32_t tile_crc32 = 0; - vec2_t tile_size{}; - uint8_t have_crc32 = 0; - uint8_t have_size = 0; + TileMatchChecker matcher; uint8_t tile_flags = 0; // begin downstream // end downstream @@ -864,40 +935,11 @@ static int32_t defsparser(scriptfile *script) yoffset = clamp(yoffset, -128, 127); break; case T_IFCRC: - scriptfile_getsymbol(script, &tile_crc32); - have_crc32 = 1; + matcher.parse_ifcrc(script); break; case T_IFMATCH: - { - char *ifmatchend; - - static const tokenlist ifmatchtokens[] = - { - { "crc32", T_CRC32 }, - { "size", T_SIZE }, - }; - - if (scriptfile_getbraces(script,&ifmatchend)) break; - while (script->textptr < ifmatchend) - { - int32_t token = getatoken(script,ifmatchtokens,ARRAY_SIZE(ifmatchtokens)); - switch (token) - { - case T_CRC32: - scriptfile_getsymbol(script, &tile_crc32); - have_crc32 = 1; - break; - case T_SIZE: - scriptfile_getsymbol(script, &tile_size.x); - scriptfile_getsymbol(script, &tile_size.y); - have_size = 1; - break; - default: - break; - } - } + matcher.parse_ifmatch(script); break; - } case T_TEXHITSCAN: flags |= PICANM_TEXHITSCAN_BIT; break; @@ -924,33 +966,8 @@ static int32_t defsparser(scriptfile *script) break; } - int32_t orig_crc32{}; - if (have_crc32) - { - orig_crc32 = tileGetCRC32(tile); - if (orig_crc32 == tile_crc32) - have_crc32 = 0; - else - DLOG_F(WARNING, "tilefromtexture: CRC32 of tile %d doesn't match! CRC32: 0x%08X, Expected: 0x%08X", tile, orig_crc32, tile_crc32); - } - - vec2_16_t orig_size{}; - if (have_size) - { - orig_size = tileGetSize(tile); - if (orig_size.x == tile_size.x && orig_size.y == tile_size.y) - have_size = 0; - else - DLOG_F(WARNING, "tilefromtexture: size of tile %d doesn't match! Size: (%d, %d), Expected: (%d, %d)", tile, orig_size.x, orig_size.y, tile_size.x, tile_size.y); - } - - if (have_crc32 || have_size) - { -#if 0 - DLOG_F(INFO, "tilefromtexture %d { ifmatch { size %d %d crc32 0x%08X } }", tile, orig_size.x, orig_size.y, orig_crc32); -#endif + if (matcher.is_different("tilefromtexture", tile)) break; - } if (!fn) { From 30deaa5201b023838a950abbeddc3e0a2833b581 Mon Sep 17 00:00:00 2001 From: Evan Ramos Date: Tue, 4 Jun 2024 05:30:56 -0500 Subject: [PATCH 6/6] Defs: Implement ifmatch subtoken for voxel token Note that due to the nature of the voxel token, this subtoken must appear *before* any tile subtokens in order to take effect. Fixes terminx/eduke32#305 --- source/build/src/defs.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 6ca199415d..5b55a33f0e 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -1941,9 +1941,11 @@ static int32_t defsparser(scriptfile *script) char *voxeltokptr = script->ltextptr; char *fn, *voxelend; int32_t tile0 = MAXTILES, tile1 = -1, tilex = -1; + TileMatchChecker matcher; static const tokenlist voxeltokens[] = { + { "ifmatch", T_IFMATCH }, { "tile", T_TILE }, { "tile0", T_TILE0 }, { "tile1", T_TILE1 }, @@ -1981,12 +1983,19 @@ static int32_t defsparser(scriptfile *script) { switch (getatoken(script, voxeltokens, ARRAY_SIZE(voxeltokens))) { + case T_IFMATCH: + matcher.parse_ifmatch(script); + break; + case T_TILE: scriptfile_getsymbol(script,&tilex); if (check_tile("voxel", tilex, script, voxeltokptr)) break; + if (matcher.is_different("voxel", tilex)) + break; + tiletovox[tilex] = lastvoxid; break; @@ -2002,7 +2011,12 @@ static int32_t defsparser(scriptfile *script) break; for (tilex=tile0; tilex<=tile1; tilex++) + { + if (matcher.is_different("voxel", tilex)) + continue; + tiletovox[tilex] = lastvoxid; + } break;