mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-23 17:45:46 +00:00
Compare commits
No commits in common. "main" and "v0.12.1" have entirely different histories.
50
.github/workflows/ci.yaml
vendored
50
.github/workflows/ci.yaml
vendored
@ -8,30 +8,40 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- "main"
|
- "main"
|
||||||
|
|
||||||
|
env:
|
||||||
|
PREMAKE_VERSION: "5.0.0-beta2"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-test-linux:
|
build-test-linux:
|
||||||
|
env:
|
||||||
|
PREMAKE_CONFIG: gmake2
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ubuntu:24.04
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install g++ and multilib
|
|
||||||
run: |
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y wget tar git make gcc-13 g++-13 gcc-13-multilib g++-13-multilib
|
|
||||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13
|
|
||||||
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
|
|
||||||
update-alternatives --set gcc /usr/bin/gcc-13
|
|
||||||
update-alternatives --set g++ /usr/bin/g++-13
|
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Install g++ and multilib
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install gcc-13 g++-13 gcc-13-multilib g++-13-multilib
|
||||||
|
|
||||||
|
- name: Set gcc/g++ to version 13
|
||||||
|
run: |
|
||||||
|
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13
|
||||||
|
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
|
||||||
|
sudo update-alternatives --set gcc /usr/bin/gcc-13
|
||||||
|
sudo update-alternatives --set g++ /usr/bin/g++-13
|
||||||
|
|
||||||
|
- name: Setup premake
|
||||||
|
uses: abel0b/setup-premake@v2.4
|
||||||
|
with:
|
||||||
|
version: ${{ env.PREMAKE_VERSION }}
|
||||||
|
|
||||||
- name: Premake generate
|
- name: Premake generate
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
env:
|
run: premake5 ${{ env.PREMAKE_CONFIG }}
|
||||||
PREMAKE_NO_PROMPT: 1
|
|
||||||
run: ./generate.sh
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
@ -41,13 +51,14 @@ jobs:
|
|||||||
working-directory: ${{ github.workspace }}/build/lib/Release_x86/tests
|
working-directory: ${{ github.workspace }}/build/lib/Release_x86/tests
|
||||||
run: |
|
run: |
|
||||||
./ObjCommonTests
|
./ObjCommonTests
|
||||||
./ObjCompilingTests
|
|
||||||
./ObjLoadingTests
|
./ObjLoadingTests
|
||||||
./ParserTests
|
./ParserTests
|
||||||
./ZoneCodeGeneratorLibTests
|
./ZoneCodeGeneratorLibTests
|
||||||
./ZoneCommonTests
|
./ZoneCommonTests
|
||||||
|
|
||||||
build-test-windows:
|
build-test-windows:
|
||||||
|
env:
|
||||||
|
PREMAKE_CONFIG: vs2022
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@ -58,11 +69,14 @@ jobs:
|
|||||||
- name: Add MSBuild to PATH
|
- name: Add MSBuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v2.0.0
|
uses: microsoft/setup-msbuild@v2.0.0
|
||||||
|
|
||||||
|
- name: Setup premake
|
||||||
|
uses: abel0b/setup-premake@v2.4
|
||||||
|
with:
|
||||||
|
version: ${{ env.PREMAKE_VERSION }}
|
||||||
|
|
||||||
- name: Premake generate
|
- name: Premake generate
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
env:
|
run: premake5 ${{ env.PREMAKE_CONFIG }}
|
||||||
PREMAKE_NO_PROMPT: 1
|
|
||||||
run: ./generate.bat
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
@ -74,8 +88,6 @@ jobs:
|
|||||||
$combinedExitCode = 0
|
$combinedExitCode = 0
|
||||||
./ObjCommonTests
|
./ObjCommonTests
|
||||||
$combinedExitCode = [System.Math]::max($combinedExitCode, $LASTEXITCODE)
|
$combinedExitCode = [System.Math]::max($combinedExitCode, $LASTEXITCODE)
|
||||||
./ObjCompilingTests
|
|
||||||
$combinedExitCode = [System.Math]::max($combinedExitCode, $LASTEXITCODE)
|
|
||||||
./ObjLoadingTests
|
./ObjLoadingTests
|
||||||
$combinedExitCode = [System.Math]::max($combinedExitCode, $LASTEXITCODE)
|
$combinedExitCode = [System.Math]::max($combinedExitCode, $LASTEXITCODE)
|
||||||
./ParserTests
|
./ParserTests
|
||||||
|
55
.github/workflows/release.yaml
vendored
55
.github/workflows/release.yaml
vendored
@ -5,30 +5,40 @@ on:
|
|||||||
tags:
|
tags:
|
||||||
- "v*.*.*"
|
- "v*.*.*"
|
||||||
|
|
||||||
|
env:
|
||||||
|
PREMAKE_VERSION: "5.0.0-beta2"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-release-linux:
|
build-release-linux:
|
||||||
|
env:
|
||||||
|
PREMAKE_CONFIG: gmake2
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container: ubuntu:24.04
|
|
||||||
steps:
|
steps:
|
||||||
- name: Install g++ and multilib
|
|
||||||
run: |
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y wget tar git make gcc-13 g++-13 gcc-13-multilib g++-13-multilib
|
|
||||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13
|
|
||||||
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
|
|
||||||
update-alternatives --set gcc /usr/bin/gcc-13
|
|
||||||
update-alternatives --set g++ /usr/bin/g++-13
|
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Install g++ and multilib
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install gcc-13 g++-13 gcc-13-multilib g++-13-multilib
|
||||||
|
|
||||||
|
- name: Set gcc/g++ to version 13
|
||||||
|
run: |
|
||||||
|
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13
|
||||||
|
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
|
||||||
|
sudo update-alternatives --set gcc /usr/bin/gcc-13
|
||||||
|
sudo update-alternatives --set g++ /usr/bin/g++-13
|
||||||
|
|
||||||
|
- name: Setup premake
|
||||||
|
uses: abel0b/setup-premake@v2.4
|
||||||
|
with:
|
||||||
|
version: ${{ env.PREMAKE_VERSION }}
|
||||||
|
|
||||||
- name: Premake generate
|
- name: Premake generate
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
env:
|
run: premake5 ${{ env.PREMAKE_CONFIG }}
|
||||||
PREMAKE_NO_PROMPT: 1
|
|
||||||
run: ./generate.sh
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
@ -42,6 +52,8 @@ jobs:
|
|||||||
${{ github.workspace }}/build/bin/Release_x86
|
${{ github.workspace }}/build/bin/Release_x86
|
||||||
|
|
||||||
build-release-windows:
|
build-release-windows:
|
||||||
|
env:
|
||||||
|
PREMAKE_CONFIG: vs2022
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@ -52,25 +64,28 @@ jobs:
|
|||||||
- name: Add MSBuild to PATH
|
- name: Add MSBuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v2.0.0
|
uses: microsoft/setup-msbuild@v2.0.0
|
||||||
|
|
||||||
|
- name: Setup premake
|
||||||
|
uses: abel0b/setup-premake@v2.4
|
||||||
|
with:
|
||||||
|
version: ${{ env.PREMAKE_VERSION }}
|
||||||
|
|
||||||
- name: Premake generate
|
- name: Premake generate
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
env:
|
run: premake5 ${{ env.PREMAKE_CONFIG }}
|
||||||
PREMAKE_NO_PROMPT: 1
|
|
||||||
run: ./generate.bat
|
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: ${{ github.workspace }}
|
working-directory: ${{ github.workspace }}
|
||||||
run: msbuild /m /p:Configuration=Release /p:Platform=Win32 build
|
run: msbuild /m /p:Configuration=Release /p:Platform=Win32 build
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: oat-windows
|
name: oat-windows
|
||||||
path: |
|
path: |
|
||||||
${{ github.workspace }}/build/bin/Release_x86
|
${{ github.workspace }}/build/bin/Release_x86
|
||||||
|
|
||||||
release:
|
release:
|
||||||
needs:
|
needs:
|
||||||
- build-release-linux
|
- build-release-linux
|
||||||
- build-release-windows
|
- build-release-windows
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -93,4 +108,4 @@ jobs:
|
|||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
draft: true
|
draft: true
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
omitDraftDuringUpdate: true
|
omitDraftDuringUpdate: true
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -13,9 +13,3 @@
|
|||||||
[submodule "thirdparty/json"]
|
[submodule "thirdparty/json"]
|
||||||
path = thirdparty/json
|
path = thirdparty/json
|
||||||
url = https://github.com/nlohmann/json.git
|
url = https://github.com/nlohmann/json.git
|
||||||
[submodule "thirdparty/eigen"]
|
|
||||||
path = thirdparty/eigen
|
|
||||||
url = https://gitlab.com/libeigen/eigen.git
|
|
||||||
[submodule "thirdparty/lz4"]
|
|
||||||
path = thirdparty/lz4
|
|
||||||
url = https://github.com/lz4/lz4.git
|
|
||||||
|
@ -44,8 +44,6 @@ In fact, I recommend against it to be able to better distinguish OAT files from
|
|||||||
For more information, check out the ["Getting started" guide in the OAT documentation](https://openassettools.dev/guide/getting-started.html).
|
For more information, check out the ["Getting started" guide in the OAT documentation](https://openassettools.dev/guide/getting-started.html).
|
||||||
You can find other useful guides and reference documentation there as well.
|
You can find other useful guides and reference documentation there as well.
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Building OAT
|
## Building OAT
|
||||||
|
|
||||||
You need to clone this repository using Git.
|
You need to clone this repository using Git.
|
||||||
@ -64,7 +62,6 @@ It is hosted on Github Pages and its source can be found in the [OAT Docs Reposi
|
|||||||
For examples of mods that can be built with OAT, you can either look into the [docs folder](docs/example) for some (currently very barebones) examples
|
For examples of mods that can be built with OAT, you can either look into the [docs folder](docs/example) for some (currently very barebones) examples
|
||||||
or check out one of the following projects that are using OAT:
|
or check out one of the following projects that are using OAT:
|
||||||
|
|
||||||
* [OpenAssetTools/Examples](https://github.com/OpenAssetTools/Examples)
|
|
||||||
* [JezuzLizard/t6-fastfile-mods](https://github.com/JezuzLizard/t6-fastfile-mods)
|
* [JezuzLizard/t6-fastfile-mods](https://github.com/JezuzLizard/t6-fastfile-mods)
|
||||||
* [Jbleezy/BO2-Reimagined](https://github.com/Jbleezy/BO2-Reimagined)
|
* [Jbleezy/BO2-Reimagined](https://github.com/Jbleezy/BO2-Reimagined)
|
||||||
* [diamante0018/PlutoIW5Arena](https://github.com/diamante0018/PlutoIW5Arena) (Includes a GitHub action pipeline for building the mod)
|
* [diamante0018/PlutoIW5Arena](https://github.com/diamante0018/PlutoIW5Arena) (Includes a GitHub action pipeline for building the mod)
|
||||||
@ -93,7 +90,7 @@ Since you are most likely on a 64-bit machine you will also need multilib for co
|
|||||||
|
|
||||||
Use `generate.sh` to generate make files.
|
Use `generate.sh` to generate make files.
|
||||||
When this is done you will have a `build` folder with a `Makefile`.
|
When this is done you will have a `build` folder with a `Makefile`.
|
||||||
You now run `make` manually or use `./scripts/make-release.sh` or `./scripts/make-debug.sh` to build.
|
You now run `make` manually or use `./scripts/make_release.sh` or `./scripts/make_debug.sh` to build.
|
||||||
|
|
||||||
The resulting binaries can be found in `build/bin/<Debug_x86|Release_x86>`.
|
The resulting binaries can be found in `build/bin/<Debug_x86|Release_x86>`.
|
||||||
|
|
||||||
|
@ -9,33 +9,33 @@ The following section specify which assets are supported to be dumped to disk (u
|
|||||||
|
|
||||||
## IW3 (Call of Duty 4: Modern Warfare)
|
## IW3 (Call of Duty 4: Modern Warfare)
|
||||||
|
|
||||||
| Asset Type | Dumping Support | Loading Support | Notes |
|
| Asset Type | Dumping Support | Loading Support | Notes |
|
||||||
| -------------------- | --------------- | --------------- | ----------------------------------------------------------------- |
|
| -------------------- | --------------- | --------------- | -------------------------------------------------------- |
|
||||||
| PhysPreset | ❌ | ❌ | |
|
| PhysPreset | ❌ | ❌ | |
|
||||||
| XAnimParts | ❌ | ❌ | |
|
| XAnimParts | ❌ | ❌ | |
|
||||||
| XModel | ⁉️ | ❌ | Model data can be exported to `XMODEL_EXPORT/XMODEL_BIN`, `OBJ`, `GLB/GLTF`. |
|
| XModel | ⁉️ | ❌ | Model data can be exported to `XMODEL_EXPORT` and `OBJ`. |
|
||||||
| Material | ❌ | ❌ | |
|
| Material | ❌ | ❌ | |
|
||||||
| MaterialTechniqueSet | ❌ | ❌ | |
|
| MaterialTechniqueSet | ❌ | ❌ | |
|
||||||
| GfxImage | ✅ | ✅ | |
|
| GfxImage | ✅ | ✅ | |
|
||||||
| snd_alias_list_t | ❌ | ❌ | |
|
| snd_alias_list_t | ❌ | ❌ | |
|
||||||
| SndCurve | ❌ | ❌ | |
|
| SndCurve | ❌ | ❌ | |
|
||||||
| LoadedSound | ✅ | ❌ | |
|
| LoadedSound | ✅ | ❌ | |
|
||||||
| clipMap_t | ❌ | ❌ | |
|
| clipMap_t | ❌ | ❌ | |
|
||||||
| ComWorld | ❌ | ❌ | |
|
| ComWorld | ❌ | ❌ | |
|
||||||
| GameWorldSp | ❌ | ❌ | |
|
| GameWorldSp | ❌ | ❌ | |
|
||||||
| GameWorldMp | ❌ | ❌ | |
|
| GameWorldMp | ❌ | ❌ | |
|
||||||
| MapEnts | ✅ | ❌ | |
|
| MapEnts | ✅ | ❌ | |
|
||||||
| GfxWorld | ❌ | ❌ | |
|
| GfxWorld | ❌ | ❌ | |
|
||||||
| GfxLightDef | ❌ | ❌ | |
|
| GfxLightDef | ❌ | ❌ | |
|
||||||
| Font_s | ❌ | ❌ | |
|
| Font_s | ❌ | ❌ | |
|
||||||
| MenuList | ❌ | ❌ | |
|
| MenuList | ❌ | ❌ | |
|
||||||
| menuDef_t | ❌ | ❌ | |
|
| menuDef_t | ❌ | ❌ | |
|
||||||
| LocalizeEntry | ✅ | ✅ | |
|
| LocalizeEntry | ✅ | ✅ | |
|
||||||
| WeaponDef | ❌ | ❌ | |
|
| WeaponDef | ❌ | ❌ | |
|
||||||
| FxEffectDef | ❌ | ❌ | |
|
| FxEffectDef | ❌ | ❌ | |
|
||||||
| FxImpactTable | ❌ | ❌ | |
|
| FxImpactTable | ❌ | ❌ | |
|
||||||
| RawFile | ✅ | ✅ | |
|
| RawFile | ✅ | ✅ | |
|
||||||
| StringTable | ✅ | ✅ | |
|
| StringTable | ✅ | ✅ | |
|
||||||
|
|
||||||
## IW4 (Call of Duty: Modern Warfare 2)
|
## IW4 (Call of Duty: Modern Warfare 2)
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ The following section specify which assets are supported to be dumped to disk (u
|
|||||||
| PhysPreset | ✅ | ✅ | |
|
| PhysPreset | ✅ | ✅ | |
|
||||||
| PhysCollmap | ❌ | ❌ | |
|
| PhysCollmap | ❌ | ❌ | |
|
||||||
| XAnimParts | ❌ | ❌ | |
|
| XAnimParts | ❌ | ❌ | |
|
||||||
| XModel | ⁉️ | ❌ | Model data can be exported to `XMODEL_EXPORT/XMODEL_BIN`, `OBJ`, `GLB/GLTF`. |
|
| XModel | ⁉️ | ❌ | Model data can be exported to `XMODEL_EXPORT` and `OBJ`. |
|
||||||
| Material | ❌ | ❌ | |
|
| Material | ❌ | ❌ | |
|
||||||
| MaterialPixelShader | ✅ | ✅ | Shaders are compiled. Only dumps/loads shader bytecode. |
|
| MaterialPixelShader | ✅ | ✅ | Shaders are compiled. Only dumps/loads shader bytecode. |
|
||||||
| MaterialVertexShader | ✅ | ✅ | Shaders are compiled. Only dumps/loads shader bytecode. |
|
| MaterialVertexShader | ✅ | ✅ | Shaders are compiled. Only dumps/loads shader bytecode. |
|
||||||
@ -71,7 +71,7 @@ The following section specify which assets are supported to be dumped to disk (u
|
|||||||
| FxImpactTable | ❌ | ❌ | |
|
| FxImpactTable | ❌ | ❌ | |
|
||||||
| RawFile | ✅ | ✅ | |
|
| RawFile | ✅ | ✅ | |
|
||||||
| StringTable | ✅ | ✅ | |
|
| StringTable | ✅ | ✅ | |
|
||||||
| LeaderboardDef | ✅ | ✅ | |
|
| LeaderboardDef | ❌ | ❌ | |
|
||||||
| StructuredDataDefSet | ✅ | ✅ | The format is custom due to lacking information about original format. |
|
| StructuredDataDefSet | ✅ | ✅ | The format is custom due to lacking information about original format. |
|
||||||
| TracerDef | ✅ | ❌ | |
|
| TracerDef | ✅ | ❌ | |
|
||||||
| VehicleDef | ✅ | ❌ | |
|
| VehicleDef | ✅ | ❌ | |
|
||||||
@ -85,7 +85,7 @@ The following section specify which assets are supported to be dumped to disk (u
|
|||||||
| PhysCollmap | ❌ | ❌ | |
|
| PhysCollmap | ❌ | ❌ | |
|
||||||
| XAnimParts | ❌ | ❌ | |
|
| XAnimParts | ❌ | ❌ | |
|
||||||
| XModelSurfs | ❌ | ❌ | |
|
| XModelSurfs | ❌ | ❌ | |
|
||||||
| XModel | ⁉️ | ❌ | Model data can be exported to `XMODEL_EXPORT/XMODEL_BIN`, `OBJ`, `GLB/GLTF`. |
|
| XModel | ⁉️ | ❌ | Model data can be exported to `XMODEL_EXPORT` and `OBJ`. |
|
||||||
| Material | ❌ | ❌ | |
|
| Material | ❌ | ❌ | |
|
||||||
| MaterialPixelShader | ❌ | ❌ | |
|
| MaterialPixelShader | ❌ | ❌ | |
|
||||||
| MaterialVertexShader | ❌ | ❌ | |
|
| MaterialVertexShader | ❌ | ❌ | |
|
||||||
@ -116,7 +116,7 @@ The following section specify which assets are supported to be dumped to disk (u
|
|||||||
| RawFile | ✅ | ✅ | |
|
| RawFile | ✅ | ✅ | |
|
||||||
| ScriptFile | ⁉️ | ⁉️ | Can only be dumped/loaded as binary. Editing is possible with [GSC-Tool](https://github.com/xensik/gsc-tool). |
|
| ScriptFile | ⁉️ | ⁉️ | Can only be dumped/loaded as binary. Editing is possible with [GSC-Tool](https://github.com/xensik/gsc-tool). |
|
||||||
| StringTable | ✅ | ✅ | |
|
| StringTable | ✅ | ✅ | |
|
||||||
| LeaderboardDef | ✅ | ✅ | |
|
| LeaderboardDef | ❌ | ❌ | |
|
||||||
| StructuredDataDefSet | ❌ | ❌ | |
|
| StructuredDataDefSet | ❌ | ❌ | |
|
||||||
| TracerDef | ❌ | ❌ | |
|
| TracerDef | ❌ | ❌ | |
|
||||||
| VehicleDef | ❌ | ❌ | |
|
| VehicleDef | ❌ | ❌ | |
|
||||||
@ -124,40 +124,40 @@ The following section specify which assets are supported to be dumped to disk (u
|
|||||||
|
|
||||||
## T5 (Call of Duty: Black Ops)
|
## T5 (Call of Duty: Black Ops)
|
||||||
|
|
||||||
| Asset Type | Dumping Support | Loading Support | Notes |
|
| Asset Type | Dumping Support | Loading Support | Notes |
|
||||||
| -------------------- | --------------- | --------------- | ----------------------------------------------------------------- |
|
| -------------------- | --------------- | --------------- | -------------------------------------------------------- |
|
||||||
| PhysPreset | ❌ | ❌ | |
|
| PhysPreset | ❌ | ❌ | |
|
||||||
| PhysConstraints | ❌ | ❌ | |
|
| PhysConstraints | ❌ | ❌ | |
|
||||||
| DestructibleDef | ❌ | ❌ | |
|
| DestructibleDef | ❌ | ❌ | |
|
||||||
| XAnimParts | ❌ | ❌ | |
|
| XAnimParts | ❌ | ❌ | |
|
||||||
| XModel | ⁉️ | ❌ | Model data can be exported to `XMODEL_EXPORT/XMODEL_BIN`, `OBJ`, `GLB/GLTF`. |
|
| XModel | ⁉️ | ❌ | Model data can be exported to `XMODEL_EXPORT` and `OBJ`. |
|
||||||
| Material | ❌ | ❌ | |
|
| Material | ❌ | ❌ | |
|
||||||
| MaterialTechniqueSet | ❌ | ❌ | |
|
| MaterialTechniqueSet | ❌ | ❌ | |
|
||||||
| GfxImage | ✅ | ❌ | A few special image encodings are not yet supported. |
|
| GfxImage | ✅ | ❌ | A few special image encodings are not yet supported. |
|
||||||
| SndBank | ❌ | ❌ | |
|
| SndBank | ❌ | ❌ | |
|
||||||
| SndPatch | ❌ | ❌ | |
|
| SndPatch | ❌ | ❌ | |
|
||||||
| clipMap_t | ❌ | ❌ | |
|
| clipMap_t | ❌ | ❌ | |
|
||||||
| ComWorld | ❌ | ❌ | |
|
| ComWorld | ❌ | ❌ | |
|
||||||
| GameWorldSp | ❌ | ❌ | |
|
| GameWorldSp | ❌ | ❌ | |
|
||||||
| GameWorldMp | ❌ | ❌ | |
|
| GameWorldMp | ❌ | ❌ | |
|
||||||
| MapEnts | ❌ | ❌ | |
|
| MapEnts | ❌ | ❌ | |
|
||||||
| GfxWorld | ❌ | ❌ | |
|
| GfxWorld | ❌ | ❌ | |
|
||||||
| GfxLightDef | ❌ | ❌ | |
|
| GfxLightDef | ❌ | ❌ | |
|
||||||
| Font_s | ❌ | ❌ | |
|
| Font_s | ❌ | ❌ | |
|
||||||
| MenuList | ❌ | ❌ | |
|
| MenuList | ❌ | ❌ | |
|
||||||
| menuDef_t | ❌ | ❌ | |
|
| menuDef_t | ❌ | ❌ | |
|
||||||
| LocalizeEntry | ✅ | ✅ | |
|
| LocalizeEntry | ✅ | ✅ | |
|
||||||
| WeaponVariantDef | ❌ | ❌ | |
|
| WeaponVariantDef | ❌ | ❌ | |
|
||||||
| SndDriverGlobals | ❌ | ❌ | |
|
| SndDriverGlobals | ❌ | ❌ | |
|
||||||
| FxEffectDef | ❌ | ❌ | |
|
| FxEffectDef | ❌ | ❌ | |
|
||||||
| FxImpactTable | ❌ | ❌ | |
|
| FxImpactTable | ❌ | ❌ | |
|
||||||
| RawFile | ✅ | ✅ | |
|
| RawFile | ✅ | ✅ | |
|
||||||
| StringTable | ✅ | ✅ | |
|
| StringTable | ✅ | ✅ | |
|
||||||
| PackIndex | ❌ | ❌ | |
|
| PackIndex | ❌ | ❌ | |
|
||||||
| XGlobals | ❌ | ❌ | |
|
| XGlobals | ❌ | ❌ | |
|
||||||
| ddlRoot_t | ❌ | ❌ | |
|
| ddlRoot_t | ❌ | ❌ | |
|
||||||
| Glasses | ❌ | ❌ | |
|
| Glasses | ❌ | ❌ | |
|
||||||
| EmblemSet | ❌ | ❌ | |
|
| EmblemSet | ❌ | ❌ | |
|
||||||
|
|
||||||
## T6 (Call of Duty: Black Ops II)
|
## T6 (Call of Duty: Black Ops II)
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ The following section specify which assets are supported to be dumped to disk (u
|
|||||||
| PhysConstraints | ✅ | ✅ | |
|
| PhysConstraints | ✅ | ✅ | |
|
||||||
| DestructibleDef | ❌ | ❌ | |
|
| DestructibleDef | ❌ | ❌ | |
|
||||||
| XAnimParts | ❌ | ❌ | |
|
| XAnimParts | ❌ | ❌ | |
|
||||||
| XModel | ✅ | ✅ | Model data can be exported to `XMODEL_EXPORT/XMODEL_BIN`, `OBJ`, `GLB/GLTF`. |
|
| XModel | ⁉️ | ❌ | Model data can be exported to `XMODEL_EXPORT` and `OBJ`. |
|
||||||
| Material | ⁉️ | ⁉️ | Dumping/Loading is currently possible for materials in their compiled form. There is currently no material pipeline. |
|
| Material | ⁉️ | ⁉️ | Dumping/Loading is currently possible for materials in their compiled form. There is currently no material pipeline. |
|
||||||
| MaterialTechniqueSet | ⁉️ | ❌ | Only dumps compiled shaders. |
|
| MaterialTechniqueSet | ⁉️ | ❌ | Only dumps compiled shaders. |
|
||||||
| GfxImage | ✅ | ✅ | A few special image encodings are not yet supported. |
|
| GfxImage | ✅ | ✅ | A few special image encodings are not yet supported. |
|
||||||
@ -177,7 +177,7 @@ The following section specify which assets are supported to be dumped to disk (u
|
|||||||
| ComWorld | ❌ | ❌ | |
|
| ComWorld | ❌ | ❌ | |
|
||||||
| GameWorldSp | ❌ | ❌ | |
|
| GameWorldSp | ❌ | ❌ | |
|
||||||
| GameWorldMp | ❌ | ❌ | |
|
| GameWorldMp | ❌ | ❌ | |
|
||||||
| MapEnts | ✅ | ❌ | |
|
| MapEnts | ❌ | ❌ | |
|
||||||
| GfxWorld | ❌ | ❌ | |
|
| GfxWorld | ❌ | ❌ | |
|
||||||
| GfxLightDef | ❌ | ❌ | |
|
| GfxLightDef | ❌ | ❌ | |
|
||||||
| Font_s | ❌ | ❌ | |
|
| Font_s | ❌ | ❌ | |
|
||||||
@ -194,7 +194,7 @@ The following section specify which assets are supported to be dumped to disk (u
|
|||||||
| FxImpactTable | ❌ | ❌ | |
|
| FxImpactTable | ❌ | ❌ | |
|
||||||
| RawFile | ✅ | ✅ | |
|
| RawFile | ✅ | ✅ | |
|
||||||
| StringTable | ✅ | ✅ | |
|
| StringTable | ✅ | ✅ | |
|
||||||
| LeaderboardDef | ✅ | ✅ | |
|
| LeaderboardDef | ❌ | ❌ | |
|
||||||
| XGlobals | ❌ | ❌ | |
|
| XGlobals | ❌ | ❌ | |
|
||||||
| ddlRoot_t | ❌ | ❌ | |
|
| ddlRoot_t | ❌ | ❌ | |
|
||||||
| Glasses | ❌ | ❌ | |
|
| Glasses | ❌ | ❌ | |
|
||||||
|
84
generate.bat
84
generate.bat
@ -1,88 +1,6 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
set PREMAKE_URL="https://github.com/premake/premake-core/releases/download/v5.0.0-beta6/premake-5.0.0-beta6-windows.zip"
|
|
||||||
set PREMAKE_HASH="c34a6e0b15f119f6284886298fdd8df543af87ad16f3ce5f4d0a847be2a88343"
|
|
||||||
|
|
||||||
@REM The following variables can be set:
|
|
||||||
@REM PREMAKE_NO_GLOBAL - Ignore premake5 executable from path
|
|
||||||
@REM PREMAKE_NO_PROMPT - Download premake5 without prompting
|
|
||||||
|
|
||||||
goto start
|
|
||||||
|
|
||||||
:downloadpremake
|
|
||||||
|
|
||||||
if not exist "build" mkdir "build"
|
|
||||||
|
|
||||||
where /q "pwsh"
|
|
||||||
IF NOT ERRORLEVEL 1 (
|
|
||||||
set POWERSHELL_BIN="pwsh"
|
|
||||||
) else (
|
|
||||||
set POWERSHELL_BIN="powershell"
|
|
||||||
)
|
|
||||||
|
|
||||||
echo Downloading...
|
|
||||||
%POWERSHELL_BIN% -NoProfile -NonInteractive -Command "Invoke-WebRequest %PREMAKE_URL% -OutFile build/premake.zip"
|
|
||||||
IF ERRORLEVEL 1 (
|
|
||||||
echo Download failed >&2
|
|
||||||
exit 2
|
|
||||||
)
|
|
||||||
|
|
||||||
echo Extracting...
|
|
||||||
%POWERSHELL_BIN% -NoProfile -NonInteractive -Command "Expand-Archive -LiteralPath build/premake.zip -DestinationPath build -Force"
|
|
||||||
IF ERRORLEVEL 1 (
|
|
||||||
echo Extraction failed >&2
|
|
||||||
exit 2
|
|
||||||
)
|
|
||||||
|
|
||||||
rm build/premake.zip
|
|
||||||
|
|
||||||
echo Verifying hash...
|
|
||||||
%POWERSHELL_BIN% -NoProfile -NonInteractive -Command "if ((Get-FileHash -LiteralPath build/premake5.exe -Algorithm SHA256).Hash -eq \"%PREMAKE_HASH%\") { exit 0 } else { exit 1 }"
|
|
||||||
IF ERRORLEVEL 1 (
|
|
||||||
echo Hash verification failed >&2
|
|
||||||
rm build/premake5.exe
|
|
||||||
exit 2
|
|
||||||
)
|
|
||||||
|
|
||||||
exit /B 0
|
|
||||||
|
|
||||||
cd %~dp0
|
cd %~dp0
|
||||||
|
|
||||||
:start
|
|
||||||
|
|
||||||
IF "%PREMAKE_NO_GLOBAL%" EQU "" (
|
|
||||||
where /Q "premake5.exe"
|
|
||||||
IF NOT ERRORLEVEL 1 (
|
|
||||||
set PREMAKE_BIN="premake5.exe"
|
|
||||||
goto runpremake
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
IF EXIST build/premake5.exe (
|
|
||||||
build\premake5.exe --version >NUL
|
|
||||||
IF NOT ERRORLEVEL 1 (
|
|
||||||
set PREMAKE_BIN="build/premake5.exe"
|
|
||||||
goto runpremake
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%PREMAKE_NO_PROMPT%" NEQ "" (
|
|
||||||
call:downloadpremake
|
|
||||||
set PREMAKE_BIN="build/premake5.exe"
|
|
||||||
goto runpremake
|
|
||||||
)
|
|
||||||
|
|
||||||
echo Could not find premake5. You can either install it yourself or this script download it for you.
|
|
||||||
set /p choice="Do you wish to download it automatically? [y/N]> "
|
|
||||||
if /i "%choice%" == "y" (
|
|
||||||
call:downloadpremake
|
|
||||||
set PREMAKE_BIN="build/premake5.exe"
|
|
||||||
goto runpremake
|
|
||||||
)
|
|
||||||
|
|
||||||
echo Please install premake5 and try again
|
|
||||||
exit 1
|
|
||||||
|
|
||||||
:runpremake
|
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
%PREMAKE_BIN% %* vs2022
|
tools\premake5.exe %* vs2022
|
75
generate.sh
75
generate.sh
@ -1,80 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
PREMAKE_URL='https://github.com/premake/premake-core/releases/download/v5.0.0-beta6/premake-5.0.0-beta6-linux.tar.gz'
|
|
||||||
PREMAKE_HASH='fade2839ace1a2953556693e6f3d8f9b8b2897894b5a1f2ad477cdf8e9af042a'
|
|
||||||
|
|
||||||
# The following variables can be set:
|
|
||||||
# PREMAKE_NO_GLOBAL - Ignore premake5 executable from path
|
|
||||||
# PREMAKE_NO_PROMPT - Download premake5 without prompting
|
|
||||||
|
|
||||||
function install_premake {
|
|
||||||
if [[ ! -x "$(command -v wget)" ]]; then
|
|
||||||
echo "Failed: Installation requires wget" >&2
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
if [[ ! -x "$(command -v tar)" ]]; then
|
|
||||||
echo "Failed: Installation requires tar" >&2
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
if [[ ! -x "$(command -v sha256sum)" ]]; then
|
|
||||||
echo "Failed: Installation requires sha256sum" >&2
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p build
|
|
||||||
wget -nd -O build/premake.tar.gz "$PREMAKE_URL"
|
|
||||||
if [[ $? -ne 0 ]]; then
|
|
||||||
echo "Download failed" >&2
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
tar -xf build/premake.tar.gz -C build
|
|
||||||
if [[ $? -ne 0 ]]; then
|
|
||||||
echo "Extraction failed" >&2
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm build/premake.tar.gz
|
|
||||||
|
|
||||||
echo "${PREMAKE_HASH} build/premake5" | sha256sum -c
|
|
||||||
if [[ $? -ne 0 ]]; then
|
|
||||||
echo "Hash verification failed" >&2
|
|
||||||
rm build/premake5
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
chmod +x build/premake5
|
|
||||||
}
|
|
||||||
|
|
||||||
function expect_inside_git_repository {
|
|
||||||
inside_git_repo="$(git rev-parse --is-inside-work-tree 2>/dev/null)"
|
|
||||||
if [ ! -d ".git" ] && [ ! "$inside_git_repo" ]; then
|
|
||||||
echo "You must clone the OpenAssetTools repository using 'git clone'. Please read README.md." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Go to repository root
|
# Go to repository root
|
||||||
cd "$(dirname "$0")" || exit 2
|
cd "$(dirname "$0")" || exit 2
|
||||||
|
|
||||||
expect_inside_git_repository
|
|
||||||
|
|
||||||
PREMAKE_BIN=''
|
|
||||||
if [[ -z "$PREMAKE_NO_GLOBAL" ]] && [[ -x "$(command -v premake5)" ]]; then
|
|
||||||
PREMAKE_BIN='premake5'
|
|
||||||
elif [[ -x "$(command -v build/premake5)" ]] && [[ ! -z "$(build/premake5 --version)" ]]; then
|
|
||||||
PREMAKE_BIN='build/premake5'
|
|
||||||
else
|
|
||||||
echo "Could not find premake5. You can either install it yourself or this script download it for you."
|
|
||||||
if [[ ! -z "$PREMAKE_NO_PROMPT" ]] || [[ "$(read -e -p 'Do you wish to download it automatically? [y/N]> '; echo $REPLY)" == [Yy]* ]]; then
|
|
||||||
echo "Installing premake"
|
|
||||||
install_premake
|
|
||||||
PREMAKE_BIN='build/premake5'
|
|
||||||
else
|
|
||||||
echo "Please install premake5 and try again"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
$PREMAKE_BIN $@ gmake
|
tools/premake5 $@ gmake2
|
29
premake5.lua
29
premake5.lua
@ -1,12 +1,9 @@
|
|||||||
require("premake", ">=5.0.0-beta5")
|
|
||||||
|
|
||||||
include "tools/scripts/folders.lua"
|
include "tools/scripts/folders.lua"
|
||||||
include "tools/scripts/including.lua"
|
include "tools/scripts/including.lua"
|
||||||
include "tools/scripts/linking.lua"
|
include "tools/scripts/linking.lua"
|
||||||
include "tools/scripts/options.lua"
|
include "tools/scripts/options.lua"
|
||||||
include "tools/scripts/platform.lua"
|
include "tools/scripts/platform.lua"
|
||||||
include "tools/scripts/version.lua"
|
include "tools/scripts/version.lua"
|
||||||
include "tools/scripts/source_templating.lua"
|
|
||||||
|
|
||||||
-- ==================
|
-- ==================
|
||||||
-- Workspace
|
-- Workspace
|
||||||
@ -16,7 +13,7 @@ workspace "OpenAssetTools"
|
|||||||
objdir "%{wks.location}/obj"
|
objdir "%{wks.location}/obj"
|
||||||
symbols "On"
|
symbols "On"
|
||||||
systemversion "latest"
|
systemversion "latest"
|
||||||
cppdialect "C++23"
|
cppdialect "C++20"
|
||||||
largeaddressaware "on"
|
largeaddressaware "on"
|
||||||
|
|
||||||
flags {
|
flags {
|
||||||
@ -54,15 +51,13 @@ workspace "OpenAssetTools"
|
|||||||
symbols "On"
|
symbols "On"
|
||||||
filter {}
|
filter {}
|
||||||
|
|
||||||
filter {"system:windows", "configurations:Debug" }
|
|
||||||
buildoptions { "/bigobj" }
|
|
||||||
filter {}
|
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
defines "NDEBUG"
|
defines "NDEBUG"
|
||||||
optimize "Full"
|
optimize "Full"
|
||||||
symbols "Off"
|
symbols "Off"
|
||||||
fatalwarnings { "All" }
|
flags {
|
||||||
|
"FatalWarnings"
|
||||||
|
}
|
||||||
filter {}
|
filter {}
|
||||||
|
|
||||||
defines {
|
defines {
|
||||||
@ -89,7 +84,6 @@ workspace "OpenAssetTools"
|
|||||||
-- ThirdParty
|
-- ThirdParty
|
||||||
-- ========================
|
-- ========================
|
||||||
include "thirdparty/catch2.lua"
|
include "thirdparty/catch2.lua"
|
||||||
include "thirdparty/eigen.lua"
|
|
||||||
include "thirdparty/libtomcrypt.lua"
|
include "thirdparty/libtomcrypt.lua"
|
||||||
include "thirdparty/libtommath.lua"
|
include "thirdparty/libtommath.lua"
|
||||||
include "thirdparty/json.lua"
|
include "thirdparty/json.lua"
|
||||||
@ -97,12 +91,10 @@ include "thirdparty/minilzo.lua"
|
|||||||
include "thirdparty/minizip.lua"
|
include "thirdparty/minizip.lua"
|
||||||
include "thirdparty/salsa20.lua"
|
include "thirdparty/salsa20.lua"
|
||||||
include "thirdparty/zlib.lua"
|
include "thirdparty/zlib.lua"
|
||||||
include "thirdparty/lz4.lua"
|
|
||||||
|
|
||||||
-- ThirdParty group: All projects that are external dependencies
|
-- ThirdParty group: All projects that are external dependencies
|
||||||
group "ThirdParty"
|
group "ThirdParty"
|
||||||
catch2:project()
|
catch2:project()
|
||||||
eigen:project()
|
|
||||||
libtommath:project()
|
libtommath:project()
|
||||||
libtomcrypt:project()
|
libtomcrypt:project()
|
||||||
json:project()
|
json:project()
|
||||||
@ -110,7 +102,6 @@ group "ThirdParty"
|
|||||||
minizip:project()
|
minizip:project()
|
||||||
salsa20:project()
|
salsa20:project()
|
||||||
zlib:project()
|
zlib:project()
|
||||||
lz4:project()
|
|
||||||
group ""
|
group ""
|
||||||
|
|
||||||
-- ========================
|
-- ========================
|
||||||
@ -118,7 +109,6 @@ group ""
|
|||||||
-- ========================
|
-- ========================
|
||||||
include "src/Common.lua"
|
include "src/Common.lua"
|
||||||
include "src/Crypto.lua"
|
include "src/Crypto.lua"
|
||||||
include "src/ImageConverter.lua"
|
|
||||||
include "src/Linker.lua"
|
include "src/Linker.lua"
|
||||||
include "src/Parser.lua"
|
include "src/Parser.lua"
|
||||||
include "src/RawTemplater.lua"
|
include "src/RawTemplater.lua"
|
||||||
@ -132,8 +122,6 @@ include "src/ZoneLoading.lua"
|
|||||||
include "src/ZoneWriting.lua"
|
include "src/ZoneWriting.lua"
|
||||||
include "src/ZoneCommon.lua"
|
include "src/ZoneCommon.lua"
|
||||||
include "src/ObjCommon.lua"
|
include "src/ObjCommon.lua"
|
||||||
include "src/ObjCompiling.lua"
|
|
||||||
include "src/ObjImage.lua"
|
|
||||||
include "src/ObjLoading.lua"
|
include "src/ObjLoading.lua"
|
||||||
include "src/ObjWriting.lua"
|
include "src/ObjWriting.lua"
|
||||||
include "tools/scripts/raw.lua"
|
include "tools/scripts/raw.lua"
|
||||||
@ -150,8 +138,6 @@ group "Components"
|
|||||||
ZoneLoading:project()
|
ZoneLoading:project()
|
||||||
ZoneWriting:project()
|
ZoneWriting:project()
|
||||||
ObjCommon:project()
|
ObjCommon:project()
|
||||||
ObjCompiling:project()
|
|
||||||
ObjImage:project()
|
|
||||||
ObjLoading:project()
|
ObjLoading:project()
|
||||||
ObjWriting:project()
|
ObjWriting:project()
|
||||||
group ""
|
group ""
|
||||||
@ -166,7 +152,6 @@ group ""
|
|||||||
group "Tools"
|
group "Tools"
|
||||||
Linker:project()
|
Linker:project()
|
||||||
Unlinker:project()
|
Unlinker:project()
|
||||||
ImageConverter:project()
|
|
||||||
group ""
|
group ""
|
||||||
|
|
||||||
group "Raw"
|
group "Raw"
|
||||||
@ -176,10 +161,7 @@ group ""
|
|||||||
-- ========================
|
-- ========================
|
||||||
-- Tests
|
-- Tests
|
||||||
-- ========================
|
-- ========================
|
||||||
include "test/Catch2Common.lua"
|
|
||||||
include "test/ObjCommonTestUtils.lua"
|
|
||||||
include "test/ObjCommonTests.lua"
|
include "test/ObjCommonTests.lua"
|
||||||
include "test/ObjCompilingTests.lua"
|
|
||||||
include "test/ObjLoadingTests.lua"
|
include "test/ObjLoadingTests.lua"
|
||||||
include "test/ParserTestUtils.lua"
|
include "test/ParserTestUtils.lua"
|
||||||
include "test/ParserTests.lua"
|
include "test/ParserTests.lua"
|
||||||
@ -188,10 +170,7 @@ include "test/ZoneCommonTests.lua"
|
|||||||
|
|
||||||
-- Tests group: Unit test and other tests projects
|
-- Tests group: Unit test and other tests projects
|
||||||
group "Tests"
|
group "Tests"
|
||||||
Catch2Common:project()
|
|
||||||
ObjCommonTestUtils:project()
|
|
||||||
ObjCommonTests:project()
|
ObjCommonTests:project()
|
||||||
ObjCompilingTests:project()
|
|
||||||
ObjLoadingTests:project()
|
ObjLoadingTests:project()
|
||||||
ParserTestUtils:project()
|
ParserTestUtils:project()
|
||||||
ParserTests:project()
|
ParserTests:project()
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
J_Hip_RI,right_leg_upper
|
|
||||||
J_Hip_LE,left_leg_upper
|
|
||||||
J_Knee_RI,right_leg_lower
|
|
||||||
J_SpineUpper,torso_upper
|
|
||||||
J_Knee_LE,left_leg_lower
|
|
||||||
J_Ankle_RI,right_foot
|
|
||||||
J_Ankle_LE,left_foot
|
|
||||||
J_Clavicle_RI,torso_upper
|
|
||||||
J_Clavicle_LE,torso_upper
|
|
||||||
J_Shoulder_RI,right_arm_upper
|
|
||||||
J_Shoulder_LE,left_arm_upper
|
|
||||||
J_Neck,neck
|
|
||||||
J_Head,head
|
|
||||||
J_Elbow_RI,right_arm_lower
|
|
||||||
J_Elbow_LE,left_arm_lower
|
|
||||||
J_Wrist_RI,right_hand
|
|
||||||
J_Wrist_LE,left_hand
|
|
||||||
J_MainRoot,torso_lower
|
|
||||||
TAG_WEAPON_LEFT,gun
|
|
||||||
TAG_WEAPON_RIGHT,gun
|
|
||||||
J_Helmet,helmet
|
|
|
@ -1,19 +0,0 @@
|
|||||||
J_Hip_RI,right_leg_upper
|
|
||||||
J_Hip_LE,left_leg_upper
|
|
||||||
J_Knee_RI,right_leg_lower
|
|
||||||
J_SpineUpper,torso_lower
|
|
||||||
J_SpineLower,torso_lower
|
|
||||||
J_MainRoot,torso_lower
|
|
||||||
J_Knee_LE,left_leg_lower
|
|
||||||
J_Ankle_RI,right_foot
|
|
||||||
J_Ankle_LE,left_foot
|
|
||||||
J_Clavicle_RI,torso_upper
|
|
||||||
J_Clavicle_LE,torso_upper
|
|
||||||
J_Shoulder_RI,right_arm_upper
|
|
||||||
J_Shoulder_LE,left_arm_upper
|
|
||||||
J_Neck,neck
|
|
||||||
J_Head,head
|
|
||||||
J_Elbow_RI,right_arm_lower
|
|
||||||
J_Elbow_LE,left_arm_lower
|
|
||||||
J_Wrist_RI,right_hand
|
|
||||||
J_Wrist_LE,left_hand
|
|
|
@ -1,21 +0,0 @@
|
|||||||
J_Hip_RI,right_leg_upper
|
|
||||||
J_Hip_LE,left_leg_upper
|
|
||||||
J_Knee_RI,right_leg_lower
|
|
||||||
J_SpineUpper,torso_upper
|
|
||||||
J_Knee_LE,left_leg_lower
|
|
||||||
J_Ankle_RI,right_foot
|
|
||||||
J_Ankle_LE,left_foot
|
|
||||||
J_Clavicle_RI,torso_upper
|
|
||||||
J_Clavicle_LE,torso_upper
|
|
||||||
J_Shoulder_RI,right_arm_upper
|
|
||||||
J_Shoulder_LE,left_arm_upper
|
|
||||||
J_Neck,neck
|
|
||||||
J_Head,head
|
|
||||||
J_Elbow_RI,right_arm_lower
|
|
||||||
J_Elbow_LE,left_arm_lower
|
|
||||||
J_Wrist_RI,right_hand
|
|
||||||
J_Wrist_LE,left_hand
|
|
||||||
J_MainRoot,torso_lower
|
|
||||||
TAG_WEAPON_LEFT,gun
|
|
||||||
TAG_WEAPON_RIGHT,gun
|
|
||||||
J_Helmet,helmet
|
|
|
@ -1,19 +0,0 @@
|
|||||||
J_Hip_RI,right_leg_upper
|
|
||||||
J_Hip_LE,left_leg_upper
|
|
||||||
J_Knee_RI,right_leg_lower
|
|
||||||
J_SpineUpper,torso_lower
|
|
||||||
J_SpineLower,torso_lower
|
|
||||||
J_MainRoot,torso_lower
|
|
||||||
J_Knee_LE,left_leg_lower
|
|
||||||
J_Ankle_RI,right_foot
|
|
||||||
J_Ankle_LE,left_foot
|
|
||||||
J_Clavicle_RI,torso_upper
|
|
||||||
J_Clavicle_LE,torso_upper
|
|
||||||
J_Shoulder_RI,right_arm_upper
|
|
||||||
J_Shoulder_LE,left_arm_upper
|
|
||||||
J_Neck,neck
|
|
||||||
J_Head,head
|
|
||||||
J_Elbow_RI,right_arm_lower
|
|
||||||
J_Elbow_LE,left_arm_lower
|
|
||||||
J_Wrist_RI,right_hand
|
|
||||||
J_Wrist_LE,left_hand
|
|
|
@ -1,23 +0,0 @@
|
|||||||
j_helmet,helmet
|
|
||||||
j_head,head
|
|
||||||
j_neck,neck
|
|
||||||
j_clavicle_le,torso_upper
|
|
||||||
j_clavicle_ri,torso_upper
|
|
||||||
j_spineupper,torso_upper
|
|
||||||
j_mainroot,torso_lower
|
|
||||||
j_shoulder_ri,right_arm_upper
|
|
||||||
j_shoulder_le,left_arm_upper
|
|
||||||
j_elbow_ri,right_arm_lower
|
|
||||||
j_elbow_le,left_arm_lower
|
|
||||||
j_wrist_ri,right_hand
|
|
||||||
j_wrist_le,left_hand
|
|
||||||
j_hip_ri,right_leg_upper
|
|
||||||
j_hip_le,left_leg_upper
|
|
||||||
j_knee_ri,right_leg_lower
|
|
||||||
j_knee_le,left_leg_lower
|
|
||||||
j_ankle_ri,right_foot
|
|
||||||
j_ankle_le,left_foot
|
|
||||||
tag_weapon_left,gun
|
|
||||||
tag_weapon_right,gun
|
|
||||||
tag_stowed_back,shield
|
|
||||||
tag_weapon_left,shield
|
|
|
@ -1,23 +0,0 @@
|
|||||||
j_helmet,helmet
|
|
||||||
j_head,head
|
|
||||||
j_neck,neck
|
|
||||||
j_clavicle_le,torso_upper
|
|
||||||
j_clavicle_ri,torso_upper
|
|
||||||
j_spineupper,torso_middle
|
|
||||||
j_mainroot,torso_lower
|
|
||||||
j_shoulder_ri,right_arm_upper
|
|
||||||
j_shoulder_le,left_arm_upper
|
|
||||||
j_elbow_ri,right_arm_lower
|
|
||||||
j_elbow_le,left_arm_lower
|
|
||||||
j_wrist_ri,right_hand
|
|
||||||
j_wrist_le,left_hand
|
|
||||||
j_hip_ri,right_leg_upper
|
|
||||||
j_hip_le,left_leg_upper
|
|
||||||
j_knee_ri,right_leg_lower
|
|
||||||
j_knee_le,left_leg_lower
|
|
||||||
j_ankle_ri,right_foot
|
|
||||||
j_ankle_le,left_foot
|
|
||||||
tag_weapon_left,gun
|
|
||||||
tag_weapon_right,gun
|
|
||||||
tag_stowed_back,shield
|
|
||||||
tag_weapon_left,shield
|
|
|
Binary file not shown.
Before Width: | Height: | Size: 814 KiB |
@ -1,23 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Go to repository root
|
|
||||||
cd "$(dirname "$0")/.." || exit 2
|
|
||||||
|
|
||||||
TARGET='all'
|
|
||||||
ARCHITECTURE='x86'
|
|
||||||
CONFIG='debug'
|
|
||||||
|
|
||||||
for var in "$@"
|
|
||||||
do
|
|
||||||
if [ "$var" == "debug" ] || [ "$var" == "release" ]; then
|
|
||||||
CONFIG="$var"
|
|
||||||
elif [ "$var" == "x86" ] || [ "$var" == "x64" ]; then
|
|
||||||
ARCHITECTURE="$var"
|
|
||||||
else
|
|
||||||
TARGET="$var"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Building config=${CONFIG} architecture=${ARCHITECTURE} target=${TARGET}"
|
|
||||||
make -C build -j$(nproc) config=${CONFIG}_${ARCHITECTURE} "${TARGET}"
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Go to repository root
|
|
||||||
cd "$(dirname "$0")/.." || exit 2
|
|
||||||
|
|
||||||
docker run --rm -v ".:/code" --user "$(id -u):$(id -g)" silkeh/clang:17 /code/scripts/check-format.sh
|
|
@ -4,6 +4,4 @@
|
|||||||
cd "$(dirname "$0")/.." || exit 2
|
cd "$(dirname "$0")/.." || exit 2
|
||||||
|
|
||||||
make -C build -j$(nproc) config=debug_x86 clean
|
make -C build -j$(nproc) config=debug_x86 clean
|
||||||
make -C build -j$(nproc) config=release_x86 clean
|
make -C build -j$(nproc) config=release_x86 clean
|
||||||
make -C build -j$(nproc) config=debug_x64 clean
|
|
||||||
make -C build -j$(nproc) config=release_x64 clean
|
|
@ -3,4 +3,4 @@
|
|||||||
# Go to repository root
|
# Go to repository root
|
||||||
cd "$(dirname "$0")/.." || exit 2
|
cd "$(dirname "$0")/.." || exit 2
|
||||||
|
|
||||||
make -C build -j$(nproc) config=debug_x86 all
|
make -C build -j$(nproc) config=debug_x86 all
|
@ -4,4 +4,4 @@
|
|||||||
cd "$(dirname "$0")/.." || exit 2
|
cd "$(dirname "$0")/.." || exit 2
|
||||||
|
|
||||||
echo "Start building with $(nproc) threads"
|
echo "Start building with $(nproc) threads"
|
||||||
make -C build -j$(nproc) config=release_x86 all
|
make -C build -j$(nproc) config=release_x86 all
|
@ -1,6 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Go to repository root
|
|
||||||
cd "$(dirname "$0")/.." || exit 2
|
|
||||||
|
|
||||||
docker run --rm -v ".:/code" --user "$(id -u):$(id -g)" silkeh/clang:17 /code/scripts/reformat-all.sh
|
|
@ -1,56 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Zone/ZoneTypes.h"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
struct IAssetBase
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template<asset_type_t AssetTypeEnum, typename AssetType> class Asset : IAssetBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static constexpr auto EnumEntry = AssetTypeEnum;
|
|
||||||
using Type = AssetType;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename AssetType> struct AssetNameAccessor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static_assert(std::is_base_of_v<IAssetBase, AssetType>);
|
|
||||||
// static constexpr bool IS_SINGLETON = false;
|
|
||||||
|
|
||||||
// const char*& operator()(AssetType::Type& asset)
|
|
||||||
// {
|
|
||||||
// throw std::runtime_error("Not implemented");
|
|
||||||
// }
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DEFINE_ASSET_NAME_ACCESSOR(assetType, nameProperty) \
|
|
||||||
template<> struct AssetNameAccessor<assetType> \
|
|
||||||
{ \
|
|
||||||
public: \
|
|
||||||
static_assert(std::is_base_of_v<IAssetBase, assetType>); \
|
|
||||||
static constexpr bool IS_SINGLETON = false; \
|
|
||||||
\
|
|
||||||
const char*& operator()(assetType::Type& asset) \
|
|
||||||
{ \
|
|
||||||
return asset.nameProperty; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEFINE_ASSET_NAME_ACCESSOR_SINGLETON(assetType, singletonName) \
|
|
||||||
template<> struct AssetNameAccessor<assetType> \
|
|
||||||
{ \
|
|
||||||
public: \
|
|
||||||
static_assert(std::is_base_of_v<IAssetBase, assetType>); \
|
|
||||||
static constexpr bool IS_SINGLETON = true; \
|
|
||||||
\
|
|
||||||
const char* const& operator()(assetType::Type& asset) \
|
|
||||||
{ \
|
|
||||||
static const char* NAME = singletonName; \
|
|
||||||
return NAME; \
|
|
||||||
} \
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#include "IGame.h"
|
|
||||||
|
|
||||||
#include "IW3/GameIW3.h"
|
|
||||||
#include "IW4/GameIW4.h"
|
|
||||||
#include "IW5/GameIW5.h"
|
|
||||||
#include "T5/GameT5.h"
|
|
||||||
#include "T6/GameT6.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
IGame* IGame::GetGameById(GameId gameId)
|
|
||||||
{
|
|
||||||
static IGame* games[static_cast<unsigned>(GameId::COUNT)]{
|
|
||||||
new IW3::Game(),
|
|
||||||
new IW4::Game(),
|
|
||||||
new IW5::Game(),
|
|
||||||
new T5::Game(),
|
|
||||||
new T6::Game(),
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(static_cast<unsigned>(gameId) < static_cast<unsigned>(GameId::COUNT));
|
|
||||||
auto* result = games[static_cast<unsigned>(gameId)];
|
|
||||||
assert(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,31 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "GameLanguage.h"
|
#include "GameLanguage.h"
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class Zone;
|
class Zone;
|
||||||
|
|
||||||
enum class GameId
|
|
||||||
{
|
|
||||||
IW3,
|
|
||||||
IW4,
|
|
||||||
IW5,
|
|
||||||
T5,
|
|
||||||
T6,
|
|
||||||
|
|
||||||
COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr const char* GameId_Names[]{
|
|
||||||
"IW3",
|
|
||||||
"IW4",
|
|
||||||
"IW5",
|
|
||||||
"T5",
|
|
||||||
"T6",
|
|
||||||
};
|
|
||||||
static_assert(std::extent_v<decltype(GameId_Names)> == static_cast<unsigned>(GameId::COUNT));
|
|
||||||
|
|
||||||
class IGame
|
class IGame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -36,13 +15,10 @@ public:
|
|||||||
IGame& operator=(const IGame& other) = default;
|
IGame& operator=(const IGame& other) = default;
|
||||||
IGame& operator=(IGame&& other) noexcept = default;
|
IGame& operator=(IGame&& other) noexcept = default;
|
||||||
|
|
||||||
[[nodiscard]] virtual GameId GetId() const = 0;
|
virtual std::string GetFullName() = 0;
|
||||||
[[nodiscard]] virtual const std::string& GetFullName() const = 0;
|
virtual std::string GetShortName() = 0;
|
||||||
[[nodiscard]] virtual const std::string& GetShortName() const = 0;
|
|
||||||
virtual void AddZone(Zone* zone) = 0;
|
virtual void AddZone(Zone* zone) = 0;
|
||||||
virtual void RemoveZone(Zone* zone) = 0;
|
virtual void RemoveZone(Zone* zone) = 0;
|
||||||
[[nodiscard]] virtual const std::vector<Zone*>& GetZones() const = 0;
|
virtual std::vector<Zone*> GetZones() = 0;
|
||||||
[[nodiscard]] virtual const std::vector<GameLanguagePrefix>& GetLanguagePrefixes() const = 0;
|
virtual std::vector<GameLanguagePrefix> GetLanguagePrefixes() = 0;
|
||||||
|
|
||||||
static IGame* GetGameById(GameId gameId);
|
|
||||||
};
|
};
|
||||||
|
@ -4,32 +4,32 @@
|
|||||||
|
|
||||||
using namespace IW3;
|
using namespace IW3;
|
||||||
|
|
||||||
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in)
|
||||||
{
|
{
|
||||||
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
return PackedTexCoords{Pack32::Vec2PackTexCoords(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3])
|
PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in)
|
||||||
{
|
{
|
||||||
return PackedUnitVec{pack32::Vec3PackUnitVecScaleBased(in)};
|
return PackedUnitVec{Pack32::Vec3PackUnitVec(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxColor Common::Vec4PackGfxColor(const float (&in)[4])
|
GfxColor Common::Vec4PackGfxColor(const vec4_t* in)
|
||||||
{
|
{
|
||||||
return GfxColor{pack32::Vec4PackGfxColor(in)};
|
return GfxColor{Pack32::Vec4PackGfxColor(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2])
|
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec2UnpackTexCoordsVU(in.packed, out);
|
Pack32::Vec2UnpackTexCoordsVU(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3])
|
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec3UnpackUnitVecScaleBased(in.packed, out);
|
Pack32::Vec3UnpackUnitVecScaleBased(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4])
|
void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec4UnpackGfxColor(in.packed, out);
|
Pack32::Vec4UnpackGfxColor(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,11 @@ namespace IW3
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
|
static PackedTexCoords Vec2PackTexCoords(const vec2_t* in);
|
||||||
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
|
static PackedUnitVec Vec3PackUnitVec(const vec3_t* in);
|
||||||
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
|
static GfxColor Vec4PackGfxColor(const vec4_t* in);
|
||||||
static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]);
|
static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out);
|
||||||
static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]);
|
static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out);
|
||||||
static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]);
|
static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out);
|
||||||
};
|
};
|
||||||
} // namespace IW3
|
} // namespace IW3
|
||||||
|
@ -1,32 +1,29 @@
|
|||||||
#include "GameIW3.h"
|
#include "GameIW3.h"
|
||||||
|
|
||||||
|
#include "IW3.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace IW3;
|
using namespace IW3;
|
||||||
|
|
||||||
GameId Game::GetId() const
|
GameIW3 g_GameIW3;
|
||||||
|
|
||||||
|
std::string GameIW3::GetFullName()
|
||||||
{
|
{
|
||||||
return GameId::IW3;
|
return "Call Of Duty 4: Modern Warfare";
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetFullName() const
|
std::string GameIW3::GetShortName()
|
||||||
{
|
{
|
||||||
static std::string fullName = "Call Of Duty 4: Modern Warfare";
|
return "IW3";
|
||||||
return fullName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetShortName() const
|
void GameIW3::AddZone(Zone* zone)
|
||||||
{
|
|
||||||
static std::string shortName = "IW3";
|
|
||||||
return shortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::AddZone(Zone* zone)
|
|
||||||
{
|
{
|
||||||
m_zones.push_back(zone);
|
m_zones.push_back(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::RemoveZone(Zone* zone)
|
void GameIW3::RemoveZone(Zone* zone)
|
||||||
{
|
{
|
||||||
const auto foundEntry = std::ranges::find(m_zones, zone);
|
const auto foundEntry = std::ranges::find(m_zones, zone);
|
||||||
|
|
||||||
@ -34,13 +31,13 @@ void Game::RemoveZone(Zone* zone)
|
|||||||
m_zones.erase(foundEntry);
|
m_zones.erase(foundEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Zone*>& Game::GetZones() const
|
std::vector<Zone*> GameIW3::GetZones()
|
||||||
{
|
{
|
||||||
return m_zones;
|
return m_zones;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<GameLanguagePrefix>& Game::GetLanguagePrefixes() const
|
std::vector<GameLanguagePrefix> GameIW3::GetLanguagePrefixes()
|
||||||
{
|
{
|
||||||
static std::vector<GameLanguagePrefix> prefixes;
|
std::vector<GameLanguagePrefix> prefixes;
|
||||||
return prefixes;
|
return prefixes;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Game/IGame.h"
|
#include "Game/IGame.h"
|
||||||
|
|
||||||
namespace IW3
|
class GameIW3 : public IGame
|
||||||
{
|
{
|
||||||
class Game final : public IGame
|
std::vector<Zone*> m_zones;
|
||||||
{
|
|
||||||
public:
|
|
||||||
[[nodiscard]] GameId GetId() const override;
|
|
||||||
[[nodiscard]] const std::string& GetFullName() const override;
|
|
||||||
[[nodiscard]] const std::string& GetShortName() const override;
|
|
||||||
void AddZone(Zone* zone) override;
|
|
||||||
void RemoveZone(Zone* zone) override;
|
|
||||||
[[nodiscard]] const std::vector<Zone*>& GetZones() const override;
|
|
||||||
[[nodiscard]] const std::vector<GameLanguagePrefix>& GetLanguagePrefixes() const override;
|
|
||||||
|
|
||||||
private:
|
public:
|
||||||
std::vector<Zone*> m_zones;
|
std::string GetFullName() override;
|
||||||
};
|
std::string GetShortName() override;
|
||||||
} // namespace IW3
|
void AddZone(Zone* zone) override;
|
||||||
|
void RemoveZone(Zone* zone) override;
|
||||||
|
std::vector<Zone*> GetZones() override;
|
||||||
|
std::vector<GameLanguagePrefix> GetLanguagePrefixes() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GameIW3 g_GameIW3;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// clang-format off: Order of includes matters here
|
// clang-format off: Order of includes matters here
|
||||||
|
|
||||||
// #include <d3d9.h>
|
// #include <d3d9.h>
|
||||||
#include "Game/IAsset.h"
|
#include "Image/Texture.h"
|
||||||
|
|
||||||
#include "IW3_Assets.h"
|
#include "IW3_Assets.h"
|
||||||
|
|
||||||
@ -83,62 +83,4 @@ namespace IW3
|
|||||||
|
|
||||||
WFT_NUM_FIELD_TYPES
|
WFT_NUM_FIELD_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
using AssetXModelPieces = Asset<ASSET_TYPE_XMODELPIECES, XModelPieces>;
|
|
||||||
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
|
|
||||||
using AssetXAnim = Asset<ASSET_TYPE_XANIMPARTS, XAnimParts>;
|
|
||||||
using AssetXModel = Asset<ASSET_TYPE_XMODEL, XModel>;
|
|
||||||
using AssetMaterial = Asset<ASSET_TYPE_MATERIAL, Material>;
|
|
||||||
using AssetTechniqueSet = Asset<ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet>;
|
|
||||||
using AssetImage = Asset<ASSET_TYPE_IMAGE, GfxImage>;
|
|
||||||
using AssetSound = Asset<ASSET_TYPE_SOUND, snd_alias_list_t>;
|
|
||||||
using AssetSoundCurve = Asset<ASSET_TYPE_SOUND_CURVE, SndCurve>;
|
|
||||||
using AssetLoadedSound = Asset<ASSET_TYPE_LOADED_SOUND, LoadedSound>;
|
|
||||||
using AssetClipMap = Asset<ASSET_TYPE_CLIPMAP, clipMap_t>;
|
|
||||||
using AssetClipMapPvs = Asset<ASSET_TYPE_CLIPMAP_PVS, clipMap_t>;
|
|
||||||
using AssetComWorld = Asset<ASSET_TYPE_COMWORLD, ComWorld>;
|
|
||||||
using AssetGameWorldSp = Asset<ASSET_TYPE_GAMEWORLD_SP, GameWorldSp>;
|
|
||||||
using AssetGameWorldMp = Asset<ASSET_TYPE_GAMEWORLD_MP, GameWorldMp>;
|
|
||||||
using AssetMapEnts = Asset<ASSET_TYPE_MAP_ENTS, MapEnts>;
|
|
||||||
using AssetGfxWorld = Asset<ASSET_TYPE_GFXWORLD, GfxWorld>;
|
|
||||||
using AssetLightDef = Asset<ASSET_TYPE_LIGHT_DEF, GfxLightDef>;
|
|
||||||
using AssetFont = Asset<ASSET_TYPE_FONT, Font_s>;
|
|
||||||
using AssetMenuList = Asset<ASSET_TYPE_MENULIST, MenuList>;
|
|
||||||
using AssetMenu = Asset<ASSET_TYPE_MENU, menuDef_t>;
|
|
||||||
using AssetLocalize = Asset<ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry>;
|
|
||||||
using AssetWeapon = Asset<ASSET_TYPE_WEAPON, WeaponDef>;
|
|
||||||
using AssetSoundDriverGlobals = Asset<ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals>;
|
|
||||||
using AssetFx = Asset<ASSET_TYPE_FX, FxEffectDef>;
|
|
||||||
using AssetImpactFx = Asset<ASSET_TYPE_IMPACT_FX, FxImpactTable>;
|
|
||||||
using AssetRawFile = Asset<ASSET_TYPE_RAWFILE, RawFile>;
|
|
||||||
using AssetStringTable = Asset<ASSET_TYPE_STRINGTABLE, StringTable>;
|
|
||||||
} // namespace IW3
|
} // namespace IW3
|
||||||
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetXModelPieces, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetPhysPreset, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetXAnim, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetXModel, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetMaterial, info.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetTechniqueSet, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetImage, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetSound, aliasName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetSoundCurve, filename);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetLoadedSound, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetClipMap, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetClipMapPvs, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetComWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetGameWorldSp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetGameWorldMp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetMapEnts, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetGfxWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetLightDef, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetFont, fontName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetMenuList, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetMenu, window.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetLocalize, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetWeapon, szInternalName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetSoundDriverGlobals, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetFx, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetImpactFx, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetRawFile, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW3::AssetStringTable, name);
|
|
||||||
|
@ -1326,6 +1326,7 @@ namespace IW3
|
|||||||
// void/*IDirect3DTexture9*/* map;
|
// void/*IDirect3DTexture9*/* map;
|
||||||
// void/*IDirect3DVolumeTexture9*/* volmap;
|
// void/*IDirect3DVolumeTexture9*/* volmap;
|
||||||
// void/*IDirect3DCubeTexture9*/* cubemap;
|
// void/*IDirect3DCubeTexture9*/* cubemap;
|
||||||
|
Texture* texture;
|
||||||
GfxImageLoadDef* loadDef;
|
GfxImageLoadDef* loadDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3090,16 +3091,20 @@ namespace IW3
|
|||||||
float fHipViewScatterMax;
|
float fHipViewScatterMax;
|
||||||
float fightDist;
|
float fightDist;
|
||||||
float maxDist;
|
float maxDist;
|
||||||
const char* aiVsAiAccuracyGraphName;
|
// TODO: Order is accuracyGraphName[0] -> originalAccuracyGraphKnots[0] -> accuracyGraphName[1] -> ...
|
||||||
const char* aiVsPlayerAccuracyGraphName;
|
// Which is currently not possible to do in code generation. Afaik this is the only place where this is the case.
|
||||||
vec2_t* aiVsAiAccuracyGraphKnots;
|
// So might be something to fix but on the other hand it might be too much work for this little inconvenience.
|
||||||
vec2_t* aiVsPlayerAccuracyGraphKnots;
|
// const char* accuracyGraphName[2];
|
||||||
vec2_t* originalAiVsAiAccuracyGraphKnots;
|
const char* accuracyGraphName0;
|
||||||
vec2_t* originalAiVsPlayerAccuracyGraphKnots;
|
const char* accuracyGraphName1;
|
||||||
int aiVsAiAccuracyGraphKnotCount;
|
// float(*accuracyGraphKnots[2])[2];
|
||||||
int aiVsPlayerAccuracyGraphKnotCount;
|
vec2_t* accuracyGraphKnots0;
|
||||||
int originalAiVsAiAccuracyGraphKnotCount;
|
vec2_t* accuracyGraphKnots1;
|
||||||
int originalAiVsPlayerAccuracyGraphKnotCount;
|
// float(*originalAccuracyGraphKnots[2])[2];
|
||||||
|
vec2_t* originalAccuracyGraphKnots0;
|
||||||
|
vec2_t* originalAccuracyGraphKnots1;
|
||||||
|
int accuracyGraphKnotCount[2];
|
||||||
|
int originalAccuracyGraphKnotCount[2];
|
||||||
int iPositionReloadTransTime;
|
int iPositionReloadTransTime;
|
||||||
float leftArc;
|
float leftArc;
|
||||||
float rightArc;
|
float rightArc;
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include "Utils/Pack.h"
|
#include "Utils/Pack.h"
|
||||||
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
|
|
||||||
int Common::StringTable_HashString(const char* str)
|
int Common::StringTable_HashString(const char* str)
|
||||||
@ -22,32 +20,32 @@ int Common::StringTable_HashString(const char* str)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in)
|
||||||
{
|
{
|
||||||
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
return PackedTexCoords{Pack32::Vec2PackTexCoords(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3])
|
PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in)
|
||||||
{
|
{
|
||||||
return PackedUnitVec{pack32::Vec3PackUnitVecScaleBased(in)};
|
return PackedUnitVec{Pack32::Vec3PackUnitVec(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxColor Common::Vec4PackGfxColor(const float (&in)[4])
|
GfxColor Common::Vec4PackGfxColor(const vec4_t* in)
|
||||||
{
|
{
|
||||||
return GfxColor{pack32::Vec4PackGfxColor(in)};
|
return GfxColor{Pack32::Vec4PackGfxColor(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2])
|
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec2UnpackTexCoordsVU(in.packed, out);
|
Pack32::Vec2UnpackTexCoordsVU(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3])
|
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec3UnpackUnitVecScaleBased(in.packed, out);
|
Pack32::Vec3UnpackUnitVecScaleBased(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4])
|
void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec4UnpackGfxColor(in.packed, out);
|
Pack32::Vec4UnpackGfxColor(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,11 @@ namespace IW4
|
|||||||
|
|
||||||
static int StringTable_HashString(const char* str);
|
static int StringTable_HashString(const char* str);
|
||||||
|
|
||||||
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
|
static PackedTexCoords Vec2PackTexCoords(const vec2_t* in);
|
||||||
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
|
static PackedUnitVec Vec3PackUnitVec(const vec3_t* in);
|
||||||
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
|
static GfxColor Vec4PackGfxColor(const vec4_t* in);
|
||||||
static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]);
|
static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out);
|
||||||
static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]);
|
static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out);
|
||||||
static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]);
|
static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out);
|
||||||
};
|
};
|
||||||
} // namespace IW4
|
} // namespace IW4
|
||||||
|
@ -1,32 +1,29 @@
|
|||||||
#include "GameIW4.h"
|
#include "GameIW4.h"
|
||||||
|
|
||||||
|
#include "IW4.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
|
|
||||||
GameId Game::GetId() const
|
GameIW4 g_GameIW4;
|
||||||
|
|
||||||
|
std::string GameIW4::GetFullName()
|
||||||
{
|
{
|
||||||
return GameId::IW4;
|
return "Call Of Duty: Modern Warfare 2";
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetFullName() const
|
std::string GameIW4::GetShortName()
|
||||||
{
|
{
|
||||||
static std::string fullName = "Call Of Duty: Modern Warfare 2";
|
return "IW4";
|
||||||
return fullName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetShortName() const
|
void GameIW4::AddZone(Zone* zone)
|
||||||
{
|
|
||||||
static std::string shortName = "IW4";
|
|
||||||
return shortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::AddZone(Zone* zone)
|
|
||||||
{
|
{
|
||||||
m_zones.push_back(zone);
|
m_zones.push_back(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::RemoveZone(Zone* zone)
|
void GameIW4::RemoveZone(Zone* zone)
|
||||||
{
|
{
|
||||||
const auto foundEntry = std::ranges::find(m_zones, zone);
|
const auto foundEntry = std::ranges::find(m_zones, zone);
|
||||||
|
|
||||||
@ -34,13 +31,13 @@ void Game::RemoveZone(Zone* zone)
|
|||||||
m_zones.erase(foundEntry);
|
m_zones.erase(foundEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Zone*>& Game::GetZones() const
|
std::vector<Zone*> GameIW4::GetZones()
|
||||||
{
|
{
|
||||||
return m_zones;
|
return m_zones;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<GameLanguagePrefix>& Game::GetLanguagePrefixes() const
|
std::vector<GameLanguagePrefix> GameIW4::GetLanguagePrefixes()
|
||||||
{
|
{
|
||||||
static std::vector<GameLanguagePrefix> prefixes;
|
std::vector<GameLanguagePrefix> prefixes;
|
||||||
return prefixes;
|
return prefixes;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Game/IGame.h"
|
#include "Game/IGame.h"
|
||||||
|
|
||||||
namespace IW4
|
class GameIW4 : public IGame
|
||||||
{
|
{
|
||||||
class Game final : public IGame
|
std::vector<Zone*> m_zones;
|
||||||
{
|
|
||||||
public:
|
|
||||||
[[nodiscard]] GameId GetId() const override;
|
|
||||||
[[nodiscard]] const std::string& GetFullName() const override;
|
|
||||||
[[nodiscard]] const std::string& GetShortName() const override;
|
|
||||||
void AddZone(Zone* zone) override;
|
|
||||||
void RemoveZone(Zone* zone) override;
|
|
||||||
[[nodiscard]] const std::vector<Zone*>& GetZones() const override;
|
|
||||||
[[nodiscard]] const std::vector<GameLanguagePrefix>& GetLanguagePrefixes() const override;
|
|
||||||
|
|
||||||
private:
|
public:
|
||||||
std::vector<Zone*> m_zones;
|
std::string GetFullName() override;
|
||||||
};
|
std::string GetShortName() override;
|
||||||
} // namespace IW4
|
void AddZone(Zone* zone) override;
|
||||||
|
void RemoveZone(Zone* zone) override;
|
||||||
|
std::vector<Zone*> GetZones() override;
|
||||||
|
std::vector<GameLanguagePrefix> GetLanguagePrefixes() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GameIW4 g_GameIW4;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// clang-format off: Order of includes matters here
|
// clang-format off: Order of includes matters here
|
||||||
|
|
||||||
// #include <d3d9.h>
|
// #include <d3d9.h>
|
||||||
#include "Game/IAsset.h"
|
#include "Image/Texture.h"
|
||||||
|
|
||||||
#include "IW4_Assets.h"
|
#include "IW4_Assets.h"
|
||||||
|
|
||||||
@ -129,80 +129,4 @@ namespace IW4
|
|||||||
|
|
||||||
VFT_NUM,
|
VFT_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
|
|
||||||
using AssetPhysCollMap = Asset<ASSET_TYPE_PHYSCOLLMAP, PhysCollmap>;
|
|
||||||
using AssetXAnim = Asset<ASSET_TYPE_XANIMPARTS, XAnimParts>;
|
|
||||||
using AssetXModelSurfs = Asset<ASSET_TYPE_XMODEL_SURFS, XModelSurfs>;
|
|
||||||
using AssetXModel = Asset<ASSET_TYPE_XMODEL, XModel>;
|
|
||||||
using AssetMaterial = Asset<ASSET_TYPE_MATERIAL, Material>;
|
|
||||||
using AssetPixelShader = Asset<ASSET_TYPE_PIXELSHADER, MaterialPixelShader>;
|
|
||||||
using AssetVertexShader = Asset<ASSET_TYPE_VERTEXSHADER, MaterialVertexShader>;
|
|
||||||
using AssetVertexDecl = Asset<ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration>;
|
|
||||||
using AssetTechniqueSet = Asset<ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet>;
|
|
||||||
using AssetImage = Asset<ASSET_TYPE_IMAGE, GfxImage>;
|
|
||||||
using AssetSound = Asset<ASSET_TYPE_SOUND, snd_alias_list_t>;
|
|
||||||
using AssetSoundCurve = Asset<ASSET_TYPE_SOUND_CURVE, SndCurve>;
|
|
||||||
using AssetLoadedSound = Asset<ASSET_TYPE_LOADED_SOUND, LoadedSound>;
|
|
||||||
using AssetClipMapSp = Asset<ASSET_TYPE_CLIPMAP_SP, clipMap_t>;
|
|
||||||
using AssetClipMapMp = Asset<ASSET_TYPE_CLIPMAP_MP, clipMap_t>;
|
|
||||||
using AssetComWorld = Asset<ASSET_TYPE_COMWORLD, ComWorld>;
|
|
||||||
using AssetGameWorldSp = Asset<ASSET_TYPE_GAMEWORLD_SP, GameWorldSp>;
|
|
||||||
using AssetGameWorldMp = Asset<ASSET_TYPE_GAMEWORLD_MP, GameWorldMp>;
|
|
||||||
using AssetMapEnts = Asset<ASSET_TYPE_MAP_ENTS, MapEnts>;
|
|
||||||
using AssetFxWorld = Asset<ASSET_TYPE_FXWORLD, FxWorld>;
|
|
||||||
using AssetGfxWorld = Asset<ASSET_TYPE_GFXWORLD, GfxWorld>;
|
|
||||||
using AssetLightDef = Asset<ASSET_TYPE_LIGHT_DEF, GfxLightDef>;
|
|
||||||
using AssetFont = Asset<ASSET_TYPE_FONT, Font_s>;
|
|
||||||
using AssetMenuList = Asset<ASSET_TYPE_MENULIST, MenuList>;
|
|
||||||
using AssetMenu = Asset<ASSET_TYPE_MENU, menuDef_t>;
|
|
||||||
using AssetLocalize = Asset<ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry>;
|
|
||||||
using AssetWeapon = Asset<ASSET_TYPE_WEAPON, WeaponCompleteDef>;
|
|
||||||
using AssetFx = Asset<ASSET_TYPE_FX, FxEffectDef>;
|
|
||||||
using AssetImpactFx = Asset<ASSET_TYPE_IMPACT_FX, FxImpactTable>;
|
|
||||||
using AssetRawFile = Asset<ASSET_TYPE_RAWFILE, RawFile>;
|
|
||||||
using AssetStringTable = Asset<ASSET_TYPE_STRINGTABLE, StringTable>;
|
|
||||||
using AssetLeaderboard = Asset<ASSET_TYPE_LEADERBOARD, LeaderboardDef>;
|
|
||||||
using AssetStructuredDataDef = Asset<ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet>;
|
|
||||||
using AssetTracer = Asset<ASSET_TYPE_TRACER, TracerDef>;
|
|
||||||
using AssetVehicle = Asset<ASSET_TYPE_VEHICLE, VehicleDef>;
|
|
||||||
using AssetAddonMapEnts = Asset<ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts>;
|
|
||||||
} // namespace IW4
|
} // namespace IW4
|
||||||
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetPhysPreset, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetPhysCollMap, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetXAnim, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetXModelSurfs, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetXModel, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetMaterial, info.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetPixelShader, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetVertexShader, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetVertexDecl, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetTechniqueSet, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetImage, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetSound, aliasName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetSoundCurve, filename);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetLoadedSound, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetClipMapSp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetClipMapMp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetComWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetGameWorldSp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetGameWorldMp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetMapEnts, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetFxWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetGfxWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetLightDef, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetFont, fontName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetMenuList, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetMenu, window.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetLocalize, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetWeapon, szInternalName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetFx, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetImpactFx, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetRawFile, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetStringTable, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetLeaderboard, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetStructuredDataDef, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetTracer, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetVehicle, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW4::AssetAddonMapEnts, name);
|
|
||||||
|
@ -1009,6 +1009,7 @@ namespace IW4
|
|||||||
// IDirect3DTexture9* map;
|
// IDirect3DTexture9* map;
|
||||||
// IDirect3DVolumeTexture9* volmap;
|
// IDirect3DVolumeTexture9* volmap;
|
||||||
// IDirect3DCubeTexture9* cubemap;
|
// IDirect3DCubeTexture9* cubemap;
|
||||||
|
Texture* texture;
|
||||||
GfxImageLoadDef* loadDef;
|
GfxImageLoadDef* loadDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2548,8 +2549,7 @@ namespace IW4
|
|||||||
LBCOL_TYPE_PRESTIGE = 0x3,
|
LBCOL_TYPE_PRESTIGE = 0x3,
|
||||||
LBCOL_TYPE_BIGNUMBER = 0x4,
|
LBCOL_TYPE_BIGNUMBER = 0x4,
|
||||||
LBCOL_TYPE_PERCENT = 0x5,
|
LBCOL_TYPE_PERCENT = 0x5,
|
||||||
|
LBCOL_TYPE_COUNT = 0x6,
|
||||||
LBCOL_TYPE_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LbAggType
|
enum LbAggType
|
||||||
@ -2558,8 +2558,7 @@ namespace IW4
|
|||||||
LBAGG_TYPE_MAX = 0x1,
|
LBAGG_TYPE_MAX = 0x1,
|
||||||
LBAGG_TYPE_SUM = 0x2,
|
LBAGG_TYPE_SUM = 0x2,
|
||||||
LBAGG_TYPE_LAST = 0x3,
|
LBAGG_TYPE_LAST = 0x3,
|
||||||
|
LBAGG_TYPE_COUNT = 0x4,
|
||||||
LBAGG_TYPE_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LbColumnDef
|
struct LbColumnDef
|
||||||
@ -4081,7 +4080,7 @@ namespace IW4
|
|||||||
HITLOC_GUN = 0x12,
|
HITLOC_GUN = 0x12,
|
||||||
HITLOC_SHIELD = 0x13,
|
HITLOC_SHIELD = 0x13,
|
||||||
|
|
||||||
HITLOC_COUNT,
|
HITLOC_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct snd_alias_list_name
|
struct snd_alias_list_name
|
||||||
@ -4398,12 +4397,15 @@ namespace IW4
|
|||||||
float fHipViewScatterMax;
|
float fHipViewScatterMax;
|
||||||
float fightDist;
|
float fightDist;
|
||||||
float maxDist;
|
float maxDist;
|
||||||
const char* aiVsAiAccuracyGraphName;
|
// const char* accuracyGraphName[2];// TODO: Order is accuracyGraphName[0] -> originalAccuracyGraphKnots[0] -> accuracyGraphName[1] -> ...
|
||||||
const char* aiVsPlayerAccuracyGraphName;
|
// Which is currently not possible to do in code generation. Afaik this is the only place where this is the case.
|
||||||
vec2_t* originalAiVsAiAccuracyGraphKnots;
|
// So might be something to fix but on the other hand it might be too much work for this little inconvenience.
|
||||||
vec2_t* originalAiVsPlayerAccuracyGraphKnots;
|
// vec2_t* originalAccuracyGraphKnots[2];
|
||||||
uint16_t originalAiVsAiAccuracyGraphKnotCount;
|
const char* accuracyGraphName0;
|
||||||
uint16_t originalAiVsPlayerAccuracyGraphKnotCount;
|
const char* accuracyGraphName1;
|
||||||
|
vec2_t* originalAccuracyGraphKnots0;
|
||||||
|
vec2_t* originalAccuracyGraphKnots1;
|
||||||
|
uint16_t originalAccuracyGraphKnotCount[2];
|
||||||
int iPositionReloadTransTime;
|
int iPositionReloadTransTime;
|
||||||
float leftArc;
|
float leftArc;
|
||||||
float rightArc;
|
float rightArc;
|
||||||
@ -4547,10 +4549,8 @@ namespace IW4
|
|||||||
int ammoDropStockMax;
|
int ammoDropStockMax;
|
||||||
float adsDofStart;
|
float adsDofStart;
|
||||||
float adsDofEnd;
|
float adsDofEnd;
|
||||||
uint16_t aiVsAiAccuracyGraphKnotCount;
|
uint16_t accuracyGraphKnotCount[2];
|
||||||
uint16_t aiVsPlayerAccuracyGraphKnotCount;
|
vec2_t* accuracyGraphKnots[2];
|
||||||
vec2_t* aiVsAiAccuracyGraphKnots;
|
|
||||||
vec2_t* aiVsPlayerAccuracyGraphKnots;
|
|
||||||
bool motionTracker;
|
bool motionTracker;
|
||||||
bool enhanced;
|
bool enhanced;
|
||||||
bool dpadIconShowsAmmo;
|
bool dpadIconShowsAmmo;
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include "Utils/Pack.h"
|
#include "Utils/Pack.h"
|
||||||
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
using namespace IW5;
|
using namespace IW5;
|
||||||
|
|
||||||
int Common::StringTable_HashString(const char* str)
|
int Common::StringTable_HashString(const char* str)
|
||||||
@ -22,32 +20,32 @@ int Common::StringTable_HashString(const char* str)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in)
|
||||||
{
|
{
|
||||||
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
return PackedTexCoords{Pack32::Vec2PackTexCoords(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3])
|
PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in)
|
||||||
{
|
{
|
||||||
return PackedUnitVec{pack32::Vec3PackUnitVecScaleBased(in)};
|
return PackedUnitVec{Pack32::Vec3PackUnitVec(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxColor Common::Vec4PackGfxColor(const float (&in)[4])
|
GfxColor Common::Vec4PackGfxColor(const vec4_t* in)
|
||||||
{
|
{
|
||||||
return GfxColor{pack32::Vec4PackGfxColor(in)};
|
return GfxColor{Pack32::Vec4PackGfxColor(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2])
|
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec2UnpackTexCoordsVU(in.packed, out);
|
Pack32::Vec2UnpackTexCoordsVU(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3])
|
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec3UnpackUnitVecScaleBased(in.packed, out);
|
Pack32::Vec3UnpackUnitVecScaleBased(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4])
|
void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec4UnpackGfxColor(in.packed, out);
|
Pack32::Vec4UnpackGfxColor(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
@ -9,26 +9,11 @@ namespace IW5
|
|||||||
public:
|
public:
|
||||||
static int StringTable_HashString(const char* str);
|
static int StringTable_HashString(const char* str);
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* str, uint32_t hash)
|
static PackedTexCoords Vec2PackTexCoords(const vec2_t* in);
|
||||||
{
|
static PackedUnitVec Vec3PackUnitVec(const vec3_t* in);
|
||||||
for (const auto* pos = str; *pos; pos++)
|
static GfxColor Vec4PackGfxColor(const vec4_t* in);
|
||||||
{
|
static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out);
|
||||||
hash = 33 * hash ^ (*pos | 0x20);
|
static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out);
|
||||||
}
|
static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out);
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* string)
|
|
||||||
{
|
|
||||||
return R_HashString(string, 0u);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
|
|
||||||
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
|
|
||||||
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
|
|
||||||
static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]);
|
|
||||||
static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]);
|
|
||||||
static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]);
|
|
||||||
};
|
};
|
||||||
} // namespace IW5
|
} // namespace IW5
|
||||||
|
@ -1,32 +1,29 @@
|
|||||||
#include "GameIW5.h"
|
#include "GameIW5.h"
|
||||||
|
|
||||||
|
#include "IW5.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace IW5;
|
using namespace IW5;
|
||||||
|
|
||||||
GameId Game::GetId() const
|
GameIW5 g_GameIW5;
|
||||||
|
|
||||||
|
std::string GameIW5::GetFullName()
|
||||||
{
|
{
|
||||||
return GameId::IW5;
|
return "Call Of Duty: Modern Warfare 3";
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetFullName() const
|
std::string GameIW5::GetShortName()
|
||||||
{
|
{
|
||||||
static std::string fullName = "Call Of Duty: Modern Warfare 3";
|
return "IW5";
|
||||||
return fullName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetShortName() const
|
void GameIW5::AddZone(Zone* zone)
|
||||||
{
|
|
||||||
static std::string shortName = "IW5";
|
|
||||||
return shortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::AddZone(Zone* zone)
|
|
||||||
{
|
{
|
||||||
m_zones.push_back(zone);
|
m_zones.push_back(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::RemoveZone(Zone* zone)
|
void GameIW5::RemoveZone(Zone* zone)
|
||||||
{
|
{
|
||||||
const auto foundEntry = std::ranges::find(m_zones, zone);
|
const auto foundEntry = std::ranges::find(m_zones, zone);
|
||||||
|
|
||||||
@ -34,13 +31,13 @@ void Game::RemoveZone(Zone* zone)
|
|||||||
m_zones.erase(foundEntry);
|
m_zones.erase(foundEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Zone*>& Game::GetZones() const
|
std::vector<Zone*> GameIW5::GetZones()
|
||||||
{
|
{
|
||||||
return m_zones;
|
return m_zones;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<GameLanguagePrefix>& Game::GetLanguagePrefixes() const
|
std::vector<GameLanguagePrefix> GameIW5::GetLanguagePrefixes()
|
||||||
{
|
{
|
||||||
static std::vector<GameLanguagePrefix> prefixes;
|
std::vector<GameLanguagePrefix> prefixes;
|
||||||
return prefixes;
|
return prefixes;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Game/IGame.h"
|
#include "Game/IGame.h"
|
||||||
|
|
||||||
namespace IW5
|
class GameIW5 : public IGame
|
||||||
{
|
{
|
||||||
class Game final : public IGame
|
std::vector<Zone*> m_zones;
|
||||||
{
|
|
||||||
public:
|
|
||||||
[[nodiscard]] GameId GetId() const override;
|
|
||||||
[[nodiscard]] const std::string& GetFullName() const override;
|
|
||||||
[[nodiscard]] const std::string& GetShortName() const override;
|
|
||||||
void AddZone(Zone* zone) override;
|
|
||||||
void RemoveZone(Zone* zone) override;
|
|
||||||
[[nodiscard]] const std::vector<Zone*>& GetZones() const override;
|
|
||||||
[[nodiscard]] const std::vector<GameLanguagePrefix>& GetLanguagePrefixes() const override;
|
|
||||||
|
|
||||||
private:
|
public:
|
||||||
std::vector<Zone*> m_zones;
|
std::string GetFullName() override;
|
||||||
};
|
std::string GetShortName() override;
|
||||||
} // namespace IW5
|
void AddZone(Zone* zone) override;
|
||||||
|
void RemoveZone(Zone* zone) override;
|
||||||
|
std::vector<Zone*> GetZones() override;
|
||||||
|
std::vector<GameLanguagePrefix> GetLanguagePrefixes() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GameIW5 g_GameIW5;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// clang-format off: Order of includes matters here
|
// clang-format off: Order of includes matters here
|
||||||
|
|
||||||
// #include <d3d9.h>
|
// #include <d3d9.h>
|
||||||
#include "Game/IAsset.h"
|
#include "Image/Texture.h"
|
||||||
|
|
||||||
#include "IW5_Assets.h"
|
#include "IW5_Assets.h"
|
||||||
|
|
||||||
@ -137,86 +137,4 @@ namespace IW5
|
|||||||
|
|
||||||
WAFT_NUM_FIELD_TYPES,
|
WAFT_NUM_FIELD_TYPES,
|
||||||
};
|
};
|
||||||
|
|
||||||
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
|
|
||||||
using AssetPhysCollMap = Asset<ASSET_TYPE_PHYSCOLLMAP, PhysCollmap>;
|
|
||||||
using AssetXAnim = Asset<ASSET_TYPE_XANIMPARTS, XAnimParts>;
|
|
||||||
using AssetXModelSurfs = Asset<ASSET_TYPE_XMODEL_SURFS, XModelSurfs>;
|
|
||||||
using AssetXModel = Asset<ASSET_TYPE_XMODEL, XModel>;
|
|
||||||
using AssetMaterial = Asset<ASSET_TYPE_MATERIAL, Material>;
|
|
||||||
using AssetPixelShader = Asset<ASSET_TYPE_PIXELSHADER, MaterialPixelShader>;
|
|
||||||
using AssetVertexShader = Asset<ASSET_TYPE_VERTEXSHADER, MaterialVertexShader>;
|
|
||||||
using AssetVertexDecl = Asset<ASSET_TYPE_VERTEXDECL, MaterialVertexDeclaration>;
|
|
||||||
using AssetTechniqueSet = Asset<ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet>;
|
|
||||||
using AssetImage = Asset<ASSET_TYPE_IMAGE, GfxImage>;
|
|
||||||
using AssetSound = Asset<ASSET_TYPE_SOUND, snd_alias_list_t>;
|
|
||||||
using AssetSoundCurve = Asset<ASSET_TYPE_SOUND_CURVE, SndCurve>;
|
|
||||||
using AssetLoadedSound = Asset<ASSET_TYPE_LOADED_SOUND, LoadedSound>;
|
|
||||||
using AssetClipMap = Asset<ASSET_TYPE_CLIPMAP, clipMap_t>;
|
|
||||||
using AssetComWorld = Asset<ASSET_TYPE_COMWORLD, ComWorld>;
|
|
||||||
using AssetGlassWorld = Asset<ASSET_TYPE_GLASSWORLD, GlassWorld>;
|
|
||||||
using AssetPathData = Asset<ASSET_TYPE_PATHDATA, PathData>;
|
|
||||||
using AssetVehicleTrack = Asset<ASSET_TYPE_VEHICLE_TRACK, VehicleTrack>;
|
|
||||||
using AssetMapEnts = Asset<ASSET_TYPE_MAP_ENTS, MapEnts>;
|
|
||||||
using AssetFxWorld = Asset<ASSET_TYPE_FXWORLD, FxWorld>;
|
|
||||||
using AssetGfxWorld = Asset<ASSET_TYPE_GFXWORLD, GfxWorld>;
|
|
||||||
using AssetLightDef = Asset<ASSET_TYPE_LIGHT_DEF, GfxLightDef>;
|
|
||||||
using AssetFont = Asset<ASSET_TYPE_FONT, Font_s>;
|
|
||||||
using AssetMenuList = Asset<ASSET_TYPE_MENULIST, MenuList>;
|
|
||||||
using AssetMenu = Asset<ASSET_TYPE_MENU, menuDef_t>;
|
|
||||||
using AssetLocalize = Asset<ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry>;
|
|
||||||
using AssetAttachment = Asset<ASSET_TYPE_ATTACHMENT, WeaponAttachment>;
|
|
||||||
using AssetWeapon = Asset<ASSET_TYPE_WEAPON, WeaponCompleteDef>;
|
|
||||||
using AssetFx = Asset<ASSET_TYPE_FX, FxEffectDef>;
|
|
||||||
using AssetImpactFx = Asset<ASSET_TYPE_IMPACT_FX, FxImpactTable>;
|
|
||||||
using AssetSurfaceFx = Asset<ASSET_TYPE_SURFACE_FX, SurfaceFxTable>;
|
|
||||||
using AssetRawFile = Asset<ASSET_TYPE_RAWFILE, RawFile>;
|
|
||||||
using AssetScript = Asset<ASSET_TYPE_SCRIPTFILE, ScriptFile>;
|
|
||||||
using AssetStringTable = Asset<ASSET_TYPE_STRINGTABLE, StringTable>;
|
|
||||||
using AssetLeaderboard = Asset<ASSET_TYPE_LEADERBOARD, LeaderboardDef>;
|
|
||||||
using AssetStructuredDataDef = Asset<ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet>;
|
|
||||||
using AssetTracer = Asset<ASSET_TYPE_TRACER, TracerDef>;
|
|
||||||
using AssetVehicle = Asset<ASSET_TYPE_VEHICLE, VehicleDef>;
|
|
||||||
using AssetAddonMapEnts = Asset<ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts>;
|
|
||||||
} // namespace IW5
|
} // namespace IW5
|
||||||
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetPhysPreset, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetPhysCollMap, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetXAnim, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetXModelSurfs, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetXModel, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetMaterial, info.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetPixelShader, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetVertexShader, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetVertexDecl, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetTechniqueSet, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetImage, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetSound, aliasName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetSoundCurve, filename);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetLoadedSound, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetClipMap, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetComWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetGlassWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetPathData, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetVehicleTrack, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetMapEnts, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetFxWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetGfxWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetLightDef, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetFont, fontName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetMenuList, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetMenu, window.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetLocalize, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetAttachment, szInternalName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetWeapon, szInternalName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetFx, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetImpactFx, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetSurfaceFx, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetRawFile, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetScript, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetStringTable, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetLeaderboard, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetStructuredDataDef, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetTracer, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetVehicle, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(IW5::AssetAddonMapEnts, name);
|
|
||||||
|
@ -177,50 +177,11 @@ namespace IW5
|
|||||||
void* data;
|
void* data;
|
||||||
};
|
};
|
||||||
|
|
||||||
union vec2_t
|
typedef float vec2_t[2];
|
||||||
{
|
typedef float vec3_t[3];
|
||||||
float v[2];
|
typedef float vec4_t[4];
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
union vec3_t
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
};
|
|
||||||
|
|
||||||
float v[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
union vec4_t
|
|
||||||
{
|
|
||||||
float v[4];
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
float w;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float r;
|
|
||||||
float g;
|
|
||||||
float b;
|
|
||||||
float a;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
typedef tdef_align(16) uint16_t r_index16_t;
|
||||||
typedef tdef_align(16) char raw_byte16;
|
typedef tdef_align(16) char raw_byte16;
|
||||||
typedef tdef_align(16) float raw_float16;
|
typedef tdef_align(16) float raw_float16;
|
||||||
typedef tdef_align(128) unsigned int raw_uint128;
|
typedef tdef_align(128) unsigned int raw_uint128;
|
||||||
@ -259,8 +220,8 @@ namespace IW5
|
|||||||
|
|
||||||
struct Bounds
|
struct Bounds
|
||||||
{
|
{
|
||||||
vec3_t midPoint;
|
float midPoint[3];
|
||||||
vec3_t halfSize;
|
float halfSize[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cplane_s
|
struct cplane_s
|
||||||
@ -485,15 +446,34 @@ namespace IW5
|
|||||||
unsigned int packed;
|
unsigned int packed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GfxQuantizedNoColorVertex
|
||||||
|
{
|
||||||
|
short xyz[3];
|
||||||
|
short binormalSign;
|
||||||
|
PackedUnitVec normal;
|
||||||
|
PackedUnitVec tangent;
|
||||||
|
PackedTexCoords texCoord;
|
||||||
|
};
|
||||||
|
|
||||||
union GfxColor
|
union GfxColor
|
||||||
{
|
{
|
||||||
unsigned int packed;
|
unsigned int packed;
|
||||||
unsigned char array[4];
|
unsigned char array[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GfxQuantizedVertex
|
||||||
|
{
|
||||||
|
short xyz[3];
|
||||||
|
short binormalSign;
|
||||||
|
PackedUnitVec normal;
|
||||||
|
PackedUnitVec tangent;
|
||||||
|
PackedTexCoords texCoord;
|
||||||
|
GfxColor color;
|
||||||
|
};
|
||||||
|
|
||||||
struct type_align(16) GfxPackedVertex
|
struct type_align(16) GfxPackedVertex
|
||||||
{
|
{
|
||||||
vec3_t xyz;
|
float xyz[3];
|
||||||
float binormalSign;
|
float binormalSign;
|
||||||
GfxColor color;
|
GfxColor color;
|
||||||
PackedTexCoords texCoord;
|
PackedTexCoords texCoord;
|
||||||
@ -501,6 +481,14 @@ namespace IW5
|
|||||||
PackedUnitVec tangent;
|
PackedUnitVec tangent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
union GfxVertexUnion0
|
||||||
|
{
|
||||||
|
GfxQuantizedNoColorVertex* quantizedNoColorVerts0;
|
||||||
|
GfxQuantizedVertex* quantizedVerts0;
|
||||||
|
GfxPackedVertex* packedVerts0;
|
||||||
|
void* verts0;
|
||||||
|
};
|
||||||
|
|
||||||
struct XSurfaceCollisionAabb
|
struct XSurfaceCollisionAabb
|
||||||
{
|
{
|
||||||
unsigned short mins[3];
|
unsigned short mins[3];
|
||||||
@ -538,13 +526,6 @@ namespace IW5
|
|||||||
XSurfaceCollisionTree* collisionTree;
|
XSurfaceCollisionTree* collisionTree;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XSurfaceTri
|
|
||||||
{
|
|
||||||
uint16_t i[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef tdef_align(16) XSurfaceTri XSurfaceTri16;
|
|
||||||
|
|
||||||
struct XSurface
|
struct XSurface
|
||||||
{
|
{
|
||||||
unsigned char tileMode;
|
unsigned char tileMode;
|
||||||
@ -555,9 +536,9 @@ namespace IW5
|
|||||||
uint16_t baseTriIndex;
|
uint16_t baseTriIndex;
|
||||||
uint16_t baseVertIndex;
|
uint16_t baseVertIndex;
|
||||||
float quantizeScale;
|
float quantizeScale;
|
||||||
XSurfaceTri16* triIndices;
|
r_index16_t (*triIndices)[3];
|
||||||
XSurfaceVertexInfo vertInfo;
|
XSurfaceVertexInfo vertInfo;
|
||||||
GfxPackedVertex* verts0;
|
GfxVertexUnion0 verts0;
|
||||||
unsigned int vertListCount;
|
unsigned int vertListCount;
|
||||||
XRigidVertList* vertList;
|
XRigidVertList* vertList;
|
||||||
int partBits[6];
|
int partBits[6];
|
||||||
@ -573,8 +554,8 @@ namespace IW5
|
|||||||
|
|
||||||
struct DObjAnimMat
|
struct DObjAnimMat
|
||||||
{
|
{
|
||||||
vec4_t quat;
|
float quat[4];
|
||||||
vec3_t trans;
|
float trans[3];
|
||||||
float transWeight;
|
float transWeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -586,7 +567,7 @@ namespace IW5
|
|||||||
XModelSurfs* modelSurfs;
|
XModelSurfs* modelSurfs;
|
||||||
int partBits[6];
|
int partBits[6];
|
||||||
XSurface* surfs;
|
XSurface* surfs;
|
||||||
unsigned char lod;
|
char lod;
|
||||||
char smcBaseIndexPlusOne;
|
char smcBaseIndexPlusOne;
|
||||||
char smcSubIndexMask;
|
char smcSubIndexMask;
|
||||||
char smcBucket;
|
char smcBucket;
|
||||||
@ -615,11 +596,6 @@ namespace IW5
|
|||||||
float radiusSquared;
|
float radiusSquared;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XModelQuat
|
|
||||||
{
|
|
||||||
int16_t v[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct XModel
|
struct XModel
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
@ -630,15 +606,15 @@ namespace IW5
|
|||||||
unsigned int noScalePartBits[6];
|
unsigned int noScalePartBits[6];
|
||||||
ScriptString* boneNames;
|
ScriptString* boneNames;
|
||||||
unsigned char* parentList;
|
unsigned char* parentList;
|
||||||
XModelQuat* quats;
|
short (*quats)[4];
|
||||||
float* trans;
|
float (*trans)[3];
|
||||||
unsigned char* partClassification;
|
unsigned char* partClassification;
|
||||||
DObjAnimMat* baseMat;
|
DObjAnimMat* baseMat;
|
||||||
Material** materialHandles;
|
Material** materialHandles;
|
||||||
XModelLodInfo lodInfo[4];
|
XModelLodInfo lodInfo[4];
|
||||||
char maxLoadedLod;
|
char maxLoadedLod;
|
||||||
unsigned char numLods;
|
unsigned char numLods;
|
||||||
char collLod;
|
unsigned char collLod;
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
XModelCollSurf_s* collSurfs;
|
XModelCollSurf_s* collSurfs;
|
||||||
int numCollSurfs;
|
int numCollSurfs;
|
||||||
@ -675,23 +651,6 @@ namespace IW5
|
|||||||
gcc_align(8) uint64_t packed;
|
gcc_align(8) uint64_t packed;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MaterialGameFlags
|
|
||||||
{
|
|
||||||
MTL_GAMEFLAG_1 = 0x1,
|
|
||||||
MTL_GAMEFLAG_2 = 0x2,
|
|
||||||
MTL_GAMEFLAG_4 = 0x4,
|
|
||||||
MTL_GAMEFLAG_8 = 0x8,
|
|
||||||
MTL_GAMEFLAG_10 = 0x10,
|
|
||||||
MTL_GAMEFLAG_20 = 0x20,
|
|
||||||
MTL_GAMEFLAG_40 = 0x40,
|
|
||||||
MTL_GAMEFLAG_80 = 0x80,
|
|
||||||
MTL_GAMEFLAG_100 = 0x100,
|
|
||||||
MTL_GAMEFLAG_200 = 0x200,
|
|
||||||
MTL_GAMEFLAG_400 = 0x400,
|
|
||||||
MTL_GAMEFLAG_800 = 0x800,
|
|
||||||
MTL_GAMEFLAG_1000 = 0x1000,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MaterialInfo
|
struct MaterialInfo
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
@ -754,71 +713,13 @@ namespace IW5
|
|||||||
water_t* water;
|
water_t* water;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TextureFilter
|
|
||||||
{
|
|
||||||
TEXTURE_FILTER_DISABLED = 0x0,
|
|
||||||
TEXTURE_FILTER_NEAREST = 0x1,
|
|
||||||
TEXTURE_FILTER_LINEAR = 0x2,
|
|
||||||
TEXTURE_FILTER_ANISO2X = 0x3,
|
|
||||||
TEXTURE_FILTER_ANISO4X = 0x4,
|
|
||||||
|
|
||||||
TEXTURE_FILTER_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SamplerStateBitsMipMap_e
|
|
||||||
{
|
|
||||||
SAMPLER_MIPMAP_ENUM_DISABLED,
|
|
||||||
SAMPLER_MIPMAP_ENUM_NEAREST,
|
|
||||||
SAMPLER_MIPMAP_ENUM_LINEAR,
|
|
||||||
|
|
||||||
SAMPLER_MIPMAP_ENUM_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SamplerStateBits_e
|
|
||||||
{
|
|
||||||
SAMPLER_FILTER_SHIFT = 0x0,
|
|
||||||
SAMPLER_FILTER_NEAREST = 0x1,
|
|
||||||
SAMPLER_FILTER_LINEAR = 0x2,
|
|
||||||
SAMPLER_FILTER_ANISO2X = 0x3,
|
|
||||||
SAMPLER_FILTER_ANISO4X = 0x4,
|
|
||||||
SAMPLER_FILTER_MASK = 0x7,
|
|
||||||
|
|
||||||
SAMPLER_MIPMAP_SHIFT = 0x3,
|
|
||||||
SAMPLER_MIPMAP_DISABLED = 0x0,
|
|
||||||
SAMPLER_MIPMAP_NEAREST = 0x8,
|
|
||||||
SAMPLER_MIPMAP_LINEAR = 0x10,
|
|
||||||
SAMPLER_MIPMAP_COUNT = 0x3,
|
|
||||||
SAMPLER_MIPMAP_MASK = 0x18,
|
|
||||||
|
|
||||||
SAMPLER_CLAMP_U_SHIFT = 0x5,
|
|
||||||
SAMPLER_CLAMP_V_SHIFT = 0x6,
|
|
||||||
SAMPLER_CLAMP_W_SHIFT = 0x7,
|
|
||||||
SAMPLER_CLAMP_U = 0x20,
|
|
||||||
SAMPLER_CLAMP_V = 0x40,
|
|
||||||
SAMPLER_CLAMP_W = 0x80,
|
|
||||||
SAMPLER_CLAMP_MASK = 0xE0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MaterialTextureDefSamplerState
|
|
||||||
{
|
|
||||||
unsigned char filter : 3;
|
|
||||||
unsigned char mipMap : 2;
|
|
||||||
unsigned char clampU : 1;
|
|
||||||
unsigned char clampV : 1;
|
|
||||||
unsigned char clampW : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef __zonecodegenerator
|
|
||||||
static_assert(sizeof(MaterialTextureDefSamplerState) == 1u);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct MaterialTextureDef
|
struct MaterialTextureDef
|
||||||
{
|
{
|
||||||
unsigned int nameHash;
|
unsigned int nameHash;
|
||||||
char nameStart;
|
char nameStart;
|
||||||
char nameEnd;
|
char nameEnd;
|
||||||
MaterialTextureDefSamplerState samplerState;
|
unsigned char samplerState;
|
||||||
unsigned char semantic; // TextureSemantic
|
unsigned char semantic;
|
||||||
MaterialTextureDefInfo u;
|
MaterialTextureDefInfo u;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -826,161 +727,18 @@ namespace IW5
|
|||||||
{
|
{
|
||||||
unsigned int nameHash;
|
unsigned int nameHash;
|
||||||
char name[12];
|
char name[12];
|
||||||
vec4_t literal;
|
float literal[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum GfxBlend
|
|
||||||
{
|
|
||||||
GFXS_BLEND_DISABLED = 0x0,
|
|
||||||
GFXS_BLEND_ZERO = 0x1,
|
|
||||||
GFXS_BLEND_ONE = 0x2,
|
|
||||||
GFXS_BLEND_SRCCOLOR = 0x3,
|
|
||||||
GFXS_BLEND_INVSRCCOLOR = 0x4,
|
|
||||||
GFXS_BLEND_SRCALPHA = 0x5,
|
|
||||||
GFXS_BLEND_INVSRCALPHA = 0x6,
|
|
||||||
GFXS_BLEND_DESTALPHA = 0x7,
|
|
||||||
GFXS_BLEND_INVDESTALPHA = 0x8,
|
|
||||||
GFXS_BLEND_DESTCOLOR = 0x9,
|
|
||||||
GFXS_BLEND_INVDESTCOLOR = 0xA,
|
|
||||||
|
|
||||||
GFXS_BLEND_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GfxBlendOp
|
|
||||||
{
|
|
||||||
GFXS_BLENDOP_DISABLED = 0x0,
|
|
||||||
GFXS_BLENDOP_ADD = 0x1,
|
|
||||||
GFXS_BLENDOP_SUBTRACT = 0x2,
|
|
||||||
GFXS_BLENDOP_REVSUBTRACT = 0x3,
|
|
||||||
GFXS_BLENDOP_MIN = 0x4,
|
|
||||||
GFXS_BLENDOP_MAX = 0x5,
|
|
||||||
|
|
||||||
GFXS_BLENDOP_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GfxAlphaTest_e
|
|
||||||
{
|
|
||||||
GFXS_ALPHA_TEST_GT_0 = 1,
|
|
||||||
GFXS_ALPHA_TEST_LT_128 = 2,
|
|
||||||
GFXS_ALPHA_TEST_GE_128 = 3,
|
|
||||||
|
|
||||||
GFXS_ALPHA_TEST_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GfxCullFace_e
|
|
||||||
{
|
|
||||||
GFXS_CULL_NONE = 1,
|
|
||||||
GFXS_CULL_BACK = 2,
|
|
||||||
GFXS_CULL_FRONT = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GfxDepthTest_e
|
|
||||||
{
|
|
||||||
GFXS_DEPTHTEST_ALWAYS = 0,
|
|
||||||
GFXS_DEPTHTEST_LESS = 1,
|
|
||||||
GFXS_DEPTHTEST_EQUAL = 2,
|
|
||||||
GFXS_DEPTHTEST_LESSEQUAL = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GfxPolygonOffset_e
|
|
||||||
{
|
|
||||||
GFXS_POLYGON_OFFSET_0 = 0,
|
|
||||||
GFXS_POLYGON_OFFSET_1 = 1,
|
|
||||||
GFXS_POLYGON_OFFSET_2 = 2,
|
|
||||||
GFXS_POLYGON_OFFSET_SHADOWMAP = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GfxStencilOp
|
|
||||||
{
|
|
||||||
GFXS_STENCILOP_KEEP = 0x0,
|
|
||||||
GFXS_STENCILOP_ZERO = 0x1,
|
|
||||||
GFXS_STENCILOP_REPLACE = 0x2,
|
|
||||||
GFXS_STENCILOP_INCRSAT = 0x3,
|
|
||||||
GFXS_STENCILOP_DECRSAT = 0x4,
|
|
||||||
GFXS_STENCILOP_INVERT = 0x5,
|
|
||||||
GFXS_STENCILOP_INCR = 0x6,
|
|
||||||
GFXS_STENCILOP_DECR = 0x7
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GfxStencilFunc
|
|
||||||
{
|
|
||||||
GFXS_STENCILFUNC_NEVER = 0x0,
|
|
||||||
GFXS_STENCILFUNC_LESS = 0x1,
|
|
||||||
GFXS_STENCILFUNC_EQUAL = 0x2,
|
|
||||||
GFXS_STENCILFUNC_LESSEQUAL = 0x3,
|
|
||||||
GFXS_STENCILFUNC_GREATER = 0x4,
|
|
||||||
GFXS_STENCILFUNC_NOTEQUAL = 0x5,
|
|
||||||
GFXS_STENCILFUNC_GREATEREQUAL = 0x6,
|
|
||||||
GFXS_STENCILFUNC_ALWAYS = 0x7
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GfxStateBitsLoadBitsStructured
|
|
||||||
{
|
|
||||||
// Byte 0
|
|
||||||
unsigned int srcBlendRgb : 4; // 0-3
|
|
||||||
unsigned int dstBlendRgb : 4; // 4-7
|
|
||||||
unsigned int blendOpRgb : 3; // 8-10
|
|
||||||
unsigned int alphaTestDisabled : 1; // 11
|
|
||||||
unsigned int alphaTest : 2; // 12-13
|
|
||||||
unsigned int cullFace : 2; // 14-15
|
|
||||||
unsigned int srcBlendAlpha : 4; // 16-19
|
|
||||||
unsigned int dstBlendAlpha : 4; // 20-23
|
|
||||||
unsigned int blendOpAlpha : 3; // 24-26
|
|
||||||
unsigned int colorWriteRgb : 1; // 27
|
|
||||||
unsigned int colorWriteAlpha : 1; // 28
|
|
||||||
unsigned int unused0 : 1; // 29
|
|
||||||
unsigned int gammaWrite : 1; // 30
|
|
||||||
unsigned int polymodeLine : 1; // 31
|
|
||||||
|
|
||||||
// Byte 1
|
|
||||||
unsigned int depthWrite : 1; // 0
|
|
||||||
unsigned int depthTestDisabled : 1; // 1
|
|
||||||
unsigned int depthTest : 2; // 2-3
|
|
||||||
unsigned int polygonOffset : 2; // 4-5
|
|
||||||
unsigned int stencilFrontEnabled : 1; // 6
|
|
||||||
unsigned int stencilBackEnabled : 1; // 7
|
|
||||||
unsigned int stencilFrontPass : 3; // 8-10
|
|
||||||
unsigned int stencilFrontFail : 3; // 11-13
|
|
||||||
unsigned int stencilFrontZFail : 3; // 14-16
|
|
||||||
unsigned int stencilFrontFunc : 3; // 17-19
|
|
||||||
unsigned int stencilBackPass : 3; // 20-22
|
|
||||||
unsigned int stencilBackFail : 3; // 23-25
|
|
||||||
unsigned int stencilBackZFail : 3; // 26-28
|
|
||||||
unsigned int stencilBackFunc : 3; // 29-31
|
|
||||||
};
|
|
||||||
|
|
||||||
union GfxStateBitsLoadBits
|
|
||||||
{
|
|
||||||
unsigned int raw[2];
|
|
||||||
GfxStateBitsLoadBitsStructured structured;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifndef __zonecodegenerator
|
|
||||||
static_assert(sizeof(GfxStateBitsLoadBits) == 8);
|
|
||||||
static_assert(sizeof(GfxStateBitsLoadBitsStructured) == 8);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct GfxStateBits
|
struct GfxStateBits
|
||||||
{
|
{
|
||||||
GfxStateBitsLoadBits loadBits;
|
unsigned int loadBits[2];
|
||||||
};
|
|
||||||
|
|
||||||
enum GfxCameraRegionType
|
|
||||||
{
|
|
||||||
CAMERA_REGION_LIT_OPAQUE = 0x0,
|
|
||||||
CAMERA_REGION_LIT_TRANS = 0x1,
|
|
||||||
CAMERA_REGION_EMISSIVE = 0x2,
|
|
||||||
CAMERA_REGION_DEPTH_HACK = 0x3,
|
|
||||||
CAMERA_REGION_LIGHT_MAP_OPAQUE = 0x4,
|
|
||||||
|
|
||||||
CAMERA_REGION_COUNT,
|
|
||||||
CAMERA_REGION_NONE = CAMERA_REGION_COUNT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
MaterialInfo info;
|
MaterialInfo info;
|
||||||
char stateBitsEntry[54];
|
unsigned char stateBitsEntry[54];
|
||||||
unsigned char textureCount;
|
unsigned char textureCount;
|
||||||
unsigned char constantCount;
|
unsigned char constantCount;
|
||||||
unsigned char stateBitsCount;
|
unsigned char stateBitsCount;
|
||||||
@ -1143,6 +901,9 @@ namespace IW5
|
|||||||
// IDirect3DTexture9* map;
|
// IDirect3DTexture9* map;
|
||||||
// IDirect3DVolumeTexture9* volmap;
|
// IDirect3DVolumeTexture9* volmap;
|
||||||
// IDirect3DCubeTexture9* cubemap;
|
// IDirect3DCubeTexture9* cubemap;
|
||||||
|
#ifndef __ida
|
||||||
|
Texture* texture;
|
||||||
|
#endif
|
||||||
GfxImageLoadDef* loadDef;
|
GfxImageLoadDef* loadDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3691,7 +3452,7 @@ namespace IW5
|
|||||||
HITLOC_GUN = 0x12,
|
HITLOC_GUN = 0x12,
|
||||||
HITLOC_SHIELD = 0x13,
|
HITLOC_SHIELD = 0x13,
|
||||||
|
|
||||||
HITLOC_COUNT
|
HITLOC_NUM
|
||||||
};
|
};
|
||||||
|
|
||||||
enum materialSurfType_t
|
enum materialSurfType_t
|
||||||
@ -3995,12 +3756,15 @@ namespace IW5
|
|||||||
float fHipViewScatterMax;
|
float fHipViewScatterMax;
|
||||||
float fightDist;
|
float fightDist;
|
||||||
float maxDist;
|
float maxDist;
|
||||||
const char* aiVsAiAccuracyGraphName;
|
// const char* accuracyGraphName[2];// TODO: Order is accuracyGraphName[0] -> originalAccuracyGraphKnots[0] -> accuracyGraphName[1] -> ...
|
||||||
const char* aiVsPlayerAccuracyGraphName;
|
// Which is currently not possible to do in code generation. Afaik this is the only place where this is the case.
|
||||||
vec2_t* originalAiVsAiAccuracyGraphKnots;
|
// So might be something to fix but on the other hand it might be too much work for this little inconvenience.
|
||||||
vec2_t* originalAiVsPlayerAccuracyGraphKnots;
|
// vec2_t* originalAccuracyGraphKnots[2];
|
||||||
unsigned short originalAiVsAiAccuracyGraphKnotCount;
|
const char* accuracyGraphName0;
|
||||||
unsigned short originalAiVsPlayerAccuracyGraphKnotCount;
|
const char* accuracyGraphName1;
|
||||||
|
vec2_t* originalAccuracyGraphKnots0;
|
||||||
|
vec2_t* originalAccuracyGraphKnots1;
|
||||||
|
unsigned short originalAccuracyGraphKnotCount[2];
|
||||||
int iPositionReloadTransTime;
|
int iPositionReloadTransTime;
|
||||||
float leftArc;
|
float leftArc;
|
||||||
float rightArc;
|
float rightArc;
|
||||||
@ -4257,10 +4021,8 @@ namespace IW5
|
|||||||
int ammoDropStockMax;
|
int ammoDropStockMax;
|
||||||
float adsDofStart;
|
float adsDofStart;
|
||||||
float adsDofEnd;
|
float adsDofEnd;
|
||||||
uint16_t aiVsAiAccuracyGraphKnotCount;
|
unsigned short accuracyGraphKnotCount[2];
|
||||||
uint16_t aiVsPlayerAccuracyGraphKnotCount;
|
vec2_t* accuracyGraphKnots[2];
|
||||||
vec2_t* aiVsAiAccuracyGraphKnots;
|
|
||||||
vec2_t* aiVsPlayerAccuracyGraphKnots;
|
|
||||||
bool motionTracker;
|
bool motionTracker;
|
||||||
bool enhanced;
|
bool enhanced;
|
||||||
bool dpadIconShowsAmmo;
|
bool dpadIconShowsAmmo;
|
||||||
@ -4584,8 +4346,7 @@ namespace IW5
|
|||||||
LBCOL_TYPE_BIGNUMBER = 0x4,
|
LBCOL_TYPE_BIGNUMBER = 0x4,
|
||||||
LBCOL_TYPE_PERCENT = 0x5,
|
LBCOL_TYPE_PERCENT = 0x5,
|
||||||
LBCOL_TYPE_TIME_FULL = 0x6,
|
LBCOL_TYPE_TIME_FULL = 0x6,
|
||||||
|
LBCOL_TYPE_COUNT = 0x7
|
||||||
LBCOL_TYPE_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LbAggType
|
enum LbAggType
|
||||||
@ -4594,8 +4355,7 @@ namespace IW5
|
|||||||
LBAGG_TYPE_MAX = 0x1,
|
LBAGG_TYPE_MAX = 0x1,
|
||||||
LBAGG_TYPE_SUM = 0x2,
|
LBAGG_TYPE_SUM = 0x2,
|
||||||
LBAGG_TYPE_LAST = 0x3,
|
LBAGG_TYPE_LAST = 0x3,
|
||||||
|
LBAGG_TYPE_COUNT = 0x4
|
||||||
LBAGG_TYPE_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LbColumnDef
|
struct LbColumnDef
|
||||||
@ -4617,22 +4377,7 @@ namespace IW5
|
|||||||
LBUPDATE_TYPE_NORMAL = 0x0,
|
LBUPDATE_TYPE_NORMAL = 0x0,
|
||||||
LBUPDATE_TYPE_RANK = 0x1,
|
LBUPDATE_TYPE_RANK = 0x1,
|
||||||
LBUPDATE_TYPE_COMBINE = 0x2,
|
LBUPDATE_TYPE_COMBINE = 0x2,
|
||||||
|
LBUPDATE_TYPE_COUNT = 0x3
|
||||||
LBUPDATE_TYPE_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LbTrackType
|
|
||||||
{
|
|
||||||
TRK_ALLTIME = 0x0,
|
|
||||||
TRK_WEEKLY = 0x1,
|
|
||||||
TRK_MONTHLY = 0x2,
|
|
||||||
TRK_PRESTIGE_ALLTIME = 0x3,
|
|
||||||
TRK_PRESTIGE_WEEKLY = 0x4,
|
|
||||||
TRK_PRESTIGE_MONTHLY = 0x5,
|
|
||||||
TRK_DAILY = 0x6,
|
|
||||||
TRK_PRESTIGE_DAILY = 0x7,
|
|
||||||
|
|
||||||
TRK_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LeaderboardDef
|
struct LeaderboardDef
|
||||||
@ -4672,8 +4417,7 @@ namespace IW5
|
|||||||
DATA_ENUM_ARRAY = 0x7,
|
DATA_ENUM_ARRAY = 0x7,
|
||||||
DATA_FLOAT = 0x8,
|
DATA_FLOAT = 0x8,
|
||||||
DATA_SHORT = 0x9,
|
DATA_SHORT = 0x9,
|
||||||
|
DATA_COUNT = 0xA
|
||||||
DATA_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
union StructuredDataTypeUnion
|
union StructuredDataTypeUnion
|
||||||
@ -4700,8 +4444,7 @@ namespace IW5
|
|||||||
VALIDATION_DELTACLAMP = 0x4,
|
VALIDATION_DELTACLAMP = 0x4,
|
||||||
VALIDATION_DELTASTRICT = 0x5,
|
VALIDATION_DELTASTRICT = 0x5,
|
||||||
VALIDATION_XP = 0x6,
|
VALIDATION_XP = 0x6,
|
||||||
|
VALIDATION_COUNT = 0x7
|
||||||
VALIDATION_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StructuredDataStructProperty
|
struct StructuredDataStructProperty
|
||||||
|
@ -58,32 +58,32 @@ int Common::Com_HashString(const char* str, const int len)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in)
|
||||||
{
|
{
|
||||||
return PackedTexCoords{pack32::Vec2PackTexCoordsVU(in)};
|
return PackedTexCoords{Pack32::Vec2PackTexCoords(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3])
|
PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in)
|
||||||
{
|
{
|
||||||
return PackedUnitVec{pack32::Vec3PackUnitVecScaleBased(in)};
|
return PackedUnitVec{Pack32::Vec3PackUnitVec(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxColor Common::Vec4PackGfxColor(const float (&in)[4])
|
GfxColor Common::Vec4PackGfxColor(const vec4_t* in)
|
||||||
{
|
{
|
||||||
return GfxColor{pack32::Vec4PackGfxColor(in)};
|
return GfxColor{Pack32::Vec4PackGfxColor(reinterpret_cast<const float*>(in))};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2])
|
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec2UnpackTexCoordsVU(in.packed, out);
|
Pack32::Vec2UnpackTexCoordsVU(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3])
|
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec3UnpackUnitVecScaleBased(in.packed, out);
|
Pack32::Vec3UnpackUnitVecScaleBased(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4])
|
void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out)
|
||||||
{
|
{
|
||||||
pack32::Vec4UnpackGfxColor(in.packed, out);
|
Pack32::Vec4UnpackGfxColor(in.packed, reinterpret_cast<float*>(out));
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ namespace T5
|
|||||||
static int Com_HashString(const char* str);
|
static int Com_HashString(const char* str);
|
||||||
static int Com_HashString(const char* str, int len);
|
static int Com_HashString(const char* str, int len);
|
||||||
|
|
||||||
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
|
static PackedTexCoords Vec2PackTexCoords(const vec2_t* in);
|
||||||
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
|
static PackedUnitVec Vec3PackUnitVec(const vec3_t* in);
|
||||||
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
|
static GfxColor Vec4PackGfxColor(const vec4_t* in);
|
||||||
static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]);
|
static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out);
|
||||||
static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]);
|
static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out);
|
||||||
static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]);
|
static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out);
|
||||||
};
|
};
|
||||||
} // namespace T5
|
} // namespace T5
|
||||||
|
@ -1,32 +1,29 @@
|
|||||||
#include "GameT5.h"
|
#include "GameT5.h"
|
||||||
|
|
||||||
|
#include "T5.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace T5;
|
using namespace T5;
|
||||||
|
|
||||||
GameId Game::GetId() const
|
GameT5 g_GameT5;
|
||||||
|
|
||||||
|
std::string GameT5::GetFullName()
|
||||||
{
|
{
|
||||||
return GameId::T5;
|
return "Call Of Duty: Black Ops";
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetFullName() const
|
std::string GameT5::GetShortName()
|
||||||
{
|
{
|
||||||
static std::string fullName = "Call Of Duty: Black Ops";
|
return "T5";
|
||||||
return fullName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetShortName() const
|
void GameT5::AddZone(Zone* zone)
|
||||||
{
|
|
||||||
static std::string shortName = "T5";
|
|
||||||
return shortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::AddZone(Zone* zone)
|
|
||||||
{
|
{
|
||||||
m_zones.push_back(zone);
|
m_zones.push_back(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::RemoveZone(Zone* zone)
|
void GameT5::RemoveZone(Zone* zone)
|
||||||
{
|
{
|
||||||
const auto foundEntry = std::ranges::find(m_zones, zone);
|
const auto foundEntry = std::ranges::find(m_zones, zone);
|
||||||
|
|
||||||
@ -34,28 +31,28 @@ void Game::RemoveZone(Zone* zone)
|
|||||||
m_zones.erase(foundEntry);
|
m_zones.erase(foundEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Zone*>& Game::GetZones() const
|
std::vector<Zone*> GameT5::GetZones()
|
||||||
{
|
{
|
||||||
return m_zones;
|
return m_zones;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<GameLanguagePrefix>& Game::GetLanguagePrefixes() const
|
std::vector<GameLanguagePrefix> GameT5::GetLanguagePrefixes()
|
||||||
{
|
{
|
||||||
static std::vector<GameLanguagePrefix> prefixes{
|
std::vector<GameLanguagePrefix> prefixes;
|
||||||
{GameLanguage::LANGUAGE_ENGLISH, "en_"},
|
|
||||||
{GameLanguage::LANGUAGE_FRENCH, "fr_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_ENGLISH, "en_");
|
||||||
{GameLanguage::LANGUAGE_FRENCH_CAN, "fc_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_FRENCH, "fr_");
|
||||||
{GameLanguage::LANGUAGE_GERMAN, "ge_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_FRENCH_CAN, "fc_");
|
||||||
{GameLanguage::LANGUAGE_AUSTRIAN, "ge_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_GERMAN, "ge_");
|
||||||
{GameLanguage::LANGUAGE_ITALIAN, "it_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_AUSTRIAN, "ge_");
|
||||||
{GameLanguage::LANGUAGE_SPANISH, "sp_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_ITALIAN, "it_");
|
||||||
{GameLanguage::LANGUAGE_BRITISH, "br_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_SPANISH, "sp_");
|
||||||
{GameLanguage::LANGUAGE_RUSSIAN, "ru_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_BRITISH, "br_");
|
||||||
{GameLanguage::LANGUAGE_POLISH, "po_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_RUSSIAN, "ru_");
|
||||||
{GameLanguage::LANGUAGE_KOREAN, "ko_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_POLISH, "po_");
|
||||||
{GameLanguage::LANGUAGE_JAPANESE, "ja_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_KOREAN, "ko_");
|
||||||
{GameLanguage::LANGUAGE_CZECH, "cz_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_JAPANESE, "ja_");
|
||||||
};
|
prefixes.emplace_back(GameLanguage::LANGUAGE_CZECH, "cz_");
|
||||||
|
|
||||||
return prefixes;
|
return prefixes;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Game/IGame.h"
|
#include "Game/IGame.h"
|
||||||
|
|
||||||
namespace T5
|
class GameT5 : public IGame
|
||||||
{
|
{
|
||||||
class Game final : public IGame
|
std::vector<Zone*> m_zones;
|
||||||
{
|
|
||||||
public:
|
|
||||||
[[nodiscard]] GameId GetId() const override;
|
|
||||||
[[nodiscard]] const std::string& GetFullName() const override;
|
|
||||||
[[nodiscard]] const std::string& GetShortName() const override;
|
|
||||||
void AddZone(Zone* zone) override;
|
|
||||||
void RemoveZone(Zone* zone) override;
|
|
||||||
[[nodiscard]] const std::vector<Zone*>& GetZones() const override;
|
|
||||||
[[nodiscard]] const std::vector<GameLanguagePrefix>& GetLanguagePrefixes() const override;
|
|
||||||
|
|
||||||
private:
|
public:
|
||||||
std::vector<Zone*> m_zones;
|
std::string GetFullName() override;
|
||||||
};
|
std::string GetShortName() override;
|
||||||
} // namespace T5
|
void AddZone(Zone* zone) override;
|
||||||
|
void RemoveZone(Zone* zone) override;
|
||||||
|
std::vector<Zone*> GetZones() override;
|
||||||
|
std::vector<GameLanguagePrefix> GetLanguagePrefixes() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GameT5 g_GameT5;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// clang-format off: Order of includes matters here
|
// clang-format off: Order of includes matters here
|
||||||
|
|
||||||
// #include <d3d9.h>
|
// #include <d3d9.h>
|
||||||
#include "Game/IAsset.h"
|
#include "Image/Texture.h"
|
||||||
|
|
||||||
#include "T5_Assets.h"
|
#include "T5_Assets.h"
|
||||||
|
|
||||||
@ -114,72 +114,4 @@ namespace T5
|
|||||||
|
|
||||||
CFT_NUM_FIELD_TYPES
|
CFT_NUM_FIELD_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
|
|
||||||
using AssetPhysConstraints = Asset<ASSET_TYPE_PHYSCONSTRAINTS, PhysConstraints>;
|
|
||||||
using AssetDestructibleDef = Asset<ASSET_TYPE_DESTRUCTIBLEDEF, DestructibleDef>;
|
|
||||||
using AssetXAnim = Asset<ASSET_TYPE_XANIMPARTS, XAnimParts>;
|
|
||||||
using AssetXModel = Asset<ASSET_TYPE_XMODEL, XModel>;
|
|
||||||
using AssetMaterial = Asset<ASSET_TYPE_MATERIAL, Material>;
|
|
||||||
using AssetTechniqueSet = Asset<ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet>;
|
|
||||||
using AssetImage = Asset<ASSET_TYPE_IMAGE, GfxImage>;
|
|
||||||
using AssetSoundBank = Asset<ASSET_TYPE_SOUND, SndBank>;
|
|
||||||
using AssetSoundPatch = Asset<ASSET_TYPE_SOUND_PATCH, SndPatch>;
|
|
||||||
using AssetClipMap = Asset<ASSET_TYPE_CLIPMAP, clipMap_t>;
|
|
||||||
using AssetClipMapPvs = Asset<ASSET_TYPE_CLIPMAP_PVS, clipMap_t>;
|
|
||||||
using AssetComWorld = Asset<ASSET_TYPE_COMWORLD, ComWorld>;
|
|
||||||
using AssetGameWorldSp = Asset<ASSET_TYPE_GAMEWORLD_SP, GameWorldSp>;
|
|
||||||
using AssetGameWorldMp = Asset<ASSET_TYPE_GAMEWORLD_MP, GameWorldMp>;
|
|
||||||
using AssetMapEnts = Asset<ASSET_TYPE_MAP_ENTS, MapEnts>;
|
|
||||||
using AssetGfxWorld = Asset<ASSET_TYPE_GFXWORLD, GfxWorld>;
|
|
||||||
using AssetLightDef = Asset<ASSET_TYPE_LIGHT_DEF, GfxLightDef>;
|
|
||||||
using AssetFont = Asset<ASSET_TYPE_FONT, Font_s>;
|
|
||||||
using AssetMenuList = Asset<ASSET_TYPE_MENULIST, MenuList>;
|
|
||||||
using AssetMenu = Asset<ASSET_TYPE_MENU, menuDef_t>;
|
|
||||||
using AssetLocalize = Asset<ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry>;
|
|
||||||
using AssetWeapon = Asset<ASSET_TYPE_WEAPON, WeaponVariantDef>;
|
|
||||||
using AssetSoundDriverGlobals = Asset<ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals>;
|
|
||||||
using AssetFx = Asset<ASSET_TYPE_FX, FxEffectDef>;
|
|
||||||
using AssetImpactFx = Asset<ASSET_TYPE_IMPACT_FX, FxImpactTable>;
|
|
||||||
using AssetRawFile = Asset<ASSET_TYPE_RAWFILE, RawFile>;
|
|
||||||
using AssetStringTable = Asset<ASSET_TYPE_STRINGTABLE, StringTable>;
|
|
||||||
using AssetPackIndex = Asset<ASSET_TYPE_PACK_INDEX, PackIndex>;
|
|
||||||
using AssetXGlobals = Asset<ASSET_TYPE_XGLOBALS, XGlobals>;
|
|
||||||
using AssetDDL = Asset<ASSET_TYPE_DDL, ddlRoot_t>;
|
|
||||||
using AssetGlasses = Asset<ASSET_TYPE_GLASSES, Glasses>;
|
|
||||||
using AssetEmblemSet = Asset<ASSET_TYPE_EMBLEMSET, EmblemSet>;
|
|
||||||
} // namespace T5
|
} // namespace T5
|
||||||
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetPhysPreset, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetPhysConstraints, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetDestructibleDef, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetXAnim, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetXModel, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetMaterial, info.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetTechniqueSet, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetImage, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetSoundBank, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetSoundPatch, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetClipMap, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetClipMapPvs, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetComWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetGameWorldSp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetGameWorldMp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetMapEnts, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetGfxWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetLightDef, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetFont, fontName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetMenuList, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetMenu, window.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetLocalize, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetWeapon, szInternalName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetSoundDriverGlobals, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetFx, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR_SINGLETON(T5::AssetImpactFx, "ImpactFx");
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetRawFile, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetStringTable, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetPackIndex, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetXGlobals, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetDDL, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T5::AssetGlasses, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR_SINGLETON(T5::AssetEmblemSet, "EmblemSet");
|
|
||||||
|
@ -108,49 +108,9 @@ namespace T5
|
|||||||
MAX_XFILE_COUNT
|
MAX_XFILE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
union vec2_t
|
typedef float vec2_t[2];
|
||||||
{
|
typedef float vec3_t[3];
|
||||||
float v[2];
|
typedef float vec4_t[4];
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
union vec3_t
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
};
|
|
||||||
|
|
||||||
float v[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
union vec4_t
|
|
||||||
{
|
|
||||||
float v[4];
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
float w;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
float r;
|
|
||||||
float g;
|
|
||||||
float b;
|
|
||||||
float a;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
union XAssetHeader
|
union XAssetHeader
|
||||||
{
|
{
|
||||||
@ -206,10 +166,10 @@ namespace T5
|
|||||||
typedef tdef_align(128) float float_align128;
|
typedef tdef_align(128) float float_align128;
|
||||||
|
|
||||||
typedef char cbrushedge_t;
|
typedef char cbrushedge_t;
|
||||||
|
typedef float vec2_t[2];
|
||||||
|
typedef float vec3_t[3];
|
||||||
typedef tdef_align(128) unsigned int raw_uint128;
|
typedef tdef_align(128) unsigned int raw_uint128;
|
||||||
|
|
||||||
typedef uint16_t ScriptString;
|
|
||||||
|
|
||||||
struct PhysPreset
|
struct PhysPreset
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
@ -461,8 +421,8 @@ namespace T5
|
|||||||
|
|
||||||
struct DObjAnimMat
|
struct DObjAnimMat
|
||||||
{
|
{
|
||||||
vec4_t quat;
|
float quat[4];
|
||||||
vec3_t trans;
|
float trans[3];
|
||||||
float transWeight;
|
float transWeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -492,7 +452,7 @@ namespace T5
|
|||||||
|
|
||||||
struct type_align(16) GfxPackedVertex
|
struct type_align(16) GfxPackedVertex
|
||||||
{
|
{
|
||||||
vec3_t xyz;
|
float xyz[3];
|
||||||
float binormalSign;
|
float binormalSign;
|
||||||
GfxColor color;
|
GfxColor color;
|
||||||
PackedTexCoords texCoord;
|
PackedTexCoords texCoord;
|
||||||
@ -537,12 +497,7 @@ namespace T5
|
|||||||
XSurfaceCollisionTree* collisionTree;
|
XSurfaceCollisionTree* collisionTree;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XSurfaceTri
|
typedef tdef_align(16) uint16_t r_index16_t;
|
||||||
{
|
|
||||||
uint16_t i[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef tdef_align(16) XSurfaceTri XSurfaceTri16;
|
|
||||||
|
|
||||||
struct XSurface
|
struct XSurface
|
||||||
{
|
{
|
||||||
@ -553,7 +508,7 @@ namespace T5
|
|||||||
uint16_t triCount;
|
uint16_t triCount;
|
||||||
uint16_t baseTriIndex;
|
uint16_t baseTriIndex;
|
||||||
uint16_t baseVertIndex;
|
uint16_t baseVertIndex;
|
||||||
XSurfaceTri16* triIndices;
|
r_index16_t (*triIndices)[3];
|
||||||
XSurfaceVertexInfo vertInfo;
|
XSurfaceVertexInfo vertInfo;
|
||||||
GfxPackedVertex* verts0;
|
GfxPackedVertex* verts0;
|
||||||
void /*IDirect3DVertexBuffer9*/* vb0;
|
void /*IDirect3DVertexBuffer9*/* vb0;
|
||||||
@ -594,8 +549,8 @@ namespace T5
|
|||||||
|
|
||||||
struct XBoneInfo
|
struct XBoneInfo
|
||||||
{
|
{
|
||||||
vec3_t bounds[2];
|
float bounds[2][3];
|
||||||
vec3_t offset;
|
float offset[3];
|
||||||
float radiusSquared;
|
float radiusSquared;
|
||||||
char collmap;
|
char collmap;
|
||||||
};
|
};
|
||||||
@ -664,31 +619,18 @@ namespace T5
|
|||||||
PhysGeomList* geomList;
|
PhysGeomList* geomList;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum XModelLodRampType : unsigned char
|
|
||||||
{
|
|
||||||
XMODEL_LOD_RAMP_RIGID = 0x0,
|
|
||||||
XMODEL_LOD_RAMP_SKINNED = 0x1,
|
|
||||||
|
|
||||||
XMODEL_LOD_RAMP_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
struct XModelQuat
|
|
||||||
{
|
|
||||||
int16_t v[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct XModel
|
struct XModel
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
unsigned char numBones;
|
unsigned char numBones;
|
||||||
unsigned char numRootBones;
|
unsigned char numRootBones;
|
||||||
unsigned char numsurfs;
|
unsigned char numsurfs;
|
||||||
XModelLodRampType lodRampType;
|
char lodRampType;
|
||||||
ScriptString* boneNames;
|
uint16_t* boneNames;
|
||||||
unsigned char* parentList;
|
char* parentList;
|
||||||
XModelQuat* quats;
|
int16_t (*quats)[4];
|
||||||
float* trans;
|
float (*trans)[4];
|
||||||
unsigned char* partClassification;
|
char* partClassification;
|
||||||
DObjAnimMat* baseMat;
|
DObjAnimMat* baseMat;
|
||||||
XSurface* surfs;
|
XSurface* surfs;
|
||||||
Material** materialHandles;
|
Material** materialHandles;
|
||||||
@ -699,13 +641,13 @@ namespace T5
|
|||||||
int contents;
|
int contents;
|
||||||
XBoneInfo* boneInfo;
|
XBoneInfo* boneInfo;
|
||||||
float radius;
|
float radius;
|
||||||
vec3_t mins;
|
float mins[3];
|
||||||
vec3_t maxs;
|
float maxs[3];
|
||||||
uint16_t numLods;
|
uint16_t numLods;
|
||||||
int16_t collLod;
|
uint16_t collLod;
|
||||||
XModelStreamInfo streamInfo;
|
XModelStreamInfo streamInfo;
|
||||||
int memUsage;
|
int memUsage;
|
||||||
unsigned int flags;
|
int flags;
|
||||||
bool bad;
|
bool bad;
|
||||||
PhysPreset* physPreset;
|
PhysPreset* physPreset;
|
||||||
unsigned char numCollmaps;
|
unsigned char numCollmaps;
|
||||||
@ -790,7 +732,7 @@ namespace T5
|
|||||||
char nameStart;
|
char nameStart;
|
||||||
char nameEnd;
|
char nameEnd;
|
||||||
char samplerState;
|
char samplerState;
|
||||||
unsigned char semantic; // TextureSemantic
|
char semantic;
|
||||||
char isMatureContent;
|
char isMatureContent;
|
||||||
char pad[3];
|
char pad[3];
|
||||||
MaterialTextureDefInfo u;
|
MaterialTextureDefInfo u;
|
||||||
@ -1024,6 +966,7 @@ namespace T5
|
|||||||
// IDirect3DTexture9* map;
|
// IDirect3DTexture9* map;
|
||||||
// IDirect3DVolumeTexture9* volmap;
|
// IDirect3DVolumeTexture9* volmap;
|
||||||
// IDirect3DCubeTexture9* cubemap;
|
// IDirect3DCubeTexture9* cubemap;
|
||||||
|
Texture* texture;
|
||||||
GfxImageLoadDef* loadDef;
|
GfxImageLoadDef* loadDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1311,7 +1254,7 @@ namespace T5
|
|||||||
|
|
||||||
struct SndPatch
|
struct SndPatch
|
||||||
{
|
{
|
||||||
const char* name;
|
char* name;
|
||||||
unsigned int elementCount;
|
unsigned int elementCount;
|
||||||
unsigned int* elements;
|
unsigned int* elements;
|
||||||
unsigned int fileCount;
|
unsigned int fileCount;
|
||||||
@ -3345,7 +3288,7 @@ namespace T5
|
|||||||
HITLOC_L_FOOT = 0x11,
|
HITLOC_L_FOOT = 0x11,
|
||||||
HITLOC_GUN = 0x12,
|
HITLOC_GUN = 0x12,
|
||||||
|
|
||||||
HITLOC_COUNT
|
HITLOC_NUM
|
||||||
};
|
};
|
||||||
|
|
||||||
struct flameTable
|
struct flameTable
|
||||||
@ -3918,16 +3861,20 @@ namespace T5
|
|||||||
float fHipViewScatterMax;
|
float fHipViewScatterMax;
|
||||||
float fightDist;
|
float fightDist;
|
||||||
float maxDist;
|
float maxDist;
|
||||||
const char* aiVsAiAccuracyGraphName;
|
// const char *accuracyGraphName[2]; // TODO: Order is accuracyGraphName[0] -> accuracyGraphKnots[0] -> originalAccuracyGraphKnots[0] ->
|
||||||
const char* aiVsPlayerAccuracyGraphName;
|
// accuracyGraphName[1] -> ...
|
||||||
vec2_t* aiVsAiAccuracyGraphKnots;
|
// Which is currently not possible to do in code generation. Afaik this is the only place where this is the case.
|
||||||
vec2_t* aiVsPlayerAccuracyGraphKnots;
|
// So might be something to fix but on the other hand it might be too much work for this little inconvenience.
|
||||||
vec2_t* originalAiVsAiAccuracyGraphKnots;
|
const char* accuracyGraphName0;
|
||||||
vec2_t* originalAiVsPlayerAccuracyGraphKnots;
|
const char* accuracyGraphName1;
|
||||||
int aiVsAiAccuracyGraphKnotCount;
|
// vec2_t *accuracyGraphKnots[2];
|
||||||
int aiVsPlayerAccuracyGraphKnotCount;
|
vec2_t* accuracyGraphKnots0;
|
||||||
int originalAiVsAiAccuracyGraphKnotCount;
|
vec2_t* accuracyGraphKnots1;
|
||||||
int originalAiVsPlayerAccuracyGraphKnotCount;
|
// vec2_t *originalAccuracyGraphKnots[2];
|
||||||
|
vec2_t* originalAccuracyGraphKnots0;
|
||||||
|
vec2_t* originalAccuracyGraphKnots1;
|
||||||
|
int accuracyGraphKnotCount[2];
|
||||||
|
int originalAccuracyGraphKnotCount[2];
|
||||||
int iPositionReloadTransTime;
|
int iPositionReloadTransTime;
|
||||||
float leftArc;
|
float leftArc;
|
||||||
float rightArc;
|
float rightArc;
|
||||||
|
@ -2,61 +2,88 @@
|
|||||||
|
|
||||||
#include "Utils/Pack.h"
|
#include "Utils/Pack.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <cctype>
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
PackedTexCoords Common::Vec2PackTexCoords(const float (&in)[2])
|
int Common::Com_HashKey(const char* str, const int maxLen)
|
||||||
{
|
{
|
||||||
return PackedTexCoords{pack32::Vec2PackTexCoordsUV(in)};
|
if (str == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int hash = 0;
|
||||||
|
for (int i = 0; i < maxLen; i++)
|
||||||
|
{
|
||||||
|
if (str[i] == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
hash += str[i] * (0x77 + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash ^ ((hash ^ (hash >> 10)) >> 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedUnitVec Common::Vec3PackUnitVec(const float (&in)[3])
|
int Common::Com_HashString(const char* str)
|
||||||
{
|
{
|
||||||
return PackedUnitVec{pack32::Vec3PackUnitVecThirdBased(in)};
|
if (!str)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto result = 0x1505;
|
||||||
|
auto offset = 0;
|
||||||
|
while (str[offset])
|
||||||
|
{
|
||||||
|
const auto c = tolower(str[offset++]);
|
||||||
|
result = c + 33 * result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxColor Common::Vec4PackGfxColor(const float (&in)[4])
|
int Common::Com_HashString(const char* str, const int len)
|
||||||
{
|
{
|
||||||
return GfxColor{pack32::Vec4PackGfxColor(in)};
|
if (!str)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int result = 0x1505;
|
||||||
|
int offset = 0;
|
||||||
|
while (str[offset])
|
||||||
|
{
|
||||||
|
if (len > 0 && offset >= len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const int c = tolower(str[offset++]);
|
||||||
|
result = c + 33 * result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2])
|
PackedTexCoords Common::Vec2PackTexCoords(const vec2_t* in)
|
||||||
{
|
{
|
||||||
pack32::Vec2UnpackTexCoordsUV(in.packed, out);
|
return PackedTexCoords{Pack32::Vec2PackTexCoords(in->v)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3])
|
PackedUnitVec Common::Vec3PackUnitVec(const vec3_t* in)
|
||||||
{
|
{
|
||||||
pack32::Vec3UnpackUnitVecThirdBased(in.packed, out);
|
return PackedUnitVec{Pack32::Vec3PackUnitVec(in->v)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Common::Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4])
|
GfxColor Common::Vec4PackGfxColor(const vec4_t* in)
|
||||||
{
|
{
|
||||||
pack32::Vec4UnpackGfxColor(in.packed, out);
|
return GfxColor{Pack32::Vec4PackGfxColor(in->v)};
|
||||||
}
|
}
|
||||||
|
|
||||||
float Common::LinearToDbspl(const float linear)
|
void Common::Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out)
|
||||||
{
|
{
|
||||||
const auto db = 20.0f * std::log10(std::max(linear, 0.0000152879f));
|
Pack32::Vec2UnpackTexCoordsUV(in.packed, out->v);
|
||||||
if (db > -95.0f)
|
|
||||||
return db + 100.0f;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float Common::DbsplToLinear(const float dbsplValue)
|
void Common::Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out)
|
||||||
{
|
{
|
||||||
return std::pow(10.0f, (dbsplValue - 100.0f) / 20.0f);
|
Pack32::Vec3UnpackUnitVecThirdBased(in.packed, out->v);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Common::HertzToCents(const float hertz)
|
void Common::Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out)
|
||||||
{
|
{
|
||||||
return 1200.0f * std::log2(hertz);
|
Pack32::Vec4UnpackGfxColor(in.packed, out->v);
|
||||||
}
|
|
||||||
|
|
||||||
float Common::CentsToHertz(const float cents)
|
|
||||||
{
|
|
||||||
return std::pow(2.0f, cents / 1200.0f);
|
|
||||||
}
|
}
|
||||||
|
@ -2,64 +2,14 @@
|
|||||||
|
|
||||||
#include "T6.h"
|
#include "T6.h"
|
||||||
|
|
||||||
#include <cctype>
|
|
||||||
|
|
||||||
namespace T6
|
namespace T6
|
||||||
{
|
{
|
||||||
class Common
|
class Common
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr int Com_HashKey(const char* str, const int maxLen)
|
static int Com_HashKey(const char* str, int maxLen);
|
||||||
{
|
static int Com_HashString(const char* str);
|
||||||
if (str == nullptr)
|
static int Com_HashString(const char* str, int len);
|
||||||
return 0;
|
|
||||||
|
|
||||||
int hash = 0;
|
|
||||||
for (int i = 0; i < maxLen; i++)
|
|
||||||
{
|
|
||||||
if (str[i] == '\0')
|
|
||||||
break;
|
|
||||||
|
|
||||||
hash += str[i] * (0x77 + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash ^ ((hash ^ (hash >> 10)) >> 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr int Com_HashString(const char* str)
|
|
||||||
{
|
|
||||||
if (!str)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
auto result = 0x1505;
|
|
||||||
auto offset = 0;
|
|
||||||
while (str[offset])
|
|
||||||
{
|
|
||||||
const auto c = tolower(str[offset++]);
|
|
||||||
result = c + 33 * result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr int Com_HashString(const char* str, const int len)
|
|
||||||
{
|
|
||||||
if (!str)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int result = 0x1505;
|
|
||||||
int offset = 0;
|
|
||||||
while (str[offset])
|
|
||||||
{
|
|
||||||
if (len > 0 && offset >= len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const int c = tolower(str[offset++]);
|
|
||||||
result = c + 33 * result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* str, uint32_t hash)
|
static constexpr uint32_t R_HashString(const char* str, uint32_t hash)
|
||||||
{
|
{
|
||||||
@ -71,11 +21,6 @@ namespace T6
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint32_t R_HashString(const char* string)
|
|
||||||
{
|
|
||||||
return R_HashString(string, 0u);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr uint32_t SND_HashName(const char* str)
|
static constexpr uint32_t SND_HashName(const char* str)
|
||||||
{
|
{
|
||||||
if (!str || !*str)
|
if (!str || !*str)
|
||||||
@ -96,15 +41,11 @@ namespace T6
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PackedTexCoords Vec2PackTexCoords(const float (&in)[2]);
|
static PackedTexCoords Vec2PackTexCoords(const vec2_t* in);
|
||||||
static PackedUnitVec Vec3PackUnitVec(const float (&in)[3]);
|
static PackedUnitVec Vec3PackUnitVec(const vec3_t* in);
|
||||||
static GfxColor Vec4PackGfxColor(const float (&in)[4]);
|
static GfxColor Vec4PackGfxColor(const vec4_t* in);
|
||||||
static void Vec2UnpackTexCoords(const PackedTexCoords& in, float (&out)[2]);
|
static void Vec2UnpackTexCoords(const PackedTexCoords& in, vec2_t* out);
|
||||||
static void Vec3UnpackUnitVec(const PackedUnitVec& in, float (&out)[3]);
|
static void Vec3UnpackUnitVec(const PackedUnitVec& in, vec3_t* out);
|
||||||
static void Vec4UnpackGfxColor(const GfxColor& in, float (&out)[4]);
|
static void Vec4UnpackGfxColor(const GfxColor& in, vec4_t* out);
|
||||||
static float LinearToDbspl(const float linear);
|
|
||||||
static float DbsplToLinear(const float dbsplValue);
|
|
||||||
static float HertzToCents(const float hertz);
|
|
||||||
static float CentsToHertz(const float cents);
|
|
||||||
};
|
};
|
||||||
} // namespace T6
|
} // namespace T6
|
||||||
|
@ -1,32 +1,29 @@
|
|||||||
#include "GameT6.h"
|
#include "GameT6.h"
|
||||||
|
|
||||||
|
#include "T6.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
GameId Game::GetId() const
|
GameT6 g_GameT6;
|
||||||
|
|
||||||
|
std::string GameT6::GetFullName()
|
||||||
{
|
{
|
||||||
return GameId::T6;
|
return "Call Of Duty: Black Ops II";
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetFullName() const
|
std::string GameT6::GetShortName()
|
||||||
{
|
{
|
||||||
static std::string fullName = "Call Of Duty: Black Ops II";
|
return "T6";
|
||||||
return fullName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& Game::GetShortName() const
|
void GameT6::AddZone(Zone* zone)
|
||||||
{
|
|
||||||
static std::string shortName = "T6";
|
|
||||||
return shortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::AddZone(Zone* zone)
|
|
||||||
{
|
{
|
||||||
m_zones.push_back(zone);
|
m_zones.push_back(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::RemoveZone(Zone* zone)
|
void GameT6::RemoveZone(Zone* zone)
|
||||||
{
|
{
|
||||||
const auto foundEntry = std::ranges::find(m_zones, zone);
|
const auto foundEntry = std::ranges::find(m_zones, zone);
|
||||||
|
|
||||||
@ -34,31 +31,31 @@ void Game::RemoveZone(Zone* zone)
|
|||||||
m_zones.erase(foundEntry);
|
m_zones.erase(foundEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Zone*>& Game::GetZones() const
|
std::vector<Zone*> GameT6::GetZones()
|
||||||
{
|
{
|
||||||
return m_zones;
|
return m_zones;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<GameLanguagePrefix>& Game::GetLanguagePrefixes() const
|
std::vector<GameLanguagePrefix> GameT6::GetLanguagePrefixes()
|
||||||
{
|
{
|
||||||
static std::vector<GameLanguagePrefix> prefixes{
|
std::vector<GameLanguagePrefix> prefixes;
|
||||||
{GameLanguage::LANGUAGE_ENGLISH, "en_"},
|
|
||||||
{GameLanguage::LANGUAGE_FRENCH, "fr_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_ENGLISH, "en_");
|
||||||
{GameLanguage::LANGUAGE_FRENCH_CAN, "fc_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_FRENCH, "fr_");
|
||||||
{GameLanguage::LANGUAGE_GERMAN, "ge_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_FRENCH_CAN, "fc_");
|
||||||
{GameLanguage::LANGUAGE_AUSTRIAN, "as_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_GERMAN, "ge_");
|
||||||
{GameLanguage::LANGUAGE_ITALIAN, "it_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_AUSTRIAN, "as_");
|
||||||
{GameLanguage::LANGUAGE_SPANISH, "sp_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_ITALIAN, "it_");
|
||||||
{GameLanguage::LANGUAGE_BRITISH, "br_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_SPANISH, "sp_");
|
||||||
{GameLanguage::LANGUAGE_RUSSIAN, "ru_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_BRITISH, "br_");
|
||||||
{GameLanguage::LANGUAGE_POLISH, "po_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_RUSSIAN, "ru_");
|
||||||
{GameLanguage::LANGUAGE_KOREAN, "ko_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_POLISH, "po_");
|
||||||
{GameLanguage::LANGUAGE_JAPANESE, "ja_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_KOREAN, "ko_");
|
||||||
{GameLanguage::LANGUAGE_CZECH, "cz_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_JAPANESE, "ja_");
|
||||||
{GameLanguage::LANGUAGE_FULL_JAPANESE, "fj_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_CZECH, "cz_");
|
||||||
{GameLanguage::LANGUAGE_PORTUGUESE, "bp_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_FULL_JAPANESE, "fj_");
|
||||||
{GameLanguage::LANGUAGE_MEXICAN_SPANISH, "ms_"},
|
prefixes.emplace_back(GameLanguage::LANGUAGE_PORTUGUESE, "bp_");
|
||||||
};
|
prefixes.emplace_back(GameLanguage::LANGUAGE_MEXICAN_SPANISH, "ms_");
|
||||||
|
|
||||||
return prefixes;
|
return prefixes;
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Game/IGame.h"
|
#include "Game/IGame.h"
|
||||||
|
|
||||||
namespace T6
|
class GameT6 : public IGame
|
||||||
{
|
{
|
||||||
class Game final : public IGame
|
std::vector<Zone*> m_zones;
|
||||||
{
|
|
||||||
public:
|
|
||||||
[[nodiscard]] GameId GetId() const override;
|
|
||||||
[[nodiscard]] const std::string& GetFullName() const override;
|
|
||||||
[[nodiscard]] const std::string& GetShortName() const override;
|
|
||||||
void AddZone(Zone* zone) override;
|
|
||||||
void RemoveZone(Zone* zone) override;
|
|
||||||
[[nodiscard]] const std::vector<Zone*>& GetZones() const override;
|
|
||||||
[[nodiscard]] const std::vector<GameLanguagePrefix>& GetLanguagePrefixes() const override;
|
|
||||||
|
|
||||||
private:
|
public:
|
||||||
std::vector<Zone*> m_zones;
|
std::string GetFullName() override;
|
||||||
};
|
std::string GetShortName() override;
|
||||||
} // namespace T6
|
void AddZone(Zone* zone) override;
|
||||||
|
void RemoveZone(Zone* zone) override;
|
||||||
|
std::vector<Zone*> GetZones() override;
|
||||||
|
std::vector<GameLanguagePrefix> GetLanguagePrefixes() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern GameT6 g_GameT6;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// clang-format off: Order of includes matters here
|
// clang-format off: Order of includes matters here
|
||||||
|
|
||||||
// #include <d3d11.h>
|
// #include <d3d11.h>
|
||||||
#include "Game/IAsset.h"
|
#include "Image/Texture.h"
|
||||||
|
|
||||||
#include "T6_Assets.h"
|
#include "T6_Assets.h"
|
||||||
|
|
||||||
@ -159,103 +159,4 @@ namespace T6
|
|||||||
AUFT_NUM_FIELD_TYPES,
|
AUFT_NUM_FIELD_TYPES,
|
||||||
};
|
};
|
||||||
|
|
||||||
using AssetPhysPreset = Asset<ASSET_TYPE_PHYSPRESET, PhysPreset>;
|
|
||||||
using AssetPhysConstraints = Asset<ASSET_TYPE_PHYSCONSTRAINTS, PhysConstraints>;
|
|
||||||
using AssetDestructibleDef = Asset<ASSET_TYPE_DESTRUCTIBLEDEF, DestructibleDef>;
|
|
||||||
using AssetXAnim = Asset<ASSET_TYPE_XANIMPARTS, XAnimParts>;
|
|
||||||
using AssetXModel = Asset<ASSET_TYPE_XMODEL, XModel>;
|
|
||||||
using AssetMaterial = Asset<ASSET_TYPE_MATERIAL, Material>;
|
|
||||||
using AssetTechniqueSet = Asset<ASSET_TYPE_TECHNIQUE_SET, MaterialTechniqueSet>;
|
|
||||||
using AssetImage = Asset<ASSET_TYPE_IMAGE, GfxImage>;
|
|
||||||
using AssetSoundBank = Asset<ASSET_TYPE_SOUND, SndBank>;
|
|
||||||
using AssetSoundPatch = Asset<ASSET_TYPE_SOUND_PATCH, SndPatch>;
|
|
||||||
using AssetClipMap = Asset<ASSET_TYPE_CLIPMAP, clipMap_t>;
|
|
||||||
using AssetClipMapPvs = Asset<ASSET_TYPE_CLIPMAP_PVS, clipMap_t>;
|
|
||||||
using AssetComWorld = Asset<ASSET_TYPE_COMWORLD, ComWorld>;
|
|
||||||
using AssetGameWorldSp = Asset<ASSET_TYPE_GAMEWORLD_SP, GameWorldSp>;
|
|
||||||
using AssetGameWorldMp = Asset<ASSET_TYPE_GAMEWORLD_MP, GameWorldMp>;
|
|
||||||
using AssetMapEnts = Asset<ASSET_TYPE_MAP_ENTS, MapEnts>;
|
|
||||||
using AssetGfxWorld = Asset<ASSET_TYPE_GFXWORLD, GfxWorld>;
|
|
||||||
using AssetLightDef = Asset<ASSET_TYPE_LIGHT_DEF, GfxLightDef>;
|
|
||||||
using AssetFont = Asset<ASSET_TYPE_FONT, Font_s>;
|
|
||||||
using AssetFontIcon = Asset<ASSET_TYPE_FONTICON, FontIcon>;
|
|
||||||
using AssetMenuList = Asset<ASSET_TYPE_MENULIST, MenuList>;
|
|
||||||
using AssetMenu = Asset<ASSET_TYPE_MENU, menuDef_t>;
|
|
||||||
using AssetLocalize = Asset<ASSET_TYPE_LOCALIZE_ENTRY, LocalizeEntry>;
|
|
||||||
using AssetWeapon = Asset<ASSET_TYPE_WEAPON, WeaponVariantDef>;
|
|
||||||
using AssetAttachment = Asset<ASSET_TYPE_ATTACHMENT, WeaponAttachment>;
|
|
||||||
using AssetAttachmentUnique = Asset<ASSET_TYPE_ATTACHMENT_UNIQUE, WeaponAttachmentUnique>;
|
|
||||||
using AssetWeaponCamo = Asset<ASSET_TYPE_WEAPON_CAMO, WeaponCamo>;
|
|
||||||
using AssetSoundDriverGlobals = Asset<ASSET_TYPE_SNDDRIVER_GLOBALS, SndDriverGlobals>;
|
|
||||||
using AssetFx = Asset<ASSET_TYPE_FX, FxEffectDef>;
|
|
||||||
using AssetImpactFx = Asset<ASSET_TYPE_IMPACT_FX, FxImpactTable>;
|
|
||||||
using AssetRawFile = Asset<ASSET_TYPE_RAWFILE, RawFile>;
|
|
||||||
using AssetStringTable = Asset<ASSET_TYPE_STRINGTABLE, StringTable>;
|
|
||||||
using AssetLeaderboard = Asset<ASSET_TYPE_LEADERBOARD, LeaderboardDef>;
|
|
||||||
using AssetXGlobals = Asset<ASSET_TYPE_XGLOBALS, XGlobals>;
|
|
||||||
using AssetDDL = Asset<ASSET_TYPE_DDL, ddlRoot_t>;
|
|
||||||
using AssetGlasses = Asset<ASSET_TYPE_GLASSES, Glasses>;
|
|
||||||
using AssetEmblemSet = Asset<ASSET_TYPE_EMBLEMSET, EmblemSet>;
|
|
||||||
using AssetScript = Asset<ASSET_TYPE_SCRIPTPARSETREE, ScriptParseTree>;
|
|
||||||
using AssetKeyValuePairs = Asset<ASSET_TYPE_KEYVALUEPAIRS, KeyValuePairs>;
|
|
||||||
using AssetVehicle = Asset<ASSET_TYPE_VEHICLEDEF, VehicleDef>;
|
|
||||||
using AssetMemoryBlock = Asset<ASSET_TYPE_MEMORYBLOCK, MemoryBlock>;
|
|
||||||
using AssetAddonMapEnts = Asset<ASSET_TYPE_ADDON_MAP_ENTS, AddonMapEnts>;
|
|
||||||
using AssetTracer = Asset<ASSET_TYPE_TRACER, TracerDef>;
|
|
||||||
using AssetSkinnedVerts = Asset<ASSET_TYPE_SKINNEDVERTS, SkinnedVertsDef>;
|
|
||||||
using AssetQdb = Asset<ASSET_TYPE_QDB, Qdb>;
|
|
||||||
using AssetSlug = Asset<ASSET_TYPE_SLUG, Slug>;
|
|
||||||
using AssetFootstepTable = Asset<ASSET_TYPE_FOOTSTEP_TABLE, FootstepTableDef>;
|
|
||||||
using AssetFootstepFxTable = Asset<ASSET_TYPE_FOOTSTEPFX_TABLE, FootstepFXTableDef>;
|
|
||||||
using AssetZBarrier = Asset<ASSET_TYPE_ZBARRIER, ZBarrierDef>;
|
|
||||||
} // namespace T6
|
} // namespace T6
|
||||||
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetPhysPreset, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetPhysConstraints, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetDestructibleDef, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetXAnim, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetXModel, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetMaterial, info.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetTechniqueSet, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetImage, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetSoundBank, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetSoundPatch, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetClipMap, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetClipMapPvs, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetComWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetGameWorldSp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetGameWorldMp, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetMapEnts, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetGfxWorld, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetLightDef, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetFont, fontName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetFontIcon, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetMenuList, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetMenu, window.name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetLocalize, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetWeapon, szInternalName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetAttachment, szInternalName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetAttachmentUnique, szInternalName);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetWeaponCamo, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetSoundDriverGlobals, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetFx, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR_SINGLETON(T6::AssetImpactFx, "ImpactFx");
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetRawFile, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetStringTable, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetLeaderboard, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetXGlobals, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetDDL, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetGlasses, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR_SINGLETON(T6::AssetEmblemSet, "EmblemSet");
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetScript, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetKeyValuePairs, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetVehicle, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetMemoryBlock, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetAddonMapEnts, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetTracer, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetSkinnedVerts, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetQdb, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetSlug, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetFootstepTable, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetFootstepFxTable, name);
|
|
||||||
DEFINE_ASSET_NAME_ACCESSOR(T6::AssetZBarrier, name);
|
|
||||||
|
@ -22,8 +22,6 @@ namespace T6
|
|||||||
|
|
||||||
typedef tdef_align(128) float float_align128;
|
typedef tdef_align(128) float float_align128;
|
||||||
|
|
||||||
typedef uint16_t ScriptString;
|
|
||||||
|
|
||||||
struct dvar_t;
|
struct dvar_t;
|
||||||
struct MenuCell;
|
struct MenuCell;
|
||||||
struct cplane_s;
|
struct cplane_s;
|
||||||
@ -590,20 +588,7 @@ namespace T6
|
|||||||
float dist;
|
float dist;
|
||||||
uint16_t numsurfs;
|
uint16_t numsurfs;
|
||||||
uint16_t surfIndex;
|
uint16_t surfIndex;
|
||||||
unsigned int partBits[5];
|
int partBits[5];
|
||||||
};
|
|
||||||
|
|
||||||
enum XModelLodRampType : unsigned char
|
|
||||||
{
|
|
||||||
XMODEL_LOD_RAMP_RIGID = 0x0,
|
|
||||||
XMODEL_LOD_RAMP_SKINNED = 0x1,
|
|
||||||
|
|
||||||
XMODEL_LOD_RAMP_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
struct XModelQuat
|
|
||||||
{
|
|
||||||
int16_t v[4];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XModel
|
struct XModel
|
||||||
@ -612,12 +597,12 @@ namespace T6
|
|||||||
unsigned char numBones;
|
unsigned char numBones;
|
||||||
unsigned char numRootBones;
|
unsigned char numRootBones;
|
||||||
unsigned char numsurfs;
|
unsigned char numsurfs;
|
||||||
XModelLodRampType lodRampType;
|
char lodRampType;
|
||||||
ScriptString* boneNames;
|
uint16_t* boneNames;
|
||||||
unsigned char* parentList;
|
unsigned char* parentList;
|
||||||
XModelQuat* quats;
|
uint16_t (*quats)[4];
|
||||||
float* trans;
|
float (*trans)[4];
|
||||||
unsigned char* partClassification;
|
char* partClassification;
|
||||||
DObjAnimMat* baseMat;
|
DObjAnimMat* baseMat;
|
||||||
XSurface* surfs;
|
XSurface* surfs;
|
||||||
Material** materialHandles;
|
Material** materialHandles;
|
||||||
@ -630,10 +615,10 @@ namespace T6
|
|||||||
vec3_t mins;
|
vec3_t mins;
|
||||||
vec3_t maxs;
|
vec3_t maxs;
|
||||||
uint16_t numLods;
|
uint16_t numLods;
|
||||||
int16_t collLod;
|
uint16_t collLod;
|
||||||
float* himipInvSqRadii;
|
float* himipInvSqRadii;
|
||||||
int memUsage;
|
int memUsage;
|
||||||
unsigned int flags;
|
int flags;
|
||||||
bool bad;
|
bool bad;
|
||||||
PhysPreset* physPreset;
|
PhysPreset* physPreset;
|
||||||
unsigned char numCollmaps;
|
unsigned char numCollmaps;
|
||||||
@ -848,6 +833,7 @@ namespace T6
|
|||||||
union GfxTexture
|
union GfxTexture
|
||||||
{
|
{
|
||||||
void /*ID3D11ShaderResourceView*/* basemap;
|
void /*ID3D11ShaderResourceView*/* basemap;
|
||||||
|
Texture* texture;
|
||||||
GfxImageLoadDef* loadDef;
|
GfxImageLoadDef* loadDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1942,7 +1928,7 @@ namespace T6
|
|||||||
int columnCount;
|
int columnCount;
|
||||||
int rowCount;
|
int rowCount;
|
||||||
StringTableCell* values;
|
StringTableCell* values;
|
||||||
uint16_t* cellIndex;
|
int16_t* cellIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LbUpdateType
|
enum LbUpdateType
|
||||||
@ -1950,22 +1936,7 @@ namespace T6
|
|||||||
LBUPDATE_TYPE_NORMAL = 0x0,
|
LBUPDATE_TYPE_NORMAL = 0x0,
|
||||||
LBUPDATE_TYPE_RANK = 0x1,
|
LBUPDATE_TYPE_RANK = 0x1,
|
||||||
LBUPDATE_TYPE_COMBINE = 0x2,
|
LBUPDATE_TYPE_COMBINE = 0x2,
|
||||||
|
LBUPDATE_TYPE_COUNT = 0x3,
|
||||||
LBUPDATE_TYPE_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LbTrackType
|
|
||||||
{
|
|
||||||
TRK_ALLTIME = 0x0,
|
|
||||||
TRK_WEEKLY = 0x1,
|
|
||||||
TRK_MONTHLY = 0x2,
|
|
||||||
TRK_PRESTIGE_ALLTIME = 0x3,
|
|
||||||
TRK_PRESTIGE_WEEKLY = 0x4,
|
|
||||||
TRK_PRESTIGE_MONTHLY = 0x5,
|
|
||||||
TRK_DAILY = 0x6,
|
|
||||||
TRK_PRESTIGE_DAILY = 0x7,
|
|
||||||
|
|
||||||
TRK_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LeaderboardDef
|
struct LeaderboardDef
|
||||||
@ -2114,7 +2085,7 @@ namespace T6
|
|||||||
struct KeyValuePairs
|
struct KeyValuePairs
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
unsigned int numVariables;
|
int numVariables;
|
||||||
KeyValuePair* keyValuePairs;
|
KeyValuePair* keyValuePairs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2748,12 +2719,7 @@ namespace T6
|
|||||||
float* tensionData;
|
float* tensionData;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XSurfaceTri
|
typedef tdef_align(16) unsigned short r_index16_t;
|
||||||
{
|
|
||||||
uint16_t i[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef tdef_align(16) XSurfaceTri XSurfaceTri16;
|
|
||||||
|
|
||||||
struct type_align(16) XSurface
|
struct type_align(16) XSurface
|
||||||
{
|
{
|
||||||
@ -2763,13 +2729,13 @@ namespace T6
|
|||||||
uint16_t vertCount;
|
uint16_t vertCount;
|
||||||
uint16_t triCount;
|
uint16_t triCount;
|
||||||
uint16_t baseVertIndex;
|
uint16_t baseVertIndex;
|
||||||
XSurfaceTri16* triIndices;
|
r_index16_t(*triIndices)[3];
|
||||||
XSurfaceVertexInfo vertInfo;
|
XSurfaceVertexInfo vertInfo;
|
||||||
GfxPackedVertex* verts0;
|
GfxPackedVertex* verts0;
|
||||||
void /*ID3D11Buffer*/* vb0;
|
void /*ID3D11Buffer*/* vb0;
|
||||||
XRigidVertList* vertList;
|
XRigidVertList* vertList;
|
||||||
void /*ID3D11Buffer*/* indexBuffer;
|
void /*ID3D11Buffer*/* indexBuffer;
|
||||||
unsigned int partBits[5];
|
int partBits[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct XModelCollSurf_s
|
struct XModelCollSurf_s
|
||||||
@ -3814,8 +3780,7 @@ namespace T6
|
|||||||
uint16_t dynEntId;
|
uint16_t dynEntId;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Usually __m128, but that is not portable
|
union gcc_align(8) __m128
|
||||||
union gcc_align(8) custom_m128
|
|
||||||
{
|
{
|
||||||
float m128_f32[4];
|
float m128_f32[4];
|
||||||
uint64_t m128_u64[2];
|
uint64_t m128_u64[2];
|
||||||
@ -3828,12 +3793,19 @@ namespace T6
|
|||||||
unsigned int m128_u32[4];
|
unsigned int m128_u32[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vector3
|
||||||
|
{
|
||||||
|
__m128 x;
|
||||||
|
__m128 y;
|
||||||
|
__m128 z;
|
||||||
|
};
|
||||||
|
|
||||||
struct vector4
|
struct vector4
|
||||||
{
|
{
|
||||||
custom_m128 x;
|
__m128 x;
|
||||||
custom_m128 y;
|
__m128 y;
|
||||||
custom_m128 z;
|
__m128 z;
|
||||||
custom_m128 w;
|
__m128 w;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct type_align(16) SSkinInstance
|
struct type_align(16) SSkinInstance
|
||||||
@ -4327,8 +4299,7 @@ namespace T6
|
|||||||
MISSILE_GUIDANCE_TVGUIDED = 0x6,
|
MISSILE_GUIDANCE_TVGUIDED = 0x6,
|
||||||
MISSILE_GUIDANCE_DRONE = 0x7,
|
MISSILE_GUIDANCE_DRONE = 0x7,
|
||||||
MISSILE_GUIDANCE_HEATSEEKING = 0x8,
|
MISSILE_GUIDANCE_HEATSEEKING = 0x8,
|
||||||
|
MISSILE_GUIDANCE_COUNT = 0x9,
|
||||||
MISSILE_GUIDANCE_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum hitLocation_t
|
enum hitLocation_t
|
||||||
@ -4355,7 +4326,7 @@ namespace T6
|
|||||||
HITLOC_GUN = 0x13,
|
HITLOC_GUN = 0x13,
|
||||||
HITLOC_SHIELD = 0x14,
|
HITLOC_SHIELD = 0x14,
|
||||||
|
|
||||||
HITLOC_COUNT,
|
HITLOC_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WeaponDef
|
struct WeaponDef
|
||||||
@ -4864,16 +4835,20 @@ namespace T6
|
|||||||
float fAntiQuickScopeSwayFactor;
|
float fAntiQuickScopeSwayFactor;
|
||||||
float fightDist;
|
float fightDist;
|
||||||
float maxDist;
|
float maxDist;
|
||||||
const char* aiVsAiAccuracyGraphName;
|
// const char *accuracyGraphName[2]; // TODO: Order is accuracyGraphName[0] -> accuracyGraphKnots[0] -> originalAccuracyGraphKnots[0] ->
|
||||||
const char* aiVsPlayerAccuracyGraphName;
|
// accuracyGraphName[1] -> ...
|
||||||
vec2_t* aiVsAiAccuracyGraphKnots;
|
// Which is currently not possible to do in code generation. Afaik this is the only place where this is the case.
|
||||||
vec2_t* aiVsPlayerAccuracyGraphKnots;
|
// So might be something to fix but on the other hand it might be too much work for this little inconvenience.
|
||||||
vec2_t* originalAiVsAiAccuracyGraphKnots;
|
const char* accuracyGraphName0;
|
||||||
vec2_t* originalAiVsPlayerAccuracyGraphKnots;
|
const char* accuracyGraphName1;
|
||||||
int aiVsAiAccuracyGraphKnotCount;
|
// vec2_t *accuracyGraphKnots[2];
|
||||||
int aiVsPlayerAccuracyGraphKnotCount;
|
vec2_t* accuracyGraphKnots0;
|
||||||
int originalAiVsAiAccuracyGraphKnotCount;
|
vec2_t* accuracyGraphKnots1;
|
||||||
int originalAiVsPlayerAccuracyGraphKnotCount;
|
// vec2_t *originalAccuracyGraphKnots[2];
|
||||||
|
vec2_t* originalAccuracyGraphKnots0;
|
||||||
|
vec2_t* originalAccuracyGraphKnots1;
|
||||||
|
int accuracyGraphKnotCount[2];
|
||||||
|
int originalAccuracyGraphKnotCount[2];
|
||||||
int iPositionReloadTransTime;
|
int iPositionReloadTransTime;
|
||||||
float leftArc;
|
float leftArc;
|
||||||
float rightArc;
|
float rightArc;
|
||||||
@ -5563,8 +5538,8 @@ namespace T6
|
|||||||
|
|
||||||
struct KeyValuePair
|
struct KeyValuePair
|
||||||
{
|
{
|
||||||
unsigned int keyHash;
|
int keyHash;
|
||||||
unsigned int namespaceHash;
|
int namespaceHash;
|
||||||
const char* value;
|
const char* value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -6175,43 +6150,7 @@ namespace T6
|
|||||||
SA_LOADED = 0x1,
|
SA_LOADED = 0x1,
|
||||||
SA_STREAMED = 0x2,
|
SA_STREAMED = 0x2,
|
||||||
SA_PRIMED = 0x3,
|
SA_PRIMED = 0x3,
|
||||||
|
SA_COUNT = 0x4,
|
||||||
SA_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SndLimitType
|
|
||||||
{
|
|
||||||
SND_LIMIT_NONE = 0x0,
|
|
||||||
SND_LIMIT_OLDEST = 0x1,
|
|
||||||
SND_LIMIT_REJECT = 0x2,
|
|
||||||
SND_LIMIT_PRIORITY = 0x3,
|
|
||||||
|
|
||||||
SND_LIMIT_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SndBus
|
|
||||||
{
|
|
||||||
SND_BUS_REVERB = 0x0,
|
|
||||||
SND_BUS_FX = 0x1,
|
|
||||||
SND_BUS_VOICE = 0x2,
|
|
||||||
SND_BUS_PFUTZ = 0x3,
|
|
||||||
SND_BUS_HDRFX = 0x4,
|
|
||||||
SND_BUS_UI = 0x5,
|
|
||||||
SND_BUS_MUSIC = 0x6,
|
|
||||||
SND_BUS_MOVIE = 0x7,
|
|
||||||
SND_BUS_REFERENCE = 0x8,
|
|
||||||
|
|
||||||
SND_BUS_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SndRandomizeType
|
|
||||||
{
|
|
||||||
SND_RANDOMIZE_INSTANCE = 0x0,
|
|
||||||
SND_RANDOMIZE_ENTITY_VOLUME = 0x1,
|
|
||||||
SND_RANDOMIZE_ENTITY_PITCH = 0x2,
|
|
||||||
SND_RANDOMIZE_ENTITY_VARIANT = 0x4,
|
|
||||||
|
|
||||||
SND_RANDOMIZE_ENTITY_COUNT
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SndAliasFlags
|
struct SndAliasFlags
|
||||||
@ -6224,7 +6163,7 @@ namespace T6
|
|||||||
unsigned int isBig : 1; // 4
|
unsigned int isBig : 1; // 4
|
||||||
unsigned int pauseable : 1; // 5
|
unsigned int pauseable : 1; // 5
|
||||||
unsigned int isMusic : 1; // 6
|
unsigned int isMusic : 1; // 6
|
||||||
unsigned int stopOnEntDeath : 1; // 7
|
unsigned int stopOnDeath : 1; // 7
|
||||||
unsigned int timescale : 1; // 8
|
unsigned int timescale : 1; // 8
|
||||||
unsigned int voiceLimit : 1; // 9
|
unsigned int voiceLimit : 1; // 9
|
||||||
unsigned int ignoreMaxDist : 1; // 10
|
unsigned int ignoreMaxDist : 1; // 10
|
||||||
@ -6243,9 +6182,7 @@ namespace T6
|
|||||||
unsigned int reverbFalloffCurve : 6; // 8-13
|
unsigned int reverbFalloffCurve : 6; // 8-13
|
||||||
unsigned int volumeMinFalloffCurve : 6; // 14-19
|
unsigned int volumeMinFalloffCurve : 6; // 14-19
|
||||||
unsigned int reverbMinFalloffCurve : 6; // 20-25
|
unsigned int reverbMinFalloffCurve : 6; // 20-25
|
||||||
unsigned int unknown1_1 : 1; // 26
|
unsigned int unknown1_1 : 6; // 26-31
|
||||||
unsigned int isCinematic : 1; // 27
|
|
||||||
unsigned int unknown1_2 : 4; // 28-31
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SndAlias
|
struct SndAlias
|
||||||
@ -6253,7 +6190,7 @@ namespace T6
|
|||||||
const char* name;
|
const char* name;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
const char* subtitle;
|
const char* subtitle;
|
||||||
const char* secondaryName;
|
const char* secondaryname;
|
||||||
unsigned int assetId;
|
unsigned int assetId;
|
||||||
const char* assetFileName;
|
const char* assetFileName;
|
||||||
SndAliasFlags flags;
|
SndAliasFlags flags;
|
||||||
@ -6279,16 +6216,16 @@ namespace T6
|
|||||||
int16_t fadeIn;
|
int16_t fadeIn;
|
||||||
int16_t fadeOut;
|
int16_t fadeOut;
|
||||||
int16_t dopplerScale;
|
int16_t dopplerScale;
|
||||||
uint8_t minPriorityThreshold;
|
char minPriorityThreshold;
|
||||||
uint8_t maxPriorityThreshold;
|
char maxPriorityThreshold;
|
||||||
uint8_t probability;
|
char probability;
|
||||||
uint8_t occlusionLevel;
|
char occlusionLevel;
|
||||||
uint8_t minPriority;
|
char minPriority;
|
||||||
uint8_t maxPriority;
|
char maxPriority;
|
||||||
uint8_t pan;
|
char pan;
|
||||||
uint8_t limitCount;
|
char limitCount;
|
||||||
uint8_t entityLimitCount;
|
char entityLimitCount;
|
||||||
uint8_t duckGroup;
|
char duckGroup;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef __zonecodegenerator
|
#ifndef __zonecodegenerator
|
||||||
|
@ -77,11 +77,6 @@ uint8_t* Texture::GetBufferForMipLevel(const int mipLevel)
|
|||||||
return GetBufferForMipLevel(mipLevel, 0);
|
return GetBufferForMipLevel(mipLevel, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* Texture::GetBufferForMipLevel(const int mipLevel) const
|
|
||||||
{
|
|
||||||
return GetBufferForMipLevel(mipLevel, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==============================================
|
// ==============================================
|
||||||
// ================ Texture2D ===================
|
// ================ Texture2D ===================
|
||||||
// ==============================================
|
// ==============================================
|
||||||
@ -188,31 +183,6 @@ uint8_t* Texture2D::GetBufferForMipLevel(const int mipLevel, const int face)
|
|||||||
return &m_data[bufferOffset];
|
return &m_data[bufferOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* Texture2D::GetBufferForMipLevel(const int mipLevel, const int face) const
|
|
||||||
{
|
|
||||||
assert(mipLevel >= 0);
|
|
||||||
assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1));
|
|
||||||
assert(face == 0);
|
|
||||||
assert(m_data);
|
|
||||||
|
|
||||||
if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (face != 0)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!m_data)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
size_t bufferOffset = 0;
|
|
||||||
for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++)
|
|
||||||
{
|
|
||||||
bufferOffset += GetSizeOfMipLevel(previousMipLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
return &m_data[bufferOffset];
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==============================================
|
// ==============================================
|
||||||
// =============== TextureCube ==================
|
// =============== TextureCube ==================
|
||||||
// ==============================================
|
// ==============================================
|
||||||
@ -281,32 +251,6 @@ uint8_t* TextureCube::GetBufferForMipLevel(const int mipLevel, const int face)
|
|||||||
return &m_data[bufferOffset + GetSizeOfMipLevel(mipLevel) * face];
|
return &m_data[bufferOffset + GetSizeOfMipLevel(mipLevel) * face];
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* TextureCube::GetBufferForMipLevel(const int mipLevel, const int face) const
|
|
||||||
{
|
|
||||||
assert(mipLevel >= 0);
|
|
||||||
assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1));
|
|
||||||
assert(face >= 0);
|
|
||||||
assert(face < FACE_COUNT);
|
|
||||||
assert(m_data);
|
|
||||||
|
|
||||||
if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (face < 0 || face >= FACE_COUNT)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!m_data)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
size_t bufferOffset = 0;
|
|
||||||
for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++)
|
|
||||||
{
|
|
||||||
bufferOffset += GetSizeOfMipLevel(previousMipLevel) * FACE_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return &m_data[bufferOffset + GetSizeOfMipLevel(mipLevel) * face];
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==============================================
|
// ==============================================
|
||||||
// ================ Texture3D ===================
|
// ================ Texture3D ===================
|
||||||
// ==============================================
|
// ==============================================
|
||||||
@ -416,28 +360,3 @@ uint8_t* Texture3D::GetBufferForMipLevel(const int mipLevel, const int face)
|
|||||||
|
|
||||||
return &m_data[bufferOffset];
|
return &m_data[bufferOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* Texture3D::GetBufferForMipLevel(const int mipLevel, const int face) const
|
|
||||||
{
|
|
||||||
assert(mipLevel >= 0);
|
|
||||||
assert(mipLevel < (m_has_mip_maps ? GetMipMapCount() : 1));
|
|
||||||
assert(face == 0);
|
|
||||||
assert(m_data);
|
|
||||||
|
|
||||||
if (mipLevel < 0 || mipLevel >= (m_has_mip_maps ? GetMipMapCount() : 1))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (face != 0)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!m_data)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
size_t bufferOffset = 0;
|
|
||||||
for (int previousMipLevel = 0; previousMipLevel < mipLevel; previousMipLevel++)
|
|
||||||
{
|
|
||||||
bufferOffset += GetSizeOfMipLevel(previousMipLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
return &m_data[bufferOffset];
|
|
||||||
}
|
|
127
src/Common/Image/Texture.h
Normal file
127
src/Common/Image/Texture.h
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ImageFormat.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
enum class TextureType
|
||||||
|
{
|
||||||
|
T_2D,
|
||||||
|
T_CUBE,
|
||||||
|
T_3D
|
||||||
|
};
|
||||||
|
|
||||||
|
class Texture
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const ImageFormat* m_format;
|
||||||
|
bool m_has_mip_maps;
|
||||||
|
uint8_t* m_data;
|
||||||
|
|
||||||
|
Texture(const ImageFormat* format, bool mipMaps);
|
||||||
|
Texture(Texture&& other) noexcept;
|
||||||
|
|
||||||
|
Texture& operator=(Texture&& other) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Texture(const Texture& other) = delete;
|
||||||
|
virtual ~Texture();
|
||||||
|
|
||||||
|
Texture& operator=(const Texture& other) = delete;
|
||||||
|
|
||||||
|
virtual TextureType GetTextureType() const = 0;
|
||||||
|
const ImageFormat* GetFormat() const;
|
||||||
|
|
||||||
|
virtual unsigned GetWidth() const = 0;
|
||||||
|
virtual unsigned GetHeight() const = 0;
|
||||||
|
virtual unsigned GetDepth() const = 0;
|
||||||
|
virtual int GetFaceCount() const = 0;
|
||||||
|
|
||||||
|
void Allocate();
|
||||||
|
bool Empty() const;
|
||||||
|
|
||||||
|
virtual size_t GetSizeOfMipLevel(int mipLevel) const = 0;
|
||||||
|
virtual uint8_t* GetBufferForMipLevel(int mipLevel, int face) = 0;
|
||||||
|
uint8_t* GetBufferForMipLevel(int mipLevel);
|
||||||
|
|
||||||
|
bool HasMipMaps() const;
|
||||||
|
virtual int GetMipMapCount() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Texture2D : public Texture
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
unsigned m_width;
|
||||||
|
unsigned m_height;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Texture2D(const ImageFormat* format, unsigned width, unsigned height);
|
||||||
|
Texture2D(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps);
|
||||||
|
Texture2D(const Texture2D& other) = delete;
|
||||||
|
Texture2D(Texture2D&& other) noexcept;
|
||||||
|
~Texture2D() override;
|
||||||
|
|
||||||
|
Texture2D& operator=(const Texture2D& other) = delete;
|
||||||
|
Texture2D& operator=(Texture2D&& other) noexcept;
|
||||||
|
|
||||||
|
TextureType GetTextureType() const override;
|
||||||
|
|
||||||
|
unsigned GetWidth() const override;
|
||||||
|
unsigned GetHeight() const override;
|
||||||
|
unsigned GetDepth() const override;
|
||||||
|
int GetFaceCount() const override;
|
||||||
|
|
||||||
|
size_t GetSizeOfMipLevel(int mipLevel) const override;
|
||||||
|
uint8_t* GetBufferForMipLevel(int mipLevel, int face) override;
|
||||||
|
|
||||||
|
int GetMipMapCount() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextureCube final : public Texture2D
|
||||||
|
{
|
||||||
|
static const int FACE_COUNT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TextureCube(const ImageFormat* format, unsigned width, unsigned height);
|
||||||
|
TextureCube(const ImageFormat* format, unsigned width, unsigned height, bool mipMaps);
|
||||||
|
TextureCube(const TextureCube& other) = delete;
|
||||||
|
TextureCube(TextureCube&& other) noexcept;
|
||||||
|
~TextureCube() override;
|
||||||
|
|
||||||
|
TextureCube& operator=(const TextureCube& other) = delete;
|
||||||
|
TextureCube& operator=(TextureCube&& other) noexcept;
|
||||||
|
|
||||||
|
TextureType GetTextureType() const override;
|
||||||
|
|
||||||
|
int GetFaceCount() const override;
|
||||||
|
|
||||||
|
uint8_t* GetBufferForMipLevel(int mipLevel, int face) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Texture3D final : public Texture
|
||||||
|
{
|
||||||
|
unsigned m_width;
|
||||||
|
unsigned m_height;
|
||||||
|
unsigned m_depth;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth);
|
||||||
|
Texture3D(const ImageFormat* format, unsigned width, unsigned height, unsigned depth, bool mipMaps);
|
||||||
|
Texture3D(const Texture3D& other) = delete;
|
||||||
|
Texture3D(Texture3D&& other) noexcept;
|
||||||
|
~Texture3D() override;
|
||||||
|
|
||||||
|
Texture3D& operator=(const Texture3D& other) = delete;
|
||||||
|
Texture3D& operator=(Texture3D&& other) noexcept;
|
||||||
|
|
||||||
|
TextureType GetTextureType() const override;
|
||||||
|
|
||||||
|
unsigned GetWidth() const override;
|
||||||
|
unsigned GetHeight() const override;
|
||||||
|
unsigned GetDepth() const override;
|
||||||
|
int GetFaceCount() const override;
|
||||||
|
|
||||||
|
size_t GetSizeOfMipLevel(int mipLevel) const override;
|
||||||
|
uint8_t* GetBufferForMipLevel(int mipLevel, int face) override;
|
||||||
|
|
||||||
|
int GetMipMapCount() const override;
|
||||||
|
};
|
@ -104,7 +104,7 @@ void TextureConverter::SetPixelFunctions(const unsigned inBitCount, const unsign
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureConverter::TextureConverter(const Texture* inputTexture, const ImageFormat* targetFormat)
|
TextureConverter::TextureConverter(Texture* inputTexture, const ImageFormat* targetFormat)
|
||||||
: m_input_texture(inputTexture),
|
: m_input_texture(inputTexture),
|
||||||
m_output_texture(nullptr),
|
m_output_texture(nullptr),
|
||||||
m_input_format(inputTexture->GetFormat()),
|
m_input_format(inputTexture->GetFormat()),
|
||||||
@ -117,17 +117,15 @@ void TextureConverter::CreateOutputTexture()
|
|||||||
switch (m_input_texture->GetTextureType())
|
switch (m_input_texture->GetTextureType())
|
||||||
{
|
{
|
||||||
case TextureType::T_2D:
|
case TextureType::T_2D:
|
||||||
m_output_texture =
|
m_output_texture = new Texture2D(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps());
|
||||||
std::make_unique<Texture2D>(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TextureType::T_CUBE:
|
case TextureType::T_CUBE:
|
||||||
m_output_texture =
|
m_output_texture = new TextureCube(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps());
|
||||||
std::make_unique<TextureCube>(m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->HasMipMaps());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TextureType::T_3D:
|
case TextureType::T_3D:
|
||||||
m_output_texture = std::make_unique<Texture3D>(
|
m_output_texture = new Texture3D(
|
||||||
m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->GetDepth(), m_input_texture->HasMipMaps());
|
m_output_format, m_input_texture->GetWidth(), m_input_texture->GetHeight(), m_input_texture->GetDepth(), m_input_texture->HasMipMaps());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -204,7 +202,7 @@ void TextureConverter::ConvertUnsignedToUnsigned()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Texture> TextureConverter::Convert()
|
Texture* TextureConverter::Convert()
|
||||||
{
|
{
|
||||||
CreateOutputTexture();
|
CreateOutputTexture();
|
||||||
|
|
||||||
@ -218,5 +216,5 @@ std::unique_ptr<Texture> TextureConverter::Convert()
|
|||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::move(m_output_texture);
|
return m_output_texture;
|
||||||
}
|
}
|
@ -3,16 +3,17 @@
|
|||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class TextureConverter
|
class TextureConverter
|
||||||
{
|
{
|
||||||
public:
|
Texture* m_input_texture;
|
||||||
TextureConverter(const Texture* inputTexture, const ImageFormat* targetFormat);
|
Texture* m_output_texture;
|
||||||
|
const ImageFormat* m_input_format;
|
||||||
|
const ImageFormat* m_output_format;
|
||||||
|
|
||||||
std::unique_ptr<Texture> Convert();
|
std::function<uint64_t(const void* offset, unsigned bitCount)> m_read_pixel_func;
|
||||||
|
std::function<void(void* offset, uint64_t pixel, unsigned bitCount)> m_write_pixel_func;
|
||||||
|
|
||||||
private:
|
|
||||||
static constexpr uint64_t Mask1(unsigned length);
|
static constexpr uint64_t Mask1(unsigned length);
|
||||||
void SetPixelFunctions(unsigned inBitCount, unsigned outBitCount);
|
void SetPixelFunctions(unsigned inBitCount, unsigned outBitCount);
|
||||||
|
|
||||||
@ -21,11 +22,8 @@ private:
|
|||||||
void ReorderUnsignedToUnsigned() const;
|
void ReorderUnsignedToUnsigned() const;
|
||||||
void ConvertUnsignedToUnsigned();
|
void ConvertUnsignedToUnsigned();
|
||||||
|
|
||||||
std::function<uint64_t(const void* offset, unsigned bitCount)> m_read_pixel_func;
|
public:
|
||||||
std::function<void(void* offset, uint64_t pixel, unsigned bitCount)> m_write_pixel_func;
|
TextureConverter(Texture* inputTexture, const ImageFormat* targetFormat);
|
||||||
|
|
||||||
const Texture* m_input_texture;
|
Texture* Convert();
|
||||||
std::unique_ptr<Texture> m_output_texture;
|
|
||||||
const ImageFormat* m_input_format;
|
|
||||||
const ImageFormat* m_output_format;
|
|
||||||
};
|
};
|
@ -17,28 +17,7 @@ float HalfFloat::ToFloat(const half_float_t half)
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
half_float_t HalfFloat::ToHalf(const float f)
|
half_float_t HalfFloat::ToHalf(float f)
|
||||||
{
|
{
|
||||||
half_float_t v3;
|
return 0;
|
||||||
int v6;
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
uint32_t u;
|
|
||||||
float f;
|
|
||||||
} result{};
|
|
||||||
|
|
||||||
result.f = f;
|
|
||||||
|
|
||||||
if (static_cast<int>((2 * result.u) ^ 0x80000000) >> 14 < 0x3FFF)
|
|
||||||
v6 = static_cast<int>((2 * result.u) ^ 0x80000000) >> 14;
|
|
||||||
else
|
|
||||||
v6 = 0x3FFF;
|
|
||||||
|
|
||||||
if (v6 > -16384)
|
|
||||||
v3 = static_cast<half_float_t>(v6);
|
|
||||||
else
|
|
||||||
v3 = 0xC000;
|
|
||||||
|
|
||||||
return (v3 & 0x3FFFu) | ((result.u >> 16) & 0xC000u);
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
union PackUtil32
|
union PackUtil32
|
||||||
{
|
{
|
||||||
@ -16,146 +14,70 @@ union PackUtil32
|
|||||||
uint8_t uc[4];
|
uint8_t uc[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace pack32
|
uint32_t Pack32::Vec2PackTexCoords(const float* in)
|
||||||
{
|
{
|
||||||
typedef float pvec3[3];
|
return static_cast<uint32_t>(HalfFloat::ToHalf(in[0])) << 16 | HalfFloat::ToHalf(in[1]);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t Vec2PackTexCoordsUV(const float (&in)[2])
|
uint32_t Pack32::Vec3PackUnitVec(const float* in)
|
||||||
{
|
{
|
||||||
return static_cast<uint32_t>(HalfFloat::ToHalf(in[1])) << 16 | HalfFloat::ToHalf(in[0]);
|
// TODO
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t Vec2PackTexCoordsVU(const float (&in)[2])
|
uint32_t Pack32::Vec4PackGfxColor(const float* in)
|
||||||
{
|
{
|
||||||
return static_cast<uint32_t>(HalfFloat::ToHalf(in[0])) << 16 | HalfFloat::ToHalf(in[1]);
|
return static_cast<uint8_t>(std::clamp(in[0], 0.0f, 1.0f) * 255.0f) | static_cast<uint8_t>(std::clamp(in[1], 0.0f, 1.0f) * 255.0f) << 8
|
||||||
}
|
| static_cast<uint8_t>(std::clamp(in[2], 0.0f, 1.0f) * 255.0f) << 16 | static_cast<uint8_t>(std::clamp(in[3], 0.0f, 1.0f) * 255.0f) << 24;
|
||||||
|
}
|
||||||
|
|
||||||
float Vec3_Normalize(pvec3& vector)
|
void Pack32::Vec2UnpackTexCoordsUV(const uint32_t in, float* out)
|
||||||
{
|
{
|
||||||
float length = std::sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]);
|
const auto inHiDw = static_cast<half_float_t>((in >> 16) & UINT16_MAX);
|
||||||
if (-length >= 0.0f)
|
const auto inLoDw = static_cast<half_float_t>(in & UINT16_MAX);
|
||||||
length = 1.0f;
|
|
||||||
const auto lengthInv = 1.0f / length;
|
|
||||||
vector[0] = lengthInv * vector[0];
|
|
||||||
vector[1] = lengthInv * vector[1];
|
|
||||||
vector[2] = lengthInv * vector[2];
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Vec3PackUnitVecScaleBased(const float (&in)[3])
|
out[0] = HalfFloat::ToFloat(inLoDw);
|
||||||
{
|
out[1] = HalfFloat::ToFloat(inHiDw);
|
||||||
PackUtil32 testEncoding{};
|
}
|
||||||
float normalized[3]{in[0], in[1], in[2]};
|
|
||||||
float decoded[3];
|
|
||||||
|
|
||||||
Vec3_Normalize(normalized);
|
void Pack32::Vec2UnpackTexCoordsVU(const uint32_t in, float* out)
|
||||||
uint32_t out = 0u;
|
{
|
||||||
auto bestDirError = 3.4028235e38f;
|
const auto inHiDw = static_cast<half_float_t>((in >> 16) & UINT16_MAX);
|
||||||
auto bestLenError = 3.4028235e38f;
|
const auto inLoDw = static_cast<half_float_t>(in & UINT16_MAX);
|
||||||
testEncoding.uc[3] = 0u;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
const auto encodeScale = 32385.0f / (static_cast<float>(testEncoding.uc[3]) - -192.0f);
|
|
||||||
testEncoding.c[0] = static_cast<int8_t>(normalized[0] * encodeScale + 127.5f);
|
|
||||||
testEncoding.c[1] = static_cast<int8_t>(normalized[1] * encodeScale + 127.5f);
|
|
||||||
testEncoding.c[2] = static_cast<int8_t>(normalized[2] * encodeScale + 127.5f);
|
|
||||||
const auto decodeScale = (static_cast<float>(testEncoding.uc[3]) - -192.0f) / 32385.0f;
|
|
||||||
decoded[0] = (static_cast<float>(testEncoding.uc[0]) - 127.0f) * decodeScale;
|
|
||||||
decoded[1] = (static_cast<float>(testEncoding.uc[1]) - 127.0f) * decodeScale;
|
|
||||||
decoded[2] = (static_cast<float>(testEncoding.uc[2]) - 127.0f) * decodeScale;
|
|
||||||
const auto v2 = Vec3_Normalize(decoded) - 1.0f;
|
|
||||||
const auto lenError = std::abs(v2);
|
|
||||||
if (lenError < 0.001f)
|
|
||||||
{
|
|
||||||
const auto dirError = std::abs(decoded[0] * normalized[0] + decoded[1] * normalized[1] + decoded[2] * normalized[2] - 1.0f);
|
|
||||||
if (bestDirError > dirError || bestDirError <= dirError && bestLenError > lenError)
|
|
||||||
{
|
|
||||||
bestDirError = dirError;
|
|
||||||
bestLenError = lenError;
|
|
||||||
out = testEncoding.u;
|
|
||||||
if (lenError + dirError == 0.0f)
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++testEncoding.c[3];
|
|
||||||
} while (testEncoding.c[3]);
|
|
||||||
|
|
||||||
return out;
|
out[0] = HalfFloat::ToFloat(inHiDw);
|
||||||
}
|
out[1] = HalfFloat::ToFloat(inLoDw);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t Vec3PackUnitVecThirdBased(const float (&in)[3])
|
void Pack32::Vec3UnpackUnitVecScaleBased(const uint32_t in, float* out)
|
||||||
{
|
{
|
||||||
// This is based on the game's reversed code, the original code may have made a bit more sense
|
assert(out != nullptr);
|
||||||
PackUtil32 x;
|
|
||||||
x.f = (in[0] - -24624.0939334638f) * 0.0001218318939208984f;
|
|
||||||
PackUtil32 y;
|
|
||||||
y.f = (in[1] - -24624.0939334638f) * 0.0001218318939208984f;
|
|
||||||
PackUtil32 z;
|
|
||||||
z.f = (in[2] - -24624.0939334638f) * 0.0001218318939208984f;
|
|
||||||
|
|
||||||
return (x.u & 0x3FF) | (y.u & 0x3FF) << 10u | (z.u & 0x3FF) << 20u;
|
PackUtil32 _in{in};
|
||||||
}
|
const float decodeScale = (static_cast<float>(_in.uc[3]) - -192.0f) / 32385.0f;
|
||||||
|
out[0] = (static_cast<float>(_in.uc[0]) + -127.0f) * decodeScale;
|
||||||
|
out[1] = (static_cast<float>(_in.uc[1]) + -127.0f) * decodeScale;
|
||||||
|
out[2] = (static_cast<float>(_in.uc[2]) + -127.0f) * decodeScale;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t Vec4PackGfxColor(const float (&in)[4])
|
void Pack32::Vec3UnpackUnitVecThirdBased(const uint32_t in, float* out)
|
||||||
{
|
{
|
||||||
// clang-format off
|
PackUtil32 v0{(in >> 0) & 0x3FF};
|
||||||
return static_cast<uint8_t>(std::clamp(in[0], 0.0f, 1.0f) * 255.0f)
|
PackUtil32 v1{(in >> 10) & 0x3FF};
|
||||||
| static_cast<uint8_t>(std::clamp(in[1], 0.0f, 1.0f) * 255.0f) << 8
|
PackUtil32 v2{(in >> 20) & 0x3FF};
|
||||||
| static_cast<uint8_t>(std::clamp(in[2], 0.0f, 1.0f) * 255.0f) << 16
|
|
||||||
| static_cast<uint8_t>(std::clamp(in[3], 0.0f, 1.0f) * 255.0f) << 24;
|
|
||||||
// clang-format on
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vec2UnpackTexCoordsUV(const uint32_t in, float (&out)[2])
|
v0.u = v0.u - 2 * (v0.u & 0x200) + 0x40400000;
|
||||||
{
|
v1.u = v1.u - 2 * (v1.u & 0x200) + 0x40400000;
|
||||||
const auto inHiDw = static_cast<half_float_t>((in >> 16) & std::numeric_limits<uint16_t>::max());
|
v2.u = v2.u - 2 * (v2.u & 0x200) + 0x40400000;
|
||||||
const auto inLoDw = static_cast<half_float_t>(in & std::numeric_limits<uint16_t>::max());
|
out[0] = (v0.f - 3.0f) * 8208.0312f;
|
||||||
|
out[1] = (v1.f - 3.0f) * 8208.0312f;
|
||||||
|
out[2] = (v2.f - 3.0f) * 8208.0312f;
|
||||||
|
}
|
||||||
|
|
||||||
out[0] = HalfFloat::ToFloat(inLoDw);
|
void Pack32::Vec4UnpackGfxColor(uint32_t in, float* out)
|
||||||
out[1] = HalfFloat::ToFloat(inHiDw);
|
{
|
||||||
}
|
out[0] = static_cast<float>(in & UINT8_MAX) / 255.0f;
|
||||||
|
out[1] = static_cast<float>((in >> 8) & UINT8_MAX) / 255.0f;
|
||||||
void Vec2UnpackTexCoordsVU(const uint32_t in, float (&out)[2])
|
out[2] = static_cast<float>((in >> 16) & UINT8_MAX) / 255.0f;
|
||||||
{
|
out[3] = static_cast<float>((in >> 24) & UINT8_MAX) / 255.0f;
|
||||||
const auto inHiDw = static_cast<half_float_t>((in >> 16) & std::numeric_limits<uint16_t>::max());
|
}
|
||||||
const auto inLoDw = static_cast<half_float_t>(in & std::numeric_limits<uint16_t>::max());
|
|
||||||
|
|
||||||
out[0] = HalfFloat::ToFloat(inHiDw);
|
|
||||||
out[1] = HalfFloat::ToFloat(inLoDw);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vec3UnpackUnitVecScaleBased(const uint32_t in, float (&out)[3])
|
|
||||||
{
|
|
||||||
assert(out != nullptr);
|
|
||||||
|
|
||||||
const PackUtil32 inUtil{in};
|
|
||||||
const float decodeScale = (static_cast<float>(inUtil.uc[3]) - -192.0f) / 32385.0f;
|
|
||||||
out[0] = (static_cast<float>(inUtil.uc[0]) + -127.0f) * decodeScale;
|
|
||||||
out[1] = (static_cast<float>(inUtil.uc[1]) + -127.0f) * decodeScale;
|
|
||||||
out[2] = (static_cast<float>(inUtil.uc[2]) + -127.0f) * decodeScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vec3UnpackUnitVecThirdBased(const uint32_t in, float (&out)[3])
|
|
||||||
{
|
|
||||||
// This is based on the game's reversed code, the original code may have made a bit more sense
|
|
||||||
PackUtil32 v0{(in >> 0) & 0x3FF};
|
|
||||||
PackUtil32 v1{(in >> 10) & 0x3FF};
|
|
||||||
PackUtil32 v2{(in >> 20) & 0x3FF};
|
|
||||||
|
|
||||||
v0.u = v0.u - 2 * (v0.u & 0x200) + 0x40400000;
|
|
||||||
v1.u = v1.u - 2 * (v1.u & 0x200) + 0x40400000;
|
|
||||||
v2.u = v2.u - 2 * (v2.u & 0x200) + 0x40400000;
|
|
||||||
out[0] = (v0.f - 3.0f) * 8208.0312f;
|
|
||||||
out[1] = (v1.f - 3.0f) * 8208.0312f;
|
|
||||||
out[2] = (v2.f - 3.0f) * 8208.0312f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vec4UnpackGfxColor(const uint32_t in, float (&out)[4])
|
|
||||||
{
|
|
||||||
out[0] = static_cast<float>(in & std::numeric_limits<uint8_t>::max()) / 255.0f;
|
|
||||||
out[1] = static_cast<float>((in >> 8) & std::numeric_limits<uint8_t>::max()) / 255.0f;
|
|
||||||
out[2] = static_cast<float>((in >> 16) & std::numeric_limits<uint8_t>::max()) / 255.0f;
|
|
||||||
out[3] = static_cast<float>((in >> 24) & std::numeric_limits<uint8_t>::max()) / 255.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace pack32
|
|
||||||
|
@ -2,17 +2,17 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace pack32
|
class Pack32
|
||||||
{
|
{
|
||||||
uint32_t Vec2PackTexCoordsUV(const float (&in)[2]);
|
Pack32() = default;
|
||||||
uint32_t Vec2PackTexCoordsVU(const float (&in)[2]);
|
|
||||||
uint32_t Vec3PackUnitVecScaleBased(const float (&in)[3]);
|
|
||||||
uint32_t Vec3PackUnitVecThirdBased(const float (&in)[3]);
|
|
||||||
uint32_t Vec4PackGfxColor(const float (&in)[4]);
|
|
||||||
|
|
||||||
void Vec2UnpackTexCoordsUV(uint32_t in, float (&out)[2]);
|
public:
|
||||||
void Vec2UnpackTexCoordsVU(uint32_t in, float (&out)[2]);
|
static uint32_t Vec2PackTexCoords(const float* in);
|
||||||
void Vec3UnpackUnitVecScaleBased(uint32_t in, float (&out)[3]);
|
static uint32_t Vec3PackUnitVec(const float* in);
|
||||||
void Vec3UnpackUnitVecThirdBased(uint32_t in, float (&out)[3]);
|
static uint32_t Vec4PackGfxColor(const float* in);
|
||||||
void Vec4UnpackGfxColor(uint32_t in, float (&out)[4]);
|
static void Vec2UnpackTexCoordsUV(uint32_t in, float* out);
|
||||||
}; // namespace pack32
|
static void Vec2UnpackTexCoordsVU(uint32_t in, float* out);
|
||||||
|
static void Vec3UnpackUnitVecScaleBased(uint32_t in, float* out);
|
||||||
|
static void Vec3UnpackUnitVecThirdBased(uint32_t in, float* out);
|
||||||
|
static void Vec4UnpackGfxColor(uint32_t in, float* out);
|
||||||
|
};
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
struct ZoneHeader
|
struct ZoneHeader
|
||||||
{
|
{
|
||||||
@ -8,11 +7,21 @@ struct ZoneHeader
|
|||||||
uint32_t m_version;
|
uint32_t m_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ARCH_x64
|
||||||
|
typedef uint32_t scr_string_t;
|
||||||
|
typedef uint64_t xchunk_size_t;
|
||||||
|
typedef uint64_t xblock_size_t;
|
||||||
|
typedef uint64_t zone_pointer_t;
|
||||||
|
|
||||||
|
constexpr uint16_t SCR_STRING_MAX = UINT32_MAX;
|
||||||
|
#elif ARCH_x86
|
||||||
typedef uint16_t scr_string_t;
|
typedef uint16_t scr_string_t;
|
||||||
typedef uint32_t xchunk_size_t;
|
typedef uint32_t xchunk_size_t;
|
||||||
typedef uint32_t xblock_size_t;
|
typedef uint32_t xblock_size_t;
|
||||||
|
typedef uint32_t zone_pointer_t;
|
||||||
|
|
||||||
constexpr uint16_t SCR_STRING_MAX = std::numeric_limits<scr_string_t>::max();
|
constexpr uint16_t SCR_STRING_MAX = UINT16_MAX;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef int block_t;
|
typedef int block_t;
|
||||||
typedef int asset_type_t;
|
typedef int asset_type_t;
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
#include "Base64.h"
|
|
||||||
|
|
||||||
#define LTC_NO_PROTOTYPES
|
|
||||||
#include <tomcrypt.h>
|
|
||||||
|
|
||||||
namespace base64
|
|
||||||
{
|
|
||||||
std::string EncodeBase64(const void* inputData, const size_t inputLength)
|
|
||||||
{
|
|
||||||
const auto base64BufferSize = GetBase64EncodeOutputLength(inputLength);
|
|
||||||
|
|
||||||
std::string output(base64BufferSize, '\0');
|
|
||||||
const auto outLength = base64BufferSize + 1u;
|
|
||||||
|
|
||||||
const auto result = EncodeBase64(inputData, inputLength, output.data(), outLength);
|
|
||||||
assert(result);
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EncodeBase64(const void* inputData, const size_t inputLength, void* outputBuffer, const size_t outputBufferSize)
|
|
||||||
{
|
|
||||||
unsigned long outLength = outputBufferSize;
|
|
||||||
const auto result = base64_encode(static_cast<const unsigned char*>(inputData), inputLength, static_cast<char*>(outputBuffer), &outLength);
|
|
||||||
return result == CRYPT_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetBase64EncodeOutputLength(const size_t inputLength)
|
|
||||||
{
|
|
||||||
return 4u * ((inputLength + 2u) / 3u);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t DecodeBase64(const void* base64Data, const size_t inputLength, void* outputBuffer, const size_t outputBufferSize)
|
|
||||||
{
|
|
||||||
unsigned long outLength = GetBase64DecodeOutputLength(base64Data, inputLength);
|
|
||||||
assert(outLength <= outputBufferSize);
|
|
||||||
if (outLength > outputBufferSize)
|
|
||||||
return 0u;
|
|
||||||
|
|
||||||
const auto result = base64_decode(static_cast<const char*>(base64Data), inputLength, static_cast<unsigned char*>(outputBuffer), &outLength);
|
|
||||||
assert(result == CRYPT_OK);
|
|
||||||
|
|
||||||
return static_cast<size_t>(outLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetBase64DecodeOutputLength(const void* base64Data, const size_t inputLength)
|
|
||||||
{
|
|
||||||
assert(base64Data);
|
|
||||||
assert(inputLength);
|
|
||||||
|
|
||||||
if (!base64Data || inputLength == 0u)
|
|
||||||
return 0u;
|
|
||||||
|
|
||||||
auto padding = 0u;
|
|
||||||
if (inputLength >= 1 && static_cast<const char*>(base64Data)[inputLength - 1] == '=')
|
|
||||||
{
|
|
||||||
if (inputLength >= 2 && static_cast<const char*>(base64Data)[inputLength - 2] == '=')
|
|
||||||
padding = 2u;
|
|
||||||
else
|
|
||||||
padding = 1u;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((inputLength / 4u) * 3u) - padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetBase64DecodeOutputLength(const size_t inputLength)
|
|
||||||
{
|
|
||||||
return (inputLength / 4u) * 3u;
|
|
||||||
}
|
|
||||||
} // namespace base64
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace base64
|
|
||||||
{
|
|
||||||
std::string EncodeBase64(const void* inputData, size_t inputLength);
|
|
||||||
bool EncodeBase64(const void* inputData, size_t inputLength, void* outputBuffer, size_t outputBufferSize);
|
|
||||||
size_t GetBase64EncodeOutputLength(size_t inputLength);
|
|
||||||
|
|
||||||
size_t DecodeBase64(const void* base64Data, size_t inputLength, void* outputBuffer, size_t outputBufferSize);
|
|
||||||
size_t GetBase64DecodeOutputLength(const void* base64Data, const size_t inputLength);
|
|
||||||
size_t GetBase64DecodeOutputLength(size_t inputLength);
|
|
||||||
} // namespace base64
|
|
@ -1,48 +0,0 @@
|
|||||||
ImageConverter = {}
|
|
||||||
|
|
||||||
function ImageConverter:include(includes)
|
|
||||||
if includes:handle(self:name()) then
|
|
||||||
includedirs {
|
|
||||||
path.join(ProjectFolder(), "ImageConverter")
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function ImageConverter:link(links)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function ImageConverter:use()
|
|
||||||
dependson(self:name())
|
|
||||||
end
|
|
||||||
|
|
||||||
function ImageConverter:name()
|
|
||||||
return "ImageConverter"
|
|
||||||
end
|
|
||||||
|
|
||||||
function ImageConverter:project()
|
|
||||||
local folder = ProjectFolder()
|
|
||||||
local includes = Includes:create()
|
|
||||||
local links = Links:create()
|
|
||||||
|
|
||||||
project(self:name())
|
|
||||||
targetdir(TargetDirectoryBin)
|
|
||||||
location "%{wks.location}/src/%{prj.name}"
|
|
||||||
kind "ConsoleApp"
|
|
||||||
language "C++"
|
|
||||||
|
|
||||||
files {
|
|
||||||
path.join(folder, "ImageConverter/**.h"),
|
|
||||||
path.join(folder, "ImageConverter/**.cpp")
|
|
||||||
}
|
|
||||||
|
|
||||||
self:include(includes)
|
|
||||||
Utils:include(includes)
|
|
||||||
ObjImage:include(includes)
|
|
||||||
|
|
||||||
Raw:use()
|
|
||||||
|
|
||||||
links:linkto(Utils)
|
|
||||||
links:linkto(ObjImage)
|
|
||||||
links:linkall()
|
|
||||||
end
|
|
@ -1,202 +0,0 @@
|
|||||||
#include "ImageConverter.h"
|
|
||||||
|
|
||||||
#include "Image/DdsLoader.h"
|
|
||||||
#include "Image/DdsWriter.h"
|
|
||||||
#include "Image/IwiLoader.h"
|
|
||||||
#include "Image/IwiWriter13.h"
|
|
||||||
#include "Image/IwiWriter27.h"
|
|
||||||
#include "Image/IwiWriter6.h"
|
|
||||||
#include "Image/IwiWriter8.h"
|
|
||||||
#include "Image/Texture.h"
|
|
||||||
#include "ImageConverterArgs.h"
|
|
||||||
#include "Utils/StringUtils.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <format>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
namespace image_converter
|
|
||||||
{
|
|
||||||
constexpr auto EXTENSION_IWI = ".iwi";
|
|
||||||
constexpr auto EXTENSION_DDS = ".dds";
|
|
||||||
|
|
||||||
class ImageConverterImpl final : public ImageConverter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImageConverterImpl()
|
|
||||||
: m_game_to_convert_to(image_converter::Game::UNKNOWN)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Start(const int argc, const char** argv) override
|
|
||||||
{
|
|
||||||
auto shouldContinue = true;
|
|
||||||
if (!m_args.ParseArgs(argc, argv, shouldContinue))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!shouldContinue)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
m_game_to_convert_to = m_args.m_game_to_convert_to;
|
|
||||||
|
|
||||||
for (const auto& file : m_args.m_files_to_convert)
|
|
||||||
Convert(file);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Convert(const std::string& file)
|
|
||||||
{
|
|
||||||
const fs::path filePath(file);
|
|
||||||
auto extension = filePath.extension().string();
|
|
||||||
utils::MakeStringLowerCase(extension);
|
|
||||||
|
|
||||||
if (extension == EXTENSION_IWI)
|
|
||||||
ConvertIwi(filePath);
|
|
||||||
else if (extension == EXTENSION_DDS)
|
|
||||||
ConvertDds(filePath);
|
|
||||||
else
|
|
||||||
std::cerr << std::format("Unsupported extension {}\n", extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConvertIwi(const fs::path& iwiPath)
|
|
||||||
{
|
|
||||||
std::ifstream file(iwiPath, std::ios::in | std::ios::binary);
|
|
||||||
if (!file.is_open())
|
|
||||||
{
|
|
||||||
std::cerr << std::format("Failed to open input file {}\n", iwiPath.string());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto texture = iwi::LoadIwi(file);
|
|
||||||
if (!texture)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto outPath = iwiPath;
|
|
||||||
outPath.replace_extension(".dds");
|
|
||||||
|
|
||||||
std::ofstream outFile(outPath, std::ios::out | std::ios::binary);
|
|
||||||
if (!outFile.is_open())
|
|
||||||
{
|
|
||||||
std::cerr << std::format("Failed to open output file {}\n", outPath.string());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dds_writer.DumpImage(outFile, texture.get());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConvertDds(const fs::path& ddsPath)
|
|
||||||
{
|
|
||||||
std::ifstream file(ddsPath, std::ios::in | std::ios::binary);
|
|
||||||
if (!file.is_open())
|
|
||||||
{
|
|
||||||
std::cerr << std::format("Failed to open input file {}\n", ddsPath.string());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto texture = dds::LoadDds(file);
|
|
||||||
if (!texture)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!EnsureIwiWriterIsPresent())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto outPath = ddsPath;
|
|
||||||
outPath.replace_extension(".iwi");
|
|
||||||
|
|
||||||
std::ofstream outFile(outPath, std::ios::out | std::ios::binary);
|
|
||||||
if (!outFile.is_open())
|
|
||||||
{
|
|
||||||
std::cerr << std::format("Failed to open output file {}\n", outPath.string());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_iwi_writer->DumpImage(outFile, texture.get());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EnsureIwiWriterIsPresent()
|
|
||||||
{
|
|
||||||
if (m_iwi_writer)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (m_game_to_convert_to == Game::UNKNOWN && !ShowGameTui())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (m_game_to_convert_to)
|
|
||||||
{
|
|
||||||
case Game::IW3:
|
|
||||||
m_iwi_writer = std::make_unique<iwi6::IwiWriter>();
|
|
||||||
break;
|
|
||||||
case Game::IW4:
|
|
||||||
case Game::IW5:
|
|
||||||
m_iwi_writer = std::make_unique<iwi8::IwiWriter>();
|
|
||||||
break;
|
|
||||||
case Game::T5:
|
|
||||||
m_iwi_writer = std::make_unique<iwi13::IwiWriter>();
|
|
||||||
break;
|
|
||||||
case Game::T6:
|
|
||||||
m_iwi_writer = std::make_unique<iwi27::IwiWriter>();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ShowGameTui()
|
|
||||||
{
|
|
||||||
std::cout << "Select the game to convert to:\n";
|
|
||||||
std::cout << " 1 - Call Of Duty 4: Modern Warfare (IW3)\n";
|
|
||||||
std::cout << " 2 - Call Of Duty: Modern Warfare 2 (IW4)\n";
|
|
||||||
std::cout << " 3 - Call Of Duty: Modern Warfare 3 (IW5)\n";
|
|
||||||
std::cout << " 4 - Call Of Duty: Black Ops (T5)\n";
|
|
||||||
std::cout << " 5 - Call Of Duty: Black Ops 2 (T6)\n";
|
|
||||||
|
|
||||||
unsigned num;
|
|
||||||
std::cin >> num;
|
|
||||||
|
|
||||||
switch (num)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
m_game_to_convert_to = Game::IW3;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
m_game_to_convert_to = Game::IW4;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
m_game_to_convert_to = Game::IW5;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
m_game_to_convert_to = Game::T5;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
m_game_to_convert_to = Game::T6;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
std::cerr << "Invalid input\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageConverterArgs m_args;
|
|
||||||
image_converter::Game m_game_to_convert_to;
|
|
||||||
DdsWriter m_dds_writer;
|
|
||||||
std::unique_ptr<IImageWriter> m_iwi_writer;
|
|
||||||
};
|
|
||||||
} // namespace image_converter
|
|
||||||
|
|
||||||
std::unique_ptr<ImageConverter> ImageConverter::Create()
|
|
||||||
{
|
|
||||||
return std::make_unique<image_converter::ImageConverterImpl>();
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class ImageConverter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImageConverter() = default;
|
|
||||||
virtual ~ImageConverter() = default;
|
|
||||||
|
|
||||||
ImageConverter(const ImageConverter& other) = delete;
|
|
||||||
ImageConverter(ImageConverter&& other) noexcept = delete;
|
|
||||||
ImageConverter& operator=(const ImageConverter& other) = delete;
|
|
||||||
ImageConverter& operator=(ImageConverter&& other) noexcept = delete;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Starts the ImageConverter application logic.
|
|
||||||
* \param argc The amount of command line arguments specified.
|
|
||||||
* \param argv The command line arguments.
|
|
||||||
* \return \c true if the application was successful or \c false if an error occurred.
|
|
||||||
*/
|
|
||||||
virtual bool Start(int argc, const char** argv) = 0;
|
|
||||||
|
|
||||||
static std::unique_ptr<ImageConverter> Create();
|
|
||||||
};
|
|
@ -1,149 +0,0 @@
|
|||||||
#include "ImageConverterArgs.h"
|
|
||||||
|
|
||||||
#include "GitVersion.h"
|
|
||||||
#include "Utils/Arguments/UsageInformation.h"
|
|
||||||
|
|
||||||
#include <format>
|
|
||||||
#include <iostream>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
const CommandLineOption* const OPTION_HELP =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithShortName("?")
|
|
||||||
.WithLongName("help")
|
|
||||||
.WithDescription("Displays usage information.")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_VERSION =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithLongName("version")
|
|
||||||
.WithDescription("Prints the application version.")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_VERBOSE =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithShortName("v")
|
|
||||||
.WithLongName("verbose")
|
|
||||||
.WithDescription("Outputs a lot more and more detailed messages.")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
constexpr auto CATEGORY_GAME = "Game";
|
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_GAME_IW3 =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithLongName("iw3")
|
|
||||||
.WithCategory(CATEGORY_GAME)
|
|
||||||
.WithDescription("Converts images for IW3.")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_GAME_IW4 =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithLongName("iw4")
|
|
||||||
.WithCategory(CATEGORY_GAME)
|
|
||||||
.WithDescription("Converts images for IW4.")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_GAME_IW5 =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithLongName("iw5")
|
|
||||||
.WithCategory(CATEGORY_GAME)
|
|
||||||
.WithDescription("Converts images for IW5.")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_GAME_T5 =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithLongName("t5")
|
|
||||||
.WithCategory(CATEGORY_GAME)
|
|
||||||
.WithDescription("Converts images for T5.")
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_GAME_T6 =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithLongName("t6")
|
|
||||||
.WithCategory(CATEGORY_GAME)
|
|
||||||
.WithDescription("Converts images for T6.")
|
|
||||||
.Build();
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
const CommandLineOption* const COMMAND_LINE_OPTIONS[]{
|
|
||||||
OPTION_HELP,
|
|
||||||
OPTION_VERSION,
|
|
||||||
OPTION_VERBOSE,
|
|
||||||
OPTION_GAME_IW3,
|
|
||||||
OPTION_GAME_IW4,
|
|
||||||
OPTION_GAME_IW5,
|
|
||||||
OPTION_GAME_T5,
|
|
||||||
OPTION_GAME_T6,
|
|
||||||
};
|
|
||||||
|
|
||||||
ImageConverterArgs::ImageConverterArgs()
|
|
||||||
: m_verbose(false),
|
|
||||||
m_game_to_convert_to(image_converter::Game::UNKNOWN),
|
|
||||||
m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v<decltype(COMMAND_LINE_OPTIONS)>)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageConverterArgs::PrintUsage()
|
|
||||||
{
|
|
||||||
UsageInformation usage("ImageConverter.exe");
|
|
||||||
|
|
||||||
for (const auto* commandLineOption : COMMAND_LINE_OPTIONS)
|
|
||||||
{
|
|
||||||
usage.AddCommandLineOption(commandLineOption);
|
|
||||||
}
|
|
||||||
|
|
||||||
usage.AddArgument("fileToConvert");
|
|
||||||
usage.SetVariableArguments(true);
|
|
||||||
|
|
||||||
usage.Print();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageConverterArgs::PrintVersion()
|
|
||||||
{
|
|
||||||
std::cout << std::format("OpenAssetTools ImageConverter {}\n", GIT_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageConverterArgs::SetVerbose(const bool isVerbose)
|
|
||||||
{
|
|
||||||
m_verbose = isVerbose;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImageConverterArgs::ParseArgs(const int argc, const char** argv, bool& shouldContinue)
|
|
||||||
{
|
|
||||||
shouldContinue = true;
|
|
||||||
if (!m_argument_parser.ParseArguments(argc, argv))
|
|
||||||
{
|
|
||||||
PrintUsage();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user requested help
|
|
||||||
if (m_argument_parser.IsOptionSpecified(OPTION_HELP))
|
|
||||||
{
|
|
||||||
PrintUsage();
|
|
||||||
shouldContinue = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user wants to see the version
|
|
||||||
if (m_argument_parser.IsOptionSpecified(OPTION_VERSION))
|
|
||||||
{
|
|
||||||
PrintVersion();
|
|
||||||
shouldContinue = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_files_to_convert = m_argument_parser.GetArguments();
|
|
||||||
if (m_files_to_convert.empty())
|
|
||||||
{
|
|
||||||
// No files to convert specified...
|
|
||||||
PrintUsage();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -v; --verbose
|
|
||||||
SetVerbose(m_argument_parser.IsOptionSpecified(OPTION_VERBOSE));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Utils/Arguments/ArgumentParser.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace image_converter
|
|
||||||
{
|
|
||||||
enum class Game : std::uint8_t
|
|
||||||
{
|
|
||||||
UNKNOWN,
|
|
||||||
IW3,
|
|
||||||
IW4,
|
|
||||||
IW5,
|
|
||||||
T5,
|
|
||||||
T6
|
|
||||||
};
|
|
||||||
} // namespace image_converter
|
|
||||||
|
|
||||||
class ImageConverterArgs
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImageConverterArgs();
|
|
||||||
bool ParseArgs(int argc, const char** argv, bool& shouldContinue);
|
|
||||||
|
|
||||||
bool m_verbose;
|
|
||||||
std::vector<std::string> m_files_to_convert;
|
|
||||||
image_converter::Game m_game_to_convert_to;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* \brief Prints a command line usage help text for the ImageConverter tool to stdout.
|
|
||||||
*/
|
|
||||||
static void PrintUsage();
|
|
||||||
static void PrintVersion();
|
|
||||||
|
|
||||||
void SetVerbose(bool isVerbose);
|
|
||||||
|
|
||||||
ArgumentParser m_argument_parser;
|
|
||||||
};
|
|
@ -1,8 +0,0 @@
|
|||||||
#include "ImageConverter.h"
|
|
||||||
|
|
||||||
int main(const int argc, const char** argv)
|
|
||||||
{
|
|
||||||
const auto imageConverter = ImageConverter::Create();
|
|
||||||
|
|
||||||
return imageConverter->Start(argc, argv) ? 0 : 1;
|
|
||||||
}
|
|
@ -39,7 +39,6 @@ function Linker:project()
|
|||||||
self:include(includes)
|
self:include(includes)
|
||||||
Utils:include(includes)
|
Utils:include(includes)
|
||||||
ZoneLoading:include(includes)
|
ZoneLoading:include(includes)
|
||||||
ObjCompiling:include(includes)
|
|
||||||
ObjLoading:include(includes)
|
ObjLoading:include(includes)
|
||||||
ObjWriting:include(includes)
|
ObjWriting:include(includes)
|
||||||
ZoneWriting:include(includes)
|
ZoneWriting:include(includes)
|
||||||
@ -47,7 +46,6 @@ function Linker:project()
|
|||||||
Raw:use()
|
Raw:use()
|
||||||
|
|
||||||
links:linkto(Utils)
|
links:linkto(Utils)
|
||||||
links:linkto(ObjCompiling)
|
|
||||||
links:linkto(ZoneLoading)
|
links:linkto(ZoneLoading)
|
||||||
links:linkto(ZoneWriting)
|
links:linkto(ZoneWriting)
|
||||||
links:linkto(ObjLoading)
|
links:linkto(ObjLoading)
|
||||||
|
98
src/Linker/Game/IW3/ZoneCreatorIW3.cpp
Normal file
98
src/Linker/Game/IW3/ZoneCreatorIW3.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "ZoneCreatorIW3.h"
|
||||||
|
|
||||||
|
#include "AssetLoading/AssetLoadingContext.h"
|
||||||
|
#include "Game/IW3/GameAssetPoolIW3.h"
|
||||||
|
#include "Game/IW3/GameIW3.h"
|
||||||
|
#include "ObjLoading.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace IW3;
|
||||||
|
|
||||||
|
ZoneCreator::ZoneCreator()
|
||||||
|
{
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
{
|
||||||
|
AddAssetTypeName(assetType, GameAssetPoolIW3::AssetTypeNameByType(assetType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name)
|
||||||
|
{
|
||||||
|
m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Gdt*> ZoneCreator::CreateGdtList(const ZoneCreationContext& context)
|
||||||
|
{
|
||||||
|
std::vector<Gdt*> gdtList;
|
||||||
|
gdtList.reserve(context.m_gdt_files.size());
|
||||||
|
for (const auto& gdt : context.m_gdt_files)
|
||||||
|
gdtList.push_back(gdt.get());
|
||||||
|
|
||||||
|
return gdtList;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const
|
||||||
|
{
|
||||||
|
for (const auto& ignoreEntry : context.m_ignored_assets.m_entries)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << ignoreEntry.m_type << "\" for ignore \"" << ignoreEntry.m_name << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ignoredAssetMap[ignoreEntry.m_name] = foundAssetTypeEntry->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::CreateZoneAssetPools(Zone* zone) const
|
||||||
|
{
|
||||||
|
zone->m_pools = std::make_unique<GameAssetPoolIW3>(zone, zone->m_priority);
|
||||||
|
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
zone->m_pools->InitPoolDynamic(assetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::SupportsGame(const std::string& gameName) const
|
||||||
|
{
|
||||||
|
return gameName == g_GameIW3.GetShortName();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
|
||||||
|
{
|
||||||
|
auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameIW3);
|
||||||
|
CreateZoneAssetPools(zone.get());
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
if (!assetEntry.m_is_reference)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name, assetEntry.m_is_reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto assetLoadingContext = std::make_unique<AssetLoadingContext>(zone.get(), context.m_asset_search_path, CreateGdtList(context));
|
||||||
|
if (!CreateIgnoredAssetMap(context, assetLoadingContext->m_ignored_asset_map))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(assetEntry.m_asset_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"\n";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ObjLoading::LoadAssetForZone(assetLoadingContext.get(), foundAssetTypeEntry->second, assetEntry.m_asset_name))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjLoading::FinalizeAssetsForZone(assetLoadingContext.get());
|
||||||
|
|
||||||
|
return zone;
|
||||||
|
}
|
25
src/Linker/Game/IW3/ZoneCreatorIW3.h
Normal file
25
src/Linker/Game/IW3/ZoneCreatorIW3.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Zone/ZoneTypes.h"
|
||||||
|
#include "ZoneCreation/IZoneCreator.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace IW3
|
||||||
|
{
|
||||||
|
class ZoneCreator final : public IZoneCreator
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, asset_type_t> m_asset_types_by_name;
|
||||||
|
|
||||||
|
void AddAssetTypeName(asset_type_t assetType, std::string name);
|
||||||
|
static std::vector<Gdt*> CreateGdtList(const ZoneCreationContext& context);
|
||||||
|
bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const;
|
||||||
|
void CreateZoneAssetPools(Zone* zone) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZoneCreator();
|
||||||
|
|
||||||
|
_NODISCARD bool SupportsGame(const std::string& gameName) const override;
|
||||||
|
_NODISCARD std::unique_ptr<Zone> CreateZoneForDefinition(ZoneCreationContext& context) const override;
|
||||||
|
};
|
||||||
|
} // namespace IW3
|
97
src/Linker/Game/IW4/ZoneCreatorIW4.cpp
Normal file
97
src/Linker/Game/IW4/ZoneCreatorIW4.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include "ZoneCreatorIW4.h"
|
||||||
|
|
||||||
|
#include "Game/IW4/GameAssetPoolIW4.h"
|
||||||
|
#include "Game/IW4/GameIW4.h"
|
||||||
|
#include "ObjLoading.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace IW4;
|
||||||
|
|
||||||
|
ZoneCreator::ZoneCreator()
|
||||||
|
{
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
{
|
||||||
|
AddAssetTypeName(assetType, GameAssetPoolIW4::AssetTypeNameByType(assetType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name)
|
||||||
|
{
|
||||||
|
m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Gdt*> ZoneCreator::CreateGdtList(const ZoneCreationContext& context)
|
||||||
|
{
|
||||||
|
std::vector<Gdt*> gdtList;
|
||||||
|
gdtList.reserve(context.m_gdt_files.size());
|
||||||
|
for (const auto& gdt : context.m_gdt_files)
|
||||||
|
gdtList.push_back(gdt.get());
|
||||||
|
|
||||||
|
return gdtList;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const
|
||||||
|
{
|
||||||
|
for (const auto& ignoreEntry : context.m_ignored_assets.m_entries)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << ignoreEntry.m_type << "\" for ignore \"" << ignoreEntry.m_name << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ignoredAssetMap[ignoreEntry.m_name] = foundAssetTypeEntry->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::CreateZoneAssetPools(Zone* zone) const
|
||||||
|
{
|
||||||
|
zone->m_pools = std::make_unique<GameAssetPoolIW4>(zone, zone->m_priority);
|
||||||
|
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
zone->m_pools->InitPoolDynamic(assetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::SupportsGame(const std::string& gameName) const
|
||||||
|
{
|
||||||
|
return gameName == g_GameIW4.GetShortName();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
|
||||||
|
{
|
||||||
|
auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameIW4);
|
||||||
|
CreateZoneAssetPools(zone.get());
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
if (!assetEntry.m_is_reference)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name, assetEntry.m_is_reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto assetLoadingContext = std::make_unique<AssetLoadingContext>(zone.get(), context.m_asset_search_path, CreateGdtList(context));
|
||||||
|
if (!CreateIgnoredAssetMap(context, assetLoadingContext->m_ignored_asset_map))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(assetEntry.m_asset_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"\n";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ObjLoading::LoadAssetForZone(assetLoadingContext.get(), foundAssetTypeEntry->second, assetEntry.m_asset_name))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjLoading::FinalizeAssetsForZone(assetLoadingContext.get());
|
||||||
|
|
||||||
|
return zone;
|
||||||
|
}
|
25
src/Linker/Game/IW4/ZoneCreatorIW4.h
Normal file
25
src/Linker/Game/IW4/ZoneCreatorIW4.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Zone/ZoneTypes.h"
|
||||||
|
#include "ZoneCreation/IZoneCreator.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace IW4
|
||||||
|
{
|
||||||
|
class ZoneCreator final : public IZoneCreator
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, asset_type_t> m_asset_types_by_name;
|
||||||
|
|
||||||
|
void AddAssetTypeName(asset_type_t assetType, std::string name);
|
||||||
|
static std::vector<Gdt*> CreateGdtList(const ZoneCreationContext& context);
|
||||||
|
bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const;
|
||||||
|
void CreateZoneAssetPools(Zone* zone) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZoneCreator();
|
||||||
|
|
||||||
|
_NODISCARD bool SupportsGame(const std::string& gameName) const override;
|
||||||
|
_NODISCARD std::unique_ptr<Zone> CreateZoneForDefinition(ZoneCreationContext& context) const override;
|
||||||
|
};
|
||||||
|
} // namespace IW4
|
97
src/Linker/Game/IW5/ZoneCreatorIW5.cpp
Normal file
97
src/Linker/Game/IW5/ZoneCreatorIW5.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include "ZoneCreatorIW5.h"
|
||||||
|
|
||||||
|
#include "Game/IW5/GameAssetPoolIW5.h"
|
||||||
|
#include "Game/IW5/GameIW5.h"
|
||||||
|
#include "ObjLoading.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace IW5;
|
||||||
|
|
||||||
|
ZoneCreator::ZoneCreator()
|
||||||
|
{
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
{
|
||||||
|
AddAssetTypeName(assetType, GameAssetPoolIW5::AssetTypeNameByType(assetType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name)
|
||||||
|
{
|
||||||
|
m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Gdt*> ZoneCreator::CreateGdtList(const ZoneCreationContext& context)
|
||||||
|
{
|
||||||
|
std::vector<Gdt*> gdtList;
|
||||||
|
gdtList.reserve(context.m_gdt_files.size());
|
||||||
|
for (const auto& gdt : context.m_gdt_files)
|
||||||
|
gdtList.push_back(gdt.get());
|
||||||
|
|
||||||
|
return gdtList;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const
|
||||||
|
{
|
||||||
|
for (const auto& ignoreEntry : context.m_ignored_assets.m_entries)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << ignoreEntry.m_type << "\" for ignore \"" << ignoreEntry.m_name << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ignoredAssetMap[ignoreEntry.m_name] = foundAssetTypeEntry->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::CreateZoneAssetPools(Zone* zone) const
|
||||||
|
{
|
||||||
|
zone->m_pools = std::make_unique<GameAssetPoolIW5>(zone, zone->m_priority);
|
||||||
|
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
zone->m_pools->InitPoolDynamic(assetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::SupportsGame(const std::string& gameName) const
|
||||||
|
{
|
||||||
|
return gameName == g_GameIW5.GetShortName();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
|
||||||
|
{
|
||||||
|
auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameIW5);
|
||||||
|
CreateZoneAssetPools(zone.get());
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
if (!assetEntry.m_is_reference)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name, assetEntry.m_is_reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto assetLoadingContext = std::make_unique<AssetLoadingContext>(zone.get(), context.m_asset_search_path, CreateGdtList(context));
|
||||||
|
if (!CreateIgnoredAssetMap(context, assetLoadingContext->m_ignored_asset_map))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(assetEntry.m_asset_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"\n";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ObjLoading::LoadAssetForZone(assetLoadingContext.get(), foundAssetTypeEntry->second, assetEntry.m_asset_name))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjLoading::FinalizeAssetsForZone(assetLoadingContext.get());
|
||||||
|
|
||||||
|
return zone;
|
||||||
|
}
|
25
src/Linker/Game/IW5/ZoneCreatorIW5.h
Normal file
25
src/Linker/Game/IW5/ZoneCreatorIW5.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Zone/ZoneTypes.h"
|
||||||
|
#include "ZoneCreation/IZoneCreator.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace IW5
|
||||||
|
{
|
||||||
|
class ZoneCreator final : public IZoneCreator
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, asset_type_t> m_asset_types_by_name;
|
||||||
|
|
||||||
|
void AddAssetTypeName(asset_type_t assetType, std::string name);
|
||||||
|
static std::vector<Gdt*> CreateGdtList(const ZoneCreationContext& context);
|
||||||
|
bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const;
|
||||||
|
void CreateZoneAssetPools(Zone* zone) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZoneCreator();
|
||||||
|
|
||||||
|
_NODISCARD bool SupportsGame(const std::string& gameName) const override;
|
||||||
|
_NODISCARD std::unique_ptr<Zone> CreateZoneForDefinition(ZoneCreationContext& context) const override;
|
||||||
|
};
|
||||||
|
} // namespace IW5
|
98
src/Linker/Game/T5/ZoneCreatorT5.cpp
Normal file
98
src/Linker/Game/T5/ZoneCreatorT5.cpp
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#include "ZoneCreatorT5.h"
|
||||||
|
|
||||||
|
#include "AssetLoading/AssetLoadingContext.h"
|
||||||
|
#include "Game/T5/GameAssetPoolT5.h"
|
||||||
|
#include "Game/T5/GameT5.h"
|
||||||
|
#include "ObjLoading.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace T5;
|
||||||
|
|
||||||
|
ZoneCreator::ZoneCreator()
|
||||||
|
{
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
{
|
||||||
|
AddAssetTypeName(assetType, GameAssetPoolT5::AssetTypeNameByType(assetType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name)
|
||||||
|
{
|
||||||
|
m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Gdt*> ZoneCreator::CreateGdtList(ZoneCreationContext& context)
|
||||||
|
{
|
||||||
|
std::vector<Gdt*> gdtList;
|
||||||
|
gdtList.reserve(context.m_gdt_files.size());
|
||||||
|
for (const auto& gdt : context.m_gdt_files)
|
||||||
|
gdtList.push_back(gdt.get());
|
||||||
|
|
||||||
|
return gdtList;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const
|
||||||
|
{
|
||||||
|
for (const auto& ignoreEntry : context.m_ignored_assets.m_entries)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << ignoreEntry.m_type << "\" for ignore \"" << ignoreEntry.m_name << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ignoredAssetMap[ignoreEntry.m_name] = foundAssetTypeEntry->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::CreateZoneAssetPools(Zone* zone) const
|
||||||
|
{
|
||||||
|
zone->m_pools = std::make_unique<GameAssetPoolT5>(zone, zone->m_priority);
|
||||||
|
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
zone->m_pools->InitPoolDynamic(assetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::SupportsGame(const std::string& gameName) const
|
||||||
|
{
|
||||||
|
return gameName == g_GameT5.GetShortName();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
|
||||||
|
{
|
||||||
|
auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameT5);
|
||||||
|
CreateZoneAssetPools(zone.get());
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
if (!assetEntry.m_is_reference)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name, assetEntry.m_is_reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto assetLoadingContext = std::make_unique<AssetLoadingContext>(zone.get(), context.m_asset_search_path, CreateGdtList(context));
|
||||||
|
if (!CreateIgnoredAssetMap(context, assetLoadingContext->m_ignored_asset_map))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(assetEntry.m_asset_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"\n";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ObjLoading::LoadAssetForZone(assetLoadingContext.get(), foundAssetTypeEntry->second, assetEntry.m_asset_name))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjLoading::FinalizeAssetsForZone(assetLoadingContext.get());
|
||||||
|
|
||||||
|
return zone;
|
||||||
|
}
|
25
src/Linker/Game/T5/ZoneCreatorT5.h
Normal file
25
src/Linker/Game/T5/ZoneCreatorT5.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Zone/ZoneTypes.h"
|
||||||
|
#include "ZoneCreation/IZoneCreator.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace T5
|
||||||
|
{
|
||||||
|
class ZoneCreator final : public IZoneCreator
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, asset_type_t> m_asset_types_by_name;
|
||||||
|
|
||||||
|
void AddAssetTypeName(asset_type_t assetType, std::string name);
|
||||||
|
static std::vector<Gdt*> CreateGdtList(ZoneCreationContext& context);
|
||||||
|
bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const;
|
||||||
|
void CreateZoneAssetPools(Zone* zone) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZoneCreator();
|
||||||
|
|
||||||
|
_NODISCARD bool SupportsGame(const std::string& gameName) const override;
|
||||||
|
_NODISCARD std::unique_ptr<Zone> CreateZoneForDefinition(ZoneCreationContext& context) const override;
|
||||||
|
};
|
||||||
|
} // namespace T5
|
149
src/Linker/Game/T6/ZoneCreatorT6.cpp
Normal file
149
src/Linker/Game/T6/ZoneCreatorT6.cpp
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#include "ZoneCreatorT6.h"
|
||||||
|
|
||||||
|
#include "Game/T6/CommonT6.h"
|
||||||
|
#include "Game/T6/GameAssetPoolT6.h"
|
||||||
|
#include "Game/T6/GameT6.h"
|
||||||
|
#include "Game/T6/T6.h"
|
||||||
|
#include "ObjLoading.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace T6;
|
||||||
|
|
||||||
|
ZoneCreator::ZoneCreator()
|
||||||
|
{
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
{
|
||||||
|
AddAssetTypeName(assetType, GameAssetPoolT6::AssetTypeNameByType(assetType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::AddAssetTypeName(asset_type_t assetType, std::string name)
|
||||||
|
{
|
||||||
|
m_asset_types_by_name.emplace(std::make_pair(std::move(name), assetType));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Gdt*> ZoneCreator::CreateGdtList(const ZoneCreationContext& context)
|
||||||
|
{
|
||||||
|
std::vector<Gdt*> gdtList;
|
||||||
|
gdtList.reserve(context.m_gdt_files.size());
|
||||||
|
for (const auto& gdt : context.m_gdt_files)
|
||||||
|
gdtList.push_back(gdt.get());
|
||||||
|
|
||||||
|
return gdtList;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const
|
||||||
|
{
|
||||||
|
for (const auto& ignoreEntry : context.m_ignored_assets.m_entries)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(ignoreEntry.m_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << ignoreEntry.m_type << "\" for ignore \"" << ignoreEntry.m_name << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ignoredAssetMap[ignoreEntry.m_name] = foundAssetTypeEntry->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::CreateZoneAssetPools(Zone* zone) const
|
||||||
|
{
|
||||||
|
zone->m_pools = std::make_unique<GameAssetPoolT6>(zone, zone->m_priority);
|
||||||
|
|
||||||
|
for (auto assetType = 0; assetType < ASSET_TYPE_COUNT; assetType++)
|
||||||
|
zone->m_pools->InitPoolDynamic(assetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneCreator::HandleMetadata(Zone* zone, const ZoneCreationContext& context) const
|
||||||
|
{
|
||||||
|
std::vector<KeyValuePair> kvpList;
|
||||||
|
|
||||||
|
for (const auto& metaData : context.m_definition->m_metadata)
|
||||||
|
{
|
||||||
|
if (metaData->m_key.rfind("level.", 0) == 0)
|
||||||
|
{
|
||||||
|
const std::string strValue = metaData->m_key.substr(std::char_traits<char>::length("level."));
|
||||||
|
if (strValue.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int keyHash;
|
||||||
|
if (strValue[0] == '@')
|
||||||
|
{
|
||||||
|
char* endPtr;
|
||||||
|
keyHash = strtol(&strValue[1], &endPtr, 16);
|
||||||
|
|
||||||
|
if (endPtr != &strValue[strValue.size()])
|
||||||
|
{
|
||||||
|
std::cout << "Could not parse metadata key \"" << metaData->m_key << "\" as hash\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyHash = Common::Com_HashKey(strValue.c_str(), 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyValuePair kvp{keyHash, Common::Com_HashKey(zone->m_name.c_str(), 64), zone->GetMemory()->Dup(metaData->m_value.c_str())};
|
||||||
|
kvpList.push_back(kvp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!kvpList.empty())
|
||||||
|
{
|
||||||
|
auto* kvps = zone->GetMemory()->Create<KeyValuePairs>();
|
||||||
|
kvps->name = zone->GetMemory()->Dup(zone->m_name.c_str());
|
||||||
|
kvps->numVariables = kvpList.size();
|
||||||
|
kvps->keyValuePairs = static_cast<KeyValuePair*>(zone->GetMemory()->Alloc(sizeof(KeyValuePair) * kvpList.size()));
|
||||||
|
|
||||||
|
for (auto i = 0u; i < kvpList.size(); i++)
|
||||||
|
kvps->keyValuePairs[i] = kvpList[i];
|
||||||
|
|
||||||
|
zone->m_pools->AddAsset(std::make_unique<XAssetInfo<KeyValuePairs>>(ASSET_TYPE_KEYVALUEPAIRS, zone->m_name, kvps));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ZoneCreator::SupportsGame(const std::string& gameName) const
|
||||||
|
{
|
||||||
|
return gameName == g_GameT6.GetShortName();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Zone> ZoneCreator::CreateZoneForDefinition(ZoneCreationContext& context) const
|
||||||
|
{
|
||||||
|
auto zone = std::make_unique<Zone>(context.m_definition->m_name, 0, &g_GameT6);
|
||||||
|
CreateZoneAssetPools(zone.get());
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
if (!assetEntry.m_is_reference)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name, assetEntry.m_is_reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto assetLoadingContext = std::make_unique<AssetLoadingContext>(zone.get(), context.m_asset_search_path, CreateGdtList(context));
|
||||||
|
if (!CreateIgnoredAssetMap(context, assetLoadingContext->m_ignored_asset_map))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
HandleMetadata(zone.get(), context);
|
||||||
|
|
||||||
|
for (const auto& assetEntry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
const auto foundAssetTypeEntry = m_asset_types_by_name.find(assetEntry.m_asset_type);
|
||||||
|
if (foundAssetTypeEntry == m_asset_types_by_name.end())
|
||||||
|
{
|
||||||
|
std::cout << "Unknown asset type \"" << assetEntry.m_asset_type << "\"\n";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ObjLoading::LoadAssetForZone(assetLoadingContext.get(), foundAssetTypeEntry->second, assetEntry.m_asset_name))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjLoading::FinalizeAssetsForZone(assetLoadingContext.get());
|
||||||
|
|
||||||
|
return zone;
|
||||||
|
}
|
26
src/Linker/Game/T6/ZoneCreatorT6.h
Normal file
26
src/Linker/Game/T6/ZoneCreatorT6.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Zone/ZoneTypes.h"
|
||||||
|
#include "ZoneCreation/IZoneCreator.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace T6
|
||||||
|
{
|
||||||
|
class ZoneCreator final : public IZoneCreator
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, asset_type_t> m_asset_types_by_name;
|
||||||
|
|
||||||
|
void AddAssetTypeName(asset_type_t assetType, std::string name);
|
||||||
|
static std::vector<Gdt*> CreateGdtList(const ZoneCreationContext& context);
|
||||||
|
bool CreateIgnoredAssetMap(const ZoneCreationContext& context, std::unordered_map<std::string, asset_type_t>& ignoredAssetMap) const;
|
||||||
|
void CreateZoneAssetPools(Zone* zone) const;
|
||||||
|
void HandleMetadata(Zone* zone, const ZoneCreationContext& context) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ZoneCreator();
|
||||||
|
|
||||||
|
_NODISCARD bool SupportsGame(const std::string& gameName) const override;
|
||||||
|
_NODISCARD std::unique_ptr<Zone> CreateZoneForDefinition(ZoneCreationContext& context) const override;
|
||||||
|
};
|
||||||
|
} // namespace T6
|
@ -1,211 +1,149 @@
|
|||||||
#include "Linker.h"
|
#include "Linker.h"
|
||||||
|
|
||||||
|
#include "Game/IW3/ZoneCreatorIW3.h"
|
||||||
|
#include "Game/IW4/ZoneCreatorIW4.h"
|
||||||
|
#include "Game/IW5/ZoneCreatorIW5.h"
|
||||||
|
#include "Game/T5/ZoneCreatorT5.h"
|
||||||
|
#include "Game/T6/ZoneCreatorT6.h"
|
||||||
#include "LinkerArgs.h"
|
#include "LinkerArgs.h"
|
||||||
#include "LinkerPaths.h"
|
#include "LinkerSearchPaths.h"
|
||||||
|
#include "ObjContainer/IPak/IPakWriter.h"
|
||||||
|
#include "ObjContainer/IWD/IWD.h"
|
||||||
#include "ObjContainer/SoundBank/SoundBankWriter.h"
|
#include "ObjContainer/SoundBank/SoundBankWriter.h"
|
||||||
|
#include "ObjLoading.h"
|
||||||
#include "ObjWriting.h"
|
#include "ObjWriting.h"
|
||||||
#include "SearchPath/OutputPathFilesystem.h"
|
|
||||||
#include "SearchPath/SearchPaths.h"
|
#include "SearchPath/SearchPaths.h"
|
||||||
|
#include "Utils/Arguments/ArgumentParser.h"
|
||||||
|
#include "Utils/ClassUtils.h"
|
||||||
#include "Utils/ObjFileStream.h"
|
#include "Utils/ObjFileStream.h"
|
||||||
|
#include "Utils/StringUtils.h"
|
||||||
#include "Zone/AssetList/AssetList.h"
|
#include "Zone/AssetList/AssetList.h"
|
||||||
#include "Zone/AssetList/AssetListReader.h"
|
#include "Zone/AssetList/AssetListStream.h"
|
||||||
#include "Zone/Definition/ZoneDefinitionStream.h"
|
#include "Zone/Definition/ZoneDefinitionStream.h"
|
||||||
|
#include "ZoneCreation/IZoneCreator.h"
|
||||||
#include "ZoneCreation/ZoneCreationContext.h"
|
#include "ZoneCreation/ZoneCreationContext.h"
|
||||||
#include "ZoneCreation/ZoneCreator.h"
|
|
||||||
#include "ZoneLoading.h"
|
#include "ZoneLoading.h"
|
||||||
#include "ZoneWriting.h"
|
#include "ZoneWriting.h"
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <format>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <unordered_set>
|
#include <regex>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
namespace
|
const IZoneCreator* const ZONE_CREATORS[]{
|
||||||
|
new IW3::ZoneCreator(),
|
||||||
|
new IW4::ZoneCreator(),
|
||||||
|
new IW5::ZoneCreator(),
|
||||||
|
new T5::ZoneCreator(),
|
||||||
|
new T6::ZoneCreator(),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ProjectType
|
||||||
{
|
{
|
||||||
class LinkerSearchPathContext
|
NONE,
|
||||||
{
|
FASTFILE,
|
||||||
public:
|
IPAK,
|
||||||
explicit LinkerSearchPathContext(const ILinkerSearchPathBuilder& searchPathBuilder)
|
|
||||||
: m_search_path_builder(searchPathBuilder)
|
|
||||||
{
|
|
||||||
m_independent_search_paths = m_search_path_builder.BuildIndependentSearchPaths();
|
|
||||||
if (m_independent_search_paths)
|
|
||||||
m_search_paths.IncludeSearchPath(m_independent_search_paths.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] ISearchPath& GetSearchPaths()
|
MAX
|
||||||
{
|
};
|
||||||
return m_search_paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadProjectSpecific(const std::string& projectName)
|
constexpr const char* PROJECT_TYPE_NAMES[static_cast<unsigned>(ProjectType::MAX)]{
|
||||||
{
|
"none",
|
||||||
m_project_specific_search_paths = m_search_path_builder.BuildSearchPathsSpecificToProject(projectName);
|
"fastfile",
|
||||||
if (m_project_specific_search_paths)
|
"ipak",
|
||||||
m_search_paths.IncludeSearchPath(m_project_specific_search_paths.get());
|
};
|
||||||
}
|
|
||||||
|
|
||||||
void UnloadProjectSpecific()
|
|
||||||
{
|
|
||||||
if (!m_project_specific_search_paths)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_search_paths.RemoveSearchPath(m_project_specific_search_paths.get());
|
|
||||||
m_project_specific_search_paths.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadGameSpecific(const std::string& projectName, const GameId game)
|
|
||||||
{
|
|
||||||
m_game_specific_search_paths = m_search_path_builder.BuildSearchPathsSpecificToProjectAndGame(projectName, game);
|
|
||||||
if (m_game_specific_search_paths)
|
|
||||||
m_search_paths.IncludeSearchPath(m_game_specific_search_paths.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnloadGameSpecific()
|
|
||||||
{
|
|
||||||
if (!m_game_specific_search_paths)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_search_paths.RemoveSearchPath(m_game_specific_search_paths.get());
|
|
||||||
m_game_specific_search_paths.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const ILinkerSearchPathBuilder& m_search_path_builder;
|
|
||||||
std::unique_ptr<ISearchPath> m_independent_search_paths;
|
|
||||||
std::unique_ptr<ISearchPath> m_project_specific_search_paths;
|
|
||||||
std::unique_ptr<ISearchPath> m_game_specific_search_paths;
|
|
||||||
SearchPaths m_search_paths;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LinkerPathManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit LinkerPathManager(const LinkerArgs& args)
|
|
||||||
: m_linker_paths(ILinkerPaths::FromArgs(args)),
|
|
||||||
m_asset_paths(m_linker_paths->AssetSearchPaths()),
|
|
||||||
m_gdt_paths(m_linker_paths->GdtSearchPaths()),
|
|
||||||
m_source_paths(m_linker_paths->SourceSearchPaths())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<ILinkerPaths> m_linker_paths;
|
|
||||||
LinkerSearchPathContext m_asset_paths;
|
|
||||||
LinkerSearchPathContext m_gdt_paths;
|
|
||||||
LinkerSearchPathContext m_source_paths;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PathProjectContext
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PathProjectContext(LinkerPathManager& paths, const std::string& projectName)
|
|
||||||
: m_paths(paths)
|
|
||||||
{
|
|
||||||
m_paths.m_asset_paths.LoadProjectSpecific(projectName);
|
|
||||||
m_paths.m_gdt_paths.LoadProjectSpecific(projectName);
|
|
||||||
m_paths.m_source_paths.LoadProjectSpecific(projectName);
|
|
||||||
}
|
|
||||||
|
|
||||||
~PathProjectContext()
|
|
||||||
{
|
|
||||||
m_paths.m_asset_paths.UnloadProjectSpecific();
|
|
||||||
m_paths.m_gdt_paths.UnloadProjectSpecific();
|
|
||||||
m_paths.m_source_paths.UnloadProjectSpecific();
|
|
||||||
}
|
|
||||||
|
|
||||||
PathProjectContext(const PathProjectContext& other) = delete;
|
|
||||||
PathProjectContext(PathProjectContext&& other) noexcept = delete;
|
|
||||||
PathProjectContext& operator=(const PathProjectContext& other) = delete;
|
|
||||||
PathProjectContext& operator=(PathProjectContext&& other) noexcept = delete;
|
|
||||||
|
|
||||||
private:
|
|
||||||
LinkerPathManager& m_paths;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PathGameContext
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PathGameContext(LinkerPathManager& paths, const std::string& projectName, const GameId game)
|
|
||||||
: m_paths(paths)
|
|
||||||
{
|
|
||||||
m_paths.m_asset_paths.LoadGameSpecific(projectName, game);
|
|
||||||
m_paths.m_gdt_paths.LoadGameSpecific(projectName, game);
|
|
||||||
m_paths.m_source_paths.LoadGameSpecific(projectName, game);
|
|
||||||
}
|
|
||||||
|
|
||||||
~PathGameContext()
|
|
||||||
{
|
|
||||||
m_paths.m_asset_paths.UnloadGameSpecific();
|
|
||||||
m_paths.m_gdt_paths.UnloadGameSpecific();
|
|
||||||
m_paths.m_source_paths.UnloadGameSpecific();
|
|
||||||
}
|
|
||||||
|
|
||||||
PathGameContext(const PathGameContext& other) = delete;
|
|
||||||
PathGameContext(PathGameContext&& other) noexcept = delete;
|
|
||||||
PathGameContext& operator=(const PathGameContext& other) = delete;
|
|
||||||
PathGameContext& operator=(PathGameContext&& other) noexcept = delete;
|
|
||||||
|
|
||||||
private:
|
|
||||||
LinkerPathManager& m_paths;
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
class LinkerImpl final : public Linker
|
class LinkerImpl final : public Linker
|
||||||
{
|
{
|
||||||
std::unique_ptr<ZoneDefinition> ReadZoneDefinition(LinkerPathManager& paths, const std::string& targetName, bool logMissing = true) const
|
static constexpr const char* METADATA_GAME = "game";
|
||||||
|
static constexpr const char* METADATA_GDT = "gdt";
|
||||||
|
static constexpr const char* METADATA_NAME = "name";
|
||||||
|
static constexpr const char* METADATA_TYPE = "type";
|
||||||
|
|
||||||
|
LinkerArgs m_args;
|
||||||
|
LinkerSearchPaths m_search_paths;
|
||||||
|
std::vector<std::unique_ptr<Zone>> m_loaded_zones;
|
||||||
|
|
||||||
|
bool IncludeAdditionalZoneDefinitions(const std::string& initialFileName, ZoneDefinition& zoneDefinition, ISearchPath* sourceSearchPath) const
|
||||||
{
|
{
|
||||||
auto& sourceSearchPath = paths.m_source_paths.GetSearchPaths();
|
std::set<std::string> sourceNames;
|
||||||
std::unique_ptr<ZoneDefinition> zoneDefinition;
|
sourceNames.emplace(initialFileName);
|
||||||
|
|
||||||
|
std::deque<std::string> toIncludeQueue;
|
||||||
|
for (const auto& include : zoneDefinition.m_includes)
|
||||||
|
toIncludeQueue.emplace_back(include);
|
||||||
|
|
||||||
|
while (!toIncludeQueue.empty())
|
||||||
{
|
{
|
||||||
const auto definitionFileName = std::format("{}.zone", targetName);
|
const auto& source = toIncludeQueue.front();
|
||||||
const auto definitionStream = sourceSearchPath.Open(definitionFileName);
|
|
||||||
if (!definitionStream.IsOpen())
|
if (sourceNames.find(source) == sourceNames.end())
|
||||||
{
|
{
|
||||||
if (logMissing)
|
sourceNames.emplace(source);
|
||||||
std::cerr << std::format("Could not find zone definition file for target \"{}\".\n", targetName);
|
|
||||||
return nullptr;
|
std::unique_ptr<ZoneDefinition> includeDefinition;
|
||||||
|
{
|
||||||
|
const auto definitionFileName = source + ".zone";
|
||||||
|
const auto definitionStream = sourceSearchPath->Open(definitionFileName);
|
||||||
|
if (!definitionStream.IsOpen())
|
||||||
|
{
|
||||||
|
std::cout << "Could not find zone definition file for project \"" << source << "\".\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream.m_stream, definitionFileName, m_args.m_verbose);
|
||||||
|
includeDefinition = zoneDefinitionInputStream.ReadDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!includeDefinition)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to read zone definition file for project \"" << source << "\".\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& include : includeDefinition->m_includes)
|
||||||
|
toIncludeQueue.emplace_back(include);
|
||||||
|
|
||||||
|
zoneDefinition.Include(*includeDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream.m_stream, targetName, definitionFileName, sourceSearchPath);
|
toIncludeQueue.pop_front();
|
||||||
zoneDefinition = zoneDefinitionInputStream.ReadDefinition();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!zoneDefinition)
|
return true;
|
||||||
{
|
|
||||||
std::cerr << std::format("Failed to read zone definition file for target \"{}\".\n", targetName);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return zoneDefinition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadIgnoreEntries(LinkerPathManager& paths, const std::string& zoneName, const GameId game, AssetList& assetList) const
|
bool ReadAssetList(const std::string& zoneName, AssetList& assetList, ISearchPath* sourceSearchPath) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
AssetListReader assetListReader(paths.m_source_paths.GetSearchPaths(), game);
|
const auto assetListFileName = "assetlist/" + zoneName + ".csv";
|
||||||
const auto maybeReadAssetList = assetListReader.ReadAssetList(zoneName, false);
|
const auto assetListStream = sourceSearchPath->Open(assetListFileName);
|
||||||
if (maybeReadAssetList)
|
|
||||||
{
|
|
||||||
assetList.m_entries.reserve(assetList.m_entries.size() + maybeReadAssetList->m_entries.size());
|
|
||||||
for (auto& entry : maybeReadAssetList->m_entries)
|
|
||||||
assetList.m_entries.emplace_back(std::move(entry));
|
|
||||||
|
|
||||||
|
if (assetListStream.IsOpen())
|
||||||
|
{
|
||||||
|
const AssetListInputStream stream(*assetListStream.m_stream);
|
||||||
|
AssetListEntry entry;
|
||||||
|
|
||||||
|
while (stream.NextEntry(entry))
|
||||||
|
{
|
||||||
|
assetList.m_entries.emplace_back(std::move(entry));
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto zoneDefinition = ReadZoneDefinition(paths, zoneName, false);
|
const auto zoneDefinition = ReadZoneDefinition(zoneName, sourceSearchPath);
|
||||||
|
|
||||||
if (zoneDefinition)
|
if (zoneDefinition)
|
||||||
{
|
{
|
||||||
assetList.m_entries.reserve(assetList.m_entries.size() + zoneDefinition->m_assets.size());
|
|
||||||
for (const auto& entry : zoneDefinition->m_assets)
|
for (const auto& entry : zoneDefinition->m_assets)
|
||||||
|
{
|
||||||
assetList.m_entries.emplace_back(entry.m_asset_type, entry.m_asset_name, entry.m_is_reference);
|
assetList.m_entries.emplace_back(entry.m_asset_type, entry.m_asset_name, entry.m_is_reference);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,33 +151,203 @@ class LinkerImpl final : public Linker
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProcessZoneDefinitionIgnores(LinkerPathManager& paths, const std::string& targetName, ZoneCreationContext& context) const
|
bool IncludeAssetLists(ZoneDefinition& zoneDefinition, ISearchPath* sourceSearchPath) const
|
||||||
|
{
|
||||||
|
for (const auto& assetListName : zoneDefinition.m_asset_lists)
|
||||||
|
{
|
||||||
|
AssetList assetList;
|
||||||
|
if (!ReadAssetList(assetListName, assetList, sourceSearchPath))
|
||||||
|
{
|
||||||
|
std::cerr << "Failed to read asset list \"" << assetListName << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
zoneDefinition.Include(assetList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool GetNameFromZoneDefinition(std::string& name, const std::string& targetName, const ZoneDefinition& zoneDefinition)
|
||||||
|
{
|
||||||
|
auto firstNameEntry = true;
|
||||||
|
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_NAME);
|
||||||
|
for (auto i = rangeBegin; i != rangeEnd; ++i)
|
||||||
|
{
|
||||||
|
if (firstNameEntry)
|
||||||
|
{
|
||||||
|
name = i->second->m_value;
|
||||||
|
firstNameEntry = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (name != i->second->m_value)
|
||||||
|
{
|
||||||
|
std::cout << "Conflicting names in target \"" << targetName << "\": " << name << " != " << i->second << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstNameEntry)
|
||||||
|
name = targetName;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ZoneDefinition> ReadZoneDefinition(const std::string& targetName, ISearchPath* sourceSearchPath) const
|
||||||
|
{
|
||||||
|
std::unique_ptr<ZoneDefinition> zoneDefinition;
|
||||||
|
{
|
||||||
|
const auto definitionFileName = targetName + ".zone";
|
||||||
|
const auto definitionStream = sourceSearchPath->Open(definitionFileName);
|
||||||
|
if (!definitionStream.IsOpen())
|
||||||
|
{
|
||||||
|
std::cout << "Could not find zone definition file for target \"" << targetName << "\".\n";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneDefinitionInputStream zoneDefinitionInputStream(*definitionStream.m_stream, definitionFileName, m_args.m_verbose);
|
||||||
|
zoneDefinition = zoneDefinitionInputStream.ReadDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!zoneDefinition)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to read zone definition file for target \"" << targetName << "\".\n";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetNameFromZoneDefinition(zoneDefinition->m_name, targetName, *zoneDefinition))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (!IncludeAdditionalZoneDefinitions(targetName, *zoneDefinition, sourceSearchPath))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (!IncludeAssetLists(*zoneDefinition, sourceSearchPath))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return zoneDefinition;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessZoneDefinitionIgnores(const std::string& targetName, ZoneCreationContext& context, ISearchPath* sourceSearchPath) const
|
||||||
{
|
{
|
||||||
if (context.m_definition->m_ignores.empty())
|
if (context.m_definition->m_ignores.empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
std::map<std::string, std::reference_wrapper<ZoneDefinitionEntry>> zoneDefinitionAssetsByName;
|
||||||
|
for (auto& entry : context.m_definition->m_assets)
|
||||||
|
{
|
||||||
|
zoneDefinitionAssetsByName.try_emplace(entry.m_asset_name, entry);
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& ignore : context.m_definition->m_ignores)
|
for (const auto& ignore : context.m_definition->m_ignores)
|
||||||
{
|
{
|
||||||
if (ignore == targetName)
|
if (ignore == targetName)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!ReadIgnoreEntries(paths, ignore, context.m_definition->m_game, context.m_ignored_assets))
|
std::vector<AssetListEntry> assetList;
|
||||||
|
if (!ReadAssetList(ignore, context.m_ignored_assets, sourceSearchPath))
|
||||||
{
|
{
|
||||||
std::cerr << std::format("Failed to read asset listing for ignoring assets of project \"{}\".\n", ignore);
|
std::cout << "Failed to read asset listing for ignoring assets of project \"" << ignore << "\".\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ProjectTypeByName(ProjectType& projectType, const std::string& projectTypeName)
|
||||||
|
{
|
||||||
|
for (auto i = 0u; i < static_cast<unsigned>(ProjectType::MAX); i++)
|
||||||
|
{
|
||||||
|
if (projectTypeName == PROJECT_TYPE_NAMES[i])
|
||||||
|
{
|
||||||
|
projectType = static_cast<ProjectType>(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool GetProjectTypeFromZoneDefinition(ProjectType& projectType, const std::string& targetName, const ZoneDefinition& zoneDefinition)
|
||||||
|
{
|
||||||
|
auto firstTypeEntry = true;
|
||||||
|
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_TYPE);
|
||||||
|
for (auto i = rangeBegin; i != rangeEnd; ++i)
|
||||||
|
{
|
||||||
|
ProjectType parsedProjectType;
|
||||||
|
if (!ProjectTypeByName(parsedProjectType, i->second->m_value))
|
||||||
|
{
|
||||||
|
std::cerr << "Not a valid project type: \"" << i->second->m_value << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstTypeEntry)
|
||||||
|
{
|
||||||
|
projectType = parsedProjectType;
|
||||||
|
firstTypeEntry = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (projectType != parsedProjectType)
|
||||||
|
{
|
||||||
|
std::cerr << "Conflicting types in target \"" << targetName << "\": " << PROJECT_TYPE_NAMES[static_cast<unsigned>(projectType)]
|
||||||
|
<< " != " << PROJECT_TYPE_NAMES[static_cast<unsigned>(parsedProjectType)] << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstTypeEntry)
|
||||||
|
{
|
||||||
|
if (zoneDefinition.m_assets.empty())
|
||||||
|
projectType = ProjectType::NONE;
|
||||||
|
else
|
||||||
|
projectType = ProjectType::FASTFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool GetGameNameFromZoneDefinition(std::string& gameName, const std::string& targetName, const ZoneDefinition& zoneDefinition)
|
||||||
|
{
|
||||||
|
auto firstGameEntry = true;
|
||||||
|
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_GAME);
|
||||||
|
for (auto i = rangeBegin; i != rangeEnd; ++i)
|
||||||
|
{
|
||||||
|
if (firstGameEntry)
|
||||||
|
{
|
||||||
|
gameName = i->second->m_value;
|
||||||
|
firstGameEntry = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (gameName != i->second->m_value)
|
||||||
|
{
|
||||||
|
std::cout << "Conflicting game names in target \"" << targetName << "\": " << gameName << " != " << i->second << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstGameEntry)
|
||||||
|
{
|
||||||
|
std::cout << "No game name was specified for target \"" << targetName << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool LoadGdtFilesFromZoneDefinition(std::vector<std::unique_ptr<Gdt>>& gdtList, const ZoneDefinition& zoneDefinition, ISearchPath* gdtSearchPath)
|
static bool LoadGdtFilesFromZoneDefinition(std::vector<std::unique_ptr<Gdt>>& gdtList, const ZoneDefinition& zoneDefinition, ISearchPath* gdtSearchPath)
|
||||||
{
|
{
|
||||||
for (const auto& gdtName : zoneDefinition.m_gdts)
|
const auto [rangeBegin, rangeEnd] = zoneDefinition.m_metadata_lookup.equal_range(METADATA_GDT);
|
||||||
|
for (auto i = rangeBegin; i != rangeEnd; ++i)
|
||||||
{
|
{
|
||||||
const auto gdtFile = gdtSearchPath->Open(std::format("{}.gdt", gdtName));
|
const auto gdtFile = gdtSearchPath->Open(i->second->m_value + ".gdt");
|
||||||
if (!gdtFile.IsOpen())
|
if (!gdtFile.IsOpen())
|
||||||
{
|
{
|
||||||
std::cerr << std::format("Failed to open file for gdt \"{}\"\n", gdtName);
|
std::cout << "Failed to open file for gdt \"" << i->second->m_value << "\"\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +355,7 @@ class LinkerImpl final : public Linker
|
|||||||
auto gdt = std::make_unique<Gdt>();
|
auto gdt = std::make_unique<Gdt>();
|
||||||
if (!gdtReader.Read(*gdt))
|
if (!gdtReader.Read(*gdt))
|
||||||
{
|
{
|
||||||
std::cerr << std::format("Failed to read gdt file \"{}\"\n", gdtName);
|
std::cout << "Failed to read gdt file \"" << i->second << "\"\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,95 +365,167 @@ class LinkerImpl final : public Linker
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Zone> CreateZoneForDefinition(
|
std::unique_ptr<Zone> CreateZoneForDefinition(const std::string& targetName,
|
||||||
LinkerPathManager& paths, const fs::path& outDir, const fs::path& cacheDir, const std::string& targetName, ZoneDefinition& zoneDefinition) const
|
ZoneDefinition& zoneDefinition,
|
||||||
|
ISearchPath* assetSearchPath,
|
||||||
|
ISearchPath* gdtSearchPath,
|
||||||
|
ISearchPath* sourceSearchPath) const
|
||||||
{
|
{
|
||||||
ZoneCreationContext context(&zoneDefinition, &paths.m_asset_paths.GetSearchPaths(), outDir, cacheDir);
|
const auto context = std::make_unique<ZoneCreationContext>(assetSearchPath, &zoneDefinition);
|
||||||
if (!ProcessZoneDefinitionIgnores(paths, targetName, context))
|
if (!ProcessZoneDefinitionIgnores(targetName, *context, sourceSearchPath))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!LoadGdtFilesFromZoneDefinition(context.m_gdt_files, zoneDefinition, &paths.m_gdt_paths.GetSearchPaths()))
|
if (!GetGameNameFromZoneDefinition(context->m_game_name, targetName, zoneDefinition))
|
||||||
|
return nullptr;
|
||||||
|
if (!LoadGdtFilesFromZoneDefinition(context->m_gdt_files, zoneDefinition, gdtSearchPath))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return zone_creator::CreateZoneForDefinition(zoneDefinition.m_game, context);
|
for (const auto* assetLoader : ZONE_CREATORS)
|
||||||
|
{
|
||||||
|
if (assetLoader->SupportsGame(context->m_game_name))
|
||||||
|
return assetLoader->CreateZoneForDefinition(*context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool WriteZoneToFile(IOutputPath& outPath, const Zone& zone)
|
bool WriteZoneToFile(const std::string& projectName, Zone* zone) const
|
||||||
{
|
{
|
||||||
const auto stream = outPath.Open(std::format("{}.ff", zone.m_name));
|
const fs::path zoneFolderPath(m_args.GetOutputFolderPathForProject(projectName));
|
||||||
if (!stream)
|
auto zoneFilePath(zoneFolderPath);
|
||||||
|
zoneFilePath.append(zone->m_name + ".ff");
|
||||||
|
|
||||||
|
fs::create_directories(zoneFolderPath);
|
||||||
|
|
||||||
|
std::ofstream stream(zoneFilePath, std::fstream::out | std::fstream::binary);
|
||||||
|
if (!stream.is_open())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!ZoneWriting::WriteZone(stream, zone))
|
||||||
{
|
{
|
||||||
std::cerr << std::format("Failed to open file for zone: {}\n", zone.m_name);
|
std::cout << "Writing zone failed.\n";
|
||||||
|
stream.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::format("Building zone \"{}\"\n", zone.m_name);
|
std::cout << "Created zone \"" << zoneFilePath.string() << "\"\n";
|
||||||
|
|
||||||
if (!ZoneWriting::WriteZone(*stream, zone))
|
|
||||||
{
|
|
||||||
std::cerr << "Writing zone failed.\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << std::format("Created zone \"{}\"\n", zone.m_name);
|
|
||||||
|
|
||||||
|
stream.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildFastFile(LinkerPathManager& paths, const std::string& projectName, const std::string& targetName, ZoneDefinition& zoneDefinition) const
|
bool BuildFastFile(const std::string& projectName,
|
||||||
|
const std::string& targetName,
|
||||||
|
ZoneDefinition& zoneDefinition,
|
||||||
|
SearchPaths& assetSearchPaths,
|
||||||
|
SearchPaths& gdtSearchPaths,
|
||||||
|
SearchPaths& sourceSearchPaths) const
|
||||||
{
|
{
|
||||||
const fs::path outDir(paths.m_linker_paths->BuildOutputFolderPath(projectName, zoneDefinition.m_game));
|
SoundBankWriter::OutputPath = fs::path(m_args.GetOutputFolderPathForProject(projectName));
|
||||||
|
|
||||||
OutputPathFilesystem outputPath(outDir);
|
const auto zone = CreateZoneForDefinition(targetName, zoneDefinition, &assetSearchPaths, &gdtSearchPaths, &sourceSearchPaths);
|
||||||
|
|
||||||
const fs::path cacheDir(paths.m_linker_paths->BuildCacheFolderPath(projectName, zoneDefinition.m_game));
|
|
||||||
SoundBankWriter::OutputPath = outDir;
|
|
||||||
|
|
||||||
const auto zone = CreateZoneForDefinition(paths, outDir, cacheDir, targetName, zoneDefinition);
|
|
||||||
auto result = zone != nullptr;
|
auto result = zone != nullptr;
|
||||||
if (zone)
|
if (zone)
|
||||||
result = WriteZoneToFile(outputPath, *zone);
|
result = WriteZoneToFile(projectName, zone.get());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BuildProject(LinkerPathManager& paths, const std::string& projectName, const std::string& targetName) const
|
bool BuildIPak(const std::string& projectName, const ZoneDefinition& zoneDefinition, SearchPaths& assetSearchPaths) const
|
||||||
{
|
{
|
||||||
std::deque<std::string> targetsToBuild;
|
const fs::path ipakFolderPath(m_args.GetOutputFolderPathForProject(projectName));
|
||||||
std::unordered_set<std::string> alreadyBuiltTargets;
|
auto ipakFilePath(ipakFolderPath);
|
||||||
|
ipakFilePath.append(zoneDefinition.m_name + ".ipak");
|
||||||
|
|
||||||
targetsToBuild.emplace_back(targetName);
|
fs::create_directories(ipakFolderPath);
|
||||||
|
|
||||||
while (!targetsToBuild.empty())
|
std::ofstream stream(ipakFilePath, std::fstream::out | std::fstream::binary);
|
||||||
|
if (!stream.is_open())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto ipakWriter = IPakWriter::Create(stream, &assetSearchPaths);
|
||||||
|
for (const auto& assetEntry : zoneDefinition.m_assets)
|
||||||
{
|
{
|
||||||
const auto currentTarget = std::move(targetsToBuild.front());
|
if (assetEntry.m_is_reference)
|
||||||
targetsToBuild.pop_front();
|
continue;
|
||||||
alreadyBuiltTargets.emplace(currentTarget);
|
|
||||||
|
|
||||||
PathProjectContext projectContext(paths, projectName);
|
if (assetEntry.m_asset_type == "image")
|
||||||
|
ipakWriter->AddImage(assetEntry.m_asset_name);
|
||||||
|
}
|
||||||
|
|
||||||
const auto zoneDefinition = ReadZoneDefinition(paths, targetName);
|
if (!ipakWriter->Write())
|
||||||
if (!zoneDefinition)
|
{
|
||||||
|
std::cout << "Writing ipak failed.\n";
|
||||||
|
stream.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Created ipak \"" << ipakFilePath.string() << "\"\n";
|
||||||
|
|
||||||
|
stream.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BuildReferencedTargets(const std::string& projectName, const std::string& targetName, const ZoneDefinition& zoneDefinition)
|
||||||
|
{
|
||||||
|
return std::ranges::all_of(zoneDefinition.m_targets_to_build,
|
||||||
|
[this, &projectName, &targetName](const std::string& buildTargetName)
|
||||||
|
{
|
||||||
|
if (buildTargetName == targetName)
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot build target with same name: \"" << targetName << "\"\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Building referenced target \"" << buildTargetName << "\"\n";
|
||||||
|
return BuildProject(projectName, buildTargetName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BuildProject(const std::string& projectName, const std::string& targetName)
|
||||||
|
{
|
||||||
|
auto sourceSearchPaths = m_search_paths.GetSourceSearchPathsForProject(projectName);
|
||||||
|
|
||||||
|
const auto zoneDefinition = ReadZoneDefinition(targetName, &sourceSearchPaths);
|
||||||
|
if (!zoneDefinition)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ProjectType projectType;
|
||||||
|
if (!GetProjectTypeFromZoneDefinition(projectType, targetName, *zoneDefinition))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto result = true;
|
||||||
|
if (projectType != ProjectType::NONE)
|
||||||
|
{
|
||||||
|
std::string gameName;
|
||||||
|
if (!GetGameNameFromZoneDefinition(gameName, targetName, *zoneDefinition))
|
||||||
return false;
|
return false;
|
||||||
|
utils::MakeStringLowerCase(gameName);
|
||||||
|
|
||||||
PathGameContext gameContext(paths, projectName, zoneDefinition->m_game);
|
auto assetSearchPaths = m_search_paths.GetAssetSearchPathsForProject(gameName, projectName);
|
||||||
|
auto gdtSearchPaths = m_search_paths.GetGdtSearchPathsForProject(gameName, projectName);
|
||||||
|
|
||||||
if (!zoneDefinition->m_assets.empty())
|
switch (projectType)
|
||||||
{
|
{
|
||||||
if (!BuildFastFile(paths, projectName, targetName, *zoneDefinition))
|
case ProjectType::FASTFILE:
|
||||||
return false;
|
result = BuildFastFile(projectName, targetName, *zoneDefinition, assetSearchPaths, gdtSearchPaths, sourceSearchPaths);
|
||||||
|
break;
|
||||||
|
|
||||||
for (const auto& referencedTarget : zoneDefinition->m_targets_to_build)
|
case ProjectType::IPAK:
|
||||||
{
|
result = BuildIPak(projectName, *zoneDefinition, assetSearchPaths);
|
||||||
if (alreadyBuiltTargets.find(referencedTarget) == alreadyBuiltTargets.end())
|
break;
|
||||||
{
|
|
||||||
targetsToBuild.emplace_back(referencedTarget);
|
default:
|
||||||
std::cout << std::format("Building referenced target \"{}\"\n", referencedTarget);
|
assert(false);
|
||||||
}
|
result = false;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
m_search_paths.UnloadProjectSpecificSearchPaths();
|
||||||
|
|
||||||
|
result = result && BuildReferencedTargets(projectName, targetName, *zoneDefinition);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadZones()
|
bool LoadZones()
|
||||||
@ -354,25 +534,22 @@ class LinkerImpl final : public Linker
|
|||||||
{
|
{
|
||||||
if (!fs::is_regular_file(zonePath))
|
if (!fs::is_regular_file(zonePath))
|
||||||
{
|
{
|
||||||
std::cerr << std::format("Could not find zone file to load \"{}\".\n", zonePath);
|
std::cout << "Could not find zone file to load \"" << zonePath << "\".\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto zoneDirectory = fs::path(zonePath).remove_filename();
|
auto absoluteZoneDirectory = absolute(std::filesystem::path(zonePath).remove_filename()).string();
|
||||||
if (zoneDirectory.empty())
|
|
||||||
zoneDirectory = fs::current_path();
|
|
||||||
auto absoluteZoneDirectory = absolute(zoneDirectory).string();
|
|
||||||
|
|
||||||
auto zone = ZoneLoading::LoadZone(zonePath);
|
auto zone = std::unique_ptr<Zone>(ZoneLoading::LoadZone(zonePath));
|
||||||
if (!zone)
|
if (zone == nullptr)
|
||||||
{
|
{
|
||||||
std::cerr << std::format("Failed to load zone \"{}\".\n", zonePath);
|
std::cout << "Failed to load zone \"" << zonePath << "\".\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_args.m_verbose)
|
if (m_args.m_verbose)
|
||||||
{
|
{
|
||||||
std::cout << std::format("Load zone \"{}\"\n", zone->m_name);
|
std::cout << "Load zone \"" << zone->m_name << "\"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
m_loaded_zones.emplace_back(std::move(zone));
|
m_loaded_zones.emplace_back(std::move(zone));
|
||||||
@ -391,7 +568,7 @@ class LinkerImpl final : public Linker
|
|||||||
loadedZone.reset();
|
loadedZone.reset();
|
||||||
|
|
||||||
if (m_args.m_verbose)
|
if (m_args.m_verbose)
|
||||||
std::cout << std::format("Unloaded zone \"{}\"\n", zoneName);
|
std::cout << "Unloaded zone \"" << zoneName << "\"\n";
|
||||||
}
|
}
|
||||||
m_loaded_zones.clear();
|
m_loaded_zones.clear();
|
||||||
}
|
}
|
||||||
@ -406,7 +583,7 @@ class LinkerImpl final : public Linker
|
|||||||
}
|
}
|
||||||
else if (projectSpecifier.find_first_of('/', targetNameSeparatorIndex + 1) != std::string::npos)
|
else if (projectSpecifier.find_first_of('/', targetNameSeparatorIndex + 1) != std::string::npos)
|
||||||
{
|
{
|
||||||
std::cerr << std::format("Project specifier cannot have more than one target name: \"{}\"\n", projectSpecifier);
|
std::cerr << "Project specifier cannot have more than one target name: \"" << projectSpecifier << "\"\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -417,13 +594,13 @@ class LinkerImpl final : public Linker
|
|||||||
|
|
||||||
if (projectName.empty())
|
if (projectName.empty())
|
||||||
{
|
{
|
||||||
std::cerr << std::format("Project name cannot be empty: \"{}\"\n", projectSpecifier);
|
std::cerr << "Project name cannot be empty: \"" << projectSpecifier << "\"\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetName.empty())
|
if (targetName.empty())
|
||||||
{
|
{
|
||||||
std::cerr << std::format("Target name cannot be empty: \"{}\"\n", projectSpecifier);
|
std::cerr << "Target name cannot be empty: \"" << projectSpecifier << "\"\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,6 +608,11 @@ class LinkerImpl final : public Linker
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
LinkerImpl()
|
||||||
|
: m_search_paths(m_args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool Start(const int argc, const char** argv) override
|
bool Start(const int argc, const char** argv) override
|
||||||
{
|
{
|
||||||
auto shouldContinue = true;
|
auto shouldContinue = true;
|
||||||
@ -440,7 +622,8 @@ public:
|
|||||||
if (!shouldContinue)
|
if (!shouldContinue)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
LinkerPathManager paths(m_args);
|
if (!m_search_paths.BuildProjectIndependentSearchPaths())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!LoadZones())
|
if (!LoadZones())
|
||||||
return false;
|
return false;
|
||||||
@ -456,7 +639,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BuildProject(paths, projectName, targetName))
|
if (!BuildProject(projectName, targetName))
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
@ -467,10 +650,6 @@ public:
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
LinkerArgs m_args;
|
|
||||||
std::vector<std::unique_ptr<Zone>> m_loaded_zones;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<Linker> Linker::Create()
|
std::unique_ptr<Linker> Linker::Create()
|
||||||
|
@ -5,11 +5,10 @@
|
|||||||
#include "ObjWriting.h"
|
#include "ObjWriting.h"
|
||||||
#include "Utils/Arguments/UsageInformation.h"
|
#include "Utils/Arguments/UsageInformation.h"
|
||||||
#include "Utils/FileUtils.h"
|
#include "Utils/FileUtils.h"
|
||||||
#include "Utils/PathUtils.h"
|
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <format>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <regex>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
@ -46,44 +45,28 @@ const CommandLineOption* const OPTION_BASE_FOLDER =
|
|||||||
const CommandLineOption* const OPTION_OUTPUT_FOLDER =
|
const CommandLineOption* const OPTION_OUTPUT_FOLDER =
|
||||||
CommandLineOption::Builder::Create()
|
CommandLineOption::Builder::Create()
|
||||||
.WithLongName("output-folder")
|
.WithLongName("output-folder")
|
||||||
.WithDescription(std::format("Specifies the output folder containing the build artifacts. Defaults to \"{}\".", LinkerArgs::DEFAULT_OUTPUT_FOLDER))
|
.WithDescription("Specifies the output folder containing the build artifacts. Defaults to \"" + std::string(LinkerArgs::DEFAULT_OUTPUT_FOLDER) + "\".")
|
||||||
.WithParameter("outputFolderPath")
|
.WithParameter("outputFolderPath")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_ADD_ASSET_SEARCH_PATH =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithLongName("add-asset-search-path")
|
|
||||||
.WithDescription("Adds a search paths used for assets. This does not override the default search paths.")
|
|
||||||
.WithParameter("assetSearchPathString")
|
|
||||||
.Reusable()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_ASSET_SEARCH_PATH =
|
const CommandLineOption* const OPTION_ASSET_SEARCH_PATH =
|
||||||
CommandLineOption::Builder::Create()
|
CommandLineOption::Builder::Create()
|
||||||
.WithLongName("asset-search-path")
|
.WithLongName("asset-search-path")
|
||||||
.WithDescription(std::format("Specifies the search paths used for assets. Defaults to \"{}\".", LinkerArgs::DEFAULT_ASSET_SEARCH_PATH))
|
.WithDescription("Specifies the search paths used for assets. Defaults to \"" + std::string(LinkerArgs::DEFAULT_ASSET_SEARCH_PATH) + "\".")
|
||||||
.WithParameter("assetSearchPathString")
|
.WithParameter("assetSearchPathString")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_GDT_SEARCH_PATH =
|
const CommandLineOption* const OPTION_GDT_SEARCH_PATH =
|
||||||
CommandLineOption::Builder::Create()
|
CommandLineOption::Builder::Create()
|
||||||
.WithLongName("gdt-search-path")
|
.WithLongName("gdt-search-path")
|
||||||
.WithDescription(std::format("Specifies the search paths used for gdt files. Defaults to \"{}\".", LinkerArgs::DEFAULT_GDT_SEARCH_PATH))
|
.WithDescription("Specifies the search paths used for assets. Defaults to \"" + std::string(LinkerArgs::DEFAULT_GDT_SEARCH_PATH) + "\".")
|
||||||
.WithParameter("gdtSearchPathString")
|
.WithParameter("gdtSearchPathString")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_ADD_SOURCE_SEARCH_PATH =
|
|
||||||
CommandLineOption::Builder::Create()
|
|
||||||
.WithLongName("add-source-search-path")
|
|
||||||
.WithDescription("Adds a search paths used for source files. This does not override the default search paths.")
|
|
||||||
.WithParameter("sourceSearchPathString")
|
|
||||||
.Reusable()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const CommandLineOption* const OPTION_SOURCE_SEARCH_PATH =
|
const CommandLineOption* const OPTION_SOURCE_SEARCH_PATH =
|
||||||
CommandLineOption::Builder::Create()
|
CommandLineOption::Builder::Create()
|
||||||
.WithLongName("source-search-path")
|
.WithLongName("source-search-path")
|
||||||
.WithDescription(std::format("Specifies the search paths used for source files. Defaults to \"{}\".", LinkerArgs::DEFAULT_SOURCE_SEARCH_PATH))
|
.WithDescription("Specifies the search paths used for assets. Defaults to \"" + std::string(LinkerArgs::DEFAULT_SOURCE_SEARCH_PATH) + "\".")
|
||||||
.WithParameter("sourceSearchPathString")
|
.WithParameter("sourceSearchPathString")
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
@ -117,10 +100,8 @@ const CommandLineOption* const COMMAND_LINE_OPTIONS[]{
|
|||||||
OPTION_VERBOSE,
|
OPTION_VERBOSE,
|
||||||
OPTION_BASE_FOLDER,
|
OPTION_BASE_FOLDER,
|
||||||
OPTION_OUTPUT_FOLDER,
|
OPTION_OUTPUT_FOLDER,
|
||||||
OPTION_ADD_ASSET_SEARCH_PATH,
|
|
||||||
OPTION_ASSET_SEARCH_PATH,
|
OPTION_ASSET_SEARCH_PATH,
|
||||||
OPTION_GDT_SEARCH_PATH,
|
OPTION_GDT_SEARCH_PATH,
|
||||||
OPTION_ADD_SOURCE_SEARCH_PATH,
|
|
||||||
OPTION_SOURCE_SEARCH_PATH,
|
OPTION_SOURCE_SEARCH_PATH,
|
||||||
OPTION_LOAD,
|
OPTION_LOAD,
|
||||||
OPTION_MENU_PERMISSIVE,
|
OPTION_MENU_PERMISSIVE,
|
||||||
@ -128,14 +109,19 @@ const CommandLineOption* const COMMAND_LINE_OPTIONS[]{
|
|||||||
};
|
};
|
||||||
|
|
||||||
LinkerArgs::LinkerArgs()
|
LinkerArgs::LinkerArgs()
|
||||||
: m_verbose(false),
|
: m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v<decltype(COMMAND_LINE_OPTIONS)>),
|
||||||
m_argument_parser(COMMAND_LINE_OPTIONS, std::extent_v<decltype(COMMAND_LINE_OPTIONS)>)
|
m_base_pattern(R"(\?base\?)"),
|
||||||
|
m_game_pattern(R"(\?game\?)"),
|
||||||
|
m_project_pattern(R"(\?project\?)"),
|
||||||
|
m_base_folder_depends_on_project(false),
|
||||||
|
m_out_folder_depends_on_project(false),
|
||||||
|
m_verbose(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkerArgs::PrintUsage() const
|
void LinkerArgs::PrintUsage()
|
||||||
{
|
{
|
||||||
UsageInformation usage(m_argument_parser.GetExecutableName());
|
UsageInformation usage("Linker.exe");
|
||||||
|
|
||||||
for (const auto* commandLineOption : COMMAND_LINE_OPTIONS)
|
for (const auto* commandLineOption : COMMAND_LINE_OPTIONS)
|
||||||
{
|
{
|
||||||
@ -150,13 +136,7 @@ void LinkerArgs::PrintUsage() const
|
|||||||
|
|
||||||
void LinkerArgs::PrintVersion()
|
void LinkerArgs::PrintVersion()
|
||||||
{
|
{
|
||||||
std::cout << std::format("OpenAssetTools Linker {}\n", GIT_VERSION);
|
std::cout << "OpenAssetTools Linker " << std::string(GIT_VERSION) << "\n";
|
||||||
}
|
|
||||||
|
|
||||||
void LinkerArgs::SetBinFolder()
|
|
||||||
{
|
|
||||||
const fs::path path(utils::GetExecutablePath());
|
|
||||||
m_bin_folder = path.parent_path().string();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkerArgs::SetVerbose(const bool isVerbose)
|
void LinkerArgs::SetVerbose(const bool isVerbose)
|
||||||
@ -166,10 +146,76 @@ void LinkerArgs::SetVerbose(const bool isVerbose)
|
|||||||
ObjWriting::Configuration.Verbose = isVerbose;
|
ObjWriting::Configuration.Verbose = isVerbose;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string LinkerArgs::GetBasePathForProject(const std::string& projectName) const
|
||||||
|
{
|
||||||
|
return std::regex_replace(m_base_folder, m_project_pattern, projectName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinkerArgs::SetDefaultBasePath()
|
||||||
|
{
|
||||||
|
const auto currentDir = fs::absolute(fs::current_path());
|
||||||
|
|
||||||
|
if (currentDir.filename() == "bin")
|
||||||
|
{
|
||||||
|
m_base_folder = currentDir.parent_path().string();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_base_folder = currentDir.string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> LinkerArgs::GetProjectIndependentSearchPaths(const std::set<std::string>& set) const
|
||||||
|
{
|
||||||
|
std::set<std::string> out;
|
||||||
|
|
||||||
|
for (const auto& path : set)
|
||||||
|
{
|
||||||
|
if (path.find(PATTERN_GAME) != std::string::npos)
|
||||||
|
continue;
|
||||||
|
if (path.find(PATTERN_PROJECT) != std::string::npos)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (path.find(PATTERN_BASE) != std::string::npos)
|
||||||
|
{
|
||||||
|
if (m_base_folder_depends_on_project)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
out.emplace(std::regex_replace(path, m_base_pattern, m_base_folder));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.emplace(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> LinkerArgs::GetSearchPathsForProject(const std::set<std::string>& set, const std::string& gameName, const std::string& projectName) const
|
||||||
|
{
|
||||||
|
std::set<std::string> out;
|
||||||
|
const auto basePath = GetBasePathForProject(projectName);
|
||||||
|
|
||||||
|
for (const auto& path : set)
|
||||||
|
{
|
||||||
|
if (path.find(PATTERN_GAME) == std::string::npos && path.find(PATTERN_PROJECT) == std::string::npos
|
||||||
|
&& (!m_base_folder_depends_on_project || path.find(PATTERN_BASE) == std::string::npos))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.emplace(std::regex_replace(
|
||||||
|
std::regex_replace(std::regex_replace(path, m_project_pattern, projectName), m_game_pattern, gameName), m_base_pattern, basePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
bool LinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldContinue)
|
bool LinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldContinue)
|
||||||
{
|
{
|
||||||
shouldContinue = true;
|
shouldContinue = true;
|
||||||
if (!m_argument_parser.ParseArguments(argc, argv))
|
if (!m_argument_parser.ParseArguments(argc - 1, &argv[1]))
|
||||||
{
|
{
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
return false;
|
return false;
|
||||||
@ -191,8 +237,6 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldContin
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetBinFolder();
|
|
||||||
|
|
||||||
m_project_specifiers_to_build = m_argument_parser.GetArguments();
|
m_project_specifiers_to_build = m_argument_parser.GetArguments();
|
||||||
if (m_project_specifiers_to_build.empty())
|
if (m_project_specifiers_to_build.empty())
|
||||||
{
|
{
|
||||||
@ -208,13 +252,15 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldContin
|
|||||||
if (m_argument_parser.IsOptionSpecified(OPTION_BASE_FOLDER))
|
if (m_argument_parser.IsOptionSpecified(OPTION_BASE_FOLDER))
|
||||||
m_base_folder = m_argument_parser.GetValueForOption(OPTION_BASE_FOLDER);
|
m_base_folder = m_argument_parser.GetValueForOption(OPTION_BASE_FOLDER);
|
||||||
else
|
else
|
||||||
m_base_folder = DEFAULT_BASE_FOLDER;
|
SetDefaultBasePath();
|
||||||
|
m_base_folder_depends_on_project = m_base_folder.find(PATTERN_GAME) != std::string::npos || m_base_folder.find(PATTERN_PROJECT) != std::string::npos;
|
||||||
|
|
||||||
// --output-folder
|
// --output-folder
|
||||||
if (m_argument_parser.IsOptionSpecified(OPTION_OUTPUT_FOLDER))
|
if (m_argument_parser.IsOptionSpecified(OPTION_OUTPUT_FOLDER))
|
||||||
m_out_folder = m_argument_parser.GetValueForOption(OPTION_OUTPUT_FOLDER);
|
m_out_folder = m_argument_parser.GetValueForOption(OPTION_OUTPUT_FOLDER);
|
||||||
else
|
else
|
||||||
m_out_folder = DEFAULT_OUTPUT_FOLDER;
|
m_out_folder = DEFAULT_OUTPUT_FOLDER;
|
||||||
|
m_out_folder_depends_on_project = m_out_folder.find(PATTERN_PROJECT) != std::string::npos;
|
||||||
|
|
||||||
// --asset-search-path
|
// --asset-search-path
|
||||||
if (m_argument_parser.IsOptionSpecified(OPTION_ASSET_SEARCH_PATH))
|
if (m_argument_parser.IsOptionSpecified(OPTION_ASSET_SEARCH_PATH))
|
||||||
@ -228,13 +274,6 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldContin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --add-assets-search-path
|
|
||||||
for (const auto& specifiedValue : m_argument_parser.GetParametersForOption(OPTION_ADD_ASSET_SEARCH_PATH))
|
|
||||||
{
|
|
||||||
if (!FileUtils::ParsePathsString(specifiedValue, m_asset_search_paths))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --gdt-search-path
|
// --gdt-search-path
|
||||||
if (m_argument_parser.IsOptionSpecified(OPTION_GDT_SEARCH_PATH))
|
if (m_argument_parser.IsOptionSpecified(OPTION_GDT_SEARCH_PATH))
|
||||||
{
|
{
|
||||||
@ -259,13 +298,6 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldContin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --add-source-search-path
|
|
||||||
for (const auto& specifiedValue : m_argument_parser.GetParametersForOption(OPTION_ADD_SOURCE_SEARCH_PATH))
|
|
||||||
{
|
|
||||||
if (!FileUtils::ParsePathsString(specifiedValue, m_source_search_paths))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -l; --load
|
// -l; --load
|
||||||
if (m_argument_parser.IsOptionSpecified(OPTION_LOAD))
|
if (m_argument_parser.IsOptionSpecified(OPTION_LOAD))
|
||||||
m_zones_to_load = m_argument_parser.GetParametersForOption(OPTION_LOAD);
|
m_zones_to_load = m_argument_parser.GetParametersForOption(OPTION_LOAD);
|
||||||
@ -280,3 +312,38 @@ bool LinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldContin
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string LinkerArgs::GetOutputFolderPathForProject(const std::string& projectName) const
|
||||||
|
{
|
||||||
|
return std::regex_replace(std::regex_replace(m_out_folder, m_project_pattern, projectName), m_base_pattern, GetBasePathForProject(projectName));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> LinkerArgs::GetProjectIndependentAssetSearchPaths() const
|
||||||
|
{
|
||||||
|
return GetProjectIndependentSearchPaths(m_asset_search_paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> LinkerArgs::GetProjectIndependentGdtSearchPaths() const
|
||||||
|
{
|
||||||
|
return GetProjectIndependentSearchPaths(m_gdt_search_paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> LinkerArgs::GetProjectIndependentSourceSearchPaths() const
|
||||||
|
{
|
||||||
|
return GetProjectIndependentSearchPaths(m_source_search_paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> LinkerArgs::GetAssetSearchPathsForProject(const std::string& gameName, const std::string& projectName) const
|
||||||
|
{
|
||||||
|
return GetSearchPathsForProject(m_asset_search_paths, gameName, projectName);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> LinkerArgs::GetGdtSearchPathsForProject(const std::string& gameName, const std::string& projectName) const
|
||||||
|
{
|
||||||
|
return GetSearchPathsForProject(m_gdt_search_paths, gameName, projectName);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> LinkerArgs::GetSourceSearchPathsForProject(const std::string& projectName) const
|
||||||
|
{
|
||||||
|
return GetSearchPathsForProject(m_source_search_paths, "", projectName);
|
||||||
|
}
|
||||||
|
@ -1,44 +1,76 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Utils/Arguments/ArgumentParser.h"
|
#include "Utils/Arguments/ArgumentParser.h"
|
||||||
|
#include "Utils/ClassUtils.h"
|
||||||
|
#include "Zone/Zone.h"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class LinkerArgs
|
class LinkerArgs
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static constexpr auto DEFAULT_BASE_FOLDER = ".";
|
static constexpr const char* PATTERN_BASE = "?base?";
|
||||||
static constexpr auto DEFAULT_CACHE_FOLDER = "?base?/.oat/cache/?project?";
|
static constexpr const char* PATTERN_GAME = "?game?";
|
||||||
static constexpr auto DEFAULT_OUTPUT_FOLDER = "?base?/zone_out/?project?";
|
static constexpr const char* PATTERN_PROJECT = "?project?";
|
||||||
static constexpr auto DEFAULT_ASSET_SEARCH_PATH = "?bin?/raw/?game?;?base?/raw;?base?/raw/?game?;?base?/zone_raw/?project?";
|
|
||||||
static constexpr auto DEFAULT_GDT_SEARCH_PATH = "?base?/source_data;?base?/zone_raw/?project?/source_data";
|
|
||||||
static constexpr auto DEFAULT_SOURCE_SEARCH_PATH = "?base?/zone_source;?base?/zone_raw/?project?;?base?/zone_raw/?project?/zone_source";
|
|
||||||
|
|
||||||
LinkerArgs();
|
static constexpr const char* DEFAULT_BASE_FOLDER = ".";
|
||||||
bool ParseArgs(int argc, const char** argv, bool& shouldContinue);
|
static constexpr const char* DEFAULT_BASE_FOLDER_MOD_TOOLS = "..";
|
||||||
|
static constexpr const char* DEFAULT_OUTPUT_FOLDER = "?base?/zone_out/?project?";
|
||||||
|
static constexpr const char* DEFAULT_ASSET_SEARCH_PATH = "?base?/raw;?base?/raw/?game?;?base?/zone_raw/?project?";
|
||||||
|
static constexpr const char* DEFAULT_GDT_SEARCH_PATH = "?base?/source_data;?base?/zone_raw/?project?/source_data";
|
||||||
|
static constexpr const char* DEFAULT_SOURCE_SEARCH_PATH = "?base?/zone_source;?base?/zone_raw/?project?/zone_source";
|
||||||
|
|
||||||
bool m_verbose;
|
private:
|
||||||
|
ArgumentParser m_argument_parser;
|
||||||
|
std::regex m_base_pattern;
|
||||||
|
std::regex m_game_pattern;
|
||||||
|
std::regex m_project_pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Prints a command line usage help text for the Linker tool to stdout.
|
||||||
|
*/
|
||||||
|
static void PrintUsage();
|
||||||
|
static void PrintVersion();
|
||||||
|
|
||||||
|
void SetVerbose(bool isVerbose);
|
||||||
|
|
||||||
|
_NODISCARD std::string GetBasePathForProject(const std::string& projectName) const;
|
||||||
|
void SetDefaultBasePath();
|
||||||
|
_NODISCARD std::set<std::string> GetProjectIndependentSearchPaths(const std::set<std::string>& set) const;
|
||||||
|
_NODISCARD std::set<std::string>
|
||||||
|
GetSearchPathsForProject(const std::set<std::string>& set, const std::string& gameName, const std::string& projectName) const;
|
||||||
|
|
||||||
|
public:
|
||||||
std::vector<std::string> m_zones_to_load;
|
std::vector<std::string> m_zones_to_load;
|
||||||
std::vector<std::string> m_project_specifiers_to_build;
|
std::vector<std::string> m_project_specifiers_to_build;
|
||||||
|
|
||||||
std::string m_bin_folder;
|
|
||||||
std::string m_base_folder;
|
std::string m_base_folder;
|
||||||
std::string m_out_folder;
|
std::string m_out_folder;
|
||||||
|
bool m_base_folder_depends_on_project;
|
||||||
|
bool m_out_folder_depends_on_project;
|
||||||
|
|
||||||
std::set<std::string> m_asset_search_paths;
|
std::set<std::string> m_asset_search_paths;
|
||||||
std::set<std::string> m_gdt_search_paths;
|
std::set<std::string> m_gdt_search_paths;
|
||||||
std::set<std::string> m_source_search_paths;
|
std::set<std::string> m_source_search_paths;
|
||||||
|
|
||||||
private:
|
bool m_verbose;
|
||||||
|
|
||||||
|
LinkerArgs();
|
||||||
|
bool ParseArgs(int argc, const char** argv, bool& shouldContinue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Prints a command line usage help text for the Linker tool to stdout.
|
* \brief Converts the output path specified by command line arguments to a path applies for the specified project.
|
||||||
|
* \param projectName The name of the project to resolve the path input for.
|
||||||
|
* \return An output path for the project based on the user input.
|
||||||
*/
|
*/
|
||||||
void PrintUsage() const;
|
_NODISCARD std::string GetOutputFolderPathForProject(const std::string& projectName) const;
|
||||||
static void PrintVersion();
|
|
||||||
|
|
||||||
void SetBinFolder();
|
_NODISCARD std::set<std::string> GetProjectIndependentAssetSearchPaths() const;
|
||||||
void SetVerbose(bool isVerbose);
|
_NODISCARD std::set<std::string> GetProjectIndependentGdtSearchPaths() const;
|
||||||
|
_NODISCARD std::set<std::string> GetProjectIndependentSourceSearchPaths() const;
|
||||||
|
|
||||||
ArgumentParser m_argument_parser;
|
_NODISCARD std::set<std::string> GetAssetSearchPathsForProject(const std::string& gameName, const std::string& projectName) const;
|
||||||
|
_NODISCARD std::set<std::string> GetGdtSearchPathsForProject(const std::string& gameName, const std::string& projectName) const;
|
||||||
|
_NODISCARD std::set<std::string> GetSourceSearchPathsForProject(const std::string& projectName) const;
|
||||||
};
|
};
|
||||||
|
@ -1,342 +0,0 @@
|
|||||||
#include "LinkerPaths.h"
|
|
||||||
|
|
||||||
#include "SearchPath/IWD.h"
|
|
||||||
#include "SearchPath/SearchPathFilesystem.h"
|
|
||||||
#include "SearchPath/SearchPaths.h"
|
|
||||||
#include "Utils/StringUtils.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <format>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
enum class PathTemplateParameterType : std::uint8_t
|
|
||||||
{
|
|
||||||
BIN = 1 << 0,
|
|
||||||
BASE = 1 << 1,
|
|
||||||
PROJECT = 1 << 2,
|
|
||||||
GAME = 1 << 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
class LinkerPathTemplate
|
|
||||||
{
|
|
||||||
static constexpr auto PATTERN_BIN = "?bin?";
|
|
||||||
static constexpr auto PATTERN_BASE = "?base?";
|
|
||||||
static constexpr auto PATTERN_GAME = "?game?";
|
|
||||||
static constexpr auto PATTERN_PROJECT = "?project?";
|
|
||||||
|
|
||||||
struct Pattern
|
|
||||||
{
|
|
||||||
const char* m_str;
|
|
||||||
PathTemplateParameterType m_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr Pattern PATTERNS[]{
|
|
||||||
{PATTERN_BIN, PathTemplateParameterType::BIN },
|
|
||||||
{PATTERN_BASE, PathTemplateParameterType::BASE },
|
|
||||||
{PATTERN_GAME, PathTemplateParameterType::GAME },
|
|
||||||
{PATTERN_PROJECT, PathTemplateParameterType::PROJECT},
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
LinkerPathTemplate()
|
|
||||||
: m_parameter_type_flags(0u)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateFromString(const std::string& templateString)
|
|
||||||
{
|
|
||||||
const auto templateStringLength = templateString.size();
|
|
||||||
auto partStart = 0u;
|
|
||||||
for (auto i = 0u; i < templateStringLength; i++)
|
|
||||||
{
|
|
||||||
if (templateString[i] != '?')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (const auto& pattern : PATTERNS)
|
|
||||||
{
|
|
||||||
const auto patternLength = std::strlen(pattern.m_str);
|
|
||||||
if (templateString.compare(i, patternLength, pattern.m_str) == 0)
|
|
||||||
{
|
|
||||||
m_parts.emplace_back(templateString.substr(partStart, i - partStart));
|
|
||||||
m_parameters.emplace_back(pattern.m_type);
|
|
||||||
m_parameter_type_flags |= static_cast<std::underlying_type_t<PathTemplateParameterType>>(pattern.m_type);
|
|
||||||
i += patternLength;
|
|
||||||
|
|
||||||
partStart = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (partStart < templateStringLength)
|
|
||||||
m_parts.emplace_back(templateString.substr(partStart, templateStringLength - partStart));
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::string
|
|
||||||
Render(const std::string& binDir, const std::string& baseDir, const std::string& projectName, const std::string& gameName) const
|
|
||||||
{
|
|
||||||
if (m_parts.empty())
|
|
||||||
return "";
|
|
||||||
|
|
||||||
if (m_parameters.empty())
|
|
||||||
return m_parts[0];
|
|
||||||
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << m_parts[0];
|
|
||||||
|
|
||||||
const auto partsCount = m_parts.size();
|
|
||||||
const auto parameterCount = m_parameters.size();
|
|
||||||
for (auto parameterIndex = 0u; parameterIndex < parameterCount; parameterIndex++)
|
|
||||||
{
|
|
||||||
switch (m_parameters[parameterIndex])
|
|
||||||
{
|
|
||||||
case PathTemplateParameterType::BIN:
|
|
||||||
ss << binDir;
|
|
||||||
break;
|
|
||||||
case PathTemplateParameterType::BASE:
|
|
||||||
ss << baseDir;
|
|
||||||
break;
|
|
||||||
case PathTemplateParameterType::PROJECT:
|
|
||||||
ss << projectName;
|
|
||||||
break;
|
|
||||||
case PathTemplateParameterType::GAME:
|
|
||||||
ss << gameName;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameterIndex + 1 < partsCount)
|
|
||||||
ss << m_parts[parameterIndex + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return fs::path(ss.str()).make_preferred().string();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool CanRender(const std::underlying_type_t<PathTemplateParameterType> availableParameters) const
|
|
||||||
{
|
|
||||||
return (m_parameter_type_flags & ~availableParameters) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::string> m_parts;
|
|
||||||
std::vector<PathTemplateParameterType> m_parameters;
|
|
||||||
std::underlying_type_t<PathTemplateParameterType> m_parameter_type_flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LinkerSearchPathBuilder final : public ILinkerSearchPathBuilder
|
|
||||||
{
|
|
||||||
static constexpr auto INDEPENDENT_MASK = static_cast<unsigned>(PathTemplateParameterType::BIN) | static_cast<unsigned>(PathTemplateParameterType::BASE);
|
|
||||||
static constexpr auto PROJECT_MASK = static_cast<unsigned>(PathTemplateParameterType::BIN) | static_cast<unsigned>(PathTemplateParameterType::BASE)
|
|
||||||
| static_cast<unsigned>(PathTemplateParameterType::PROJECT);
|
|
||||||
static constexpr auto GAME_MASK = static_cast<unsigned>(PathTemplateParameterType::BIN) | static_cast<unsigned>(PathTemplateParameterType::BASE)
|
|
||||||
| static_cast<unsigned>(PathTemplateParameterType::PROJECT) | static_cast<unsigned>(PathTemplateParameterType::GAME);
|
|
||||||
|
|
||||||
public:
|
|
||||||
LinkerSearchPathBuilder(const char* typeName, std::string binDir, std::string baseDir)
|
|
||||||
: m_type_name(typeName),
|
|
||||||
m_bin_dir(std::move(binDir)),
|
|
||||||
m_base_dir(std::move(baseDir))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildFromArgs(const std::set<std::string>& templates)
|
|
||||||
{
|
|
||||||
m_templates.reserve(templates.size());
|
|
||||||
for (const auto& templateString : templates)
|
|
||||||
{
|
|
||||||
LinkerPathTemplate templateStruct;
|
|
||||||
templateStruct.CreateFromString(templateString);
|
|
||||||
m_templates.emplace_back(std::move(templateStruct));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::unique_ptr<ISearchPath> BuildIndependentSearchPaths() const override
|
|
||||||
{
|
|
||||||
SearchPaths searchPaths;
|
|
||||||
std::unordered_set<std::string> addedSearchPaths;
|
|
||||||
auto hasSearchPath = false;
|
|
||||||
|
|
||||||
for (const auto& curTemplate : m_templates)
|
|
||||||
{
|
|
||||||
if (curTemplate.CanRender(INDEPENDENT_MASK))
|
|
||||||
{
|
|
||||||
auto renderedTemplate = curTemplate.Render(m_bin_dir, m_base_dir, std::string(), std::string());
|
|
||||||
if (AddSearchPath(addedSearchPaths, searchPaths, renderedTemplate))
|
|
||||||
hasSearchPath = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasSearchPath)
|
|
||||||
return std::make_unique<SearchPaths>(std::move(searchPaths));
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::unique_ptr<ISearchPath> BuildSearchPathsSpecificToProject(const std::string& projectName) const override
|
|
||||||
{
|
|
||||||
SearchPaths searchPaths;
|
|
||||||
std::unordered_set<std::string> addedSearchPaths;
|
|
||||||
auto hasSearchPath = false;
|
|
||||||
|
|
||||||
for (const auto& curTemplate : m_templates)
|
|
||||||
{
|
|
||||||
if (!curTemplate.CanRender(INDEPENDENT_MASK) && curTemplate.CanRender(PROJECT_MASK))
|
|
||||||
{
|
|
||||||
auto renderedTemplate = curTemplate.Render(m_bin_dir, m_base_dir, projectName, std::string());
|
|
||||||
if (AddSearchPath(addedSearchPaths, searchPaths, renderedTemplate))
|
|
||||||
hasSearchPath = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasSearchPath)
|
|
||||||
return std::make_unique<SearchPaths>(std::move(searchPaths));
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::unique_ptr<ISearchPath> BuildSearchPathsSpecificToProjectAndGame(const std::string& projectName, GameId game) const override
|
|
||||||
{
|
|
||||||
SearchPaths searchPaths;
|
|
||||||
std::unordered_set<std::string> addedSearchPaths;
|
|
||||||
auto hasSearchPath = false;
|
|
||||||
|
|
||||||
for (const auto& curTemplate : m_templates)
|
|
||||||
{
|
|
||||||
if (!curTemplate.CanRender(PROJECT_MASK) && curTemplate.CanRender(GAME_MASK))
|
|
||||||
{
|
|
||||||
std::string gameName(GameId_Names[static_cast<unsigned>(game)]);
|
|
||||||
utils::MakeStringLowerCase(gameName);
|
|
||||||
|
|
||||||
auto renderedTemplate = curTemplate.Render(m_bin_dir, m_base_dir, projectName, gameName);
|
|
||||||
if (AddSearchPath(addedSearchPaths, searchPaths, renderedTemplate))
|
|
||||||
hasSearchPath = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasSearchPath)
|
|
||||||
return std::make_unique<SearchPaths>(std::move(searchPaths));
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool AddSearchPath(std::unordered_set<std::string>& existingSearchPaths, SearchPaths& searchPaths, const std::string& path) const
|
|
||||||
{
|
|
||||||
const auto existingSearchPath = existingSearchPaths.find(path);
|
|
||||||
if (existingSearchPath != existingSearchPaths.end())
|
|
||||||
return false;
|
|
||||||
existingSearchPaths.emplace(path);
|
|
||||||
|
|
||||||
if (!fs::is_directory(path))
|
|
||||||
{
|
|
||||||
std::cout << std::format("Adding {} search path (Not found): {}\n", m_type_name, path);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << std::format("Adding {} search path: {}\n", m_type_name, path);
|
|
||||||
searchPaths.CommitSearchPath(std::make_unique<SearchPathFilesystem>(path));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* m_type_name;
|
|
||||||
std::vector<LinkerPathTemplate> m_templates;
|
|
||||||
std::string m_bin_dir;
|
|
||||||
std::string m_base_dir;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LinkerPaths final : public ILinkerPaths
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LinkerPaths(std::string binDir,
|
|
||||||
std::string baseDir,
|
|
||||||
LinkerSearchPathBuilder assetSearchPaths,
|
|
||||||
LinkerSearchPathBuilder gdtSearchPaths,
|
|
||||||
LinkerSearchPathBuilder sourceSearchPaths,
|
|
||||||
LinkerPathTemplate cacheTemplate,
|
|
||||||
LinkerPathTemplate outTemplate)
|
|
||||||
: m_bin_dir(std::move(binDir)),
|
|
||||||
m_base_dir(std::move(baseDir)),
|
|
||||||
m_asset_search_paths(std::move(assetSearchPaths)),
|
|
||||||
m_gdt_search_paths(std::move(gdtSearchPaths)),
|
|
||||||
m_source_search_paths(std::move(sourceSearchPaths)),
|
|
||||||
m_cache_template(std::move(cacheTemplate)),
|
|
||||||
m_out_template(std::move(outTemplate))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const ILinkerSearchPathBuilder& AssetSearchPaths() const override
|
|
||||||
{
|
|
||||||
return m_asset_search_paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const ILinkerSearchPathBuilder& GdtSearchPaths() const override
|
|
||||||
{
|
|
||||||
return m_gdt_search_paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const ILinkerSearchPathBuilder& SourceSearchPaths() const override
|
|
||||||
{
|
|
||||||
return m_source_search_paths;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::string BuildCacheFolderPath(const std::string& projectName, GameId game) const override
|
|
||||||
{
|
|
||||||
return m_cache_template.Render(m_bin_dir, m_base_dir, projectName, GameId_Names[static_cast<unsigned>(game)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::string BuildOutputFolderPath(const std::string& projectName, GameId game) const override
|
|
||||||
{
|
|
||||||
return m_out_template.Render(m_bin_dir, m_base_dir, projectName, GameId_Names[static_cast<unsigned>(game)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_bin_dir;
|
|
||||||
std::string m_base_dir;
|
|
||||||
LinkerSearchPathBuilder m_asset_search_paths;
|
|
||||||
LinkerSearchPathBuilder m_gdt_search_paths;
|
|
||||||
LinkerSearchPathBuilder m_source_search_paths;
|
|
||||||
LinkerPathTemplate m_cache_template;
|
|
||||||
LinkerPathTemplate m_out_template;
|
|
||||||
};
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
std::unique_ptr<ILinkerPaths> ILinkerPaths::FromArgs(const LinkerArgs& args)
|
|
||||||
{
|
|
||||||
std::string normalizedBinPath = fs::weakly_canonical(args.m_bin_folder).make_preferred().string();
|
|
||||||
std::string normalizedBasePath = fs::weakly_canonical(args.m_base_folder).make_preferred().string();
|
|
||||||
|
|
||||||
LinkerSearchPathBuilder assetSearchPaths("asset", normalizedBinPath, normalizedBasePath);
|
|
||||||
assetSearchPaths.BuildFromArgs(args.m_asset_search_paths);
|
|
||||||
|
|
||||||
LinkerSearchPathBuilder gdtSearchPaths("gdt", normalizedBinPath, normalizedBasePath);
|
|
||||||
gdtSearchPaths.BuildFromArgs(args.m_gdt_search_paths);
|
|
||||||
|
|
||||||
LinkerSearchPathBuilder sourceSearchPaths("source", normalizedBinPath, normalizedBasePath);
|
|
||||||
sourceSearchPaths.BuildFromArgs(args.m_source_search_paths);
|
|
||||||
|
|
||||||
LinkerPathTemplate cacheTemplate;
|
|
||||||
cacheTemplate.CreateFromString(LinkerArgs::DEFAULT_CACHE_FOLDER);
|
|
||||||
|
|
||||||
LinkerPathTemplate outTemplate;
|
|
||||||
outTemplate.CreateFromString(args.m_out_folder);
|
|
||||||
|
|
||||||
return std::make_unique<LinkerPaths>(std::move(normalizedBinPath),
|
|
||||||
std::move(normalizedBasePath),
|
|
||||||
std::move(assetSearchPaths),
|
|
||||||
std::move(gdtSearchPaths),
|
|
||||||
std::move(sourceSearchPaths),
|
|
||||||
std::move(cacheTemplate),
|
|
||||||
std::move(outTemplate));
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Game/IGame.h"
|
|
||||||
#include "LinkerArgs.h"
|
|
||||||
#include "SearchPath/ISearchPath.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class ILinkerSearchPathBuilder
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ILinkerSearchPathBuilder() = default;
|
|
||||||
virtual ~ILinkerSearchPathBuilder() = default;
|
|
||||||
ILinkerSearchPathBuilder(const ILinkerSearchPathBuilder& other) = default;
|
|
||||||
ILinkerSearchPathBuilder(ILinkerSearchPathBuilder&& other) noexcept = default;
|
|
||||||
ILinkerSearchPathBuilder& operator=(const ILinkerSearchPathBuilder& other) = default;
|
|
||||||
ILinkerSearchPathBuilder& operator=(ILinkerSearchPathBuilder&& other) noexcept = default;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual std::unique_ptr<ISearchPath> BuildIndependentSearchPaths() const = 0;
|
|
||||||
[[nodiscard]] virtual std::unique_ptr<ISearchPath> BuildSearchPathsSpecificToProject(const std::string& projectName) const = 0;
|
|
||||||
[[nodiscard]] virtual std::unique_ptr<ISearchPath> BuildSearchPathsSpecificToProjectAndGame(const std::string& projectName, GameId game) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ILinkerPaths
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ILinkerPaths() = default;
|
|
||||||
virtual ~ILinkerPaths() = default;
|
|
||||||
ILinkerPaths(const ILinkerPaths& other) = default;
|
|
||||||
ILinkerPaths(ILinkerPaths&& other) noexcept = default;
|
|
||||||
ILinkerPaths& operator=(const ILinkerPaths& other) = default;
|
|
||||||
ILinkerPaths& operator=(ILinkerPaths&& other) noexcept = default;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Creates linker search paths based on templates from user specified args.
|
|
||||||
* \param args The user specified args.
|
|
||||||
* \return Linker search paths based on user specified templates.
|
|
||||||
*/
|
|
||||||
static std::unique_ptr<ILinkerPaths> FromArgs(const LinkerArgs& args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Grants access to the builder for asset search paths.
|
|
||||||
* \return A builder instance for building asset search paths.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] virtual const ILinkerSearchPathBuilder& AssetSearchPaths() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Grants access to the builder for gdt search paths.
|
|
||||||
* \return A builder instance for building gdt search paths.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] virtual const ILinkerSearchPathBuilder& GdtSearchPaths() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Grants access to the builder for source search paths.
|
|
||||||
* \return A builder instance for building source search paths.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] virtual const ILinkerSearchPathBuilder& SourceSearchPaths() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Builds the cache path based on the specified information.
|
|
||||||
* \param projectName The name of the project to resolve the path input for.
|
|
||||||
* \param game The game to resolve the path input for.
|
|
||||||
* \return A cache path based on the input and preconfigured template.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] virtual std::string BuildCacheFolderPath(const std::string& projectName, GameId game) const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Builds the output path based on the specified information.
|
|
||||||
* \param projectName The name of the project to resolve the path input for.
|
|
||||||
* \param game The game to resolve the path input for.
|
|
||||||
* \return An output path based on the input and preconfigured template.
|
|
||||||
*/
|
|
||||||
[[nodiscard]] virtual std::string BuildOutputFolderPath(const std::string& projectName, GameId game) const = 0;
|
|
||||||
};
|
|
189
src/Linker/LinkerSearchPaths.cpp
Normal file
189
src/Linker/LinkerSearchPaths.cpp
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
#include "LinkerSearchPaths.h"
|
||||||
|
|
||||||
|
#include "ObjContainer/IWD/IWD.h"
|
||||||
|
#include "ObjLoading.h"
|
||||||
|
#include "SearchPath/SearchPathFilesystem.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
LinkerSearchPaths::LinkerSearchPaths(const LinkerArgs& args)
|
||||||
|
: m_args(args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinkerSearchPaths::LoadSearchPath(ISearchPath* searchPath) const
|
||||||
|
{
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
{
|
||||||
|
printf("Loading search path: \"%s\"\n", searchPath->GetPath().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjLoading::LoadIWDsInSearchPath(searchPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinkerSearchPaths::UnloadSearchPath(ISearchPath* searchPath) const
|
||||||
|
{
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
{
|
||||||
|
printf("Unloading search path: \"%s\"\n", searchPath->GetPath().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjLoading::UnloadIWDsInSearchPath(searchPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPaths LinkerSearchPaths::GetAssetSearchPathsForProject(const std::string& gameName, const std::string& projectName)
|
||||||
|
{
|
||||||
|
SearchPaths searchPathsForProject;
|
||||||
|
|
||||||
|
for (const auto& searchPathStr : m_args.GetAssetSearchPathsForProject(gameName, projectName))
|
||||||
|
{
|
||||||
|
auto absolutePath = fs::absolute(searchPathStr);
|
||||||
|
|
||||||
|
if (!fs::is_directory(absolutePath))
|
||||||
|
{
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding asset search path (Not found): " << absolutePath.string() << "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding asset search path: " << absolutePath.string() << "\n";
|
||||||
|
|
||||||
|
auto searchPath = std::make_unique<SearchPathFilesystem>(searchPathStr);
|
||||||
|
LoadSearchPath(searchPath.get());
|
||||||
|
searchPathsForProject.IncludeSearchPath(searchPath.get());
|
||||||
|
m_loaded_project_search_paths.emplace_back(std::move(searchPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
searchPathsForProject.IncludeSearchPath(&m_asset_search_paths);
|
||||||
|
|
||||||
|
for (auto* iwd : IWD::Repository)
|
||||||
|
{
|
||||||
|
searchPathsForProject.IncludeSearchPath(iwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return searchPathsForProject;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPaths LinkerSearchPaths::GetGdtSearchPathsForProject(const std::string& gameName, const std::string& projectName)
|
||||||
|
{
|
||||||
|
SearchPaths searchPathsForProject;
|
||||||
|
|
||||||
|
for (const auto& searchPathStr : m_args.GetGdtSearchPathsForProject(gameName, projectName))
|
||||||
|
{
|
||||||
|
auto absolutePath = fs::absolute(searchPathStr);
|
||||||
|
|
||||||
|
if (!fs::is_directory(absolutePath))
|
||||||
|
{
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding gdt search path (Not found): " << absolutePath.string() << "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding gdt search path: " << absolutePath.string() << "\n";
|
||||||
|
|
||||||
|
searchPathsForProject.CommitSearchPath(std::make_unique<SearchPathFilesystem>(searchPathStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
searchPathsForProject.IncludeSearchPath(&m_gdt_search_paths);
|
||||||
|
|
||||||
|
return searchPathsForProject;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchPaths LinkerSearchPaths::GetSourceSearchPathsForProject(const std::string& projectName)
|
||||||
|
{
|
||||||
|
SearchPaths searchPathsForProject;
|
||||||
|
|
||||||
|
for (const auto& searchPathStr : m_args.GetSourceSearchPathsForProject(projectName))
|
||||||
|
{
|
||||||
|
auto absolutePath = fs::absolute(searchPathStr);
|
||||||
|
|
||||||
|
if (!fs::is_directory(absolutePath))
|
||||||
|
{
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding source search path (Not found): " << absolutePath.string() << "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding source search path: " << absolutePath.string() << "\n";
|
||||||
|
|
||||||
|
searchPathsForProject.CommitSearchPath(std::make_unique<SearchPathFilesystem>(searchPathStr));
|
||||||
|
}
|
||||||
|
|
||||||
|
searchPathsForProject.IncludeSearchPath(&m_source_search_paths);
|
||||||
|
|
||||||
|
return searchPathsForProject;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LinkerSearchPaths::BuildProjectIndependentSearchPaths()
|
||||||
|
{
|
||||||
|
for (const auto& path : m_args.GetProjectIndependentAssetSearchPaths())
|
||||||
|
{
|
||||||
|
auto absolutePath = fs::absolute(path);
|
||||||
|
|
||||||
|
if (!fs::is_directory(absolutePath))
|
||||||
|
{
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding asset search path (Not found): " << absolutePath.string() << "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding asset search path: " << absolutePath.string() << "\n";
|
||||||
|
|
||||||
|
auto searchPath = std::make_unique<SearchPathFilesystem>(absolutePath.string());
|
||||||
|
LoadSearchPath(searchPath.get());
|
||||||
|
m_asset_search_paths.CommitSearchPath(std::move(searchPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& path : m_args.GetProjectIndependentGdtSearchPaths())
|
||||||
|
{
|
||||||
|
auto absolutePath = fs::absolute(path);
|
||||||
|
|
||||||
|
if (!fs::is_directory(absolutePath))
|
||||||
|
{
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Loading gdt search path (Not found): " << absolutePath.string() << "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding gdt search path: " << absolutePath.string() << "\n";
|
||||||
|
|
||||||
|
m_gdt_search_paths.CommitSearchPath(std::make_unique<SearchPathFilesystem>(absolutePath.string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& path : m_args.GetProjectIndependentSourceSearchPaths())
|
||||||
|
{
|
||||||
|
auto absolutePath = fs::absolute(path);
|
||||||
|
|
||||||
|
if (!fs::is_directory(absolutePath))
|
||||||
|
{
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Loading source search path (Not found): " << absolutePath.string() << "\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_args.m_verbose)
|
||||||
|
std::cout << "Adding source search path: " << absolutePath.string() << "\n";
|
||||||
|
|
||||||
|
m_source_search_paths.CommitSearchPath(std::make_unique<SearchPathFilesystem>(absolutePath.string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinkerSearchPaths::UnloadProjectSpecificSearchPaths()
|
||||||
|
{
|
||||||
|
for (const auto& loadedSearchPath : m_loaded_project_search_paths)
|
||||||
|
{
|
||||||
|
UnloadSearchPath(loadedSearchPath.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_loaded_project_search_paths.clear();
|
||||||
|
}
|
45
src/Linker/LinkerSearchPaths.h
Normal file
45
src/Linker/LinkerSearchPaths.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "LinkerArgs.h"
|
||||||
|
#include "SearchPath/SearchPaths.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class LinkerSearchPaths
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit LinkerSearchPaths(const LinkerArgs& args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Loads a search path.
|
||||||
|
* \param searchPath The search path to load.
|
||||||
|
*/
|
||||||
|
void LoadSearchPath(ISearchPath* searchPath) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Unloads a search path.
|
||||||
|
* \param searchPath The search path to unload.
|
||||||
|
*/
|
||||||
|
void UnloadSearchPath(ISearchPath* searchPath) const;
|
||||||
|
|
||||||
|
SearchPaths GetAssetSearchPathsForProject(const std::string& gameName, const std::string& projectName);
|
||||||
|
|
||||||
|
SearchPaths GetGdtSearchPathsForProject(const std::string& gameName, const std::string& projectName);
|
||||||
|
|
||||||
|
SearchPaths GetSourceSearchPathsForProject(const std::string& projectName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Initializes the Linker object's search paths based on the user's input.
|
||||||
|
* \return \c true if building the search paths was successful, otherwise \c false.
|
||||||
|
*/
|
||||||
|
bool BuildProjectIndependentSearchPaths();
|
||||||
|
|
||||||
|
void UnloadProjectSpecificSearchPaths();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const LinkerArgs& m_args;
|
||||||
|
std::vector<std::unique_ptr<ISearchPath>> m_loaded_project_search_paths;
|
||||||
|
SearchPaths m_asset_search_paths;
|
||||||
|
SearchPaths m_gdt_search_paths;
|
||||||
|
SearchPaths m_source_search_paths;
|
||||||
|
};
|
20
src/Linker/ZoneCreation/IZoneCreator.h
Normal file
20
src/Linker/ZoneCreation/IZoneCreator.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Utils/ClassUtils.h"
|
||||||
|
#include "Zone/Zone.h"
|
||||||
|
#include "ZoneCreationContext.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class IZoneCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IZoneCreator() = default;
|
||||||
|
virtual ~IZoneCreator() = default;
|
||||||
|
IZoneCreator(const IZoneCreator& other) = default;
|
||||||
|
IZoneCreator(IZoneCreator&& other) noexcept = default;
|
||||||
|
IZoneCreator& operator=(const IZoneCreator& other) = default;
|
||||||
|
IZoneCreator& operator=(IZoneCreator&& other) noexcept = default;
|
||||||
|
|
||||||
|
_NODISCARD virtual bool SupportsGame(const std::string& gameName) const = 0;
|
||||||
|
_NODISCARD virtual std::unique_ptr<Zone> CreateZoneForDefinition(ZoneCreationContext& context) const = 0;
|
||||||
|
};
|
@ -1,17 +1,13 @@
|
|||||||
#include "ZoneCreationContext.h"
|
#include "ZoneCreationContext.h"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
|
||||||
|
|
||||||
ZoneCreationContext::ZoneCreationContext()
|
ZoneCreationContext::ZoneCreationContext()
|
||||||
: m_definition(nullptr),
|
: m_asset_search_path(nullptr),
|
||||||
m_asset_search_path(nullptr)
|
m_definition(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneCreationContext::ZoneCreationContext(ZoneDefinition* definition, ISearchPath* assetSearchPath, fs::path outDir, fs::path cacheDir)
|
ZoneCreationContext::ZoneCreationContext(ISearchPath* assetSearchPath, ZoneDefinition* definition)
|
||||||
: m_definition(definition),
|
: m_asset_search_path(assetSearchPath),
|
||||||
m_asset_search_path(assetSearchPath),
|
m_definition(definition)
|
||||||
m_out_dir(std::move(outDir)),
|
|
||||||
m_cache_dir(std::move(cacheDir))
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -4,20 +4,19 @@
|
|||||||
#include "Zone/AssetList/AssetList.h"
|
#include "Zone/AssetList/AssetList.h"
|
||||||
#include "Zone/Definition/ZoneDefinition.h"
|
#include "Zone/Definition/ZoneDefinition.h"
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class ZoneCreationContext
|
class ZoneCreationContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ZoneDefinition* m_definition;
|
std::string m_game_name;
|
||||||
ISearchPath* m_asset_search_path;
|
ISearchPath* m_asset_search_path;
|
||||||
std::filesystem::path m_out_dir;
|
ZoneDefinition* m_definition;
|
||||||
std::filesystem::path m_cache_dir;
|
|
||||||
std::vector<std::unique_ptr<Gdt>> m_gdt_files;
|
std::vector<std::unique_ptr<Gdt>> m_gdt_files;
|
||||||
AssetList m_ignored_assets;
|
AssetList m_ignored_assets;
|
||||||
|
|
||||||
ZoneCreationContext();
|
ZoneCreationContext();
|
||||||
ZoneCreationContext(ZoneDefinition* definition, ISearchPath* assetSearchPath, std::filesystem::path outDir, std::filesystem::path cacheDir);
|
ZoneCreationContext(ISearchPath* assetSearchPath, ZoneDefinition* definition);
|
||||||
};
|
};
|
||||||
|
@ -1,91 +0,0 @@
|
|||||||
#include "ZoneCreator.h"
|
|
||||||
|
|
||||||
#include "Gdt/GdtLookup.h"
|
|
||||||
#include "IObjCompiler.h"
|
|
||||||
#include "IObjLoader.h"
|
|
||||||
#include "SearchPath/OutputPathFilesystem.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
std::unique_ptr<Zone> CreateZone(const ZoneCreationContext& context, const GameId gameId)
|
|
||||||
{
|
|
||||||
return std::make_unique<Zone>(context.m_definition->m_name, 0, IGame::GetGameById(gameId));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Gdt*> CreateGdtList(const ZoneCreationContext& context)
|
|
||||||
{
|
|
||||||
std::vector<Gdt*> gdtList;
|
|
||||||
gdtList.reserve(context.m_gdt_files.size());
|
|
||||||
for (const auto& gdt : context.m_gdt_files)
|
|
||||||
gdtList.push_back(gdt.get());
|
|
||||||
|
|
||||||
return gdtList;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IgnoreReferencesFromAssets(ZoneCreationContext& context)
|
|
||||||
{
|
|
||||||
for (const auto& assetEntry : context.m_definition->m_assets)
|
|
||||||
{
|
|
||||||
if (!assetEntry.m_is_reference)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
context.m_ignored_assets.m_entries.emplace_back(assetEntry.m_asset_type, assetEntry.m_asset_name, assetEntry.m_is_reference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace zone_creator
|
|
||||||
{
|
|
||||||
void InitLookup(const ZoneCreationContext& context, GdtLookup& lookup)
|
|
||||||
{
|
|
||||||
std::vector<const Gdt*> gdtFiles;
|
|
||||||
gdtFiles.reserve(context.m_gdt_files.size());
|
|
||||||
|
|
||||||
for (const auto& gdt : context.m_gdt_files)
|
|
||||||
{
|
|
||||||
gdtFiles.emplace_back(gdt.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
lookup.Initialize(gdtFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Zone> CreateZoneForDefinition(GameId gameId, ZoneCreationContext& context)
|
|
||||||
{
|
|
||||||
auto zone = CreateZone(context, gameId);
|
|
||||||
|
|
||||||
IgnoreReferencesFromAssets(context);
|
|
||||||
IgnoredAssetLookup ignoredAssetLookup(context.m_ignored_assets);
|
|
||||||
|
|
||||||
GdtLookup lookup;
|
|
||||||
InitLookup(context, lookup);
|
|
||||||
|
|
||||||
const auto* objCompiler = IObjCompiler::GetObjCompilerForGame(gameId);
|
|
||||||
const auto* objLoader = IObjLoader::GetObjLoaderForGame(gameId);
|
|
||||||
|
|
||||||
AssetCreatorCollection creatorCollection(*zone);
|
|
||||||
ZoneDefinitionContext zoneDefinitionContext(*context.m_definition);
|
|
||||||
AssetCreationContext creationContext(*zone, &creatorCollection, &ignoredAssetLookup);
|
|
||||||
|
|
||||||
OutputPathFilesystem outDir(context.m_out_dir);
|
|
||||||
OutputPathFilesystem cacheDir(context.m_cache_dir);
|
|
||||||
objCompiler->ConfigureCreatorCollection(
|
|
||||||
creatorCollection, *zone, zoneDefinitionContext, *context.m_asset_search_path, lookup, creationContext, outDir, cacheDir);
|
|
||||||
objLoader->ConfigureCreatorCollection(creatorCollection, *zone, *context.m_asset_search_path, lookup);
|
|
||||||
|
|
||||||
for (const auto& assetEntry : context.m_definition->m_assets)
|
|
||||||
{
|
|
||||||
const auto* createdAsset = creationContext.LoadDependencyGeneric(assetEntry.m_asset_type, assetEntry.m_asset_name);
|
|
||||||
|
|
||||||
if (!createdAsset)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
++zoneDefinitionContext.m_asset_index_in_definition;
|
|
||||||
}
|
|
||||||
|
|
||||||
creatorCollection.FinalizeZone(creationContext);
|
|
||||||
|
|
||||||
return zone;
|
|
||||||
}
|
|
||||||
} // namespace zone_creator
|
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Zone/Zone.h"
|
|
||||||
#include "ZoneCreationContext.h"
|
|
||||||
|
|
||||||
namespace zone_creator
|
|
||||||
{
|
|
||||||
[[nodiscard]] std::unique_ptr<Zone> CreateZoneForDefinition(GameId game, ZoneCreationContext& context);
|
|
||||||
}
|
|
@ -5,7 +5,6 @@ function ObjCommon:include(includes)
|
|||||||
Common:include(includes)
|
Common:include(includes)
|
||||||
json:include(includes)
|
json:include(includes)
|
||||||
minizip:include(includes)
|
minizip:include(includes)
|
||||||
Parser:include(includes)
|
|
||||||
includedirs {
|
includedirs {
|
||||||
path.join(ProjectFolder(), "ObjCommon")
|
path.join(ProjectFolder(), "ObjCommon")
|
||||||
}
|
}
|
||||||
@ -17,7 +16,6 @@ function ObjCommon:link(links)
|
|||||||
links:linkto(Utils)
|
links:linkto(Utils)
|
||||||
links:linkto(Common)
|
links:linkto(Common)
|
||||||
links:linkto(minizip)
|
links:linkto(minizip)
|
||||||
links:linkto(Parser)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function ObjCommon:use()
|
function ObjCommon:use()
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user