From 09a8e3527b3aa95ed37c2070ad86c56ce19ed4e0 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sat, 8 Feb 2025 16:21:40 -0500 Subject: [PATCH 1/8] c: change a typedef and some enum constants to be properly namespaced --- lang/c/include/sourceppc/Helpers.h | 4 ++-- lang/c/include/steamppc/steampp.h | 24 ++++++++++++------------ lang/c/include/vpkppc/Options.h | 14 +++++++------- lang/c/src/vpkppc/format/ZIP.cpp | 6 +++--- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lang/c/include/sourceppc/Helpers.h b/lang/c/include/sourceppc/Helpers.h index 9331f5412..d8245d043 100644 --- a/lang/c/include/sourceppc/Helpers.h +++ b/lang/c/include/sourceppc/Helpers.h @@ -2,14 +2,14 @@ #define SOURCEPP_EARLY_RETURN(var) \ do { \ - if (!var) { \ + if (!(var)) { \ return; \ } \ } while (0) #define SOURCEPP_EARLY_RETURN_VAL(var, value) \ do { \ - if (!var) { \ + if (!(var)) { \ return value; \ } \ } while (0) diff --git a/lang/c/include/steamppc/steampp.h b/lang/c/include/steamppc/steampp.h index 5d183ec87..562ab48f6 100644 --- a/lang/c/include/steamppc/steampp.h +++ b/lang/c/include/steamppc/steampp.h @@ -7,7 +7,7 @@ extern "C" { #endif -typedef uint32_t AppID; +typedef uint32_t steampp_appid_t; typedef void* steampp_steam_handle_t; @@ -28,31 +28,31 @@ SOURCEPP_API sourcepp_string_array_t steampp_get_library_dirs(steampp_steam_hand // REQUIRES MANUAL FREE: sourcepp_string_free SOURCEPP_API sourcepp_string_t steampp_get_sourcemod_dir(steampp_steam_handle_t handle); -SOURCEPP_API size_t steampp_get_installed_apps(steampp_steam_handle_t handle, AppID* array, size_t arrayLen); +SOURCEPP_API size_t steampp_get_installed_apps(steampp_steam_handle_t handle, steampp_appid_t* array, size_t arrayLen); SOURCEPP_API size_t steampp_get_installed_apps_count(steampp_steam_handle_t handle); -SOURCEPP_API bool steampp_is_app_installed(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API bool steampp_is_app_installed(steampp_steam_handle_t handle, steampp_appid_t appID); -SOURCEPP_API const char* steampp_get_app_name(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API const char* steampp_get_app_name(steampp_steam_handle_t handle, steampp_appid_t appID); // REQUIRES MANUAL FREE: sourcepp_string_free -SOURCEPP_API sourcepp_string_t steampp_get_app_install_dir(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API sourcepp_string_t steampp_get_app_install_dir(steampp_steam_handle_t handle, steampp_appid_t appID); // REQUIRES MANUAL FREE: sourcepp_string_free -SOURCEPP_API sourcepp_string_t steampp_get_app_icon_path(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API sourcepp_string_t steampp_get_app_icon_path(steampp_steam_handle_t handle, steampp_appid_t appID); // REQUIRES MANUAL FREE: sourcepp_string_free -SOURCEPP_API sourcepp_string_t steampp_get_app_logo_path(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API sourcepp_string_t steampp_get_app_logo_path(steampp_steam_handle_t handle, steampp_appid_t appID); // REQUIRES MANUAL FREE: sourcepp_string_free -SOURCEPP_API sourcepp_string_t steampp_get_app_box_art_path(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API sourcepp_string_t steampp_get_app_box_art_path(steampp_steam_handle_t handle, steampp_appid_t appID); // REQUIRES MANUAL FREE: sourcepp_string_free -SOURCEPP_API sourcepp_string_t steampp_get_app_store_art_path(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API sourcepp_string_t steampp_get_app_store_art_path(steampp_steam_handle_t handle, steampp_appid_t appID); -SOURCEPP_API bool steampp_is_app_using_goldsrc_engine(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API bool steampp_is_app_using_goldsrc_engine(steampp_steam_handle_t handle, steampp_appid_t appID); -SOURCEPP_API bool steampp_is_app_using_source_engine(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API bool steampp_is_app_using_source_engine(steampp_steam_handle_t handle, steampp_appid_t appID); -SOURCEPP_API bool steampp_is_app_using_source_2_engine(steampp_steam_handle_t handle, AppID appID); +SOURCEPP_API bool steampp_is_app_using_source_2_engine(steampp_steam_handle_t handle, steampp_appid_t appID); diff --git a/lang/c/include/vpkppc/Options.h b/lang/c/include/vpkppc/Options.h index 1571273a9..8611c7acb 100644 --- a/lang/c/include/vpkppc/Options.h +++ b/lang/c/include/vpkppc/Options.h @@ -7,13 +7,13 @@ extern "C" { #endif typedef enum { - ENTRY_COMPRESSION_TYPE_NO_OVERRIDE = -1, - ENTRY_COMPRESSION_TYPE_NO_COMPRESS = 0, - ENTRY_COMPRESSION_TYPE_DEFLATE = 8, - ENTRY_COMPRESSION_TYPE_BZIP2 = 12, - ENTRY_COMPRESSION_TYPE_LZMA = 14, - ENTRY_COMPRESSION_TYPE_ZSTD = 93, - ENTRY_COMPRESSION_TYPE_XZ = 95, + VPKPP_ENTRY_COMPRESSION_TYPE_NO_OVERRIDE = -1, + VPKPP_ENTRY_COMPRESSION_TYPE_NO_COMPRESS = 0, + VPKPP_ENTRY_COMPRESSION_TYPE_DEFLATE = 8, + VPKPP_ENTRY_COMPRESSION_TYPE_BZIP2 = 12, + VPKPP_ENTRY_COMPRESSION_TYPE_LZMA = 14, + VPKPP_ENTRY_COMPRESSION_TYPE_ZSTD = 93, + VPKPP_ENTRY_COMPRESSION_TYPE_XZ = 95, } vpkpp_entry_compression_type_e; typedef struct { diff --git a/lang/c/src/vpkppc/format/ZIP.cpp b/lang/c/src/vpkppc/format/ZIP.cpp index cbdd73905..cbfd4a9c6 100644 --- a/lang/c/src/vpkppc/format/ZIP.cpp +++ b/lang/c/src/vpkppc/format/ZIP.cpp @@ -38,11 +38,11 @@ SOURCEPP_API sourcepp_string_t vpkpp_zip_guid(vpkpp_pack_file_handle_t handle) { } SOURCEPP_API vpkpp_entry_compression_type_e vpkpp_zip_get_entry_compression_type(vpkpp_pack_file_handle_t handle, const char* path) { - SOURCEPP_EARLY_RETURN_VAL(handle, ENTRY_COMPRESSION_TYPE_NO_COMPRESS); - SOURCEPP_EARLY_RETURN_VAL(path, ENTRY_COMPRESSION_TYPE_NO_COMPRESS); + SOURCEPP_EARLY_RETURN_VAL(handle, VPKPP_ENTRY_COMPRESSION_TYPE_NO_COMPRESS); + SOURCEPP_EARLY_RETURN_VAL(path, VPKPP_ENTRY_COMPRESSION_TYPE_NO_COMPRESS); auto* zip = Convert::packFile(handle); - SOURCEPP_EARLY_RETURN_VAL(zip->isInstanceOf(), ENTRY_COMPRESSION_TYPE_NO_COMPRESS); + SOURCEPP_EARLY_RETURN_VAL(zip->isInstanceOf(), VPKPP_ENTRY_COMPRESSION_TYPE_NO_COMPRESS); return static_cast(dynamic_cast(zip)->getEntryCompressionType(path)); } From 77454d12bfe48099f8d96caf5a40109ff085dfc8 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sat, 8 Feb 2025 20:16:18 -0500 Subject: [PATCH 2/8] c: generalize buffer type, avoid accessing possible nullptr --- lang/c/include/sourceppc/Buffer.h | 2 +- lang/c/include/sourceppc/Convert.hpp | 8 +++++++- lang/c/src/sourceppc/Buffer.cpp | 4 ++++ lang/c/src/sourceppc/Convert.cpp | 6 ------ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lang/c/include/sourceppc/Buffer.h b/lang/c/include/sourceppc/Buffer.h index 6ce723efd..881b18343 100644 --- a/lang/c/include/sourceppc/Buffer.h +++ b/lang/c/include/sourceppc/Buffer.h @@ -8,7 +8,7 @@ extern "C" { typedef struct { int64_t size; - uint8_t* data; + void* data; } sourcepp_buffer_t; #define SOURCEPP_BUFFER_INVALID (sourcepp_buffer_t{.size = -1, .data = NULL}) diff --git a/lang/c/include/sourceppc/Convert.hpp b/lang/c/include/sourceppc/Convert.hpp index 528d82765..a08872b9d 100644 --- a/lang/c/include/sourceppc/Convert.hpp +++ b/lang/c/include/sourceppc/Convert.hpp @@ -19,7 +19,13 @@ namespace Convert { -sourcepp_buffer_t toBuffer(const std::vector& vec); +template +requires (std::is_trivially_copyable_v && !std::is_pointer_v) +sourcepp_buffer_t toBuffer(const std::vector& vec) { + auto buf = sourcepp_buffer_new(vec.size() * sizeof(T)); + std::memcpy(buf.data, vec.data(), vec.size() * sizeof(T)); + return buf; +} sourcepp_string_t toString(std::string_view str); diff --git a/lang/c/src/sourceppc/Buffer.cpp b/lang/c/src/sourceppc/Buffer.cpp index fbb88a347..d53616fe9 100644 --- a/lang/c/src/sourceppc/Buffer.cpp +++ b/lang/c/src/sourceppc/Buffer.cpp @@ -2,6 +2,8 @@ #include +#include + SOURCEPP_API sourcepp_buffer_t sourcepp_buffer_new(size_t size) { sourcepp_buffer_t buffer; if (size > 0) { @@ -15,6 +17,8 @@ SOURCEPP_API sourcepp_buffer_t sourcepp_buffer_new(size_t size) { } SOURCEPP_API void sourcepp_buffer_free(sourcepp_buffer_t* buffer) { + SOURCEPP_EARLY_RETURN(buffer); + if (buffer->data) { std::free(buffer->data); buffer->data = nullptr; diff --git a/lang/c/src/sourceppc/Convert.cpp b/lang/c/src/sourceppc/Convert.cpp index ecc00b9e6..1d99cf194 100644 --- a/lang/c/src/sourceppc/Convert.cpp +++ b/lang/c/src/sourceppc/Convert.cpp @@ -1,11 +1,5 @@ #include -sourcepp_buffer_t Convert::toBuffer(const std::vector& vec) { - auto buf = sourcepp_buffer_new(vec.size()); - std::memcpy(buf.data, vec.data(), vec.size()); - return buf; -} - sourcepp_string_t Convert::toString(std::string_view str) { auto newStr = sourcepp_string_new(str.size()); std::memcpy(newStr.data, str.data(), str.size()); From cfec3bfffbf99c6fce2cf879334cc00b18b321ef Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sat, 8 Feb 2025 17:12:18 -0500 Subject: [PATCH 3/8] vtfpp: tweak PPL checksum naming to make it clear its for the associated model --- include/vtfpp/PPL.h | 6 +++--- lang/python/src/vtfpp.h | 4 ++-- src/vtfpp/PPL.cpp | 8 ++++---- test/vtfpp.cpp | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/vtfpp/PPL.h b/include/vtfpp/PPL.h index 365c7970b..ae3e7280a 100644 --- a/include/vtfpp/PPL.h +++ b/include/vtfpp/PPL.h @@ -19,7 +19,7 @@ class PPL { std::vector data; }; - explicit PPL(uint32_t checksum_, ImageFormat format_ = ImageFormat::RGB888, uint32_t version_ = 0); + explicit PPL(uint32_t modelChecksum, ImageFormat format_ = ImageFormat::RGB888, uint32_t version_ = 0); explicit PPL(std::span pplData); @@ -31,9 +31,9 @@ class PPL { void setVersion(uint32_t newVersion); - [[nodiscard]] uint32_t getChecksum() const; + [[nodiscard]] uint32_t getModelChecksum() const; - void setChecksum(uint32_t newChecksum); + void setModelChecksum(uint32_t newChecksum); [[nodiscard]] ImageFormat getFormat() const; diff --git a/lang/python/src/vtfpp.h b/lang/python/src/vtfpp.h index 23bfeb0b0..2bfe07116 100644 --- a/lang/python/src/vtfpp.h +++ b/lang/python/src/vtfpp.h @@ -212,14 +212,14 @@ void register_python(py::module_& m) { }); cPPL - .def(py::init(), py::arg("checksum"), py::arg("format") = ImageFormat::RGB888, py::arg("version") = 0) + .def(py::init(), py::arg("model_checksum"), py::arg("format") = ImageFormat::RGB888, py::arg("version") = 0) .def("__init__", [](PPL* self, const py::bytes& pplData) { return new(self) PPL{{reinterpret_cast(pplData.data()), pplData.size()}}; }, py::arg("ppl_data")) .def(py::init(), py::arg("path")) .def("__bool__", &PPL::operator bool, py::is_operator()) .def_prop_rw("version", &PPL::getVersion, &PPL::setVersion) - .def_prop_rw("checksum", &PPL::getChecksum, &PPL::setChecksum) + .def_prop_rw("model_checksum", &PPL::getModelChecksum, &PPL::setModelChecksum) .def_prop_rw("format", &PPL::getFormat, &PPL::setFormat) .def("has_image_for_lod", &PPL::hasImageForLOD, py::arg("lod")) .def_prop_ro("image_lods", &PPL::getImageLODs) diff --git a/src/vtfpp/PPL.cpp b/src/vtfpp/PPL.cpp index 2f3b45db8..ed12c8dda 100644 --- a/src/vtfpp/PPL.cpp +++ b/src/vtfpp/PPL.cpp @@ -7,9 +7,9 @@ using namespace sourcepp; using namespace vtfpp; -PPL::PPL(uint32_t checksum_, ImageFormat format_, uint32_t version_) +PPL::PPL(uint32_t modelChecksum, ImageFormat format_, uint32_t version_) : version(version_) - , checksum(checksum_) + , checksum(modelChecksum) , format(format_) {} PPL::PPL(std::span pplData) { @@ -49,11 +49,11 @@ void PPL::setVersion(uint32_t newVersion) { this->version = newVersion; } -uint32_t PPL::getChecksum() const { +uint32_t PPL::getModelChecksum() const { return this->checksum; } -void PPL::setChecksum(uint32_t newChecksum) { +void PPL::setModelChecksum(uint32_t newChecksum) { this->checksum = newChecksum; } diff --git a/test/vtfpp.cpp b/test/vtfpp.cpp index 23ade0105..d1ce693ef 100644 --- a/test/vtfpp.cpp +++ b/test/vtfpp.cpp @@ -11,13 +11,13 @@ TEST(vtfpp, read_write_ppl) { PPL reader{in}; EXPECT_EQ(reader.getVersion(), 0); - EXPECT_EQ(reader.getChecksum(), 0xa9230a52); + EXPECT_EQ(reader.getModelChecksum(), 0xa9230a52); EXPECT_EQ(reader.getFormat(), ImageFormat::RGB888); const auto* image = reader.getImageRaw(); ASSERT_TRUE(reader); - PPL writer{reader.getChecksum(), reader.getFormat(), reader.getVersion()}; + PPL writer{reader.getModelChecksum(), reader.getFormat(), reader.getVersion()}; writer.setImage(image->data, reader.getFormat(), image->width, image->height); auto out = writer.bake(); From a5202dc9150bb9c2164609b9559ecc64332afc98 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sat, 8 Feb 2025 22:04:47 -0500 Subject: [PATCH 4/8] docs: FUTURE.md additions --- FUTURE.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FUTURE.md b/FUTURE.md index bd19312f3..0eeda2938 100644 --- a/FUTURE.md +++ b/FUTURE.md @@ -6,8 +6,9 @@ ### Future Improvements - External - - Move from cryptopp to a maintained cryptography library + - Strip down cryptopp and stop downloading it at CMake configuration time - Move from compressonator to something that isn't a pile of garbage + - There is literally nothing else that supports BC6H - Fork minizip-ng and change how it handles dependencies - `bsppp` - Support parsing more lumps @@ -31,6 +32,7 @@ - Parse animations/sequences - Make something to construct StudioModel objects from a given model file like obj/glTF? - Add a save method to write the constituent parts of a StudioModel to disk + - Add an SMD parser/writer - `sndpp` - WAV write support - XWV write support From 4844bb6fd029433734479883798a6da11d56964f Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sat, 8 Feb 2025 22:06:00 -0500 Subject: [PATCH 5/8] c: bind up vtfpp --- CMakeLists.txt | 556 +++++++++---------- README.md | 2 +- docs/index.md | 2 +- include/vtfpp/VTF.h | 10 +- lang/c/include/sourceppc/Buffer.h | 4 + lang/c/include/vtfppc/Convert.hpp | 64 +++ lang/c/include/vtfppc/ImageConversion.h | 83 +++ lang/c/include/vtfppc/ImageFormats.h | 113 ++++ lang/c/include/vtfppc/PPL.h | 74 +++ lang/c/include/vtfppc/SHT.h | 85 +++ lang/c/include/vtfppc/TTX.h | 61 +++ lang/c/include/vtfppc/VTF.h | 366 +++++++++++++ lang/c/include/vtfppc/vtfpp.h | 13 + lang/c/src/gameppc/gamepp.cpp | 2 + lang/c/src/vtfppc/Convert.cpp | 117 ++++ lang/c/src/vtfppc/ImageConversion.cpp | 138 +++++ lang/c/src/vtfppc/ImageFormats.cpp | 94 ++++ lang/c/src/vtfppc/PPL.cpp | 186 +++++++ lang/c/src/vtfppc/SHT.cpp | 259 +++++++++ lang/c/src/vtfppc/TTX.cpp | 155 ++++++ lang/c/src/vtfppc/VTF.cpp | 677 ++++++++++++++++++++++++ lang/c/src/vtfppc/_vtfppc.cmake | 18 + src/vtfpp/TTX.cpp | 6 +- 23 files changed, 2798 insertions(+), 287 deletions(-) create mode 100644 lang/c/include/vtfppc/Convert.hpp create mode 100644 lang/c/include/vtfppc/ImageConversion.h create mode 100644 lang/c/include/vtfppc/ImageFormats.h create mode 100644 lang/c/include/vtfppc/PPL.h create mode 100644 lang/c/include/vtfppc/SHT.h create mode 100644 lang/c/include/vtfppc/TTX.h create mode 100644 lang/c/include/vtfppc/VTF.h create mode 100644 lang/c/include/vtfppc/vtfpp.h create mode 100644 lang/c/src/vtfppc/Convert.cpp create mode 100644 lang/c/src/vtfppc/ImageConversion.cpp create mode 100644 lang/c/src/vtfppc/ImageFormats.cpp create mode 100644 lang/c/src/vtfppc/PPL.cpp create mode 100644 lang/c/src/vtfppc/SHT.cpp create mode 100644 lang/c/src/vtfppc/TTX.cpp create mode 100644 lang/c/src/vtfppc/VTF.cpp create mode 100644 lang/c/src/vtfppc/_vtfppc.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f8e2f31fe..bc67dcd01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,278 +1,278 @@ -cmake_minimum_required(VERSION 3.25 FATAL_ERROR) - - -# Set defaults before project call -if(PROJECT_IS_TOP_LEVEL) - set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE INTERNAL "" FORCE) -endif() - - -# Create project -project(sourcepp - DESCRIPTION "Several modern C++20 libraries for sanely parsing Valve formats.") -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - - -# Options (update print_options at the bottom of this file when modifying) -option(SOURCEPP_LIBS_START_ENABLED "Libraries will all build by default" ON) -option(SOURCEPP_USE_BSPPP "Build bsppp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_DMXPP "Build dmxpp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_FSPP "Build fspp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_GAMEPP "Build gamepp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_KVPP "Build kvpp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_MDLPP "Build mdlpp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_SNDPP "Build sndpp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_STEAMPP "Build steampp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_TOOLPP "Build toolpp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_VCRYPTPP "Build vcryptpp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_VPKPP "Build vpkpp library" ${SOURCEPP_LIBS_START_ENABLED}) -option(SOURCEPP_USE_VTFPP "Build vtfpp library" ${SOURCEPP_LIBS_START_ENABLED}) - -option(SOURCEPP_BUILD_BENCHMARKS "Build benchmarks for supported libraries" OFF) -option(SOURCEPP_BUILD_C_WRAPPERS "Build C wrappers for supported libraries" OFF) -option(SOURCEPP_BUILD_CSHARP_WRAPPERS "Build C# wrappers for supported libraries" OFF) -option(SOURCEPP_BUILD_PYTHON_WRAPPERS "Build Python wrappers for supported libraries" OFF) -option(SOURCEPP_BUILD_WITH_OPENCL "Build with support for GPU compute" OFF) -option(SOURCEPP_BUILD_WITH_TBB "Build with support for std::execution" OFF) -option(SOURCEPP_BUILD_WITH_THREADS "Build with support for threading" ON) -option(SOURCEPP_BUILD_TESTS "Build tests for supported libraries" OFF) -option(SOURCEPP_BUILD_WIN7_COMPAT "Build with Windows 7 compatibility" OFF) - -option(SOURCEPP_LINK_STATIC_MSVC_RUNTIME "Link to static MSVC runtime library" OFF) - - -# Options (library-specific) -option(SOURCEPP_VPKPP_SUPPORT_VPK_V54 "Support compressed v54 VPKs" ON) - - -# Option overrides -if(SOURCEPP_USE_BSPPP) - set(SOURCEPP_USE_VPKPP ON CACHE INTERNAL "" FORCE) -endif() -if(SOURCEPP_USE_FSPP) - set(SOURCEPP_USE_BSPPP ON CACHE INTERNAL "" FORCE) - set(SOURCEPP_USE_KVPP ON CACHE INTERNAL "" FORCE) - set(SOURCEPP_USE_STEAMPP ON CACHE INTERNAL "" FORCE) - set(SOURCEPP_USE_VPKPP ON CACHE INTERNAL "" FORCE) -endif() -if(SOURCEPP_USE_STEAMPP) - set(SOURCEPP_USE_KVPP ON CACHE INTERNAL "" FORCE) -endif() -if(SOURCEPP_USE_TOOLPP) - set(SOURCEPP_USE_KVPP ON CACHE INTERNAL "" FORCE) -endif() -if(SOURCEPP_USE_VPKPP) - set(SOURCEPP_USE_KVPP ON CACHE INTERNAL "" FORCE) -endif() - -if(SOURCEPP_BUILD_CSHARP_WRAPPERS) - set(SOURCEPP_BUILD_C_WRAPPERS ON CACHE INTERNAL "" FORCE) -endif() -if(MSVC) - # MSVC does not rely on tbb for std::execution policies, so we can force this on - set(SOURCEPP_BUILD_WITH_TBB ON CACHE INTERNAL "" FORCE) -endif() - - -# Versioning published bindings -if((SOURCEPP_BUILD_CSHARP_WRAPPERS OR SOURCEPP_BUILD_PYTHON_WRAPPERS) AND NOT SOURCEPP_VERSION) - set(SOURCEPP_VERSION "0.0.1") - message(AUTHOR_WARNING "SOURCEPP_VERSION is not defined, do not release this build publicly! Defaulting it to ${SOURCEPP_VERSION}...") -endif() - - -# Set defaults after project call -if(PROJECT_IS_TOP_LEVEL) - set(CMAKE_POSITION_INDEPENDENT_CODE ON) -endif() - -if(SOURCEPP_USE_STATIC_MSVC_RUNTIME) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") -endif() - - -# Add scripts -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -include(AddPrettyParser) -include(AddSourcePPLibrary) -include(FetchContent) -include(IncludeSubdirectory) -include(PrintOptions) -include(TargetOptimize) - - -# Include thirdparty libraries -include_subdirectory(ext) - - -# Shared code -include_subdirectory(src/sourcepp) -include_subdirectory(src/sourcepp/compression) -include_subdirectory(src/sourcepp/crypto) -include_subdirectory(src/sourcepp/parser) - - -# Shared C code -if(SOURCEPP_BUILD_C_WRAPPERS) - include_subdirectory(lang/c/src/sourceppc PROPAGATE ${PROJECT_NAME}c_SOURCES) -endif() - - -# Python bindings, part 1 -if(SOURCEPP_BUILD_PYTHON_WRAPPERS) - set(SOURCEPP_PYTHON_NAME "${PROJECT_NAME}_python") - find_package(Python REQUIRED - COMPONENTS Interpreter Development.Module - OPTIONAL_COMPONENTS Development.SABIModule) - FetchContent_Declare( - nanobind - GIT_REPOSITORY "https://github.com/wjakob/nanobind.git" - GIT_TAG "origin/master") - FetchContent_MakeAvailable(nanobind) - set(${SOURCEPP_PYTHON_NAME}_SOURCES "") - set(${SOURCEPP_PYTHON_NAME}_DEFINES "") - - # Set the version and git commit hash here - find_package(Git REQUIRED) - execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%H - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - OUTPUT_VARIABLE SOURCEPP_GIT_TAG - RESULT_VARIABLE SOURCEPP_GIT_TAG_ERROR - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT SOURCEPP_GIT_TAG) - message(FATAL_ERROR "Failed to retrieve git commit SHA: ${SOURCEPP_GIT_TAG_ERROR}") - endif() - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lang/python/cfg/CMakeLists.txt" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/CMakeLists.txt" @ONLY) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lang/python/cfg/pyproject.toml" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/pyproject.toml") - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lang/python/cfg/__init__.py" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp/__init__.py") - - # These need to be inside the python directory, let's duplicate them! - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/LICENSE" COPYONLY) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/README.md" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/README.md" COPYONLY) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/THIRDPARTY_LEGAL_NOTICES.txt" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/THIRDPARTY_LEGAL_NOTICES.txt" COPYONLY) -endif() - - -# Tests, part 1 -if(SOURCEPP_BUILD_TESTS) - set(SOURCEPP_TEST_NAME "${PROJECT_NAME}_test") - FetchContent_Declare( - googletest - GIT_REPOSITORY "https://github.com/google/googletest.git" - GIT_TAG "v1.15.2") - FetchContent_MakeAvailable(googletest) - enable_testing() - set(${SOURCEPP_TEST_NAME}_SOURCES "") - list(APPEND ${SOURCEPP_TEST_NAME}_DEPS gtest_main) - - # Download assets - FetchContent_Declare( - ${PROJECT_NAME}_assets - GIT_REPOSITORY "https://github.com/craftablescience/sourcepp_assets.git" - GIT_TAG "origin/main" - GIT_SHALLOW ON - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/test/res" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "") - FetchContent_MakeAvailable(${PROJECT_NAME}_assets) -endif() - - -# Benchmarks -if(SOURCEPP_BUILD_BENCHMARKS) - set(SOURCEPP_BENCH_NAME "${PROJECT_NAME}_bench") - FetchContent_Declare( - benchmark - GIT_REPOSITORY https://github.com/google/benchmark.git - GIT_TAG v1.9.0) - set(BENCHMARK_ENABLE_TESTING OFF CACHE INTERNAL "" FORCE) - FetchContent_MakeAvailable(benchmark) - - add_library(${SOURCEPP_BENCH_NAME} STATIC "${CMAKE_CURRENT_SOURCE_DIR}/bench/_bench.cpp") - target_link_libraries(${SOURCEPP_BENCH_NAME} PUBLIC benchmark::benchmark) - target_compile_definitions(${SOURCEPP_BENCH_NAME} PUBLIC ASSET_ROOT="${CMAKE_CURRENT_SOURCE_DIR}/test/res/") -endif() - - -# Add libraries -add_sourcepp_library(bsppp PYTHON NO_TEST ) # sourcepp::bsppp -add_sourcepp_library(dmxpp ) # sourcepp::dmxpp -add_sourcepp_library(fspp ) # sourcepp::fspp -add_sourcepp_library(gamepp C PYTHON ) # sourcepp::gamepp -add_sourcepp_library(kvpp BENCH) # sourcepp::kvpp -add_sourcepp_library(mdlpp ) # sourcepp::mdlpp -add_sourcepp_library(sndpp ) # sourcepp::sndpp -add_sourcepp_library(steampp C PYTHON ) # sourcepp::steampp -add_sourcepp_library(toolpp PYTHON ) # sourcepp::toolpp -add_sourcepp_library(vcryptpp C CSHARP PYTHON ) # sourcepp::vcryptpp -add_sourcepp_library(vpkpp C CSHARP ) # sourcepp::vpkpp -add_sourcepp_library(vtfpp PYTHON BENCH) # sourcepp::vtfpp - - -# Tests, part 2 -if(SOURCEPP_BUILD_TESTS) - add_executable(${SOURCEPP_TEST_NAME} ${${SOURCEPP_TEST_NAME}_SOURCES}) - target_link_libraries(${SOURCEPP_TEST_NAME} PUBLIC ${${SOURCEPP_TEST_NAME}_DEPS}) - target_compile_definitions(${SOURCEPP_TEST_NAME} PUBLIC ASSET_ROOT="${CMAKE_CURRENT_SOURCE_DIR}/test/res/") - include(GoogleTest) - gtest_discover_tests(${SOURCEPP_TEST_NAME}) -endif() - - -# Python bindings, part 2 -if(SOURCEPP_BUILD_PYTHON_WRAPPERS) - nanobind_add_module(${SOURCEPP_PYTHON_NAME} NB_STATIC STABLE_ABI LTO - "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp.cpp" - ${${SOURCEPP_PYTHON_NAME}_SOURCES}) - set_target_properties(${SOURCEPP_PYTHON_NAME} PROPERTIES - OUTPUT_NAME "_${PROJECT_NAME}_impl" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp" - LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp" - LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp") - target_compile_definitions(${SOURCEPP_PYTHON_NAME} PRIVATE ${${SOURCEPP_PYTHON_NAME}_DEFINES}) - target_link_libraries(${SOURCEPP_PYTHON_NAME} PRIVATE ${${SOURCEPP_PYTHON_NAME}_DEPS}) - install(TARGETS ${SOURCEPP_PYTHON_NAME} LIBRARY DESTINATION "./${PROJECT_NAME}") - - add_custom_target(${SOURCEPP_PYTHON_NAME}_all) - add_dependencies(${SOURCEPP_PYTHON_NAME}_all ${SOURCEPP_PYTHON_NAME}) - - # We need to manually write out each module :( - set(${SOURCEPP_PYTHON_NAME}_MODULES - "sourcepp._sourcepp_impl" - "sourcepp._sourcepp_impl.bsppp" - "sourcepp._sourcepp_impl.gamepp" - "sourcepp._sourcepp_impl.sourcepp" - "sourcepp._sourcepp_impl.sourcepp.math" - "sourcepp._sourcepp_impl.steampp" - "sourcepp._sourcepp_impl.toolpp" - "sourcepp._sourcepp_impl.vcryptpp" - "sourcepp._sourcepp_impl.vcryptpp.VFONT" - "sourcepp._sourcepp_impl.vcryptpp.VICE" - "sourcepp._sourcepp_impl.vtfpp" - "sourcepp._sourcepp_impl.vtfpp.ImageFormatDetails" - "sourcepp._sourcepp_impl.vtfpp.ImageDimensions" - "sourcepp._sourcepp_impl.vtfpp.ImageConversion") - foreach(MODULE ${${SOURCEPP_PYTHON_NAME}_MODULES}) - string(REPLACE "." "/" MODULE_DIR "${MODULE}") - string(REPLACE "." "_" MODULE_NAME_NORMALIZED "${MODULE}") - set(MODULE_NAME_NORMALIZED "${MODULE_NAME_NORMALIZED}_stub") - nanobind_add_stub("${SOURCEPP_PYTHON_NAME}_stub_${MODULE_NAME_NORMALIZED}" - DEPENDS ${SOURCEPP_PYTHON_NAME} - MODULE "${MODULE}" - OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/${MODULE_DIR}.pyi" - PYTHON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src") - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/${MODULE_DIR}.pyi" DESTINATION "./${MODULE_DIR}/..") - add_dependencies(${SOURCEPP_PYTHON_NAME}_all ${SOURCEPP_PYTHON_NAME}_stub_${MODULE_NAME_NORMALIZED}) - endforeach() -endif() - - -# Print options -print_options(OPTIONS - USE_BSPPP USE_DMXPP USE_FSPP USE_GAMEPP USE_KVPP USE_MDLPP USE_SNDPP USE_STEAMPP USE_TOOLPP USE_VCRYPTPP USE_VPKPP USE_VTFPP - BUILD_BENCHMARKS BUILD_C_WRAPPERS BUILD_CSHARP_WRAPPERS BUILD_PYTHON_WRAPPERS BUILD_WITH_OPENCL BUILD_WITH_TBB BUILD_WITH_THREADS BUILD_TESTS BUILD_WIN7_COMPAT - LINK_STATIC_MSVC_RUNTIME - VPKPP_SUPPORT_VPK_V54) +cmake_minimum_required(VERSION 3.25 FATAL_ERROR) + + +# Set defaults before project call +if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE INTERNAL "" FORCE) +endif() + + +# Create project +project(sourcepp + DESCRIPTION "Several modern C++20 libraries for sanely parsing Valve formats.") +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + + +# Options (update print_options at the bottom of this file when modifying) +option(SOURCEPP_LIBS_START_ENABLED "Libraries will all build by default" ON) +option(SOURCEPP_USE_BSPPP "Build bsppp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_DMXPP "Build dmxpp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_FSPP "Build fspp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_GAMEPP "Build gamepp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_KVPP "Build kvpp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_MDLPP "Build mdlpp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_SNDPP "Build sndpp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_STEAMPP "Build steampp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_TOOLPP "Build toolpp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_VCRYPTPP "Build vcryptpp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_VPKPP "Build vpkpp library" ${SOURCEPP_LIBS_START_ENABLED}) +option(SOURCEPP_USE_VTFPP "Build vtfpp library" ${SOURCEPP_LIBS_START_ENABLED}) + +option(SOURCEPP_BUILD_BENCHMARKS "Build benchmarks for supported libraries" OFF) +option(SOURCEPP_BUILD_C_WRAPPERS "Build C wrappers for supported libraries" OFF) +option(SOURCEPP_BUILD_CSHARP_WRAPPERS "Build C# wrappers for supported libraries" OFF) +option(SOURCEPP_BUILD_PYTHON_WRAPPERS "Build Python wrappers for supported libraries" OFF) +option(SOURCEPP_BUILD_WITH_OPENCL "Build with support for GPU compute" OFF) +option(SOURCEPP_BUILD_WITH_TBB "Build with support for std::execution" OFF) +option(SOURCEPP_BUILD_WITH_THREADS "Build with support for threading" ON) +option(SOURCEPP_BUILD_TESTS "Build tests for supported libraries" OFF) +option(SOURCEPP_BUILD_WIN7_COMPAT "Build with Windows 7 compatibility" OFF) + +option(SOURCEPP_LINK_STATIC_MSVC_RUNTIME "Link to static MSVC runtime library" OFF) + + +# Options (library-specific) +option(SOURCEPP_VPKPP_SUPPORT_VPK_V54 "Support compressed v54 VPKs" ON) + + +# Option overrides +if(SOURCEPP_USE_BSPPP) + set(SOURCEPP_USE_VPKPP ON CACHE INTERNAL "" FORCE) +endif() +if(SOURCEPP_USE_FSPP) + set(SOURCEPP_USE_BSPPP ON CACHE INTERNAL "" FORCE) + set(SOURCEPP_USE_KVPP ON CACHE INTERNAL "" FORCE) + set(SOURCEPP_USE_STEAMPP ON CACHE INTERNAL "" FORCE) + set(SOURCEPP_USE_VPKPP ON CACHE INTERNAL "" FORCE) +endif() +if(SOURCEPP_USE_STEAMPP) + set(SOURCEPP_USE_KVPP ON CACHE INTERNAL "" FORCE) +endif() +if(SOURCEPP_USE_TOOLPP) + set(SOURCEPP_USE_KVPP ON CACHE INTERNAL "" FORCE) +endif() +if(SOURCEPP_USE_VPKPP) + set(SOURCEPP_USE_KVPP ON CACHE INTERNAL "" FORCE) +endif() + +if(SOURCEPP_BUILD_CSHARP_WRAPPERS) + set(SOURCEPP_BUILD_C_WRAPPERS ON CACHE INTERNAL "" FORCE) +endif() +if(MSVC) + # MSVC does not rely on tbb for std::execution policies, so we can force this on + set(SOURCEPP_BUILD_WITH_TBB ON CACHE INTERNAL "" FORCE) +endif() + + +# Versioning published bindings +if((SOURCEPP_BUILD_CSHARP_WRAPPERS OR SOURCEPP_BUILD_PYTHON_WRAPPERS) AND NOT SOURCEPP_VERSION) + set(SOURCEPP_VERSION "0.0.1") + message(AUTHOR_WARNING "SOURCEPP_VERSION is not defined, do not release this build publicly! Defaulting it to ${SOURCEPP_VERSION}...") +endif() + + +# Set defaults after project call +if(PROJECT_IS_TOP_LEVEL) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + +if(SOURCEPP_USE_STATIC_MSVC_RUNTIME) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +endif() + + +# Add scripts +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(AddPrettyParser) +include(AddSourcePPLibrary) +include(FetchContent) +include(IncludeSubdirectory) +include(PrintOptions) +include(TargetOptimize) + + +# Include thirdparty libraries +include_subdirectory(ext) + + +# Shared code +include_subdirectory(src/sourcepp) +include_subdirectory(src/sourcepp/compression) +include_subdirectory(src/sourcepp/crypto) +include_subdirectory(src/sourcepp/parser) + + +# Shared C code +if(SOURCEPP_BUILD_C_WRAPPERS) + include_subdirectory(lang/c/src/sourceppc PROPAGATE ${PROJECT_NAME}c_SOURCES) +endif() + + +# Python bindings, part 1 +if(SOURCEPP_BUILD_PYTHON_WRAPPERS) + set(SOURCEPP_PYTHON_NAME "${PROJECT_NAME}_python") + find_package(Python REQUIRED + COMPONENTS Interpreter Development.Module + OPTIONAL_COMPONENTS Development.SABIModule) + FetchContent_Declare( + nanobind + GIT_REPOSITORY "https://github.com/wjakob/nanobind.git" + GIT_TAG "origin/master") + FetchContent_MakeAvailable(nanobind) + set(${SOURCEPP_PYTHON_NAME}_SOURCES "") + set(${SOURCEPP_PYTHON_NAME}_DEFINES "") + + # Set the version and git commit hash here + find_package(Git REQUIRED) + execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%H + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + OUTPUT_VARIABLE SOURCEPP_GIT_TAG + RESULT_VARIABLE SOURCEPP_GIT_TAG_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT SOURCEPP_GIT_TAG) + message(FATAL_ERROR "Failed to retrieve git commit SHA: ${SOURCEPP_GIT_TAG_ERROR}") + endif() + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lang/python/cfg/CMakeLists.txt" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/CMakeLists.txt" @ONLY) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lang/python/cfg/pyproject.toml" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/pyproject.toml") + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lang/python/cfg/__init__.py" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp/__init__.py") + + # These need to be inside the python directory, let's duplicate them! + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/LICENSE" COPYONLY) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/README.md" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/README.md" COPYONLY) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/THIRDPARTY_LEGAL_NOTICES.txt" "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/THIRDPARTY_LEGAL_NOTICES.txt" COPYONLY) +endif() + + +# Tests, part 1 +if(SOURCEPP_BUILD_TESTS) + set(SOURCEPP_TEST_NAME "${PROJECT_NAME}_test") + FetchContent_Declare( + googletest + GIT_REPOSITORY "https://github.com/google/googletest.git" + GIT_TAG "v1.15.2") + FetchContent_MakeAvailable(googletest) + enable_testing() + set(${SOURCEPP_TEST_NAME}_SOURCES "") + list(APPEND ${SOURCEPP_TEST_NAME}_DEPS gtest_main) + + # Download assets + FetchContent_Declare( + ${PROJECT_NAME}_assets + GIT_REPOSITORY "https://github.com/craftablescience/sourcepp_assets.git" + GIT_TAG "origin/main" + GIT_SHALLOW ON + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/test/res" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "") + FetchContent_MakeAvailable(${PROJECT_NAME}_assets) +endif() + + +# Benchmarks +if(SOURCEPP_BUILD_BENCHMARKS) + set(SOURCEPP_BENCH_NAME "${PROJECT_NAME}_bench") + FetchContent_Declare( + benchmark + GIT_REPOSITORY https://github.com/google/benchmark.git + GIT_TAG v1.9.0) + set(BENCHMARK_ENABLE_TESTING OFF CACHE INTERNAL "" FORCE) + FetchContent_MakeAvailable(benchmark) + + add_library(${SOURCEPP_BENCH_NAME} STATIC "${CMAKE_CURRENT_SOURCE_DIR}/bench/_bench.cpp") + target_link_libraries(${SOURCEPP_BENCH_NAME} PUBLIC benchmark::benchmark) + target_compile_definitions(${SOURCEPP_BENCH_NAME} PUBLIC ASSET_ROOT="${CMAKE_CURRENT_SOURCE_DIR}/test/res/") +endif() + + +# Add libraries +add_sourcepp_library(bsppp PYTHON NO_TEST ) # sourcepp::bsppp +add_sourcepp_library(dmxpp ) # sourcepp::dmxpp +add_sourcepp_library(fspp ) # sourcepp::fspp +add_sourcepp_library(gamepp C PYTHON ) # sourcepp::gamepp +add_sourcepp_library(kvpp BENCH) # sourcepp::kvpp +add_sourcepp_library(mdlpp ) # sourcepp::mdlpp +add_sourcepp_library(sndpp ) # sourcepp::sndpp +add_sourcepp_library(steampp C PYTHON ) # sourcepp::steampp +add_sourcepp_library(toolpp PYTHON ) # sourcepp::toolpp +add_sourcepp_library(vcryptpp C CSHARP PYTHON ) # sourcepp::vcryptpp +add_sourcepp_library(vpkpp C CSHARP ) # sourcepp::vpkpp +add_sourcepp_library(vtfpp C PYTHON BENCH) # sourcepp::vtfpp + + +# Tests, part 2 +if(SOURCEPP_BUILD_TESTS) + add_executable(${SOURCEPP_TEST_NAME} ${${SOURCEPP_TEST_NAME}_SOURCES}) + target_link_libraries(${SOURCEPP_TEST_NAME} PUBLIC ${${SOURCEPP_TEST_NAME}_DEPS}) + target_compile_definitions(${SOURCEPP_TEST_NAME} PUBLIC ASSET_ROOT="${CMAKE_CURRENT_SOURCE_DIR}/test/res/") + include(GoogleTest) + gtest_discover_tests(${SOURCEPP_TEST_NAME}) +endif() + + +# Python bindings, part 2 +if(SOURCEPP_BUILD_PYTHON_WRAPPERS) + nanobind_add_module(${SOURCEPP_PYTHON_NAME} NB_STATIC STABLE_ABI LTO + "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp.cpp" + ${${SOURCEPP_PYTHON_NAME}_SOURCES}) + set_target_properties(${SOURCEPP_PYTHON_NAME} PROPERTIES + OUTPUT_NAME "_${PROJECT_NAME}_impl" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp" + LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp" + LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/sourcepp") + target_compile_definitions(${SOURCEPP_PYTHON_NAME} PRIVATE ${${SOURCEPP_PYTHON_NAME}_DEFINES}) + target_link_libraries(${SOURCEPP_PYTHON_NAME} PRIVATE ${${SOURCEPP_PYTHON_NAME}_DEPS}) + install(TARGETS ${SOURCEPP_PYTHON_NAME} LIBRARY DESTINATION "./${PROJECT_NAME}") + + add_custom_target(${SOURCEPP_PYTHON_NAME}_all) + add_dependencies(${SOURCEPP_PYTHON_NAME}_all ${SOURCEPP_PYTHON_NAME}) + + # We need to manually write out each module :( + set(${SOURCEPP_PYTHON_NAME}_MODULES + "sourcepp._sourcepp_impl" + "sourcepp._sourcepp_impl.bsppp" + "sourcepp._sourcepp_impl.gamepp" + "sourcepp._sourcepp_impl.sourcepp" + "sourcepp._sourcepp_impl.sourcepp.math" + "sourcepp._sourcepp_impl.steampp" + "sourcepp._sourcepp_impl.toolpp" + "sourcepp._sourcepp_impl.vcryptpp" + "sourcepp._sourcepp_impl.vcryptpp.VFONT" + "sourcepp._sourcepp_impl.vcryptpp.VICE" + "sourcepp._sourcepp_impl.vtfpp" + "sourcepp._sourcepp_impl.vtfpp.ImageFormatDetails" + "sourcepp._sourcepp_impl.vtfpp.ImageDimensions" + "sourcepp._sourcepp_impl.vtfpp.ImageConversion") + foreach(MODULE ${${SOURCEPP_PYTHON_NAME}_MODULES}) + string(REPLACE "." "/" MODULE_DIR "${MODULE}") + string(REPLACE "." "_" MODULE_NAME_NORMALIZED "${MODULE}") + set(MODULE_NAME_NORMALIZED "${MODULE_NAME_NORMALIZED}_stub") + nanobind_add_stub("${SOURCEPP_PYTHON_NAME}_stub_${MODULE_NAME_NORMALIZED}" + DEPENDS ${SOURCEPP_PYTHON_NAME} + MODULE "${MODULE}" + OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/${MODULE_DIR}.pyi" + PYTHON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src") + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/lang/python/src/${MODULE_DIR}.pyi" DESTINATION "./${MODULE_DIR}/..") + add_dependencies(${SOURCEPP_PYTHON_NAME}_all ${SOURCEPP_PYTHON_NAME}_stub_${MODULE_NAME_NORMALIZED}) + endforeach() +endif() + + +# Print options +print_options(OPTIONS + USE_BSPPP USE_DMXPP USE_FSPP USE_GAMEPP USE_KVPP USE_MDLPP USE_SNDPP USE_STEAMPP USE_TOOLPP USE_VCRYPTPP USE_VPKPP USE_VTFPP + BUILD_BENCHMARKS BUILD_C_WRAPPERS BUILD_CSHARP_WRAPPERS BUILD_PYTHON_WRAPPERS BUILD_WITH_OPENCL BUILD_WITH_TBB BUILD_WITH_THREADS BUILD_TESTS BUILD_WIN7_COMPAT + LINK_STATIC_MSVC_RUNTIME + VPKPP_SUPPORT_VPK_V54) diff --git a/README.md b/README.md index b3c6fcd90..31c769d01 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one APNG ✅ ❌ - Python + C
Python diff --git a/docs/index.md b/docs/index.md index 0ee0f1685..1601d40f0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -231,7 +231,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one APNG ✅ ❌ - Python + C
Python BMP diff --git a/include/vtfpp/VTF.h b/include/vtfpp/VTF.h index be3e25c06..d3da18284 100644 --- a/include/vtfpp/VTF.h +++ b/include/vtfpp/VTF.h @@ -135,13 +135,13 @@ class VTF { FLAG_HINT_DXT5 = 1 << 5, FLAG_PWL_CORRECTED = 1 << 6, FLAG_NORMAL = 1 << 7, - FLAG_NO_MIP = 1 << 8, // Applied at VTF bake time - FLAG_NO_LOD = 1 << 9, // Applied at VTF bake time + FLAG_NO_MIP = 1 << 8, // Controlled by mip count + FLAG_NO_LOD = 1 << 9, FLAG_LOAD_ALL_MIPS = 1 << 10, FLAG_PROCEDURAL = 1 << 11, - FLAG_ONE_BIT_ALPHA = 1 << 12, // Applied at VTF bake time - FLAG_MULTI_BIT_ALPHA = 1 << 13, // Applied at VTF bake time - FLAG_ENVMAP = 1 << 14, // Applied at VTF bake time + FLAG_ONE_BIT_ALPHA = 1 << 12, + FLAG_MULTI_BIT_ALPHA = 1 << 13, + FLAG_ENVMAP = 1 << 14, // Controlled by face count FLAG_RENDERTARGET = 1 << 15, FLAG_DEPTH_RENDERTARGET = 1 << 16, FLAG_NO_DEBUG_OVERRIDE = 1 << 17, diff --git a/lang/c/include/sourceppc/Buffer.h b/lang/c/include/sourceppc/Buffer.h index 881b18343..4b9718e2c 100644 --- a/lang/c/include/sourceppc/Buffer.h +++ b/lang/c/include/sourceppc/Buffer.h @@ -13,6 +13,10 @@ typedef struct { #define SOURCEPP_BUFFER_INVALID (sourcepp_buffer_t{.size = -1, .data = NULL}) +// Aliases +typedef sourcepp_buffer_t sourcepp_buffer_uint32_t; +typedef sourcepp_buffer_t sourcepp_buffer_uint64_t; + #ifdef __cplusplus } // extern "C" #endif diff --git a/lang/c/include/vtfppc/Convert.hpp b/lang/c/include/vtfppc/Convert.hpp new file mode 100644 index 000000000..fcffdfd4a --- /dev/null +++ b/lang/c/include/vtfppc/Convert.hpp @@ -0,0 +1,64 @@ +#pragma once + +#include + +#include "PPL.h" +#include "SHT.h" +#include "TTX.h" +#include "VTF.h" + +/* + * This is a header designed to be included in C++ source code. + * It should not be included in applications using any C wrapper libraries! + */ +#ifndef __cplusplus +#error "This header can only be used in C++!" +#endif + +namespace Convert { + +vtfpp::ImageConversion::ResizeMethod resizeMethod(vtfpp_image_conversion_resize_method_e method); + +vtfpp_image_conversion_resize_method_e resizeMethod(vtfpp::ImageConversion::ResizeMethod method); + +vtfpp::ImageConversion::ResizeFilter resizeFilter(vtfpp_image_conversion_resize_filter_e filter); + +vtfpp::ImageConversion::FileFormat fileFormat(vtfpp_image_conversion_file_format_e fileFormat); + +vtfpp::ImageFormat imageFormat(vtfpp_image_format_e format); + +vtfpp_image_format_e imageFormat(vtfpp::ImageFormat format); + +vtfpp::PPL* ppl(vtfpp_ppl_handle_t handle); + +vtfpp::SHT* sht(vtfpp_sht_handle_t handle); + +vtfpp::TTX* ttx(vtfpp_ttx_handle_t handle); + +vtfpp::CompressionMethod compressionMethod(vtfpp_compression_method_e method); + +vtfpp_compression_method_e compressionMethod(vtfpp::CompressionMethod method); + +vtfpp::Resource::Type resourceType(vtfpp_resource_type_e type); + +vtfpp_resource_type_e resourceType(vtfpp::Resource::Type type); + +vtfpp::Resource::Flags resourceFlags(vtfpp_resource_flags_e flags); + +vtfpp_resource_flags_e resourceFlags(vtfpp::Resource::Flags flags); + +const vtfpp::Resource* resource(vtfpp_resource_handle_t resource); + +vtfpp::VTF::Flags vtfFlags(vtfpp_vtf_flags_e flags); + +vtfpp_vtf_flags_e vtfFlags(vtfpp::VTF::Flags flags); + +vtfpp::VTF::Platform vtfPlatform(vtfpp_vtf_platform_e platform); + +vtfpp_vtf_platform_e vtfPlatform(vtfpp::VTF::Platform platform); + +vtfpp::VTF::CreationOptions vtfCreationOptions(vtfpp_vtf_creation_options_t options); + +vtfpp::VTF* vtf(vtfpp_vtf_handle_t handle); + +} // namespace Convert diff --git a/lang/c/include/vtfppc/ImageConversion.h b/lang/c/include/vtfppc/ImageConversion.h new file mode 100644 index 000000000..62e751feb --- /dev/null +++ b/lang/c/include/vtfppc/ImageConversion.h @@ -0,0 +1,83 @@ +#pragma once + +#include +#include + +#include "ImageFormats.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Skipping vtfpp::ImagePixel, not super useful + +typedef enum { + VTFPP_IMAGE_CONVERSION_FILE_FORMAT_DEFAULT, + VTFPP_IMAGE_CONVERSION_FILE_FORMAT_PNG, + VTFPP_IMAGE_CONVERSION_FILE_FORMAT_JPEG, + VTFPP_IMAGE_CONVERSION_FILE_FORMAT_BMP, + VTFPP_IMAGE_CONVERSION_FILE_FORMAT_TGA, + VTFPP_IMAGE_CONVERSION_FILE_FORMAT_HDR, + VTFPP_IMAGE_CONVERSION_FILE_FORMAT_EXR, +} vtfpp_image_conversion_file_format_e; + +typedef enum { + VTFPP_IMAGE_CONVERSION_RESIZE_EDGE_CLAMP, + VTFPP_IMAGE_CONVERSION_RESIZE_EDGE_REFLECT, + VTFPP_IMAGE_CONVERSION_RESIZE_EDGE_WRAP, + VTFPP_IMAGE_CONVERSION_RESIZE_EDGE_ZERO, +} vtfpp_image_conversion_resize_edge_e; + +typedef enum { + VTFPP_IMAGE_CONVERSION_RESIZE_FILTER_DEFAULT, + VTFPP_IMAGE_CONVERSION_RESIZE_FILTER_BOX, + VTFPP_IMAGE_CONVERSION_RESIZE_FILTER_BILINEAR, + VTFPP_IMAGE_CONVERSION_RESIZE_FILTER_CUBIC_BSPLINE, + VTFPP_IMAGE_CONVERSION_RESIZE_FILTER_CATMULLROM, + VTFPP_IMAGE_CONVERSION_RESIZE_FILTER_MITCHELL, + //VTFPP_IMAGE_CONVERSION_RESIZE_FILTER_POINT_SAMPLE, +} vtfpp_image_conversion_resize_filter_e; + +typedef enum { + VTFPP_IMAGE_CONVERSION_RESIZE_METHOD_NONE, + VTFPP_IMAGE_CONVERSION_RESIZE_METHOD_POWER_OF_TWO_BIGGER, + VTFPP_IMAGE_CONVERSION_RESIZE_METHOD_POWER_OF_TWO_SMALLER, + VTFPP_IMAGE_CONVERSION_RESIZE_METHOD_POWER_OF_TWO_NEAREST, +} vtfpp_image_conversion_resize_method_e; + +#ifdef __cplusplus +} // extern "C" +#endif + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_image_data_to_format(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e oldFormat, vtfpp_image_format_e newFormat, uint16_t width, uint16_t height); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_convert_several_image_data_to_format(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e oldFormat, vtfpp_image_format_e newFormat, uint8_t mipCount, uint16_t frameCount, uint16_t faceCount, uint16_t width, uint16_t height, uint16_t sliceCount); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap_ex(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, uint16_t resolution, int bilinear); + +SOURCEPP_API vtfpp_image_conversion_file_format_e vtfpp_image_conversion_get_default_file_format_for_image_format(vtfpp_image_format_e format); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_image_data_to_file(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, vtfpp_image_conversion_file_format_e fileFormat); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_file_to_image_data(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e* format, int* width, int* height, int* frameCount); + +SOURCEPP_API uint16_t vtfpp_image_conversion_get_resized_dim(uint16_t n, vtfpp_image_conversion_resize_method_e method); + +SOURCEPP_API void vtfpp_image_conversion_set_resized_dims(uint16_t* width, vtfpp_image_conversion_resize_method_e widthResize, uint16_t* height, vtfpp_image_conversion_resize_method_e heightResize); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t height, uint16_t newHeight, int srgb, vtfpp_image_conversion_resize_filter_e filter, vtfpp_image_conversion_resize_edge_e edge); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data_strict(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t* widthOut, vtfpp_image_conversion_resize_method_e widthResize, uint16_t height, uint16_t newHeight, uint16_t* heightOut, vtfpp_image_conversion_resize_method_e heightResize, bool srgb, vtfpp_image_conversion_resize_filter_e filter, vtfpp_image_conversion_resize_edge_e edge); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_crop_image_data(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t xOffset, uint16_t height, uint16_t newHeight, uint16_t yOffset); diff --git a/lang/c/include/vtfppc/ImageFormats.h b/lang/c/include/vtfppc/ImageFormats.h new file mode 100644 index 000000000..bc80e3b14 --- /dev/null +++ b/lang/c/include/vtfppc/ImageFormats.h @@ -0,0 +1,113 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + VTFPP_IMAGE_FORMAT_RGBA8888 = 0, + VTFPP_IMAGE_FORMAT_ABGR8888, + VTFPP_IMAGE_FORMAT_RGB888, + VTFPP_IMAGE_FORMAT_BGR888, + VTFPP_IMAGE_FORMAT_RGB565, + VTFPP_IMAGE_FORMAT_I8, + VTFPP_IMAGE_FORMAT_IA88, + VTFPP_IMAGE_FORMAT_P8, + VTFPP_IMAGE_FORMAT_A8, + VTFPP_IMAGE_FORMAT_RGB888_BLUESCREEN, + VTFPP_IMAGE_FORMAT_BGR888_BLUESCREEN, + VTFPP_IMAGE_FORMAT_ARGB8888, + VTFPP_IMAGE_FORMAT_BGRA8888, + VTFPP_IMAGE_FORMAT_DXT1, + VTFPP_IMAGE_FORMAT_DXT3, + VTFPP_IMAGE_FORMAT_DXT5, + VTFPP_IMAGE_FORMAT_BGRX8888, + VTFPP_IMAGE_FORMAT_BGR565, + VTFPP_IMAGE_FORMAT_BGRX5551, + VTFPP_IMAGE_FORMAT_BGRA4444, + VTFPP_IMAGE_FORMAT_DXT1_ONE_BIT_ALPHA, + VTFPP_IMAGE_FORMAT_BGRA5551, + VTFPP_IMAGE_FORMAT_UV88, + VTFPP_IMAGE_FORMAT_UVWQ8888, + VTFPP_IMAGE_FORMAT_RGBA16161616F, + VTFPP_IMAGE_FORMAT_RGBA16161616, + VTFPP_IMAGE_FORMAT_UVLX8888, + VTFPP_IMAGE_FORMAT_R32F, + VTFPP_IMAGE_FORMAT_RGB323232F, + VTFPP_IMAGE_FORMAT_RGBA32323232F, + VTFPP_IMAGE_FORMAT_RG1616F, + VTFPP_IMAGE_FORMAT_RG3232F, + VTFPP_IMAGE_FORMAT_RGBX8888, + VTFPP_IMAGE_FORMAT_EMPTY, + VTFPP_IMAGE_FORMAT_ATI2N, + VTFPP_IMAGE_FORMAT_ATI1N, + VTFPP_IMAGE_FORMAT_RGBA1010102, + VTFPP_IMAGE_FORMAT_BGRA1010102, + VTFPP_IMAGE_FORMAT_R16F, + + VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LINEAR = 42, + VTFPP_IMAGE_FORMAT_CONSOLE_RGBA8888_LINEAR, + VTFPP_IMAGE_FORMAT_CONSOLE_ABGR8888_LINEAR, + VTFPP_IMAGE_FORMAT_CONSOLE_ARGB8888_LINEAR, + VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LINEAR, + VTFPP_IMAGE_FORMAT_CONSOLE_RGB888_LINEAR, + VTFPP_IMAGE_FORMAT_CONSOLE_BGR888_LINEAR, + VTFPP_IMAGE_FORMAT_CONSOLE_BGRX5551_LINEAR, + VTFPP_IMAGE_FORMAT_CONSOLE_I8_LINEAR, + VTFPP_IMAGE_FORMAT_CONSOLE_RGBA16161616_LINEAR, + VTFPP_IMAGE_FORMAT_CONSOLE_BGRX8888_LE, + VTFPP_IMAGE_FORMAT_CONSOLE_BGRA8888_LE, + + VTFPP_IMAGE_FORMAT_R8 = 69, + VTFPP_IMAGE_FORMAT_BC7, + VTFPP_IMAGE_FORMAT_BC6H, +} vtfpp_image_format_e; + +#ifdef __cplusplus +} // extern "C" +#endif + +SOURCEPP_API int8_t vtfpp_image_format_details_red(vtfpp_image_format_e format); + +SOURCEPP_API int8_t vtfpp_image_format_details_decompressed_red(vtfpp_image_format_e format); + +SOURCEPP_API int8_t vtfpp_image_format_details_green(vtfpp_image_format_e format); + +SOURCEPP_API int8_t vtfpp_image_format_details_decompressed_green(vtfpp_image_format_e format); + +SOURCEPP_API int8_t vtfpp_image_format_details_blue(vtfpp_image_format_e format); + +SOURCEPP_API int8_t vtfpp_image_format_details_decompressed_blue(vtfpp_image_format_e format); + +SOURCEPP_API int8_t vtfpp_image_format_details_alpha(vtfpp_image_format_e format); + +SOURCEPP_API int8_t vtfpp_image_format_details_decompressed_alpha(vtfpp_image_format_e format); + +SOURCEPP_API int8_t vtfpp_image_format_details_bpp(vtfpp_image_format_e format); + +SOURCEPP_API vtfpp_image_format_e vtfpp_image_format_details_container_format(vtfpp_image_format_e format); + +SOURCEPP_API int vtfpp_image_format_details_large(vtfpp_image_format_e format); + +SOURCEPP_API int vtfpp_image_format_details_decimal(vtfpp_image_format_e format); + +SOURCEPP_API int vtfpp_image_format_details_compressed(vtfpp_image_format_e format); + +SOURCEPP_API int vtfpp_image_format_details_transparent(vtfpp_image_format_e format); + +SOURCEPP_API int vtfpp_image_format_details_opaque(vtfpp_image_format_e format); + +SOURCEPP_API uint32_t vtfpp_image_dimensions_get_mip_dim(uint8_t mip, uint16_t dim); + +SOURCEPP_API uint8_t vtfpp_image_dimensions_get_recommended_mip_count_for_dim(vtfpp_image_format_e format, uint16_t width, uint16_t height); + +SOURCEPP_API uint8_t vtfpp_image_dimensions_get_actual_mip_count_for_dims_on_console(uint16_t width, uint16_t height); + +SOURCEPP_API uint32_t vtfpp_image_format_details_get_data_length(vtfpp_image_format_e format, uint16_t width, uint16_t height, uint16_t sliceCount); + +SOURCEPP_API uint32_t vtfpp_image_format_details_get_data_length_ex(vtfpp_image_format_e format, uint8_t mipCount, uint16_t frameCount, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t sliceCount); + +SOURCEPP_API int vtfpp_image_format_details_get_data_position(uint32_t* offset, uint32_t* length, vtfpp_image_format_e format, uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint8_t face, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t slice, uint16_t sliceCount); diff --git a/lang/c/include/vtfppc/PPL.h b/lang/c/include/vtfppc/PPL.h new file mode 100644 index 000000000..88034fe61 --- /dev/null +++ b/lang/c/include/vtfppc/PPL.h @@ -0,0 +1,74 @@ +#pragma once + +#include +#include + +#include "ImageConversion.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* vtfpp_ppl_handle_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +// REQUIRES MANUAL FREE: vtfpp_ppl_close +SOURCEPP_API vtfpp_ppl_handle_t vtfpp_ppl_create(uint32_t modelChecksum); + +// REQUIRES MANUAL FREE: vtfpp_ppl_close +SOURCEPP_API vtfpp_ppl_handle_t vtfpp_ppl_create_with_options(uint32_t modelChecksum, vtfpp_image_format_e format, uint32_t version); + +// REQUIRES MANUAL FREE: vtfpp_ppl_close +SOURCEPP_API vtfpp_ppl_handle_t vtfpp_ppl_open_from_mem(const unsigned char* buffer, size_t bufferLen); + +// REQUIRES MANUAL FREE: vtfpp_ppl_close +SOURCEPP_API vtfpp_ppl_handle_t vtfpp_ppl_open_from_file(const char* pplPath); + +SOURCEPP_API int vtfpp_ppl_is_valid(vtfpp_ppl_handle_t handle); + +SOURCEPP_API uint32_t vtfpp_ppl_get_version(vtfpp_ppl_handle_t handle); + +SOURCEPP_API void vtfpp_ppl_set_version(vtfpp_ppl_handle_t handle, uint32_t version); + +SOURCEPP_API uint32_t vtfpp_ppl_get_model_checksum(vtfpp_ppl_handle_t handle); + +SOURCEPP_API void vtfpp_ppl_set_model_checksum(vtfpp_ppl_handle_t handle, uint32_t modelChecksum); + +SOURCEPP_API vtfpp_image_format_e vtfpp_ppl_get_format(vtfpp_ppl_handle_t handle); + +SOURCEPP_API void vtfpp_ppl_set_format(vtfpp_ppl_handle_t handle, vtfpp_image_format_e format); + +SOURCEPP_API int vtfpp_ppl_has_image_for_lod(vtfpp_ppl_handle_t handle, uint32_t lod); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_uint32_t vtfpp_ppl_get_image_lods(vtfpp_ppl_handle_t handle); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_get_image_raw(vtfpp_ppl_handle_t handle, uint32_t* width, uint32_t* height, uint32_t lod); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_get_image_as(vtfpp_ppl_handle_t handle, uint32_t* width, uint32_t* height, vtfpp_image_format_e format, uint32_t lod); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_get_image_as_rgb888(vtfpp_ppl_handle_t handle, uint32_t* width, uint32_t* height, uint32_t lod); + +SOURCEPP_API int vtfpp_ppl_set_image_from_file(vtfpp_ppl_handle_t handle, const char* imagePath, uint32_t lod); + +SOURCEPP_API int vtfpp_ppl_set_image_from_file_with_options(vtfpp_ppl_handle_t handle, const char* imagePath, uint32_t resizedWidth, uint32_t resizedHeight, uint32_t lod, vtfpp_image_conversion_resize_filter_e filter); + +SOURCEPP_API int vtfpp_ppl_set_image_from_mem(vtfpp_ppl_handle_t handle, const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint32_t width, uint32_t height, uint32_t lod); + +SOURCEPP_API int vtfpp_ppl_set_image_from_mem_with_options(vtfpp_ppl_handle_t handle, const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint32_t width, uint32_t height, uint32_t resizedWidth, uint32_t resizedHeight, uint32_t lod, vtfpp_image_conversion_resize_filter_e filter); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_save_image_to_file(vtfpp_ppl_handle_t handle, const char* imagePath, uint32_t lod, vtfpp_image_conversion_file_format_e fileFormat); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_bake(vtfpp_ppl_handle_t handle); + +SOURCEPP_API int vtfpp_ppl_bake_to_file(vtfpp_ppl_handle_t handle, const char* pplPath); + +SOURCEPP_API void vtfpp_ppl_close(vtfpp_ppl_handle_t* handle); diff --git a/lang/c/include/vtfppc/SHT.h b/lang/c/include/vtfppc/SHT.h new file mode 100644 index 000000000..d60974713 --- /dev/null +++ b/lang/c/include/vtfppc/SHT.h @@ -0,0 +1,85 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + float x1; + float y1; + float x2; + float y2; +} vtfpp_sht_frame_bounds_t; + +typedef struct { + float duration; + vtfpp_sht_frame_bounds_t bounds[4]; +} vtfpp_sht_frame_t; + +#define VTFPP_SHT_FRAME_INVALID (vtfpp_sht_frame_t{.duration = 0.f}) + +typedef struct { + uint32_t id; + int32_t loop; + uint32_t frameCount; + float durationTotal; +} vtfpp_sht_sequence_t; + +#define VTFPP_SHT_SEQUENCE_INVALID (vtfpp_sht_sequence_t{.id = 0, .loop = 0, .frameCount = 0, .durationTotal = 0.f}) + +typedef void* vtfpp_sht_handle_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +// REQUIRES MANUAL FREE: vtfpp_sht_close +SOURCEPP_API vtfpp_sht_handle_t vtfpp_sht_create(); + +// REQUIRES MANUAL FREE: vtfpp_sht_close +SOURCEPP_API vtfpp_sht_handle_t vtfpp_sht_open_from_mem(const unsigned char* shtData, size_t shtLen); + +// REQUIRES MANUAL FREE: vtfpp_sht_close +SOURCEPP_API vtfpp_sht_handle_t vtfpp_sht_open_from_file(const char* shtPath); + +SOURCEPP_API int vtfpp_sht_is_valid(vtfpp_sht_handle_t handle); + +SOURCEPP_API uint32_t vtfpp_sht_get_version(vtfpp_sht_handle_t handle); + +SOURCEPP_API void vtfpp_sht_set_version(vtfpp_sht_handle_t handle, uint32_t version); + +SOURCEPP_API uint32_t vtfpp_sht_get_sequences_count(vtfpp_sht_handle_t handle); + +SOURCEPP_API vtfpp_sht_sequence_t vtfpp_sht_get_sequence_at_index(vtfpp_sht_handle_t handle, uint32_t index); + +SOURCEPP_API vtfpp_sht_sequence_t vtfpp_sht_get_sequence_with_id(vtfpp_sht_handle_t handle, uint32_t id); + +SOURCEPP_API void vtfpp_sht_set_sequence_at_index(vtfpp_sht_handle_t handle, uint32_t index, vtfpp_sht_sequence_t sequence); + +SOURCEPP_API void vtfpp_sht_set_sequence_with_id(vtfpp_sht_handle_t handle, uint32_t id, vtfpp_sht_sequence_t sequence); + +SOURCEPP_API void vtfpp_sht_add_sequence(vtfpp_sht_handle_t handle, vtfpp_sht_sequence_t sequence); + +SOURCEPP_API void vtfpp_sht_remove_sequence_at_index(vtfpp_sht_handle_t handle, uint32_t index); + +SOURCEPP_API void vtfpp_sht_remove_sequence_with_id(vtfpp_sht_handle_t handle, uint32_t id); + +SOURCEPP_API vtfpp_sht_frame_t vtfpp_sht_get_frame(vtfpp_sht_handle_t handle, uint32_t sequenceID, uint32_t index); + +SOURCEPP_API void vtfpp_sht_set_frame(vtfpp_sht_handle_t handle, uint32_t sequenceID, uint32_t index, vtfpp_sht_frame_t frame); + +SOURCEPP_API void vtfpp_sht_add_frame(vtfpp_sht_handle_t handle, uint32_t sequenceID, vtfpp_sht_frame_t frame); + +SOURCEPP_API void vtfpp_sht_remove_frame(vtfpp_sht_handle_t handle, uint32_t sequenceID, uint32_t index); + +SOURCEPP_API uint8_t vtfpp_sht_get_frame_bounds_count(vtfpp_sht_handle_t handle); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_sht_bake(vtfpp_sht_handle_t handle); + +SOURCEPP_API int vtfpp_sht_bake_to_file(vtfpp_sht_handle_t handle, const char* shtPath); + +SOURCEPP_API void vtfpp_sht_close(vtfpp_sht_handle_t* handle); diff --git a/lang/c/include/vtfppc/TTX.h b/lang/c/include/vtfppc/TTX.h new file mode 100644 index 000000000..96933d9f9 --- /dev/null +++ b/lang/c/include/vtfppc/TTX.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include + +#include "VTF.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* vtfpp_ttx_handle_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +// REQUIRES MANUAL FREE: vtfpp_ttx_close +SOURCEPP_API vtfpp_ttx_handle_t vtfpp_ttx_create(vtfpp_vtf_handle_t vtf); + +// REQUIRES MANUAL FREE: vtfpp_ttx_close +SOURCEPP_API vtfpp_ttx_handle_t vtfpp_ttx_open_from_mem(const unsigned char* tthData, size_t tthLen, const unsigned char* ttzData, size_t ttzLen); + +// REQUIRES MANUAL FREE: vtfpp_ttx_close +SOURCEPP_API vtfpp_ttx_handle_t vtfpp_ttx_open_from_file(const char* tthPath, const char* ttzPath); + +SOURCEPP_API int vtfpp_ttx_is_valid(vtfpp_ttx_handle_t handle); + +SOURCEPP_API uint8_t vtfpp_ttx_get_major_version(vtfpp_ttx_handle_t handle); + +SOURCEPP_API uint8_t vtfpp_ttx_get_minor_version(vtfpp_ttx_handle_t handle); + +SOURCEPP_API void vtfpp_ttx_set_version(vtfpp_ttx_handle_t handle, uint8_t majorVersion, uint8_t minorVersion); + +SOURCEPP_API void vtfpp_ttx_set_major_version(vtfpp_ttx_handle_t handle, uint8_t majorVersion); + +SOURCEPP_API void vtfpp_ttx_set_minor_version(vtfpp_ttx_handle_t handle, uint8_t minorVersion); + +SOURCEPP_API uint8_t vtfpp_ttx_get_aspect_ratio_type(vtfpp_ttx_handle_t handle); + +SOURCEPP_API void vtfpp_ttx_set_aspect_ratio_type(vtfpp_ttx_handle_t handle, uint8_t aspectRatioType); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_uint64_t vtfpp_ttx_get_mip_flags(vtfpp_ttx_handle_t handle); + +SOURCEPP_API void vtfpp_ttx_set_mip_flags(vtfpp_ttx_handle_t handle, const uint64_t* mipFlags, size_t mipFlagsLen); + +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_ttx_get_vtf(vtfpp_ttx_handle_t handle); + +SOURCEPP_API void vtfpp_ttx_set_vtf(vtfpp_ttx_handle_t handle, vtfpp_vtf_handle_t vtf); + +SOURCEPP_API int16_t vtfpp_ttx_get_compression_level(vtfpp_ttx_handle_t handle); + +SOURCEPP_API void vtfpp_ttx_set_compression_level(vtfpp_ttx_handle_t handle, int16_t compressionLevel); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_ttx_bake(vtfpp_ttx_handle_t handle, size_t* tthLen, size_t* ttzLen); + +SOURCEPP_API int vtfpp_ttx_bake_to_file(vtfpp_ttx_handle_t handle, const char* tthPath, const char* ttzPath); + +SOURCEPP_API void vtfpp_ttx_close(vtfpp_ttx_handle_t* handle); diff --git a/lang/c/include/vtfppc/VTF.h b/lang/c/include/vtfppc/VTF.h new file mode 100644 index 000000000..10c732916 --- /dev/null +++ b/lang/c/include/vtfppc/VTF.h @@ -0,0 +1,366 @@ +#pragma once + +#include +#include +#include + +#include "ImageConversion.h" +#include "SHT.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + VTFPP_COMPRESSION_METHOD_DEFLATE = 8, + VTFPP_COMPRESSION_METHOD_ZSTD = 93, + VTFPP_COMPRESSION_METHOD_CONSOLE_LZMA = 0x360, +} vtfpp_compression_method_e; + +typedef enum { + VTFPP_RESOURCE_TYPE_UNKNOWN, + VTFPP_RESOURCE_TYPE_THUMBNAIL_DATA, + VTFPP_RESOURCE_TYPE_IMAGE_DATA, + VTFPP_RESOURCE_TYPE_PARTICLE_SHEET_DATA, + VTFPP_RESOURCE_TYPE_CRC, + VTFPP_RESOURCE_TYPE_LOD_CONTROL_INFO, + VTFPP_RESOURCE_TYPE_EXTENDED_FLAGS, + VTFPP_RESOURCE_TYPE_KEYVALUES_DATA, + VTFPP_RESOURCE_TYPE_AUX_COMPRESSION, +} vtfpp_resource_type_e; + +typedef enum { + VTFPP_RESOURCE_FLAG_NONE = 0, + VTFPP_RESOURCE_FLAG_LOCAL_DATA = 1 << 1, +} vtfpp_resource_flags_e; + +typedef const void* vtfpp_resource_handle_t; + +typedef enum { + VTFPP_VTF_FLAG_NONE = 0, + VTFPP_VTF_FLAG_POINT_SAMPLE = 1 << 0, + VTFPP_VTF_FLAG_TRILINEAR = 1 << 1, + VTFPP_VTF_FLAG_CLAMP_S = 1 << 2, + VTFPP_VTF_FLAG_CLAMP_T = 1 << 3, + VTFPP_VTF_FLAG_ANISOTROPIC = 1 << 4, + VTFPP_VTF_FLAG_HINT_DXT5 = 1 << 5, + VTFPP_VTF_FLAG_PWL_CORRECTED = 1 << 6, + VTFPP_VTF_FLAG_NORMAL = 1 << 7, + VTFPP_VTF_FLAG_NO_MIP = 1 << 8, + VTFPP_VTF_FLAG_NO_LOD = 1 << 9, + VTFPP_VTF_FLAG_LOAD_ALL_MIPS = 1 << 10, + VTFPP_VTF_FLAG_PROCEDURAL = 1 << 11, + VTFPP_VTF_FLAG_ONE_BIT_ALPHA = 1 << 12, + VTFPP_VTF_FLAG_MULTI_BIT_ALPHA = 1 << 13, + VTFPP_VTF_FLAG_ENVMAP = 1 << 14, + VTFPP_VTF_FLAG_RENDERTARGET = 1 << 15, + VTFPP_VTF_FLAG_DEPTH_RENDERTARGET = 1 << 16, + VTFPP_VTF_FLAG_NO_DEBUG_OVERRIDE = 1 << 17, + VTFPP_VTF_FLAG_SINGLE_COPY = 1 << 18, + VTFPP_VTF_FLAG_SRGB = 1 << 19, + VTFPP_VTF_FLAG_DEFAULT_POOL = 1 << 20, + VTFPP_VTF_FLAG_COMBINED = 1 << 21, + VTFPP_VTF_FLAG_ASYNC_DOWNLOAD = 1 << 22, + VTFPP_VTF_FLAG_NO_DEPTH_BUFFER = 1 << 23, + VTFPP_VTF_FLAG_SKIP_INITIAL_DOWNLOAD = 1 << 24, + VTFPP_VTF_FLAG_CLAMP_U = 1 << 25, + VTFPP_VTF_FLAG_VERTEX_TEXTURE = 1 << 26, + VTFPP_VTF_FLAG_XBOX_PRESWIZZLED = 1 << 26, + VTFPP_VTF_FLAG_SSBUMP = 1 << 27, + VTFPP_VTF_FLAG_XBOX_CACHEABLE = 1 << 27, + VTFPP_VTF_FLAG_LOAD_MOST_MIPS = 1 << 28, + VTFPP_VTF_FLAG_BORDER = 1 << 29, + VTFPP_VTF_FLAG_YCOCG = 1 << 30, + VTFPP_VTF_FLAG_ASYNC_SKIP_INITIAL_LOW_RES = 1 << 31, +} vtfpp_vtf_flags_e; + +#define VTFPP_VTF_FLAGS_MASK_AFTER_V7_3 (VTFPP_VTF_FLAG_FLAG_LOAD_ALL_MIPS | VTFPP_VTF_FLAG_SRGB | VTFPP_VTF_FLAG_DEFAULT_POOL | VTFPP_VTF_FLAG_COMBINED | VTFPP_VTF_FLAG_ASYNC_DOWNLOAD | VTFPP_VTF_FLAG_SKIP_INITIAL_DOWNLOAD | VTFPP_VTF_FLAG_LOAD_MOST_MIPS | VTFPP_VTF_FLAG_YCOCG | VTFPP_VTF_FLAG_ASYNC_SKIP_INITIAL_LOW_RES) +#define VTFPP_VTF_FLAGS_MASK_INTERNAL (VTFPP_VTF_FLAG_NO_MIP | VTFPP_VTF_FLAG_ENVMAP) +#define VTFPP_VTF_FLAGS_MASK_SRGB (VTFPP_VTF_FLAG_PWL_CORRECTED | VTFPP_VTF_FLAG_SRGB) + +typedef enum { + VTFPP_VTF_PLATFORM_UNKNOWN = 0x000, + VTFPP_VTF_PLATFORM_PC = 0x001, + VTFPP_VTF_PLATFORM_PS3_PORTAL2 = 0x003, + VTFPP_VTF_PLATFORM_PS3_ORANGEBOX = 0x333, + VTFPP_VTF_PLATFORM_X360 = 0x360, +} vtfpp_vtf_platform_e; + +#define VTFPP_VTF_FORMAT_UNCHANGED ((vtfpp_image_format_e) -2) +#define VTFPP_VTF_FORMAT_DEFAULT ((vtfpp_image_format_e) -1) + +typedef struct { + uint32_t majorVersion; + uint32_t minorVersion; + vtfpp_image_format_e outputFormat; + vtfpp_image_conversion_resize_method_e widthResizeMethod; + vtfpp_image_conversion_resize_method_e heightResizeMethod; + vtfpp_image_conversion_resize_filter_e filter; + vtfpp_vtf_flags_e flags; + uint16_t initialFrameCount; + uint16_t startFrame; + int isCubeMap; + int hasSphereMap; + uint16_t initialSliceCount; + int computeTransparencyFlags; + int computeMips; + int computeThumbnail; + int computeReflectivity; + vtfpp_vtf_platform_e platform; + int16_t compressionLevel; + vtfpp_compression_method_e compressionMethod; + float bumpMapScale; +} vtfpp_vtf_creation_options_t; + +#define VTFPP_VTF_CREATION_OPTIONS_DEFAULT (vtfpp_vtf_creation_options_t{ \ + .majorVersion = 7, \ + .minorVersion = 4, \ + .outputFormat = VTFPP_VTF_FORMAT_DEFAULT, \ + .widthResizeMethod = VTFPP_IMAGE_CONVERSION_RESIZE_METHOD_POWER_OF_TWO_BIGGER, \ + .heightResizeMethod = VTFPP_IMAGE_CONVERSION_RESIZE_METHOD_POWER_OF_TWO_BIGGER, \ + .filter = VTFPP_IMAGE_CONVERSION_RESIZE_FILTER_DEFAULT, \ + .flags = VTFPP_VTF_FLAG_NONE, \ + .initialFrameCount = 1, \ + .startFrame = 0, \ + .isCubeMap = 0, \ + .hasSphereMap = 0, \ + .initialSliceCount = 1, \ + .computeTransparencyFlags = 1, \ + .computeMips = 1, \ + .computeThumbnail = 1, \ + .computeReflectivity = 1, \ + .platform = VTFPP_VTF_PLATFORM_PC, \ + .compressionLevel = -1, \ + .compressionMethod = VTFPP_COMPRESSION_METHOD_ZSTD, \ + .bumpMapScale = 1.f, \ +}) + +typedef void* vtfpp_vtf_handle_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +SOURCEPP_API vtfpp_resource_type_e vtfpp_resource_get_type(vtfpp_resource_handle_t handle); + +SOURCEPP_API vtfpp_resource_flags_e vtfpp_resource_get_flags(vtfpp_resource_handle_t handle); + +SOURCEPP_API const unsigned char* vtfpp_resource_get_data(vtfpp_resource_handle_t handle, size_t* dataLen); + +// REQUIRES MANUAL FREE: vtfpp_sht_close +SOURCEPP_API vtfpp_sht_handle_t vtfpp_resource_get_data_as_particle_sheet(vtfpp_resource_handle_t handle); + +SOURCEPP_API uint32_t vtfpp_resource_get_data_as_crc(vtfpp_resource_handle_t handle); + +SOURCEPP_API uint32_t vtfpp_resource_get_data_as_extended_flags(vtfpp_resource_handle_t handle); + +SOURCEPP_API void vtfpp_resource_get_data_as_lod(vtfpp_resource_handle_t handle, uint8_t* u, uint8_t* v, uint8_t* u360, uint8_t* v360); + +// REQUIRES MANUAL FREE: sourcepp_string_free +SOURCEPP_API sourcepp_string_t vtfpp_resource_get_data_as_keyvalues_data(vtfpp_resource_handle_t handle); + +SOURCEPP_API int16_t vtfpp_resource_get_data_as_aux_compression_level(vtfpp_resource_handle_t handle); + +SOURCEPP_API vtfpp_compression_method_e vtfpp_resource_get_data_as_aux_compression_method(vtfpp_resource_handle_t handle); + +SOURCEPP_API uint32_t vtfpp_resource_get_data_as_aux_compression_length(vtfpp_resource_handle_t handle, uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint16_t face, uint16_t faceCount); + +// REQUIRES MANUAL FREE: vtfpp_vtf_close +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_empty(); + +// REQUIRES MANUAL FREE: vtfpp_vtf_close +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_mem(const unsigned char* vtfData, size_t vtfLen, int parseHeaderOnly); + +// REQUIRES MANUAL FREE: vtfpp_vtf_close +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_file(const char* vtfPath, int parseHeaderOnly); + +SOURCEPP_API int vtfpp_vtf_is_valid(vtfpp_vtf_handle_t handle); + +SOURCEPP_API int vtfpp_vtf_create_from_mem_and_bake(const unsigned char* imageData, size_t imageLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, const char* vtfPath, vtfpp_vtf_creation_options_t options); + +SOURCEPP_API int vtfpp_vtf_create_blank_and_bake(vtfpp_image_format_e format, uint16_t width, uint16_t height, const char* vtfPath, vtfpp_vtf_creation_options_t options); + +// REQUIRES MANUAL FREE: vtfpp_vtf_close +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_from_mem(const unsigned char* imageData, size_t imageLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, vtfpp_vtf_creation_options_t options); + +// REQUIRES MANUAL FREE: vtfpp_vtf_close +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_blank(vtfpp_image_format_e format, uint16_t width, uint16_t height, vtfpp_vtf_creation_options_t options); + +SOURCEPP_API int vtfpp_vtf_create_from_file_and_bake(const char* imagePath, const char* vtfPath, vtfpp_vtf_creation_options_t options); + +// REQUIRES MANUAL FREE: vtfpp_vtf_close +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_from_file(const char* imagePath, vtfpp_vtf_creation_options_t options); + +SOURCEPP_API vtfpp_vtf_platform_e vtfpp_vtf_get_platform(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_platform(vtfpp_vtf_handle_t handle, vtfpp_vtf_platform_e platform); + +SOURCEPP_API uint32_t vtfpp_vtf_get_major_version(vtfpp_vtf_handle_t handle); + +SOURCEPP_API uint32_t vtfpp_vtf_get_minor_version(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_version(vtfpp_vtf_handle_t handle, uint32_t majorVersion, uint32_t minorVersion); + +SOURCEPP_API void vtfpp_vtf_set_major_version(vtfpp_vtf_handle_t handle, uint32_t majorVersion); + +SOURCEPP_API void vtfpp_vtf_set_minor_version(vtfpp_vtf_handle_t handle, uint32_t minorVersion); + +SOURCEPP_API vtfpp_image_conversion_resize_method_e vtfpp_vtf_get_image_width_resize_method(vtfpp_vtf_handle_t handle); + +SOURCEPP_API vtfpp_image_conversion_resize_method_e vtfpp_vtf_get_image_height_resize_method(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_image_resize_methods(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_method_e imageWidthResizeMethod, vtfpp_image_conversion_resize_method_e imageHeightResizeMethod); + +SOURCEPP_API void vtfpp_vtf_set_image_width_resize_method(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_method_e imageWidthResizeMethod); + +SOURCEPP_API void vtfpp_vtf_set_image_height_resize_method(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_method_e imageHeightResizeMethod); + +SOURCEPP_API uint16_t vtfpp_vtf_get_width(vtfpp_vtf_handle_t handle, uint8_t mip); + +SOURCEPP_API uint16_t vtfpp_vtf_get_height(vtfpp_vtf_handle_t handle, uint8_t mip); + +SOURCEPP_API void vtfpp_vtf_set_size(vtfpp_vtf_handle_t handle, uint16_t width, uint16_t height, vtfpp_image_conversion_resize_filter_e filter); + +SOURCEPP_API vtfpp_vtf_flags_e vtfpp_vtf_get_flags(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_flags(vtfpp_vtf_handle_t handle, vtfpp_vtf_flags_e flags); + +SOURCEPP_API void vtfpp_vtf_add_flags(vtfpp_vtf_handle_t handle, vtfpp_vtf_flags_e flags); + +SOURCEPP_API void vtfpp_vtf_remove_flags(vtfpp_vtf_handle_t handle, vtfpp_vtf_flags_e flags); + +SOURCEPP_API void vtfpp_vtf_compute_transparency_flags(vtfpp_vtf_handle_t handle); + +SOURCEPP_API vtfpp_image_format_e vtfpp_vtf_get_default_compressed_format(vtfpp_image_format_e inputFormat, uint32_t majorVersion, uint32_t minorVersion); + +SOURCEPP_API vtfpp_image_format_e vtfpp_vtf_get_format(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_format(vtfpp_vtf_handle_t handle, vtfpp_image_format_e format, vtfpp_image_conversion_resize_filter_e filter); + +SOURCEPP_API uint8_t vtfpp_vtf_get_mip_count(vtfpp_vtf_handle_t handle); + +SOURCEPP_API int vtfpp_vtf_set_mip_count(vtfpp_vtf_handle_t handle, uint8_t mipCount); + +SOURCEPP_API int vtfpp_vtf_set_recommended_mip_count(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_compute_mips(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_filter_e filter); + +SOURCEPP_API uint16_t vtfpp_vtf_get_frame_count(vtfpp_vtf_handle_t handle); + +SOURCEPP_API int vtfpp_vtf_set_frame_count(vtfpp_vtf_handle_t handle, uint16_t frameCount); + +SOURCEPP_API uint8_t vtfpp_vtf_get_face_count(vtfpp_vtf_handle_t handle); + +SOURCEPP_API int vtfpp_vtf_set_face_count(vtfpp_vtf_handle_t handle, int isCubemap, int hasSphereMap); + +SOURCEPP_API uint16_t vtfpp_vtf_get_slice_count(vtfpp_vtf_handle_t handle); + +SOURCEPP_API int vtfpp_vtf_set_slice_count(vtfpp_vtf_handle_t handle, uint16_t sliceCount); + +SOURCEPP_API int vtfpp_vtf_set_frame_face_and_slice_count(vtfpp_vtf_handle_t handle, uint16_t frameCount, int isCubemap, int hasSphereMap, uint16_t sliceCount); + +SOURCEPP_API uint16_t vtfpp_vtf_get_start_frame(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_start_frame(vtfpp_vtf_handle_t handle, uint16_t startFrame); + +SOURCEPP_API void vtfpp_vtf_get_reflectivity(vtfpp_vtf_handle_t handle, float* r, float* g, float* b); + +SOURCEPP_API void vtfpp_vtf_set_reflectivity(vtfpp_vtf_handle_t handle, float r, float g, float b); + +SOURCEPP_API void vtfpp_vtf_compute_reflectivity(vtfpp_vtf_handle_t handle); + +SOURCEPP_API float vtfpp_vtf_get_bumpmap_scale(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_bumpmap_scale(vtfpp_vtf_handle_t handle, float bumpMapScale); + +SOURCEPP_API vtfpp_image_format_e vtfpp_vtf_get_thumbnail_format(vtfpp_vtf_handle_t handle); + +SOURCEPP_API uint8_t vtfpp_vtf_get_thumbnail_width(vtfpp_vtf_handle_t handle); + +SOURCEPP_API uint8_t vtfpp_vtf_get_thumbnail_height(vtfpp_vtf_handle_t handle); + +SOURCEPP_API uint32_t vtfpp_vtf_get_resources_count(vtfpp_vtf_handle_t handle); + +SOURCEPP_API vtfpp_resource_handle_t vtfpp_vtf_get_resource_at_index(vtfpp_vtf_handle_t handle, uint32_t index); + +SOURCEPP_API vtfpp_resource_handle_t vtfpp_vtf_get_resource_with_type(vtfpp_vtf_handle_t handle, vtfpp_resource_type_e type); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_particle_sheet_frame_data_raw(vtfpp_vtf_handle_t handle, uint16_t* width, uint16_t* height, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_particle_sheet_frame_data_as(vtfpp_vtf_handle_t handle, vtfpp_image_format_e format, uint16_t* width, uint16_t* height, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_particle_sheet_frame_data_as_rgba8888(vtfpp_vtf_handle_t handle, uint16_t* width, uint16_t* height, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice); + +SOURCEPP_API void vtfpp_vtf_set_particle_sheet_resource(vtfpp_vtf_handle_t handle, vtfpp_sht_handle_t sht); + +SOURCEPP_API void vtfpp_vtf_remove_particle_sheet_resource(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_crc_resource(vtfpp_vtf_handle_t handle, uint32_t value); + +SOURCEPP_API void vtfpp_vtf_remove_crc_resource(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_lod_resource(vtfpp_vtf_handle_t handle, uint8_t u, uint8_t v, uint8_t u360, uint8_t v360); + +SOURCEPP_API void vtfpp_vtf_remove_lod_resource(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_extended_flags_resource(vtfpp_vtf_handle_t handle, uint32_t value); + +SOURCEPP_API void vtfpp_vtf_remove_extended_flags_resource(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_keyvalues_data_resource(vtfpp_vtf_handle_t handle, const char* value); + +SOURCEPP_API void vtfpp_vtf_remove_keyvalues_data_resource(vtfpp_vtf_handle_t handle); + +SOURCEPP_API int16_t vtfpp_vtf_get_compression_level(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_compression_level(vtfpp_vtf_handle_t handle, int16_t compressionLevel); + +SOURCEPP_API vtfpp_compression_method_e vtfpp_vtf_get_compression_method(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_compression_method(vtfpp_vtf_handle_t handle, vtfpp_compression_method_e compressionMethod); + +SOURCEPP_API int vtfpp_vtf_has_image_data(vtfpp_vtf_handle_t handle); + +SOURCEPP_API int vtfpp_vtf_image_data_is_srgb(vtfpp_vtf_handle_t handle); + +SOURCEPP_API const unsigned char* vtfpp_vtf_get_image_data_raw(vtfpp_vtf_handle_t handle, size_t* imageLen, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_image_data_as(vtfpp_vtf_handle_t handle, vtfpp_image_format_e format, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_image_data_as_rgba8888(vtfpp_vtf_handle_t handle, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice); + +SOURCEPP_API int vtfpp_vtf_set_image_from_mem(vtfpp_vtf_handle_t handle, const unsigned char* imageData, size_t imageLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, vtfpp_image_conversion_resize_filter_e filter, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice); + +SOURCEPP_API int vtfpp_vtf_set_image_from_file(vtfpp_vtf_handle_t handle, const char* imagePath, vtfpp_image_conversion_resize_filter_e filter, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice); + +SOURCEPP_API int vtfpp_vtf_save_image_to_file(vtfpp_vtf_handle_t handle, const char* imagePath, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice, vtfpp_image_conversion_file_format_e fileFormat); + +SOURCEPP_API int vtfpp_vtf_has_thumbnail_data(vtfpp_vtf_handle_t handle); + +SOURCEPP_API const unsigned char* vtfpp_vtf_get_thumbnail_data_raw(vtfpp_vtf_handle_t handle, size_t* imageLen); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_thumbnail_data_as(vtfpp_vtf_handle_t handle, vtfpp_image_format_e format); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_thumbnail_data_as_rgba8888(vtfpp_vtf_handle_t handle); + +SOURCEPP_API void vtfpp_vtf_set_thumbnail(vtfpp_vtf_handle_t handle, const unsigned char* imageData, size_t imageLen, vtfpp_image_format_e format, uint16_t width, uint16_t height); + +SOURCEPP_API void vtfpp_vtf_compute_thumbnail(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_filter_e filter); + +SOURCEPP_API void vtfpp_vtf_remove_thumbnail(vtfpp_vtf_handle_t handle); + +SOURCEPP_API int vtfpp_vtf_save_thumbnail_to_file(vtfpp_vtf_handle_t handle, const char* imagePath, vtfpp_image_conversion_file_format_e fileFormat); + +// REQUIRES MANUAL FREE: sourcepp_buffer_free +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_bake(vtfpp_vtf_handle_t handle); + +SOURCEPP_API int vtfpp_vtf_bake_to_file(vtfpp_vtf_handle_t handle, const char* vtfPath); + +SOURCEPP_API void vtfpp_vtf_close(vtfpp_vtf_handle_t* handle); diff --git a/lang/c/include/vtfppc/vtfpp.h b/lang/c/include/vtfppc/vtfpp.h new file mode 100644 index 000000000..1a7591b4a --- /dev/null +++ b/lang/c/include/vtfppc/vtfpp.h @@ -0,0 +1,13 @@ +#pragma once + +/* + * This header is just included so consumers of this library can + * include it the same way as any of the other SourcePP libraries. + */ + +#include "ImageConversion.h" +#include "ImageFormats.h" +#include "PPL.h" +#include "SHT.h" +#include "TTX.h" +#include "VTF.h" diff --git a/lang/c/src/gameppc/gamepp.cpp b/lang/c/src/gameppc/gamepp.cpp index 12c660899..60dbd5d6a 100644 --- a/lang/c/src/gameppc/gamepp.cpp +++ b/lang/c/src/gameppc/gamepp.cpp @@ -17,6 +17,8 @@ SOURCEPP_API gamepp_game_instance_handle_t gamepp_find_game_instance() { } SOURCEPP_API gamepp_game_instance_handle_t gamepp_find_game_instance_with_name(const char* windowNameOverride) { + SOURCEPP_EARLY_RETURN_VAL(windowNameOverride, nullptr); + auto instance = GameInstance::find(windowNameOverride); if (!instance) { return nullptr; diff --git a/lang/c/src/vtfppc/Convert.cpp b/lang/c/src/vtfppc/Convert.cpp new file mode 100644 index 000000000..2b1e7c26b --- /dev/null +++ b/lang/c/src/vtfppc/Convert.cpp @@ -0,0 +1,117 @@ +#include + +#include +#include +#include +#include + +using namespace vtfpp; + +ImageConversion::ResizeMethod Convert::resizeMethod(vtfpp_image_conversion_resize_method_e method) { + return static_cast(method); +} + +vtfpp_image_conversion_resize_method_e Convert::resizeMethod(vtfpp::ImageConversion::ResizeMethod method) { + return static_cast(method); +} + +ImageConversion::ResizeFilter Convert::resizeFilter(vtfpp_image_conversion_resize_filter_e filter) { + return static_cast(filter); +} + +ImageConversion::FileFormat Convert::fileFormat(vtfpp_image_conversion_file_format_e fileFormat) { + return static_cast(fileFormat); +} + +ImageFormat Convert::imageFormat(vtfpp_image_format_e format) { + return static_cast(format); +} + +vtfpp_image_format_e Convert::imageFormat(vtfpp::ImageFormat format) { + return static_cast(format); +} + +PPL* Convert::ppl(vtfpp_ppl_handle_t handle) { + return static_cast(handle); +} + +SHT* Convert::sht(vtfpp_sht_handle_t handle) { + return static_cast(handle); +} + +TTX* Convert::ttx(vtfpp_ttx_handle_t handle) { + return static_cast(handle); +} + +CompressionMethod Convert::compressionMethod(vtfpp_compression_method_e method) { + return static_cast(method); +} + +vtfpp_compression_method_e Convert::compressionMethod(CompressionMethod method) { + return static_cast(method); +} + +Resource::Type Convert::resourceType(vtfpp_resource_type_e type) { + return static_cast(type); +} + +vtfpp_resource_type_e Convert::resourceType(Resource::Type type) { + return static_cast(type); +} + +Resource::Flags Convert::resourceFlags(vtfpp_resource_flags_e flags) { + return static_cast(flags); +} + +vtfpp_resource_flags_e Convert::resourceFlags(Resource::Flags flags) { + return static_cast(flags); +} + +const Resource* Convert::resource(vtfpp_resource_handle_t resource) { + return static_cast(resource); +} + +VTF::Flags Convert::vtfFlags(vtfpp_vtf_flags_e flags) { + return static_cast(flags); +} + +vtfpp_vtf_flags_e Convert::vtfFlags(VTF::Flags flags) { + return static_cast(flags); +} + +VTF::Platform Convert::vtfPlatform(vtfpp_vtf_platform_e platform) { + return static_cast(platform); +} + +vtfpp_vtf_platform_e Convert::vtfPlatform(VTF::Platform platform) { + return static_cast(platform); +} + +VTF::CreationOptions Convert::vtfCreationOptions(vtfpp_vtf_creation_options_t options) { + return { + .majorVersion = options.majorVersion, + .minorVersion = options.minorVersion, + .outputFormat = Convert::imageFormat(options.outputFormat), + .widthResizeMethod = Convert::resizeMethod(options.widthResizeMethod), + .heightResizeMethod = Convert::resizeMethod(options.heightResizeMethod), + .filter = Convert::resizeFilter(options.filter), + .flags = Convert::vtfFlags(options.flags), + .initialFrameCount = options.initialFrameCount, + .startFrame = options.startFrame, + .isCubeMap = static_cast(options.isCubeMap), + .hasSphereMap = static_cast(options.hasSphereMap), + .initialSliceCount = options.initialSliceCount, + .computeTransparencyFlags = static_cast(options.computeTransparencyFlags), + .computeMips = static_cast(options.computeMips), + .computeThumbnail = static_cast(options.computeThumbnail), + .computeReflectivity = static_cast(options.computeReflectivity), + .platform = Convert::vtfPlatform(options.platform), + .compressionLevel = options.compressionLevel, + .compressionMethod = Convert::compressionMethod(options.compressionMethod), + .bumpMapScale = options.bumpMapScale, + }; +} + +VTF* Convert::vtf(vtfpp_vtf_handle_t handle) { + return static_cast(handle); +} diff --git a/lang/c/src/vtfppc/ImageConversion.cpp b/lang/c/src/vtfppc/ImageConversion.cpp new file mode 100644 index 000000000..bea646982 --- /dev/null +++ b/lang/c/src/vtfppc/ImageConversion.cpp @@ -0,0 +1,138 @@ +#include + +#include + +#include +#include + +using namespace vtfpp; + +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_image_data_to_format(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e oldFormat, vtfpp_image_format_e newFormat, uint16_t width, uint16_t height) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(oldFormat != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(newFormat != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(ImageConversion::convertImageDataToFormat({reinterpret_cast(buffer), bufferLen}, static_cast(oldFormat), static_cast(newFormat), width, height)); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_convert_several_image_data_to_format(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e oldFormat, vtfpp_image_format_e newFormat, uint8_t mipCount, uint16_t frameCount, uint16_t faceCount, uint16_t width, uint16_t height, uint16_t sliceCount) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(oldFormat != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(newFormat != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(mipCount, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(frameCount, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(faceCount == 0 || faceCount == 6 || faceCount == 7, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(sliceCount, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(ImageConversion::convertSeveralImageDataToFormat({reinterpret_cast(buffer), bufferLen}, static_cast(oldFormat), static_cast(newFormat), mipCount, frameCount, faceCount, width, height, sliceCount)); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + + const auto faces = ImageConversion::convertHDRIToCubeMap({reinterpret_cast(buffer), bufferLen}, static_cast(format), width, height); + std::vector out; + for (int i = 0; i < faces.size(); i++) { + out.insert(out.end(), faces[i].begin(), faces[i].end()); + } + return Convert::toBuffer(out); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_hdri_to_cubemap_ex(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, uint16_t resolution, int bilinear) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + + const auto faces = ImageConversion::convertHDRIToCubeMap({reinterpret_cast(buffer), bufferLen}, static_cast(format), width, height, resolution, bilinear); + std::vector out; + for (int i = 0; i < faces.size(); i++) { + out.insert(out.end(), faces[i].begin(), faces[i].end()); + } + return Convert::toBuffer(out); +} + +SOURCEPP_API vtfpp_image_conversion_file_format_e vtfpp_image_conversion_get_default_file_format_for_image_format(vtfpp_image_format_e format) { + return static_cast(ImageConversion::getDefaultFileFormatForImageFormat(static_cast(format))); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_image_data_to_file(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, vtfpp_image_conversion_file_format_e fileFormat) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(ImageConversion::convertImageDataToFile({reinterpret_cast(buffer), bufferLen}, static_cast(format), width, height, static_cast(fileFormat))); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_convert_file_to_image_data(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e* format, int* width, int* height, int* frameCount) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(format, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(frameCount, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(ImageConversion::convertFileToImageData({reinterpret_cast(buffer), bufferLen}, reinterpret_cast(*format), *width, *height, *frameCount)); +} + +SOURCEPP_API uint16_t vtfpp_image_conversion_get_resized_dim(uint16_t n, vtfpp_image_conversion_resize_method_e method) { + return ImageConversion::getResizedDim(n, static_cast(method)); +} + +SOURCEPP_API void vtfpp_image_conversion_set_resized_dims(uint16_t* width, vtfpp_image_conversion_resize_method_e widthResize, uint16_t* height, vtfpp_image_conversion_resize_method_e heightResize) { + SOURCEPP_EARLY_RETURN(width); + SOURCEPP_EARLY_RETURN(height); + + ImageConversion::setResizedDims(*width, static_cast(widthResize), *height, static_cast(heightResize)); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t height, uint16_t newHeight, int srgb, vtfpp_image_conversion_resize_filter_e filter, vtfpp_image_conversion_resize_edge_e edge) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(newWidth, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(newHeight, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(ImageConversion::resizeImageData({reinterpret_cast(buffer), bufferLen}, static_cast(format), width, newWidth, height, newHeight, srgb, static_cast(filter), static_cast(edge))); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data_strict(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t* widthOut, vtfpp_image_conversion_resize_method_e widthResize, uint16_t height, uint16_t newHeight, uint16_t* heightOut, vtfpp_image_conversion_resize_method_e heightResize, bool srgb, vtfpp_image_conversion_resize_filter_e filter, vtfpp_image_conversion_resize_edge_e edge) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(newWidth, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(widthOut, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(newHeight, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(heightOut, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(ImageConversion::resizeImageDataStrict({reinterpret_cast(buffer), bufferLen}, static_cast(format), width, newWidth, *widthOut, static_cast(widthResize), height, newHeight, *heightOut, static_cast(heightResize), srgb, static_cast(filter), static_cast(edge))); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_crop_image_data(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t xOffset, uint16_t height, uint16_t newHeight, uint16_t yOffset) { + SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(newWidth, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(newHeight, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(ImageConversion::cropImageData({reinterpret_cast(buffer), bufferLen}, static_cast(format), width, newWidth, xOffset, height, newHeight, yOffset)); +} diff --git a/lang/c/src/vtfppc/ImageFormats.cpp b/lang/c/src/vtfppc/ImageFormats.cpp new file mode 100644 index 000000000..47e61acac --- /dev/null +++ b/lang/c/src/vtfppc/ImageFormats.cpp @@ -0,0 +1,94 @@ +#include + +#include + +#include + +using namespace vtfpp; + +SOURCEPP_API int8_t vtfpp_image_format_details_red(vtfpp_image_format_e format) { + return ImageFormatDetails::red(static_cast(format)); +} + +SOURCEPP_API int8_t vtfpp_image_format_details_decompressed_red(vtfpp_image_format_e format) { + return ImageFormatDetails::decompressedRed(static_cast(format)); +} + +SOURCEPP_API int8_t vtfpp_image_format_details_green(vtfpp_image_format_e format) { + return ImageFormatDetails::green(static_cast(format)); +} + +SOURCEPP_API int8_t vtfpp_image_format_details_decompressed_green(vtfpp_image_format_e format) { + return ImageFormatDetails::decompressedGreen(static_cast(format)); +} + +SOURCEPP_API int8_t vtfpp_image_format_details_blue(vtfpp_image_format_e format) { + return ImageFormatDetails::blue(static_cast(format)); +} + +SOURCEPP_API int8_t vtfpp_image_format_details_decompressed_blue(vtfpp_image_format_e format) { + return ImageFormatDetails::decompressedBlue(static_cast(format)); +} + +SOURCEPP_API int8_t vtfpp_image_format_details_alpha(vtfpp_image_format_e format) { + return ImageFormatDetails::alpha(static_cast(format)); +} + +SOURCEPP_API int8_t vtfpp_image_format_details_decompressed_alpha(vtfpp_image_format_e format) { + return ImageFormatDetails::decompressedAlpha(static_cast(format)); +} + +SOURCEPP_API int8_t vtfpp_image_format_details_bpp(vtfpp_image_format_e format) { + return ImageFormatDetails::bpp(static_cast(format)); +} + +SOURCEPP_API vtfpp_image_format_e vtfpp_image_format_details_container_format(vtfpp_image_format_e format) { + return static_cast(ImageFormatDetails::containerFormat(static_cast(format))); +} + +SOURCEPP_API int vtfpp_image_format_details_large(vtfpp_image_format_e format) { + return ImageFormatDetails::large(static_cast(format)); +} + +SOURCEPP_API int vtfpp_image_format_details_decimal(vtfpp_image_format_e format) { + return ImageFormatDetails::decimal(static_cast(format)); +} + +SOURCEPP_API int vtfpp_image_format_details_compressed(vtfpp_image_format_e format) { + return ImageFormatDetails::compressed(static_cast(format)); +} + +SOURCEPP_API int vtfpp_image_format_details_transparent(vtfpp_image_format_e format) { + return ImageFormatDetails::transparent(static_cast(format)); +} + +SOURCEPP_API int vtfpp_image_format_details_opaque(vtfpp_image_format_e format) { + return ImageFormatDetails::opaque(static_cast(format)); +} + +SOURCEPP_API uint32_t vtfpp_image_dimensions_get_mip_dim(uint8_t mip, uint16_t dim) { + return ImageDimensions::getMipDim(mip, dim); +} + +SOURCEPP_API uint8_t vtfpp_image_dimensions_get_recommended_mip_count_for_dim(vtfpp_image_format_e format, uint16_t width, uint16_t height) { + return ImageDimensions::getRecommendedMipCountForDims(static_cast(format), width, height); +} + +SOURCEPP_API uint8_t vtfpp_image_dimensions_get_actual_mip_count_for_dims_on_console(uint16_t width, uint16_t height) { + return ImageDimensions::getActualMipCountForDimsOnConsole(width, height); +} + +SOURCEPP_API uint32_t vtfpp_image_format_details_get_data_length(vtfpp_image_format_e format, uint16_t width, uint16_t height, uint16_t sliceCount) { + return ImageFormatDetails::getDataLength(static_cast(format), width, height, sliceCount); +} + +SOURCEPP_API uint32_t vtfpp_image_format_details_get_data_length_ex(vtfpp_image_format_e format, uint8_t mipCount, uint16_t frameCount, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t sliceCount) { + return ImageFormatDetails::getDataLength(static_cast(format), mipCount, frameCount, faceCount, width, height, sliceCount); +} + +SOURCEPP_API int vtfpp_image_format_details_get_data_position(uint32_t* offset, uint32_t* length, vtfpp_image_format_e format, uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint8_t face, uint8_t faceCount, uint16_t width, uint16_t height, uint16_t slice, uint16_t sliceCount) { + SOURCEPP_EARLY_RETURN_VAL(offset, -1); + SOURCEPP_EARLY_RETURN_VAL(length, -1); + + return ImageFormatDetails::getDataPosition(*offset, *length, static_cast(format), mip, mipCount, frame, frameCount, face, faceCount, width, height, slice, sliceCount); +} diff --git a/lang/c/src/vtfppc/PPL.cpp b/lang/c/src/vtfppc/PPL.cpp new file mode 100644 index 000000000..e7d20295a --- /dev/null +++ b/lang/c/src/vtfppc/PPL.cpp @@ -0,0 +1,186 @@ +#include + +#include + +#include +#include +#include + +using namespace vtfpp; + +SOURCEPP_API vtfpp_ppl_handle_t vtfpp_ppl_create(uint32_t modelChecksum) { + return new PPL{modelChecksum}; +} + +SOURCEPP_API vtfpp_ppl_handle_t vtfpp_ppl_create_with_options(uint32_t modelChecksum, vtfpp_image_format_e format, uint32_t version) { + return new PPL{modelChecksum, static_cast(format), version}; +} + +SOURCEPP_API vtfpp_ppl_handle_t vtfpp_ppl_open_from_mem(const unsigned char* buffer, size_t bufferLen) { + SOURCEPP_EARLY_RETURN_VAL(buffer, nullptr); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, nullptr); + + return new PPL{{reinterpret_cast(buffer), bufferLen}}; +} + +SOURCEPP_API vtfpp_ppl_handle_t vtfpp_ppl_open_from_file(const char* pplPath) { + SOURCEPP_EARLY_RETURN_VAL(pplPath, nullptr); + + return new PPL{pplPath}; +} + +SOURCEPP_API int vtfpp_ppl_is_valid(vtfpp_ppl_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::ppl(handle)->operator bool(); +} + +SOURCEPP_API uint32_t vtfpp_ppl_get_version(vtfpp_ppl_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::ppl(handle)->getVersion(); +} + +SOURCEPP_API void vtfpp_ppl_set_version(vtfpp_ppl_handle_t handle, uint32_t version) { + SOURCEPP_EARLY_RETURN(handle); + + return Convert::ppl(handle)->setVersion(version); +} + +SOURCEPP_API uint32_t vtfpp_ppl_get_model_checksum(vtfpp_ppl_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::ppl(handle)->getModelChecksum(); +} + +SOURCEPP_API void vtfpp_ppl_set_model_checksum(vtfpp_ppl_handle_t handle, uint32_t modelChecksum) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::ppl(handle)->setModelChecksum(modelChecksum); +} + +SOURCEPP_API vtfpp_image_format_e vtfpp_ppl_get_format(vtfpp_ppl_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_IMAGE_FORMAT_EMPTY); + + return static_cast(Convert::ppl(handle)->getFormat()); +} + +SOURCEPP_API void vtfpp_ppl_set_format(vtfpp_ppl_handle_t handle, vtfpp_image_format_e format) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::ppl(handle)->setFormat(static_cast(format)); +} + +SOURCEPP_API int vtfpp_ppl_has_image_for_lod(vtfpp_ppl_handle_t handle, uint32_t lod) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::ppl(handle)->hasImageForLOD(lod); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_get_image_lods(vtfpp_ppl_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::ppl(handle)->getImageLODs()); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_get_image_raw(vtfpp_ppl_handle_t handle, uint32_t* width, uint32_t* height, uint32_t lod) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::ppl(handle)->getImageLODs()); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_get_image_as(vtfpp_ppl_handle_t handle, uint32_t* width, uint32_t* height, vtfpp_image_format_e format, uint32_t lod) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); + + auto image = Convert::ppl(handle)->getImageAs(static_cast(format), lod); + if (!image) { + return SOURCEPP_BUFFER_INVALID; + } + *width = image->width; + *height = image->height; + return Convert::toBuffer(image->data); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_get_image_as_rgb888(vtfpp_ppl_handle_t handle, uint32_t* width, uint32_t* height, uint32_t lod) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + + auto image = Convert::ppl(handle)->getImageAs(ImageFormat::RGB888, lod); + if (!image) { + return SOURCEPP_BUFFER_INVALID; + } + *width = image->width; + *height = image->height; + return Convert::toBuffer(image->data); +} + +SOURCEPP_API int vtfpp_ppl_set_image_from_file(vtfpp_ppl_handle_t handle, const char* imagePath, uint32_t lod) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(imagePath, false); + + return Convert::ppl(handle)->setImage(imagePath, lod); +} + +SOURCEPP_API int vtfpp_ppl_set_image_from_file_with_options(vtfpp_ppl_handle_t handle, const char* imagePath, uint32_t resizedWidth, uint32_t resizedHeight, uint32_t lod, vtfpp_image_conversion_resize_filter_e filter) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(imagePath, false); + SOURCEPP_EARLY_RETURN_VAL(resizedWidth, false); + SOURCEPP_EARLY_RETURN_VAL(resizedHeight, false); + + return Convert::ppl(handle)->setImage(imagePath, resizedWidth, resizedHeight, lod, static_cast(filter)); +} + +SOURCEPP_API int vtfpp_ppl_set_image_from_mem(vtfpp_ppl_handle_t handle, const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint32_t width, uint32_t height, uint32_t lod) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(buffer, false); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, false); + SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, false); + SOURCEPP_EARLY_RETURN_VAL(width, false); + SOURCEPP_EARLY_RETURN_VAL(height, false); + + return Convert::ppl(handle)->setImage({reinterpret_cast(buffer), bufferLen}, static_cast(format), width, height, lod); +} + +SOURCEPP_API int vtfpp_ppl_set_image_from_mem_with_options(vtfpp_ppl_handle_t handle, const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint32_t width, uint32_t height, uint32_t resizedWidth, uint32_t resizedHeight, uint32_t lod, vtfpp_image_conversion_resize_filter_e filter) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(buffer, false); + SOURCEPP_EARLY_RETURN_VAL(bufferLen, false); + SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, false); + SOURCEPP_EARLY_RETURN_VAL(width, false); + SOURCEPP_EARLY_RETURN_VAL(height, false); + SOURCEPP_EARLY_RETURN_VAL(resizedWidth, false); + SOURCEPP_EARLY_RETURN_VAL(resizedHeight, false); + + return Convert::ppl(handle)->setImage({reinterpret_cast(buffer), bufferLen}, static_cast(format), width, height, resizedWidth, resizedHeight, lod, static_cast(filter)); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_save_image_to_file(vtfpp_ppl_handle_t handle, const char* imagePath, uint32_t lod, vtfpp_image_conversion_file_format_e fileFormat) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(imagePath, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::ppl(handle)->saveImageToFile(lod, static_cast(fileFormat))); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_ppl_bake(vtfpp_ppl_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::ppl(handle)->bake()); +} + +SOURCEPP_API int vtfpp_ppl_bake_to_file(vtfpp_ppl_handle_t handle, const char* pplPath) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(pplPath, false); + + return Convert::ppl(handle)->bake(pplPath); +} + +SOURCEPP_API void vtfpp_ppl_close(vtfpp_ppl_handle_t* handle) { + SOURCEPP_EARLY_RETURN(handle); + + delete Convert::ppl(*handle); + *handle = nullptr; +} diff --git a/lang/c/src/vtfppc/SHT.cpp b/lang/c/src/vtfppc/SHT.cpp new file mode 100644 index 000000000..e75d6f6eb --- /dev/null +++ b/lang/c/src/vtfppc/SHT.cpp @@ -0,0 +1,259 @@ +#include + +#include + +#include +#include +#include + +using namespace vtfpp; + +SOURCEPP_API vtfpp_sht_handle_t vtfpp_sht_create() { + return new SHT{}; +} + +SOURCEPP_API vtfpp_sht_handle_t vtfpp_sht_open_from_mem(const unsigned char* shtData, size_t shtLen) { + SOURCEPP_EARLY_RETURN_VAL(shtData, nullptr); + SOURCEPP_EARLY_RETURN_VAL(shtLen, nullptr); + + return new SHT{{reinterpret_cast(shtData), shtLen}}; +} + +SOURCEPP_API vtfpp_sht_handle_t vtfpp_sht_open_from_file(const char* shtPath) { + SOURCEPP_EARLY_RETURN_VAL(shtPath, nullptr); + + return new SHT{std::string{shtPath}}; +} + +SOURCEPP_API int vtfpp_sht_is_valid(vtfpp_sht_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::sht(handle)->operator bool(); +} + +SOURCEPP_API uint32_t vtfpp_sht_get_version(vtfpp_sht_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::sht(handle)->getVersion(); +} + +SOURCEPP_API void vtfpp_sht_set_version(vtfpp_sht_handle_t handle, uint32_t version) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::sht(handle)->setVersion(version); +} + +SOURCEPP_API uint32_t vtfpp_sht_get_sequences_count(vtfpp_sht_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::sht(handle)->getSequences().size(); +} + +SOURCEPP_API vtfpp_sht_sequence_t vtfpp_sht_get_sequence_at_index(vtfpp_sht_handle_t handle, uint32_t index) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_SHT_SEQUENCE_INVALID); + SOURCEPP_EARLY_RETURN_VAL(Convert::sht(handle)->getSequences().size() >= index, VTFPP_SHT_SEQUENCE_INVALID); + + const auto& sequence = Convert::sht(handle)->getSequences().at(index); + return { + .id = sequence.id, + .loop = sequence.loop, + .frameCount = static_cast(sequence.frames.size()), + .durationTotal = sequence.durationTotal, + }; +} + +SOURCEPP_API vtfpp_sht_sequence_t vtfpp_sht_get_sequence_with_id(vtfpp_sht_handle_t handle, uint32_t id) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_SHT_SEQUENCE_INVALID); + + const auto* sequence = Convert::sht(handle)->getSequenceFromID(id); + SOURCEPP_EARLY_RETURN_VAL(sequence, VTFPP_SHT_SEQUENCE_INVALID); + + return { + .id = sequence->id, + .loop = sequence->loop, + .frameCount = static_cast(sequence->frames.size()), + .durationTotal = sequence->durationTotal, + }; +} + +SOURCEPP_API void vtfpp_sht_set_sequence_at_index(vtfpp_sht_handle_t handle, uint32_t index, vtfpp_sht_sequence_t sequence) { + SOURCEPP_EARLY_RETURN(handle); + SOURCEPP_EARLY_RETURN(Convert::sht(handle)->getSequences().size() >= index); + + auto& sequence_ = Convert::sht(handle)->getSequences().at(index); + sequence_.id = sequence.id; + sequence_.loop = sequence.loop; + if (sequence_.frames.size() != sequence.frameCount) { + sequence_.frames.resize(sequence.frameCount); + } + sequence_.durationTotal = sequence.durationTotal; +} + +SOURCEPP_API void vtfpp_sht_set_sequence_with_id(vtfpp_sht_handle_t handle, uint32_t id, vtfpp_sht_sequence_t sequence) { + SOURCEPP_EARLY_RETURN(handle); + + auto* sequence_ = Convert::sht(handle)->getSequenceFromID(id); + SOURCEPP_EARLY_RETURN(sequence_); + + sequence_->id = sequence.id; + sequence_->loop = sequence.loop; + if (sequence_->frames.size() != sequence.frameCount) { + sequence_->frames.resize(sequence.frameCount); + } + sequence_->durationTotal = sequence.durationTotal; +} + +SOURCEPP_API void vtfpp_sht_add_sequence(vtfpp_sht_handle_t handle, vtfpp_sht_sequence_t sequence) { + SOURCEPP_EARLY_RETURN(handle); + + auto& sequence_ = Convert::sht(handle)->getSequences().emplace_back(); + sequence_.id = sequence.id; + sequence_.loop = sequence.loop; + if (sequence_.frames.size() != sequence.frameCount) { + sequence_.frames.resize(sequence.frameCount); + } + sequence_.durationTotal = sequence.durationTotal; +} + +SOURCEPP_API void vtfpp_sht_remove_sequence_at_index(vtfpp_sht_handle_t handle, uint32_t index) { + SOURCEPP_EARLY_RETURN(handle); + SOURCEPP_EARLY_RETURN(Convert::sht(handle)->getSequences().size() >= index); + + Convert::sht(handle)->getSequences().erase(Convert::sht(handle)->getSequences().begin() + index); +} + +SOURCEPP_API void vtfpp_sht_remove_sequence_with_id(vtfpp_sht_handle_t handle, uint32_t id) { + SOURCEPP_EARLY_RETURN(handle); + + auto* sequence_ = Convert::sht(handle)->getSequenceFromID(id); + SOURCEPP_EARLY_RETURN(sequence_); + + Convert::sht(handle)->getSequences().erase(Convert::sht(handle)->getSequences().begin() + (sequence_ - Convert::sht(handle)->getSequences().data())); +} + +SOURCEPP_API vtfpp_sht_frame_t vtfpp_sht_get_frame(vtfpp_sht_handle_t handle, uint32_t sequenceID, uint32_t index) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_SHT_FRAME_INVALID); + + auto* sequence = Convert::sht(handle)->getSequenceFromID(sequenceID); + SOURCEPP_EARLY_RETURN_VAL(sequence, VTFPP_SHT_FRAME_INVALID); + SOURCEPP_EARLY_RETURN_VAL(sequence->frames.size() >= index, VTFPP_SHT_FRAME_INVALID); + + return { + .duration = sequence->frames.at(index).duration, + .bounds = { + { + .x1 = sequence->frames.at(index).bounds.at(0).x1, + .y1 = sequence->frames.at(index).bounds.at(0).y1, + .x2 = sequence->frames.at(index).bounds.at(0).x2, + .y2 = sequence->frames.at(index).bounds.at(0).y2, + }, + { + .x1 = sequence->frames.at(index).bounds.at(1).x1, + .y1 = sequence->frames.at(index).bounds.at(1).y1, + .x2 = sequence->frames.at(index).bounds.at(1).x2, + .y2 = sequence->frames.at(index).bounds.at(1).y2, + }, + { + .x1 = sequence->frames.at(index).bounds.at(2).x1, + .y1 = sequence->frames.at(index).bounds.at(2).y1, + .x2 = sequence->frames.at(index).bounds.at(2).x2, + .y2 = sequence->frames.at(index).bounds.at(2).y2, + }, + { + .x1 = sequence->frames.at(index).bounds.at(3).x1, + .y1 = sequence->frames.at(index).bounds.at(3).y1, + .x2 = sequence->frames.at(index).bounds.at(3).x2, + .y2 = sequence->frames.at(index).bounds.at(3).y2, + }, + } + }; +} + +SOURCEPP_API void vtfpp_sht_set_frame(vtfpp_sht_handle_t handle, uint32_t sequenceID, uint32_t index, vtfpp_sht_frame_t frame) { + SOURCEPP_EARLY_RETURN(handle); + + auto* sequence = Convert::sht(handle)->getSequenceFromID(sequenceID); + SOURCEPP_EARLY_RETURN(sequence); + SOURCEPP_EARLY_RETURN(sequence->frames.size() >= index); + + auto& frame_ = sequence->frames.at(index); + frame_.duration = frame.duration; + frame_.bounds.at(0).x1 = frame.bounds[0].x1; + frame_.bounds.at(0).y1 = frame.bounds[0].y1; + frame_.bounds.at(0).x2 = frame.bounds[0].x2; + frame_.bounds.at(0).y2 = frame.bounds[0].y2; + frame_.bounds.at(1).x1 = frame.bounds[1].x1; + frame_.bounds.at(1).y1 = frame.bounds[1].y1; + frame_.bounds.at(1).x2 = frame.bounds[1].x2; + frame_.bounds.at(1).y2 = frame.bounds[1].y2; + frame_.bounds.at(2).x1 = frame.bounds[2].x1; + frame_.bounds.at(2).y1 = frame.bounds[2].y1; + frame_.bounds.at(2).x2 = frame.bounds[2].x2; + frame_.bounds.at(2).y2 = frame.bounds[2].y2; + frame_.bounds.at(3).x1 = frame.bounds[3].x1; + frame_.bounds.at(3).y1 = frame.bounds[3].y1; + frame_.bounds.at(3).x2 = frame.bounds[3].x2; + frame_.bounds.at(3).y2 = frame.bounds[3].y2; +} + +SOURCEPP_API void vtfpp_sht_add_frame(vtfpp_sht_handle_t handle, uint32_t sequenceID, vtfpp_sht_frame_t frame) { + SOURCEPP_EARLY_RETURN(handle); + + auto* sequence = Convert::sht(handle)->getSequenceFromID(sequenceID); + SOURCEPP_EARLY_RETURN(sequence); + + auto& frame_ = sequence->frames.emplace_back(); + frame_.duration = frame.duration; + frame_.bounds.at(0).x1 = frame.bounds[0].x1; + frame_.bounds.at(0).y1 = frame.bounds[0].y1; + frame_.bounds.at(0).x2 = frame.bounds[0].x2; + frame_.bounds.at(0).y2 = frame.bounds[0].y2; + frame_.bounds.at(1).x1 = frame.bounds[1].x1; + frame_.bounds.at(1).y1 = frame.bounds[1].y1; + frame_.bounds.at(1).x2 = frame.bounds[1].x2; + frame_.bounds.at(1).y2 = frame.bounds[1].y2; + frame_.bounds.at(2).x1 = frame.bounds[2].x1; + frame_.bounds.at(2).y1 = frame.bounds[2].y1; + frame_.bounds.at(2).x2 = frame.bounds[2].x2; + frame_.bounds.at(2).y2 = frame.bounds[2].y2; + frame_.bounds.at(3).x1 = frame.bounds[3].x1; + frame_.bounds.at(3).y1 = frame.bounds[3].y1; + frame_.bounds.at(3).x2 = frame.bounds[3].x2; + frame_.bounds.at(3).y2 = frame.bounds[3].y2; +} + +SOURCEPP_API void vtfpp_sht_remove_frame(vtfpp_sht_handle_t handle, uint32_t sequenceID, uint32_t index) { + SOURCEPP_EARLY_RETURN(handle); + + auto* sequence = Convert::sht(handle)->getSequenceFromID(sequenceID); + SOURCEPP_EARLY_RETURN(sequence); + SOURCEPP_EARLY_RETURN(sequence->frames.size() >= index); + + sequence->frames.erase(sequence->frames.begin() + index); +} + +SOURCEPP_API uint8_t vtfpp_sht_get_frame_bounds_count(vtfpp_sht_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::sht(handle)->getFrameBoundsCount(); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_sht_bake(vtfpp_sht_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::sht(handle)->bake()); +} + +SOURCEPP_API int vtfpp_sht_bake_to_file(vtfpp_sht_handle_t handle, const char* shtPath) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(shtPath, false); + + return Convert::sht(handle)->bake(shtPath); +} + +SOURCEPP_API void vtfpp_sht_close(vtfpp_sht_handle_t* handle) { + SOURCEPP_EARLY_RETURN(handle); + + delete Convert::sht(*handle); + *handle = nullptr; +} diff --git a/lang/c/src/vtfppc/TTX.cpp b/lang/c/src/vtfppc/TTX.cpp new file mode 100644 index 000000000..709a7ad16 --- /dev/null +++ b/lang/c/src/vtfppc/TTX.cpp @@ -0,0 +1,155 @@ +#include + +#include + +#include +#include +#include + +using namespace vtfpp; + +SOURCEPP_API vtfpp_ttx_handle_t vtfpp_ttx_create(vtfpp_vtf_handle_t vtf) { + SOURCEPP_EARLY_RETURN_VAL(vtf, nullptr); + + auto vtfCopy = *Convert::vtf(vtf); + return new TTX{std::move(vtfCopy)}; +} + +SOURCEPP_API vtfpp_ttx_handle_t vtfpp_ttx_open_from_mem(const unsigned char* tthData, size_t tthLen, const unsigned char* ttzData, size_t ttzLen) { + SOURCEPP_EARLY_RETURN_VAL(tthData, nullptr); + SOURCEPP_EARLY_RETURN_VAL(tthLen, nullptr); + + if (!ttzData || !ttzLen) { + return new TTX{{reinterpret_cast(tthData), tthLen}}; + } + return new TTX{{reinterpret_cast(tthData), tthLen}, {reinterpret_cast(ttzData), ttzLen}}; +} + +SOURCEPP_API vtfpp_ttx_handle_t vtfpp_ttx_open_from_file(const char* tthPath, const char* ttzPath) { + SOURCEPP_EARLY_RETURN_VAL(tthPath, nullptr); + + if (!ttzPath) { + return new TTX{tthPath}; + } + return new TTX{tthPath, ttzPath}; +} + +SOURCEPP_API int vtfpp_ttx_is_valid(vtfpp_ttx_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::ttx(handle)->operator bool(); +} + +SOURCEPP_API uint8_t vtfpp_ttx_get_major_version(vtfpp_ttx_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::ttx(handle)->getMajorVersion(); +} + +SOURCEPP_API uint8_t vtfpp_ttx_get_minor_version(vtfpp_ttx_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::ttx(handle)->getMinorVersion(); +} + +SOURCEPP_API void vtfpp_ttx_set_version(vtfpp_ttx_handle_t handle, uint8_t majorVersion, uint8_t minorVersion) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::ttx(handle)->setVersion(majorVersion, minorVersion); +} + +SOURCEPP_API void vtfpp_ttx_set_major_version(vtfpp_ttx_handle_t handle, uint8_t majorVersion) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::ttx(handle)->setMajorVersion(majorVersion); +} + +SOURCEPP_API void vtfpp_ttx_set_minor_version(vtfpp_ttx_handle_t handle, uint8_t minorVersion) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::ttx(handle)->setMinorVersion(minorVersion); +} + +SOURCEPP_API uint8_t vtfpp_ttx_get_aspect_ratio_type(vtfpp_ttx_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::ttx(handle)->getAspectRatioType(); +} + +SOURCEPP_API void vtfpp_ttx_set_aspect_ratio_type(vtfpp_ttx_handle_t handle, uint8_t aspectRatioType) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::ttx(handle)->setAspectRatioType(aspectRatioType); +} + +SOURCEPP_API sourcepp_buffer_uint64_t vtfpp_ttx_get_mip_flags(vtfpp_ttx_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::ttx(handle)->getMipFlags()); +} + +SOURCEPP_API void vtfpp_ttx_set_mip_flags(vtfpp_ttx_handle_t handle, const uint64_t* mipFlags, size_t mipFlagsLen) { + SOURCEPP_EARLY_RETURN(handle); + + if (!mipFlags || !mipFlagsLen) { + Convert::ttx(handle)->getMipFlags().clear(); + } else { + std::span mipFlagsSpan{mipFlags, mipFlagsLen}; + Convert::ttx(handle)->getMipFlags().assign(mipFlagsSpan.begin(), mipFlagsSpan.end()); + } +} + +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_ttx_get_vtf(vtfpp_ttx_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, nullptr); + + return &Convert::ttx(handle)->getVTF(); +} + +SOURCEPP_API void vtfpp_ttx_set_vtf(vtfpp_ttx_handle_t handle, vtfpp_vtf_handle_t vtf) { + SOURCEPP_EARLY_RETURN(handle); + SOURCEPP_EARLY_RETURN(vtf); + + Convert::ttx(handle)->getVTF() = *Convert::vtf(vtf); +} + +SOURCEPP_API int16_t vtfpp_ttx_get_compression_level(vtfpp_ttx_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::ttx(handle)->getCompressionLevel(); +} + +SOURCEPP_API void vtfpp_ttx_set_compression_level(vtfpp_ttx_handle_t handle, int16_t compressionLevel) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::ttx(handle)->setCompressionLevel(compressionLevel); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_ttx_bake(vtfpp_ttx_handle_t handle, size_t* tthLen, size_t* ttzLen) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(tthLen, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(ttzLen, SOURCEPP_BUFFER_INVALID); + + auto [tthData, ttzData] = Convert::ttx(handle)->bake(); + *tthLen = tthData.size(); + *ttzLen = ttzData.size(); + + std::vector out; + out.insert(out.end(), tthData.begin(), tthData.end()); + out.insert(out.end(), ttzData.begin(), ttzData.end()); + return Convert::toBuffer(out); +} + +SOURCEPP_API int vtfpp_ttx_bake_to_file(vtfpp_ttx_handle_t handle, const char* tthPath, const char* ttzPath) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(tthPath, false); + SOURCEPP_EARLY_RETURN_VAL(ttzPath, false); + + return Convert::ttx(handle)->bake(tthPath, ttzPath); +} + +SOURCEPP_API void vtfpp_ttx_close(vtfpp_ttx_handle_t* handle) { + SOURCEPP_EARLY_RETURN(handle); + + delete Convert::ttx(*handle); + *handle = nullptr; +} diff --git a/lang/c/src/vtfppc/VTF.cpp b/lang/c/src/vtfppc/VTF.cpp new file mode 100644 index 000000000..97e465464 --- /dev/null +++ b/lang/c/src/vtfppc/VTF.cpp @@ -0,0 +1,677 @@ +#include + +#include + +#include +#include +#include + +using namespace vtfpp; + +SOURCEPP_API vtfpp_resource_type_e vtfpp_resource_get_type(vtfpp_resource_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_RESOURCE_TYPE_UNKNOWN); + + return Convert::resourceType(Convert::resource(handle)->type); +} + +SOURCEPP_API vtfpp_resource_flags_e vtfpp_resource_get_flags(vtfpp_resource_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_RESOURCE_FLAG_NONE); + + return Convert::resourceFlags(Convert::resource(handle)->flags); +} + +SOURCEPP_API const unsigned char* vtfpp_resource_get_data(vtfpp_resource_handle_t handle, size_t* dataLen) { + SOURCEPP_EARLY_RETURN_VAL(handle, nullptr); + SOURCEPP_EARLY_RETURN_VAL(dataLen, nullptr); + + const auto resourceData = Convert::resource(handle)->data; + *dataLen = resourceData.size(); + return reinterpret_cast(resourceData.data()); +} + +// REQUIRES MANUAL FREE: vtfpp_sht_close +SOURCEPP_API vtfpp_sht_handle_t vtfpp_resource_get_data_as_particle_sheet(vtfpp_resource_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, nullptr); + + return new SHT{Convert::resource(handle)->getDataAsParticleSheet()}; +} + +SOURCEPP_API uint32_t vtfpp_resource_get_data_as_crc(vtfpp_resource_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::resource(handle)->getDataAsCRC(); +} + +SOURCEPP_API uint32_t vtfpp_resource_get_data_as_extended_flags(vtfpp_resource_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::resource(handle)->getDataAsExtendedFlags(); +} + +SOURCEPP_API void vtfpp_resource_get_data_as_lod(vtfpp_resource_handle_t handle, uint8_t* u, uint8_t* v, uint8_t* u360, uint8_t* v360) { + SOURCEPP_EARLY_RETURN(handle); + + const auto lodData = Convert::resource(handle)->getDataAsLODControlInfo(); + if (u) { + *u = std::get<0>(lodData); + } + if (v) { + *v = std::get<1>(lodData); + } + if (u360) { + *u360 = std::get<2>(lodData); + } + if (v360) { + *v360 = std::get<3>(lodData); + } +} + +// REQUIRES MANUAL FREE: sourcepp_string_free +SOURCEPP_API sourcepp_string_t vtfpp_resource_get_data_as_keyvalues_data(vtfpp_resource_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID); + + return Convert::toString(Convert::resource(handle)->getDataAsKeyValuesData()); +} + +SOURCEPP_API int16_t vtfpp_resource_get_data_as_aux_compression_level(vtfpp_resource_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::resource(handle)->getDataAsAuxCompressionLevel(); +} + +SOURCEPP_API vtfpp_compression_method_e vtfpp_resource_get_data_as_aux_compression_method(vtfpp_resource_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_COMPRESSION_METHOD_ZSTD); + + return Convert::compressionMethod(Convert::resource(handle)->getDataAsAuxCompressionMethod()); +} + +SOURCEPP_API uint32_t vtfpp_resource_get_data_as_aux_compression_length(vtfpp_resource_handle_t handle, uint8_t mip, uint8_t mipCount, uint16_t frame, uint16_t frameCount, uint16_t face, uint16_t faceCount) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::resource(handle)->getDataAsAuxCompressionLength(mip, mipCount, frame, frameCount, face, faceCount); +} + +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_empty() { + return new VTF{}; +} + +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_mem(const unsigned char* vtfData, size_t vtfLen, int parseHeaderOnly) { + SOURCEPP_EARLY_RETURN_VAL(vtfData, nullptr); + SOURCEPP_EARLY_RETURN_VAL(vtfLen, nullptr); + + return new VTF{{reinterpret_cast(vtfData), vtfLen}, static_cast(parseHeaderOnly)}; +} + +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_open_from_file(const char* vtfPath, int parseHeaderOnly) { + SOURCEPP_EARLY_RETURN_VAL(vtfPath, nullptr); + + return new VTF{vtfPath, static_cast(parseHeaderOnly)}; +} + +SOURCEPP_API int vtfpp_vtf_is_valid(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->operator bool(); +} + +SOURCEPP_API int vtfpp_vtf_create_from_mem_and_bake(const unsigned char* imageData, size_t imageLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, const char* vtfPath, vtfpp_vtf_creation_options_t options) { + SOURCEPP_EARLY_RETURN_VAL(imageData, false); + SOURCEPP_EARLY_RETURN_VAL(imageLen, false); + SOURCEPP_EARLY_RETURN_VAL(vtfPath, false); + + return VTF::create({reinterpret_cast(imageData), imageLen}, Convert::imageFormat(format), width, height, vtfPath, Convert::vtfCreationOptions(options)); +} + +SOURCEPP_API int vtfpp_vtf_create_blank_and_bake(vtfpp_image_format_e format, uint16_t width, uint16_t height, const char* vtfPath, vtfpp_vtf_creation_options_t options) { + SOURCEPP_EARLY_RETURN_VAL(vtfPath, false); + + return VTF::create(Convert::imageFormat(format), width, height, vtfPath, Convert::vtfCreationOptions(options)); +} + +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_from_mem(const unsigned char* imageData, size_t imageLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, vtfpp_vtf_creation_options_t options) { + SOURCEPP_EARLY_RETURN_VAL(imageData, nullptr); + SOURCEPP_EARLY_RETURN_VAL(imageLen, nullptr); + + return new VTF{VTF::create({reinterpret_cast(imageData), imageLen}, Convert::imageFormat(format), width, height, Convert::vtfCreationOptions(options))}; +} + +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_blank(vtfpp_image_format_e format, uint16_t width, uint16_t height, vtfpp_vtf_creation_options_t options) { + return new VTF{VTF::create(Convert::imageFormat(format), width, height, Convert::vtfCreationOptions(options))}; +} + +SOURCEPP_API int vtfpp_vtf_create_from_file_and_bake(const char* imagePath, const char* vtfPath, vtfpp_vtf_creation_options_t options) { + SOURCEPP_EARLY_RETURN_VAL(imagePath, false); + SOURCEPP_EARLY_RETURN_VAL(vtfPath, false); + + return VTF::create(imagePath, vtfPath, Convert::vtfCreationOptions(options)); +} + +SOURCEPP_API vtfpp_vtf_handle_t vtfpp_vtf_create_from_file(const char* imagePath, vtfpp_vtf_creation_options_t options) { + SOURCEPP_EARLY_RETURN_VAL(imagePath, nullptr); + + return new VTF{VTF::create(imagePath, Convert::vtfCreationOptions(options))}; +} + +SOURCEPP_API vtfpp_vtf_platform_e vtfpp_vtf_get_platform(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_VTF_PLATFORM_UNKNOWN); + + return Convert::vtfPlatform(Convert::vtf(handle)->getPlatform()); +} + +SOURCEPP_API void vtfpp_vtf_set_platform(vtfpp_vtf_handle_t handle, vtfpp_vtf_platform_e platform) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setPlatform(Convert::vtfPlatform(platform)); +} + +SOURCEPP_API uint32_t vtfpp_vtf_get_major_version(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getMajorVersion(); +} + +SOURCEPP_API uint32_t vtfpp_vtf_get_minor_version(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getMinorVersion(); +} + +SOURCEPP_API void vtfpp_vtf_set_version(vtfpp_vtf_handle_t handle, uint32_t majorVersion, uint32_t minorVersion) { + SOURCEPP_EARLY_RETURN(handle); + + return Convert::vtf(handle)->setVersion(majorVersion, minorVersion); +} + +SOURCEPP_API void vtfpp_vtf_set_major_version(vtfpp_vtf_handle_t handle, uint32_t majorVersion) { + SOURCEPP_EARLY_RETURN(handle); + + return Convert::vtf(handle)->setMajorVersion(majorVersion); +} + +SOURCEPP_API void vtfpp_vtf_set_minor_version(vtfpp_vtf_handle_t handle, uint32_t minorVersion) { + SOURCEPP_EARLY_RETURN(handle); + + return Convert::vtf(handle)->setMinorVersion(minorVersion); +} + +SOURCEPP_API vtfpp_image_conversion_resize_method_e vtfpp_vtf_get_image_width_resize_method(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_IMAGE_CONVERSION_RESIZE_METHOD_NONE); + + return Convert::resizeMethod(Convert::vtf(handle)->getImageWidthResizeMethod()); +} + +SOURCEPP_API vtfpp_image_conversion_resize_method_e vtfpp_vtf_get_image_height_resize_method(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_IMAGE_CONVERSION_RESIZE_METHOD_NONE); + + return Convert::resizeMethod(Convert::vtf(handle)->getImageHeightResizeMethod()); +} + +SOURCEPP_API void vtfpp_vtf_set_image_resize_methods(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_method_e imageWidthResizeMethod, vtfpp_image_conversion_resize_method_e imageHeightResizeMethod) { + SOURCEPP_EARLY_RETURN(handle); + + return Convert::vtf(handle)->setImageResizeMethods(Convert::resizeMethod(imageWidthResizeMethod), Convert::resizeMethod(imageHeightResizeMethod)); +} + +SOURCEPP_API void vtfpp_vtf_set_image_width_resize_method(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_method_e imageWidthResizeMethod) { + SOURCEPP_EARLY_RETURN(handle); + + return Convert::vtf(handle)->setImageWidthResizeMethod(Convert::resizeMethod(imageWidthResizeMethod)); +} + +SOURCEPP_API void vtfpp_vtf_set_image_height_resize_method(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_method_e imageHeightResizeMethod) { + SOURCEPP_EARLY_RETURN(handle); + + return Convert::vtf(handle)->setImageHeightResizeMethod(Convert::resizeMethod(imageHeightResizeMethod)); +} + +SOURCEPP_API uint16_t vtfpp_vtf_get_width(vtfpp_vtf_handle_t handle, uint8_t mip) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getWidth(mip); +} + +SOURCEPP_API uint16_t vtfpp_vtf_get_height(vtfpp_vtf_handle_t handle, uint8_t mip) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getHeight(mip); +} + +SOURCEPP_API void vtfpp_vtf_set_size(vtfpp_vtf_handle_t handle, uint16_t width, uint16_t height, vtfpp_image_conversion_resize_filter_e filter) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setSize(width, height, Convert::resizeFilter(filter)); +} + +SOURCEPP_API vtfpp_vtf_flags_e vtfpp_vtf_get_flags(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_VTF_FLAG_NONE); + + return Convert::vtfFlags(Convert::vtf(handle)->getFlags()); +} + +SOURCEPP_API void vtfpp_vtf_set_flags(vtfpp_vtf_handle_t handle, vtfpp_vtf_flags_e flags) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setFlags(Convert::vtfFlags(flags)); +} + +SOURCEPP_API void vtfpp_vtf_add_flags(vtfpp_vtf_handle_t handle, vtfpp_vtf_flags_e flags) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->addFlags(Convert::vtfFlags(flags)); +} + +SOURCEPP_API void vtfpp_vtf_remove_flags(vtfpp_vtf_handle_t handle, vtfpp_vtf_flags_e flags) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->removeFlags(Convert::vtfFlags(flags)); +} + +SOURCEPP_API void vtfpp_vtf_compute_transparency_flags(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->computeTransparencyFlags(); +} + +SOURCEPP_API vtfpp_image_format_e vtfpp_vtf_get_default_compressed_format(vtfpp_image_format_e inputFormat, uint32_t majorVersion, uint32_t minorVersion) { + return Convert::imageFormat(VTF::getDefaultCompressedFormat(Convert::imageFormat(inputFormat), majorVersion, minorVersion)); +} + +SOURCEPP_API vtfpp_image_format_e vtfpp_vtf_get_format(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_IMAGE_FORMAT_EMPTY); + + return Convert::imageFormat(Convert::vtf(handle)->getFormat()); +} + +SOURCEPP_API void vtfpp_vtf_set_format(vtfpp_vtf_handle_t handle, vtfpp_image_format_e format, vtfpp_image_conversion_resize_filter_e filter) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setFormat(Convert::imageFormat(format), Convert::resizeFilter(filter)); +} + +SOURCEPP_API uint8_t vtfpp_vtf_get_mip_count(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getMipCount(); +} + +SOURCEPP_API int vtfpp_vtf_set_mip_count(vtfpp_vtf_handle_t handle, uint8_t mipCount) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->setMipCount(mipCount); +} + +SOURCEPP_API int vtfpp_vtf_set_recommended_mip_count(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->setRecommendedMipCount(); +} + +SOURCEPP_API void vtfpp_vtf_compute_mips(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_filter_e filter) { + SOURCEPP_EARLY_RETURN(handle); + + return Convert::vtf(handle)->computeMips(Convert::resizeFilter(filter)); +} + +SOURCEPP_API uint16_t vtfpp_vtf_get_frame_count(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getFrameCount(); +} + +SOURCEPP_API int vtfpp_vtf_set_frame_count(vtfpp_vtf_handle_t handle, uint16_t frameCount) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->setFrameCount(frameCount); +} + +SOURCEPP_API uint8_t vtfpp_vtf_get_face_count(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getFaceCount(); +} + +SOURCEPP_API int vtfpp_vtf_set_face_count(vtfpp_vtf_handle_t handle, int isCubemap, int hasSphereMap) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->setFaceCount(isCubemap, hasSphereMap); +} + +SOURCEPP_API uint16_t vtfpp_vtf_get_slice_count(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getSliceCount(); +} + +SOURCEPP_API int vtfpp_vtf_set_slice_count(vtfpp_vtf_handle_t handle, uint16_t sliceCount) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->setSliceCount(sliceCount); +} + +SOURCEPP_API int vtfpp_vtf_set_frame_face_and_slice_count(vtfpp_vtf_handle_t handle, uint16_t frameCount, int isCubemap, int hasSphereMap, uint16_t sliceCount) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->setFrameFaceAndSliceCount(frameCount, isCubemap, hasSphereMap, sliceCount); +} + +SOURCEPP_API uint16_t vtfpp_vtf_get_start_frame(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getStartFrame(); +} + +SOURCEPP_API void vtfpp_vtf_set_start_frame(vtfpp_vtf_handle_t handle, uint16_t startFrame) { + SOURCEPP_EARLY_RETURN(handle); + + return Convert::vtf(handle)->setStartFrame(startFrame); +} + +SOURCEPP_API void vtfpp_vtf_get_reflectivity(vtfpp_vtf_handle_t handle, float* r, float* g, float* b) { + SOURCEPP_EARLY_RETURN(handle); + SOURCEPP_EARLY_RETURN(r); + SOURCEPP_EARLY_RETURN(g); + SOURCEPP_EARLY_RETURN(b); + + const auto reflectivity = Convert::vtf(handle)->getReflectivity(); + *r = reflectivity[0]; + *g = reflectivity[1]; + *b = reflectivity[2]; +} + +SOURCEPP_API void vtfpp_vtf_set_reflectivity(vtfpp_vtf_handle_t handle, float r, float g, float b) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setReflectivity({r, g, b}); +} + +SOURCEPP_API void vtfpp_vtf_compute_reflectivity(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->computeReflectivity(); +} + +SOURCEPP_API float vtfpp_vtf_get_bumpmap_scale(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0.f); + + return Convert::vtf(handle)->getBumpMapScale(); +} + +SOURCEPP_API void vtfpp_vtf_set_bumpmap_scale(vtfpp_vtf_handle_t handle, float bumpMapScale) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setBumpMapScale(bumpMapScale); +} + +SOURCEPP_API vtfpp_image_format_e vtfpp_vtf_get_thumbnail_format(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_IMAGE_FORMAT_EMPTY); + + return Convert::imageFormat(Convert::vtf(handle)->getThumbnailFormat()); +} + +SOURCEPP_API uint8_t vtfpp_vtf_get_thumbnail_width(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getThumbnailWidth(); +} + +SOURCEPP_API uint8_t vtfpp_vtf_get_thumbnail_height(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getThumbnailHeight(); +} + +SOURCEPP_API uint32_t vtfpp_vtf_get_resources_count(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getResources().size(); +} + +SOURCEPP_API vtfpp_resource_handle_t vtfpp_vtf_get_resource_at_index(vtfpp_vtf_handle_t handle, uint32_t index) { + SOURCEPP_EARLY_RETURN_VAL(handle, nullptr); + + return &Convert::vtf(handle)->getResources().at(index); +} + +SOURCEPP_API vtfpp_resource_handle_t vtfpp_vtf_get_resource_with_type(vtfpp_vtf_handle_t handle, vtfpp_resource_type_e type) { + SOURCEPP_EARLY_RETURN_VAL(handle, nullptr); + + return Convert::vtf(handle)->getResource(Convert::resourceType(type)); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_particle_sheet_frame_data_raw(vtfpp_vtf_handle_t handle, uint16_t* width, uint16_t* height, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::vtf(handle)->getParticleSheetFrameDataRaw(*width, *height, shtSequenceID, shtFrame, shtBounds, mip, frame, face, slice)); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_particle_sheet_frame_data_as(vtfpp_vtf_handle_t handle, vtfpp_image_format_e format, uint16_t* width, uint16_t* height, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::vtf(handle)->getParticleSheetFrameDataAs(Convert::imageFormat(format), *width, *height, shtSequenceID, shtFrame, shtBounds, mip, frame, face, slice)); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_particle_sheet_frame_data_as_rgba8888(vtfpp_vtf_handle_t handle, uint16_t* width, uint16_t* height, uint32_t shtSequenceID, uint32_t shtFrame, uint8_t shtBounds, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(width, SOURCEPP_BUFFER_INVALID); + SOURCEPP_EARLY_RETURN_VAL(height, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::vtf(handle)->getParticleSheetFrameDataAsRGBA8888(*width, *height, shtSequenceID, shtFrame, shtBounds, mip, frame, face, slice)); +} + +SOURCEPP_API void vtfpp_vtf_set_particle_sheet_resource(vtfpp_vtf_handle_t handle, vtfpp_sht_handle_t sht) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setParticleSheetResource(*Convert::sht(sht)); +} + +SOURCEPP_API void vtfpp_vtf_remove_particle_sheet_resource(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->removeParticleSheetResource(); +} + +SOURCEPP_API void vtfpp_vtf_set_crc_resource(vtfpp_vtf_handle_t handle, uint32_t value) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setCRCResource(value); +} + +SOURCEPP_API void vtfpp_vtf_remove_crc_resource(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->removeCRCResource(); +} + +SOURCEPP_API void vtfpp_vtf_set_lod_resource(vtfpp_vtf_handle_t handle, uint8_t u, uint8_t v, uint8_t u360, uint8_t v360) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setLODResource(u, v, u360, v360); +} + +SOURCEPP_API void vtfpp_vtf_remove_lod_resource(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->removeLODResource(); +} + +SOURCEPP_API void vtfpp_vtf_set_extended_flags_resource(vtfpp_vtf_handle_t handle, uint32_t value) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setExtendedFlagsResource(value); +} + +SOURCEPP_API void vtfpp_vtf_remove_extended_flags_resource(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->removeExtendedFlagsResource(); +} + +SOURCEPP_API void vtfpp_vtf_set_keyvalues_data_resource(vtfpp_vtf_handle_t handle, const char* value) { + SOURCEPP_EARLY_RETURN(handle); + SOURCEPP_EARLY_RETURN(value); + + Convert::vtf(handle)->setKeyValuesDataResource(value); +} + +SOURCEPP_API void vtfpp_vtf_remove_keyvalues_data_resource(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->removeKeyValuesDataResource(); +} + +SOURCEPP_API int16_t vtfpp_vtf_get_compression_level(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, 0); + + return Convert::vtf(handle)->getCompressionLevel(); +} + +SOURCEPP_API void vtfpp_vtf_set_compression_level(vtfpp_vtf_handle_t handle, int16_t compressionLevel) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setCompressionLevel(compressionLevel); +} + +SOURCEPP_API vtfpp_compression_method_e vtfpp_vtf_get_compression_method(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, VTFPP_COMPRESSION_METHOD_ZSTD); + + return Convert::compressionMethod(Convert::vtf(handle)->getCompressionMethod()); +} + +SOURCEPP_API void vtfpp_vtf_set_compression_method(vtfpp_vtf_handle_t handle, vtfpp_compression_method_e compressionMethod) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->setCompressionMethod(Convert::compressionMethod(compressionMethod)); +} + +SOURCEPP_API int vtfpp_vtf_has_image_data(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->hasImageData(); +} + +SOURCEPP_API int vtfpp_vtf_image_data_is_srgb(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->imageDataIsSRGB(); +} + +SOURCEPP_API const unsigned char* vtfpp_vtf_get_image_data_raw(vtfpp_vtf_handle_t handle, size_t* imageLen, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) { + SOURCEPP_EARLY_RETURN_VAL(handle, nullptr); + SOURCEPP_EARLY_RETURN_VAL(imageLen, nullptr); + + const auto imageData = Convert::vtf(handle)->getImageDataRaw(mip, frame, face, slice); + *imageLen = imageData.size(); + return reinterpret_cast(imageData.data()); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_image_data_as(vtfpp_vtf_handle_t handle, vtfpp_image_format_e format, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::vtf(handle)->getImageDataAs(Convert::imageFormat(format), mip, frame, face, slice)); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_image_data_as_rgba8888(vtfpp_vtf_handle_t handle, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::vtf(handle)->getImageDataAsRGBA8888(mip, frame, face, slice)); +} + +SOURCEPP_API int vtfpp_vtf_set_image_from_mem(vtfpp_vtf_handle_t handle, const unsigned char* imageData, size_t imageLen, vtfpp_image_format_e format, uint16_t width, uint16_t height, vtfpp_image_conversion_resize_filter_e filter, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(imageData, false); + SOURCEPP_EARLY_RETURN_VAL(imageLen, false); + + return Convert::vtf(handle)->setImage({reinterpret_cast(imageData), imageLen}, Convert::imageFormat(format), width, height, Convert::resizeFilter(filter), mip, frame, face, slice); +} + +SOURCEPP_API int vtfpp_vtf_set_image_from_file(vtfpp_vtf_handle_t handle, const char* imagePath, vtfpp_image_conversion_resize_filter_e filter, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(imagePath, false); + + return Convert::vtf(handle)->setImage(imagePath, Convert::resizeFilter(filter), mip, frame, face, slice); +} + +SOURCEPP_API int vtfpp_vtf_save_image_to_file(vtfpp_vtf_handle_t handle, const char* imagePath, uint8_t mip, uint16_t frame, uint8_t face, uint16_t slice, vtfpp_image_conversion_file_format_e fileFormat) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(imagePath, false); + + return Convert::vtf(handle)->saveImageToFile(imagePath, mip, frame, face, slice, Convert::fileFormat(fileFormat)); +} + +SOURCEPP_API int vtfpp_vtf_has_thumbnail_data(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + + return Convert::vtf(handle)->hasThumbnailData(); +} + +SOURCEPP_API const unsigned char* vtfpp_vtf_get_thumbnail_data_raw(vtfpp_vtf_handle_t handle, size_t* imageLen) { + SOURCEPP_EARLY_RETURN_VAL(handle, nullptr); + SOURCEPP_EARLY_RETURN_VAL(imageLen, nullptr); + + const auto thumbnailData = Convert::vtf(handle)->getThumbnailDataRaw(); + *imageLen = thumbnailData.size(); + return reinterpret_cast(thumbnailData.data()); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_thumbnail_data_as(vtfpp_vtf_handle_t handle, vtfpp_image_format_e format) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::vtf(handle)->getThumbnailDataAs(Convert::imageFormat(format))); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_get_thumbnail_data_as_rgba8888(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::vtf(handle)->getThumbnailDataAsRGBA8888()); +} + +SOURCEPP_API void vtfpp_vtf_set_thumbnail(vtfpp_vtf_handle_t handle, const unsigned char* imageData, size_t imageLen, vtfpp_image_format_e format, uint16_t width, uint16_t height) { + SOURCEPP_EARLY_RETURN(handle); + SOURCEPP_EARLY_RETURN(imageData); + SOURCEPP_EARLY_RETURN(imageLen); + + Convert::vtf(handle)->setThumbnail({reinterpret_cast(imageData), imageLen}, Convert::imageFormat(format), width, height); +} + +SOURCEPP_API void vtfpp_vtf_compute_thumbnail(vtfpp_vtf_handle_t handle, vtfpp_image_conversion_resize_filter_e filter) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->computeThumbnail(Convert::resizeFilter(filter)); +} + +SOURCEPP_API void vtfpp_vtf_remove_thumbnail(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN(handle); + + Convert::vtf(handle)->removeThumbnail(); +} + +SOURCEPP_API int vtfpp_vtf_save_thumbnail_to_file(vtfpp_vtf_handle_t handle, const char* imagePath, vtfpp_image_conversion_file_format_e fileFormat) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(imagePath, false); + + return Convert::vtf(handle)->saveThumbnailToFile(imagePath, Convert::fileFormat(fileFormat)); +} + +SOURCEPP_API sourcepp_buffer_t vtfpp_vtf_bake(vtfpp_vtf_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_BUFFER_INVALID); + + return Convert::toBuffer(Convert::vtf(handle)->bake()); +} + +SOURCEPP_API int vtfpp_vtf_bake_to_file(vtfpp_vtf_handle_t handle, const char* vtfPath) { + SOURCEPP_EARLY_RETURN_VAL(handle, false); + SOURCEPP_EARLY_RETURN_VAL(vtfPath, false); + + return Convert::vtf(handle)->bake(vtfPath); +} + +SOURCEPP_API void vtfpp_vtf_close(vtfpp_vtf_handle_t* handle) { + SOURCEPP_EARLY_RETURN(handle); + + delete Convert::vtf(*handle); + *handle = nullptr; +} diff --git a/lang/c/src/vtfppc/_vtfppc.cmake b/lang/c/src/vtfppc/_vtfppc.cmake new file mode 100644 index 000000000..6d5a7a533 --- /dev/null +++ b/lang/c/src/vtfppc/_vtfppc.cmake @@ -0,0 +1,18 @@ +add_pretty_parser(vtfpp C + PRECOMPILED_HEADERS + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vtfppc/ImageConversion.h" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vtfppc/ImageFormats.h" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vtfppc/PPL.h" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vtfppc/SHT.h" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vtfppc/TTX.h" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vtfppc/VTF.h" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vtfppc/vtfpp.h" + SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vtfppc/Convert.hpp" + "${CMAKE_CURRENT_LIST_DIR}/Convert.cpp" + "${CMAKE_CURRENT_LIST_DIR}/ImageConversion.cpp" + "${CMAKE_CURRENT_LIST_DIR}/ImageFormats.cpp" + "${CMAKE_CURRENT_LIST_DIR}/PPL.cpp" + "${CMAKE_CURRENT_LIST_DIR}/SHT.cpp" + "${CMAKE_CURRENT_LIST_DIR}/TTX.cpp" + "${CMAKE_CURRENT_LIST_DIR}/VTF.cpp") diff --git a/src/vtfpp/TTX.cpp b/src/vtfpp/TTX.cpp index 393f2ecc2..2acf24768 100644 --- a/src/vtfpp/TTX.cpp +++ b/src/vtfpp/TTX.cpp @@ -171,6 +171,8 @@ std::pair, std::vector> TTX::bake() const { bool TTX::bake(const std::string& tthPath, const std::string& ttzPath) const { const auto data = this->bake(); const bool tth = fs::writeFileBuffer(tthPath, data.first); - const bool ttz = fs::writeFileBuffer(ttzPath, data.second); - return tth && ttz; + if (!data.second.empty()) { + return fs::writeFileBuffer(ttzPath, data.second) && tth; + } + return tth; } From 2aa5a16e2d27442cc61774983f18dff2e6febdac Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sat, 22 Feb 2025 14:20:58 -0500 Subject: [PATCH 6/8] c: fix compilation, use C-style initializer list cast in a C program --- lang/c/include/sourceppc/API.h | 2 ++ lang/c/include/sourceppc/Buffer.h | 2 +- lang/c/include/sourceppc/String.h | 4 ++-- lang/c/include/vtfppc/ImageConversion.h | 2 +- lang/c/include/vtfppc/SHT.h | 4 ++-- lang/c/include/vtfppc/VTF.h | 2 +- lang/c/src/vtfppc/ImageConversion.cpp | 2 +- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lang/c/include/sourceppc/API.h b/lang/c/include/sourceppc/API.h index fe367b5b2..7bc675cc0 100644 --- a/lang/c/include/sourceppc/API.h +++ b/lang/c/include/sourceppc/API.h @@ -10,6 +10,7 @@ #ifdef __cplusplus #define SOURCEPP_API extern "C" SOURCEPP_EXPORT + #define SOURCEPP_CAST_CTOR(name) name #include #include using std::size_t; @@ -23,6 +24,7 @@ using std::uint64_t; #else #define SOURCEPP_API SOURCEPP_EXPORT + #define SOURCEPP_CAST_CTOR(name) (name) #include #include #endif diff --git a/lang/c/include/sourceppc/Buffer.h b/lang/c/include/sourceppc/Buffer.h index 4b9718e2c..dbf002d77 100644 --- a/lang/c/include/sourceppc/Buffer.h +++ b/lang/c/include/sourceppc/Buffer.h @@ -11,7 +11,7 @@ typedef struct { void* data; } sourcepp_buffer_t; -#define SOURCEPP_BUFFER_INVALID (sourcepp_buffer_t{.size = -1, .data = NULL}) +#define SOURCEPP_BUFFER_INVALID (SOURCEPP_CAST_CTOR(sourcepp_buffer_t) {.size = -1, .data = NULL}) // Aliases typedef sourcepp_buffer_t sourcepp_buffer_uint32_t; diff --git a/lang/c/include/sourceppc/String.h b/lang/c/include/sourceppc/String.h index e09c3ad12..e13270983 100644 --- a/lang/c/include/sourceppc/String.h +++ b/lang/c/include/sourceppc/String.h @@ -11,14 +11,14 @@ typedef struct { uint8_t* data; } sourcepp_string_t; -#define SOURCEPP_STRING_INVALID (sourcepp_string_t{.size = -1, .data = NULL}) +#define SOURCEPP_STRING_INVALID (SOURCEPP_CAST_CTOR(sourcepp_string_t) {.size = -1, .data = NULL}) typedef struct { int64_t size; char** data; } sourcepp_string_array_t; -#define SOURCEPP_STRING_ARRAY_INVALID (sourcepp_string_array_t{.size = -1, .data = NULL}) +#define SOURCEPP_STRING_ARRAY_INVALID (SOURCEPP_CAST_CTOR(sourcepp_string_array_t) {.size = -1, .data = NULL}) #ifdef __cplusplus } // extern "C" diff --git a/lang/c/include/vtfppc/ImageConversion.h b/lang/c/include/vtfppc/ImageConversion.h index 62e751feb..7ca8b32ce 100644 --- a/lang/c/include/vtfppc/ImageConversion.h +++ b/lang/c/include/vtfppc/ImageConversion.h @@ -77,7 +77,7 @@ SOURCEPP_API void vtfpp_image_conversion_set_resized_dims(uint16_t* width, vtfpp SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t height, uint16_t newHeight, int srgb, vtfpp_image_conversion_resize_filter_e filter, vtfpp_image_conversion_resize_edge_e edge); // REQUIRES MANUAL FREE: sourcepp_buffer_free -SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data_strict(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t* widthOut, vtfpp_image_conversion_resize_method_e widthResize, uint16_t height, uint16_t newHeight, uint16_t* heightOut, vtfpp_image_conversion_resize_method_e heightResize, bool srgb, vtfpp_image_conversion_resize_filter_e filter, vtfpp_image_conversion_resize_edge_e edge); +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data_strict(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t* widthOut, vtfpp_image_conversion_resize_method_e widthResize, uint16_t height, uint16_t newHeight, uint16_t* heightOut, vtfpp_image_conversion_resize_method_e heightResize, int srgb, vtfpp_image_conversion_resize_filter_e filter, vtfpp_image_conversion_resize_edge_e edge); // REQUIRES MANUAL FREE: sourcepp_buffer_free SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_crop_image_data(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t xOffset, uint16_t height, uint16_t newHeight, uint16_t yOffset); diff --git a/lang/c/include/vtfppc/SHT.h b/lang/c/include/vtfppc/SHT.h index d60974713..5b5e175c9 100644 --- a/lang/c/include/vtfppc/SHT.h +++ b/lang/c/include/vtfppc/SHT.h @@ -19,7 +19,7 @@ typedef struct { vtfpp_sht_frame_bounds_t bounds[4]; } vtfpp_sht_frame_t; -#define VTFPP_SHT_FRAME_INVALID (vtfpp_sht_frame_t{.duration = 0.f}) +#define VTFPP_SHT_FRAME_INVALID (SOURCEPP_CAST_CTOR(vtfpp_sht_frame_t) {.duration = 0.f}) typedef struct { uint32_t id; @@ -28,7 +28,7 @@ typedef struct { float durationTotal; } vtfpp_sht_sequence_t; -#define VTFPP_SHT_SEQUENCE_INVALID (vtfpp_sht_sequence_t{.id = 0, .loop = 0, .frameCount = 0, .durationTotal = 0.f}) +#define VTFPP_SHT_SEQUENCE_INVALID (SOURCEPP_CAST_CTOR(vtfpp_sht_sequence_t) {.id = 0, .loop = 0, .frameCount = 0, .durationTotal = 0.f}) typedef void* vtfpp_sht_handle_t; diff --git a/lang/c/include/vtfppc/VTF.h b/lang/c/include/vtfppc/VTF.h index 10c732916..00e9ad64a 100644 --- a/lang/c/include/vtfppc/VTF.h +++ b/lang/c/include/vtfppc/VTF.h @@ -112,7 +112,7 @@ typedef struct { float bumpMapScale; } vtfpp_vtf_creation_options_t; -#define VTFPP_VTF_CREATION_OPTIONS_DEFAULT (vtfpp_vtf_creation_options_t{ \ +#define VTFPP_VTF_CREATION_OPTIONS_DEFAULT (SOURCEPP_CAST_CTOR(vtfpp_vtf_creation_options_t) { \ .majorVersion = 7, \ .minorVersion = 4, \ .outputFormat = VTFPP_VTF_FORMAT_DEFAULT, \ diff --git a/lang/c/src/vtfppc/ImageConversion.cpp b/lang/c/src/vtfppc/ImageConversion.cpp index bea646982..6349dbbb4 100644 --- a/lang/c/src/vtfppc/ImageConversion.cpp +++ b/lang/c/src/vtfppc/ImageConversion.cpp @@ -111,7 +111,7 @@ SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data(const un return Convert::toBuffer(ImageConversion::resizeImageData({reinterpret_cast(buffer), bufferLen}, static_cast(format), width, newWidth, height, newHeight, srgb, static_cast(filter), static_cast(edge))); } -SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data_strict(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t* widthOut, vtfpp_image_conversion_resize_method_e widthResize, uint16_t height, uint16_t newHeight, uint16_t* heightOut, vtfpp_image_conversion_resize_method_e heightResize, bool srgb, vtfpp_image_conversion_resize_filter_e filter, vtfpp_image_conversion_resize_edge_e edge) { +SOURCEPP_API sourcepp_buffer_t vtfpp_image_conversion_resize_image_data_strict(const unsigned char* buffer, size_t bufferLen, vtfpp_image_format_e format, uint16_t width, uint16_t newWidth, uint16_t* widthOut, vtfpp_image_conversion_resize_method_e widthResize, uint16_t height, uint16_t newHeight, uint16_t* heightOut, vtfpp_image_conversion_resize_method_e heightResize, int srgb, vtfpp_image_conversion_resize_filter_e filter, vtfpp_image_conversion_resize_edge_e edge) { SOURCEPP_EARLY_RETURN_VAL(buffer, SOURCEPP_BUFFER_INVALID); SOURCEPP_EARLY_RETURN_VAL(bufferLen, SOURCEPP_BUFFER_INVALID); SOURCEPP_EARLY_RETURN_VAL(format != VTFPP_IMAGE_FORMAT_EMPTY, SOURCEPP_BUFFER_INVALID); From bb433021929a73033fcc6bea62ce499141d384c1 Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sun, 23 Feb 2025 16:48:39 -0500 Subject: [PATCH 7/8] c: update vpkpp bindings --- include/vpkpp/vpkpp.h | 2 +- lang/c/include/vpkppc/format/HOG.h | 9 +++++++++ lang/c/include/vpkppc/format/VPP.h | 9 +++++++++ lang/c/include/vpkppc/vpkpp.h | 3 ++- lang/c/src/vpkppc/_vpkppc.cmake | 6 +++++- lang/c/src/vpkppc/format/HOG.cpp | 27 +++++++++++++++++++++++++++ lang/c/src/vpkppc/format/VPP.cpp | 27 +++++++++++++++++++++++++++ 7 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 lang/c/include/vpkppc/format/HOG.h create mode 100644 lang/c/include/vpkppc/format/VPP.h create mode 100644 lang/c/src/vpkppc/format/HOG.cpp create mode 100644 lang/c/src/vpkppc/format/VPP.cpp diff --git a/include/vpkpp/vpkpp.h b/include/vpkpp/vpkpp.h index 31620225c..2e8a1fb11 100644 --- a/include/vpkpp/vpkpp.h +++ b/include/vpkpp/vpkpp.h @@ -9,8 +9,8 @@ #include "format/GCF.h" #include "format/GMA.h" #include "format/HOG.h" -#include "format/OO7.h" #include "format/OL.h" +#include "format/OO7.h" #include "format/ORE.h" #include "format/PAK.h" #include "format/PCK.h" diff --git a/lang/c/include/vpkppc/format/HOG.h b/lang/c/include/vpkppc/format/HOG.h new file mode 100644 index 000000000..344145a54 --- /dev/null +++ b/lang/c/include/vpkppc/format/HOG.h @@ -0,0 +1,9 @@ +#pragma once + +#include "../PackFile.h" + +// REQUIRES MANUAL FREE: vpkpp_close +SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_hog_open(const char* path, vpkpp_entry_callback_t callback); + +// REQUIRES MANUAL FREE: sourcepp_string_free +SOURCEPP_API sourcepp_string_t vpkpp_hog_guid(vpkpp_pack_file_handle_t handle); diff --git a/lang/c/include/vpkppc/format/VPP.h b/lang/c/include/vpkppc/format/VPP.h new file mode 100644 index 000000000..fc0a8b758 --- /dev/null +++ b/lang/c/include/vpkppc/format/VPP.h @@ -0,0 +1,9 @@ +#pragma once + +#include "../PackFile.h" + +// REQUIRES MANUAL FREE: vpkpp_close +SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpp_open(const char* path, vpkpp_entry_callback_t callback); + +// REQUIRES MANUAL FREE: sourcepp_string_free +SOURCEPP_API sourcepp_string_t vpkpp_vpp_guid(vpkpp_pack_file_handle_t handle); diff --git a/lang/c/include/vpkppc/vpkpp.h b/lang/c/include/vpkppc/vpkpp.h index b3aff870e..23b8dd39d 100644 --- a/lang/c/include/vpkppc/vpkpp.h +++ b/lang/c/include/vpkppc/vpkpp.h @@ -8,8 +8,9 @@ #include "format/FPX.h" #include "format/GCF.h" #include "format/GMA.h" -#include "format/OO7.h" +#include "format/HOG.h" #include "format/OL.h" +#include "format/OO7.h" #include "format/ORE.h" #include "format/PAK.h" #include "format/PCK.h" diff --git a/lang/c/src/vpkppc/_vpkppc.cmake b/lang/c/src/vpkppc/_vpkppc.cmake index a50bd5519..478c62315 100644 --- a/lang/c/src/vpkppc/_vpkppc.cmake +++ b/lang/c/src/vpkppc/_vpkppc.cmake @@ -3,13 +3,15 @@ add_pretty_parser(vpkpp C "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/FPX.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/GCF.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/GMA.h" - "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/OO7.h" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/HOG.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/OL.h" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/OO7.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/ORE.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/PAK.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/PCK.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/VPK.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/VPK_VTMB.h" + "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/VPP.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/WAD3.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/format/ZIP.h" "${CMAKE_CURRENT_SOURCE_DIR}/lang/c/include/vpkppc/Attribute.h" @@ -22,6 +24,7 @@ add_pretty_parser(vpkpp C "${CMAKE_CURRENT_LIST_DIR}/format/FPX.cpp" "${CMAKE_CURRENT_LIST_DIR}/format/GCF.cpp" "${CMAKE_CURRENT_LIST_DIR}/format/GMA.cpp" + "${CMAKE_CURRENT_LIST_DIR}/format/HOG.cpp" "${CMAKE_CURRENT_LIST_DIR}/format/OL.cpp" "${CMAKE_CURRENT_LIST_DIR}/format/OO7.cpp" "${CMAKE_CURRENT_LIST_DIR}/format/ORE.cpp" @@ -29,6 +32,7 @@ add_pretty_parser(vpkpp C "${CMAKE_CURRENT_LIST_DIR}/format/PCK.cpp" "${CMAKE_CURRENT_LIST_DIR}/format/VPK.cpp" "${CMAKE_CURRENT_LIST_DIR}/format/VPK_VTMB.cpp" + "${CMAKE_CURRENT_LIST_DIR}/format/VPP.cpp" "${CMAKE_CURRENT_LIST_DIR}/format/WAD3.cpp" "${CMAKE_CURRENT_LIST_DIR}/format/ZIP.cpp" "${CMAKE_CURRENT_LIST_DIR}/Convert.cpp" diff --git a/lang/c/src/vpkppc/format/HOG.cpp b/lang/c/src/vpkppc/format/HOG.cpp new file mode 100644 index 000000000..7b16dd792 --- /dev/null +++ b/lang/c/src/vpkppc/format/HOG.cpp @@ -0,0 +1,27 @@ +#include + +#include + +#include +#include + +using namespace vpkpp; + +SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_hog_open(const char* path, vpkpp_entry_callback_t callback) { + SOURCEPP_EARLY_RETURN_VAL(path, nullptr); + + auto packFile = HOG::open(path, callback ? [callback](const std::string& path, const Entry& entry) { + callback(path.c_str(), const_cast(&entry)); + } : static_cast(nullptr)); + if (!packFile) { + return nullptr; + } + return packFile.release(); +} + +// REQUIRES MANUAL FREE: sourcepp_string_free +SOURCEPP_API sourcepp_string_t vpkpp_hog_guid(vpkpp_pack_file_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID); + + return Convert::toString(HOG::GUID); +} diff --git a/lang/c/src/vpkppc/format/VPP.cpp b/lang/c/src/vpkppc/format/VPP.cpp new file mode 100644 index 000000000..4106b6a86 --- /dev/null +++ b/lang/c/src/vpkppc/format/VPP.cpp @@ -0,0 +1,27 @@ +#include + +#include + +#include +#include + +using namespace vpkpp; + +SOURCEPP_API vpkpp_pack_file_handle_t vpkpp_vpp_open(const char* path, vpkpp_entry_callback_t callback) { + SOURCEPP_EARLY_RETURN_VAL(path, nullptr); + + auto packFile = VPP::open(path, callback ? [callback](const std::string& path, const Entry& entry) { + callback(path.c_str(), const_cast(&entry)); + } : static_cast(nullptr)); + if (!packFile) { + return nullptr; + } + return packFile.release(); +} + +// REQUIRES MANUAL FREE: sourcepp_string_free +SOURCEPP_API sourcepp_string_t vpkpp_vpp_guid(vpkpp_pack_file_handle_t handle) { + SOURCEPP_EARLY_RETURN_VAL(handle, SOURCEPP_STRING_INVALID); + + return Convert::toString(VPP::GUID); +} From 37f6417112523aaf3baa1f45a12f2dc44658d14c Mon Sep 17 00:00:00 2001 From: craftablescience Date: Sun, 23 Feb 2025 16:48:44 -0500 Subject: [PATCH 8/8] csharp: update vpkpp bindings --- lang/csharp/src/vpkpp/Format/HOG.cs | 58 +++++++++++++++++++++++++++++ lang/csharp/src/vpkpp/Format/VPP.cs | 58 +++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 lang/csharp/src/vpkpp/Format/HOG.cs create mode 100644 lang/csharp/src/vpkpp/Format/VPP.cs diff --git a/lang/csharp/src/vpkpp/Format/HOG.cs b/lang/csharp/src/vpkpp/Format/HOG.cs new file mode 100644 index 000000000..1e7d5e88e --- /dev/null +++ b/lang/csharp/src/vpkpp/Format/HOG.cs @@ -0,0 +1,58 @@ +using System; +using System.Runtime.InteropServices; + +namespace vpkpp.Format +{ + using EntryCallback = Action; + + internal static unsafe partial class Extern + { + internal static unsafe partial class HOG + { + [LibraryImport("sourcepp_vpkppc", EntryPoint = "vpkpp_hog_open")] + public static partial void* Open([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback); + + [LibraryImport("sourcepp_vpkppc", EntryPoint = "vpkpp_hog_guid")] + public static partial sourcepp.String GUID(); + } + } + + public class HOG : PackFile + { + private protected unsafe HOG(void* handle) : base(handle) {} + + public new static HOG? Open(string path) + { + unsafe + { + var handle = Extern.HOG.Open(path, 0); + return handle == null ? null : new HOG(handle); + } + } + + public new static HOG? Open(string path, EntryCallback callback) + { + unsafe + { + EntryCallbackNative callbackNative = (path, entry) => + { + callback(path, new Entry(entry, true)); + }; + var handle = Extern.HOG.Open(path, Marshal.GetFunctionPointerForDelegate(callbackNative)); + return handle == null ? null : new HOG(handle); + } + } + + public static string GUID + { + get + { + unsafe + { + var str = Extern.HOG.GUID(); + return sourcepp.StringUtils.ConvertToStringAndDelete(ref str); + } + } + } + } +} diff --git a/lang/csharp/src/vpkpp/Format/VPP.cs b/lang/csharp/src/vpkpp/Format/VPP.cs new file mode 100644 index 000000000..32027c269 --- /dev/null +++ b/lang/csharp/src/vpkpp/Format/VPP.cs @@ -0,0 +1,58 @@ +using System; +using System.Runtime.InteropServices; + +namespace vpkpp.Format +{ + using EntryCallback = Action; + + internal static unsafe partial class Extern + { + internal static unsafe partial class VPP + { + [LibraryImport("sourcepp_vpkppc", EntryPoint = "vpkpp_vpp_open")] + public static partial void* Open([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr callback); + + [LibraryImport("sourcepp_vpkppc", EntryPoint = "vpkpp_vpp_guid")] + public static partial sourcepp.String GUID(); + } + } + + public class VPP : PackFile + { + private protected unsafe VPP(void* handle) : base(handle) {} + + public new static VPP? Open(string path) + { + unsafe + { + var handle = Extern.VPP.Open(path, 0); + return handle == null ? null : new VPP(handle); + } + } + + public new static VPP? Open(string path, EntryCallback callback) + { + unsafe + { + EntryCallbackNative callbackNative = (path, entry) => + { + callback(path, new Entry(entry, true)); + }; + var handle = Extern.VPP.Open(path, Marshal.GetFunctionPointerForDelegate(callbackNative)); + return handle == null ? null : new VPP(handle); + } + } + + public static string GUID + { + get + { + unsafe + { + var str = Extern.VPP.GUID(); + return sourcepp.StringUtils.ConvertToStringAndDelete(ref str); + } + } + } + } +}