From a8443ef0cfec10accb3b56438d10817f36a9cc19 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Tue, 23 Jan 2024 21:16:40 -0700 Subject: [PATCH] qbsp: make ALPHATEST imply DETAIL, TRANSLUCENT, and WINDOW (if solid) like the existing logic for TRANS33/TRANS66 --- common/bspfile.cc | 4 ++-- testmaps/q2_alphatest_solid.map | 22 ++++++++++++++++++ testmaps/q2_alphatest_window.map | 22 ++++++++++++++++++ testmaps/q2_trans33_solid.map | 22 ++++++++++++++++++ testmaps/q2_trans33_window.map | 22 ++++++++++++++++++ tests/test_qbsp_q2.cc | 40 ++++++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 testmaps/q2_alphatest_solid.map create mode 100644 testmaps/q2_alphatest_window.map create mode 100644 testmaps/q2_trans33_solid.map create mode 100644 testmaps/q2_trans33_window.map diff --git a/common/bspfile.cc b/common/bspfile.cc index e16b27e8..81028cf1 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -1427,9 +1427,9 @@ struct gamedef_q2_t : public gamedef_t surf_contents.native |= Q2_CONTENTS_SOLID; } - // if we have TRANS33 or TRANS66, we have to be marked as WINDOW, + // if we have TRANS33 or TRANS66 or ALPHATEST, we have to be marked as WINDOW, // so unset SOLID, give us WINDOW, and give us TRANSLUCENT - if (flags.native & (Q2_SURF_TRANS33 | Q2_SURF_TRANS66)) { + if (flags.native & (Q2_SURF_TRANS33 | Q2_SURF_TRANS66 | Q2_SURF_ALPHATEST)) { surf_contents.native |= Q2_CONTENTS_TRANSLUCENT; if (surf_contents.native & Q2_CONTENTS_SOLID) { diff --git a/testmaps/q2_alphatest_solid.map b/testmaps/q2_alphatest_solid.map new file mode 100644 index 00000000..f27b803d --- /dev/null +++ b/testmaps/q2_alphatest_solid.map @@ -0,0 +1,22 @@ +// Game: Quake 2 +// Format: Quake2 +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures/tomc" +// brush 0 +{ +( -48 0 0 ) ( -48 1 0 ) ( -48 0 1 ) tomc/tc_tomb_roots_a -80 -80 0 1 1 0 33554432 0 +( -32 -48 0 ) ( -32 -48 1 ) ( -31 -48 0 ) tomc/tc_tomb_roots_a -80 -80 0 1 1 0 33554432 0 +( -32 0 -16 ) ( -31 0 -16 ) ( -32 1 -16 ) tomc/tc_tomb_roots_a -80 80 0 1 1 0 33554432 0 +( 16 80 16 ) ( 16 81 16 ) ( 17 80 16 ) tomc/tc_tomb_roots_a -80 80 0 1 1 0 33554432 0 +( 16 80 16 ) ( 17 80 16 ) ( 16 80 17 ) tomc/tc_tomb_roots_a -80 -80 0 1 1 0 33554432 0 +( 48 80 16 ) ( 48 80 17 ) ( 48 81 16 ) tomc/tc_tomb_roots_a -80 -80 0 1 1 0 33554432 0 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "8 16 56" +"angle" "90" +} diff --git a/testmaps/q2_alphatest_window.map b/testmaps/q2_alphatest_window.map new file mode 100644 index 00000000..5be66de2 --- /dev/null +++ b/testmaps/q2_alphatest_window.map @@ -0,0 +1,22 @@ +// Game: Quake 2 +// Format: Quake2 +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures/tomc" +// brush 0 +{ +( -48 0 0 ) ( -48 1 0 ) ( -48 0 1 ) tomc/tc_tomb_roots_a -80 -80 0 1 1 2 33554432 0 +( -32 -48 0 ) ( -32 -48 1 ) ( -31 -48 0 ) tomc/tc_tomb_roots_a -80 -80 0 1 1 2 33554432 0 +( -32 0 -16 ) ( -31 0 -16 ) ( -32 1 -16 ) tomc/tc_tomb_roots_a -80 80 0 1 1 2 33554432 0 +( 16 80 16 ) ( 16 81 16 ) ( 17 80 16 ) tomc/tc_tomb_roots_a -80 80 0 1 1 2 33554432 0 +( 16 80 16 ) ( 17 80 16 ) ( 16 80 17 ) tomc/tc_tomb_roots_a -80 -80 0 1 1 2 33554432 0 +( 48 80 16 ) ( 48 80 17 ) ( 48 81 16 ) tomc/tc_tomb_roots_a -80 -80 0 1 1 2 33554432 0 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "8 16 56" +"angle" "90" +} diff --git a/testmaps/q2_trans33_solid.map b/testmaps/q2_trans33_solid.map new file mode 100644 index 00000000..24715647 --- /dev/null +++ b/testmaps/q2_trans33_solid.map @@ -0,0 +1,22 @@ +// Game: Quake 2 +// Format: Quake2 +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures/e1u1" +// brush 0 +{ +( -48 0 0 ) ( -48 1 0 ) ( -48 0 1 ) e1u1/wndow1_1 -80 -80 0 1 1 1 16 0 +( -32 -48 0 ) ( -32 -48 1 ) ( -31 -48 0 ) e1u1/wndow1_1 -80 -80 0 1 1 1 16 0 +( -32 0 -16 ) ( -31 0 -16 ) ( -32 1 -16 ) e1u1/wndow1_1 -80 80 0 1 1 1 16 0 +( 16 80 16 ) ( 16 81 16 ) ( 17 80 16 ) e1u1/wndow1_1 -80 80 0 1 1 1 16 0 +( 16 80 16 ) ( 17 80 16 ) ( 16 80 17 ) e1u1/wndow1_1 -80 -80 0 1 1 1 16 0 +( 48 80 16 ) ( 48 80 17 ) ( 48 81 16 ) e1u1/wndow1_1 -80 -80 0 1 1 1 16 0 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "8 16 56" +"angle" "90" +} diff --git a/testmaps/q2_trans33_window.map b/testmaps/q2_trans33_window.map new file mode 100644 index 00000000..936b87b2 --- /dev/null +++ b/testmaps/q2_trans33_window.map @@ -0,0 +1,22 @@ +// Game: Quake 2 +// Format: Quake2 +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures/e1u1" +// brush 0 +{ +( -48 0 0 ) ( -48 1 0 ) ( -48 0 1 ) e1u1/wndow1_1 -80 -80 0 1 1 2 16 0 +( -32 -48 0 ) ( -32 -48 1 ) ( -31 -48 0 ) e1u1/wndow1_1 -80 -80 0 1 1 2 16 0 +( -32 0 -16 ) ( -31 0 -16 ) ( -32 1 -16 ) e1u1/wndow1_1 -80 80 0 1 1 2 16 0 +( 16 80 16 ) ( 16 81 16 ) ( 17 80 16 ) e1u1/wndow1_1 -80 80 0 1 1 2 16 0 +( 16 80 16 ) ( 17 80 16 ) ( 16 80 17 ) e1u1/wndow1_1 -80 -80 0 1 1 2 16 0 +( 48 80 16 ) ( 48 80 17 ) ( 48 81 16 ) e1u1/wndow1_1 -80 -80 0 1 1 2 16 0 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "8 16 56" +"angle" "90" +} diff --git a/tests/test_qbsp_q2.cc b/tests/test_qbsp_q2.cc index f1327c0d..13cc85c9 100644 --- a/tests/test_qbsp_q2.cc +++ b/tests/test_qbsp_q2.cc @@ -632,6 +632,46 @@ TEST_CASE("q2_mirrorinside" * doctest::test_suite("testmaps_q2")) } } +TEST_CASE("q2_alphatest_window" * doctest::test_suite("testmaps_q2")) +{ + const auto [bsp, bspx, prt] = LoadTestmapQ2("q2_alphatest_window.map"); + + INFO("alphatest + window implies detail and translucent"); + auto *leaf = BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], {0, 0, 0}); + + CHECK(leaf->contents == (Q2_CONTENTS_DETAIL | Q2_CONTENTS_WINDOW | Q2_CONTENTS_TRANSLUCENT)); +} + +TEST_CASE("q2_alphatest_solid" * doctest::test_suite("testmaps_q2")) +{ + const auto [bsp, bspx, prt] = LoadTestmapQ2("q2_alphatest_solid.map"); + + INFO("alphatest + solid implies window, detail and translucent"); + auto *leaf = BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], {0, 0, 0}); + + CHECK(leaf->contents == (Q2_CONTENTS_DETAIL | Q2_CONTENTS_WINDOW | Q2_CONTENTS_TRANSLUCENT)); +} + +TEST_CASE("q2_trans33_window" * doctest::test_suite("testmaps_q2")) +{ + const auto [bsp, bspx, prt] = LoadTestmapQ2("q2_trans33_window.map"); + + INFO("trans33 + window implies detail and translucent"); + auto *leaf = BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], {0, 0, 0}); + + CHECK(leaf->contents == (Q2_CONTENTS_DETAIL | Q2_CONTENTS_WINDOW | Q2_CONTENTS_TRANSLUCENT)); +} + +TEST_CASE("q2_trans33_solid" * doctest::test_suite("testmaps_q2")) +{ + const auto [bsp, bspx, prt] = LoadTestmapQ2("q2_trans33_solid.map"); + + INFO("trans33 + solid implies window, detail and translucent"); + auto *leaf = BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], {0, 0, 0}); + + CHECK(leaf->contents == (Q2_CONTENTS_DETAIL | Q2_CONTENTS_WINDOW | Q2_CONTENTS_TRANSLUCENT)); +} + /** * Ensure that leaked maps still get areas assigned properly * (empty leafs should get area 1, solid leafs area 0)