diff --git a/testmaps/q1_light_black.map b/testmaps/q1_light_black.map new file mode 100644 index 00000000..c5e0f0ca --- /dev/null +++ b/testmaps/q1_light_black.map @@ -0,0 +1,92 @@ +// Game: Quake +// Format: Standard +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures/e1u1" +"_bounce" "0" +"wad" "deprecated/free_wad.wad" +// brush 0 +{ +( 480 1088 928 ) ( 480 1089 928 ) ( 480 1088 929 ) bolt14 0 32 0 1 1 +( 704 1088 928 ) ( 704 1088 929 ) ( 705 1088 928 ) bolt14 0 32 0 1 1 +( 704 1088 928 ) ( 705 1088 928 ) ( 704 1089 928 ) bolt14 0 0 0 1 1 +( 944 1472 944 ) ( 944 1473 944 ) ( 945 1472 944 ) bolt14 0 0 0 1 1 +( 944 1488 944 ) ( 945 1488 944 ) ( 944 1488 945 ) bolt14 0 32 0 1 1 +( 1056 1472 944 ) ( 1056 1472 945 ) ( 1056 1473 944 ) bolt14 0 32 0 1 1 +} +// brush 1 +{ +( 480 1088 1248 ) ( 480 1089 1248 ) ( 480 1088 1249 ) bolt14 0 96 0 1 1 +( 704 1072 1248 ) ( 704 1072 1249 ) ( 705 1072 1248 ) bolt14 0 96 0 1 1 +( 704 1088 1248 ) ( 705 1088 1248 ) ( 704 1089 1248 ) bolt14 0 0 0 1 1 +( 944 1472 1264 ) ( 944 1473 1264 ) ( 945 1472 1264 ) bolt14 0 0 0 1 1 +( 944 1488 1264 ) ( 945 1488 1264 ) ( 944 1488 1265 ) bolt14 0 96 0 1 1 +( 1056 1472 1264 ) ( 1056 1472 1265 ) ( 1056 1473 1264 ) bolt14 0 96 0 1 1 +} +// brush 2 +{ +( 480 1072 928 ) ( 480 1073 928 ) ( 480 1072 929 ) bolt14 16 32 0 1 1 +( 704 1072 928 ) ( 704 1072 929 ) ( 705 1072 928 ) bolt14 0 32 0 1 1 +( 704 1072 928 ) ( 705 1072 928 ) ( 704 1073 928 ) bolt14 0 -16 0 1 1 +( 944 1456 1248 ) ( 944 1457 1248 ) ( 945 1456 1248 ) bolt14 0 -16 0 1 1 +( 944 1088 944 ) ( 945 1088 944 ) ( 944 1088 945 ) bolt14 0 32 0 1 1 +( 1056 1456 944 ) ( 1056 1456 945 ) ( 1056 1457 944 ) bolt14 16 32 0 1 1 +} +// brush 3 +{ +( 480 1392 928 ) ( 480 1393 928 ) ( 480 1392 929 ) bolt14 -48 32 0 1 1 +( 832 1488 928 ) ( 832 1488 929 ) ( 833 1488 928 ) bolt14 -128 32 0 1 1 +( 832 1392 928 ) ( 833 1392 928 ) ( 832 1393 928 ) bolt14 -128 48 0 1 1 +( 1072 1776 1248 ) ( 1072 1777 1248 ) ( 1073 1776 1248 ) bolt14 -128 48 0 1 1 +( 1072 1504 944 ) ( 1073 1504 944 ) ( 1072 1504 945 ) bolt14 -128 32 0 1 1 +( 1056 1392 928 ) ( 1056 1392 929 ) ( 1056 1393 928 ) bolt14 -48 32 0 1 1 +} +// brush 4 +{ +( 1056 1088 1056 ) ( 1056 1089 1056 ) ( 1056 1088 1057 ) bolt14 0 32 0 1 1 +( 736 1088 1056 ) ( 736 1088 1057 ) ( 737 1088 1056 ) bolt14 -32 32 0 1 1 +( 736 1088 928 ) ( 737 1088 928 ) ( 736 1089 928 ) bolt14 -32 0 0 1 1 +( 976 1472 1248 ) ( 976 1473 1248 ) ( 977 1472 1248 ) bolt14 -32 0 0 1 1 +( 976 1488 1072 ) ( 977 1488 1072 ) ( 976 1488 1073 ) bolt14 -32 32 0 1 1 +( 1072 1472 1072 ) ( 1072 1472 1073 ) ( 1072 1473 1072 ) bolt14 0 32 0 1 1 +} +// brush 5 +{ +( 464 1088 1056 ) ( 464 1089 1056 ) ( 464 1088 1057 ) bolt14 0 32 0 1 1 +( 144 1072 1056 ) ( 144 1072 1057 ) ( 145 1072 1056 ) bolt14 48 32 0 1 1 +( 144 1088 928 ) ( 145 1088 928 ) ( 144 1089 928 ) bolt14 48 0 0 1 1 +( 384 1472 1248 ) ( 384 1473 1248 ) ( 385 1472 1248 ) bolt14 48 0 0 1 1 +( 384 1488 1072 ) ( 385 1488 1072 ) ( 384 1488 1073 ) bolt14 48 32 0 1 1 +( 480 1472 1072 ) ( 480 1472 1073 ) ( 480 1473 1072 ) bolt14 0 32 0 1 1 +} +// brush 6 +{ +( 480 1216 944 ) ( 480 1217 944 ) ( 480 1216 945 ) *swater4 0 0 0 1 1 +( 544 1088 944 ) ( 544 1088 945 ) ( 545 1088 944 ) *swater4 0 0 0 1 1 +( 544 1216 944 ) ( 545 1216 944 ) ( 544 1217 944 ) *swater4 0 0 0 1 1 +( 608 1312 976 ) ( 608 1313 976 ) ( 609 1312 976 ) *swater4 0 0 0 1 1 +( 608 1488 960 ) ( 609 1488 960 ) ( 608 1488 961 ) *swater4 0 0 0 1 1 +( 608 1312 960 ) ( 608 1312 961 ) ( 608 1313 960 ) *swater4 0 0 0 1 1 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "976 1408 968" +"angle" "180" +} +// entity 2 +{ +"classname" "light" +"origin" "600 1288 1112" +"light" "1000" +"angle" "30" +"target" "s1" +} +// entity 3 +{ +"classname" "info_null" +"origin" "484 1284 1116" +"targetname" "s1" +} diff --git a/tests/test_ltface.cc b/tests/test_ltface.cc index 6dbe6ae9..3f3fb96c 100644 --- a/tests/test_ltface.cc +++ b/tests/test_ltface.cc @@ -892,3 +892,45 @@ TEST_CASE("q2_light_black") CheckFaceLuxelAtPoint(&bsp, &bsp.dmodels[0], {0, 0, 0}, point, {-1, 0, 0}); } + +TEST_CASE("q1_light_black") +{ + auto [bsp, bspx, lit] = QbspVisLight_Q1("q1_light_black.map", {"-lit"}); + + { + const qvec3d point{1056, 1300, 972}; + + INFO("ensure completely black lightmaps are written out as style 255 / lightofs -1 in Q1 mode"); + + const mface_t *face = BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[0], point, {-1, 0, 0}); + REQUIRE(face); + CHECK(face->styles[0] == 255); + CHECK(face->styles[1] == 255); + CHECK(face->styles[2] == 255); + CHECK(face->styles[3] == 255); + CHECK(face->lightofs == -1); + + // this is consistent with original tools, see: + // https://github.com/id-Software/Quake-Tools/blob/master/qutils/LIGHT/LTFACE.C#L542 + } + { + INFO("ensure lit water receiving no light is also written out as style 255 / lightofs -1"); + + const qvec3d point{568, 1288, 976}; + + const mface_t *face = BSP_FindFaceAtPoint(&bsp, &bsp.dmodels[0], point, {0, 0, 1}); + REQUIRE(face); + auto *texinfo = Face_Texinfo(&bsp, face); + REQUIRE(texinfo); + + CHECK(texinfo->flags.native == 0); // i.e. TEX_SPECIAL is not set because it's lit water + CHECK(face->styles[0] == 255); + CHECK(face->styles[1] == 255); + CHECK(face->styles[2] == 255); + CHECK(face->styles[3] == 255); + CHECK(face->lightofs == -1); + + // Note, this liquid face is rendering as fullbright (incorrect) in: QS 0.96.0 and Ironwail 0.7.0 + // and rendering as solid black (correct) in vkQuake 1.30.1, FTEQW Mar 1 2022 + } +}