Skip to content

Commit

Permalink
Merge branch 'brushbsp' of https://github.com/ericwa/ericw-tools into…
Browse files Browse the repository at this point in the history
… brushbsp
  • Loading branch information
Paril committed Aug 26, 2024
2 parents 2b700f0 + 7389adf commit 6c9b681
Show file tree
Hide file tree
Showing 42 changed files with 5,099 additions and 3,314 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/continuous-building.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
matrix:
os:
- ubuntu-22.04
- ubuntu-24.04
- macos-12
- windows-2022
use-asan:
Expand All @@ -33,6 +34,11 @@ jobs:
run: |
sudo apt update
sudo apt install qtbase5-dev libqt5svg5-dev
- name: 'Linux: Install TBB and Embree, if using distro packages'
if: ${{ matrix.os == 'ubuntu-24.04' }}
run: |
sudo apt install libtbb-dev libembree-dev
echo "USE_SYSTEM_TBB_AND_EMBREE=1" >> $GITHUB_ENV
- name: 'Linux: Build the artifact'
if: startsWith(matrix.os, 'ubuntu-')
run: ./build-linux-64.sh
Expand All @@ -42,15 +48,15 @@ jobs:
mkdir ericw-tools-linux
unzip build-linux/*-Linux.zip -d ericw-tools-linux
- name: 'Linux: Upload the artifact'
if: ${{ startsWith(matrix.os, 'ubuntu-') && matrix.use-asan == 'NO' }}
if: ${{ matrix.os == 'ubuntu-22.04' && matrix.use-asan == 'NO' }}
uses: actions/upload-artifact@v4
with:
path: ericw-tools-linux/
name: ericw-tools-${{ github.sha }}-linux
if-no-files-found: error
- name: 'Linux: Create GitHub Release and upload build'
uses: softprops/action-gh-release@v1
if: ${{ startsWith(matrix.os, 'ubuntu-') && matrix.use-asan == 'NO' && startsWith(github.ref, 'refs/tags/') }}
if: ${{ matrix.os == 'ubuntu-22.04' && matrix.use-asan == 'NO' && startsWith(github.ref, 'refs/tags/') }}
with:
draft: true
files: |
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,3 @@
[submodule "3rdparty/pareto"]
path = 3rdparty/pareto
url = https://github.com/alandefreitas/pareto.git
[submodule "3rdparty/doctest"]
path = 3rdparty/doctest
url = https://github.com/doctest/doctest
11 changes: 10 additions & 1 deletion 3rdparty/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
add_subdirectory(fmt EXCLUDE_FROM_ALL)
add_subdirectory(doctest EXCLUDE_FROM_ALL)
add_subdirectory(json EXCLUDE_FROM_ALL)
add_subdirectory(nanobench EXCLUDE_FROM_ALL)

set(BUILD_WITH_PEDANTIC_WARNINGS OFF CACHE BOOL "prevent pareto from adding /WX" FORCE)
add_subdirectory(pareto EXCLUDE_FROM_ALL)

include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 # v1.14.0
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
1 change: 0 additions & 1 deletion 3rdparty/doctest
Submodule doctest deleted from b7c21e
151 changes: 50 additions & 101 deletions bsputil/bsputil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
See file, 'COPYING', for details.
*/

#include <bsputil/bsputil.hh>

#include <cstdint>

#ifndef _WIN32
Expand All @@ -42,93 +44,41 @@
#include <fstream>
#include <fmt/ostream.h>

// special type of setting that combines multiple
// settings. just for the casting capability of bsputil_settings.
class setting_combined : public settings::setting_base
{
protected:
std::vector<std::shared_ptr<settings::setting_base>> _settings;

public:
setting_combined(settings::setting_container *dictionary, const settings::nameset &names, std::initializer_list<std::shared_ptr<settings::setting_base>> settings,
const settings::setting_group *group = nullptr, const char *description = "")
: setting_base(dictionary, names, group, description),
_settings(settings)
{
}
bool copy_from(const setting_base &other) override
{
throw std::runtime_error("not implemented");
}
void reset() override
{
throw std::runtime_error("not implemented");
}
bool parse(const std::string &setting_name, parser_base_t &parser, settings::source source) override
{
throw std::runtime_error("not implemented");
}
std::string string_value() const override
{
throw std::runtime_error("not implemented");
}
std::string format() const override
{
throw std::runtime_error("not implemented");
}
// bsputil_settings

template<typename TSetting>
const TSetting *get(size_t index) const
{
return dynamic_cast<const TSetting *>(_settings[index].get());
}
};

struct bsputil_settings : public settings::common_settings
bool bsputil_settings::load_setting(const std::string &name, settings::source src)
{
private:
template<typename TSetting, typename...TArgs>
bool load_setting(const std::string &name, parser_base_t &parser, settings::source src, TArgs&& ...setting_arguments)
{
auto setting = std::make_unique<TSetting>(nullptr, name, std::forward<TArgs>(setting_arguments)...);
bool parsed = setting->parse(name, parser, src);
operations.push_back(std::move(setting));
return parsed;
}

bool load_setting(const std::string &name, settings::source src)
{
auto setting = std::make_unique<settings::setting_func>(nullptr, name, nullptr);
operations.push_back(std::move(setting));
return true;
}
auto setting = std::make_unique<settings::setting_func>(nullptr, name, nullptr);
operations.push_back(std::move(setting));
return true;
}

public:
settings::setting_func scale{this, "scale", [&](const std::string &name, parser_base_t &parser, settings::source src) {
bsputil_settings::bsputil_settings() :
scale{this, "scale", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_vec3>(name, parser, src, 0.f, 0.f, 0.f);
}, nullptr, "Scale the BSP by the given scalar vectors (can be negative, too)"};
settings::setting_func replace_entities{this, "replace-entities", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Scale the BSP by the given scalar vectors (can be negative, too)"},
replace_entities{this, "replace-entities", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_string>(name, parser, src, "");
}, nullptr, "Replace BSP entities with the given files' contents"};
settings::setting_func extract_entities{this, "extract-entities", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Replace BSP entities with the given files' contents"},
extract_entities{this, "extract-entities", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_bool>(name, parser, src, "");
}, nullptr, "Extract BSP entities to the given file name"},
extract_textures{this, "extract-textures", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_bool>(name, parser, src, "");
}, nullptr, "Extract BSP texutres to the given wad file"},
replace_textures{this, "replace-textures", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_string>(name, parser, src, "");
}, nullptr, "Extract BSP entities to the given file name"};
settings::setting_func extract_textures{this, "extract-textures", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Replace BSP textures with the given wads' contents"},
convert{this, "convert", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_string>(name, parser, src, "");
}, nullptr, "Extract BSP texutres to the given wad file"};
settings::setting_func replace_textures{this, "replace-textures", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_string>(name, parser, src, "");
}, nullptr, "Replace BSP textures with the given wads' contents"};
settings::setting_func convert{this, "convert", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_string>(name, parser, src, "");
}, nullptr, "Convert the BSP file to a different BSP format"};
settings::setting_func check{this, "check", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Convert the BSP file to a different BSP format"},
check{this, "check", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting(name, src);
}, nullptr, "Check/verify BSP data"};
settings::setting_func modelinfo{this, "modelinfo", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Check/verify BSP data"},
modelinfo{this, "modelinfo", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting(name, src);
}, nullptr, "Print model info"};
settings::setting_func findfaces{this, "findfaces", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Print model info"},
findfaces{this, "findfaces", [&](const std::string &name, parser_base_t &parser, settings::source src) {
auto pos = std::make_shared<settings::setting_vec3>(nullptr, name, 0.f, 0.f, 0.f);
if (bool parsed = pos->parse(name, parser, src); !parsed)
return false;
Expand All @@ -137,11 +87,11 @@ struct bsputil_settings : public settings::common_settings
return false;
operations.push_back(std::make_unique<setting_combined>(nullptr, name, std::initializer_list<std::shared_ptr<settings::setting_base>> { pos, norm }));
return true;
}, nullptr, "Find faces with specified pos/normal"};
settings::setting_func findleaf{this, "findleaf", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Find faces with specified pos/normal"},
findleaf{this, "findleaf", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_vec3>(name, parser, src, 0.f, 0.f, 0.f);
}, nullptr, "Find closest leaf"};
settings::setting_func settexinfo{this, "settexinfo", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Find closest leaf"},
settexinfo{this, "settexinfo", [&](const std::string &name, parser_base_t &parser, settings::source src) {
auto faceNum = std::make_shared<settings::setting_int32>(nullptr, name, 0);
if (bool parsed = faceNum->parse(name, parser, src); !parsed)
return false;
Expand All @@ -150,20 +100,20 @@ struct bsputil_settings : public settings::common_settings
return false;
operations.push_back(std::make_unique<setting_combined>(nullptr, name, std::initializer_list<std::shared_ptr<settings::setting_base>> { faceNum, texInfoNum }));
return true;
}, nullptr, "Set texinfo"};
settings::setting_func decompile{this, "decompile", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Set texinfo"},
decompile{this, "decompile", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting(name, src);
}, nullptr, "Decompile to the given .map file"};
settings::setting_func decompile_geomonly{this, "decompile-geomonly", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Decompile to the given .map file"},
decompile_geomonly{this, "decompile-geomonly", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting(name, src);
}, nullptr, "Decompile"};
settings::setting_func decompile_ignore_brushes{this, "decompile-ignore-brushes", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Decompile"},
decompile_ignore_brushes{this, "decompile-ignore-brushes", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting(name, src);
}, nullptr, "Decompile entities only"};
settings::setting_func decompile_hull{this, "decompile-hull", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Decompile entities only"},
decompile_hull{this, "decompile-hull", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_int32>(name, parser, src, 0);
}, nullptr, "Decompile specific hull"};
settings::setting_func extract_bspx_lump{this, "extract-bspx-lump", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Decompile specific hull"},
extract_bspx_lump{this, "extract-bspx-lump", [&](const std::string &name, parser_base_t &parser, settings::source src) {
auto lump = std::make_shared<settings::setting_string>(nullptr, name, "");
if (bool parsed = lump->parse(name, parser, src); !parsed)
return false;
Expand All @@ -172,8 +122,8 @@ struct bsputil_settings : public settings::common_settings
return false;
operations.push_back(std::make_unique<setting_combined>(nullptr, name, std::initializer_list<std::shared_ptr<settings::setting_base>> { lump, output }));
return true;
}, nullptr, "Extract a BSPX lump"};
settings::setting_func insert_bspx_lump{this, "insert-bspx-lump", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Extract a BSPX lump"},
insert_bspx_lump{this, "insert-bspx-lump", [&](const std::string &name, parser_base_t &parser, settings::source src) {
auto lump = std::make_shared<settings::setting_string>(nullptr, name, "");
if (bool parsed = lump->parse(name, parser, src); !parsed)
return false;
Expand All @@ -182,16 +132,15 @@ struct bsputil_settings : public settings::common_settings
return false;
operations.push_back(std::make_unique<setting_combined>(nullptr, name, std::initializer_list<std::shared_ptr<settings::setting_base>> { lump, input }));
return true;
}, nullptr, "Insert a BSPX lump"};
settings::setting_func remove_bspx_lump{this, "remove-bspx-lump", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Insert a BSPX lump"},
remove_bspx_lump{this, "remove-bspx-lump", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_string>(name, parser, src, "");
}, nullptr, "Remove a BSPX lump"};
settings::setting_func svg{this, "svg", [&](const std::string &name, parser_base_t &parser, settings::source src) {
}, nullptr, "Remove a BSPX lump"},
svg{this, "svg", [&](const std::string &name, parser_base_t &parser, settings::source src) {
return this->load_setting<settings::setting_int32>(name, parser, src, 0);
}, nullptr, "Create an SVG view of the input BSP"};
}, nullptr, "Create an SVG view of the input BSP"}
{}

std::vector<std::unique_ptr<settings::setting_base>> operations;
};

bsputil_settings bsputil_options;

Expand Down
2 changes: 1 addition & 1 deletion build-appveyor.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ if ( $? -eq $false ) {
throw "package failed"
}

.\tests\Release\tests.exe --no-skip
.\tests\Release\tests.exe

if ( $? -eq $false ) {
throw "tests failed"
Expand Down
37 changes: 21 additions & 16 deletions build-linux-64.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,29 @@ cmake --version

mkdir "$BUILD_DIR"
cd "$BUILD_DIR"
wget -q https://github.com/embree/embree/releases/download/v3.13.1/embree-3.13.1.x86_64.linux.tar.gz -O embree.tgz
wget -q https://github.com/oneapi-src/oneTBB/releases/download/v2021.3.0/oneapi-tbb-2021.3.0-lin.tgz -O tbb.tgz

tar xf embree.tgz
tar xf tbb.tgz
if [ "$USE_SYSTEM_TBB_AND_EMBREE" == "1" ]; then
if [ "$USE_ASAN" == "YES" ]; then
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DERICWTOOLS_ASAN=YES -DSKIP_EMBREE_INSTALL=YES -DSKIP_TBB_INSTALL=YES
else
cmake .. -DCMAKE_BUILD_TYPE=Release -DSKIP_EMBREE_INSTALL=YES -DSKIP_TBB_INSTALL=YES
fi
else
wget -q https://github.com/embree/embree/releases/download/v3.13.1/embree-3.13.1.x86_64.linux.tar.gz -O embree.tgz
wget -q https://github.com/oneapi-src/oneTBB/releases/download/v2021.3.0/oneapi-tbb-2021.3.0-lin.tgz -O tbb.tgz

EMBREE_CMAKE_DIR="$(pwd)/embree-3.13.1.x86_64.linux/lib/cmake/embree-3.13.1"
TBB_CMAKE_DIR="$(pwd)/oneapi-tbb-2021.3.0/lib/cmake"
tar xf embree.tgz
tar xf tbb.tgz

# check USE_ASAN environment variable (see cmake.yml)
if [ "$USE_ASAN" == "YES" ]; then
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH="$EMBREE_CMAKE_DIR;$TBB_CMAKE_DIR" -DENABLE_LIGHTPREVIEW=YES -DERICWTOOLS_ASAN=YES
else
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$EMBREE_CMAKE_DIR;$TBB_CMAKE_DIR"
EMBREE_CMAKE_DIR="$(pwd)/embree-3.13.1.x86_64.linux/lib/cmake/embree-3.13.1"
TBB_CMAKE_DIR="$(pwd)/oneapi-tbb-2021.3.0/lib/cmake"

# check USE_ASAN environment variable (see cmake.yml)
if [ "$USE_ASAN" == "YES" ]; then
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_PREFIX_PATH="$EMBREE_CMAKE_DIR;$TBB_CMAKE_DIR" -DENABLE_LIGHTPREVIEW=YES -DERICWTOOLS_ASAN=YES
else
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$EMBREE_CMAKE_DIR;$TBB_CMAKE_DIR"
fi
fi

# not yet free of memory leaks, so don't abort on leak detection
Expand All @@ -36,11 +45,7 @@ export ASAN_OPTIONS=detect_leaks=false
make -j8 VERBOSE=1 package || exit 1

# run tests
if [ "$USE_ASAN" != "YES" ]; then
./tests/tests --no-skip || exit 1 # run hidden tests (releaseonly)
else
./tests/tests || exit 1
fi
./tests/tests || exit 1

# check rpath
readelf -d ./light/light
6 changes: 1 addition & 5 deletions build-osx.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,4 @@ otool -L ./bspinfo/bspinfo
otool -L ./bsputil/bsputil

# run tests
if [ "$USE_ASAN" != "YES" ]; then
./tests/tests --no-skip || exit 1 # run hidden tests (releaseonly)
else
./tests/tests || exit 1
fi
./tests/tests || exit 1
2 changes: 1 addition & 1 deletion build-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if ( $? -eq $false ) {
throw "build failed"
}

.\tests\tests.exe --no-skip
.\tests\tests.exe

if ( $? -eq $false ) {
throw "tests failed"
Expand Down
2 changes: 2 additions & 0 deletions common/bspfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,7 @@ struct gamedef_q2_t : public gamedef_t
if (native & Q2_CONTENTS_MONSTERCLIP) result |= EWT_INVISCONTENTS_MONSTERCLIP;
if (native & Q2_CONTENTS_PROJECTILECLIP) result |= EWT_INVISCONTENTS_PROJECTILECLIP;
if (native & Q2_CONTENTS_ORIGIN) result |= EWT_INVISCONTENTS_ORIGIN;
if (native & Q2_CONTENTS_NO_WATERJUMP) result |= EWT_INVISCONTENTS_NO_WATERJUMP;

// contents flags
if (native & Q2_CONTENTS_CURRENT_0) result |= EWT_CFLAG_CURRENT_0;
Expand Down Expand Up @@ -908,6 +909,7 @@ struct gamedef_q2_t : public gamedef_t
if (contents.flags & EWT_VISCONTENTS_WATER) result |= Q2_CONTENTS_WATER;
if (contents.flags & EWT_VISCONTENTS_MIST) result |= Q2_CONTENTS_MIST;
if (contents.flags & EWT_INVISCONTENTS_ORIGIN) result |= Q2_CONTENTS_ORIGIN;
if (contents.flags & EWT_INVISCONTENTS_NO_WATERJUMP) result |= Q2_CONTENTS_NO_WATERJUMP;
if (contents.flags & EWT_INVISCONTENTS_PLAYERCLIP) result |= Q2_CONTENTS_PLAYERCLIP;
if (contents.flags & EWT_INVISCONTENTS_MONSTERCLIP) result |= Q2_CONTENTS_MONSTERCLIP;
if (contents.flags & EWT_INVISCONTENTS_PROJECTILECLIP) result |= Q2_CONTENTS_PROJECTILECLIP;
Expand Down
6 changes: 3 additions & 3 deletions common/bsputils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1099,10 +1099,10 @@ static int StyleOffset(int style, const mface_t *face, const faceextents_t &face
}

/**
* Samples the lightmap at an integer coordinate in style 0
* Samples the lightmap at an integer coordinate in the given style
*/
qvec3b LM_Sample(const mbsp_t *bsp, const mface_t *face, const lit_variant_t *lit, const faceextents_t &faceextents,
int byte_offset_of_face, qvec2i coord)
int byte_offset_of_face, qvec2i coord, int style)
{
if (byte_offset_of_face == -1) {
return {0, 0, 0};
Expand All @@ -1113,7 +1113,7 @@ qvec3b LM_Sample(const mbsp_t *bsp, const mface_t *face, const lit_variant_t *li
Q_assert(coord[0] < faceextents.width());
Q_assert(coord[1] < faceextents.height());

int style_offset = StyleOffset(0, face, faceextents);
int style_offset = StyleOffset(style, face, faceextents);
if (style_offset == -1) {
return {0, 0, 0};
}
Expand Down
Loading

0 comments on commit 6c9b681

Please sign in to comment.