From 3d7916e966d23df5a713c93b512115cbfe452aa2 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 3 Nov 2024 23:37:31 -0700 Subject: [PATCH] qbsp: fix -notex --- common/imglib.cc | 6 +- qbsp/qbsp.cc | 5 +- testmaps/q1_loose_textures.map | 67 ++++++++++++++++++ .../textures/floor_purple_c.png | Bin 0 -> 1378 bytes .../textures/lq_dev_readme.txt | 5 ++ .../q1_loose_textures/textures/wall_tan_a.png | Bin 0 -> 1336 bytes tests/CMakeLists.txt | 2 +- tests/test_qbsp.cc | 46 +++++++++++- 8 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 testmaps/q1_loose_textures.map create mode 100644 testmaps/q1_loose_textures/textures/floor_purple_c.png create mode 100644 testmaps/q1_loose_textures/textures/lq_dev_readme.txt create mode 100644 testmaps/q1_loose_textures/textures/wall_tan_a.png diff --git a/common/imglib.cc b/common/imglib.cc index 4b4079b0..39733168 100644 --- a/common/imglib.cc +++ b/common/imglib.cc @@ -331,8 +331,10 @@ std::tuple, fs::resolve_result, fs::data> load_textu { fs::path prefix{}; - if (!no_prefix && game->id == GAME_QUAKE_II) { - prefix = "textures"; + if (!no_prefix) { + if (game->id == GAME_QUAKE_II || !mip_only) { + prefix = "textures"; + } } std::vector exts; diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 61d8422d..33dec578 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -1540,7 +1540,10 @@ static void LoadTextureData() miptex.name = map.miptex[i].name; { - auto [tex, pos, file] = img::load_texture(map.miptex[i].name, true, qbsp_options.target_game, qbsp_options, false, true); + // i.e. only allow loose (non-.wad) textures if -notex is in use + const bool mip_only = !qbsp_options.notextures.value(); + + auto [tex, pos, file] = img::load_texture(map.miptex[i].name, true, qbsp_options.target_game, qbsp_options, false, mip_only); if (!tex) { if (pos.archive) { diff --git a/testmaps/q1_loose_textures.map b/testmaps/q1_loose_textures.map new file mode 100644 index 00000000..b37cd362 --- /dev/null +++ b/testmaps/q1_loose_textures.map @@ -0,0 +1,67 @@ +// Game: Generic +// Format: Standard +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures" +// brush 0 +{ +( -64 -64 -16 ) ( -64 -63 -16 ) ( -64 -64 -15 ) floor_purple_c 0 0 0 1 1 +( -64 -224 -16 ) ( -64 -224 -15 ) ( -63 -224 -16 ) floor_purple_c 0 0 0 1 1 +( -64 -64 -16 ) ( -63 -64 -16 ) ( -64 -63 -16 ) floor_purple_c 0 0 0 1 1 +( 64 64 16 ) ( 64 65 16 ) ( 65 64 16 ) floor_purple_c 0 0 0 1 1 +( 64 64 16 ) ( 65 64 16 ) ( 64 64 17 ) floor_purple_c 0 0 0 1 1 +( 304 64 16 ) ( 304 64 17 ) ( 304 65 16 ) floor_purple_c 0 0 0 1 1 +} +// brush 1 +{ +( -80 -64 -32 ) ( -80 -63 -32 ) ( -80 -64 -31 ) wall_tan_a 0 -16 0 1 1 +( -64 -224 -32 ) ( -64 -224 -31 ) ( -63 -224 -32 ) wall_tan_a 0 -16 0 1 1 +( -64 -64 16 ) ( -63 -64 16 ) ( -64 -63 16 ) wall_tan_a 0 0 0 1 1 +( 64 64 144 ) ( 64 65 144 ) ( 65 64 144 ) wall_tan_a 0 0 0 1 1 +( 64 64 0 ) ( 65 64 0 ) ( 64 64 1 ) wall_tan_a 0 -16 0 1 1 +( -64 -64 -32 ) ( -64 -64 -31 ) ( -64 -63 -32 ) wall_tan_a 0 -16 0 1 1 +} +// brush 2 +{ +( -80 -64 -32 ) ( -80 -63 -32 ) ( -80 -64 -31 ) wall_tan_a 0 -16 0 1 1 +( 64 64 0 ) ( 64 64 1 ) ( 65 64 0 ) wall_tan_a 0 -16 0 1 1 +( -64 -64 16 ) ( -63 -64 16 ) ( -64 -63 16 ) wall_tan_a 0 0 0 1 1 +( 64 64 144 ) ( 64 65 144 ) ( 65 64 144 ) wall_tan_a 0 0 0 1 1 +( 64 80 0 ) ( 65 80 0 ) ( 64 80 1 ) wall_tan_a 0 -16 0 1 1 +( 304 -64 -32 ) ( 304 -64 -31 ) ( 304 -63 -32 ) wall_tan_a 0 -16 0 1 1 +} +// brush 3 +{ +( 304 -64 -32 ) ( 304 -63 -32 ) ( 304 -64 -31 ) wall_tan_a 0 -16 0 1 1 +( 64 -224 0 ) ( 64 -224 1 ) ( 65 -224 0 ) wall_tan_a 0 -16 0 1 1 +( -64 -64 16 ) ( -63 -64 16 ) ( -64 -63 16 ) wall_tan_a 0 0 0 1 1 +( 64 64 144 ) ( 64 65 144 ) ( 65 64 144 ) wall_tan_a 0 0 0 1 1 +( 64 80 0 ) ( 65 80 0 ) ( 64 80 1 ) wall_tan_a 0 -16 0 1 1 +( 320 -64 -32 ) ( 320 -64 -31 ) ( 320 -63 -32 ) wall_tan_a 0 -16 0 1 1 +} +// brush 4 +{ +( -64 -64 -32 ) ( -64 -63 -32 ) ( -64 -64 -31 ) wall_tan_a 0 -16 0 1 1 +( 64 -240 0 ) ( 64 -240 1 ) ( 65 -240 0 ) wall_tan_a 0 -16 0 1 1 +( -64 -64 16 ) ( -63 -64 16 ) ( -64 -63 16 ) wall_tan_a 0 0 0 1 1 +( 64 64 144 ) ( 64 65 144 ) ( 65 64 144 ) wall_tan_a 0 0 0 1 1 +( 64 -224 0 ) ( 65 -224 0 ) ( 64 -224 1 ) wall_tan_a 0 -16 0 1 1 +( 320 -64 -32 ) ( 320 -64 -31 ) ( 320 -63 -32 ) wall_tan_a 0 -16 0 1 1 +} +// brush 5 +{ +( -64 -64 144 ) ( -64 -63 144 ) ( -64 -64 145 ) floor_purple_c 0 -32 0 1 1 +( -64 -224 144 ) ( -64 -224 145 ) ( -63 -224 144 ) floor_purple_c 0 -32 0 1 1 +( -64 -64 144 ) ( -63 -64 144 ) ( -64 -63 144 ) floor_purple_c 0 0 0 1 1 +( 64 64 176 ) ( 64 65 176 ) ( 65 64 176 ) floor_purple_c 0 0 0 1 1 +( 64 64 176 ) ( 65 64 176 ) ( 64 64 177 ) floor_purple_c 0 -32 0 1 1 +( 304 64 176 ) ( 304 64 177 ) ( 304 65 176 ) floor_purple_c 0 -32 0 1 1 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "224 -144 40" +"angle" "180" +} diff --git a/testmaps/q1_loose_textures/textures/floor_purple_c.png b/testmaps/q1_loose_textures/textures/floor_purple_c.png new file mode 100644 index 0000000000000000000000000000000000000000..9954d68776b0fb06b79e6c5612d9f03610d54c89 GIT binary patch literal 1378 zcmYjRe^3;46#t^xB8#lJ=w(ao#a5>-x-_S*aq0>SF6Wv@E_UWsr=D=oax8L3SUY+k zgPdN8NP6at9(4kZr<{#7D2Kv?q|+H{{+fX?NJR73ppii%O3Pn0Z{BfA7N`&!(J=E3%bVTV9=-yX!+{ z7#}%!bk)9>hIaorv39Uy|=>&%HA=e(~X=-JO$K-2jZM&0L<9uJD5(2#(_vMKKJ+^SsGq5=Bv#Ww+by z^?Cz=KqwRnhr`|7-S_X`M_@>Wz_<$5Ueu_JFMV=AOOPvMFEBZ zf&e55Q4~be5W_$m2k|^C2(ZZnTP(0BB9MX~02Kf@02%-&0B8Uh05|{)02l!<17HO} z0-yu{C-|={MFN@vEDd-aWMm;T2Z=mfA|T~P)NMjNX3THFgI0n-AxZ`7aD*pNBdM}b zxSb}PIw{{0nI=dA05PC2w*5634|t5PKyaNVPQy#(>evlZRWh9 z&>)+eD#i91`Lf^LciaFfo9(P1>Ugu35lEUNNF7d4|BLT#4~366wEDe4kK11duA8l1#c zgbKk>7=0 zDpIHAN%?sN#hWyC_4<6tsxFl54t1Vwoi*G3W?MX~RN10WOUYW@{_wq&s5W)<;Ik(O zhYIe^I&!Rka@F0A`m)llEbL6~AFUBT`C?tKoJvUA5_zWaMqbL=k+^eR=c2~-dD;&D za!8%@Jk}N082P!OYCAKrU2Z{GX8KfgC` zNA4P7YQjqi05H{>la;626;EaIBwZiu+Ij~duBL?NbFDmYEU!?CN=gd><}_|;T$a~|*d=3m!e?YOivbw_+!=C;Z4`K2w1#HODs^U@CATKd}v>3cl=)Qk#Gb)#$6%;JW3 zxQFDUL&x&>zc9A@n<*_1`Zg`!zV+h#i(kIpKX!a%(VFUEb9rmmqrDjm9$P;;*4nqL z`fJbdweHrr>e=f_3+`<^-*#u!%JrF_!|CSl*z46#94+dVkmEs0JGNqb(cbR3q@=Bl zsfC^YoQ_7elui7-=;qj@$I96ad~Nm(Mjc2adx z0XJ2zP$-JwI6)95lgX@CU|Esl?1JF7*}M*i-{sO|Iq3C&u7sD;Et3b)e+7ejhk z%5S0Td2_SP-05O^s+fU#dMIKVjgb=%2owPV2b#iI8W+rj#8NJfRs^$O;xwlalBIUl z*;Om|HmR4w+Q^AuL<=|jgH7IA&8_+!N|of2MZ1#|?JO@cEN^01lA;X+h2sW&l?W2` zHh0SPVP_y{uhML?UvzqTNw$biGbhokK+zVGV*VFD*c*+VXzvM!I)hrcRt>63t>RQ& zl57{8qDA7&yxGLkq=_^TIHr@U1XQ=GIK6JW?6kS;g2Tp1f=(L4v$Tbw%qEg14U_>R za1=)o6wyZ>9Wo5Y@K_fXZO0-(G!#HIFQU2-SptUuA`2E8Xc7nv^yL6dpy()$4-v!w zMfK2hC&M%|Og+Q+8Af3kCr#TZiX#XH$4PzS_9t13^`t4~Id6IO=W_L_#AVJ2ZGL(v zKI@y=$c?y^X?SX2U_poO%J5~c^YMzuQ&{GMtiqxVm8CvoMWI(It@M>BWyT_(11*MAHSgv?|#uCp4ccFLo*%V$!S!>N&xprOe-F*uaz?e8`e8RqQ+R&}x zy!g8fyMo!TlxuH$&aW>1IDABj`()2}+YzJz>iPU3WO(LMNH3t$3r3#%amX?r2eYT+ gQ;6fq#7|g%nk|K|n)bnGqK*&N>@`^(neT1;7h0Fma{vGU literal 0 HcmV?d00001 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cca831e6..35225455 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -27,7 +27,7 @@ if (NOT EMBREE_TBB_DLL STREQUAL EMBREE_TBB_DLL-NOTFOUND) message(STATUS "Found embree EMBREE_TBB_DLL: ${EMBREE_TBB_DLL}") endif() -target_link_libraries(tests libqbsp liblight libvis libbsputil common TBB::tbb TBB::tbbmalloc GTest::gtest fmt::fmt nanobench::nanobench) +target_link_libraries(tests libqbsp liblight libvis libbsputil common TBB::tbb TBB::tbbmalloc GTest::gtest GTest::gmock fmt::fmt nanobench::nanobench) # HACK: copy .dll dependencies add_custom_command(TARGET tests POST_BUILD diff --git a/tests/test_qbsp.cc b/tests/test_qbsp.cc index e18b0552..6ee9e308 100644 --- a/tests/test_qbsp.cc +++ b/tests/test_qbsp.cc @@ -14,12 +14,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include "testutils.hh" #include "test_main.hh" @@ -102,14 +104,18 @@ std::tuple> LoadTestmap( auto wal_metadata_path = std::filesystem::path(testmaps_dir) / "q2_wal_metadata"; - std::vector args{"", // the exe path, which we're ignoring in this case - "-path", wal_metadata_path.string()}; + std::vector args{""}; // the exe path, which we're ignoring in this case + if (std::ranges::find(extra_args, "-path") == extra_args.end()) { + extra_args.push_back("-path"); + extra_args.push_back(wal_metadata_path.string()); + } if (!tests_verbose) { args.push_back("-noverbose"); } else { args.push_back("-nopercent"); args.push_back("-loghulls"); + args.push_back("-verbose"); } for (auto &arg : extra_args) { @@ -1576,6 +1582,42 @@ TEST(testmapsQ1, wadExternal) EXPECT_EQ(bsp.dtex.textures[3].data.size(), sizeof(dmiptex_t)); } +TEST(testmapsQ1, looseTextures) +{ + SCOPED_TRACE("loose textures are only loaded when -notex is in use"); + + auto q1_loose_textures_path = std::filesystem::path(testmaps_dir) / "q1_loose_textures"; + + const auto [bsp, bspx, prt] = LoadTestmapQ1("q1_loose_textures.map", + {"-path", q1_loose_textures_path.string(), "-notex"}); + + EXPECT_EQ(GAME_QUAKE, bsp.loadversion->game->id); + + // FIXME: we shouldn't really write out skip + const miptex_t &skip = bsp.dtex.textures[0]; + EXPECT_EQ(skip.name, ""); + EXPECT_TRUE(skip.null_texture); + EXPECT_EQ(skip.width, 0); + EXPECT_EQ(skip.height, 0); + EXPECT_EQ(skip.data.size(), 0); + + const miptex_t &floor_purple_c = bsp.dtex.textures[1]; + EXPECT_EQ(floor_purple_c.name, "floor_purple_c"); + EXPECT_FALSE(floor_purple_c.null_texture); + EXPECT_EQ(floor_purple_c.width, 64); + EXPECT_EQ(floor_purple_c.height, 64); + EXPECT_EQ(floor_purple_c.data.size(), sizeof(dmiptex_t)); + EXPECT_THAT(floor_purple_c.offsets, testing::ElementsAre(0, 0, 0, 0)); + + const miptex_t &wall_tan_a = bsp.dtex.textures[2]; + EXPECT_EQ(wall_tan_a.name, "wall_tan_a"); + EXPECT_FALSE(wall_tan_a.null_texture); + EXPECT_EQ(wall_tan_a.width, 64); + EXPECT_EQ(wall_tan_a.height, 64); + EXPECT_EQ(wall_tan_a.data.size(), sizeof(dmiptex_t)); + EXPECT_THAT(wall_tan_a.offsets, testing::ElementsAre(0, 0, 0, 0)); +} + TEST(testmapsQ1, looseTexturesIgnored) { SCOPED_TRACE("q1 should only load textures from .wad's. loose textures should not be included.");