From a37880fc0d62671527017b1d160ff442f26ce918 Mon Sep 17 00:00:00 2001
From: Faber <103538724+FaberTheCatboy@users.noreply.github.com>
Date: Tue, 5 Jul 2022 15:08:18 -0700
Subject: [PATCH 1/5] Bo1 main_point_hook
Changed Hook address from Cod4 to Bo1 Radiant
---
src/main.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main.cpp b/src/main.cpp
index def2e73..2c208fe 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -39,7 +39,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l
Beep(523, 100);
// Adress is the entry adress found in IDA under Exports
- main::entry_point_hook.initialize(0x5C4299, entry_point)->install();
+ main::entry_point_hook.initialize(0x5D92E3, entry_point)->install(); //This is the entry point for the Linkermod Bo1 Radiant
}
else if (ul_reason_for_call == DLL_PROCESS_DETACH)
From b0247ad2c456656dcf7ea4285a79636ba386c95e Mon Sep 17 00:00:00 2001
From: Faber <103538724+FaberTheCatboy@users.noreply.github.com>
Date: Tue, 5 Jul 2022 16:03:57 -0700
Subject: [PATCH 2/5] Update main.cpp
---
src/main.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main.cpp b/src/main.cpp
index 2c208fe..b025e6c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -24,7 +24,7 @@ __declspec(naked) void entry_point()
call main::initialize
// same address as entry_point_hook.initialize
- mov eax, 5C4299h
+ mov eax, 5D92E3h
jmp eax
}
}
@@ -34,7 +34,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
DWORD oldProtect;
- VirtualProtect(GetModuleHandle(nullptr), 0x234D000, PAGE_EXECUTE_READWRITE, &oldProtect); // find this with CFF Explorer - Optinal Headers - SizeOfImage
+ VirtualProtect(GetModuleHandle(nullptr), 0x257A000, PAGE_EXECUTE_READWRITE, &oldProtect); // find this with CFF Explorer - Optinal Headers - SizeOfImage
Beep(523, 100);
From 66ab9f8886096e4f7d827c876f999148dec2623c Mon Sep 17 00:00:00 2001
From: FaberTheCatgirl <103538724+FaberTheCatgirl@users.noreply.github.com>
Date: Fri, 17 Mar 2023 10:21:28 -0700
Subject: [PATCH 3/5] Wip Update README.md
---
README.md | 37 +++++++++++++++++++------------------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/README.md b/README.md
index 35c73bc..d8e09f6 100644
--- a/README.md
+++ b/README.md
@@ -112,14 +112,14 @@ ___
-1. Install the CoD4 Modtools
-2. Download the latest [release](https://github.com/xoxor4d/iw3xo-radiant/releases)
+1. Install the Bo1 Modtools
+2. Download the latest [release](https://github.com/VenomModding/T5xRadiant/releases)
3. Copy the contents into your cod4 root directory
-4. Start `bin/IW3xRadiant.exe`
+4. Start `bin/T5xRadiant.exe`
-- [NIGHTLY] install latest release, download nightly, unpack and replace `iw3r.dll` within the `bin` folder
- -> check for additional assets in the __#nightly-builds__ channel (📍) on the [iw3xo discord](https://discord.gg/t5jRGbj)
-- [OPTIONAL] __bo3-tool-textures.zip__ (unpack and place `.iwi's` into `bin\IW3xRadiant\images`)
+- [NIGHTLY] install latest release, download nightly, unpack and replace `t5xr.dll` within the `bin` folder
+ -> check for additional assets in the __#nightly-builds__ channel (📍) on the [Venom Modding discord](https://discord.gg/QuNcjXbsqY)
+- [OPTIONAL] __bo3-tool-textures.zip__ (unpack and place `.iwi's` into `bin\T5xRadiant\images`)
@@ -130,14 +130,14 @@ ___
### How to build / compile the project using Visual Studio
1. Clone the repo! __(zip does not include deps!)__
-2. Copy everything within the assets folder into your cod4-root folder
+2. Copy everything within the assets folder into your bo1-root folder
3. Use __update_submodules.bat__ to update submodules
4. Use __generate-buildfiles.bat__ to build project files with premake
-5. Load the solution `(build/iw3xo-radiant.sln)` and open the iw3r project-settings to setup paths:
-> - General output directory path -> `path-to-cod4-root\bin\`
-> - Debugging command -> `path-to-cod4-root\bin\IW3xRadiant.exe`
-> - Debugging working directory -> `path-to-cod4-root\bin\`
-> + Preferred: Create a new environment variable called `COD4_ROOT` that points to your cod4 directory and re-generate the project files.
+5. Load the solution `(build/t5x-radiant.sln)` and open the iw3r project-settings to setup paths:
+> - General output directory path -> `path-to-bo1-root\bin\`
+> - Debugging command -> `path-to-bo1-root\bin\T5xRadiant.exe`
+> - Debugging working directory -> `path-to-bo1-root\bin\`
+> + Preferred: Create a new environment variable called `BO1_ROOT` that points to your bo1 directory and re-generate the project files.
6. Build -> Build Solution or run with debugger
@@ -146,17 +146,17 @@ ___
1. Install C++ Build tools (msbuild)
2. Add msbuild folder to the "PATH" environment variable:
> `%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin`
-3. Add `COD4_ROOT` environment variable with path to your cod4 directory
-> `"COD4_ROOT" "D:\COD4-Modtools"`
+3. Add `BO1_ROOT` environment variable with path to your bo1 directory
+> `"BO1_ROOT" "D:\BO1-Modtools"`
4. Clone the repo (zip does not include deps!)
-5. Copy everything within the assets folder into your cod4-root folder
+5. Copy everything within the assets folder into your bo1-root folder
6. Drag and drop all files from `.vscode/tracked\` into `.vscode\`
-7. Open __iw3xo-radiant.code-workspace__
+7. Open __t5x-radiant.code-workspace__
8. Run task: `update_submodules` or open __update_submodules.bat__
9. Run task: `generate-buildfiles` or open __generate-buildfiles.bat__
-Use provided build-tasks with the option to copy `iw3r.dll` and `iw3r.pdb` to `%COD4_ROOT%/bin`
-__Run->Start Debugging__ will build and copy a debug build to to `%COD4_ROOT%/bin` and launch IW3xRadiant.
+Use provided build-tasks with the option to copy `T5xr.dll` and `T5xr.pdb` to `%BO1_ROOT%/bin`
+__Run->Start Debugging__ will build and copy a debug build to to `%BO1_ROOT%/bin` and launch IW3xRadiant.
@@ -165,6 +165,7 @@ ___
### Optional:
+https://github.com/VenomModding/t5xo-dev
https://github.com/xoxor4d/iw3xo-dev
### Project Page:
From acc6a11b431b8a5cc324cdd449cc1e5ccfdc18bc Mon Sep 17 00:00:00 2001
From: Faber <103538724+FaberTheCatboy@users.noreply.github.com>
Date: Fri, 17 Mar 2023 11:13:55 -0700
Subject: [PATCH 4/5] T5 Radiant
---
.github/workflows/build-debug.yml | 4 +-
.github/workflows/build-release.yml | 4 +-
.vscode/readme.txt | 10 +-
.vscode/tracked/copy-to-cod4-dir.bat | 4 +-
.vscode/tracked/launch.json | 4 +-
.vscode/tracked/tasks.json | 12 +-
assets/bin/IW3xRadiant/batch/compile_bsp.bat | 4 +-
assets/bin/iw3xradiant.def | 2 +-
assets/bin/iw3xradiant.prj | 4 +-
premake5.lua | 16 +-
src/Resource.rc | 14 +-
src/common/mainframe.cpp | 6 +-
src/common/radiantapp.cpp | 16 +-
src/common/texwnd.cpp | 12 +-
src/components/modules/config.cpp | 8 +-
src/components/modules/d3dbsp.cpp | 1994 +++++++++---------
src/components/modules/effects.cpp | 2 +-
src/components/modules/generate_previews.cpp | 2 +-
src/components/modules/gui.cpp | 4 +-
src/components/modules/main_module.cpp | 12 +-
src/components/modules/mesh_painter.cpp | 12 +-
src/components/modules/patches.cpp | 2 +-
src/components/modules/reflectionprobes.cpp | 4 +-
src/components/modules/renderer.cpp | 8 +-
src/components/modules/time_wasted.cpp | 4 +-
src/ggui/effects_editor_gui.cpp | 2 +-
src/ggui/hotkeys.cpp | 8 +-
src/ggui/menubar.cpp | 2 +-
src/ggui/textures.cpp | 4 +-
src/ggui/toolbar.cpp | 4 +-
src/utils/filesystem.cpp | 2 +-
31 files changed, 1093 insertions(+), 1093 deletions(-)
diff --git a/.github/workflows/build-debug.yml b/.github/workflows/build-debug.yml
index 00823f2..35e748b 100644
--- a/.github/workflows/build-debug.yml
+++ b/.github/workflows/build-debug.yml
@@ -47,8 +47,8 @@ jobs:
with:
name: ${{matrix.configuration}} binaries
path: |
- build/bin/${{matrix.configuration}}/iw3r.dll
- build/bin/${{matrix.configuration}}/iw3r.pdb
+ build/bin/${{matrix.configuration}}/t5xr.dll
+ build/bin/${{matrix.configuration}}/t5xr.pdb
build/bin/${{matrix.configuration}}/PhysX_32.dll
build/bin/${{matrix.configuration}}/PhysXCommon_32.dll
build/bin/${{matrix.configuration}}/PhysXCooking_32.dll
diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
index 7ded048..c619a24 100644
--- a/.github/workflows/build-release.yml
+++ b/.github/workflows/build-release.yml
@@ -47,8 +47,8 @@ jobs:
with:
name: ${{matrix.configuration}} binaries
path: |
- build/bin/${{matrix.configuration}}/iw3r.dll
- build/bin/${{matrix.configuration}}/iw3r.pdb
+ build/bin/${{matrix.configuration}}/t5xr.dll
+ build/bin/${{matrix.configuration}}/t5xr.pdb
build/bin/${{matrix.configuration}}/PhysX_32.dll
build/bin/${{matrix.configuration}}/PhysXCommon_32.dll
build/bin/${{matrix.configuration}}/PhysXCooking_32.dll
diff --git a/.vscode/readme.txt b/.vscode/readme.txt
index ac09f28..74ba0f7 100644
--- a/.vscode/readme.txt
+++ b/.vscode/readme.txt
@@ -1,10 +1,10 @@
1.) Install C++ Build tools (msbuild)
-2.) Add msbuild to the "PATH" environment variable (eg. "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin")
-3.) Add "COD4_ROOT" environment variable with path to your cod4 directory (eg. "COD4_ROOT" "D:\COD4-Modtools")
+2.) Add msbuild to the "PATH" environment variable (eg. "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin")
+3.) Add "BO1_ROOT" environment variable with path to your bo1 directory (eg. "BO1_ROOT" "D:\BO1-Modtools")
4.) Drag and drop all files from ".vscode/tracked\" into ".vscode\ (we ignore all files in .vscode/ besides the readme)
-5.) Open "iw3xo-radiant.code-workspace"
+5.) Open "t5xo-radiant.code-workspace"
6.) Run task "update_submodules" or open "update_submodules.bat"
7.) Run task "generate-buildfiles" or open "generate-buildfiles.bat"
-Use provided build-tasks to build debug/release builds with the option to copy iw3r.dll and iw3r.pdb to %COD4_ROOT%/bin.
-Run->Start Debugging will build and copy a debug build to to %COD4_ROOT%/bin and launch IW3xRadiant.
\ No newline at end of file
+Use provided build-tasks to build debug/release builds with the option to copy t5xr.dll and t5xr.pdb to %BO1_ROOT%/bin.
+Run->Start Debugging will build and copy a debug build to to %BO1_ROOT%/bin and launch T5xRadiant.
\ No newline at end of file
diff --git a/.vscode/tracked/copy-to-cod4-dir.bat b/.vscode/tracked/copy-to-cod4-dir.bat
index 95f2187..7680884 100644
--- a/.vscode/tracked/copy-to-cod4-dir.bat
+++ b/.vscode/tracked/copy-to-cod4-dir.bat
@@ -3,5 +3,5 @@ set path=%~1
cd ../build/bin/%path%
@echo on
-copy iw3r.dll "%COD4_ROOT%\bin\"
-copy iw3r.pdb "%COD4_ROOT%\bin\"
\ No newline at end of file
+copy t5xr.dll "%BO1_ROOT%\bin\"
+copy t5xr.pdb "%BO1_ROOT%\bin\"
\ No newline at end of file
diff --git a/.vscode/tracked/launch.json b/.vscode/tracked/launch.json
index 4ca7209..e1d292f 100644
--- a/.vscode/tracked/launch.json
+++ b/.vscode/tracked/launch.json
@@ -8,10 +8,10 @@
"name": "(Windows) Start",
"type": "cppvsdbg",
"request": "launch",
- "program": "IW3xRadiant.exe",
+ "program": "T5xRadiant.exe",
"args": [],
"stopAtEntry": false,
- "cwd": "${env:COD4_ROOT}\\bin",
+ "cwd": "${env:BO1_ROOT}\\bin",
"environment": [],
"preLaunchTask": "debug-build-copy"
}
diff --git a/.vscode/tracked/tasks.json b/.vscode/tracked/tasks.json
index 927c4a8..4298af7 100644
--- a/.vscode/tracked/tasks.json
+++ b/.vscode/tracked/tasks.json
@@ -45,7 +45,7 @@
"label": "debug-build",
"command": "msbuild.exe",
"args": [
- "build/iw3xo-radiant.sln",
+ "build/t5xo-radiant.sln",
"/p:Configuration=Debug;Platform=Win32",
],
"problemMatcher": "$msCompile",
@@ -61,7 +61,7 @@
"label": "release-build",
"command": "msbuild.exe",
"args": [
- "build/iw3xo-radiant.sln",
+ "build/t5xo-radiant.sln",
"/p:Configuration=Release;Platform=Win32",
],
"problemMatcher": ["$msCompile"],
@@ -72,22 +72,22 @@
// *
// copy to dir
- // debug: copy build to cod4/bin
+ // debug: copy build to bo1/bin
{
"type": "shell",
"label": "z-copy-debug",
- "command": "copy-to-cod4-dir.bat",
+ "command": "copy-to-bo1-dir.bat",
"options":
{
"cwd": "${workspaceFolder}\\.vscode"
},
"args": ["debug"],
},
- // release: copy build to cod4/bin
+ // release: copy build to bo1/bin
{
"type": "shell",
"label": "z-copy-release",
- "command": "copy-to-cod4-dir.bat",
+ "command": "copy-to-bo1-dir.bat",
"options":
{
"cwd": "${workspaceFolder}\\.vscode"
diff --git a/assets/bin/IW3xRadiant/batch/compile_bsp.bat b/assets/bin/IW3xRadiant/batch/compile_bsp.bat
index 45676ea..fd89577 100644
--- a/assets/bin/IW3xRadiant/batch/compile_bsp.bat
+++ b/assets/bin/IW3xRadiant/batch/compile_bsp.bat
@@ -38,7 +38,7 @@ if "%compileBSP%" == "1" (
echo.
copy "%mapsourcepath%%mapname%.map" "%bsppath%%mapname%.map"
- "%treepath%bin\cod4map" -platform pc -loadFrom "%mapsourcepath%%mapname%.map" %parmBSPOptions% "%bsppath%%mapname%"
+ "%treepath%bin\bo1map" -platform pc -loadFrom "%mapsourcepath%%mapname%.map" %parmBSPOptions% "%bsppath%%mapname%"
)
if "%compileLight%" == "1" (
@@ -47,7 +47,7 @@ if "%compileLight%" == "1" (
echo.
IF EXIST "%mapsourcepath%%mapname%.grid" copy "%mapsourcepath%%mapname%.grid" "%bsppath%%mapname%.grid"
- "%treepath%bin\cod4rad" -platform pc %parmLightOptions% "%bsppath%%mapname%"
+ "%treepath%bin\bo1rad" -platform pc %parmLightOptions% "%bsppath%%mapname%"
)
IF EXIST "%bsppath%%mapname%.map" del "%bsppath%%mapname%.map"
diff --git a/assets/bin/iw3xradiant.def b/assets/bin/iw3xradiant.def
index b75b047..fff7e63 100644
--- a/assets/bin/iw3xradiant.def
+++ b/assets/bin/iw3xradiant.def
@@ -145,7 +145,7 @@ NO_STATIC_SHADOWS - the opaque surfaces will not cast static light map shadows
/*QUAKED fx_origin (0.45 0.3 0.2) (-2 -2 -2) (2 2 2)
used for createFX generation and general effect handling.
-default: "fx" "iw3xradiant_def"
+default: "fx" "t5xradiant_def"
fx - effect definition
fxloop - make createFX gen. use loopfx instead of createOneshotEffect
diff --git a/assets/bin/iw3xradiant.prj b/assets/bin/iw3xradiant.prj
index 5c807dd..ac1bbd9 100644
--- a/assets/bin/iw3xradiant.prj
+++ b/assets/bin/iw3xradiant.prj
@@ -1,9 +1,9 @@
{
"basepath" ".."
"mapspath" "..\\map_source"
-"entitypath" ".\\iw3xradiant.def"
+"entitypath" ".\\t5xradiant.def"
"autosave" "autosave.map"
"game" ""
"basegame" ""
-"layeredmaterials" "cod4_layered_material_library.txt"
+"layeredmaterials" "bo1_layered_material_library.txt"
}
diff --git a/premake5.lua b/premake5.lua
index 5d15b78..3f0e303 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -212,9 +212,9 @@ end
dependencies.load()
-workspace "iw3xo-radiant"
+workspace "T5xRadiant"
- startproject "iw3r"
+ startproject "t5xr"
location "./build"
objdir "%{wks.location}/obj"
targetdir "%{wks.location}/bin/%{cfg.buildcfg}"
@@ -283,7 +283,7 @@ workspace "iw3xo-radiant"
-- Project
- project "iw3r"
+ project "t5xr"
kind "SharedLib"
language "C++"
@@ -313,11 +313,11 @@ workspace "iw3xo-radiant"
"/Zm100 -Zm100"
}
- if(os.getenv("COD4_ROOT")) then
- print ("Setup paths using environment variable 'COD4_ROOT' :: '" .. os.getenv("COD4_ROOT") .. "'")
- targetdir(os.getenv("COD4_ROOT") .. "/bin/")
- debugdir (os.getenv("COD4_ROOT") .. "/bin/")
- debugcommand (os.getenv("COD4_ROOT") .. "/bin/" .. "IW3xRadiant.exe")
+ if(os.getenv("BO1_ROOT")) then
+ print ("Setup paths using environment variable 'BO1_ROOT' :: '" .. os.getenv("BO1_ROOT") .. "'")
+ targetdir(os.getenv("BO1_ROOT") .. "/bin/")
+ debugdir (os.getenv("BO1_ROOT") .. "/bin/")
+ debugcommand (os.getenv("BO1_ROOT") .. "/bin/" .. "T5xRadiant.exe")
end
-- Specific configurations
diff --git a/src/Resource.rc b/src/Resource.rc
index d6f6dcb..e304fb8 100644
--- a/src/Resource.rc
+++ b/src/Resource.rc
@@ -67,17 +67,17 @@ BEGIN
BEGIN
BLOCK "040904b0"
BEGIN
- VALUE "CompanyName", ""
+ VALUE "CompanyName", "Gungnir Studios LLC"
#ifdef _DEBUG
- VALUE "FileDescription", "Radiant modification built for IW3xo"
+ VALUE "FileDescription", "Radiant modification built for T5xo-dev"
#else
- VALUE "FileDescription", "Radiant modification built for IW3xo"
+ VALUE "FileDescription", "Radiant modification built for T5xo-dev"
#endif
VALUE "FileVersion", VERSION_FILE
- VALUE "InternalName", "iw3r"
- VALUE "LegalCopyright", "xoxor4d.github.io"
- VALUE "OriginalFilename", "iw3r.dll"
- VALUE "ProductName", "IW3xRadiant"
+ VALUE "InternalName", "t5xr"
+ VALUE "LegalCopyright", "Copyright (C) 2023 Gungnir Studios LLC"
+ VALUE "OriginalFilename", "t5xr.dll"
+ VALUE "ProductName", "T5xRadiant"
VALUE "ProductVersion", VERSION_PRODUCT
END
END
diff --git a/src/common/mainframe.cpp b/src/common/mainframe.cpp
index 6fc63db..19cb3a2 100644
--- a/src/common/mainframe.cpp
+++ b/src/common/mainframe.cpp
@@ -203,7 +203,7 @@ void __declspec(naked) hk_on_createclient()
}
}
-// auto load iw3xradiant.prj
+// auto load t5xradiant.prj
void create_qe_children(cmainframe* mainframe)
{
char app_path[_MAX_PATH + 1];
@@ -216,7 +216,7 @@ void create_qe_children(cmainframe* mainframe)
if(!bProjectLoaded)
{
- game::Com_Error("Unable to load project file ");
+ game::Com_Error("Unable to load project file ");
}
auto* m_camera_origin = reinterpret_cast(0x241A5A4);
@@ -882,7 +882,7 @@ void cmainframe::hooks()
// handle wm_char events for non-focused subwindows
utils::hook(0x421A7B, cmainframe::windowproc, HOOK_CALL).install()->quick();
- // automatically load iw3xradiant.prj
+ // automatically load t5xradiant.prj
utils::hook(0x422984, hk_create_qe_children_stub, HOOK_JUMP).install()->quick();
// hook end of createclient
diff --git a/src/common/radiantapp.cpp b/src/common/radiantapp.cpp
index 69a1db9..56cab2a 100644
--- a/src/common/radiantapp.cpp
+++ b/src/common/radiantapp.cpp
@@ -102,7 +102,7 @@ bool on_exit_instance()
void registery_save([[maybe_unused]] CPrefsDlg* prefs)
{
const auto state = afx::get_module_state();
- CWinApp_WriteProfileInt(state->m_pCurrentWinApp, "Prefs", "iw3x_mainframe_menubar_enabled", ggui::mainframe_menubar_enabled);
+ CWinApp_WriteProfileInt(state->m_pCurrentWinApp, "Prefs", "t5x_mainframe_menubar_enabled", ggui::mainframe_menubar_enabled);
CWinApp_WriteProfileInt(state->m_pCurrentWinApp, "Prefs", "lights_max_intensity", game::g_qeglobals->preview_at_max_intensity);
CWinApp_WriteProfileInt(state->m_pCurrentWinApp, "Prefs", "force_zero_dropheight", prefs->m_bForceZeroDropHeight);
CWinApp_WriteProfileInt(state->m_pCurrentWinApp, "Prefs", "discord_rpc", components::discord::g_enable_discord_rpc);
@@ -111,7 +111,7 @@ void registery_save([[maybe_unused]] CPrefsDlg* prefs)
void registery_load()
{
const auto state = afx::get_module_state();
- ggui::mainframe_menubar_enabled = CWinApp_GetProfileIntA(state->m_pCurrentWinApp, "Prefs", "iw3x_mainframe_menubar_enabled", 0);
+ ggui::mainframe_menubar_enabled = CWinApp_GetProfileIntA(state->m_pCurrentWinApp, "Prefs", "t5x_mainframe_menubar_enabled", 0);
// always bothered me ..
game::g_qeglobals->preview_at_max_intensity = CWinApp_GetProfileIntA(state->m_pCurrentWinApp, "Prefs", "lights_max_intensity", 0);
@@ -147,7 +147,7 @@ BOOL LoadRegistryInfo(const char* pszName, void* pvBuf, long* plSize)
}
else
{
- RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\iw\\IW3xRadiant\\IW3xRadiant", 0, KEY_READ, &hKey);
+ RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\iw\\T5xRadiant\\T5xRadiant", 0, KEY_READ, &hKey);
}
RegQueryValueExA(hKey, pszName, NULL, (unsigned long*)&lType, (unsigned char*)pvBuf, (unsigned long*)plSize);
@@ -424,11 +424,11 @@ void radiantapp::hooks()
// show/hide mainframe menubar on startup 03 :: CMainFrame::OnCreate
utils::hook(0x421057, menubar_stub_03, HOOK_JUMP).install()->quick();
- // do not use or overwrite stock radiant registry keys - create seperate ones for IW3xRadiant
- utils::hook::write_string(0x6EBA58, R"(Software\iw\IW3xRadiant\IW3xRadiant)"s);
- utils::hook::write_string(0x6E2320, R"(iw\IW3xRadiant)"s);
- utils::hook::write_string(0x6E22F0, R"(Software\iw\IW3xRadiant\IniPrefs)"s);
- utils::hook::write_string(0x6DC1EC, R"(Software\iw\IW3xRadiant\MRU)"s);
+ // do not use or overwrite stock radiant registry keys - create seperate ones for T5xRadiant
+ utils::hook::write_string(0x6EBA58, R"(Software\iw\T5xRadiant\T5xRadiant)"s);
+ utils::hook::write_string(0x6E2320, R"(iw\T5xRadiant)"s);
+ utils::hook::write_string(0x6E22F0, R"(Software\iw\T5xRadiant\IniPrefs)"s);
+ utils::hook::write_string(0x6DC1EC, R"(Software\iw\T5xRadiant\MRU)"s);
#ifdef HIDE_MAINFRAME_MENUBAR
// -----------------------------------------------------------------------
diff --git a/src/common/texwnd.cpp b/src/common/texwnd.cpp
index 68c78c4..eac8c39 100644
--- a/src/common/texwnd.cpp
+++ b/src/common/texwnd.cpp
@@ -53,7 +53,7 @@ void ctexwnd::write_favourite_list(int list_id)
dvars::fs_homepath)
{
std::string dir_path = dvars::fs_homepath->current.string;
- dir_path += R"(\IW3xRadiant\texture_favourites\)";
+ dir_path += R"(\T5xRadiant\texture_favourites\)";
std::filesystem::create_directories(dir_path);
if (std::filesystem::exists(dir_path))
@@ -77,7 +77,7 @@ void ctexwnd::write_favourite_list(int list_id)
// read line by line
while (std::getline(file, input))
{
- if (!line_num && input.find("// texture favourites generated by iw3xo-radiant") == std::string::npos)
+ if (!line_num && input.find("// texture favourites generated by t5xo-radiant") == std::string::npos)
{
// invalid file
break;
@@ -115,7 +115,7 @@ void ctexwnd::write_favourite_list(int list_id)
if (ofile.is_open())
{
- ofile << "// texture favourites generated by iw3xo-radiant" << std::endl;
+ ofile << "// texture favourites generated by t5xo-radiant" << std::endl;
ofile << texwnd_vector_of_favourites[list_id][0] << std::endl;
int line_num = 0;
@@ -136,7 +136,7 @@ void ctexwnd::write_favourite_list(int list_id)
}
else
{
- game::printf_to_console("[ERR][TEX] Failed to find favourite list '%s' in 'bin/IW3xRadiant/texture_favourites'", texwnd_vector_of_favourites[list_id][0].c_str());
+ game::printf_to_console("[ERR][TEX] Failed to find favourite list '%s' in 'bin/T5xRadiant/texture_favourites'", texwnd_vector_of_favourites[list_id][0].c_str());
}
}
}
@@ -199,7 +199,7 @@ void ctexwnd::load_favourites()
std::ifstream file;
std::string filepath = dvars::fs_homepath->current.string;
- filepath += R"(\IW3xRadiant\texture_favourites\)";
+ filepath += R"(\T5xRadiant\texture_favourites\)";
if (std::filesystem::exists(filepath))
{
@@ -221,7 +221,7 @@ void ctexwnd::load_favourites()
// read line by line
while (std::getline(file, input))
{
- if (!line_num && input.find("// texture favourites generated by iw3xo-radiant") == std::string::npos)
+ if (!line_num && input.find("// texture favourites generated by t5xo-radiant") == std::string::npos)
{
// invalid file
break;
diff --git a/src/components/modules/config.cpp b/src/components/modules/config.cpp
index d15d678..eb60cd8 100644
--- a/src/components/modules/config.cpp
+++ b/src/components/modules/config.cpp
@@ -15,9 +15,9 @@ namespace components
int loaded_dvar_count = 0;
std::ifstream cfg;
- if (utils::fs::open_file_homepath("IW3xRadiant", "dvars.cfg", false, cfg))
+ if (utils::fs::open_file_homepath("T5xRadiant", "dvars.cfg", false, cfg))
{
- game::printf_to_console("[CFG] Loading dvars from config 'bin/IW3xRadiant/dvars.cfg'");
+ game::printf_to_console("[CFG] Loading dvars from config 'bin/T5xRadiant/dvars.cfg'");
std::string input;
std::vector args;
@@ -94,9 +94,9 @@ namespace components
{
std::ofstream cfg;
- if (utils::fs::write_file_homepath("IW3xRadiant", "dvars.cfg", false, cfg))
+ if (utils::fs::write_file_homepath("T5xRadiant", "dvars.cfg", false, cfg))
{
- cfg << "// generated by iw3xo-radiant" << std::endl;
+ cfg << "// generated by t5xo-radiant" << std::endl;
for (auto iter = 0; iter < *game::dvarCount; ++iter)
{
diff --git a/src/components/modules/d3dbsp.cpp b/src/components/modules/d3dbsp.cpp
index bd3b443..8ecf87b 100644
--- a/src/components/modules/d3dbsp.cpp
+++ b/src/components/modules/d3dbsp.cpp
@@ -1,181 +1,181 @@
-#include "std_include.hpp"
-
-namespace components
-{
- // *
- // * Entity Handling
- // *
-
- int d3dbsp::radiant_dobj_count = 0;
- d3dbsp::radiant_dobj_s d3dbsp::radiant_dobj[512] = {};
-
-
+#include "std_include.hpp"
+
+namespace components
+{
+ // *
+ // * Entity Handling
+ // *
+
+ int d3dbsp::radiant_dobj_count = 0;
+ d3dbsp::radiant_dobj_s d3dbsp::radiant_dobj[512] = {};
+
+
void d3dbsp::dobj_clear_list()
{
- memset(d3dbsp::radiant_dobj, 0, sizeof(d3dbsp::radiant_dobj));
+ memset(d3dbsp::radiant_dobj, 0, sizeof(d3dbsp::radiant_dobj));
d3dbsp::radiant_dobj_count = 0;
- }
-
- // hack but works
- unsigned short lightinghandle = 0;
-
- // R_AddDObjToScene
- void dobj_add_to_scene(game::DObj_s* obj, game::cpose_t* pose, unsigned int ent_num, float* lighting_origin)
- {
- if (!obj)
- {
- Assert();
- }
-
- if (!pose)
- {
- Assert();
- }
-
- unsigned int& gfxCfg_entCount = *reinterpret_cast(0x13683DC);
- //DWORD& scene_dpvs_sceneDObjIndex = *reinterpret_cast(0x14C564C);
- DWORD& scene_dpvs_sceneXModelIndex = *reinterpret_cast(0x14C5648);
-
- if (ent_num >= gfxCfg_entCount)
- {
- Assert();
- }
-
- if (game::Dvar_FindVar("r_drawEntities")->current.enabled)
- {
- const unsigned int scene_ent_index = utils::hook::call(0x501D80)(); // R_AllocSceneModel()
- if (scene_ent_index < 1024)
- {
- game::GfxSceneModel* sceneModel = &game::scene->sceneModel[scene_ent_index];
- sceneModel->model = obj->models[0];
- sceneModel->DObj_s_obj = obj;
- sceneModel->entnum = static_cast(ent_num);
- sceneModel->cachedLightingHandle = &lightinghandle;
- sceneModel->placement.base.origin[0] = pose->origin[0];
- sceneModel->placement.base.origin[1] = pose->origin[1];
- sceneModel->placement.base.origin[2] = pose->origin[2];
-
- game::AnglesToQuat(pose->angles, sceneModel->placement.base.quat);
-
- sceneModel->placement.scale = 1.0f;
- sceneModel->radius = sceneModel->model->radius;
- sceneModel->lightingOrigin[0] = *lighting_origin;
- sceneModel->lightingOrigin[1] = lighting_origin[1];
- sceneModel->lightingOrigin[2] = lighting_origin[2];
- sceneModel->gfxEntIndex = 0;
-
- *((WORD*)scene_dpvs_sceneXModelIndex + ent_num) = static_cast(scene_ent_index);
- }
- }
- }
-
- void dobj_get_lighting_origin(game::cpose_t* pose, float* lighting_origin)
- {
+ }
+
+ // hack but works
+ unsigned short lightinghandle = 0;
+
+ // R_AddDObjToScene
+ void dobj_add_to_scene(game::DObj_s* obj, game::cpose_t* pose, unsigned int ent_num, float* lighting_origin)
+ {
+ if (!obj)
+ {
+ Assert();
+ }
+
+ if (!pose)
+ {
+ Assert();
+ }
+
+ unsigned int& gfxCfg_entCount = *reinterpret_cast(0x13683DC);
+ //DWORD& scene_dpvs_sceneDObjIndex = *reinterpret_cast(0x14C564C);
+ DWORD& scene_dpvs_sceneXModelIndex = *reinterpret_cast(0x14C5648);
+
+ if (ent_num >= gfxCfg_entCount)
+ {
+ Assert();
+ }
+
+ if (game::Dvar_FindVar("r_drawEntities")->current.enabled)
+ {
+ const unsigned int scene_ent_index = utils::hook::call(0x501D80)(); // R_AllocSceneModel()
+ if (scene_ent_index < 1024)
+ {
+ game::GfxSceneModel* sceneModel = &game::scene->sceneModel[scene_ent_index];
+ sceneModel->model = obj->models[0];
+ sceneModel->DObj_s_obj = obj;
+ sceneModel->entnum = static_cast(ent_num);
+ sceneModel->cachedLightingHandle = &lightinghandle;
+ sceneModel->placement.base.origin[0] = pose->origin[0];
+ sceneModel->placement.base.origin[1] = pose->origin[1];
+ sceneModel->placement.base.origin[2] = pose->origin[2];
+
+ game::AnglesToQuat(pose->angles, sceneModel->placement.base.quat);
+
+ sceneModel->placement.scale = 1.0f;
+ sceneModel->radius = sceneModel->model->radius;
+ sceneModel->lightingOrigin[0] = *lighting_origin;
+ sceneModel->lightingOrigin[1] = lighting_origin[1];
+ sceneModel->lightingOrigin[2] = lighting_origin[2];
+ sceneModel->gfxEntIndex = 0;
+
+ *((WORD*)scene_dpvs_sceneXModelIndex + ent_num) = static_cast(scene_ent_index);
+ }
+ }
+ }
+
+ void dobj_get_lighting_origin(game::cpose_t* pose, float* lighting_origin)
+ {
lighting_origin[0] = pose->origin[0];
lighting_origin[1] = pose->origin[1];
- lighting_origin[2] = pose->origin[2] + 4.0f;
- }
-
- void d3dbsp::add_entities_to_scene()
- {
- for (auto i = 0; i < radiant_dobj_count; i++)
- {
- game::vec3_t lighting_origin = {};
- dobj_get_lighting_origin(&radiant_dobj[i].pose, lighting_origin);
- dobj_add_to_scene(&radiant_dobj[i].obj, &radiant_dobj[i].pose, 0, lighting_origin);
- }
- }
-
-
- // *
- // * BSP Loading
- // *
-
- std::string d3dbsp::loaded_bsp_path;
- d3dbsp::bspGlob_s d3dbsp::comBspGlob = {};
- game::clipMap_t d3dbsp::cm = {};
- game::GfxLight d3dbsp::scene_lights[255] = {};
-
-
- game::cplane_s* d3dbsp::CM_GetPlanes()
- {
- return d3dbsp::cm.planes;
- }
-
- int d3dbsp::CM_GetPlaneCount()
- {
- return d3dbsp::cm.planeCount;
- }
-
- bool d3dbsp::Com_IsBspLoaded()
- {
- return comBspGlob.header != nullptr;
- }
-
- std::uint32_t d3dbsp::Com_GetBspVersion()
- {
- if (!d3dbsp::Com_IsBspLoaded())
- {
- return 0;
- }
-
- return comBspGlob.header->version;
- }
-
- char* d3dbsp::Com_ValidateBspLumpData(LumpType type, unsigned int offset, unsigned int length, unsigned int elemSize, unsigned int* count)
- {
- char* result = nullptr;
-
- ASSERT_MSG(count, "count");
-
- if (length)
- {
- if (length + offset > comBspGlob.fileSize)
- {
- game::Com_Error("LoadMap: lump %i extends past end of file", type);
- }
-
- *count = length / elemSize;
-
- if (elemSize * *count != length)
- {
- game::Com_Error("LoadMap: lump %i has funny size", type);
- }
-
- result = (char*)comBspGlob.header + offset;
- }
- else
- {
- *count = 0;
- }
-
- return result;
- }
-
- bool d3dbsp::Com_GetBspLumpBool(LumpType type)
- {
- auto t_count = 0u;
- if (d3dbsp::Com_GetBspLump(type, 1, &t_count))
- {
- return true;
- }
-
- return false;
- }
-
+ lighting_origin[2] = pose->origin[2] + 4.0f;
+ }
+
+ void d3dbsp::add_entities_to_scene()
+ {
+ for (auto i = 0; i < radiant_dobj_count; i++)
+ {
+ game::vec3_t lighting_origin = {};
+ dobj_get_lighting_origin(&radiant_dobj[i].pose, lighting_origin);
+ dobj_add_to_scene(&radiant_dobj[i].obj, &radiant_dobj[i].pose, 0, lighting_origin);
+ }
+ }
+
+
+ // *
+ // * BSP Loading
+ // *
+
+ std::string d3dbsp::loaded_bsp_path;
+ d3dbsp::bspGlob_s d3dbsp::comBspGlob = {};
+ game::clipMap_t d3dbsp::cm = {};
+ game::GfxLight d3dbsp::scene_lights[255] = {};
+
+
+ game::cplane_s* d3dbsp::CM_GetPlanes()
+ {
+ return d3dbsp::cm.planes;
+ }
+
+ int d3dbsp::CM_GetPlaneCount()
+ {
+ return d3dbsp::cm.planeCount;
+ }
+
+ bool d3dbsp::Com_IsBspLoaded()
+ {
+ return comBspGlob.header != nullptr;
+ }
+
+ std::uint32_t d3dbsp::Com_GetBspVersion()
+ {
+ if (!d3dbsp::Com_IsBspLoaded())
+ {
+ return 0;
+ }
+
+ return comBspGlob.header->version;
+ }
+
+ char* d3dbsp::Com_ValidateBspLumpData(LumpType type, unsigned int offset, unsigned int length, unsigned int elemSize, unsigned int* count)
+ {
+ char* result = nullptr;
+
+ ASSERT_MSG(count, "count");
+
+ if (length)
+ {
+ if (length + offset > comBspGlob.fileSize)
+ {
+ game::Com_Error("LoadMap: lump %i extends past end of file", type);
+ }
+
+ *count = length / elemSize;
+
+ if (elemSize * *count != length)
+ {
+ game::Com_Error("LoadMap: lump %i has funny size", type);
+ }
+
+ result = (char*)comBspGlob.header + offset;
+ }
+ else
+ {
+ *count = 0;
+ }
+
+ return result;
+ }
+
+ bool d3dbsp::Com_GetBspLumpBool(LumpType type)
+ {
+ auto t_count = 0u;
+ if (d3dbsp::Com_GetBspLump(type, 1, &t_count))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
#pragma warning(push)
#pragma warning(disable: 4146)
void d3dbsp::Com_SaveLump(LumpType type, const void* newLump, unsigned int size)
{
const void* chunkData[100];
-
+
BspHeader new_header = {};
new_header.ident = 1347633737;
new_header.version = 22;
- new_header.chunkCount = 0;
+ new_header.chunkCount = 0;
bool isNewChunk = true;
- unsigned int offset = 8 * comBspGlob.header->chunkCount + 12;
+ unsigned int offset = 8 * comBspGlob.header->chunkCount + 12;
for (auto chunkIter = 0u; chunkIter < comBspGlob.header->chunkCount; ++chunkIter)
{
@@ -195,7 +195,7 @@ namespace components
new_header.chunks[new_header.chunkCount].type = chunk->type;
new_header.chunks[new_header.chunkCount].length = chunk->length;
chunkData[new_header.chunkCount++] = (char*)comBspGlob.header + offset;
- }
+ }
offset += (chunk->length + 3) & 0xFFFFFFFC;
}
@@ -204,287 +204,287 @@ namespace components
new_header.chunks[new_header.chunkCount].type = type;
new_header.chunks[new_header.chunkCount].length = size;
chunkData[new_header.chunkCount++] = newLump;
- }
+ }
if (const auto h = game::FS_OpenFileOverwrite(comBspGlob.name); h)
- {
+ {
game::FS_Write(&new_header, 8 * new_header.chunkCount + 12, h);
for (auto chunkIter = 0u; chunkIter < new_header.chunkCount; ++chunkIter)
- {
- game::FS_Write(chunkData[chunkIter], new_header.chunks[chunkIter].length, h);
- const unsigned int zeroCount = -new_header.chunks[chunkIter].length & 3;
-
- if (zeroCount)
- {
- unsigned int zero;
- game::FS_Write(&zero, zeroCount, h);
- }
+ {
+ game::FS_Write(chunkData[chunkIter], new_header.chunks[chunkIter].length, h);
+ const unsigned int zeroCount = -new_header.chunks[chunkIter].length & 3;
+
+ if (zeroCount)
+ {
+ unsigned int zero;
+ game::FS_Write(&zero, zeroCount, h);
+ }
}
-
- game::FS_FCloseFile(h);
+
+ game::FS_FCloseFile(h);
d3dbsp::radiant_load_bsp(d3dbsp::loaded_bsp_path.c_str(), true);
}
else
- {
+ {
game::Com_Error("Failed to open file %s for writing", comBspGlob.name);
}
- }
-#pragma warning(pop)
-
- const void* d3dbsp::Com_GetBspLump(LumpType type, unsigned int elemSize, unsigned int* count)
- {
- const void* result = nullptr;
- unsigned int offset;
-
- ASSERT_MSG(Com_IsBspLoaded(), "Com_IsBspLoaded()");
-
- if (comBspGlob.header->version > 18)
- {
- offset = 8 * comBspGlob.header->chunkCount + 12;
- for (auto chunkIter = 0u; chunkIter < comBspGlob.header->chunkCount; ++chunkIter)
- {
- if (comBspGlob.header->chunks[chunkIter].type == type)
- {
- return Com_ValidateBspLumpData(type, offset, comBspGlob.header->chunks[chunkIter].length, elemSize, count);
- }
-
- offset += (comBspGlob.header->chunks[chunkIter].length + 3) & 0xFFFFFFFC;
- }
-
- *count = 0;
- }
- else
- {
- *count = 0;
- }
-
- return result;
- }
-
- const char* Com_GetHunkStringCopy(const char* string)
- {
- const auto len = strlen(string);
- const auto hunk_copy = reinterpret_cast(game::Hunk_Alloc(len + 1));
-
- memcpy(hunk_copy, string, len + 1);
- return hunk_copy;
- }
-
- const char* Com_GetLightDefName(const char* defName, game::ComPrimaryLight* primaryLights, unsigned int primaryLightCount)
- {
- for (auto primaryLightIndex = 0u; primaryLightIndex < primaryLightCount; ++primaryLightIndex)
- {
- if (primaryLights[primaryLightIndex].defName && !strcmp(defName, primaryLights[primaryLightIndex].defName))
- {
- return primaryLights[primaryLightIndex].defName;
- }
- }
-
- return Com_GetHunkStringCopy(defName);
- }
-
- void Com_LoadPrimaryLights()
- {
- unsigned int primary_light_count;
- auto bsp_lights = (game::DiskPrimaryLight*)(d3dbsp::Com_GetBspLump(d3dbsp::LUMP_PRIMARY_LIGHTS, 128, &primary_light_count));
-
- if (primary_light_count <= 1)
- {
- game::Com_Error("Com_LoadPrimaryLights: no primary lights in bsp\n");
- }
-
- game::comworld->primaryLightCount = primary_light_count;
- game::comworld->primaryLights = reinterpret_cast(game::Hunk_Alloc(sizeof(game::ComPrimaryLight) * primary_light_count));
-
- game::ComPrimaryLight* out = game::comworld->primaryLights;
- auto lightIndex = 0u;
-
- while (lightIndex < primary_light_count)
- {
- out->type = bsp_lights->type;
- out->canUseShadowMap = bsp_lights->canUseShadowMap;
- out->exponent = static_cast(bsp_lights->exponent);
- out->color[0] = bsp_lights->color[0];
- out->color[1] = bsp_lights->color[1];
- out->color[2] = bsp_lights->color[2];
- out->dir[0] = bsp_lights->dir[0];
- out->dir[1] = bsp_lights->dir[1];
- out->dir[2] = bsp_lights->dir[2];
- out->origin[0] = bsp_lights->origin[0];
- out->origin[1] = bsp_lights->origin[1];
- out->origin[2] = bsp_lights->origin[2];
- out->radius = bsp_lights->radius;
- out->cosHalfFovOuter = bsp_lights->cosHalfFovOuter;
- out->cosHalfFovInner = bsp_lights->cosHalfFovInner;
- out->rotationLimit = bsp_lights->rotationLimit;
- out->translationLimit = bsp_lights->translationLimit;
-
- if (bsp_lights->type && bsp_lights->type != 1)
- {
- out->defName = Com_GetLightDefName(bsp_lights->defName, game::comworld->primaryLights, lightIndex);
- if (out->cosHalfFovOuter >= out->cosHalfFovInner)
- {
- out->cosHalfFovInner = out->cosHalfFovOuter * 0.75f + 0.25f;
- }
- if (out->rotationLimit == 1.0f)
- {
- out->cosHalfFovExpanded = out->cosHalfFovOuter;
- }
- else if (-out->cosHalfFovOuter < out->rotationLimit)
- {
- out->cosHalfFovExpanded = utils::vector::cos_of_sum_of_arc_cos(out->cosHalfFovOuter, out->rotationLimit);
- }
- else
- {
- out->cosHalfFovExpanded = -1.0f;
- }
- }
- else
- {
- out->defName = nullptr;
- out->cosHalfFovExpanded = bsp_lights->cosHalfFovOuter;
- }
-
- ++lightIndex;
- ++bsp_lights;
- ++out;
- }
- }
-
- void R_LoadPrimaryLights(unsigned int bsp_version)
- {
- if (bsp_version > 14)
- {
- game::s_world->primaryLightCount = game::comworld->primaryLightCount; // Com_GetPrimaryLightCount();
-
- if (game::s_world->primaryLightCount <= 1)
- {
- game::s_world->sunPrimaryLightIndex = 0;
- }
- else
- {
- game::s_world->sunPrimaryLightIndex = game::comworld->primaryLights[1].type == 1; // Com_GetPrimaryLight(1u)->type == 1;
- }
-
- for (auto light_index = 0u; light_index < game::s_world->primaryLightCount; ++light_index)
- {
- const auto primary_light = &game::comworld->primaryLights[light_index]; // Com_GetPrimaryLight(lightIndex);
- if (primary_light->defName)
- {
- game::R_RegisterLightDef(primary_light->defName);
- }
- }
- }
- else
- {
- game::s_world->sunPrimaryLightIndex = 1;
- game::s_world->primaryLightCount = 2;
- }
- }
-
- void R_InitPrimaryLights(game::GfxLight* primaryLights)
- {
- for (auto lightIndex = 0u; lightIndex < game::s_world->primaryLightCount; ++lightIndex)
- {
- const auto in = &game::comworld->primaryLights[lightIndex]; //Com_GetPrimaryLight(lightIndex);
- const auto out = &primaryLights[lightIndex];
-
- out->type = in->type;
- out->canUseShadowMap = in->canUseShadowMap;
- out->color[0] = in->color[0];
- out->color[1] = in->color[1];
- out->color[2] = in->color[2];
- out->dir[0] = in->dir[0];
- out->dir[1] = in->dir[1];
- out->dir[2] = in->dir[2];
- out->origin[0] = in->origin[0];
- out->origin[1] = in->origin[1];
- out->origin[2] = in->origin[2];
- out->radius = in->radius;
- out->cosHalfFovOuter = in->cosHalfFovOuter;
- out->cosHalfFovInner = in->cosHalfFovInner;
- out->exponent = static_cast(in->exponent);
- out->def = nullptr;
-
- if (in->defName)
- {
- out->def = game::R_RegisterLightDef(in->defName);
- }
- }
- }
-
- void CMod_LoadPlanes()
- {
- unsigned int count;
- auto in = static_cast(d3dbsp::Com_GetBspLump(d3dbsp::LUMP_PLANES, sizeof(game::dplane_t), &count));
- if (!count)
- {
- game::Com_Error("CMod_LoadPlanes: Map with no planes");
- }
-
- if (count > 0x10000)
- {
- game::Com_Error("CMod_LoadPlanes: Number of planes exceeds 65536");
- }
-
- d3dbsp::cm.planes = reinterpret_cast(game::Hunk_Alloc(sizeof(game::cplane_s) * count));
- d3dbsp::cm.planeCount = static_cast(count);
-
- game::cplane_s* out = d3dbsp::cm.planes;
-
- for (auto plane = 0u; plane < count; ++plane)
- {
- char bits = 0;
-
- for (auto axis = 0u; axis < 3; ++axis)
- {
- out->normal[axis] = in->normal[axis];
- if (out->normal[axis] < 0.0f)
- {
- bits |= 1 << axis;
- }
- }
-
- out->dist = in->dist;
- char n0;
-
- if (out->normal[0] == 1.0f)
- {
- n0 = 0;
- }
- else
- {
- char n1;
- if (out->normal[1] == 1.0f)
- {
- n1 = 1;
- }
- else
- {
- char n2;
- if (out->normal[2] == 1.0f)
- {
- n2 = 2;
- }
- else
- {
- n2 = 3;
- }
-
- n1 = n2;
- }
-
- n0 = n1;
- }
-
- out->type = n0;
- out->signbits = bits;
- ++in;
- ++out;
- }
- }
-
+ }
+#pragma warning(pop)
+
+ const void* d3dbsp::Com_GetBspLump(LumpType type, unsigned int elemSize, unsigned int* count)
+ {
+ const void* result = nullptr;
+ unsigned int offset;
+
+ ASSERT_MSG(Com_IsBspLoaded(), "Com_IsBspLoaded()");
+
+ if (comBspGlob.header->version > 18)
+ {
+ offset = 8 * comBspGlob.header->chunkCount + 12;
+ for (auto chunkIter = 0u; chunkIter < comBspGlob.header->chunkCount; ++chunkIter)
+ {
+ if (comBspGlob.header->chunks[chunkIter].type == type)
+ {
+ return Com_ValidateBspLumpData(type, offset, comBspGlob.header->chunks[chunkIter].length, elemSize, count);
+ }
+
+ offset += (comBspGlob.header->chunks[chunkIter].length + 3) & 0xFFFFFFFC;
+ }
+
+ *count = 0;
+ }
+ else
+ {
+ *count = 0;
+ }
+
+ return result;
+ }
+
+ const char* Com_GetHunkStringCopy(const char* string)
+ {
+ const auto len = strlen(string);
+ const auto hunk_copy = reinterpret_cast(game::Hunk_Alloc(len + 1));
+
+ memcpy(hunk_copy, string, len + 1);
+ return hunk_copy;
+ }
+
+ const char* Com_GetLightDefName(const char* defName, game::ComPrimaryLight* primaryLights, unsigned int primaryLightCount)
+ {
+ for (auto primaryLightIndex = 0u; primaryLightIndex < primaryLightCount; ++primaryLightIndex)
+ {
+ if (primaryLights[primaryLightIndex].defName && !strcmp(defName, primaryLights[primaryLightIndex].defName))
+ {
+ return primaryLights[primaryLightIndex].defName;
+ }
+ }
+
+ return Com_GetHunkStringCopy(defName);
+ }
+
+ void Com_LoadPrimaryLights()
+ {
+ unsigned int primary_light_count;
+ auto bsp_lights = (game::DiskPrimaryLight*)(d3dbsp::Com_GetBspLump(d3dbsp::LUMP_PRIMARY_LIGHTS, 128, &primary_light_count));
+
+ if (primary_light_count <= 1)
+ {
+ game::Com_Error("Com_LoadPrimaryLights: no primary lights in bsp\n");
+ }
+
+ game::comworld->primaryLightCount = primary_light_count;
+ game::comworld->primaryLights = reinterpret_cast(game::Hunk_Alloc(sizeof(game::ComPrimaryLight) * primary_light_count));
+
+ game::ComPrimaryLight* out = game::comworld->primaryLights;
+ auto lightIndex = 0u;
+
+ while (lightIndex < primary_light_count)
+ {
+ out->type = bsp_lights->type;
+ out->canUseShadowMap = bsp_lights->canUseShadowMap;
+ out->exponent = static_cast(bsp_lights->exponent);
+ out->color[0] = bsp_lights->color[0];
+ out->color[1] = bsp_lights->color[1];
+ out->color[2] = bsp_lights->color[2];
+ out->dir[0] = bsp_lights->dir[0];
+ out->dir[1] = bsp_lights->dir[1];
+ out->dir[2] = bsp_lights->dir[2];
+ out->origin[0] = bsp_lights->origin[0];
+ out->origin[1] = bsp_lights->origin[1];
+ out->origin[2] = bsp_lights->origin[2];
+ out->radius = bsp_lights->radius;
+ out->cosHalfFovOuter = bsp_lights->cosHalfFovOuter;
+ out->cosHalfFovInner = bsp_lights->cosHalfFovInner;
+ out->rotationLimit = bsp_lights->rotationLimit;
+ out->translationLimit = bsp_lights->translationLimit;
+
+ if (bsp_lights->type && bsp_lights->type != 1)
+ {
+ out->defName = Com_GetLightDefName(bsp_lights->defName, game::comworld->primaryLights, lightIndex);
+ if (out->cosHalfFovOuter >= out->cosHalfFovInner)
+ {
+ out->cosHalfFovInner = out->cosHalfFovOuter * 0.75f + 0.25f;
+ }
+ if (out->rotationLimit == 1.0f)
+ {
+ out->cosHalfFovExpanded = out->cosHalfFovOuter;
+ }
+ else if (-out->cosHalfFovOuter < out->rotationLimit)
+ {
+ out->cosHalfFovExpanded = utils::vector::cos_of_sum_of_arc_cos(out->cosHalfFovOuter, out->rotationLimit);
+ }
+ else
+ {
+ out->cosHalfFovExpanded = -1.0f;
+ }
+ }
+ else
+ {
+ out->defName = nullptr;
+ out->cosHalfFovExpanded = bsp_lights->cosHalfFovOuter;
+ }
+
+ ++lightIndex;
+ ++bsp_lights;
+ ++out;
+ }
+ }
+
+ void R_LoadPrimaryLights(unsigned int bsp_version)
+ {
+ if (bsp_version > 14)
+ {
+ game::s_world->primaryLightCount = game::comworld->primaryLightCount; // Com_GetPrimaryLightCount();
+
+ if (game::s_world->primaryLightCount <= 1)
+ {
+ game::s_world->sunPrimaryLightIndex = 0;
+ }
+ else
+ {
+ game::s_world->sunPrimaryLightIndex = game::comworld->primaryLights[1].type == 1; // Com_GetPrimaryLight(1u)->type == 1;
+ }
+
+ for (auto light_index = 0u; light_index < game::s_world->primaryLightCount; ++light_index)
+ {
+ const auto primary_light = &game::comworld->primaryLights[light_index]; // Com_GetPrimaryLight(lightIndex);
+ if (primary_light->defName)
+ {
+ game::R_RegisterLightDef(primary_light->defName);
+ }
+ }
+ }
+ else
+ {
+ game::s_world->sunPrimaryLightIndex = 1;
+ game::s_world->primaryLightCount = 2;
+ }
+ }
+
+ void R_InitPrimaryLights(game::GfxLight* primaryLights)
+ {
+ for (auto lightIndex = 0u; lightIndex < game::s_world->primaryLightCount; ++lightIndex)
+ {
+ const auto in = &game::comworld->primaryLights[lightIndex]; //Com_GetPrimaryLight(lightIndex);
+ const auto out = &primaryLights[lightIndex];
+
+ out->type = in->type;
+ out->canUseShadowMap = in->canUseShadowMap;
+ out->color[0] = in->color[0];
+ out->color[1] = in->color[1];
+ out->color[2] = in->color[2];
+ out->dir[0] = in->dir[0];
+ out->dir[1] = in->dir[1];
+ out->dir[2] = in->dir[2];
+ out->origin[0] = in->origin[0];
+ out->origin[1] = in->origin[1];
+ out->origin[2] = in->origin[2];
+ out->radius = in->radius;
+ out->cosHalfFovOuter = in->cosHalfFovOuter;
+ out->cosHalfFovInner = in->cosHalfFovInner;
+ out->exponent = static_cast(in->exponent);
+ out->def = nullptr;
+
+ if (in->defName)
+ {
+ out->def = game::R_RegisterLightDef(in->defName);
+ }
+ }
+ }
+
+ void CMod_LoadPlanes()
+ {
+ unsigned int count;
+ auto in = static_cast(d3dbsp::Com_GetBspLump(d3dbsp::LUMP_PLANES, sizeof(game::dplane_t), &count));
+ if (!count)
+ {
+ game::Com_Error("CMod_LoadPlanes: Map with no planes");
+ }
+
+ if (count > 0x10000)
+ {
+ game::Com_Error("CMod_LoadPlanes: Number of planes exceeds 65536");
+ }
+
+ d3dbsp::cm.planes = reinterpret_cast(game::Hunk_Alloc(sizeof(game::cplane_s) * count));
+ d3dbsp::cm.planeCount = static_cast(count);
+
+ game::cplane_s* out = d3dbsp::cm.planes;
+
+ for (auto plane = 0u; plane < count; ++plane)
+ {
+ char bits = 0;
+
+ for (auto axis = 0u; axis < 3; ++axis)
+ {
+ out->normal[axis] = in->normal[axis];
+ if (out->normal[axis] < 0.0f)
+ {
+ bits |= 1 << axis;
+ }
+ }
+
+ out->dist = in->dist;
+ char n0;
+
+ if (out->normal[0] == 1.0f)
+ {
+ n0 = 0;
+ }
+ else
+ {
+ char n1;
+ if (out->normal[1] == 1.0f)
+ {
+ n1 = 1;
+ }
+ else
+ {
+ char n2;
+ if (out->normal[2] == 1.0f)
+ {
+ n2 = 2;
+ }
+ else
+ {
+ n2 = 3;
+ }
+
+ n1 = n2;
+ }
+
+ n0 = n1;
+ }
+
+ out->type = n0;
+ out->signbits = bits;
+ ++in;
+ ++out;
+ }
+ }
+
void CMod_LoadCollisionVertsAndTris()
{
unsigned int vert_count;
@@ -493,9 +493,9 @@ namespace components
d3dbsp::cm.verts = reinterpret_cast(game::Hunk_Alloc(sizeof(float[3]) * vert_count));
d3dbsp::cm.vertCount = static_cast(vert_count);
memcpy(d3dbsp::cm.verts, verts, sizeof(float[3]) * vert_count);
-
- // #
+
+ // #
// CMod_LoadCollisionTriangles();
unsigned int tri_count;
@@ -504,584 +504,584 @@ namespace components
d3dbsp::cm.triIndices = reinterpret_cast(game::Hunk_Alloc(sizeof(uint16_t) * tri_count));
d3dbsp::cm.triCount = static_cast(tri_count) / 3;
memcpy(d3dbsp::cm.triIndices, tris, sizeof(uint16_t) * tri_count);
- }
-
+ }
+
const char* Com_EntityString(unsigned int* num_entity_chars)
{
if (!d3dbsp::Com_IsBspLoaded())
{
Assert();
- }
-
+ }
+
unsigned int count;
const char* entity_string = static_cast(d3dbsp::Com_GetBspLump(d3dbsp::LUMP_ENTITIES, 1u, &count));
-
+
if (num_entity_chars)
{
*num_entity_chars = count;
- }
+ }
return entity_string;
- }
-
+ }
+
game::MapEnts* MapEnts_GetFromString(const char* name, const char* entity_string, int num_entity_chars)
{
- const auto ents = reinterpret_cast(game::Hunk_Alloc(sizeof(game::MapEnts)));
- ents->name = Com_GetHunkStringCopy(name);
+ const auto ents = reinterpret_cast(game::Hunk_Alloc(sizeof(game::MapEnts)));
+ ents->name = Com_GetHunkStringCopy(name);
- ents->entityString = reinterpret_cast(game::Hunk_Alloc(num_entity_chars));
- memcpy(ents->entityString, entity_string, num_entity_chars);
- ents->numEntityChars = num_entity_chars;
+ ents->entityString = reinterpret_cast(game::Hunk_Alloc(num_entity_chars));
+ memcpy(ents->entityString, entity_string, num_entity_chars);
+ ents->numEntityChars = num_entity_chars;
return ents;
- }
-
- void CMod_LoadEntityString()
- {
- unsigned int numEntityChars;
-
- const char* entityString = Com_EntityString(&numEntityChars);
- d3dbsp::cm.mapEnts = MapEnts_GetFromString(d3dbsp::cm.name, entityString, numEntityChars);
- }
-
- bool d3dbsp::Com_LoadBsp(const char* filename)
- {
- int h;
- comBspGlob.fileSize = game::FS_FOpenFileRead(filename, &h);
-
- if (!h)
- {
- game::printf_to_console("[ERR][BSP] Couldn't open %s\n", filename);
- return false;
- }
-
- comBspGlob.header = reinterpret_cast(game::Z_Malloc(comBspGlob.fileSize));
-
- unsigned int bytesRead;
- bytesRead = game::FS_Read(comBspGlob.header, comBspGlob.fileSize, h);
- game::FS_FCloseFile(h);
-
- if (bytesRead != comBspGlob.fileSize)
- {
- game::Z_Free(comBspGlob.header);
- game::printf_to_console("[ERR][BSP] bytesRead != comBspGlob.fileSize");
- return false;
- }
-
- // skip checksum and version checks for now
-
- memcpy(comBspGlob.name, filename, strlen(filename) + 1);
-
- return d3dbsp::Com_IsBspLoaded();
- }
-
- void d3dbsp::shutdown_bsp()
- {
- d3dbsp::dobj_clear_list();
-
- comBspGlob.loadedLumpData = nullptr;
-
- game::Z_Free(comBspGlob.header);
-
- comBspGlob.header = nullptr;
- comBspGlob.name[0] = 0;
-
- memset(&d3dbsp::cm, 0, sizeof(d3dbsp::cm));
- memset(&d3dbsp::scene_lights, 0, sizeof(d3dbsp::scene_lights));
-
- game::comworld->isInUse = false;
-
- cdeclcall(void, 0x52E7D0); // R_ShutdownWorld
- game::rgp->world = nullptr;
-
- memset(game::s_world, 0, 0x2D0 /*sizeof(game::GfxWorld)*/);
-
- if (game::rg->registered)
- {
- cdeclcall(void, 0x529D50); // R_ResetModelLighting
- }
- }
-
- bool d3dbsp::radiant_load_bsp(const char* bsppath, bool reload)
- {
- const auto con = GetConsoleWindow();
-
- if (d3dbsp::Com_IsBspLoaded())
- {
- d3dbsp::shutdown_bsp();
- }
-
- if (d3dbsp::Com_LoadBsp(bsppath))
- {
- if (!reload) ShowWindow(con, SW_SHOW);
- game::printf_to_console("[BSP] loading bsp: %s\n", bsppath);
-
- // *
- // clipmap
-
- if(!reload) game::printf_to_console("[BSP] clipmap ..\n");
-
- // CM_LoadMapFromBsp
- d3dbsp::cm.name = Com_GetHunkStringCopy(bsppath);
- CMod_LoadPlanes();
- CMod_LoadCollisionVertsAndTris();
- CMod_LoadEntityString();
- d3dbsp::cm.isInUse = 1;
-
-
- // *
- // entities (script_models only for now)
-
- // spawn:
- /* "classname" "script_model"
- * "model" "vehicle_80s_sedan1_red_destructible_mp"
- * "origin" "-235.1 1394.7 230.2"
- * "angles" "358.94 101.765 3.47606" */
-
- // exclude:
- /* "script_exploder"
- * "script_gameobjectname" */
-
- if (dvars::bsp_load_entities->current.enabled && d3dbsp::cm.isInUse && d3dbsp::cm.mapEnts && d3dbsp::cm.mapEnts->numEntityChars)
- {
- if (!reload) game::printf_to_console("[BSP] entities ..\n");
-
- // create a spawnvar for each map entity
- utils::spawnvars script_models(d3dbsp::cm.mapEnts->entityString);
-
- // get name, origin and angles for script_models (see spawn/exclude note)
- std::vector dobjs;
- script_models.get_script_models_for_dobj(dobjs);
-
- if (!dobjs.empty())
- {
- for(radiant_dobj_count = 0; radiant_dobj_count < static_cast(dobjs.size()) && radiant_dobj_count < 512; radiant_dobj_count++)
- {
- game::DObjModel_s dobjModels = {};
- dobjModels.model = game::R_RegisterModel(dobjs[radiant_dobj_count].model_name.c_str());
- dobjModels.boneName = 0;
- dobjModels.ignoreCollision = true;
-
- game::DObjCreate(&dobjModels, &radiant_dobj[radiant_dobj_count].obj, 1, nullptr, 0);
-
- utils::vector::copy(dobjs[radiant_dobj_count].origin, radiant_dobj[radiant_dobj_count].pose.origin);
- utils::vector::copy(dobjs[radiant_dobj_count].angles, radiant_dobj[radiant_dobj_count].pose.angles);
- }
- }
-
- if (!reload) game::printf_to_console("[BSP] loaded %d entities\n", radiant_dobj_count);
- }
-
-
- // *
- // load com world
-
- if (!reload) game::printf_to_console("[BSP] primary lights ..\n");
-
- Com_LoadPrimaryLights();
- game::comworld->name = Com_GetHunkStringCopy(bsppath);
- game::comworld->isInUse = true;
-
-
- // *
- // R_LoadPrimaryLights is missing in R_LoadWorldInternal (s_world ...)
- // so load it here and nop s_world memset at the beginning of R_LoadWorld->R_LoadWorldInternal
-
- R_LoadPrimaryLights(d3dbsp::Com_GetBspVersion());
- R_InitPrimaryLights(d3dbsp::scene_lights);
-
- unsigned int checksum;
-
- if (!reload) game::printf_to_console("[BSP] the world ..\n");
-
- // R_LoadWorld
- utils::hook::call(0x52E450)(bsppath, &checksum, 0);
-
- if (game::s_world->sunPrimaryLightIndex)
- {
- memcpy(&d3dbsp::scene_lights[game::s_world->sunPrimaryLightIndex], game::s_world->sunLight, sizeof(game::GfxLight));
- }
-
- game::R_SortWorldSurfaces();
- d3dbsp::loaded_bsp_path = bsppath;
-
- game::printf_to_console("[BSP] finished loading bsp\n");
- if (!reload) ShowWindow(con, SW_HIDE);
-
- return true;
- }
-
- return false;
- }
-
- /**
- * @brief reload currently loaded bsp\n
- * tries to load the bsp for the currently loaded .map otherwise
- */
- void d3dbsp::reload_bsp()
- {
- if (d3dbsp::Com_IsBspLoaded() && !d3dbsp::loaded_bsp_path.empty())
- {
- d3dbsp::radiant_load_bsp(d3dbsp::loaded_bsp_path.c_str(), true);
- }
- else
- {
- std::string mapname;
- if (game::current_map_filepath && game::current_map_filepath != "unnamed.map"s)
- {
- mapname = std::string(game::current_map_filepath).substr(std::string(game::current_map_filepath).find_last_of("\\") + 1);
- utils::replace(mapname, ".map", ".d3dbsp");
-
- const bool is_mp = utils::starts_with(mapname, "mp_");
- const std::string bsp_path = (is_mp ? R"(maps\mp\)"s : R"(maps\)"s) + mapname;
-
- d3dbsp::radiant_load_bsp(bsp_path.c_str());
- }
- else
- {
- game::printf_to_console("Load a .map first!");
- }
- }
- }
-
- /**
- * @brief run batch to compile bsp
- * @param bsp_name plain map name with no extension or pathing
- * @param generate_createfx automatically generate createfx files + place into raw instead of bin/IW3xRadiant
- */
- void d3dbsp::compile_bsp(const std::string& bsp_name, bool generate_createfx)
- {
- //game::printf_to_console("^1generate_createfx is %s", generate_createfx ? "true" : "false");
- game::printf_to_console("[BSP] Compiling bsp for map: %s ...", bsp_name.c_str());
-
- const auto egui = GET_GUI(ggui::entity_dialog);
-
- const char* base_path = egui->get_value_for_key_from_epairs(game::g_qeglobals->d_project_entity->epairs, "basepath");
- const char* map_path = egui->get_value_for_key_from_epairs(game::g_qeglobals->d_project_entity->epairs, "mapspath");
-
- const bool is_mp = utils::starts_with(bsp_name, "mp_");
- const std::string bsp_path = (is_mp ? R"(maps\mp\)"s : R"(maps\)"s) + bsp_name + ".d3dbsp";
-
- std::string bps_args;
- bps_args += (dvars::bsp_compile_onlyents->current.enabled ? "-onlyents" : "") + " "s;
- bps_args += (dvars::bsp_compile_samplescale_enabled->current.enabled ? ("-samplescale " + std::to_string(dvars::bsp_compile_samplescale->current.value)) : "") + " "s;
- bps_args += (dvars::bsp_compile_custom_cmd_enabled->current.enabled ? dvars::bsp_compile_custom_cmd->current.string : "") + " "s;
- utils::rtrim(bps_args);
-
- std::string light_args;
- light_args += (dvars::bsp_compile_light_fast->current.enabled ? "-fast" : "") + " "s;
- light_args += (dvars::bsp_compile_light_extra->current.enabled ? "-extra" : "") + " "s;
- light_args += (dvars::bsp_compile_light_modelshadow->current.enabled ? "-modelshadow" : "") + " "s;
- light_args += (dvars::bsp_compile_light_dump->current.enabled ? "-dumpoptions" : "") + " "s;
- light_args += (dvars::bsp_compile_light_traces_enabled->current.enabled ? ("-traces " + std::to_string(dvars::bsp_compile_light_traces->current.integer)) : "") + " "s;
- light_args += (dvars::bsp_compile_light_custom_cmd_enabled->current.enabled ? dvars::bsp_compile_light_custom_cmd->current.string : "") + " "s;
- utils::rtrim(light_args);
-
- std::string args;
-
- // launch arg
- args += R"(")"s + base_path + R"(\bin\IW3xRadiant\batch\compile_bsp.bat")"s + " ";
-
- // bsppath
- args += R"(")"s + base_path + (is_mp ? R"(\raw\maps\mp\")"s : R"(\raw\maps\")"s) + " "s;
-
- // mapsourcepath
- args += R"(")"s + map_path + R"(\")"s + " "s;
-
- // treepath
- args += R"(")"s + base_path + R"(\")"s + " "s;
-
- // mapname
- args += bsp_name + " "s;
-
- // parmBSPOptions
- args += (!bps_args.empty() ? R"(")" + bps_args + R"(" )" : "- ");
-
- // parmLightOptions
- args += (!light_args.empty() ? R"(")" + light_args + R"(" )" : "- ");
-
- // compileBSP
- args += (dvars::bsp_compile_bsp->current.enabled ? "1 "s : "0 "s);
-
- // compileLight
- args += (dvars::bsp_compile_light->current.enabled ? "1 "s : "0 "s);
-
- const auto process = components::process::get();
- process->set_process_type(process::PROC_TYPE_BATCH);
- process->set_indicator(process::INDICATOR_TYPE_SPINNER);
- process->set_output(true);
- process->set_arguments(args);
- process->set_post_process_callback([bsp_path, generate_createfx]
- {
- game::printf_to_console("^2[PROCESS] Post-Process Callback");
-
- if (d3dbsp::radiant_load_bsp(bsp_path.c_str(), true))
- {
- if (dvars::bsp_gen_reflections_on_compile->current.enabled)
- {
- //components::renderer::on_cam_paint_post_rendercommands
- dvars::set_bool(dvars::r_reflectionprobe_generate, true);
- }
- else
- {
- if (dvars::bsp_show_bsp_after_compile->current.enabled)
- {
- command::execute("toggle_bsp_radiant");
- dvars::set_bool(dvars::r_draw_bsp, dvars::bsp_show_bsp_after_compile->current.enabled);
- }
- }
- }
-
+ }
+
+ void CMod_LoadEntityString()
+ {
+ unsigned int numEntityChars;
+
+ const char* entityString = Com_EntityString(&numEntityChars);
+ d3dbsp::cm.mapEnts = MapEnts_GetFromString(d3dbsp::cm.name, entityString, numEntityChars);
+ }
+
+ bool d3dbsp::Com_LoadBsp(const char* filename)
+ {
+ int h;
+ comBspGlob.fileSize = game::FS_FOpenFileRead(filename, &h);
+
+ if (!h)
+ {
+ game::printf_to_console("[ERR][BSP] Couldn't open %s\n", filename);
+ return false;
+ }
+
+ comBspGlob.header = reinterpret_cast(game::Z_Malloc(comBspGlob.fileSize));
+
+ unsigned int bytesRead;
+ bytesRead = game::FS_Read(comBspGlob.header, comBspGlob.fileSize, h);
+ game::FS_FCloseFile(h);
+
+ if (bytesRead != comBspGlob.fileSize)
+ {
+ game::Z_Free(comBspGlob.header);
+ game::printf_to_console("[ERR][BSP] bytesRead != comBspGlob.fileSize");
+ return false;
+ }
+
+ // skip checksum and version checks for now
+
+ memcpy(comBspGlob.name, filename, strlen(filename) + 1);
+
+ return d3dbsp::Com_IsBspLoaded();
+ }
+
+ void d3dbsp::shutdown_bsp()
+ {
+ d3dbsp::dobj_clear_list();
+
+ comBspGlob.loadedLumpData = nullptr;
+
+ game::Z_Free(comBspGlob.header);
+
+ comBspGlob.header = nullptr;
+ comBspGlob.name[0] = 0;
+
+ memset(&d3dbsp::cm, 0, sizeof(d3dbsp::cm));
+ memset(&d3dbsp::scene_lights, 0, sizeof(d3dbsp::scene_lights));
+
+ game::comworld->isInUse = false;
+
+ cdeclcall(void, 0x52E7D0); // R_ShutdownWorld
+ game::rgp->world = nullptr;
+
+ memset(game::s_world, 0, 0x2D0 /*sizeof(game::GfxWorld)*/);
+
+ if (game::rg->registered)
+ {
+ cdeclcall(void, 0x529D50); // R_ResetModelLighting
+ }
+ }
+
+ bool d3dbsp::radiant_load_bsp(const char* bsppath, bool reload)
+ {
+ const auto con = GetConsoleWindow();
+
+ if (d3dbsp::Com_IsBspLoaded())
+ {
+ d3dbsp::shutdown_bsp();
+ }
+
+ if (d3dbsp::Com_LoadBsp(bsppath))
+ {
+ if (!reload) ShowWindow(con, SW_SHOW);
+ game::printf_to_console("[BSP] loading bsp: %s\n", bsppath);
+
+ // *
+ // clipmap
+
+ if(!reload) game::printf_to_console("[BSP] clipmap ..\n");
+
+ // CM_LoadMapFromBsp
+ d3dbsp::cm.name = Com_GetHunkStringCopy(bsppath);
+ CMod_LoadPlanes();
+ CMod_LoadCollisionVertsAndTris();
+ CMod_LoadEntityString();
+ d3dbsp::cm.isInUse = 1;
+
+
+ // *
+ // entities (script_models only for now)
+
+ // spawn:
+ /* "classname" "script_model"
+ * "model" "vehicle_80s_sedan1_red_destructible_mp"
+ * "origin" "-235.1 1394.7 230.2"
+ * "angles" "358.94 101.765 3.47606" */
+
+ // exclude:
+ /* "script_exploder"
+ * "script_gameobjectname" */
+
+ if (dvars::bsp_load_entities->current.enabled && d3dbsp::cm.isInUse && d3dbsp::cm.mapEnts && d3dbsp::cm.mapEnts->numEntityChars)
+ {
+ if (!reload) game::printf_to_console("[BSP] entities ..\n");
+
+ // create a spawnvar for each map entity
+ utils::spawnvars script_models(d3dbsp::cm.mapEnts->entityString);
+
+ // get name, origin and angles for script_models (see spawn/exclude note)
+ std::vector dobjs;
+ script_models.get_script_models_for_dobj(dobjs);
+
+ if (!dobjs.empty())
+ {
+ for(radiant_dobj_count = 0; radiant_dobj_count < static_cast(dobjs.size()) && radiant_dobj_count < 512; radiant_dobj_count++)
+ {
+ game::DObjModel_s dobjModels = {};
+ dobjModels.model = game::R_RegisterModel(dobjs[radiant_dobj_count].model_name.c_str());
+ dobjModels.boneName = 0;
+ dobjModels.ignoreCollision = true;
+
+ game::DObjCreate(&dobjModels, &radiant_dobj[radiant_dobj_count].obj, 1, nullptr, 0);
+
+ utils::vector::copy(dobjs[radiant_dobj_count].origin, radiant_dobj[radiant_dobj_count].pose.origin);
+ utils::vector::copy(dobjs[radiant_dobj_count].angles, radiant_dobj[radiant_dobj_count].pose.angles);
+ }
+ }
+
+ if (!reload) game::printf_to_console("[BSP] loaded %d entities\n", radiant_dobj_count);
+ }
+
+
+ // *
+ // load com world
+
+ if (!reload) game::printf_to_console("[BSP] primary lights ..\n");
+
+ Com_LoadPrimaryLights();
+ game::comworld->name = Com_GetHunkStringCopy(bsppath);
+ game::comworld->isInUse = true;
+
+
+ // *
+ // R_LoadPrimaryLights is missing in R_LoadWorldInternal (s_world ...)
+ // so load it here and nop s_world memset at the beginning of R_LoadWorld->R_LoadWorldInternal
+
+ R_LoadPrimaryLights(d3dbsp::Com_GetBspVersion());
+ R_InitPrimaryLights(d3dbsp::scene_lights);
+
+ unsigned int checksum;
+
+ if (!reload) game::printf_to_console("[BSP] the world ..\n");
+
+ // R_LoadWorld
+ utils::hook::call(0x52E450)(bsppath, &checksum, 0);
+
+ if (game::s_world->sunPrimaryLightIndex)
+ {
+ memcpy(&d3dbsp::scene_lights[game::s_world->sunPrimaryLightIndex], game::s_world->sunLight, sizeof(game::GfxLight));
+ }
+
+ game::R_SortWorldSurfaces();
+ d3dbsp::loaded_bsp_path = bsppath;
+
+ game::printf_to_console("[BSP] finished loading bsp\n");
+ if (!reload) ShowWindow(con, SW_HIDE);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief reload currently loaded bsp\n
+ * tries to load the bsp for the currently loaded .map otherwise
+ */
+ void d3dbsp::reload_bsp()
+ {
+ if (d3dbsp::Com_IsBspLoaded() && !d3dbsp::loaded_bsp_path.empty())
+ {
+ d3dbsp::radiant_load_bsp(d3dbsp::loaded_bsp_path.c_str(), true);
+ }
+ else
+ {
+ std::string mapname;
+ if (game::current_map_filepath && game::current_map_filepath != "unnamed.map"s)
+ {
+ mapname = std::string(game::current_map_filepath).substr(std::string(game::current_map_filepath).find_last_of("\\") + 1);
+ utils::replace(mapname, ".map", ".d3dbsp");
+
+ const bool is_mp = utils::starts_with(mapname, "mp_");
+ const std::string bsp_path = (is_mp ? R"(maps\mp\)"s : R"(maps\)"s) + mapname;
+
+ d3dbsp::radiant_load_bsp(bsp_path.c_str());
+ }
+ else
+ {
+ game::printf_to_console("Load a .map first!");
+ }
+ }
+ }
+
+ /**
+ * @brief run batch to compile bsp
+ * @param bsp_name plain map name with no extension or pathing
+ * @param generate_createfx automatically generate createfx files + place into raw instead of bin/T5xRadiant
+ */
+ void d3dbsp::compile_bsp(const std::string& bsp_name, bool generate_createfx)
+ {
+ //game::printf_to_console("^1generate_createfx is %s", generate_createfx ? "true" : "false");
+ game::printf_to_console("[BSP] Compiling bsp for map: %s ...", bsp_name.c_str());
+
+ const auto egui = GET_GUI(ggui::entity_dialog);
+
+ const char* base_path = egui->get_value_for_key_from_epairs(game::g_qeglobals->d_project_entity->epairs, "basepath");
+ const char* map_path = egui->get_value_for_key_from_epairs(game::g_qeglobals->d_project_entity->epairs, "mapspath");
+
+ const bool is_mp = utils::starts_with(bsp_name, "mp_");
+ const std::string bsp_path = (is_mp ? R"(maps\mp\)"s : R"(maps\)"s) + bsp_name + ".d3dbsp";
+
+ std::string bps_args;
+ bps_args += (dvars::bsp_compile_onlyents->current.enabled ? "-onlyents" : "") + " "s;
+ bps_args += (dvars::bsp_compile_samplescale_enabled->current.enabled ? ("-samplescale " + std::to_string(dvars::bsp_compile_samplescale->current.value)) : "") + " "s;
+ bps_args += (dvars::bsp_compile_custom_cmd_enabled->current.enabled ? dvars::bsp_compile_custom_cmd->current.string : "") + " "s;
+ utils::rtrim(bps_args);
+
+ std::string light_args;
+ light_args += (dvars::bsp_compile_light_fast->current.enabled ? "-fast" : "") + " "s;
+ light_args += (dvars::bsp_compile_light_extra->current.enabled ? "-extra" : "") + " "s;
+ light_args += (dvars::bsp_compile_light_modelshadow->current.enabled ? "-modelshadow" : "") + " "s;
+ light_args += (dvars::bsp_compile_light_dump->current.enabled ? "-dumpoptions" : "") + " "s;
+ light_args += (dvars::bsp_compile_light_traces_enabled->current.enabled ? ("-traces " + std::to_string(dvars::bsp_compile_light_traces->current.integer)) : "") + " "s;
+ light_args += (dvars::bsp_compile_light_custom_cmd_enabled->current.enabled ? dvars::bsp_compile_light_custom_cmd->current.string : "") + " "s;
+ utils::rtrim(light_args);
+
+ std::string args;
+
+ // launch arg
+ args += R"(")"s + base_path + R"(\bin\T5xRadiant\batch\compile_bsp.bat")"s + " ";
+
+ // bsppath
+ args += R"(")"s + base_path + (is_mp ? R"(\raw\maps\mp\")"s : R"(\raw\maps\")"s) + " "s;
+
+ // mapsourcepath
+ args += R"(")"s + map_path + R"(\")"s + " "s;
+
+ // treepath
+ args += R"(")"s + base_path + R"(\")"s + " "s;
+
+ // mapname
+ args += bsp_name + " "s;
+
+ // parmBSPOptions
+ args += (!bps_args.empty() ? R"(")" + bps_args + R"(" )" : "- ");
+
+ // parmLightOptions
+ args += (!light_args.empty() ? R"(")" + light_args + R"(" )" : "- ");
+
+ // compileBSP
+ args += (dvars::bsp_compile_bsp->current.enabled ? "1 "s : "0 "s);
+
+ // compileLight
+ args += (dvars::bsp_compile_light->current.enabled ? "1 "s : "0 "s);
+
+ const auto process = components::process::get();
+ process->set_process_type(process::PROC_TYPE_BATCH);
+ process->set_indicator(process::INDICATOR_TYPE_SPINNER);
+ process->set_output(true);
+ process->set_arguments(args);
+ process->set_post_process_callback([bsp_path, generate_createfx]
+ {
+ game::printf_to_console("^2[PROCESS] Post-Process Callback");
+
+ if (d3dbsp::radiant_load_bsp(bsp_path.c_str(), true))
+ {
+ if (dvars::bsp_gen_reflections_on_compile->current.enabled)
+ {
+ //components::renderer::on_cam_paint_post_rendercommands
+ dvars::set_bool(dvars::r_reflectionprobe_generate, true);
+ }
+ else
+ {
+ if (dvars::bsp_show_bsp_after_compile->current.enabled)
+ {
+ command::execute("toggle_bsp_radiant");
+ dvars::set_bool(dvars::r_draw_bsp, dvars::bsp_show_bsp_after_compile->current.enabled);
+ }
+ }
+ }
+
if (generate_createfx)
- {
+ {
game::printf_to_console("Generating CreateFX files ...");
components::effects::generate_createfx(true);
- }
- }, true );
-
- process->create_process();
- }
-
- /**
- * @brief run batch to compile bsp for currently loaded .map
- */
- void d3dbsp::compile_current_map()
- {
- std::string d3dbsp_name = std::string(game::current_map_filepath).substr(std::string(game::current_map_filepath).find_last_of("\\") + 1);
- utils::erase_substring(d3dbsp_name, ".map");
-
- components::d3dbsp::compile_bsp(d3dbsp_name, dvars::bsp_gen_createfx_on_compile->current.enabled);
- }
-
-
- // *
- // *
-
-
- float* CG_GetEntityOrigin(int scene_model_index)
- {
- return game::scene->sceneModel[scene_model_index].placement.base.origin;
- }
-
- void __declspec(naked) CG_GetEntityOrigin_stub()
- {
- const static uint32_t retn_addr = 0x5274D1;
- __asm
- {
- push edi; // curr index in do-while loop (i < sceneModelCount)
- call CG_GetEntityOrigin;
- add esp, 4;
- jmp retn_addr;
- }
- }
-
-
- // *
- // *
-
-
- void d3dbsp::force_dvars()
- {
- /*if (const auto& sm_enable = game::Dvar_FindVar("sm_enable"); sm_enable && sm_enable->current.enabled) {
- dvars::set_bool(sm_enable, false);
- }*/
-
- if (const auto& r_floatz = game::Dvar_FindVar("r_floatz"); r_floatz && !r_floatz->current.enabled) {
- dvars::set_bool(r_floatz, true);
- }
-
- if (const auto& r_distortion = game::Dvar_FindVar("r_distortion"); r_distortion && !r_distortion->current.enabled) {
- dvars::set_bool(r_distortion, true);
- }
-
- if (const auto& r_zFeather = game::Dvar_FindVar("r_zFeather"); r_zFeather && !r_zFeather->current.enabled) {
- dvars::set_bool(r_zFeather, true);
- }
-
- if (const auto& r_useLayeredMaterials = game::Dvar_FindVar("r_useLayeredMaterials"); r_useLayeredMaterials && r_useLayeredMaterials->current.enabled) {
- dvars::set_bool(r_useLayeredMaterials, false);
- }
-
- if (const auto& r_polygonOffsetBias = game::Dvar_FindVar("r_polygonOffsetBias"); r_polygonOffsetBias) {
- dvars::set_float(r_polygonOffsetBias, 0.0f);
- }
-
- if (const auto& r_polygonOffsetScale = game::Dvar_FindVar("r_polygonOffsetScale"); r_polygonOffsetScale) {
- dvars::set_float(r_polygonOffsetScale, -0.05f); // or radiant brushes/decals start to flicker
- }
-
- if (const auto& r_zNear = game::Dvar_FindVar("r_zNear"); r_zNear) {
- dvars::set_float(r_zNear, 4.0f);
- }
- }
-
- void d3dbsp::register_dvars()
- {
- dvars::bsp_load_entities = dvars::register_bool(
- /* name */ "bsp_load_entities",
- /* default */ true,
- /* flags */ game::dvar_flags::saved,
- /* desc */ "enable to load entities when loading a bsp (static_models only)");
-
- dvars::bsp_show_bsp_after_compile = dvars::register_bool(
- /* name */ "bsp_show_bsp_after_compile",
- /* default */ true,
- /* flags */ game::dvar_flags::saved,
- /* desc */ "automatically turn on bsp view after compiling");
-
- dvars::bsp_gen_reflections_on_compile = dvars::register_bool(
- /* name */ "bsp_gen_reflections_on_compile",
- /* default */ true,
- /* flags */ game::dvar_flags::saved,
- /* desc */ "automatically build reflections when compiling the bsp");
-
- dvars::bsp_gen_createfx_on_compile = dvars::register_bool(
- /* name */ "bsp_gen_createfx_on_compile",
- /* default */ true,
- /* flags */ game::dvar_flags::saved,
- /* desc */ "automatically generate CreateFX files when compiling the bsp");
-
- dvars::r_draw_bsp = dvars::register_bool(
- /* name */ "r_draw_bsp",
- /* default */ false,
- /* flags */ game::dvar_flags::none,
- /* desc */ "enable to render bsp (if loaded)");
-
- dvars::r_draw_bsp_overwrite_sunlight = dvars::register_bool(
- /* name */ "r_draw_bsp_overwrite_sunlight",
- /* default */ false,
- /* flags */ game::dvar_flags::none,
- /* desc */ "enable to overwrite bsp sunlight with fakesun settings");
-
- dvars::r_draw_bsp_overwrite_sundir = dvars::register_bool(
- /* name */ "r_draw_bsp_overwrite_sundir",
- /* default */ false,
- /* flags */ game::dvar_flags::none,
- /* desc */ "enable to overwrite bsp sundir with fakesun settings");
-
- dvars::r_draw_bsp_overwrite_sunspecular = dvars::register_bool(
- /* name */ "r_draw_bsp_overwrite_sunspecular",
- /* default */ false,
- /* flags */ game::dvar_flags::none,
- /* desc */ "enable to overwrite bsp sunspecular with fakesun settings");
- }
-
- d3dbsp::d3dbsp()
- {
- // #
- // * NOTES
- // * DONE: load "dynamic" entities like exploding cars (scene.sceneModelCount :: R_AddXModelSurfacesCamera :: R_AddAllSceneEntSurfacesCamera)
- // * TODO: ^ CG_ProcessEntity :: CG_ScriptMover :: R_AddDObjToScene
- // * ^ G_InitGame :: G_SpawnEntitiesFromString .... G_ModelIndex -> XModelPrecache_LoadObj
-
- // * TODO: draw sun / load sun dvars from sun file
-
- // #
- // R_LoadWorldInternal patches
-
- // re-implement a LUMP_UNLAYERED_TRIANGLES check (r_useLayeredMaterials)
- utils::hook::detour(0x4161B0, d3dbsp::Com_GetBspLumpBool, HK_JUMP);
-
- // re-implement Com_GetBspVersion
- utils::hook::detour(0x416150, d3dbsp::Com_GetBspVersion, HK_JUMP);
-
- // re-implement Com_GetBspLump
- utils::hook::detour(0x416180, d3dbsp::Com_GetBspLump, HK_JUMP);
-
- // re-implement CM_GetPlanes
- utils::hook::detour(0x4161E0, d3dbsp::CM_GetPlanes, HK_JUMP);
-
- // re-implement CM_GetPlaneCount
- utils::hook::detour(0x4161F0, d3dbsp::CM_GetPlaneCount, HK_JUMP);
-
- // re-implement CG_GetEntityOrigin in R_ShowCull
- utils::hook(0x5274CC, CG_GetEntityOrigin_stub, HOOK_JUMP).install()->quick();
-
-
- // #
- // dirty hacks
-
- utils::hook::nop(0x5525A2, 5); // Outdoor_ComputeTexels call
- utils::hook::nop(0x5101A4, 5); // memset of s_world in R_LoadWorldInternal
-
- utils::hook::nop(0x41625A, 5); // CM_BoxSightTrace Assert
- utils::hook::nop(0x56C8DC, 5); // bspSurf->material->info.name) = %s", "(!lightmapSecondaryFlag) Assert
-
- utils::hook::nop(0x41637A, 5); // Ragdoll_HandleBody Assert
-
-
-
- // Material_Add :: set rgp.needSortMaterials = 1 to 0 (do not re-sort materials when loading new ones; fixes bsp texture issues)
- utils::hook::set(0x510CF1 + 6, 0x0);
-
- // RENDERTARGET_SCENE to FRAMEBUFFER in R_DrawPointLitSurfsCallback
- utils::hook::set(0x55BC8F + 1, 0x1);
-
- // R_LoadSun (not needed and prints irrelevant info)
- utils::hook::nop(0x51047D, 5);
-
- // R_LoadSunThroughDvars :: no longer called because above nop ^
- utils::hook::nop(0x52DAFA, 5); // Com_LoadDvarsFromBuffer (not implemented)
-
-
-
- // #
- // no bsp culling
-
- // R_AddCellSceneEntSurfacesInFrustumCmd :: active ents like destructible cars / players (disable all culling)
- //utils::hook::nop(0x56998B, 3);
-
- // R_AddWorldSurfacesPortalWalk :: less culling :: 0x7C -> 0xEB (jl -> jmp)
- //utils::hook::set(0x527370, 0xEB);
-
- // R_AddAabbTreeSurfacesInFrustum_r :: less culling :: 0x74 -> 0xEB (je to jmp)
- //utils::hook::set(0x555C4C, 0xEB);
-
-
- // #
- // --------------------------
-
-
- // reload the currently loaded bsp
- // tries to automatically load a bsp based of the .map name if no bsp is loaded
- command::register_command_with_hotkey("bsp_reload"s, [](auto)
- {
- components::d3dbsp::reload_bsp();
- });
-
- // toggle bsp rendering on/off
- command::register_command_with_hotkey("toggle_bsp"s, [this](auto)
- {
- dvars::set_bool(dvars::r_draw_bsp, !dvars::r_draw_bsp->current.enabled);
- });
-
- // toggle between bsp and radiant rendering
- command::register_command_with_hotkey("toggle_bsp_radiant"s, [this](auto)
- {
- if (d3dbsp::Com_IsBspLoaded())
- {
- const bool tstate = gameview::p_this->get_all_geo_state() || gameview::p_this->get_all_ents_state() || gameview::p_this->get_all_triggers_state() || gameview::p_this->get_all_others_state();
-
- const bool gameview_was_enabled = dvars::radiant_gameview->current.enabled;
-
- dvars::set_bool(dvars::r_draw_bsp, !tstate);
- command::execute("toggle_filter_all");
-
- if (gameview_was_enabled)
- {
- components::gameview::p_this->set_state(gameview_was_enabled);
- }
- }
- });
-
- command::register_command_with_hotkey("bsp_compile"s, [this](auto)
- {
- components::d3dbsp::compile_current_map();
- });
- }
-
- d3dbsp::~d3dbsp()
- {
- d3dbsp::shutdown_bsp();
- }
-}
+ }
+ }, true );
+
+ process->create_process();
+ }
+
+ /**
+ * @brief run batch to compile bsp for currently loaded .map
+ */
+ void d3dbsp::compile_current_map()
+ {
+ std::string d3dbsp_name = std::string(game::current_map_filepath).substr(std::string(game::current_map_filepath).find_last_of("\\") + 1);
+ utils::erase_substring(d3dbsp_name, ".map");
+
+ components::d3dbsp::compile_bsp(d3dbsp_name, dvars::bsp_gen_createfx_on_compile->current.enabled);
+ }
+
+
+ // *
+ // *
+
+
+ float* CG_GetEntityOrigin(int scene_model_index)
+ {
+ return game::scene->sceneModel[scene_model_index].placement.base.origin;
+ }
+
+ void __declspec(naked) CG_GetEntityOrigin_stub()
+ {
+ const static uint32_t retn_addr = 0x5274D1;
+ __asm
+ {
+ push edi; // curr index in do-while loop (i < sceneModelCount)
+ call CG_GetEntityOrigin;
+ add esp, 4;
+ jmp retn_addr;
+ }
+ }
+
+
+ // *
+ // *
+
+
+ void d3dbsp::force_dvars()
+ {
+ /*if (const auto& sm_enable = game::Dvar_FindVar("sm_enable"); sm_enable && sm_enable->current.enabled) {
+ dvars::set_bool(sm_enable, false);
+ }*/
+
+ if (const auto& r_floatz = game::Dvar_FindVar("r_floatz"); r_floatz && !r_floatz->current.enabled) {
+ dvars::set_bool(r_floatz, true);
+ }
+
+ if (const auto& r_distortion = game::Dvar_FindVar("r_distortion"); r_distortion && !r_distortion->current.enabled) {
+ dvars::set_bool(r_distortion, true);
+ }
+
+ if (const auto& r_zFeather = game::Dvar_FindVar("r_zFeather"); r_zFeather && !r_zFeather->current.enabled) {
+ dvars::set_bool(r_zFeather, true);
+ }
+
+ if (const auto& r_useLayeredMaterials = game::Dvar_FindVar("r_useLayeredMaterials"); r_useLayeredMaterials && r_useLayeredMaterials->current.enabled) {
+ dvars::set_bool(r_useLayeredMaterials, false);
+ }
+
+ if (const auto& r_polygonOffsetBias = game::Dvar_FindVar("r_polygonOffsetBias"); r_polygonOffsetBias) {
+ dvars::set_float(r_polygonOffsetBias, 0.0f);
+ }
+
+ if (const auto& r_polygonOffsetScale = game::Dvar_FindVar("r_polygonOffsetScale"); r_polygonOffsetScale) {
+ dvars::set_float(r_polygonOffsetScale, -0.05f); // or radiant brushes/decals start to flicker
+ }
+
+ if (const auto& r_zNear = game::Dvar_FindVar("r_zNear"); r_zNear) {
+ dvars::set_float(r_zNear, 4.0f);
+ }
+ }
+
+ void d3dbsp::register_dvars()
+ {
+ dvars::bsp_load_entities = dvars::register_bool(
+ /* name */ "bsp_load_entities",
+ /* default */ true,
+ /* flags */ game::dvar_flags::saved,
+ /* desc */ "enable to load entities when loading a bsp (static_models only)");
+
+ dvars::bsp_show_bsp_after_compile = dvars::register_bool(
+ /* name */ "bsp_show_bsp_after_compile",
+ /* default */ true,
+ /* flags */ game::dvar_flags::saved,
+ /* desc */ "automatically turn on bsp view after compiling");
+
+ dvars::bsp_gen_reflections_on_compile = dvars::register_bool(
+ /* name */ "bsp_gen_reflections_on_compile",
+ /* default */ true,
+ /* flags */ game::dvar_flags::saved,
+ /* desc */ "automatically build reflections when compiling the bsp");
+
+ dvars::bsp_gen_createfx_on_compile = dvars::register_bool(
+ /* name */ "bsp_gen_createfx_on_compile",
+ /* default */ true,
+ /* flags */ game::dvar_flags::saved,
+ /* desc */ "automatically generate CreateFX files when compiling the bsp");
+
+ dvars::r_draw_bsp = dvars::register_bool(
+ /* name */ "r_draw_bsp",
+ /* default */ false,
+ /* flags */ game::dvar_flags::none,
+ /* desc */ "enable to render bsp (if loaded)");
+
+ dvars::r_draw_bsp_overwrite_sunlight = dvars::register_bool(
+ /* name */ "r_draw_bsp_overwrite_sunlight",
+ /* default */ false,
+ /* flags */ game::dvar_flags::none,
+ /* desc */ "enable to overwrite bsp sunlight with fakesun settings");
+
+ dvars::r_draw_bsp_overwrite_sundir = dvars::register_bool(
+ /* name */ "r_draw_bsp_overwrite_sundir",
+ /* default */ false,
+ /* flags */ game::dvar_flags::none,
+ /* desc */ "enable to overwrite bsp sundir with fakesun settings");
+
+ dvars::r_draw_bsp_overwrite_sunspecular = dvars::register_bool(
+ /* name */ "r_draw_bsp_overwrite_sunspecular",
+ /* default */ false,
+ /* flags */ game::dvar_flags::none,
+ /* desc */ "enable to overwrite bsp sunspecular with fakesun settings");
+ }
+
+ d3dbsp::d3dbsp()
+ {
+ // #
+ // * NOTES
+ // * DONE: load "dynamic" entities like exploding cars (scene.sceneModelCount :: R_AddXModelSurfacesCamera :: R_AddAllSceneEntSurfacesCamera)
+ // * TODO: ^ CG_ProcessEntity :: CG_ScriptMover :: R_AddDObjToScene
+ // * ^ G_InitGame :: G_SpawnEntitiesFromString .... G_ModelIndex -> XModelPrecache_LoadObj
+
+ // * TODO: draw sun / load sun dvars from sun file
+
+ // #
+ // R_LoadWorldInternal patches
+
+ // re-implement a LUMP_UNLAYERED_TRIANGLES check (r_useLayeredMaterials)
+ utils::hook::detour(0x4161B0, d3dbsp::Com_GetBspLumpBool, HK_JUMP);
+
+ // re-implement Com_GetBspVersion
+ utils::hook::detour(0x416150, d3dbsp::Com_GetBspVersion, HK_JUMP);
+
+ // re-implement Com_GetBspLump
+ utils::hook::detour(0x416180, d3dbsp::Com_GetBspLump, HK_JUMP);
+
+ // re-implement CM_GetPlanes
+ utils::hook::detour(0x4161E0, d3dbsp::CM_GetPlanes, HK_JUMP);
+
+ // re-implement CM_GetPlaneCount
+ utils::hook::detour(0x4161F0, d3dbsp::CM_GetPlaneCount, HK_JUMP);
+
+ // re-implement CG_GetEntityOrigin in R_ShowCull
+ utils::hook(0x5274CC, CG_GetEntityOrigin_stub, HOOK_JUMP).install()->quick();
+
+
+ // #
+ // dirty hacks
+
+ utils::hook::nop(0x5525A2, 5); // Outdoor_ComputeTexels call
+ utils::hook::nop(0x5101A4, 5); // memset of s_world in R_LoadWorldInternal
+
+ utils::hook::nop(0x41625A, 5); // CM_BoxSightTrace Assert
+ utils::hook::nop(0x56C8DC, 5); // bspSurf->material->info.name) = %s", "(!lightmapSecondaryFlag) Assert
+
+ utils::hook::nop(0x41637A, 5); // Ragdoll_HandleBody Assert
+
+
+
+ // Material_Add :: set rgp.needSortMaterials = 1 to 0 (do not re-sort materials when loading new ones; fixes bsp texture issues)
+ utils::hook::set(0x510CF1 + 6, 0x0);
+
+ // RENDERTARGET_SCENE to FRAMEBUFFER in R_DrawPointLitSurfsCallback
+ utils::hook::set(0x55BC8F + 1, 0x1);
+
+ // R_LoadSun (not needed and prints irrelevant info)
+ utils::hook::nop(0x51047D, 5);
+
+ // R_LoadSunThroughDvars :: no longer called because above nop ^
+ utils::hook::nop(0x52DAFA, 5); // Com_LoadDvarsFromBuffer (not implemented)
+
+
+
+ // #
+ // no bsp culling
+
+ // R_AddCellSceneEntSurfacesInFrustumCmd :: active ents like destructible cars / players (disable all culling)
+ //utils::hook::nop(0x56998B, 3);
+
+ // R_AddWorldSurfacesPortalWalk :: less culling :: 0x7C -> 0xEB (jl -> jmp)
+ //utils::hook::set(0x527370, 0xEB);
+
+ // R_AddAabbTreeSurfacesInFrustum_r :: less culling :: 0x74 -> 0xEB (je to jmp)
+ //utils::hook::set(0x555C4C, 0xEB);
+
+
+ // #
+ // --------------------------
+
+
+ // reload the currently loaded bsp
+ // tries to automatically load a bsp based of the .map name if no bsp is loaded
+ command::register_command_with_hotkey("bsp_reload"s, [](auto)
+ {
+ components::d3dbsp::reload_bsp();
+ });
+
+ // toggle bsp rendering on/off
+ command::register_command_with_hotkey("toggle_bsp"s, [this](auto)
+ {
+ dvars::set_bool(dvars::r_draw_bsp, !dvars::r_draw_bsp->current.enabled);
+ });
+
+ // toggle between bsp and radiant rendering
+ command::register_command_with_hotkey("toggle_bsp_radiant"s, [this](auto)
+ {
+ if (d3dbsp::Com_IsBspLoaded())
+ {
+ const bool tstate = gameview::p_this->get_all_geo_state() || gameview::p_this->get_all_ents_state() || gameview::p_this->get_all_triggers_state() || gameview::p_this->get_all_others_state();
+
+ const bool gameview_was_enabled = dvars::radiant_gameview->current.enabled;
+
+ dvars::set_bool(dvars::r_draw_bsp, !tstate);
+ command::execute("toggle_filter_all");
+
+ if (gameview_was_enabled)
+ {
+ components::gameview::p_this->set_state(gameview_was_enabled);
+ }
+ }
+ });
+
+ command::register_command_with_hotkey("bsp_compile"s, [this](auto)
+ {
+ components::d3dbsp::compile_current_map();
+ });
+ }
+
+ d3dbsp::~d3dbsp()
+ {
+ d3dbsp::shutdown_bsp();
+ }
+}
diff --git a/src/components/modules/effects.cpp b/src/components/modules/effects.cpp
index 6300cba..3ef934e 100644
--- a/src/components/modules/effects.cpp
+++ b/src/components/modules/effects.cpp
@@ -726,7 +726,7 @@ namespace components
else
{
filepath = dvars::fs_homepath->current.string;
- filepath += "\\IW3xRadiant\\createfx\\"s;
+ filepath += "\\T5xRadiant\\createfx\\"s;
}
diff --git a/src/components/modules/generate_previews.cpp b/src/components/modules/generate_previews.cpp
index 171a7cc..8415714 100644
--- a/src/components/modules/generate_previews.cpp
+++ b/src/components/modules/generate_previews.cpp
@@ -114,7 +114,7 @@ namespace components
// take screenshot
std::string file_path = game::Dvar_FindVar("fs_homepath")->current.string;
- file_path += R"(\IW3xRadiant\prefab_thumbs\)";
+ file_path += R"(\T5xRadiant\prefab_thumbs\)";
auto thumbnail_str = GET_GUI(ggui::prefab_preview_dialog)->get_thumbnail_string(rel_path.has_parent_path() ? rel_path.parent_path() : "", rel_path.filename().string());
thumbnail_str += ".jpg";
diff --git a/src/components/modules/gui.cpp b/src/components/modules/gui.cpp
index 675cd10..a7095b4 100644
--- a/src/components/modules/gui.cpp
+++ b/src/components/modules/gui.cpp
@@ -60,7 +60,7 @@ namespace components
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
io.ConfigWindowsResizeFromEdges = true;
- io.IniFilename = "IW3xRadiant\\imgui.ini";
+ io.IniFilename = "T5xRadiant\\imgui.ini";
// implementation
ImGui_ImplWin32_Init(cmainframe::activewnd->m_pZWnd->GetWindow());
@@ -478,7 +478,7 @@ namespace components
{
ImGuiToast toast(ImGuiToastType_Info, 2500);
toast.set_title("Snapshot created");
- toast.set_content(R"(D:\COD4Modtools\map_source\snapshots\mp_bsptest.map.5)");
+ toast.set_content(R"(D:\BO1Modtools\map_source\snapshots\mp_bsptest.map.5)");
ImGui::InsertNotification(toast);
}
diff --git a/src/components/modules/main_module.cpp b/src/components/modules/main_module.cpp
index 3d6dbd4..ef92529 100644
--- a/src/components/modules/main_module.cpp
+++ b/src/components/modules/main_module.cpp
@@ -296,7 +296,7 @@ BOOL init_threads()
// discord rich presence
CreateThread(nullptr, 0, discord_rpc, nullptr, 0, nullptr);
- // check for iw3xradiant updates
+ // check for t5xradiant updates
CreateThread(nullptr, 0, update_check, nullptr, 0, nullptr);
game::glob::command_thread_running = false;
@@ -316,7 +316,7 @@ BOOL init_threads()
freopen_s(&file, "CONOUT$", "w", stdout);
freopen_s(&file, "CONOUT$", "w", stderr);
- SetConsoleTitleA("IW3xRadiant Console");
+ SetConsoleTitleA("T5xRadiant Console");
}
return TRUE;
@@ -325,12 +325,12 @@ BOOL init_threads()
namespace components
{
- void add_iw3xradiant_searchpath()
+ void add_t5xradiant_searchpath()
{
if(const auto fs_basepath = game::Dvar_FindVar("fs_basepath");
fs_basepath)
{
- game::FS_ScanForDir("bin/IW3xRadiant", fs_basepath->current.string, false);
+ game::FS_ScanForDir("bin/T5xRadiant", fs_basepath->current.string, false);
}
}
@@ -344,7 +344,7 @@ namespace components
call Com_Printf_Func;
pushad;
- call add_iw3xradiant_searchpath;
+ call add_t5xradiant_searchpath;
popad;
jmp retn_pt;
@@ -456,7 +456,7 @@ namespace components
// *
// *
- // add iw3xradiant search path (imgui images)
+ // add t5xradiant search path (imgui images)
utils::hook(0x4A29A7, fs_scan_base_directory_stub, HOOK_JUMP).install()->quick();
// set max undo memory
diff --git a/src/components/modules/mesh_painter.cpp b/src/components/modules/mesh_painter.cpp
index 92a5f9e..ab9c620 100644
--- a/src/components/modules/mesh_painter.cpp
+++ b/src/components/modules/mesh_painter.cpp
@@ -20,7 +20,7 @@ namespace components
dvars::fs_homepath)
{
std::string dir_path = dvars::fs_homepath->current.string;
- dir_path += R"(\IW3xRadiant\mesh_painter)";
+ dir_path += R"(\T5xRadiant\mesh_painter)";
const auto file = GET_GUI(ggui::file_dialog);
file->set_default_path(dir_path);
@@ -38,7 +38,7 @@ namespace components
if (ofile.is_open())
{
- ofile << "// mesh painter list generated by iw3xo-radiant" << std::endl;
+ ofile << "// mesh painter list generated by t5xo-radiant" << std::endl;
ofile << "// # radius, paint threshold, paint density" << std::endl;
ofile << "// name, enabled, paint_weight, random_rotation, align_to_ground, z_offset, random_size, size_range[0], size_range[1]" << std::endl;
@@ -55,7 +55,7 @@ namespace components
}
else
{
- game::printf_to_console("[ERR] [Mesh-Painter] Failed to find open '%s' in 'bin/IW3xRadiant/mesh_painter'", filename.c_str());
+ game::printf_to_console("[ERR] [Mesh-Painter] Failed to find open '%s' in 'bin/T5xRadiant/mesh_painter'", filename.c_str());
}
});
@@ -69,7 +69,7 @@ namespace components
dvars::fs_homepath)
{
std::string dir_path = dvars::fs_homepath->current.string;
- dir_path += R"(\IW3xRadiant\mesh_painter)";
+ dir_path += R"(\T5xRadiant\mesh_painter)";
const auto file = GET_GUI(ggui::file_dialog);
file->set_default_path(dir_path);
@@ -97,7 +97,7 @@ namespace components
// read line by line
while (std::getline(ifile, input))
{
- if (!first_line && input.find("// mesh painter list generated by iw3xo-radiant") == std::string::npos)
+ if (!first_line && input.find("// mesh painter list generated by t5xo-radiant") == std::string::npos)
{
// invalid file
break;
@@ -162,7 +162,7 @@ namespace components
}
else
{
- game::printf_to_console("[ERR] [Mesh-Painter] Failed to find open '%s' in 'bin/IW3xRadiant/mesh_painter'", filename.c_str());
+ game::printf_to_console("[ERR] [Mesh-Painter] Failed to find open '%s' in 'bin/T5xRadiant/mesh_painter'", filename.c_str());
}
});
diff --git a/src/components/modules/patches.cpp b/src/components/modules/patches.cpp
index 2d12d79..fa8457a 100644
--- a/src/components/modules/patches.cpp
+++ b/src/components/modules/patches.cpp
@@ -94,7 +94,7 @@ namespace components
void DECLSPEC_NORETURN on_invalid_hwnd_assert()
{
- game::Com_Error("Failed to initialize renderer. This might indicate that you have not installed the cod4 modtools or are missing parts of it.\n");
+ game::Com_Error("Failed to initialize renderer. This might indicate that you have not installed the bo1 modtools or are missing parts of it.\n");
exit(0);
}
diff --git a/src/components/modules/reflectionprobes.cpp b/src/components/modules/reflectionprobes.cpp
index 5e41bd0..4b1d5ed 100644
--- a/src/components/modules/reflectionprobes.cpp
+++ b/src/components/modules/reflectionprobes.cpp
@@ -32,7 +32,7 @@ namespace components
dvars::fs_homepath)
{
std::string filePath = dvars::fs_homepath->current.string;
- filePath += R"(\IW3xRadiant\reflection_probes\)";
+ filePath += R"(\T5xRadiant\reflection_probes\)";
std::filesystem::create_directories(filePath);
filePath += filename + ".tga"s;
@@ -808,7 +808,7 @@ namespace components
/* name */ "r_reflectionprobe_export_tga",
/* default */ false,
/* flags */ game::dvar_flags::none,
- /* desc */ "export all reflection probes as tga files when building reflections (bin/IW3xRadiant/reflection_probes)");
+ /* desc */ "export all reflection probes as tga files when building reflections (bin/T5xRadiant/reflection_probes)");
}
reflectionprobes::reflectionprobes()
diff --git a/src/components/modules/renderer.cpp b/src/components/modules/renderer.cpp
index 8ad78fd..6e00524 100644
--- a/src/components/modules/renderer.cpp
+++ b/src/components/modules/renderer.cpp
@@ -451,9 +451,9 @@ namespace components
sprintf_s(shader_path, 260u, "%s/raw/shader_bin/%s_%8.8x", game::Dvar_FindVar("fs_basepath")->current.string, prefix_str, shader_hash);
if (!r_load_shader_programm(&shader_len, &chachedShader, shader_path))
{
- // look for addon shaders in bin/IW3xRadiant/shader_bin
+ // look for addon shaders in bin/T5xRadiant/shader_bin
memset(&shader_path, 0, sizeof(shader_path));
- sprintf_s(shader_path, 260u, "%s/bin/IW3xRadiant/shader_bin/%s_%8.8x", game::Dvar_FindVar("fs_basepath")->current.string, prefix_str, shader_hash);
+ sprintf_s(shader_path, 260u, "%s/bin/T5xRadiant/shader_bin/%s_%8.8x", game::Dvar_FindVar("fs_basepath")->current.string, prefix_str, shader_hash);
if (!r_load_shader_programm(&shader_len, &chachedShader, shader_path))
{
@@ -1202,7 +1202,7 @@ namespace components
}
}
- // return handle for loaded technique, loads new technique from "raw/techniques" or "bin/IW3xRadiant/techniques" otherwise
+ // return handle for loaded technique, loads new technique from "raw/techniques" or "bin/T5xRadiant/techniques" otherwise
game::MaterialTechnique* Material_RegisterTechnique(const char* name /*eax*/, int is_renderer_in_use /*edi*/)
{
const static uint32_t func_addr = 0x519790;
@@ -2032,7 +2032,7 @@ namespace components
if (dvars::fs_homepath)
{
std::string filePath = dvars::fs_homepath->current.string;
- filePath += "\\IW3xRadiant\\LOG_rendercommands.txt"s;
+ filePath += "\\T5xRadiant\\LOG_rendercommands.txt"s;
log_file.open(filePath.c_str());
if (!log_file.is_open())
diff --git a/src/components/modules/time_wasted.cpp b/src/components/modules/time_wasted.cpp
index 27dac07..765fd2a 100644
--- a/src/components/modules/time_wasted.cpp
+++ b/src/components/modules/time_wasted.cpp
@@ -22,7 +22,7 @@ namespace components
void time_wasted::write_entries_to_file()
{
std::ofstream file;
- if (utils::fs::write_file_homepath("IW3xRadiant", "time_wasted.ini", false, file))
+ if (utils::fs::write_file_homepath("T5xRadiant", "time_wasted.ini", false, file))
{
for (const auto& entry : m_entries)
{
@@ -38,7 +38,7 @@ namespace components
m_entries.clear();
std::ifstream file;
- if (utils::fs::open_file_homepath("IW3xRadiant", "time_wasted.ini", false, file))
+ if (utils::fs::open_file_homepath("T5xRadiant", "time_wasted.ini", false, file))
{
std::string input;
std::vector args;
diff --git a/src/ggui/effects_editor_gui.cpp b/src/ggui/effects_editor_gui.cpp
index e8f9d31..7ed991e 100644
--- a/src/ggui/effects_editor_gui.cpp
+++ b/src/ggui/effects_editor_gui.cpp
@@ -1648,7 +1648,7 @@ namespace ggui
if (elem->elemType == fx_system::FX_ELEM_TYPE_MODEL)
{
MOD_CHECK(ImGui::Checkbox_FxElemFlag("Enable simulation (PhysX / ODE)", elem, fx_system::FX_ELEM_USE_MODEL_PHYSICS, &physx_enabled));
- TT("This enables PhysX (in radiant) and the stock physics engine in cod4");
+ TT("This enables PhysX (in radiant) and the stock physics engine in bo1");
}
if (physx_enabled)
diff --git a/src/ggui/hotkeys.cpp b/src/ggui/hotkeys.cpp
index 361a8df..4f0f6e2 100644
--- a/src/ggui/hotkeys.cpp
+++ b/src/ggui/hotkeys.cpp
@@ -22,7 +22,7 @@ namespace ggui
if (const auto& fs_homepath = game::Dvar_FindVar("fs_homepath");
fs_homepath)
{
- const char* apply_hint = utils::va("Could not find file 'hotkeys.ini' in\n'%s/IW3xRadiant'.", fs_homepath->current.string);
+ const char* apply_hint = utils::va("Could not find file 'hotkeys.ini' in\n'%s/T5xRadiant'.", fs_homepath->current.string);
ImGui::SetCursorPosX((ImGui::GetWindowWidth() - ImGui::CalcTextSize(apply_hint).x) * 0.5f);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetWindowHeight() * 0.5f - ImGui::CalcTextSize(apply_hint).y);
ImGui::TextUnformatted(apply_hint);
@@ -300,7 +300,7 @@ namespace ggui
cmd_hotkeys.clear();
std::ifstream ini;
- if (utils::fs::open_file_homepath("IW3xRadiant", file, false, ini))
+ if (utils::fs::open_file_homepath("T5xRadiant", file, false, ini))
{
std::string input;
std::vector args;
@@ -368,7 +368,7 @@ namespace ggui
}
game::printf_to_console("[ERR][Hotkeys] Failed to find 'hotkeys.ini'\n");
- game::printf_to_console("[ERR] ^ will be created upon closing radiant with default bindings. Please consider using the ini file that came with iw3xo-radiant.\n");
+ game::printf_to_console("[ERR] ^ will be created upon closing radiant with default bindings. Please consider using the ini file that came with t5xo-radiant.\n");
return false;
}
@@ -754,7 +754,7 @@ namespace ggui
}
std::ofstream ini;
- if (utils::fs::write_file_homepath("IW3xRadiant", "hotkeys.ini", false, ini))
+ if (utils::fs::write_file_homepath("T5xRadiant", "hotkeys.ini", false, ini))
{
ini << "[Commands]" << std::endl;
diff --git a/src/ggui/menubar.cpp b/src/ggui/menubar.cpp
index 3745b6f..cbaedd6 100644
--- a/src/ggui/menubar.cpp
+++ b/src/ggui/menubar.cpp
@@ -174,7 +174,7 @@ namespace ggui
{
components::effects::generate_createfx();
- } TT("Generate createfx files for current map.\n (bin\\IW3xRadiant\\createfx)");
+ } TT("Generate createfx files for current map.\n (bin\\T5xRadiant\\createfx)");
if (ImGui::MenuItem("Pointfile")) {
mainframe_cdeclcall(void, 0x423B20); //cmainframe::OnPointfileOpen
diff --git a/src/ggui/textures.cpp b/src/ggui/textures.cpp
index 163ce44..459e662 100644
--- a/src/ggui/textures.cpp
+++ b/src/ggui/textures.cpp
@@ -626,7 +626,7 @@ namespace ggui
std::ifstream file;
std::string dir_path = dvars::fs_homepath->current.string;
- dir_path += R"(\IW3xRadiant\texture_favourites\)";
+ dir_path += R"(\T5xRadiant\texture_favourites\)";
std::filesystem::create_directories(dir_path);
@@ -640,7 +640,7 @@ namespace ggui
if (ofile.is_open())
{
- ofile << "// texture favourites generated by iw3xo-radiant" << std::endl;
+ ofile << "// texture favourites generated by t5xo-radiant" << std::endl;
ofile << new_list_name << std::endl;
ofile.close();
diff --git a/src/ggui/toolbar.cpp b/src/ggui/toolbar.cpp
index d70c99b..a50cbb4 100644
--- a/src/ggui/toolbar.cpp
+++ b/src/ggui/toolbar.cpp
@@ -1144,7 +1144,7 @@ namespace ggui
std::string ini_path = fs_homepath->current.string;
- ini_path += "\\IW3xRadiant\\" + TB_INI_FILENAME;
+ ini_path += "\\T5xRadiant\\" + TB_INI_FILENAME;
std::ifstream ini;
ini.open(ini_path.c_str());
@@ -1260,7 +1260,7 @@ namespace ggui
{
std::ofstream ini;
std::string ini_path = fs_homepath->current.string;
- ini_path += "\\IW3xRadiant\\" + TB_INI_FILENAME;
+ ini_path += "\\T5xRadiant\\" + TB_INI_FILENAME;
ini.open(ini_path.c_str());
if (!ini.is_open())
diff --git a/src/utils/filesystem.cpp b/src/utils/filesystem.cpp
index b4249cd..340002a 100644
--- a/src/utils/filesystem.cpp
+++ b/src/utils/filesystem.cpp
@@ -71,7 +71,7 @@ namespace utils::fs
}
/**
- * @return cod4 root path
+ * @return bo1 root path
*/
std::string get_basepath()
{
From 71504e407aba816db71e9492f59c1112fe4b4c16 Mon Sep 17 00:00:00 2001
From: Faber <103538724+FaberTheCatboy@users.noreply.github.com>
Date: Fri, 17 Mar 2023 11:14:35 -0700
Subject: [PATCH 5/5] Update README.md
---
README.md | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/README.md b/README.md
index d8e09f6..2610024 100644
--- a/README.md
+++ b/README.md
@@ -62,14 +62,14 @@ If you want to buy me a coffee:
___
-### New features not found within the original cod4 radiant:
+### New features not found within the original bo1 radiant:
+ completely revamped user interface with docking, tabs, saved layouts and more (Dear ImGui)
+ [play](https://xoxor4d.github.io/tutorials/iw3xradiant-using-effects/) && [edit / create](https://xoxor4d.github.io/tutorials/iw3xradiant-effects-editor/) && [export effects as CreateFX](https://xoxor4d.github.io/tutorials/iw3xradiant-createfx/) files right from within radiant (__makes effectsEd completely obsolete__)
+ Nvidia PhysX integration for [dynamic placement of prefabs](https://xoxor4d.github.io/tutorials/iw3xradiant-physx-prefabs) or [physics-enabled effects](https://xoxor4d.github.io/tutorials/iw3xradiant-physx-effects) (can be turned into misc_models)
-+ Nvidia PhysX enabled character movement with cod4 movement mechanics (bouncing) [character movement](https://xoxor4d.github.io/tutorials/iw3xradiant-physx-movement)
++ Nvidia PhysX enabled character movement with bo1 movement mechanics (bouncing) [character movement](https://xoxor4d.github.io/tutorials/iw3xradiant-physx-movement)
+ [d3dbsp loading](https://xoxor4d.github.io/tutorials/iw3xradiant-d3dbsp) and bsp/light compilation from within radiant
+ [automatically generate reflections](https://xoxor4d.github.io/tutorials/iw3xradiant-d3dbsp-reflections) within radiant when compiling the maps bsp
-+ [live link](https://xoxor4d.github.io/tutorials/iw3xradiant-livelink) (sync. brushes (with collision), camera and worldspawn settings between cod4 and radiant)
++ [live link](https://xoxor4d.github.io/tutorials/iw3xradiant-livelink) (sync. brushes (with collision), camera and worldspawn settings between bo1 and radiant)
+ [mesh painting](https://xoxor4d.github.io/tutorials/iw3xradiant-mesh-painting) (xmodels/prefabs) with per object settings, random size, angles, weight etc.
+ 3D guizmo to precisely manipulate entities and brushes from the camera window (ImGuizmo)
+ a prefab browser with the ability to generate thumbnails + drag and drop prefabs into the scene
@@ -112,14 +112,14 @@ ___
-1. Install the Bo1 Modtools
-2. Download the latest [release](https://github.com/VenomModding/T5xRadiant/releases)
-3. Copy the contents into your cod4 root directory
+1. Install the bo1 Modtools
+2. Download the latest [release](https://github.com/xoxor4d/iw3xo-radiant/releases)
+3. Copy the contents into your bo1 root directory
4. Start `bin/T5xRadiant.exe`
- [NIGHTLY] install latest release, download nightly, unpack and replace `t5xr.dll` within the `bin` folder
- -> check for additional assets in the __#nightly-builds__ channel (📍) on the [Venom Modding discord](https://discord.gg/QuNcjXbsqY)
-- [OPTIONAL] __bo3-tool-textures.zip__ (unpack and place `.iwi's` into `bin\T5xRadiant\images`)
+ -> check for additional assets in the __#nightly-builds__ channel (📍) on the [iw3xo discord](https://discord.gg/t5jRGbj)
+- [OPTIONAL] __bo3-tool-textures.zip__ (unpack and place `.iwi's` into `bin\IW3xRadiant\images`)
@@ -133,7 +133,7 @@ ___
2. Copy everything within the assets folder into your bo1-root folder
3. Use __update_submodules.bat__ to update submodules
4. Use __generate-buildfiles.bat__ to build project files with premake
-5. Load the solution `(build/t5x-radiant.sln)` and open the iw3r project-settings to setup paths:
+5. Load the solution `(build/iw3xo-radiant.sln)` and open the iw3r project-settings to setup paths:
> - General output directory path -> `path-to-bo1-root\bin\`
> - Debugging command -> `path-to-bo1-root\bin\T5xRadiant.exe`
> - Debugging working directory -> `path-to-bo1-root\bin\`
@@ -145,18 +145,18 @@ ___
### How to build the project using VSCode
1. Install C++ Build tools (msbuild)
2. Add msbuild folder to the "PATH" environment variable:
-> `%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin`
+> `%ProgramFiles(x86)%\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin`
3. Add `BO1_ROOT` environment variable with path to your bo1 directory
> `"BO1_ROOT" "D:\BO1-Modtools"`
4. Clone the repo (zip does not include deps!)
5. Copy everything within the assets folder into your bo1-root folder
6. Drag and drop all files from `.vscode/tracked\` into `.vscode\`
-7. Open __t5x-radiant.code-workspace__
+7. Open __t5xo-radiant.code-workspace__
8. Run task: `update_submodules` or open __update_submodules.bat__
9. Run task: `generate-buildfiles` or open __generate-buildfiles.bat__
-Use provided build-tasks with the option to copy `T5xr.dll` and `T5xr.pdb` to `%BO1_ROOT%/bin`
-__Run->Start Debugging__ will build and copy a debug build to to `%BO1_ROOT%/bin` and launch IW3xRadiant.
+Use provided build-tasks with the option to copy `t5xr.dll` and `t5xr.pdb` to `%BO1_ROOT%/bin`
+__Run->Start Debugging__ will build and copy a debug build to to `%BO1_ROOT%/bin` and launch T5xRadiant.
@@ -164,8 +164,8 @@ ___
-### Optional:
-https://github.com/VenomModding/t5xo-dev
+### Optional:
+
https://github.com/xoxor4d/iw3xo-dev
### Project Page:
@@ -211,7 +211,7 @@ ___
### Effect Browser and Playback

-### In-Editor cod4 based movement with bouncing :>
+### In-Editor bo1 based movement with bouncing :>
