diff --git a/qbsp/map.cc b/qbsp/map.cc index 1d54cf76..f7bc9aef 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -212,12 +212,21 @@ const std::optional &mapdata_t::load_image_meta(const std::st static std::shared_ptr LoadTexturePath(const fs::path &path) { - if (qbsp_options.wadpaths.pathsValue().empty() || path.is_absolute()) { + // if absolute, don't try anything else + if (path.is_absolute()) { return fs::addArchive(path, false); } + // try wadpath (this includes relative to the .map file) for (auto &wadpath : qbsp_options.wadpaths.pathsValue()) { - return fs::addArchive(wadpath.path / path, wadpath.external); + if (auto archive = fs::addArchive(wadpath.path / path, wadpath.external)) { + return archive; + } + } + + // try relative to cwd + if (auto archive = fs::addArchive(path, false)) { + return archive; } return nullptr; diff --git a/testmaps/q1_cwd_relative_wad.map b/testmaps/q1_cwd_relative_wad.map new file mode 100644 index 00000000..6942c8bb --- /dev/null +++ b/testmaps/q1_cwd_relative_wad.map @@ -0,0 +1,24 @@ +// Game: Quake +// Format: Valve +// entity 0 +{ +"mapversion" "220" +"classname" "worldspawn" +"wad" "gfx/free_wad.wad" +"_wateralpha" "0.5" +"_tb_def" "builtin:Quake.fgd" +// brush 0 +{ +( 32 -256 112 ) ( 32 -255 112 ) ( 32 -256 113 ) orangestuff8 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 1 1 +( 64 -240 96 ) ( 63 -240 96 ) ( 64 -240 97 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 1 1 +( 64 -576 80 ) ( 64 -575 80 ) ( 63 -576 80 ) orangestuff8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 1 1 +( -16 -256 112 ) ( -17 -256 112 ) ( -16 -255 112 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 1 1 +( -16 -144 112 ) ( -16 -144 113 ) ( -17 -144 112 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 1 1 +( 80 -576 96 ) ( 80 -576 97 ) ( 80 -575 96 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 1 1 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "56 -208 136" +} diff --git a/tests/test_qbsp.cc b/tests/test_qbsp.cc index 39e3e02e..9686d430 100644 --- a/tests/test_qbsp.cc +++ b/tests/test_qbsp.cc @@ -1673,3 +1673,34 @@ TEST_CASE("q1_water_subdivision with defaults") CHECK(texinfo->flags.native == 0); } } + +TEST_CASE("textures search relative to current directory") +{ + // QuArK runs the compilers like this: + // + // working directory: "c:\quake\tmpquark" + // command line: "maps\something.map" + // worldspawn key: "wad" "gfx/quark.wad" + // wad located in: "c:\quake\tmpquark\gfx\quark.wad" + + auto target_gfx_dir = fs::current_path() / "gfx"; + + fs::create_directory(target_gfx_dir); + + try { + fs::copy(std::filesystem::path(testmaps_dir) / "deprecated" / "free_wad.wad", target_gfx_dir); + } catch (const fs::filesystem_error &e) { + logging::print("{}\n", e.what()); + } + + const auto [bsp, bspx, prt] = LoadTestmapQ1("q1_cwd_relative_wad.map"); + REQUIRE(2 == bsp.dtex.textures.size()); + // FIXME: we shouldn't really be writing skip + CHECK("skip" == bsp.dtex.textures[0].name); + + // make sure the texture was written + CHECK("orangestuff8" == bsp.dtex.textures[1].name); + CHECK(64 == bsp.dtex.textures[1].width); + CHECK(64 == bsp.dtex.textures[1].height); + CHECK(bsp.dtex.textures[1].data.size() > 0); +}