mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-05-25 07:32:48 -04:00
Compare commits
454 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 36b42635d6 | |||
| 4a029cc6cf | |||
| 57ba36b063 | |||
| 4173eadae2 | |||
| 1b6dd8a0fe | |||
| dd6a8b5084 | |||
| f4c871e35c | |||
| 8e808c4305 | |||
| 03c3eef193 | |||
| 42a5f46e5e | |||
| 7878b8f3e4 | |||
| 7906d70485 | |||
| dd62d0882e | |||
| 6e88a3706c | |||
| d102506fba | |||
| 7c7f032e0e | |||
| da8f80bb28 | |||
| 63f763a556 | |||
| 83541f4605 | |||
| 43b7ca96d7 | |||
| c00edb928b | |||
| b0510d78f8 | |||
| fd3872ae30 | |||
| aa00cba76e | |||
| 18208cc993 | |||
| b310d675f1 | |||
| eb081dc719 | |||
| e883f27436 | |||
| f563ac733f | |||
| a133be625e | |||
| 06e8a5af41 | |||
| f1070a2e74 | |||
| 02c0caff4f | |||
| 2ad0b37fa5 | |||
| 6b6a352205 | |||
| 37ffc8b9c8 | |||
| d75b38d457 | |||
| 36e40665bb | |||
| 9804035dc0 | |||
| 973ec52b2a | |||
| d61b398f41 | |||
| af13595aae | |||
| 97211093f3 | |||
| 15e22349df | |||
| 8888fb2ec1 | |||
| dc3c0dd9c8 | |||
| 08915e5684 | |||
| 083ceb4423 | |||
| 87125ae334 | |||
| c487e4ba0b | |||
| 1b141fd68c | |||
| 694c6c9832 | |||
| c6a875eb5c | |||
| 677c4845f6 | |||
| 7fb8902e7f | |||
| 58c097cfb9 | |||
| 6265613bc7 | |||
| c21b2e8f00 | |||
| b3c7edcf76 | |||
| c2ff12c3e8 | |||
| dbc4d8199e | |||
| 0e1248f840 | |||
| 7a516c72c3 | |||
| a927a881fc | |||
| ac1a87730e | |||
| cf881d7d25 | |||
| 41eb6c585d | |||
| ee505fc47d | |||
| 7758749770 | |||
| da893a5b86 | |||
| e412a8b55e | |||
| 5a0b854c5c | |||
| bf2420f7d3 | |||
| 50d6836b4a | |||
| da677682cd | |||
| 11b6ce819d | |||
| 5ee86cb558 | |||
| 3a2fcc9604 | |||
| fde05e65c0 | |||
| 00fb12134a | |||
| fa8d64ec3a | |||
| b4740d131f | |||
| ec2222347e | |||
| 3d0d97d6b5 | |||
| 2b78bea475 | |||
| 28b7f23769 | |||
| 784cb98d7f | |||
| d47746eab1 | |||
| 936c493b9e | |||
| d628bafe29 | |||
| d83c6f1753 | |||
| e1b83b6eb4 | |||
| d2153d601c | |||
| 98be9a8472 | |||
| 5d2b5559c8 | |||
| b54f6daa27 | |||
| c5acef2957 | |||
| b5b5a58302 | |||
| d6d7ffd3da | |||
| 66c2fdaacd | |||
| f6fa3c74c7 | |||
| 22c963c0a0 | |||
| e97ba37a5e | |||
| b18cc9d628 | |||
| 978b325a30 | |||
| 006506240f | |||
| f712068a17 | |||
| 55e79cd9d2 | |||
| c9aafcf7c5 | |||
| 34d6212ab2 | |||
| e76890a796 | |||
| e2e0a070ea | |||
| d53c8588e2 | |||
| 941cf65227 | |||
| e1f95a5ad9 | |||
| 18a26b480e | |||
| 67bbeca809 | |||
| eda5a6ac91 | |||
| a2d4f4766d | |||
| a9f3aedf8e | |||
| 9686a7ca4c | |||
| e80e3440e1 | |||
| 4cda92462a | |||
| 4a0269b3b1 | |||
| 4d81c28738 | |||
| 3b844375b7 | |||
| f1dc980de8 | |||
| 6daf357fd9 | |||
| d2fa0d6485 | |||
| b14fb37b81 | |||
| edb5261b07 | |||
| 8118947ab0 | |||
| 0ce0ab1260 | |||
| 64aca78450 | |||
| 584a4ad818 | |||
| bf505dba5c | |||
| 776219fb52 | |||
| a572c11f4f | |||
| 05136c13b7 | |||
| c2fed1a382 | |||
| 90067be132 | |||
| 80863fc7f2 | |||
| c0b9171f98 | |||
| b70ad81f57 | |||
| 0573a1b2ac | |||
| b774252f0c | |||
| 3792b03a7d | |||
| 927ffd0b8b | |||
| d6ebce068d | |||
| 4680641514 | |||
| ca08680a12 | |||
| 70d7d66d0c | |||
| d735616020 | |||
| 168e84498f | |||
| ed1708508a | |||
| e12e1d67c6 | |||
| d39a1a0bdf | |||
| f87f636828 | |||
| eed3942b81 | |||
| f5112a709a | |||
| f6bb46a0dc | |||
| 51e4485966 | |||
| ad8179287e | |||
| 0971b9aa78 | |||
| 9bc6aac81e | |||
| ad3efccb88 | |||
| f4c1332159 | |||
| 72981221ad | |||
| 6723f4c7c2 | |||
| f9621dcc17 | |||
| 10ce3c88fb | |||
| ea92a2e123 | |||
| b43eb2d0bd | |||
| d09172d74d | |||
| 6b0338a37d | |||
| 6206cd7db0 | |||
| 01b7fedc35 | |||
| 71b1db1fb6 | |||
| b4614acf70 | |||
| cd37a56161 | |||
| eb632ccb50 | |||
| 0f2e7db8e0 | |||
| a3d0962054 | |||
| 46a421f933 | |||
| b7f9960a60 | |||
| b46c7a0607 | |||
| ee9ea3f2bd | |||
| a31256d956 | |||
| 7a9160ed78 | |||
| 42bce9d33e | |||
| fabe051d3d | |||
| 8945b2ed48 | |||
| d575a3dda6 | |||
| 37dd045bd2 | |||
| 651e0ddad4 | |||
| 68e7f2e6c1 | |||
| b989ef4f7f | |||
| 789cf13aae | |||
| 86faa42acf | |||
| d623ac5918 | |||
| 4a3e43f73f | |||
| 094388187f | |||
| 791f7774a5 | |||
| e88000aeb0 | |||
| d34a6d7666 | |||
| 3bcc9514ab | |||
| 15fba97949 | |||
| 6766719969 | |||
| 6484d9354d | |||
| 23fb885e09 | |||
| 81cd594704 | |||
| 797d9fab7c | |||
| 96c2033361 | |||
| 7b11509010 | |||
| a4804d7290 | |||
| 5751b5c278 | |||
| f97f9ae422 | |||
| c7ccd6dbff | |||
| 1f351418e1 | |||
| e4b58e5a0c | |||
| 0d9c390526 | |||
| b924831eba | |||
| 317de33a8b | |||
| fa090c51f6 | |||
| e63d84bd7d | |||
| 5581f45050 | |||
| b6934b34db | |||
| 5453c68399 | |||
| 4ea7f8371f | |||
| c803ff65ce | |||
| 0e10b59307 | |||
| 4bf4ad3359 | |||
| f80ba4102a | |||
| a4334ecb02 | |||
| a8fea61bda | |||
| 1f5d323d89 | |||
| cf639b1d51 | |||
| 59baf24dc6 | |||
| 9b33827d02 | |||
| 9afbe42720 | |||
| 7f233de502 | |||
| ed9378375d | |||
| e51e7f3d45 | |||
| cb2410d9c5 | |||
| b2ac01bc98 | |||
| 1794683d3a | |||
| c70e3f38b1 | |||
| aadabe1ecd | |||
| 7f58ef14ee | |||
| 8efeceb236 | |||
| 9a126dec4e | |||
| 7ef3fff869 | |||
| 1ebca42f46 | |||
| 93d0d7443a | |||
| c23457d666 | |||
| d397c1d871 | |||
| 2f5f089e7f | |||
| facd1723f8 | |||
| 5f913cb9bf | |||
| 739434e3e4 | |||
| 78ad282056 | |||
| d61d4e508a | |||
| bd86c792c3 | |||
| dffcbb035e | |||
| 0f7a88bd5a | |||
| 97adc4a7f2 | |||
| 6190388164 | |||
| 8c9d067657 | |||
| 6d3d5e7da5 | |||
| 212d774613 | |||
| e68fac14c8 | |||
| 7675309e3f | |||
| 4ce19e1448 | |||
| fd379896d6 | |||
| 8431cddb14 | |||
| 2d60c772bf | |||
| 6d0d608e38 | |||
| fe02818d51 | |||
| db33604171 | |||
| 27e0f19dac | |||
| b89cc25df3 | |||
| 7267b60a26 | |||
| 67d5ba08ab | |||
| 1de525900d | |||
| 352b46c1f5 | |||
| 1bf7771981 | |||
| c1659d3dcf | |||
| b3c3882b12 | |||
| d80742d882 | |||
| a007bfd14a | |||
| 7eba85c3b4 | |||
| d9443d98f0 | |||
| 73447f05ab | |||
| 85c4cd3863 | |||
| cec0bc6fca | |||
| 53229f0905 | |||
| 18013e1ae0 | |||
| 61c68666d6 | |||
| bb8152b376 | |||
| 480053dfaa | |||
| eae97cff79 | |||
| 4d30cc50a1 | |||
| 4ed82c71dc | |||
| 9389ceb8c1 | |||
| b4f4e36acb | |||
| d332c3d9d6 | |||
| b59c9cdf02 | |||
| 8c25e9a992 | |||
| 4f29833476 | |||
| d648c7275c | |||
| a1ed35e5bd | |||
| 206f63f9e6 | |||
| 7a45380123 | |||
| 99ecccfaab | |||
| 7dd6f59b8b | |||
| 361a986b8e | |||
| b98c8b4abb | |||
| 582f084973 | |||
| 2f9874c68f | |||
| 47ad3bdc47 | |||
| 9d12813282 | |||
| 3bb234e6a6 | |||
| 44bf5af33a | |||
| 0193489b00 | |||
| a6092c21d4 | |||
| 02c50cd0c4 | |||
| fa0a66695c | |||
| 6818247317 | |||
| e8d2b0cceb | |||
| 5a97e9f0de | |||
| d0968a99c1 | |||
| 0ed8c277e8 | |||
| 477cf7f6ec | |||
| 59dc52f394 | |||
| 822476373b | |||
| 4c9e4b2d84 | |||
| 2ff5d54592 | |||
| cd01e8b778 | |||
| 8bdc4458c7 | |||
| 5f718932e6 | |||
| 3fc783b832 | |||
| c36b891d9b | |||
| fb64a11d38 | |||
| 26a4622982 | |||
| 257cd92208 | |||
| 2d9129084e | |||
| d6ce37ce7e | |||
| 6da8ffae11 | |||
| 62f56a4791 | |||
| 294684213a | |||
| ab691e64db | |||
| 3a9dd95abc | |||
| 706e57dd7b | |||
| d180b8a299 | |||
| 50bc5de2da | |||
| 4a15e113f7 | |||
| 1160fb2b15 | |||
| 27b3644335 | |||
| b6af684583 | |||
| 1ca64b1fdf | |||
| 3c1d28b081 | |||
| 5d0452d1dc | |||
| 87ed5fedfd | |||
| d05295aad2 | |||
| 9f2eb46663 | |||
| c1155bb08c | |||
| 661946b4f5 | |||
| 780e9f4669 | |||
| a33c3d606a | |||
| a21998c489 | |||
| dca922ade8 | |||
| 5f6d0939bd | |||
| ffb3523cb5 | |||
| 01347dc9f9 | |||
| 62d9390c9b | |||
| 44bdfe552c | |||
| d3c2c0ec7d | |||
| bd787719b8 | |||
| d4bd953c0b | |||
| 474eee5d98 | |||
| 38ecb6cfff | |||
| ccf1bffd4f | |||
| 1de5b72802 | |||
| bd95fe616b | |||
| d299284751 | |||
| b3d3148383 | |||
| 2ad78887b9 | |||
| 1ca12feaed | |||
| 84236e7ac3 | |||
| 1cbaa592d0 | |||
| df756b2ce0 | |||
| c7c16c39b0 | |||
| 059045481c | |||
| 44dbd3a8a9 | |||
| 753031df17 | |||
| 52f22275e3 | |||
| c19beca980 | |||
| eb49053e73 | |||
| d08b1d277e | |||
| e41873fff4 | |||
| dfa929a16f | |||
| 880e3928cf | |||
| 41d1bbe137 | |||
| e519caa554 | |||
| 1d208c7dc2 | |||
| 2edc81ee2d | |||
| 21c585b2ce | |||
| b5dc097587 | |||
| cddca2700a | |||
| 17b3f65276 | |||
| 75a4d2cf99 | |||
| 795ee54f2b | |||
| 3633bdeeaf | |||
| c5f66373c3 | |||
| 2d1aa1d13a | |||
| 32abe61554 | |||
| 235cef6abf | |||
| e871b53afc | |||
| dabb83fccf | |||
| 046b7e8949 | |||
| 97d1f0e46c | |||
| edfa369639 | |||
| 169f757954 | |||
| 4745f73655 | |||
| 660897ff63 | |||
| 37afdbd84c | |||
| 9679075cba | |||
| 5e5e57ea8f | |||
| 9118788149 | |||
| cc28a1444d | |||
| c65a40f432 | |||
| 9e8335c1f0 | |||
| 10cb23ad74 | |||
| 2daddd8a5a | |||
| d45968270a | |||
| e04b2c80b6 | |||
| 1ed45e1433 | |||
| ee1270f346 | |||
| 98c771cf2c | |||
| 69d2b5b3a3 | |||
| f57a912ca1 | |||
| 4eaf70b859 | |||
| 3f2111a3e6 | |||
| 1165e70434 | |||
| 93bea4c151 | |||
| 46df17e29f | |||
| 9c57ed6642 | |||
| cd096ce5e9 | |||
| 873995199b | |||
| 0ae5c4c0f2 | |||
| a81ecfcfcc | |||
| d9277530a2 | |||
| 14a87f83b3 | |||
| e9ba8f734f |
+40
-1
@@ -9,6 +9,7 @@ __pycache__/
|
||||
.idea/
|
||||
cmake-build-debug
|
||||
venv/
|
||||
.cache/
|
||||
|
||||
# Project-specific ignores
|
||||
build/
|
||||
@@ -24,6 +25,10 @@ docs/doxygen/
|
||||
*.map
|
||||
*.dump
|
||||
out.txt
|
||||
*.sln
|
||||
*.vcxproj
|
||||
*.vcxproj.user
|
||||
*.vcxproj.filters
|
||||
|
||||
# Tool artifacts
|
||||
tools/mipspro7.2_compiler/
|
||||
@@ -405,4 +410,38 @@ tags
|
||||
oot.otr
|
||||
*.sav
|
||||
shipofharkinian.ini
|
||||
shipofharkinian.json
|
||||
shipofharkinian.json
|
||||
imgui.ini
|
||||
|
||||
# Switch Stuff
|
||||
|
||||
*.nro
|
||||
*.nacp
|
||||
ZAPDTR/ZAPDUtils/lib/*
|
||||
!/soh/icon.jpg
|
||||
|
||||
# Xcode
|
||||
xcuserdata/
|
||||
*.xcconfig
|
||||
*.xcodeproj/*
|
||||
!*.xcodeproj/project.pbxproj
|
||||
!*.xcodeproj/xcshareddata/
|
||||
!*.xcworkspace/contents.xcworkspacedata
|
||||
/*.gcno
|
||||
**/xcshareddata/WorkspaceSettings.xcsettings
|
||||
|
||||
# cmake
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
*/extract_assets_cmake*
|
||||
/build*
|
||||
build.c
|
||||
|
||||
+169
-44
@@ -2,22 +2,84 @@
|
||||
|
||||
## Windows
|
||||
|
||||
1. Requires [Python](https://www.python.org/downloads/) >= 3.6.
|
||||
2. Install [Visual Studio 2022 Community Edition](https://visualstudio.microsoft.com/vs/community/)
|
||||
3. In the Visual Studio Installer, install `MSVC v142 - VS 2019 C++`.
|
||||
4. Clone the Ship of Harkinian repository.
|
||||
5. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice.
|
||||
6. Run `OTRExporter/OTRExporter.sln`.
|
||||
7. Switch the solution to `Release x64`.
|
||||
8. Build the solution.
|
||||
9. Launching `OTRExporter/extract_assets.py` will generate an `oot.otr` archive file in `OTRExporter/oot.otr`.
|
||||
10. Run `soh/soh.sln`
|
||||
11. Switch the solution to `Release x86`.
|
||||
12. Build the solution.
|
||||
13. Copy the `OTRExporter/oot.otr` archive file to `soh/Release`.
|
||||
14. Launch `soh.exe`.
|
||||
Requires:
|
||||
* At least 8GB of RAM (machines with 4GB have seen complier failures)
|
||||
* Visual Studio 2022 Community Edition with the C++ feature set
|
||||
* One of the Windows SDKs that comes with Visual Studio, for example the current Windows 10 version 10.0.19041.0
|
||||
* The `MSVC v142 - VS 2019 C++ build tools` component of Visual Studio
|
||||
* Python 3 (can be installed manually or as part of Visual Studio)
|
||||
* Git (can be installed manually or as part of Visual Studio)
|
||||
* Cmake (can be installed via chocolatey or manually)
|
||||
|
||||
During installation, check the "Desktop development with C++" feature set:
|
||||
|
||||

|
||||
Doing so should also check one of the Windows SDKs by default. Then, in the installation details in the right-hand column, make sure you also check the v142 toolset.
|
||||
|
||||
You can also find the v142 toolset by searching through the individual components tab:
|
||||
|
||||

|
||||
While you're there, you can also install Python 3 and Git if needed.
|
||||
|
||||
1. Clone the Ship of Harkinian repository
|
||||
2. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice
|
||||
|
||||
_Note: Instructions assume using powershell_
|
||||
```powershell
|
||||
# Navigate to the Shipwright repo within powershell. ie: cd "C:\yourpath\Shipwright"
|
||||
cd Shipwright
|
||||
|
||||
# Setup cmake project
|
||||
& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v142 -A x64 # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging)
|
||||
# or for VS2019
|
||||
& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 16 2019" -T v142 -A x64
|
||||
# Extract assets & generate OTR (run this anytime you need to regenerate OTR)
|
||||
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target ExtractAssets # --config Release (if you're packaging)
|
||||
# Compile project
|
||||
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 # --config Release (if you're packaging)
|
||||
|
||||
# Now you can run the executable in .\build\x64
|
||||
|
||||
# If you need to clean the project you can run
|
||||
& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target clean
|
||||
```
|
||||
|
||||
### Developing SoH
|
||||
With the cmake build system you have two options for working on the project:
|
||||
|
||||
#### Visual Studio
|
||||
To develop using Visual Studio you only need to use cmake to generate the solution file:
|
||||
```powershell
|
||||
# Generates Ship.sln at `build/x64` for Visual Studio 2022
|
||||
& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v142 -A x64
|
||||
# or for Visual Studio 2019
|
||||
& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 16 2019" -T v142 -A x64
|
||||
```
|
||||
|
||||
#### Visual Studio Code or another editor
|
||||
To develop using Visual Studio Code or another editor you only need to open the repository in it.
|
||||
To build you'll need to follow the instructions from the building section.
|
||||
|
||||
_Note: If you're using Visual Studio Code, the [cpack plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) makes it very easy to just press run and debug._
|
||||
|
||||
_Experimental: You can also use another build system entirely rather than MSVC like [Ninja](https://ninja-build.org/) for possibly better performance._
|
||||
|
||||
|
||||
### Generating the distributable
|
||||
After compiling the project you can generate the distributable by running:
|
||||
```powershell
|
||||
# Go to build folder
|
||||
cd "build/x64"
|
||||
# Generate
|
||||
& 'C:\Program Files\CMake\bin\cpack.exe' -G ZIP
|
||||
```
|
||||
|
||||
## Linux
|
||||
Requires `gcc >= 10, x11, curl, python3, sdl2 >= 2.0.22, libpng, glew >= 2.2, ninja, cmake, lld`
|
||||
|
||||
**Important: For maximum performance make sure you have ninja build tools installed!**
|
||||
|
||||
_Note: If you're using Visual Studio Code, the [cpack plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) makes it very easy to just press run and debug._
|
||||
|
||||
```bash
|
||||
# Clone the repo
|
||||
@@ -25,48 +87,112 @@ git clone https://github.com/HarbourMasters/Shipwright.git
|
||||
cd Shipwright
|
||||
# Copy the baserom to the OTRExporter folder
|
||||
cp <path to your ROM> OTRExporter
|
||||
# Build the docker image
|
||||
sudo docker build . -t soh
|
||||
# Run the docker image with the working directory mounted to /soh
|
||||
sudo docker run --rm -it -v $(pwd):/soh soh /bin/bash
|
||||
```
|
||||
Inside the Docker container:
|
||||
```bash
|
||||
# Clone and build StormLib
|
||||
git clone https://github.com/ladislav-zezula/StormLib external/StormLib
|
||||
cmake -B external/StormLib/build -S external/StormLib
|
||||
cmake --build external/StormLib/build
|
||||
cp external/StormLib/build/libstorm.a external
|
||||
cp /usr/local/lib/libGLEW.a external
|
||||
# Generate Ninja project
|
||||
cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging)
|
||||
# Extract assets & generate OTR (run this anytime you need to regenerate OTR)
|
||||
cmake --build build-cmake --target ExtractAssets
|
||||
# Compile the project
|
||||
cmake --build build-cmake # --config Release (if you're packaging)
|
||||
|
||||
cd soh
|
||||
# Extract the assets/Compile the exporter/Run the exporter
|
||||
make setup -j$(nproc) OPTFLAGS=-O2 DEBUG=0
|
||||
# Compile the code
|
||||
make -j $(nproc) OPTFLAGS=-O2 DEBUG=0
|
||||
# Now you can run the executable in ./build-cmake/soh/soh.elf
|
||||
# To develop the project open the repository in VSCode (or your preferred editor)
|
||||
|
||||
# If you need to clean the project you can run
|
||||
cmake --build build-cmake --target clean
|
||||
```
|
||||
|
||||
### Generating a distributable
|
||||
After compiling the project you can generate a distributable by running of the following:
|
||||
```bash
|
||||
# Go to build folder
|
||||
cd build-cmake
|
||||
# Generate
|
||||
cpack -G DEB
|
||||
cpack -G ZIP
|
||||
cpack -G External (creates appimage)
|
||||
```
|
||||
|
||||
## macOS
|
||||
Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, ninja, cmake` (can be installed via homebrew, macports, etc)
|
||||
|
||||
**Important: For maximum performance make sure you have ninja build tools installed!**
|
||||
|
||||
_Note: If you're using Visual Studio Code, the [cpack plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) makes it very easy to just press run and debug._
|
||||
|
||||
1. Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, dylibbundler` (can be installed via brew, etc)
|
||||
```bash
|
||||
# Clone the repo
|
||||
git clone https://github.com/HarbourMasters/Shipwright.git
|
||||
cd ShipWright
|
||||
# Copy the baserom to the OTRExporter folder
|
||||
cp <path to your ROM> OTRExporter
|
||||
# Generate Ninja project
|
||||
cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging)
|
||||
# Extract assets & generate OTR (run this anytime you need to regenerate OTR)
|
||||
cmake --build build-cmake --target ExtractAssets
|
||||
# Compile the project
|
||||
cmake --build build-cmake # --config Release (if you're packaging)
|
||||
|
||||
cd soh
|
||||
# Extract the assets/Compile the exporter/Run the exporter
|
||||
# -jX defines number of cores to use for compilation - lower or remove entirely if having issues
|
||||
make setup -j8 DEBUG=0
|
||||
# Compile the code (watch the -j parameter as above)
|
||||
make -j8 DEBUG=0
|
||||
# Create macOS app bundle
|
||||
make appbundle
|
||||
# Copy oot.otr into the Application Support directory
|
||||
cp build-cmake/soh/oot.otr ~/Library/Application\ Support/com.shipofharkinian.soh/
|
||||
|
||||
# Now you can run the executable file:
|
||||
./build-cmake/soh/soh-macos
|
||||
# To develop the project open the repository in VSCode (or your preferred editor)
|
||||
|
||||
# If you need to clean the project you can run
|
||||
cmake --build build-cmake --target clean
|
||||
```
|
||||
|
||||
### Generating a distributable
|
||||
After compiling the project you can generate a distributable by running of the following:
|
||||
```bash
|
||||
# Go to build folder
|
||||
cd build-cmake
|
||||
# Generate
|
||||
cpack
|
||||
```
|
||||
|
||||
## Switch
|
||||
1. Requires that your build machine is setup with the tools necessary for your platform above
|
||||
2. Requires that you have the switch build tools installed
|
||||
3. Clone the Ship of Harkinian repository
|
||||
4. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice
|
||||
|
||||
```bash
|
||||
cd Shipwright
|
||||
# Setup cmake project for your host machine
|
||||
cmake -H. -Bbuild-cmake -GNinja
|
||||
# Extract assets & generate OTR (run this anytime you need to regenerate OTR)
|
||||
cmake --build build-cmake --target ExtractAssets
|
||||
# Setup cmake project for building for Switch
|
||||
cmake -H. -Bbuild-switch -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/Switch.cmake
|
||||
# Build project and generate nro
|
||||
cmake --build build-switch --target soh_nro
|
||||
|
||||
# Now you can run the executable in ./build-switch/soh/soh.nro
|
||||
# To develop the project open the repository in VSCode (or your preferred editor)
|
||||
```
|
||||
|
||||
## Wii U
|
||||
1. Requires that your build machine is setup with the tools necessary for your platform above
|
||||
2. Requires that you have the Wii U build tools installed
|
||||
3. Clone the Ship of Harkinian repository
|
||||
4. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice
|
||||
|
||||
```bash
|
||||
cd Shipwright
|
||||
# Setup cmake project for your host machine
|
||||
cmake -H. -Bbuild-cmake -GNinja
|
||||
# Extract assets & generate OTR (run this anytime you need to regenerate OTR)
|
||||
cmake --build build-cmake --target ExtractAssets
|
||||
# Setup cmake project for building for Wii U
|
||||
cmake -H. -Bbuild-wiiu -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/WiiU.cmake # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging)
|
||||
# Build project and generate rpx
|
||||
cmake --build build-wiiu --target soh # --target soh_wuhb (for building .wuhb)
|
||||
|
||||
# Now you can run the executable in ./build-wiiu/soh/soh.rpx or the Wii U Homebrew Bundle in ./build-wiiu/soh/soh.wuhb
|
||||
# To develop the project open the repository in VSCode (or your preferred editor)
|
||||
```
|
||||
9. Copy your OTR file to ~/Library/Application\ Support/com.shipofharkinian.soh
|
||||
10. Launch soh app in the soh folder!
|
||||
|
||||
# Compatible Roms
|
||||
```
|
||||
@@ -85,4 +211,3 @@ Use the `extract_assets.py` script file to run the exporter using any of the fol
|
||||
4) In a terminal run `python3 extract_assets.py <path_to_rom>`
|
||||
|
||||
If the script finds multiple roms the user is prompted which to use. Selection is done using the number keys and then pressing the carriage return key.
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
################################################################################
|
||||
# Command for variable_watch. This command issues error message, if a variable
|
||||
# is changed. If variable PROPERTY_READER_GUARD_DISABLED is TRUE nothing happens
|
||||
# variable_watch(<variable> property_reader_guard)
|
||||
################################################################################
|
||||
function(property_reader_guard VARIABLE ACCESS VALUE CURRENT_LIST_FILE STACK)
|
||||
if("${PROPERTY_READER_GUARD_DISABLED}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if("${ACCESS}" STREQUAL "MODIFIED_ACCESS")
|
||||
message(FATAL_ERROR
|
||||
" Variable ${VARIABLE} is not supposed to be changed.\n"
|
||||
" It is used only for reading target property ${VARIABLE}.\n"
|
||||
" Use\n"
|
||||
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}\" \"<value>\")\n"
|
||||
" or\n"
|
||||
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}_<CONFIG>\" \"<value>\")\n"
|
||||
" instead.\n")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Create variable <name> with generator expression that expands to value of
|
||||
# target property <name>_<CONFIG>. If property is empty or not set then property
|
||||
# <name> is used instead. Variable <name> has watcher property_reader_guard that
|
||||
# doesn't allow to edit it.
|
||||
# create_property_reader(<name>)
|
||||
# Input:
|
||||
# name - Name of watched property and output variable
|
||||
################################################################################
|
||||
function(create_property_reader NAME)
|
||||
set(PROPERTY_READER_GUARD_DISABLED TRUE)
|
||||
set(CONFIG_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}_$<UPPER_CASE:$<CONFIG>>>>")
|
||||
set(IS_CONFIG_VALUE_EMPTY "$<STREQUAL:${CONFIG_VALUE},>")
|
||||
set(GENERAL_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}>>")
|
||||
set("${NAME}" "$<IF:${IS_CONFIG_VALUE_EMPTY},${GENERAL_VALUE},${CONFIG_VALUE}>" PARENT_SCOPE)
|
||||
variable_watch("${NAME}" property_reader_guard)
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Set property $<name>_${PROPS_CONFIG_U} of ${PROPS_TARGET} to <value>
|
||||
# set_config_specific_property(<name> <value>)
|
||||
# Input:
|
||||
# name - Prefix of property name
|
||||
# value - New value
|
||||
################################################################################
|
||||
function(set_config_specific_property NAME VALUE)
|
||||
set_target_properties("${PROPS_TARGET}" PROPERTIES "${NAME}_${PROPS_CONFIG_U}" "${VALUE}")
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
|
||||
create_property_reader("TARGET_NAME")
|
||||
create_property_reader("OUTPUT_DIRECTORY")
|
||||
|
||||
set_config_specific_property("TARGET_NAME" "${PROPS_TARGET}")
|
||||
set_config_specific_property("OUTPUT_NAME" "${TARGET_NAME}")
|
||||
set_config_specific_property("ARCHIVE_OUTPUT_NAME" "${TARGET_NAME}")
|
||||
set_config_specific_property("LIBRARY_OUTPUT_NAME" "${TARGET_NAME}")
|
||||
set_config_specific_property("RUNTIME_OUTPUT_NAME" "${TARGET_NAME}")
|
||||
|
||||
set_config_specific_property("ARCHIVE_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
|
||||
set_config_specific_property("LIBRARY_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
|
||||
set_config_specific_property("RUNTIME_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
|
||||
@@ -0,0 +1,12 @@
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/Default.cmake")
|
||||
|
||||
set_config_specific_property("OUTPUT_DIRECTORY" "${CMAKE_SOURCE_DIR}$<$<NOT:$<STREQUAL:${CMAKE_VS_PLATFORM_NAME},Win32>>:/${CMAKE_VS_PLATFORM_NAME}>/${PROPS_CONFIG}")
|
||||
|
||||
if(MSVC)
|
||||
create_property_reader("DEFAULT_CXX_EXCEPTION_HANDLING")
|
||||
create_property_reader("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT")
|
||||
|
||||
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
|
||||
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
|
||||
endif()
|
||||
@@ -0,0 +1,30 @@
|
||||
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
|
||||
set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY 0)
|
||||
set(CPACK_COMPONENTS_ALL "ship" "appimage")
|
||||
|
||||
if (NOT CPACK_GENERATOR STREQUAL "External")
|
||||
list(REMOVE_ITEM CPACK_COMPONENTS_ALL "appimage")
|
||||
endif()
|
||||
|
||||
if (CPACK_GENERATOR MATCHES "DEB|RPM")
|
||||
# https://unix.stackexchange.com/a/11552/254512
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/ship/bin")#/${CMAKE_PROJECT_VERSION}")
|
||||
set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY 0)
|
||||
elseif (CPACK_GENERATOR MATCHES "ZIP")
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX "")
|
||||
endif()
|
||||
|
||||
if (CPACK_GENERATOR MATCHES "External")
|
||||
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
|
||||
SET(CPACK_MONOLITHIC_INSTALL 1)
|
||||
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/bin")
|
||||
endif()
|
||||
|
||||
if (CPACK_GENERATOR MATCHES "Bundle")
|
||||
set(CPACK_BUNDLE_NAME "soh")
|
||||
set(CPACK_BUNDLE_PLIST "macosx/Info.plist")
|
||||
set(CPACK_BUNDLE_ICON "macosx/soh.icns")
|
||||
set(CPACK_BUNDLE_STARTUP_COMMAND "../soh/macosx/soh-macos.sh")
|
||||
set(CPACK_BUNDLE_APPLE_CERT_APP "-")
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
# these are cache variables, so they could be overwritten with -D,
|
||||
|
||||
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}"
|
||||
CACHE STRING "The resulting package name"
|
||||
)
|
||||
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Simple C++ application"
|
||||
CACHE STRING "Package description for the package metadata"
|
||||
)
|
||||
set(CPACK_PACKAGE_VENDOR "Some Company")
|
||||
|
||||
set(CPACK_VERBATIM_VARIABLES YES)
|
||||
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
|
||||
SET(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_SOURCE_DIR}/_packages")
|
||||
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
|
||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
set(CPACK_PACKAGE_CONTACT "YOUR@E-MAIL.net")
|
||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "YOUR NAME")
|
||||
|
||||
#set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(CPACK_SYSTEM_NAME ${LSB_RELEASE_CODENAME_SHORT})
|
||||
# package name for deb
|
||||
# if set, then instead of some-application-0.9.2-Linux.deb
|
||||
# you'll get some-application_0.9.2_amd64.deb (note the underscores too)
|
||||
#set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
|
||||
execute_process(COMMAND dpkg --print-architecture OUTPUT_VARIABLE ARCHITECTURE OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set( CPACK_DEBIAN_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}-${ARCHITECTURE}.deb )
|
||||
# if you want every group to have its own package,
|
||||
# although the same happens if this is not sent (so it defaults to ONE_PER_GROUP)
|
||||
# and CPACK_DEB_COMPONENT_INSTALL is set to YES
|
||||
set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE)#ONE_PER_GROUP)
|
||||
# without this you won't be able to pack only specified component
|
||||
set(CPACK_DEB_COMPONENT_INSTALL YES)
|
||||
|
||||
set(CPACK_EXTERNAL_ENABLE_STAGING YES)
|
||||
set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${PROJECT_BINARY_DIR}/appimage-generate.cmake")
|
||||
|
||||
file(GENERATE
|
||||
OUTPUT "${PROJECT_BINARY_DIR}/appimage-generate.cmake"
|
||||
CONTENT [[
|
||||
include(CMakePrintHelpers)
|
||||
cmake_print_variables(CPACK_TEMPORARY_DIRECTORY)
|
||||
cmake_print_variables(CPACK_TOPLEVEL_DIRECTORY)
|
||||
cmake_print_variables(CPACK_PACKAGE_DIRECTORY)
|
||||
cmake_print_variables(CPACK_PACKAGE_FILE_NAME)
|
||||
|
||||
find_program(LINUXDEPLOY_EXECUTABLE
|
||||
NAMES linuxdeploy linuxdeploy-x86_64.AppImage
|
||||
PATHS ${CPACK_PACKAGE_DIRECTORY}/linuxdeploy)
|
||||
|
||||
if (NOT LINUXDEPLOY_EXECUTABLE)
|
||||
message(STATUS "Downloading linuxdeploy")
|
||||
set(LINUXDEPLOY_EXECUTABLE ${CPACK_PACKAGE_DIRECTORY}/linuxdeploy/linuxdeploy)
|
||||
file(DOWNLOAD
|
||||
https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
${LINUXDEPLOY_EXECUTABLE}
|
||||
INACTIVITY_TIMEOUT 10
|
||||
LOG ${CPACK_PACKAGE_DIRECTORY}/linuxdeploy/download.log
|
||||
STATUS LINUXDEPLOY_DOWNLOAD)
|
||||
execute_process(COMMAND chmod +x ${LINUXDEPLOY_EXECUTABLE} COMMAND_ECHO STDOUT)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E env
|
||||
OUTPUT=${CPACK_PACKAGE_FILE_NAME}.appimage
|
||||
VERSION=$<IF:$<BOOL:${CPACK_PACKAGE_VERSION}>,${CPACK_PACKAGE_VERSION},0.1.0>
|
||||
${LINUXDEPLOY_EXECUTABLE}
|
||||
--appimage-extract-and-run
|
||||
--appdir=${CPACK_TEMPORARY_DIRECTORY}
|
||||
--executable=$<TARGET_FILE:soh>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:soh,APPIMAGE_DESKTOP_FILE>>:--desktop-file=$<TARGET_PROPERTY:soh,APPIMAGE_DESKTOP_FILE>>
|
||||
$<$<BOOL:$<TARGET_PROPERTY:soh,APPIMAGE_ICON_FILE>>:--icon-file=$<TARGET_PROPERTY:soh,APPIMAGE_ICON_FILE>>
|
||||
--output=appimage
|
||||
# --verbosity=2
|
||||
)
|
||||
]])
|
||||
|
||||
endif()
|
||||
|
||||
include(CPack)
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
# utils file for projects came from visual studio solution with cmake-converter.
|
||||
|
||||
################################################################################
|
||||
# Wrap each token of the command with condition
|
||||
################################################################################
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
macro(prepare_commands)
|
||||
unset(TOKEN_ROLE)
|
||||
unset(COMMANDS)
|
||||
foreach(TOKEN ${ARG_COMMANDS})
|
||||
if("${TOKEN}" STREQUAL "COMMAND")
|
||||
set(TOKEN_ROLE "KEYWORD")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "KEYWORD")
|
||||
set(TOKEN_ROLE "CONDITION")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
|
||||
set(TOKEN_ROLE "COMMAND")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
|
||||
set(TOKEN_ROLE "ARG")
|
||||
endif()
|
||||
|
||||
if("${TOKEN_ROLE}" STREQUAL "KEYWORD")
|
||||
list(APPEND COMMANDS "${TOKEN}")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
|
||||
set(CONDITION ${TOKEN})
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
|
||||
list(APPEND COMMANDS "$<$<NOT:${CONDITION}>:${DUMMY}>$<${CONDITION}:${TOKEN}>")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "ARG")
|
||||
list(APPEND COMMANDS "$<${CONDITION}:${TOKEN}>")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
cmake_policy(POP)
|
||||
|
||||
################################################################################
|
||||
# Transform all the tokens to absolute paths
|
||||
################################################################################
|
||||
macro(prepare_output)
|
||||
unset(OUTPUT)
|
||||
foreach(TOKEN ${ARG_OUTPUT})
|
||||
if(IS_ABSOLUTE ${TOKEN})
|
||||
list(APPEND OUTPUT "${TOKEN}")
|
||||
else()
|
||||
list(APPEND OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${TOKEN}")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
################################################################################
|
||||
# Parse add_custom_command_if args.
|
||||
#
|
||||
# Input:
|
||||
# PRE_BUILD - Pre build event option
|
||||
# PRE_LINK - Pre link event option
|
||||
# POST_BUILD - Post build event option
|
||||
# TARGET - Target
|
||||
# OUTPUT - List of output files
|
||||
# DEPENDS - List of files on which the command depends
|
||||
# COMMANDS - List of commands(COMMAND condition1 commannd1 args1 COMMAND
|
||||
# condition2 commannd2 args2 ...)
|
||||
# Output:
|
||||
# OUTPUT - Output files
|
||||
# DEPENDS - Files on which the command depends
|
||||
# COMMENT - Comment
|
||||
# PRE_BUILD - TRUE/FALSE
|
||||
# PRE_LINK - TRUE/FALSE
|
||||
# POST_BUILD - TRUE/FALSE
|
||||
# TARGET - Target name
|
||||
# COMMANDS - Prepared commands(every token is wrapped in CONDITION)
|
||||
# NAME - Unique name for custom target
|
||||
# STEP - PRE_BUILD/PRE_LINK/POST_BUILD
|
||||
################################################################################
|
||||
function(add_custom_command_if_parse_arguments)
|
||||
cmake_parse_arguments("ARG" "PRE_BUILD;PRE_LINK;POST_BUILD" "TARGET;COMMENT" "DEPENDS;OUTPUT;COMMANDS" ${ARGN})
|
||||
|
||||
if(WIN32)
|
||||
set(DUMMY "cd.")
|
||||
elseif(UNIX)
|
||||
set(DUMMY "true")
|
||||
endif()
|
||||
|
||||
prepare_commands()
|
||||
prepare_output()
|
||||
|
||||
set(DEPENDS "${ARG_DEPENDS}")
|
||||
set(COMMENT "${ARG_COMMENT}")
|
||||
set(PRE_BUILD "${ARG_PRE_BUILD}")
|
||||
set(PRE_LINK "${ARG_PRE_LINK}")
|
||||
set(POST_BUILD "${ARG_POST_BUILD}")
|
||||
set(TARGET "${ARG_TARGET}")
|
||||
if(PRE_BUILD)
|
||||
set(STEP "PRE_BUILD")
|
||||
elseif(PRE_LINK)
|
||||
set(STEP "PRE_LINK")
|
||||
elseif(POST_BUILD)
|
||||
set(STEP "POST_BUILD")
|
||||
endif()
|
||||
set(NAME "${TARGET}_${STEP}")
|
||||
|
||||
set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
|
||||
set(DEPENDS "${DEPENDS}" PARENT_SCOPE)
|
||||
set(COMMENT "${COMMENT}" PARENT_SCOPE)
|
||||
set(PRE_BUILD "${PRE_BUILD}" PARENT_SCOPE)
|
||||
set(PRE_LINK "${PRE_LINK}" PARENT_SCOPE)
|
||||
set(POST_BUILD "${POST_BUILD}" PARENT_SCOPE)
|
||||
set(TARGET "${TARGET}" PARENT_SCOPE)
|
||||
set(COMMANDS "${COMMANDS}" PARENT_SCOPE)
|
||||
set(STEP "${STEP}" PARENT_SCOPE)
|
||||
set(NAME "${NAME}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Add conditional custom command
|
||||
#
|
||||
# Generating Files
|
||||
# The first signature is for adding a custom command to produce an output:
|
||||
# add_custom_command_if(
|
||||
# <OUTPUT output1 [output2 ...]>
|
||||
# <COMMANDS>
|
||||
# <COMMAND condition command1 [args1...]>
|
||||
# [COMMAND condition command2 [args2...]]
|
||||
# [DEPENDS [depends...]]
|
||||
# [COMMENT comment]
|
||||
#
|
||||
# Build Events
|
||||
# add_custom_command_if(
|
||||
# <TARGET target>
|
||||
# <PRE_BUILD | PRE_LINK | POST_BUILD>
|
||||
# <COMMAND condition command1 [args1...]>
|
||||
# [COMMAND condition command2 [args2...]]
|
||||
# [COMMENT comment]
|
||||
#
|
||||
# Input:
|
||||
# output - Output files the command is expected to produce
|
||||
# condition - Generator expression for wrapping the command
|
||||
# command - Command-line(s) to execute at build time.
|
||||
# args - Command`s args
|
||||
# depends - Files on which the command depends
|
||||
# comment - Display the given message before the commands are executed at
|
||||
# build time.
|
||||
# PRE_BUILD - Run before any other rules are executed within the target
|
||||
# PRE_LINK - Run after sources have been compiled but before linking the
|
||||
# binary
|
||||
# POST_BUILD - Run after all other rules within the target have been
|
||||
# executed
|
||||
################################################################################
|
||||
function(add_custom_command_if)
|
||||
add_custom_command_if_parse_arguments(${ARGN})
|
||||
|
||||
if(OUTPUT AND TARGET)
|
||||
message(FATAL_ERROR "Wrong syntax. A TARGET and OUTPUT can not both be specified.")
|
||||
endif()
|
||||
|
||||
if(OUTPUT)
|
||||
add_custom_command(OUTPUT ${OUTPUT}
|
||||
${COMMANDS}
|
||||
DEPENDS ${DEPENDS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT ${COMMENT})
|
||||
elseif(TARGET)
|
||||
if(PRE_BUILD AND NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio")
|
||||
add_custom_target(
|
||||
${NAME}
|
||||
${COMMANDS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT ${COMMENT})
|
||||
add_dependencies(${TARGET} ${NAME})
|
||||
else()
|
||||
add_custom_command(
|
||||
TARGET ${TARGET}
|
||||
${STEP}
|
||||
${COMMANDS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT ${COMMENT})
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Wrong syntax. A TARGET or OUTPUT must be specified.")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Use props file for a target and configs
|
||||
# use_props(<target> <configs...> <props_file>)
|
||||
# Inside <props_file> there are following variables:
|
||||
# PROPS_TARGET - <target>
|
||||
# PROPS_CONFIG - One of <configs...>
|
||||
# PROPS_CONFIG_U - Uppercase PROPS_CONFIG
|
||||
# Input:
|
||||
# target - Target to apply props file
|
||||
# configs - Build configurations to apply props file
|
||||
# props_file - CMake script
|
||||
################################################################################
|
||||
macro(use_props TARGET CONFIGS PROPS_FILE)
|
||||
set(PROPS_TARGET "${TARGET}")
|
||||
foreach(PROPS_CONFIG ${CONFIGS})
|
||||
string(TOUPPER "${PROPS_CONFIG}" PROPS_CONFIG_U)
|
||||
|
||||
get_filename_component(ABSOLUTE_PROPS_FILE "${PROPS_FILE}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||
if(EXISTS "${ABSOLUTE_PROPS_FILE}")
|
||||
include("${ABSOLUTE_PROPS_FILE}")
|
||||
else()
|
||||
message(WARNING "Corresponding cmake file from props \"${ABSOLUTE_PROPS_FILE}\" doesn't exist")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
################################################################################
|
||||
# Add compile options to source file
|
||||
# source_file_compile_options(<source_file> [compile_options...])
|
||||
# Input:
|
||||
# source_file - Source file
|
||||
# compile_options - Options to add to COMPILE_FLAGS property
|
||||
################################################################################
|
||||
function(source_file_compile_options SOURCE_FILE)
|
||||
if("${ARGC}" LESS_EQUAL "1")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_source_file_property(COMPILE_OPTIONS "${SOURCE_FILE}" COMPILE_OPTIONS)
|
||||
|
||||
if(COMPILE_OPTIONS)
|
||||
list(APPEND COMPILE_OPTIONS ${ARGN})
|
||||
else()
|
||||
set(COMPILE_OPTIONS "${ARGN}")
|
||||
endif()
|
||||
|
||||
set_source_files_properties("${SOURCE_FILE}" PROPERTIES COMPILE_OPTIONS "${COMPILE_OPTIONS}")
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Default properties of visual studio projects
|
||||
################################################################################
|
||||
set(DEFAULT_CXX_PROPS "${CMAKE_CURRENT_LIST_DIR}/DefaultCXX.cmake")
|
||||
|
||||
function(get_linux_lsb_release_information)
|
||||
find_program(LSB_RELEASE_EXEC lsb_release)
|
||||
if(NOT LSB_RELEASE_EXEC)
|
||||
message(FATAL_ERROR "Could not detect lsb_release executable, can not gather required information")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --id OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --codename OUTPUT_VARIABLE LSB_RELEASE_CODENAME_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
set(LSB_RELEASE_ID_SHORT "${LSB_RELEASE_ID_SHORT}" PARENT_SCOPE)
|
||||
set(LSB_RELEASE_VERSION_SHORT "${LSB_RELEASE_VERSION_SHORT}" PARENT_SCOPE)
|
||||
set(LSB_RELEASE_CODENAME_SHORT "${LSB_RELEASE_CODENAME_SHORT}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,191 @@
|
||||
#------------------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# Automate-VCPKG by Andre Taulien
|
||||
# ===============================
|
||||
#
|
||||
# Project Repository: https://github.com/REGoth-project/Automate-VCPKG
|
||||
# License ..........: MIT, see end of file.
|
||||
#
|
||||
# Based on: https://github.com/sutambe/cpptruths/blob/vcpkg_cmake_blog/cpp0x/vcpkg_test/CMakeLists.txt
|
||||
#
|
||||
#
|
||||
# While [Vcpkg](https://github.com/microsoft/vcpkg) on it's own is awesome, it does add
|
||||
# a little bit of complexity to getting a project to build. Even more if the one trying
|
||||
# to compile your application is not too fond of the commandline. Additionally, CMake
|
||||
# commands tend to get rather long with the toolchain path.
|
||||
#
|
||||
# To keep things simple for new users who just want to get the project to build, this
|
||||
# script offers a solution.
|
||||
#
|
||||
# Lets assume your main `CMakelists.txt` looks something like this:
|
||||
#
|
||||
# cmake_minimum_required (VERSION 3.12.0)
|
||||
# project (MyProject)
|
||||
#
|
||||
# add_executable(MyExecutable main.c)
|
||||
#
|
||||
# To integrate Vcpkg into that `CMakelists.txt`, simple put the following lines before the
|
||||
# call to `project(MyProject)`:
|
||||
#
|
||||
# include(cmake/automate-vcpkg.cmake)
|
||||
#
|
||||
# vcpkg_bootstrap()
|
||||
# vcpkg_install_packages(libsquish physfs)
|
||||
#
|
||||
# The call to `vcpkg_bootstrap()` will clone the official Vcpkg repository and bootstrap it.
|
||||
# If it detected an existing environment variable defining a valid `VCPKG_ROOT`, it will
|
||||
# update the existing installation of Vcpkg.
|
||||
#
|
||||
# Arguments to `vcpkg_install_packages()` are the packages you want to install using Vcpkg.
|
||||
#
|
||||
# If you want to keep the possibility for users to chose their own copy of Vcpkg, you can
|
||||
# simply not run the code snippet mentioned above, something like this will work:
|
||||
#
|
||||
# option(SKIP_AUTOMATE_VCPKG "When ON, you will need to built the packages
|
||||
# required by MyProject on your own or supply your own vcpkg toolchain.")
|
||||
#
|
||||
# if (NOT SKIP_AUTOMATE_VCPKG)
|
||||
# include(cmake/automate-vcpkg.cmake)
|
||||
#
|
||||
# vcpkg_bootstrap()
|
||||
# vcpkg_install_packages(libsquish physfs)
|
||||
# endif()
|
||||
#
|
||||
# Then, the user has to supply the packages on their own, be it through Vcpkg or manually
|
||||
# specifying their locations.
|
||||
#------------------------------------------------------------------------------------------------------------
|
||||
|
||||
cmake_minimum_required (VERSION 3.12)
|
||||
|
||||
if(WIN32)
|
||||
set(VCPKG_FALLBACK_ROOT ${CMAKE_CURRENT_BINARY_DIR}/vcpkg CACHE STRING "vcpkg configuration directory to use if vcpkg was not installed on the system before")
|
||||
else()
|
||||
set(VCPKG_FALLBACK_ROOT ${CMAKE_CURRENT_BINARY_DIR}/.vcpkg CACHE STRING "vcpkg configuration directory to use if vcpkg was not installed on the system before")
|
||||
endif()
|
||||
|
||||
# On Windows, Vcpkg defaults to x86, even on x64 systems. If we're
|
||||
# doing a 64-bit build, we need to fix that.
|
||||
if (WIN32)
|
||||
|
||||
# Since the compiler checks haven't run yet, we need to figure
|
||||
# out the value of CMAKE_SIZEOF_VOID_P ourselfs
|
||||
|
||||
include(CheckTypeSize)
|
||||
enable_language(C)
|
||||
check_type_size("void*" SIZEOF_VOID_P BUILTIN_TYPES_ONLY)
|
||||
|
||||
if (SIZEOF_VOID_P EQUAL 8)
|
||||
message(STATUS "Using Vcpkg triplet 'x64-windows'")
|
||||
|
||||
set(VCPKG_TRIPLET x64-windows)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED VCPKG_ROOT)
|
||||
if(NOT DEFINED ENV{VCPKG_ROOT})
|
||||
set(VCPKG_ROOT ${VCPKG_FALLBACK_ROOT})
|
||||
else()
|
||||
set(VCPKG_ROOT $ENV{VCPKG_ROOT})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Installs a new copy of Vcpkg or updates an existing one
|
||||
macro(vcpkg_bootstrap)
|
||||
_install_or_update_vcpkg()
|
||||
|
||||
# Find out whether the user supplied their own VCPKG toolchain file
|
||||
if(NOT DEFINED ${CMAKE_TOOLCHAIN_FILE})
|
||||
# We know this wasn't set before so we need point the toolchain file to the newly found VCPKG_ROOT
|
||||
set(CMAKE_TOOLCHAIN_FILE ${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake CACHE STRING "")
|
||||
|
||||
# Just setting vcpkg.cmake as toolchain file does not seem to actually pull in the code
|
||||
include(${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
|
||||
|
||||
set(AUTOMATE_VCPKG_USE_SYSTEM_VCPKG OFF)
|
||||
else()
|
||||
# VCPKG_ROOT has been defined by the toolchain file already
|
||||
set(AUTOMATE_VCPKG_USE_SYSTEM_VCPKG ON)
|
||||
endif()
|
||||
|
||||
message(STATUS "Automate VCPKG status:")
|
||||
message(STATUS " VCPKG_ROOT.....: ${VCPKG_ROOT}")
|
||||
message(STATUS " VCPKG_EXEC.....: ${VCPKG_EXEC}")
|
||||
message(STATUS " VCPKG_BOOTSTRAP: ${VCPKG_BOOTSTRAP}")
|
||||
endmacro()
|
||||
|
||||
macro(_install_or_update_vcpkg)
|
||||
if(NOT EXISTS ${VCPKG_ROOT})
|
||||
message(STATUS "Cloning vcpkg in ${VCPKG_ROOT}")
|
||||
execute_process(COMMAND git clone https://github.com/Microsoft/vcpkg.git ${VCPKG_ROOT})
|
||||
|
||||
# If a reproducible build is desired (and potentially old libraries are # ok), uncomment the
|
||||
# following line and pin the vcpkg repository to a specific githash.
|
||||
# execute_process(COMMAND git checkout 745a0aea597771a580d0b0f4886ea1e3a94dbca6 WORKING_DIRECTORY ${VCPKG_ROOT})
|
||||
else()
|
||||
# The following command has no effect if the vcpkg repository is in a detached head state.
|
||||
message(STATUS "Auto-updating vcpkg in ${VCPKG_ROOT}")
|
||||
execute_process(COMMAND git pull WORKING_DIRECTORY ${VCPKG_ROOT})
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${VCPKG_ROOT}/README.md)
|
||||
message(FATAL_ERROR "***** FATAL ERROR: Could not clone vcpkg *****")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(VCPKG_EXEC ${VCPKG_ROOT}/vcpkg.exe)
|
||||
set(VCPKG_BOOTSTRAP ${VCPKG_ROOT}/bootstrap-vcpkg.bat)
|
||||
else()
|
||||
set(VCPKG_EXEC ${VCPKG_ROOT}/vcpkg)
|
||||
set(VCPKG_BOOTSTRAP ${VCPKG_ROOT}/bootstrap-vcpkg.sh)
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${VCPKG_EXEC})
|
||||
message("Bootstrapping vcpkg in ${VCPKG_ROOT}")
|
||||
execute_process(COMMAND ${VCPKG_BOOTSTRAP} WORKING_DIRECTORY ${VCPKG_ROOT})
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${VCPKG_EXEC})
|
||||
message(FATAL_ERROR "***** FATAL ERROR: Could not bootstrap vcpkg *****")
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
# Installs the list of packages given as parameters using Vcpkg
|
||||
macro(vcpkg_install_packages)
|
||||
|
||||
# Need the given list to be space-separated
|
||||
#string (REPLACE ";" " " PACKAGES_LIST_STR "${ARGN}")
|
||||
|
||||
message(STATUS "Installing/Updating the following vcpkg-packages: ${PACKAGES_LIST_STR}")
|
||||
|
||||
if (VCPKG_TRIPLET)
|
||||
set(ENV{VCPKG_DEFAULT_TRIPLET} "${VCPKG_TRIPLET}")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${VCPKG_EXEC} install ${ARGN}
|
||||
WORKING_DIRECTORY ${VCPKG_ROOT}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2019 REGoth-project
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
|
||||
|
||||
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
#set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use") - issue with soh compile with MSVC
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE)
|
||||
|
||||
project(Ship LANGUAGES C CXX
|
||||
VERSION 4.0.4)
|
||||
set(PROJECT_BUILD_NAME "ZHORA ECHO" CACHE STRING "")
|
||||
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "")
|
||||
|
||||
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh)
|
||||
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/MP>)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
include(CMake/automate-vcpkg.cmake)
|
||||
|
||||
set(VCPKG_TRIPLET x64-windows-static)
|
||||
set(VCPKG_TARGET_TRIPLET x64-windows-static)
|
||||
|
||||
vcpkg_bootstrap()
|
||||
vcpkg_install_packages(zlib bzip2 libpng SDL2 SDL2-net GLEW glfw3)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Set target arch type if empty. Visual studio solution generator provides it.
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if(NOT CMAKE_VS_PLATFORM_NAME)
|
||||
set(CMAKE_VS_PLATFORM_NAME "x64")
|
||||
endif()
|
||||
message("${CMAKE_VS_PLATFORM_NAME} architecture in use")
|
||||
|
||||
if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64"
|
||||
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"))
|
||||
message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Global configuration types
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O3 -ffast-math")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-O3 -ffast-math")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -ffast-math -DNDEBUG")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
||||
set(CMAKE_OBJCXX_FLAGS_RELEASE "-O2 -DNDEBUG")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE )
|
||||
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Global compiler options
|
||||
################################################################################
|
||||
if(MSVC)
|
||||
# remove default flags provided with CMake for MSVC
|
||||
set(CMAKE_C_FLAGS "")
|
||||
set(CMAKE_C_FLAGS_DEBUG "")
|
||||
set(CMAKE_C_FLAGS_RELEASE "")
|
||||
set(CMAKE_CXX_FLAGS "")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "")
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Global linker options
|
||||
################################################################################
|
||||
if(MSVC)
|
||||
# remove default flags provided with CMake for MSVC
|
||||
set(CMAKE_EXE_LINKER_FLAGS "")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "${CMAKE_STATIC_LINKER_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS}")
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Common utils
|
||||
################################################################################
|
||||
include(CMake/Utils.cmake)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
get_linux_lsb_release_information()
|
||||
message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}")
|
||||
else()
|
||||
message(STATUS ${CMAKE_SYSTEM_NAME})
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Additional Global Settings(add specific info there)
|
||||
################################################################################
|
||||
include(CMake/GlobalSettingsInclude.cmake OPTIONAL)
|
||||
|
||||
################################################################################
|
||||
# Use solution folders feature
|
||||
################################################################################
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
################################################################################
|
||||
# Sub-projects
|
||||
################################################################################
|
||||
add_subdirectory(libultraship/libultraship ${CMAKE_BINARY_DIR}/libultraship)
|
||||
add_subdirectory(ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
|
||||
add_subdirectory(ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils)
|
||||
add_subdirectory(OTRExporter)
|
||||
add_subdirectory(soh)
|
||||
if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin|NintendoSwitch|CafeOS")
|
||||
add_subdirectory(OTRGui)
|
||||
endif()
|
||||
|
||||
set_property(TARGET soh PROPERTY APPIMAGE_DESKTOP_FILE_TERMINAL YES)
|
||||
set_property(TARGET soh PROPERTY APPIMAGE_DESKTOP_FILE "${CMAKE_SOURCE_DIR}/scripts/linux/appimage/soh.desktop")
|
||||
set_property(TARGET soh PROPERTY APPIMAGE_ICON_FILE "${CMAKE_BINARY_DIR}/sohIcon.png")
|
||||
|
||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||
install(PROGRAMS "${CMAKE_SOURCE_DIR}/scripts/linux/appimage/soh.sh" DESTINATION . COMPONENT appimage)
|
||||
endif()
|
||||
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
|
||||
add_custom_target(
|
||||
ExtractAssets
|
||||
# CMake versions prior to 3.17 do not have the rm command, use remove instead for older versions
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<VERSION_LESS:${CMAKE_VERSION},3.17>,remove,rm> -f oot.otr
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$<TARGET_FILE:ZAPD>"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy oot.otr ${CMAKE_SOURCE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy oot.otr ${CMAKE_BINARY_DIR}/soh
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter
|
||||
COMMENT "Running asset extraction..."
|
||||
DEPENDS ZAPD
|
||||
BYPRODUCTS oot.otr ${CMAKE_SOURCE_DIR}/oot.otr
|
||||
)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
find_package(ImageMagick COMPONENTS convert)
|
||||
if (ImageMagick_FOUND)
|
||||
execute_process (
|
||||
COMMAND ${ImageMagick_convert_EXECUTABLE} soh/macosx/sohIcon.png -resize 512x512 ${CMAKE_BINARY_DIR}/sohIcon.png
|
||||
OUTPUT_VARIABLE outVar
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
add_custom_target(CreateOSXIcons
|
||||
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/macosx/soh.iconset
|
||||
COMMAND sips -z 16 16 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16.png
|
||||
COMMAND sips -z 32 32 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_16x16@2x.png
|
||||
COMMAND sips -z 32 32 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32.png
|
||||
COMMAND sips -z 64 64 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_32x32@2x.png
|
||||
COMMAND sips -z 128 128 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128.png
|
||||
COMMAND sips -z 256 256 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_128x128@2x.png
|
||||
COMMAND sips -z 256 256 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256.png
|
||||
COMMAND sips -z 512 512 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_256x256@2x.png
|
||||
COMMAND sips -z 512 512 soh/macosx/sohIcon.png --out ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512.png
|
||||
COMMAND cp soh/macosx/sohIcon.png ${CMAKE_BINARY_DIR}/macosx/soh.iconset/icon_512x512@2x.png
|
||||
COMMAND iconutil -c icns -o ${CMAKE_BINARY_DIR}/macosx/soh.icns ${CMAKE_BINARY_DIR}/macosx/soh.iconset
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMENT "Creating OSX icons ..."
|
||||
)
|
||||
add_dependencies(soh CreateOSXIcons)
|
||||
|
||||
add_custom_target(Assets ALL
|
||||
COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_SOURCE_DIR}/OTRGui/assets/extractor" -Ddst_dir="${CMAKE_BINARY_DIR}/assets/extractor" -P "${CMAKE_SOURCE_DIR}/OTRGui/Overwrite.cmake"
|
||||
COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_SOURCE_DIR}/OTRExporter/assets" -Ddst_dir="${CMAKE_BINARY_DIR}/assets/game" -P "${CMAKE_SOURCE_DIR}/OTRGui/Overwrite.cmake"
|
||||
COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_SOURCE_DIR}/soh/assets/xml" -Ddst_dir="${CMAKE_BINARY_DIR}/assets/extractor/xmls" -P "${CMAKE_SOURCE_DIR}/OTRGui/Overwrite.cmake"
|
||||
)
|
||||
add_dependencies(soh Assets)
|
||||
|
||||
install(TARGETS ZAPD DESTINATION ${CMAKE_BINARY_DIR}/assets/extractor)
|
||||
|
||||
set(PROGRAM_PERMISSIONS_EXECUTE OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ)
|
||||
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/assets
|
||||
DESTINATION .
|
||||
PATTERN ZAPD.out
|
||||
PERMISSIONS ${PROGRAM_PERMISSIONS_EXECUTE}
|
||||
)
|
||||
|
||||
install(CODE "
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/soh-macos\" \"\" \"${dirs}\")
|
||||
")
|
||||
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS")
|
||||
install(FILES ${CMAKE_SOURCE_DIR}/README.md DESTINATION . COMPONENT ship RENAME readme.txt )
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(CPACK_GENERATOR "External")
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS")
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
set(CPACK_GENERATOR "Bundle")
|
||||
endif()
|
||||
|
||||
set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_SOURCE_DIR}/CMake/Packaging-2.cmake)
|
||||
include(CMake/Packaging.cmake)
|
||||
+36
-15
@@ -3,17 +3,18 @@ FROM ubuntu:20.04 as build
|
||||
ENV LANG C.UTF-8
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ENV GCCVER=10
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
apt-get install -y \
|
||||
binutils \
|
||||
gcc-10 \
|
||||
g++-10 \
|
||||
gcc-${GCCVER} \
|
||||
g++-${GCCVER} \
|
||||
patchelf \
|
||||
p7zip-full \
|
||||
python3.9 \
|
||||
make \
|
||||
python3 \
|
||||
cmake \
|
||||
make \
|
||||
curl \
|
||||
git \
|
||||
lld \
|
||||
@@ -21,27 +22,47 @@ RUN apt-get update && \
|
||||
zlib1g-dev \
|
||||
libbz2-dev \
|
||||
libpng-dev \
|
||||
libgles2-mesa-dev && \
|
||||
ln -s /usr/bin/g++-10 /usr/bin/g++ && \
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10 && \
|
||||
gcc --version && \
|
||||
g++ --version
|
||||
|
||||
RUN apt-get clean autoclean && apt-get autoremove --yes && rm -rf /var/lib/apt /var/lib/cache /var/lib/log
|
||||
libgles2-mesa-dev \
|
||||
wget \
|
||||
gpg \
|
||||
imagemagick \
|
||||
ninja-build && \
|
||||
apt-get install -y software-properties-common && \
|
||||
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null && \
|
||||
apt-add-repository "deb https://apt.kitware.com/ubuntu/ focal main" && \
|
||||
apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCCVER} 10 && \
|
||||
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCCVER} 10
|
||||
|
||||
RUN git clone https://github.com/Perlmint/glew-cmake.git && \
|
||||
cmake glew-cmake && \
|
||||
make -j$(nproc) && \
|
||||
make install
|
||||
|
||||
|
||||
ENV SDL2VER=2.0.22
|
||||
RUN curl -sLO https://libsdl.org/release/SDL2-${SDL2VER}.tar.gz && \
|
||||
tar -xzf SDL2-${SDL2VER}.tar.gz && \
|
||||
cd SDL2-${SDL2VER} && \
|
||||
./configure --prefix=/usr && \
|
||||
make && make install && \
|
||||
./configure --build=x86_64-linux-gnu && \
|
||||
make -j$(nproc) && make install && \
|
||||
rm ../SDL2-${SDL2VER}.tar.gz && \
|
||||
cp -av /lib/libSDL* /lib/x86_64-linux-gnu/
|
||||
cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
|
||||
|
||||
RUN \
|
||||
ln -sf /proc/self/mounts /etc/mtab && \
|
||||
mkdir -p /usr/local/share/keyring/ && \
|
||||
wget -O /usr/local/share/keyring/devkitpro-pub.gpg https://apt.devkitpro.org/devkitpro-pub.gpg && \
|
||||
echo "deb [signed-by=/usr/local/share/keyring/devkitpro-pub.gpg] https://apt.devkitpro.org stable main" > /etc/apt/sources.list.d/devkitpro.list && \
|
||||
apt-get update -y && \
|
||||
apt-get install -y devkitpro-pacman && \
|
||||
yes | dkp-pacman -Syu switch-dev switch-portlibs wiiu-dev wiiu-portlibs --noconfirm
|
||||
|
||||
ENV DEVKITPRO=/opt/devkitpro
|
||||
ENV DEVKITARM=/opt/devkitpro/devkitARM
|
||||
ENV DEVKITPPC=/opt/devkitpro/devkitPPC
|
||||
ENV PATH=$PATH:/opt/devkitpro/portlibs/switch/bin/:$DEVKITPPC/bin
|
||||
ENV WUT_ROOT=$DEVKITPRO/wut
|
||||
|
||||
RUN mkdir /soh
|
||||
WORKDIR /soh
|
||||
|
||||
Vendored
+133
-61
@@ -4,23 +4,45 @@ pipeline {
|
||||
options {
|
||||
timestamps()
|
||||
skipDefaultCheckout(true)
|
||||
disableConcurrentBuilds(abortPrevious: true)
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Generate Assets') {
|
||||
agent {
|
||||
label "SoH-Asset-Builders"
|
||||
}
|
||||
steps {
|
||||
timeout(time: 10) {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: scm.branches,
|
||||
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
|
||||
extensions: scm.extensions,
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
sh '''
|
||||
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
cmake --build build-cmake --target ExtractAssets --config Release
|
||||
'''
|
||||
stash includes: 'soh/assets/**/*', name: 'assets'
|
||||
}
|
||||
}
|
||||
post {
|
||||
unsuccessful {
|
||||
step([$class: 'WsCleanup']) // Clean workspace
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Build SoH') {
|
||||
parallel {
|
||||
stage ('Build Windows') {
|
||||
options {
|
||||
timeout(time: 20)
|
||||
}
|
||||
environment {
|
||||
MSBUILD='C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\Msbuild\\Current\\Bin\\msbuild.exe'
|
||||
CONFIG='Release'
|
||||
OTRPLATFORM='x64'
|
||||
PLATFORM='x64'
|
||||
ZIP='C:\\Program Files\\7-Zip\\7z.exe'
|
||||
PYTHON='C:\\Users\\jenkins\\AppData\\Local\\Programs\\Python\\Python310\\python.exe'
|
||||
CMAKE='C:\\Program Files\\CMake\\bin\\cmake.exe'
|
||||
CPACK='C:\\Program Files\\CMake\\bin\\cpack.exe'
|
||||
TOOLSET='v142'
|
||||
}
|
||||
agent {
|
||||
@@ -36,38 +58,19 @@ pipeline {
|
||||
])
|
||||
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
bat """
|
||||
|
||||
"${env.MSBUILD}" ".\\OTRExporter\\OTRExporter.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.OTRPLATFORM};PlatformToolset=${env.TOOLSET};RestorePackagesConfig=true /restore /nodeReuse:false /m
|
||||
|
||||
xcopy "..\\..\\ZELOOTD.z64" "OTRExporter\\"
|
||||
|
||||
cd "OTRExporter"
|
||||
"${env.PYTHON}" ".\\extract_assets.py"
|
||||
cd "..\\"
|
||||
|
||||
"${env.MSBUILD}" ".\\soh\\soh.sln" -t:build -p:Configuration=${env.CONFIG};Platform=${env.PLATFORM};PlatformToolset=${env.TOOLSET} /nodeReuse:false /m
|
||||
|
||||
cd OTRGui
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
"${env.CMAKE}" ..
|
||||
"${env.CMAKE}" --build . --config Release
|
||||
|
||||
unstash 'assets'
|
||||
bat """
|
||||
"${env.CMAKE}" -S . -B "build\\${env.PLATFORM}" -G "Visual Studio 17 2022" -T ${env.TOOLSET} -A ${env.PLATFORM} -D Python_EXECUTABLE=${env.PYTHON} -D CMAKE_BUILD_TYPE:STRING=Release
|
||||
"${env.CMAKE}" --build ".\\build\\${env.PLATFORM}" --target OTRGui --config Release
|
||||
"${env.CMAKE}" --build ".\\build\\${env.PLATFORM}" --config Release
|
||||
cd ".\\build\\${env.PLATFORM}"
|
||||
"${env.CPACK}" -G ZIP
|
||||
cd "..\\..\\"
|
||||
|
||||
move "soh\\x64\\Release\\soh.exe" ".\\"
|
||||
move "OTRGui\\build\\assets" ".\\"
|
||||
move ".\\OTRExporter\\x64\\Release\\ZAPD.exe" ".\\assets\\extractor\\"
|
||||
move ".\\OTRGui\\build\\Release\\OTRGui.exe" ".\\"
|
||||
rename README.md readme.txt
|
||||
|
||||
"${env.ZIP}" a soh.7z soh.exe OTRGui.exe assets readme.txt
|
||||
|
||||
|
||||
move "_packages\\*.zip" "soh.zip"
|
||||
"""
|
||||
archiveArtifacts artifacts: 'soh.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
archiveArtifacts artifacts: 'soh.zip', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
post {
|
||||
always {
|
||||
@@ -76,9 +79,6 @@ pipeline {
|
||||
}
|
||||
}
|
||||
stage ('Build Linux') {
|
||||
options {
|
||||
timeout(time: 20)
|
||||
}
|
||||
agent {
|
||||
label "SoH-Linux-Builders"
|
||||
}
|
||||
@@ -91,32 +91,26 @@ pipeline {
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
unstash 'assets'
|
||||
sh '''
|
||||
|
||||
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||
if docker ps -aq --filter "name=sohcont" | grep -q .; then docker rm -f sohcont; fi
|
||||
docker build . -t soh
|
||||
docker run --name sohcont -dit --rm -v $(pwd):/soh soh /bin/bash
|
||||
cp ../../buildsoh.bash soh
|
||||
docker exec sohcont soh/buildsoh.bash
|
||||
docker exec sohcont scripts/linux/appimage/build.sh
|
||||
|
||||
mkdir build
|
||||
mv soh/soh.elf build/
|
||||
mv OTRGui/build/OTRGui build/
|
||||
mv OTRGui/build/assets build/
|
||||
mv ZAPDTR/ZAPD.out build/assets/extractor/
|
||||
mv README.md readme.txt
|
||||
|
||||
docker exec sohcont appimage/appimage.sh
|
||||
|
||||
7z a soh-linux.7z SOH-Linux.AppImage readme.txt
|
||||
mv build-cmake/*.appimage soh.appimage
|
||||
|
||||
7z a soh-linux.7z soh.appimage readme.txt
|
||||
|
||||
'''
|
||||
}
|
||||
sh 'sudo docker container stop sohcont'
|
||||
archiveArtifacts artifacts: 'soh-linux.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
post {
|
||||
always {
|
||||
sh 'sudo docker container stop sohcont'
|
||||
sh 'docker images --quiet --filter=dangling=true | xargs --no-run-if-empty docker rmi' // Clean dangling docker images
|
||||
step([$class: 'WsCleanup']) // Clean workspace
|
||||
}
|
||||
}
|
||||
@@ -134,17 +128,19 @@ pipeline {
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
unstash 'assets'
|
||||
sh '''
|
||||
cp ../../ZELOOTD.z64 OTRExporter/baserom_non_mq.z64
|
||||
cd soh
|
||||
export CC="clang -arch arm64 -arch x86_64"; export CXX="clang++ -arch arm64 -arch x86_64"; make setup -j4 OPTFLAGS=-O2 DEBUG=0 LD="ld"
|
||||
export CC="clang -arch arm64 -arch x86_64"; export CXX="clang++ -arch arm64 -arch x86_64"; make -j4 DEBUG=0 OPTFLAGS=-O2 LD="ld"
|
||||
make -j4 appbundle
|
||||
mv ../README.md readme.txt
|
||||
7z a soh-mac.7z soh.app readme.txt
|
||||
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
|
||||
cmake --build build-cmake --config Release --
|
||||
(cd build-cmake && cpack)
|
||||
|
||||
mv README.md readme.txt
|
||||
mv _packages/*.dmg SoH.dmg
|
||||
|
||||
7z a soh-mac.7z SoH.dmg readme.txt
|
||||
'''
|
||||
}
|
||||
archiveArtifacts artifacts: 'soh/soh-mac.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
archiveArtifacts artifacts: 'soh-mac.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
post {
|
||||
always {
|
||||
@@ -152,7 +148,83 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ('Build Switch') {
|
||||
agent {
|
||||
label "SoH-Linux-Builders"
|
||||
}
|
||||
steps {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: scm.branches,
|
||||
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
|
||||
extensions: scm.extensions,
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
unstash 'assets'
|
||||
sh '''
|
||||
if docker ps -aq --filter "name=sohswitchcont" | grep -q .; then docker rm -f sohswitchcont; fi
|
||||
docker build . -t sohswitch
|
||||
docker run --name sohswitchcont -dit --rm -v $(pwd):/soh sohswitch /bin/bash
|
||||
docker exec sohswitchcont scripts/switch/build.sh
|
||||
|
||||
mv build-switch/soh/*.nro soh.nro
|
||||
mv README.md readme.txt
|
||||
|
||||
7z a soh-switch.7z soh.nro readme.txt
|
||||
|
||||
'''
|
||||
}
|
||||
archiveArtifacts artifacts: 'soh-switch.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
post {
|
||||
always {
|
||||
sh 'sudo docker container stop sohswitchcont'
|
||||
sh 'docker images --quiet --filter=dangling=true | xargs --no-run-if-empty docker rmi' // Clean dangling docker images
|
||||
step([$class: 'WsCleanup']) // Clean workspace
|
||||
}
|
||||
}
|
||||
}
|
||||
stage ('Build Wii U') {
|
||||
agent {
|
||||
label "SoH-Linux-Builders"
|
||||
}
|
||||
steps {
|
||||
checkout([
|
||||
$class: 'GitSCM',
|
||||
branches: scm.branches,
|
||||
doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
|
||||
extensions: scm.extensions,
|
||||
userRemoteConfigs: scm.userRemoteConfigs
|
||||
])
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
unstash 'assets'
|
||||
sh '''
|
||||
if docker ps -aq --filter "name=sohwiiucont" | grep -q .; then docker rm -f sohwiiucont; fi
|
||||
docker build . -t sohwiiu
|
||||
docker run --name sohwiiucont -dit --rm -v $(pwd):/soh sohwiiu /bin/bash
|
||||
docker exec sohwiiucont scripts/wiiu/build.sh
|
||||
|
||||
mv build-wiiu/soh/*.rpx soh.rpx
|
||||
mv build-wiiu/soh/*.wuhb soh.wuhb
|
||||
mv README.md readme.txt
|
||||
|
||||
7z a soh-wiiu.7z soh.rpx soh.wuhb readme.txt
|
||||
|
||||
'''
|
||||
}
|
||||
archiveArtifacts artifacts: 'soh-wiiu.7z', followSymlinks: false, onlyIfSuccessful: true
|
||||
}
|
||||
post {
|
||||
always {
|
||||
sh 'sudo docker container stop sohwiiucont'
|
||||
sh 'docker images --quiet --filter=dangling=true | xargs --no-run-if-empty docker rmi' // Clean dangling docker images
|
||||
step([$class: 'WsCleanup']) // Clean workspace
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
################################################################################
|
||||
# Command for variable_watch. This command issues error message, if a variable
|
||||
# is changed. If variable PROPERTY_READER_GUARD_DISABLED is TRUE nothing happens
|
||||
# variable_watch(<variable> property_reader_guard)
|
||||
################################################################################
|
||||
function(property_reader_guard VARIABLE ACCESS VALUE CURRENT_LIST_FILE STACK)
|
||||
if("${PROPERTY_READER_GUARD_DISABLED}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if("${ACCESS}" STREQUAL "MODIFIED_ACCESS")
|
||||
message(FATAL_ERROR
|
||||
" Variable ${VARIABLE} is not supposed to be changed.\n"
|
||||
" It is used only for reading target property ${VARIABLE}.\n"
|
||||
" Use\n"
|
||||
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}\" \"<value>\")\n"
|
||||
" or\n"
|
||||
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}_<CONFIG>\" \"<value>\")\n"
|
||||
" instead.\n")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Create variable <name> with generator expression that expands to value of
|
||||
# target property <name>_<CONFIG>. If property is empty or not set then property
|
||||
# <name> is used instead. Variable <name> has watcher property_reader_guard that
|
||||
# doesn't allow to edit it.
|
||||
# create_property_reader(<name>)
|
||||
# Input:
|
||||
# name - Name of watched property and output variable
|
||||
################################################################################
|
||||
function(create_property_reader NAME)
|
||||
set(PROPERTY_READER_GUARD_DISABLED TRUE)
|
||||
set(CONFIG_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}_$<UPPER_CASE:$<CONFIG>>>>")
|
||||
set(IS_CONFIG_VALUE_EMPTY "$<STREQUAL:${CONFIG_VALUE},>")
|
||||
set(GENERAL_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}>>")
|
||||
set("${NAME}" "$<IF:${IS_CONFIG_VALUE_EMPTY},${GENERAL_VALUE},${CONFIG_VALUE}>" PARENT_SCOPE)
|
||||
variable_watch("${NAME}" property_reader_guard)
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Set property $<name>_${PROPS_CONFIG_U} of ${PROPS_TARGET} to <value>
|
||||
# set_config_specific_property(<name> <value>)
|
||||
# Input:
|
||||
# name - Prefix of property name
|
||||
# value - New value
|
||||
################################################################################
|
||||
function(set_config_specific_property NAME VALUE)
|
||||
set_target_properties("${PROPS_TARGET}" PROPERTIES "${NAME}_${PROPS_CONFIG_U}" "${VALUE}")
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
|
||||
create_property_reader("TARGET_NAME")
|
||||
create_property_reader("OUTPUT_DIRECTORY")
|
||||
|
||||
set_config_specific_property("TARGET_NAME" "${PROPS_TARGET}")
|
||||
set_config_specific_property("OUTPUT_NAME" "${TARGET_NAME}")
|
||||
set_config_specific_property("ARCHIVE_OUTPUT_NAME" "${TARGET_NAME}")
|
||||
set_config_specific_property("LIBRARY_OUTPUT_NAME" "${TARGET_NAME}")
|
||||
set_config_specific_property("RUNTIME_OUTPUT_NAME" "${TARGET_NAME}")
|
||||
|
||||
set_config_specific_property("ARCHIVE_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
|
||||
set_config_specific_property("LIBRARY_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
|
||||
set_config_specific_property("RUNTIME_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
|
||||
@@ -0,0 +1,12 @@
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/Default.cmake")
|
||||
|
||||
set_config_specific_property("OUTPUT_DIRECTORY" "${CMAKE_SOURCE_DIR}$<$<NOT:$<STREQUAL:${CMAKE_VS_PLATFORM_NAME},Win32>>:/${CMAKE_VS_PLATFORM_NAME}>/${PROPS_CONFIG}")
|
||||
|
||||
if(MSVC)
|
||||
create_property_reader("DEFAULT_CXX_EXCEPTION_HANDLING")
|
||||
create_property_reader("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT")
|
||||
|
||||
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
|
||||
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
|
||||
endif()
|
||||
@@ -0,0 +1,233 @@
|
||||
# utils file for projects came from visual studio solution with cmake-converter.
|
||||
|
||||
################################################################################
|
||||
# Wrap each token of the command with condition
|
||||
################################################################################
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
macro(prepare_commands)
|
||||
unset(TOKEN_ROLE)
|
||||
unset(COMMANDS)
|
||||
foreach(TOKEN ${ARG_COMMANDS})
|
||||
if("${TOKEN}" STREQUAL "COMMAND")
|
||||
set(TOKEN_ROLE "KEYWORD")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "KEYWORD")
|
||||
set(TOKEN_ROLE "CONDITION")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
|
||||
set(TOKEN_ROLE "COMMAND")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
|
||||
set(TOKEN_ROLE "ARG")
|
||||
endif()
|
||||
|
||||
if("${TOKEN_ROLE}" STREQUAL "KEYWORD")
|
||||
list(APPEND COMMANDS "${TOKEN}")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
|
||||
set(CONDITION ${TOKEN})
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
|
||||
list(APPEND COMMANDS "$<$<NOT:${CONDITION}>:${DUMMY}>$<${CONDITION}:${TOKEN}>")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "ARG")
|
||||
list(APPEND COMMANDS "$<${CONDITION}:${TOKEN}>")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
cmake_policy(POP)
|
||||
|
||||
################################################################################
|
||||
# Transform all the tokens to absolute paths
|
||||
################################################################################
|
||||
macro(prepare_output)
|
||||
unset(OUTPUT)
|
||||
foreach(TOKEN ${ARG_OUTPUT})
|
||||
if(IS_ABSOLUTE ${TOKEN})
|
||||
list(APPEND OUTPUT "${TOKEN}")
|
||||
else()
|
||||
list(APPEND OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${TOKEN}")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
################################################################################
|
||||
# Parse add_custom_command_if args.
|
||||
#
|
||||
# Input:
|
||||
# PRE_BUILD - Pre build event option
|
||||
# PRE_LINK - Pre link event option
|
||||
# POST_BUILD - Post build event option
|
||||
# TARGET - Target
|
||||
# OUTPUT - List of output files
|
||||
# DEPENDS - List of files on which the command depends
|
||||
# COMMANDS - List of commands(COMMAND condition1 commannd1 args1 COMMAND
|
||||
# condition2 commannd2 args2 ...)
|
||||
# Output:
|
||||
# OUTPUT - Output files
|
||||
# DEPENDS - Files on which the command depends
|
||||
# COMMENT - Comment
|
||||
# PRE_BUILD - TRUE/FALSE
|
||||
# PRE_LINK - TRUE/FALSE
|
||||
# POST_BUILD - TRUE/FALSE
|
||||
# TARGET - Target name
|
||||
# COMMANDS - Prepared commands(every token is wrapped in CONDITION)
|
||||
# NAME - Unique name for custom target
|
||||
# STEP - PRE_BUILD/PRE_LINK/POST_BUILD
|
||||
################################################################################
|
||||
function(add_custom_command_if_parse_arguments)
|
||||
cmake_parse_arguments("ARG" "PRE_BUILD;PRE_LINK;POST_BUILD" "TARGET;COMMENT" "DEPENDS;OUTPUT;COMMANDS" ${ARGN})
|
||||
|
||||
if(WIN32)
|
||||
set(DUMMY "cd.")
|
||||
elseif(UNIX)
|
||||
set(DUMMY "true")
|
||||
endif()
|
||||
|
||||
prepare_commands()
|
||||
prepare_output()
|
||||
|
||||
set(DEPENDS "${ARG_DEPENDS}")
|
||||
set(COMMENT "${ARG_COMMENT}")
|
||||
set(PRE_BUILD "${ARG_PRE_BUILD}")
|
||||
set(PRE_LINK "${ARG_PRE_LINK}")
|
||||
set(POST_BUILD "${ARG_POST_BUILD}")
|
||||
set(TARGET "${ARG_TARGET}")
|
||||
if(PRE_BUILD)
|
||||
set(STEP "PRE_BUILD")
|
||||
elseif(PRE_LINK)
|
||||
set(STEP "PRE_LINK")
|
||||
elseif(POST_BUILD)
|
||||
set(STEP "POST_BUILD")
|
||||
endif()
|
||||
set(NAME "${TARGET}_${STEP}")
|
||||
|
||||
set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
|
||||
set(DEPENDS "${DEPENDS}" PARENT_SCOPE)
|
||||
set(COMMENT "${COMMENT}" PARENT_SCOPE)
|
||||
set(PRE_BUILD "${PRE_BUILD}" PARENT_SCOPE)
|
||||
set(PRE_LINK "${PRE_LINK}" PARENT_SCOPE)
|
||||
set(POST_BUILD "${POST_BUILD}" PARENT_SCOPE)
|
||||
set(TARGET "${TARGET}" PARENT_SCOPE)
|
||||
set(COMMANDS "${COMMANDS}" PARENT_SCOPE)
|
||||
set(STEP "${STEP}" PARENT_SCOPE)
|
||||
set(NAME "${NAME}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Add conditional custom command
|
||||
#
|
||||
# Generating Files
|
||||
# The first signature is for adding a custom command to produce an output:
|
||||
# add_custom_command_if(
|
||||
# <OUTPUT output1 [output2 ...]>
|
||||
# <COMMANDS>
|
||||
# <COMMAND condition command1 [args1...]>
|
||||
# [COMMAND condition command2 [args2...]]
|
||||
# [DEPENDS [depends...]]
|
||||
# [COMMENT comment]
|
||||
#
|
||||
# Build Events
|
||||
# add_custom_command_if(
|
||||
# <TARGET target>
|
||||
# <PRE_BUILD | PRE_LINK | POST_BUILD>
|
||||
# <COMMAND condition command1 [args1...]>
|
||||
# [COMMAND condition command2 [args2...]]
|
||||
# [COMMENT comment]
|
||||
#
|
||||
# Input:
|
||||
# output - Output files the command is expected to produce
|
||||
# condition - Generator expression for wrapping the command
|
||||
# command - Command-line(s) to execute at build time.
|
||||
# args - Command`s args
|
||||
# depends - Files on which the command depends
|
||||
# comment - Display the given message before the commands are executed at
|
||||
# build time.
|
||||
# PRE_BUILD - Run before any other rules are executed within the target
|
||||
# PRE_LINK - Run after sources have been compiled but before linking the
|
||||
# binary
|
||||
# POST_BUILD - Run after all other rules within the target have been
|
||||
# executed
|
||||
################################################################################
|
||||
function(add_custom_command_if)
|
||||
add_custom_command_if_parse_arguments(${ARGN})
|
||||
|
||||
if(OUTPUT AND TARGET)
|
||||
message(FATAL_ERROR "Wrong syntax. A TARGET and OUTPUT can not both be specified.")
|
||||
endif()
|
||||
|
||||
if(OUTPUT)
|
||||
add_custom_command(OUTPUT ${OUTPUT}
|
||||
${COMMANDS}
|
||||
DEPENDS ${DEPENDS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT ${COMMENT})
|
||||
elseif(TARGET)
|
||||
if(PRE_BUILD AND NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio")
|
||||
add_custom_target(
|
||||
${NAME}
|
||||
${COMMANDS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT ${COMMENT})
|
||||
add_dependencies(${TARGET} ${NAME})
|
||||
else()
|
||||
add_custom_command(
|
||||
TARGET ${TARGET}
|
||||
${STEP}
|
||||
${COMMANDS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT ${COMMENT})
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Wrong syntax. A TARGET or OUTPUT must be specified.")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Use props file for a target and configs
|
||||
# use_props(<target> <configs...> <props_file>)
|
||||
# Inside <props_file> there are following variables:
|
||||
# PROPS_TARGET - <target>
|
||||
# PROPS_CONFIG - One of <configs...>
|
||||
# PROPS_CONFIG_U - Uppercase PROPS_CONFIG
|
||||
# Input:
|
||||
# target - Target to apply props file
|
||||
# configs - Build configurations to apply props file
|
||||
# props_file - CMake script
|
||||
################################################################################
|
||||
macro(use_props TARGET CONFIGS PROPS_FILE)
|
||||
set(PROPS_TARGET "${TARGET}")
|
||||
foreach(PROPS_CONFIG ${CONFIGS})
|
||||
string(TOUPPER "${PROPS_CONFIG}" PROPS_CONFIG_U)
|
||||
|
||||
get_filename_component(ABSOLUTE_PROPS_FILE "${PROPS_FILE}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||
if(EXISTS "${ABSOLUTE_PROPS_FILE}")
|
||||
include("${ABSOLUTE_PROPS_FILE}")
|
||||
else()
|
||||
message(WARNING "Corresponding cmake file from props \"${ABSOLUTE_PROPS_FILE}\" doesn't exist")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
################################################################################
|
||||
# Add compile options to source file
|
||||
# source_file_compile_options(<source_file> [compile_options...])
|
||||
# Input:
|
||||
# source_file - Source file
|
||||
# compile_options - Options to add to COMPILE_FLAGS property
|
||||
################################################################################
|
||||
function(source_file_compile_options SOURCE_FILE)
|
||||
if("${ARGC}" LESS_EQUAL "1")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_source_file_property(COMPILE_OPTIONS "${SOURCE_FILE}" COMPILE_OPTIONS)
|
||||
|
||||
if(COMPILE_OPTIONS)
|
||||
list(APPEND COMPILE_OPTIONS ${ARGN})
|
||||
else()
|
||||
set(COMPILE_OPTIONS "${ARGN}")
|
||||
endif()
|
||||
|
||||
set_source_files_properties("${SOURCE_FILE}" PROPERTIES COMPILE_OPTIONS "${COMPILE_OPTIONS}")
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Default properties of visual studio projects
|
||||
################################################################################
|
||||
set(DEFAULT_CXX_PROPS "${CMAKE_CURRENT_LIST_DIR}/DefaultCXX.cmake")
|
||||
@@ -0,0 +1,96 @@
|
||||
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
|
||||
|
||||
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
#set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use")
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
project(OTRExporter C CXX)
|
||||
|
||||
################################################################################
|
||||
# Set target arch type if empty. Visual studio solution generator provides it.
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if(NOT CMAKE_VS_PLATFORM_NAME)
|
||||
set(CMAKE_VS_PLATFORM_NAME "x64")
|
||||
endif()
|
||||
message("${CMAKE_VS_PLATFORM_NAME} architecture in use")
|
||||
|
||||
if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64"
|
||||
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"))
|
||||
message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Global configuration types
|
||||
################################################################################
|
||||
set(CMAKE_CONFIGURATION_TYPES
|
||||
"Debug"
|
||||
"Release"
|
||||
CACHE STRING "" FORCE
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Global compiler options
|
||||
################################################################################
|
||||
if(MSVC)
|
||||
# remove default flags provided with CMake for MSVC
|
||||
set(CMAKE_C_FLAGS "")
|
||||
set(CMAKE_C_FLAGS_DEBUG "")
|
||||
set(CMAKE_C_FLAGS_RELEASE "")
|
||||
set(CMAKE_CXX_FLAGS "")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "")
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Global linker options
|
||||
################################################################################
|
||||
if(MSVC)
|
||||
# remove default flags provided with CMake for MSVC
|
||||
set(CMAKE_EXE_LINKER_FLAGS "")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "${CMAKE_STATIC_LINKER_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS}")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS}")
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Common utils
|
||||
################################################################################
|
||||
include(CMake/Utils.cmake)
|
||||
|
||||
################################################################################
|
||||
# Additional Global Settings(add specific info there)
|
||||
################################################################################
|
||||
include(CMake/GlobalSettingsInclude.cmake OPTIONAL)
|
||||
|
||||
################################################################################
|
||||
# Use solution folders feature
|
||||
################################################################################
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
################################################################################
|
||||
# Sub-projects
|
||||
################################################################################
|
||||
if (NOT TARGET libultraship)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship ${CMAKE_BINARY_DIR}/libultraship)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET ZAPD)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET ZAPDUtils)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils)
|
||||
endif()
|
||||
|
||||
add_subdirectory(OTRExporter)
|
||||
@@ -1,79 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30320.27
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OTRExporter", "OTRExporter\OTRExporter.vcxproj", "{A6103FD3-0709-4FC7-B066-1A6E056D6306}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} = {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libultraship", "..\libultraship\libultraship\libultraship.vcxproj", "{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPD", "..\ZAPDTR\ZAPD\ZAPD.vcxproj", "{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055} = {78424708-1F6E-4D4B-920C-FB6D26847055}
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} = {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908} = {A2E01C3E-D647-45D1-9788-043DEBC1A908}
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306} = {A6103FD3-0709-4FC7-B066-1A6E056D6306}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPDUtils", "..\ZAPDTR\ZAPDUtils\ZAPDUtils.vcxproj", "{A2E01C3E-D647-45D1-9788-043DEBC1A908}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StormLib", "..\StormLib\StormLib_vs19.vcxproj", "{78424708-1F6E-4D4B-920C-FB6D26847055}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306}.Debug|x64.Build.0 = Debug|x64
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306}.Release|x64.ActiveCfg = Release|x64
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306}.Release|x64.Build.0 = Release|x64
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A6103FD3-0709-4FC7-B066-1A6E056D6306}.Release|x86.Build.0 = Release|Win32
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x64.Build.0 = Debug|x64
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x64.ActiveCfg = Release|x64
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x64.Build.0 = Release|x64
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x86.Build.0 = Release|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.Build.0 = Debug|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.ActiveCfg = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.Build.0 = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.Build.0 = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.Build.0 = Debug|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.ActiveCfg = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.Build.0 = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.Build.0 = Release|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.ActiveCfg = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x64.Build.0 = DebugUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.ActiveCfg = DebugAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Debug|x86.Build.0 = DebugAD|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.ActiveCfg = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x64.Build.0 = ReleaseUS|x64
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.ActiveCfg = ReleaseAS|Win32
|
||||
{78424708-1F6E-4D4B-920C-FB6D26847055}.Release|x86.Build.0 = ReleaseAS|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DCE19FF1-37C0-49CD-915A-DD695E15F00B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,249 @@
|
||||
set(PROJECT_NAME OTRExporter)
|
||||
|
||||
################################################################################
|
||||
# Source groups
|
||||
################################################################################
|
||||
set(Header_Files
|
||||
"AnimationExporter.h"
|
||||
"ArrayExporter.h"
|
||||
"AudioExporter.h"
|
||||
"BackgroundExporter.h"
|
||||
"BlobExporter.h"
|
||||
"CollisionExporter.h"
|
||||
"command_macros_base.h"
|
||||
"CutsceneExporter.h"
|
||||
"DisplayListExporter.h"
|
||||
"Exporter.h"
|
||||
"Main.h"
|
||||
"MtxExporter.h"
|
||||
"PathExporter.h"
|
||||
"PlayerAnimationExporter.h"
|
||||
"RoomExporter.h"
|
||||
"SkeletonExporter.h"
|
||||
"SkeletonLimbExporter.h"
|
||||
"TextExporter.h"
|
||||
"TextureExporter.h"
|
||||
"VersionInfo.h"
|
||||
"VtxExporter.h"
|
||||
"z64cutscene.h"
|
||||
"z64cutscene_commands.h"
|
||||
)
|
||||
source_group("Header Files" FILES ${Header_Files})
|
||||
|
||||
set(Source_Files
|
||||
"AnimationExporter.cpp"
|
||||
"ArrayExporter.cpp"
|
||||
"AudioExporter.cpp"
|
||||
"BackgroundExporter.cpp"
|
||||
"BlobExporter.cpp"
|
||||
"CollisionExporter.cpp"
|
||||
"CutsceneExporter.cpp"
|
||||
"DisplayListExporter.cpp"
|
||||
"Exporter.cpp"
|
||||
"Main.cpp"
|
||||
"MtxExporter.cpp"
|
||||
"PathExporter.cpp"
|
||||
"PlayerAnimationExporter.cpp"
|
||||
"RoomExporter.cpp"
|
||||
"SkeletonExporter.cpp"
|
||||
"SkeletonLimbExporter.cpp"
|
||||
"TextExporter.cpp"
|
||||
"TextureExporter.cpp"
|
||||
"VersionInfo.cpp"
|
||||
"VtxExporter.cpp"
|
||||
)
|
||||
source_group("Source Files" FILES ${Source_Files})
|
||||
|
||||
set(ALL_FILES
|
||||
${Header_Files}
|
||||
${Source_Files}
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Target
|
||||
################################################################################
|
||||
add_library(${PROJECT_NAME} STATIC ${ALL_FILES})
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||
endif()
|
||||
|
||||
set(ROOT_NAMESPACE OTRExporter)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
VS_GLOBAL_KEYWORD "Win32Proj"
|
||||
)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
################################################################################
|
||||
# MSVC runtime library
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||
$<$<CONFIG:Debug>:
|
||||
MultiThreadedDebug
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
MultiThreaded
|
||||
>
|
||||
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
||||
)
|
||||
endif()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
||||
endif()
|
||||
################################################################################
|
||||
# Compile definitions
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
"_CONSOLE;"
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG;"
|
||||
"_CRT_SECURE_NO_WARNINGS"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
"WIN32;"
|
||||
"_CONSOLE;"
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
"_CONSOLE;"
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
)
|
||||
endif()
|
||||
################################################################################
|
||||
# Compile and link options
|
||||
################################################################################
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/ZAPD/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/ZAPDUtils
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/lib/tinyxml2
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship/libultraship
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship/libultraship/Lib/spdlog/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship/libultraship/Lib/Fast3D/U64
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../StormLib/src
|
||||
.
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:
|
||||
/Oi;
|
||||
/Gy
|
||||
>
|
||||
/permissive-;
|
||||
/sdl;
|
||||
/W3;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:
|
||||
/Oi;
|
||||
/Gy
|
||||
>
|
||||
/permissive-;
|
||||
/sdl;
|
||||
/W3;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
endif()
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:
|
||||
/OPT:REF;
|
||||
/OPT:ICF
|
||||
>
|
||||
/SUBSYSTEM:CONSOLE
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:
|
||||
/DEBUG;
|
||||
/OPT:REF;
|
||||
/OPT:ICF;
|
||||
/INCREMENTAL:NO
|
||||
>
|
||||
/SUBSYSTEM:CONSOLE
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
-Wall -Wextra -Wno-error
|
||||
-Wno-unused-parameter
|
||||
-Wno-unused-function
|
||||
-Wno-unused-variable
|
||||
-Wno-missing-field-initializers
|
||||
-Wno-parentheses
|
||||
-Wno-narrowing
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>
|
||||
)
|
||||
endif()
|
||||
################################################################################
|
||||
# Dependencies
|
||||
################################################################################
|
||||
add_dependencies(${PROJECT_NAME}
|
||||
libultraship
|
||||
)
|
||||
|
||||
# Link with other targets.
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"ZAPDUtils;"
|
||||
"OTRLib"
|
||||
">"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC "${ADDITIONAL_LIBRARY_DEPENDENCIES}")
|
||||
|
||||
@@ -653,8 +653,13 @@ void OTRExporter_DisplayList::Save(ZResource* res, const fs::path& outPath, Bina
|
||||
uint32_t seg = data & 0xFFFFFFFF;
|
||||
int32_t texAddress = Seg2Filespace(data, dList->parent->baseAddress);
|
||||
|
||||
if (!Globals::Instance->HasSegment(GETSEGNUM(seg), res->parent->workerID))
|
||||
if (!Globals::Instance->HasSegment(GETSEGNUM(seg), res->parent->workerID) || (res->GetName() == "sShadowMaterialDL"))
|
||||
{
|
||||
if (res->GetName() == "sShadowMaterialDL") {
|
||||
// sShadowMaterialDL (In ovl_En_Jsjutan) has a texture in bss. This is a hack to override the reference to one
|
||||
// to segment C. The actor has been modified to load the texture into segment C.
|
||||
seg = 0x0C000000;
|
||||
}
|
||||
int32_t __ = (data & 0x00FF000000000000) >> 48;
|
||||
int32_t www = (data & 0x00000FFF00000000) >> 32;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, Ship::ResourceType resType, Ship::Version resVersion)
|
||||
{
|
||||
writer->Write((uint8_t)Endianess::Little); // 0x00
|
||||
writer->Write((uint8_t)Endianness::Little); // 0x00
|
||||
writer->Write((uint8_t)0); // 0x01
|
||||
writer->Write((uint8_t)0); // 0x02
|
||||
writer->Write((uint8_t)0); // 0x03
|
||||
|
||||
@@ -63,13 +63,29 @@ static void ExporterProgramEnd()
|
||||
{
|
||||
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||
{
|
||||
printf("Creating version file...\n");
|
||||
|
||||
// Get crc from rom
|
||||
std::string romPath = Globals::Instance->baseRomPath.string();
|
||||
std::vector<uint8_t> romData = File::ReadAllBytes(romPath);
|
||||
uint32_t crc = BitConverter::ToUInt32BE(romData, 0x10);
|
||||
|
||||
// Write crc to version file
|
||||
fs::path versionPath("Extract/version");
|
||||
std::ofstream versionFile(versionPath.c_str(), std::ios::out | std::ios::binary);
|
||||
versionFile.write((char*)&crc, sizeof(crc));
|
||||
versionFile.flush();
|
||||
versionFile.close();
|
||||
|
||||
printf("Created version file.\n");
|
||||
|
||||
printf("Generating OTR Archive...\n");
|
||||
otrArchive = Ship::Archive::CreateArchive(otrFileName, 40000);
|
||||
|
||||
for (auto item : files)
|
||||
{
|
||||
for (auto item : files) {
|
||||
auto fileData = item.second;
|
||||
otrArchive->AddFile(item.first, (uintptr_t)fileData.data(), fileData.size());
|
||||
otrArchive->AddFile(item.first, (uintptr_t)fileData.data(),
|
||||
fileData.size());
|
||||
}
|
||||
|
||||
// Add any additional files that need to be manually copied...
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
# Only used for standalone compilation, usually inherits these from the main makefile
|
||||
|
||||
CXX ?= g++
|
||||
AR := ar
|
||||
FORMAT := clang-format-11
|
||||
|
||||
ASAN ?= 0
|
||||
DEBUG ?= 1
|
||||
OPTFLAGS ?= -O0
|
||||
LTO ?= 0
|
||||
|
||||
WARN := -Wall -Wextra -Werror \
|
||||
-Wno-unused-parameter \
|
||||
-Wno-unused-function \
|
||||
-Wno-unused-variable \
|
||||
-Wno-error=multichar
|
||||
|
||||
|
||||
CXXFLAGS := $(WARN) -std=c++17
|
||||
CPPFLAGS := -MMD
|
||||
|
||||
ifneq ($(DEBUG),0)
|
||||
CXXFLAGS += -g
|
||||
endif
|
||||
|
||||
ifneq ($(ASAN),0)
|
||||
CXXFLAGS += -fsanitize=address
|
||||
endif
|
||||
|
||||
ifneq ($(LTO),0)
|
||||
CXXFLAGS += -flto
|
||||
endif
|
||||
|
||||
SRC_DIRS := $(shell find . -type d -not -path "*build*")
|
||||
CXX_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp))
|
||||
H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h))
|
||||
|
||||
O_FILES := $(CXX_FILES:%.cpp=build/%.o)
|
||||
D_FILES := $(O_FILES:%.o=%.d)
|
||||
LIB := OTRExporter.a
|
||||
|
||||
INC_DIRS := $(addprefix -I, \
|
||||
../../ZAPDTR/ZAPD \
|
||||
../../ZAPDTR/lib/tinyxml2 \
|
||||
../../ZAPDTR/lib/libgfxd \
|
||||
../../ZAPDTR/ZAPDUtils \
|
||||
../../libultraship/libultraship \
|
||||
../../libultraship/libultraship/Lib/spdlog/include \
|
||||
../../libultraship/libultraship/Lib/Fast3D/U64 \
|
||||
../../StormLib/src \
|
||||
)
|
||||
|
||||
# create build directories
|
||||
$(shell mkdir -p $(SRC_DIRS:%=build/%))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
clean:
|
||||
rm -rf build $(LIB)
|
||||
|
||||
format:
|
||||
$(FORMAT) -i $(CXX_FILES) $(H_FILES)
|
||||
|
||||
.PHONY: all clean format
|
||||
|
||||
build/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@
|
||||
|
||||
$(LIB): $(O_FILES)
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
-include $(D_FILES)
|
||||
@@ -1,222 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ArrayExporter.h" />
|
||||
<ClInclude Include="AudioExporter.h" />
|
||||
<ClInclude Include="BackgroundExporter.h" />
|
||||
<ClInclude Include="BlobExporter.h" />
|
||||
<ClInclude Include="CollisionExporter.h" />
|
||||
<ClInclude Include="command_macros_base.h" />
|
||||
<ClInclude Include="CutsceneExporter.h" />
|
||||
<ClInclude Include="DisplayListExporter.h" />
|
||||
<ClInclude Include="AnimationExporter.h" />
|
||||
<ClInclude Include="Main.h" />
|
||||
<ClInclude Include="Exporter.h" />
|
||||
<ClInclude Include="MtxExporter.h" />
|
||||
<ClInclude Include="SkeletonExporter.h" />
|
||||
<ClInclude Include="SkeletonLimbExporter.h" />
|
||||
<ClInclude Include="PathExporter.h" />
|
||||
<ClInclude Include="PlayerAnimationExporter.h" />
|
||||
<ClInclude Include="RoomExporter.h" />
|
||||
<ClInclude Include="TextExporter.h" />
|
||||
<ClInclude Include="TextureExporter.h" />
|
||||
<ClInclude Include="VersionInfo.h" />
|
||||
<ClInclude Include="VtxExporter.h" />
|
||||
<ClInclude Include="z64cutscene.h" />
|
||||
<ClInclude Include="z64cutscene_commands.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ArrayExporter.cpp" />
|
||||
<ClCompile Include="AudioExporter.cpp" />
|
||||
<ClCompile Include="BackgroundExporter.cpp" />
|
||||
<ClCompile Include="BlobExporter.cpp" />
|
||||
<ClCompile Include="CollisionExporter.cpp" />
|
||||
<ClCompile Include="CutsceneExporter.cpp" />
|
||||
<ClCompile Include="DisplayListExporter.cpp" />
|
||||
<ClCompile Include="AnimationExporter.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="Exporter.cpp" />
|
||||
<ClCompile Include="MtxExporter.cpp" />
|
||||
<ClCompile Include="SkeletonExporter.cpp" />
|
||||
<ClCompile Include="SkeletonLimbExporter.cpp" />
|
||||
<ClCompile Include="PathExporter.cpp" />
|
||||
<ClCompile Include="PlayerAnimationExporter.cpp" />
|
||||
<ClCompile Include="RoomExporter.cpp" />
|
||||
<ClCompile Include="TextExporter.cpp" />
|
||||
<ClCompile Include="TextureExporter.cpp" />
|
||||
<ClCompile Include="VersionInfo.cpp" />
|
||||
<ClCompile Include="VtxExporter.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\OTRGui\build\ZERO_CHECK.vcxproj">
|
||||
<Project>{02d10590-9542-3f55-aaf8-6055677e2a2a}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{a6103fd3-0709-4fc7-b066-1a6e056d6306}</ProjectGuid>
|
||||
<RootNamespace>OTRExporter</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)otrlib;$(SolutionDir)\ZAPD\ZAPD\;$(SolutionDir)\ZAPD\lib\tinyxml2;$(SolutionDir)\ZAPD\lib\libgfxd;$(SolutionDir)\ZAPD\lib\elfio;$(SolutionDir)\ZAPD\lib\assimp\include;$(SolutionDir)\ZAPD\lib\stb;$(ProjectDir);$(IncludePath)</IncludePath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules />
|
||||
<CodeAnalysisRuleAssemblies />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules />
|
||||
<CodeAnalysisRuleAssemblies />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(ProjectDir)..\..\StormLib\src\;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)..\..\libultraship\libultraship;$(LibraryPath)</LibraryPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules />
|
||||
<CodeAnalysisRuleAssemblies />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir)..\..\ZAPDTR\ZAPD;$(ProjectDir)..\..\ZAPDTR\lib\tinyxml2;$(ProjectDir)..\..\ZAPDTR\lib\libgfxd;$(ProjectDir)..\..\ZAPDTR\ZAPDUtils;$(ProjectDir)..\..\libultraship\libultraship;$(ProjectDir)..\..\libultraship\libultraship\lib\spdlog\include;$(ProjectDir)..\..\libultraship\libultraship\Lib\Fast3D\U64;$(ProjectDir)..\..\StormLib\src\;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)..\..\libultraship\libultraship;$(LibraryPath)</LibraryPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules />
|
||||
<CodeAnalysisRuleAssemblies />
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ZAPDUtils.lib;OTRLib.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,150 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CollisionExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RoomExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TextureExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DisplayListExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Main.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PlayerAnimationExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BackgroundExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VtxExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ArrayExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Exporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AnimationExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CutsceneExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="z64cutscene.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="z64cutscene_commands.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="command_macros_base.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PathExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SkeletonExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SkeletonLimbExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="TextExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BlobExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MtxExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VersionInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AudioExporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CollisionExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RoomExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TextureExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DisplayListExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PlayerAnimationExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SkeletonExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SkeletonLimbExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BackgroundExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VtxExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ArrayExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Exporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AnimationExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CutsceneExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PathExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TextExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BlobExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MtxExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VersionInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AudioExporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -4,15 +4,22 @@ import os, sys, shutil
|
||||
import shutil
|
||||
from rom_info import Z64Rom
|
||||
import rom_chooser
|
||||
import struct
|
||||
import subprocess
|
||||
import argparse
|
||||
|
||||
def BuildOTR(xmlPath, rom):
|
||||
def BuildOTR(xmlPath, rom, zapd_exe=None):
|
||||
shutil.copytree("assets", "Extract/assets")
|
||||
|
||||
execStr = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPDTR/ZAPD.out"
|
||||
execStr += " ed -i %s -b %s -fl CFG/filelists -o placeholder -osf placeholder -gsf 1 -rconf CFG/Config.xml -se OTR" % (xmlPath, rom)
|
||||
if not zapd_exe:
|
||||
zapd_exe = "x64\\Release\\ZAPD.exe" if sys.platform == "win32" else "../ZAPDTR/ZAPD.out"
|
||||
|
||||
print(execStr)
|
||||
exitValue = os.system(execStr)
|
||||
exec_cmd = [zapd_exe, "ed", "-i", xmlPath, "-b", rom, "-fl", "CFG/filelists",
|
||||
"-o", "placeholder", "-osf", "placeholder", "-gsf", "1",
|
||||
"-rconf", "CFG/Config.xml", "-se", "OTR"]
|
||||
|
||||
print(exec_cmd)
|
||||
exitValue = subprocess.call(exec_cmd)
|
||||
if exitValue != 0:
|
||||
print("\n")
|
||||
print("Error when building the OTR file...", file=os.sys.stderr)
|
||||
@@ -20,13 +27,19 @@ def BuildOTR(xmlPath, rom):
|
||||
print("\n")
|
||||
|
||||
def main():
|
||||
rom_path = rom_chooser.chooseROM()
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-z", "--zapd", help="Path to ZAPD executable", dest="zapd_exe", type=str)
|
||||
parser.add_argument("rom", help="Path to the rom", type=str, nargs="?")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
rom_path = args.rom if args.rom else rom_chooser.chooseROM()
|
||||
rom = Z64Rom(rom_path)
|
||||
|
||||
if (os.path.exists("Extract")):
|
||||
shutil.rmtree("Extract")
|
||||
|
||||
BuildOTR("../soh/assets/xml/" + rom.version.xml_ver + "/", rom_path)
|
||||
BuildOTR("../soh/assets/xml/" + rom.version.xml_ver + "/", rom_path, zapd_exe=args.zapd_exe)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -36,6 +36,7 @@ class RomVersion:
|
||||
ROM_INFO_TABLE = dict()
|
||||
ROM_INFO_TABLE[Checksums.OOT_PAL_GC] = RomVersion("CFG/filelists/gamecube_pal.txt", 0x7170, "GC_NMQ_PAL_F")
|
||||
ROM_INFO_TABLE[Checksums.OOT_PAL_GC_DBG1] = RomVersion("CFG/filelists/dbg.txt", 0x12F70, "GC_NMQ_D")
|
||||
ROM_INFO_TABLE[Checksums.OOT_PAL_GC_MQ_DBG] = RomVersion("CFG/filelists/dbg.txt", 0x12F70, "GC_MQ_D")
|
||||
|
||||
class RomDmaEntry:
|
||||
def __init__(self, rom, i):
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
################################################################################
|
||||
# Command for variable_watch. This command issues error message, if a variable
|
||||
# is changed. If variable PROPERTY_READER_GUARD_DISABLED is TRUE nothing happens
|
||||
# variable_watch(<variable> property_reader_guard)
|
||||
################################################################################
|
||||
function(property_reader_guard VARIABLE ACCESS VALUE CURRENT_LIST_FILE STACK)
|
||||
if("${PROPERTY_READER_GUARD_DISABLED}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if("${ACCESS}" STREQUAL "MODIFIED_ACCESS")
|
||||
message(FATAL_ERROR
|
||||
" Variable ${VARIABLE} is not supposed to be changed.\n"
|
||||
" It is used only for reading target property ${VARIABLE}.\n"
|
||||
" Use\n"
|
||||
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}\" \"<value>\")\n"
|
||||
" or\n"
|
||||
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}_<CONFIG>\" \"<value>\")\n"
|
||||
" instead.\n")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Create variable <name> with generator expression that expands to value of
|
||||
# target property <name>_<CONFIG>. If property is empty or not set then property
|
||||
# <name> is used instead. Variable <name> has watcher property_reader_guard that
|
||||
# doesn't allow to edit it.
|
||||
# create_property_reader(<name>)
|
||||
# Input:
|
||||
# name - Name of watched property and output variable
|
||||
################################################################################
|
||||
function(create_property_reader NAME)
|
||||
set(PROPERTY_READER_GUARD_DISABLED TRUE)
|
||||
set(CONFIG_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}_$<UPPER_CASE:$<CONFIG>>>>")
|
||||
set(IS_CONFIG_VALUE_EMPTY "$<STREQUAL:${CONFIG_VALUE},>")
|
||||
set(GENERAL_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}>>")
|
||||
set("${NAME}" "$<IF:${IS_CONFIG_VALUE_EMPTY},${GENERAL_VALUE},${CONFIG_VALUE}>" PARENT_SCOPE)
|
||||
variable_watch("${NAME}" property_reader_guard)
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Set property $<name>_${PROPS_CONFIG_U} of ${PROPS_TARGET} to <value>
|
||||
# set_config_specific_property(<name> <value>)
|
||||
# Input:
|
||||
# name - Prefix of property name
|
||||
# value - New value
|
||||
################################################################################
|
||||
function(set_config_specific_property NAME VALUE)
|
||||
set_target_properties("${PROPS_TARGET}" PROPERTIES "${NAME}_${PROPS_CONFIG_U}" "${VALUE}")
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
|
||||
create_property_reader("TARGET_NAME")
|
||||
create_property_reader("OUTPUT_DIRECTORY")
|
||||
|
||||
set_config_specific_property("TARGET_NAME" "${PROPS_TARGET}")
|
||||
set_config_specific_property("OUTPUT_NAME" "${TARGET_NAME}")
|
||||
set_config_specific_property("ARCHIVE_OUTPUT_NAME" "${TARGET_NAME}")
|
||||
set_config_specific_property("LIBRARY_OUTPUT_NAME" "${TARGET_NAME}")
|
||||
set_config_specific_property("RUNTIME_OUTPUT_NAME" "${TARGET_NAME}")
|
||||
|
||||
set_config_specific_property("ARCHIVE_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
|
||||
set_config_specific_property("LIBRARY_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
|
||||
set_config_specific_property("RUNTIME_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
|
||||
@@ -0,0 +1,12 @@
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/Default.cmake")
|
||||
|
||||
set_config_specific_property("OUTPUT_DIRECTORY" "${CMAKE_SOURCE_DIR}$<$<NOT:$<STREQUAL:${CMAKE_VS_PLATFORM_NAME},Win32>>:/${CMAKE_VS_PLATFORM_NAME}>/${PROPS_CONFIG}")
|
||||
|
||||
if(MSVC)
|
||||
create_property_reader("DEFAULT_CXX_EXCEPTION_HANDLING")
|
||||
create_property_reader("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT")
|
||||
|
||||
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
|
||||
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
|
||||
endif()
|
||||
@@ -0,0 +1,234 @@
|
||||
# utils file for projects came from visual studio solution with cmake-converter.
|
||||
|
||||
################################################################################
|
||||
# Wrap each token of the command with condition
|
||||
################################################################################
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
macro(prepare_commands)
|
||||
unset(TOKEN_ROLE)
|
||||
unset(COMMANDS)
|
||||
foreach(TOKEN ${ARG_COMMANDS})
|
||||
if("${TOKEN}" STREQUAL "COMMAND")
|
||||
set(TOKEN_ROLE "KEYWORD")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "KEYWORD")
|
||||
set(TOKEN_ROLE "CONDITION")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
|
||||
set(TOKEN_ROLE "COMMAND")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
|
||||
set(TOKEN_ROLE "ARG")
|
||||
endif()
|
||||
|
||||
if("${TOKEN_ROLE}" STREQUAL "KEYWORD")
|
||||
list(APPEND COMMANDS "${TOKEN}")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
|
||||
set(CONDITION ${TOKEN})
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
|
||||
list(APPEND COMMANDS "$<$<NOT:${CONDITION}>:${DUMMY}>$<${CONDITION}:${TOKEN}>")
|
||||
elseif("${TOKEN_ROLE}" STREQUAL "ARG")
|
||||
list(APPEND COMMANDS "$<${CONDITION}:${TOKEN}>")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
cmake_policy(POP)
|
||||
|
||||
################################################################################
|
||||
# Transform all the tokens to absolute paths
|
||||
################################################################################
|
||||
macro(prepare_output)
|
||||
unset(OUTPUT)
|
||||
foreach(TOKEN ${ARG_OUTPUT})
|
||||
if(IS_ABSOLUTE ${TOKEN})
|
||||
list(APPEND OUTPUT "${TOKEN}")
|
||||
else()
|
||||
list(APPEND OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${TOKEN}")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
################################################################################
|
||||
# Parse add_custom_command_if args.
|
||||
#
|
||||
# Input:
|
||||
# PRE_BUILD - Pre build event option
|
||||
# PRE_LINK - Pre link event option
|
||||
# POST_BUILD - Post build event option
|
||||
# TARGET - Target
|
||||
# OUTPUT - List of output files
|
||||
# DEPENDS - List of files on which the command depends
|
||||
# COMMANDS - List of commands(COMMAND condition1 commannd1 args1 COMMAND
|
||||
# condition2 commannd2 args2 ...)
|
||||
# Output:
|
||||
# OUTPUT - Output files
|
||||
# DEPENDS - Files on which the command depends
|
||||
# COMMENT - Comment
|
||||
# PRE_BUILD - TRUE/FALSE
|
||||
# PRE_LINK - TRUE/FALSE
|
||||
# POST_BUILD - TRUE/FALSE
|
||||
# TARGET - Target name
|
||||
# COMMANDS - Prepared commands(every token is wrapped in CONDITION)
|
||||
# NAME - Unique name for custom target
|
||||
# STEP - PRE_BUILD/PRE_LINK/POST_BUILD
|
||||
################################################################################
|
||||
function(add_custom_command_if_parse_arguments)
|
||||
cmake_parse_arguments("ARG" "PRE_BUILD;PRE_LINK;POST_BUILD" "TARGET;COMMENT" "DEPENDS;OUTPUT;COMMANDS" ${ARGN})
|
||||
|
||||
if(WIN32)
|
||||
set(DUMMY "cd.")
|
||||
elseif(UNIX)
|
||||
set(DUMMY "true")
|
||||
endif()
|
||||
|
||||
prepare_commands()
|
||||
prepare_output()
|
||||
|
||||
set(DEPENDS "${ARG_DEPENDS}")
|
||||
set(COMMENT "${ARG_COMMENT}")
|
||||
set(PRE_BUILD "${ARG_PRE_BUILD}")
|
||||
set(PRE_LINK "${ARG_PRE_LINK}")
|
||||
set(POST_BUILD "${ARG_POST_BUILD}")
|
||||
set(TARGET "${ARG_TARGET}")
|
||||
if(PRE_BUILD)
|
||||
set(STEP "PRE_BUILD")
|
||||
elseif(PRE_LINK)
|
||||
set(STEP "PRE_LINK")
|
||||
elseif(POST_BUILD)
|
||||
set(STEP "POST_BUILD")
|
||||
endif()
|
||||
set(NAME "${TARGET}_${STEP}")
|
||||
|
||||
set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
|
||||
set(DEPENDS "${DEPENDS}" PARENT_SCOPE)
|
||||
set(COMMENT "${COMMENT}" PARENT_SCOPE)
|
||||
set(PRE_BUILD "${PRE_BUILD}" PARENT_SCOPE)
|
||||
set(PRE_LINK "${PRE_LINK}" PARENT_SCOPE)
|
||||
set(POST_BUILD "${POST_BUILD}" PARENT_SCOPE)
|
||||
set(TARGET "${TARGET}" PARENT_SCOPE)
|
||||
set(COMMANDS "${COMMANDS}" PARENT_SCOPE)
|
||||
set(STEP "${STEP}" PARENT_SCOPE)
|
||||
set(NAME "${NAME}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Add conditional custom command
|
||||
#
|
||||
# Generating Files
|
||||
# The first signature is for adding a custom command to produce an output:
|
||||
# add_custom_command_if(
|
||||
# <OUTPUT output1 [output2 ...]>
|
||||
# <COMMANDS>
|
||||
# <COMMAND condition command1 [args1...]>
|
||||
# [COMMAND condition command2 [args2...]]
|
||||
# [DEPENDS [depends...]]
|
||||
# [COMMENT comment]
|
||||
#
|
||||
# Build Events
|
||||
# add_custom_command_if(
|
||||
# <TARGET target>
|
||||
# <PRE_BUILD | PRE_LINK | POST_BUILD>
|
||||
# <COMMAND condition command1 [args1...]>
|
||||
# [COMMAND condition command2 [args2...]]
|
||||
# [COMMENT comment]
|
||||
#
|
||||
# Input:
|
||||
# output - Output files the command is expected to produce
|
||||
# condition - Generator expression for wrapping the command
|
||||
# command - Command-line(s) to execute at build time.
|
||||
# args - Command`s args
|
||||
# depends - Files on which the command depends
|
||||
# comment - Display the given message before the commands are executed at
|
||||
# build time.
|
||||
# PRE_BUILD - Run before any other rules are executed within the target
|
||||
# PRE_LINK - Run after sources have been compiled but before linking the
|
||||
# binary
|
||||
# POST_BUILD - Run after all other rules within the target have been
|
||||
# executed
|
||||
################################################################################
|
||||
function(add_custom_command_if)
|
||||
add_custom_command_if_parse_arguments(${ARGN})
|
||||
|
||||
if(OUTPUT AND TARGET)
|
||||
message(FATAL_ERROR "Wrong syntax. A TARGET and OUTPUT can not both be specified.")
|
||||
endif()
|
||||
|
||||
if(OUTPUT)
|
||||
add_custom_command(OUTPUT ${OUTPUT}
|
||||
${COMMANDS}
|
||||
DEPENDS ${DEPENDS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT ${COMMENT})
|
||||
elseif(TARGET)
|
||||
if(PRE_BUILD AND NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio")
|
||||
add_custom_target(
|
||||
${NAME}
|
||||
${COMMANDS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT ${COMMENT})
|
||||
add_dependencies(${TARGET} ${NAME})
|
||||
else()
|
||||
add_custom_command(
|
||||
TARGET ${TARGET}
|
||||
${STEP}
|
||||
${COMMANDS}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT ${COMMENT})
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Wrong syntax. A TARGET or OUTPUT must be specified.")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Use props file for a target and configs
|
||||
# use_props(<target> <configs...> <props_file>)
|
||||
# Inside <props_file> there are following variables:
|
||||
# PROPS_TARGET - <target>
|
||||
# PROPS_CONFIG - One of <configs...>
|
||||
# PROPS_CONFIG_U - Uppercase PROPS_CONFIG
|
||||
# Input:
|
||||
# target - Target to apply props file
|
||||
# configs - Build configurations to apply props file
|
||||
# props_file - CMake script
|
||||
################################################################################
|
||||
macro(use_props TARGET CONFIGS PROPS_FILE)
|
||||
set(PROPS_TARGET "${TARGET}")
|
||||
foreach(PROPS_CONFIG ${CONFIGS})
|
||||
string(TOUPPER "${PROPS_CONFIG}" PROPS_CONFIG_U)
|
||||
|
||||
get_filename_component(ABSOLUTE_PROPS_FILE "${PROPS_FILE}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
||||
if(EXISTS "${ABSOLUTE_PROPS_FILE}")
|
||||
include("${ABSOLUTE_PROPS_FILE}")
|
||||
else()
|
||||
message(WARNING "Corresponding cmake file from props \"${ABSOLUTE_PROPS_FILE}\" doesn't exist")
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
################################################################################
|
||||
# Add compile options to source file
|
||||
# source_file_compile_options(<source_file> [compile_options...])
|
||||
# Input:
|
||||
# source_file - Source file
|
||||
# compile_options - Options to add to COMPILE_FLAGS property
|
||||
################################################################################
|
||||
function(source_file_compile_options SOURCE_FILE)
|
||||
if("${ARGC}" LESS_EQUAL "1")
|
||||
return()
|
||||
endif()
|
||||
|
||||
get_source_file_property(COMPILE_OPTIONS "${SOURCE_FILE}" COMPILE_OPTIONS)
|
||||
|
||||
if(COMPILE_OPTIONS)
|
||||
list(APPEND COMPILE_OPTIONS ${ARGN})
|
||||
else()
|
||||
set(COMPILE_OPTIONS "${ARGN}")
|
||||
endif()
|
||||
|
||||
set_source_files_properties("${SOURCE_FILE}" PROPERTIES COMPILE_OPTIONS "${COMPILE_OPTIONS}")
|
||||
endfunction()
|
||||
|
||||
################################################################################
|
||||
# Default properties of visual studio projects
|
||||
################################################################################
|
||||
set(DEFAULT_CXX_PROPS "${CMAKE_CURRENT_LIST_DIR}/DefaultCXX.cmake")
|
||||
set(DEFAULT_Fortran_PROPS "${CMAKE_CURRENT_LIST_DIR}/DefaultFortran.cmake")
|
||||
+44
-10
@@ -3,27 +3,61 @@ project(OTRGui)
|
||||
|
||||
set(PLATFORM "Desktop")
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
set(APP_ICON_RESOURCE_WINDOWS ${CMAKE_CURRENT_SOURCE_DIR}/appicon.rc)
|
||||
|
||||
add_subdirectory(libs/raylib)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(OpenGL_GL_PREFERENCE "GLVND")
|
||||
endif()
|
||||
|
||||
include(CMake/Utils.cmake)
|
||||
|
||||
add_subdirectory(libs/raylib EXCLUDE_FROM_ALL)
|
||||
|
||||
include_directories(src)
|
||||
include_directories(src/game)
|
||||
include_directories(include)
|
||||
|
||||
include_external_msproject(ZAPD ../../ZAPDTR/ZAPD/ZAPD.vcproj)
|
||||
include_external_msproject(ZAPDUtils ../../ZAPDTR/ZAPDUtils/ZAPDUtils.vcproj)
|
||||
include_external_msproject(libultraship ../../libultraship/libultraship/libultraship.vcproj)
|
||||
include_external_msproject(OTRExporter ../../OTRExporter/OTRExporter/OTRExporter.vcproj)
|
||||
if (NOT TARGET libultraship)
|
||||
add_subdirectory(../libultraship/libultraship ${CMAKE_BINARY_DIR}/libultraship)
|
||||
endif()
|
||||
if (NOT TARGET ZAPD)
|
||||
add_subdirectory(../ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
|
||||
endif()
|
||||
if (NOT TARGET ZAPDUtils)
|
||||
add_subdirectory(../ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils)
|
||||
endif()
|
||||
if (NOT TARGET OTRExporter)
|
||||
add_subdirectory(../OTRExporter/OTRExporter ${CMAKE_BINARY_DIR}/OTRExporter)
|
||||
endif()
|
||||
if (NOT TARGET storm)
|
||||
add_subdirectory(../StormLib ${CMAKE_BINARY_DIR}/StormLib)
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE HEADERS src/*.h)
|
||||
file(GLOB_RECURSE SOURCES src/*.cpp)
|
||||
file(GLOB_RECURSE C_SOURCES src/*.c)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} ${C_SOURCES} ${HEADERS} ${APP_ICON_RESOURCE_WINDOWS})
|
||||
add_custom_command(TARGET ${PROJECT_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_SOURCE_DIR}/assets" -Ddst_dir="${CMAKE_CURRENT_BINARY_DIR}/assets" -P "${CMAKE_CURRENT_SOURCE_DIR}/Overwrite.cmake")
|
||||
add_custom_command(TARGET ${PROJECT_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_SOURCE_DIR}/../OTRExporter/assets" -Ddst_dir="${CMAKE_CURRENT_BINARY_DIR}/assets/game" -P "${CMAKE_CURRENT_SOURCE_DIR}/Overwrite.cmake")
|
||||
add_custom_command(TARGET ${PROJECT_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_SOURCE_DIR}/../soh/assets/xml" -Ddst_dir="${CMAKE_CURRENT_BINARY_DIR}/assets/extractor/xmls" -P "${CMAKE_CURRENT_SOURCE_DIR}/Overwrite.cmake")
|
||||
add_executable(${PROJECT_NAME} EXCLUDE_FROM_ALL ${SOURCES} ${C_SOURCES} ${HEADERS} ${APP_ICON_RESOURCE_WINDOWS})
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||
endif()
|
||||
|
||||
add_custom_target(Assets ALL
|
||||
COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_CURRENT_SOURCE_DIR}/assets" -Ddst_dir="${CMAKE_CURRENT_BINARY_DIR}/assets" -P "${CMAKE_CURRENT_SOURCE_DIR}/Overwrite.cmake"
|
||||
COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_CURRENT_SOURCE_DIR}/../OTRExporter/assets" -Ddst_dir="${CMAKE_CURRENT_BINARY_DIR}/assets/game" -P "${CMAKE_CURRENT_SOURCE_DIR}/Overwrite.cmake"
|
||||
COMMAND ${CMAKE_COMMAND} -Dsrc_dir="${CMAKE_CURRENT_SOURCE_DIR}/../soh/assets/xml" -Ddst_dir="${CMAKE_CURRENT_BINARY_DIR}/assets/extractor/xmls" -P "${CMAKE_CURRENT_SOURCE_DIR}/Overwrite.cmake"
|
||||
)
|
||||
|
||||
add_dependencies(OTRGui Assets)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC raylib)
|
||||
|
||||
INSTALL(TARGETS OTRGui DESTINATION . COMPONENT ship)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/assets
|
||||
DESTINATION .
|
||||
COMPONENT ship
|
||||
)
|
||||
INSTALL(TARGETS ZAPD DESTINATION assets/extractor COMPONENT ship)
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
file(GLOB_RECURSE _file_list RELATIVE "${src_dir}" "${src_dir}/*")
|
||||
include(CMakePrintHelpers)
|
||||
|
||||
string(REPLACE "\\ " " " sources_dir "${src_dir}")
|
||||
string(REPLACE "\\ " " " destination_dir "${dst_dir}")
|
||||
|
||||
file(GLOB_RECURSE _file_list RELATIVE "${sources_dir}" "${sources_dir}/*")
|
||||
|
||||
foreach( each_file ${_file_list} )
|
||||
set(destinationfile "${dst_dir}/${each_file}")
|
||||
set(sourcefile "${src_dir}/${each_file}")
|
||||
set(destinationfile "${destination_dir}/${each_file}")
|
||||
set(sourcefile "${sources_dir}/${each_file}")
|
||||
if(NOT EXISTS ${destinationfile} OR ${sourcefile} IS_NEWER_THAN ${destinationfile})
|
||||
get_filename_component(destinationdir ${destinationfile} DIRECTORY)
|
||||
file(COPY ${sourcefile} DESTINATION ${destinationdir})
|
||||
endif()
|
||||
endforeach(each_file)
|
||||
endforeach(each_file)
|
||||
|
||||
@@ -91,7 +91,6 @@ void ExtractRom()
|
||||
//MoonUtils::copy("tmp/baserom/Audioseq", "Extract/Audioseq");
|
||||
//MoonUtils::copy("tmp/baserom/Audiotable", "Extract/Audiotable");
|
||||
//MoonUtils::copy("tmp/baserom/version", "Extract/version");
|
||||
MoonUtils::write("Extract/version", (char*)&version.crc, sizeof(version.crc));
|
||||
|
||||
MoonUtils::copy("assets/game/", "Extract/assets/");
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ std::string GetXMLVersion(RomVersion version)
|
||||
switch (version.crc)
|
||||
{
|
||||
case OOT_PAL_GC_DBG1: return "GC_NMQ_D";
|
||||
case OOT_PAL_GC_DBG2: return "GC_MQ_D";
|
||||
case OOT_PAL_GC_MQ_DBG: return "GC_MQ_D";
|
||||
case OOT_PAL_GC: return "GC_NMQ_PAL_F";
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ void startWorker(RomVersion version) {
|
||||
|
||||
path += GetXMLVersion(version);
|
||||
|
||||
Util::write("tmp/baserom/version", (char*)&version.crc, sizeof(version.crc));
|
||||
// Util::write("tmp/baserom/version", (char*)&version.crc, sizeof(version.crc));
|
||||
|
||||
if (oldExtractMode)
|
||||
{
|
||||
@@ -144,4 +144,4 @@ void updateWorker(const std::string& output) {
|
||||
std::thread otr(BuildOTR, output);
|
||||
otr.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ The Ship does not include assets and as such requires a prior copy of the game t
|
||||
4) Launch `soh.exe`
|
||||
|
||||
### Supported Games
|
||||
#### Ocarina of Time Debug (not Master Quest)
|
||||
#### Ocarina of Time Debug PAL GC (not Master Quest)
|
||||
> Currently the recommended option
|
||||
```
|
||||
Build team: `zelda@srd022j`
|
||||
@@ -24,6 +24,13 @@ sha1: cee6bc3c2a634b41728f2af8da54d9bf8cc14099
|
||||
```
|
||||
sha1: 0227d7c0074f2d0ac935631990da8ec5914597b4
|
||||
```
|
||||
#### Ocarina of Time Debug PAL GC MQ (Dungeons will be Master Quest)
|
||||
```
|
||||
Build team: `zelda@srd022j`
|
||||
Build date: `03-02-21 00:16:31` (year-month-day)
|
||||
sha1: 079b855b943d6ad8bd1eb026c0ed169ecbdac7da (Produced by decomp)
|
||||
sha1: 50bebedad9e0f10746a52b07239e47fa6c284d03 (Alternate)
|
||||
```
|
||||
|
||||
Congratulations, you are now sailing with the Ship of Harkinian! Have fun!
|
||||
|
||||
@@ -31,10 +38,10 @@ Congratulations, you are now sailing with the Ship of Harkinian! Have fun!
|
||||
|
||||
The Ship of Harkinian uses a proprietary versioning system consisting of a sci-fi film character followed by a phonetic alphabet code word. The film character represents a major release version which increments with the addition of many new features and bug fixes. The code word represents a minor release version which increments with small updates mainly comprised of bug fixes. For example, `DECKARD ALFA`.
|
||||
|
||||
### The Extraction Tool
|
||||
### Windows Rom Extraction
|
||||
|
||||
* Open a rom to initiate generating the `oot.otr` archive file.
|
||||
* If a second button exists then `oot.otr` already exists. To prevent overwriting the old `oot.otr` use this button to choose a new game directory. The new directory must not already contain an `oot.otr` to prevent an error.
|
||||
* Open OTRGui.exe, and select one of the supported roms listed above, to generate the `oot.otr` archive file.
|
||||
* If a second button already exits then `oot.otr` already exists. To prevent overwriting the old `oot.otr` use this button to choose a new game directory. The new directory must not already contain an `oot.otr` to prevent an error.
|
||||
* When the process completes, place `oot.otr` beside `soh.exe` if it is not already.
|
||||
|
||||
This packaging process can take up to **5 minutes**.
|
||||
@@ -42,6 +49,37 @@ This packaging process can take up to **5 minutes**.
|
||||
Close the OTRGui when the `Done!` message appears.
|
||||
If you get another message, then you might have selected the wrong rom. Make sure to use a rom consistent with the above checksum.
|
||||
|
||||
### Linux Rom Extraction
|
||||
|
||||
* Place one of the supported roms in the same folder as the appimage.
|
||||
* When you run the soh appimage, it should begin generating the `oot.otr` archive file.
|
||||
* When the process completes, place `oot.otr` in the same folder as the appimage, if it is not already, then run the appimage.
|
||||
|
||||
The packaging process can take up to **5 minutes**.
|
||||
|
||||
If you get any errors, then you might have selected the wrong rom. Make sure to use a rom consistent with the above checksum.
|
||||
|
||||
### MacOS Rom Extraction
|
||||
|
||||
* Run `soh.app`, and when prompted, select one of the supported roms listed above.
|
||||
* You should see a notification saying `Processing OTR`, then, once the process is complete, you should get a notification saying `OTR Successfully Generated`, then the game should start.
|
||||
|
||||
The packing process can take up to **5 minutes**.
|
||||
|
||||
If you get an error saying `Incompatible ROM hash`, you have selected the wrong rom, make sure the checksum matches one of the ones listed above.
|
||||
|
||||
### Nintendo Switch Rom Extraction
|
||||
|
||||
* Download the latest PC release of the Ship of Harkinian, and follow the instructions above for generating the `oot.otr` archive on that platform.
|
||||
* Place the `.nro` and the `oot.otr` archive into a folder called `soh` in your Switch folder on your Switch
|
||||
|
||||
### Nintendo Wii U Rom Extraction
|
||||
|
||||
* Download the latest PC release of the Ship of Harkinian, and follow the instructions above for generating the `oot.otr` archive on that platform.
|
||||
* Copy the `.rpx` and the `oot.otr` archive to `wiiu/apps/soh`
|
||||
|
||||
---
|
||||
|
||||
If you still cannot get the tool to work, join our [Discord Server](https://discord.com/invite/BtBmd55HVH) and ask for help in the `#support` text channel. Keep-in-mind that we do not condone piracy in any way.
|
||||
|
||||
### Running The Ship of Harkinian
|
||||
@@ -64,7 +102,7 @@ Other shortcuts:
|
||||
| Alt+Enter | Fullscreen (DirectX) |
|
||||
| Ctrl+R | Reset |
|
||||
|
||||
Currently, DirectX 11 and OpenGL are supported. Change the renderer by opening the `shipofharkinian.ini` configuration file in notepad and add `sdl` to `gfx backend` for OpenGL or leave blank for DirectX.
|
||||
Currently, DirectX 11 and OpenGL are supported. Change the renderer by opening the `shipofharkinian.json` configuration file in notepad and add `sdl` to the quotes in `"GfxBackend": ""` for OpenGL or leave blank for DirectX.
|
||||
|
||||
## Take The Survey
|
||||
Want to use cartridge readers in tandem with the OTRGui?
|
||||
@@ -83,7 +121,7 @@ Refer to the [building instructions](BUILDING.md) to compile SoH.
|
||||
- Confirm that `zapd.exe` exists in the `/assets/extractor` folder
|
||||
|
||||
## Nightly Builds
|
||||
Nightly builds of Ship of Harkinian are available [here](https://builds.shipofharkinian.com/job/SoH_Multibranch/job/develop)
|
||||
Nightly builds of Ship of Harkinian are available [here](https://builds.shipofharkinian.com/)
|
||||
|
||||
|
||||
## The Harbour Masters Are...
|
||||
@@ -123,7 +161,8 @@ Nightly builds of Ship of Harkinian are available [here](https://builds.shipofha
|
||||
|
||||
## Video Credits
|
||||
Kenix | Producer / Writer
|
||||
rainbow_fash | Executive Producer
|
||||
briaguya | Writer
|
||||
rainbow_fash | Executive Producer
|
||||
ReveriePass | Editor
|
||||
MicTheMicrophone | Gwonam / The King
|
||||
Amphibibro | Link
|
||||
|
||||
@@ -140,6 +140,7 @@ Desktop.ini
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
nxbuild
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
|
||||
+86
-2
@@ -1,8 +1,9 @@
|
||||
project(StormLib)
|
||||
set(PROJECT_NAME StormLib)
|
||||
#project(StormLib)
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
set(LIBRARY_NAME storm)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
@@ -15,6 +16,13 @@ option(STORM_BUILD_TESTS
|
||||
# "BUILD_TESTING" OFF # Stay coherent with CTest variables
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(Source_Files__Windows
|
||||
src/lzma/C/LzFindMt.c
|
||||
src/lzma/C/Threads.c
|
||||
)
|
||||
endif()
|
||||
|
||||
set(SRC_FILES
|
||||
src/adpcm/adpcm.cpp
|
||||
src/huffman/huff.cpp
|
||||
@@ -46,6 +54,7 @@ set(SRC_FILES
|
||||
src/SFileVerify.cpp
|
||||
src/libtomcrypt/src/pk/rsa/rsa_verify_simple.c
|
||||
src/libtomcrypt/src/misc/crypt_libc.c
|
||||
${Source_Files__Windows}
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
@@ -323,11 +332,86 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DO_LARGEFILE=0 -Dstat64=stat -Dlstat64=lstat -Dlseek64=lseek -Doff64_t=off_t -Dfstat64=fstat -Dftruncate64=ftruncate")
|
||||
endif()
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
|
||||
# Enable POSIX extensions such as `readlink` and `ftruncate`.
|
||||
add_definitions(-D_POSIX_C_SOURCE=200809L)
|
||||
endif()
|
||||
|
||||
add_library(${LIBRARY_NAME} ${LIB_TYPE} ${SRC_FILES} ${SRC_ADDITIONAL_FILES} ${STORM_DEF_FILES})
|
||||
if(WIN32)
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES OUTPUT_NAME "StormLib")
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
use_props(${LIBRARY_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Compile definitions
|
||||
################################################################################
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_definitions(${LIBRARY_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG;"
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
WIN32
|
||||
_LIB
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
target_compile_definitions(${LIBRARY_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG;"
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG;"
|
||||
">"
|
||||
"WIN32;"
|
||||
_LIB
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# MSVC runtime library
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${LIBRARY_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||
$<$<CONFIG:Debug>:
|
||||
MultiThreadedDebug
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
MultiThreaded
|
||||
>
|
||||
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||
$<$<CONFIG:Debug>:
|
||||
MultiThreadedDebug
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
MultiThreaded
|
||||
>
|
||||
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
||||
)
|
||||
endif()
|
||||
set_target_properties(${LIBRARY_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
||||
endif()
|
||||
|
||||
|
||||
target_link_libraries(${LIBRARY_NAME} ${LINK_LIBS})
|
||||
target_compile_definitions(${LIBRARY_NAME} INTERFACE STORMLIB_NO_AUTO_LINK) #CMake will take care of the linking
|
||||
target_include_directories(${LIBRARY_NAME} PUBLIC src/)
|
||||
|
||||
@@ -34,7 +34,12 @@
|
||||
// Local functions - platform-specific functions
|
||||
|
||||
#ifndef STORMLIB_WINDOWS
|
||||
|
||||
#ifndef STORMLIB_WIIU // WIIU doesn't support thread_local
|
||||
static thread_local DWORD dwLastError = ERROR_SUCCESS;
|
||||
#else
|
||||
static DWORD dwLastError = ERROR_SUCCESS;
|
||||
#endif
|
||||
|
||||
DWORD GetLastError()
|
||||
{
|
||||
|
||||
@@ -2005,7 +2005,7 @@ void ConvertTMPQHeader(void *header, uint16_t version)
|
||||
TMPQHeader * theHeader = (TMPQHeader *)header;
|
||||
|
||||
// Swap header part version 1
|
||||
if(version == MPQ_FORMAT_VERSION_1)
|
||||
if(version >= MPQ_FORMAT_VERSION_1)
|
||||
{
|
||||
theHeader->dwID = SwapUInt32(theHeader->dwID);
|
||||
theHeader->dwHeaderSize = SwapUInt32(theHeader->dwHeaderSize);
|
||||
@@ -2018,21 +2018,21 @@ void ConvertTMPQHeader(void *header, uint16_t version)
|
||||
theHeader->dwBlockTableSize = SwapUInt32(theHeader->dwBlockTableSize);
|
||||
}
|
||||
|
||||
if(version == MPQ_FORMAT_VERSION_2)
|
||||
if(version >= MPQ_FORMAT_VERSION_2)
|
||||
{
|
||||
theHeader->HiBlockTablePos64 = SwapUInt64(theHeader->HiBlockTablePos64);
|
||||
theHeader->wHashTablePosHi = SwapUInt16(theHeader->wHashTablePosHi);
|
||||
theHeader->wBlockTablePosHi = SwapUInt16(theHeader->wBlockTablePosHi);
|
||||
}
|
||||
|
||||
if(version == MPQ_FORMAT_VERSION_3)
|
||||
if(version >= MPQ_FORMAT_VERSION_3)
|
||||
{
|
||||
theHeader->ArchiveSize64 = SwapUInt64(theHeader->ArchiveSize64);
|
||||
theHeader->BetTablePos64 = SwapUInt64(theHeader->BetTablePos64);
|
||||
theHeader->HetTablePos64 = SwapUInt64(theHeader->HetTablePos64);
|
||||
}
|
||||
|
||||
if(version == MPQ_FORMAT_VERSION_4)
|
||||
if(version >= MPQ_FORMAT_VERSION_4)
|
||||
{
|
||||
theHeader->HashTableSize64 = SwapUInt64(theHeader->HashTableSize64);
|
||||
theHeader->BlockTableSize64 = SwapUInt64(theHeader->BlockTableSize64);
|
||||
|
||||
@@ -180,7 +180,7 @@ static DWORD LoadAttributesFile(TMPQArchive * ha, LPBYTE pbAttrFile, DWORD cbAtt
|
||||
if((pbAttrPtr + cbArraySize) > pbAttrFileEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
BSWAP_ARRAY32_UNSIGNED(ArrayCRC32, cbCRC32Size);
|
||||
BSWAP_ARRAY32_UNSIGNED(ArrayCRC32, cbArraySize);
|
||||
for(i = 0; i < dwAttributesEntries; i++)
|
||||
ha->pFileTable[i].dwCrc32 = ArrayCRC32[i];
|
||||
pbAttrPtr += cbArraySize;
|
||||
@@ -196,7 +196,7 @@ static DWORD LoadAttributesFile(TMPQArchive * ha, LPBYTE pbAttrFile, DWORD cbAtt
|
||||
if((pbAttrPtr + cbArraySize) > pbAttrFileEnd)
|
||||
return ERROR_FILE_CORRUPT;
|
||||
|
||||
BSWAP_ARRAY64_UNSIGNED(ArrayFileTime, cbFileTimeSize);
|
||||
BSWAP_ARRAY64_UNSIGNED(ArrayFileTime, cbArraySize);
|
||||
for(i = 0; i < dwAttributesEntries; i++)
|
||||
ha->pFileTable[i].FileTime = ArrayFileTime[i];
|
||||
pbAttrPtr += cbArraySize;
|
||||
|
||||
@@ -480,7 +480,7 @@ static bool IsMatchingPatchFile(
|
||||
{
|
||||
// Load the patch header
|
||||
SFileReadFile(hFile, &PatchHeader, sizeof(MPQ_PATCH_HEADER), &dwTransferred, NULL);
|
||||
BSWAP_ARRAY32_UNSIGNED(pPatchHeader, sizeof(DWORD) * 6);
|
||||
BSWAP_ARRAY32_UNSIGNED(&PatchHeader, sizeof(DWORD) * 6);
|
||||
|
||||
// If the file contains an incremental patch,
|
||||
// compare the "MD5 before patching" with the base file MD5
|
||||
|
||||
@@ -631,8 +631,8 @@ typedef struct _TMPQHash
|
||||
|
||||
#else
|
||||
|
||||
BYTE Platform;
|
||||
BYTE Reserved;
|
||||
BYTE Platform;
|
||||
USHORT lcLocale;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
|
||||
#define PKEXPORT
|
||||
|
||||
#ifndef __SYS_ZLIB
|
||||
#ifndef __SYS_ZLIB
|
||||
#define __SYS_ZLIB
|
||||
#endif
|
||||
|
||||
@@ -254,6 +254,34 @@
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines for Wii U platform
|
||||
|
||||
#if !defined(STORMLIB_PLATFORM_DEFINED) && defined(__WIIU__)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#undef STORMLIB_LITTLE_ENDIAN // Wii U is always big endian
|
||||
|
||||
#define STORMLIB_MAC // Use Mac compatible code
|
||||
#define STORMLIB_WIIU
|
||||
#define STORMLIB_PLATFORM_DEFINED
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Assumption: If the platform is not defined, assume a Linux-like platform
|
||||
|
||||
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
# use variables in submakes
|
||||
export
|
||||
OPTIMIZATION_ON ?= 1
|
||||
ASAN ?= 0
|
||||
DEPRECATION_ON ?= 1
|
||||
DEBUG ?= 0
|
||||
COPYCHECK_ARGS ?=
|
||||
LLD ?= 0
|
||||
WERROR ?= 0
|
||||
UNAME := $(shell uname)
|
||||
|
||||
# Use clang++ if available, else use g++
|
||||
ifeq ($(shell command -v clang++ >/dev/null 2>&1; echo $$?),0)
|
||||
CXX ?= clang++
|
||||
else
|
||||
CXX ?= g++
|
||||
endif
|
||||
|
||||
INC := -I ZAPD -I lib/elfio -I lib/libgfxd -I lib/tinyxml2 -I ZAPDUtils
|
||||
CXXFLAGS := -fpic -std=c++17 -Wall -Wextra -fno-omit-frame-pointer
|
||||
OPTFLAGS :=
|
||||
|
||||
ifneq ($(DEBUG),0)
|
||||
OPTIMIZATION_ON = 0
|
||||
CXXFLAGS += -g3 -DDEVELOPMENT -D_DEBUG
|
||||
COPYCHECK_ARGS += --devel
|
||||
DEPRECATION_ON = 0
|
||||
endif
|
||||
|
||||
ifneq ($(WERROR),0)
|
||||
CXXFLAGS += -Werror
|
||||
endif
|
||||
|
||||
ifeq ($(OPTIMIZATION_ON),0)
|
||||
OPTFLAGS := -O0
|
||||
else
|
||||
OPTFLAGS := -O2
|
||||
endif
|
||||
|
||||
ifneq ($(ASAN),0)
|
||||
CXXFLAGS += -fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined
|
||||
endif
|
||||
ifneq ($(DEPRECATION_ON),0)
|
||||
CXXFLAGS += -DDEPRECATION_ON
|
||||
endif
|
||||
# CXXFLAGS += -DTEXTURE_DEBUG
|
||||
|
||||
LDFLAGS := -lm -ldl \
|
||||
-L../StormLib/build -L../libultraship -lbz2 -pthread -lultraship -lstorm
|
||||
|
||||
ifeq ($(UNAME), Darwin)
|
||||
LDFLAGS += $(shell pkg-config --libs glew libpng zlib) $(shell sdl2-config --libs) -framework OpenGL -framework Foundation
|
||||
INC += $(shell pkg-config --cflags libpng)
|
||||
else
|
||||
LDFLAGS += -lpng -lGL -lGLEW -lX11 -lz -lSDL2 -lpulse
|
||||
endif
|
||||
|
||||
# Use LLD if available. Set LLD=0 to not use it
|
||||
ifeq ($(shell command -v ld.lld >/dev/null 2>&1; echo $$?),0)
|
||||
LLD := 1
|
||||
endif
|
||||
|
||||
ifneq ($(LLD),0)
|
||||
LDFLAGS += -fuse-ld=lld
|
||||
endif
|
||||
|
||||
UNAMEM := $(shell uname -m)
|
||||
ifneq ($(UNAME), Darwin)
|
||||
LDFLAGS += -Wl,-export-dynamic -lstdc++fs
|
||||
EXPORTERS := -Wl,--whole-archive ../OTRExporter/OTRExporter/OTRExporter.a -Wl,--no-whole-archive
|
||||
else
|
||||
EXPORTERS := -Wl,-force_load ../OTRExporter/OTRExporter/OTRExporter.a
|
||||
endif
|
||||
|
||||
|
||||
ZAPD_SRC_DIRS := $(shell find ZAPD -type d)
|
||||
SRC_DIRS = $(ZAPD_SRC_DIRS) lib/tinyxml2
|
||||
|
||||
ZAPD_CPP_FILES := $(foreach dir,$(ZAPD_SRC_DIRS),$(wildcard $(dir)/*.cpp))
|
||||
ZAPD_H_FILES := $(foreach dir,$(ZAPD_SRC_DIRS),$(wildcard $(dir)/*.h))
|
||||
|
||||
CPP_FILES += $(ZAPD_CPP_FILES) lib/tinyxml2/tinyxml2.cpp
|
||||
O_FILES := $(foreach f,$(CPP_FILES:.cpp=.o),build/$f)
|
||||
O_FILES += build/ZAPD/BuildInfo.o
|
||||
|
||||
# create build directories
|
||||
$(shell mkdir -p $(foreach dir,$(SRC_DIRS),build/$(dir)))
|
||||
|
||||
|
||||
# Main targets
|
||||
all: ZAPD.out copycheck
|
||||
|
||||
build/ZAPD/BuildInfo.o:
|
||||
python3 ZAPD/genbuildinfo.py $(COPYCHECK_ARGS)
|
||||
$(CXX) $(CXXFLAGS) $(OPTFLAGS) $(INC) -c $(OUTPUT_OPTION) build/ZAPD/BuildInfo.cpp
|
||||
|
||||
copycheck: ZAPD.out
|
||||
python3 copycheck.py
|
||||
|
||||
clean:
|
||||
rm -rf build ZAPD.out
|
||||
$(MAKE) -C lib/libgfxd clean
|
||||
$(MAKE) -C ZAPDUtils clean
|
||||
$(MAKE) -C ExporterTest clean
|
||||
rm -rf ../StormLib/build
|
||||
|
||||
rebuild: clean all
|
||||
|
||||
format:
|
||||
clang-format-11 -i $(ZAPD_CPP_FILES) $(ZAPD_H_FILES)
|
||||
$(MAKE) -C ZAPDUtils format
|
||||
$(MAKE) -C ExporterTest format
|
||||
|
||||
.PHONY: all build/ZAPD/BuildInfo.o copycheck clean rebuild format
|
||||
|
||||
build/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(OPTFLAGS) $(INC) -c $(OUTPUT_OPTION) $<
|
||||
|
||||
|
||||
# Submakes
|
||||
lib/libgfxd/libgfxd.a:
|
||||
$(MAKE) -C lib/libgfxd
|
||||
|
||||
.PHONY: StormLib
|
||||
StormLib:
|
||||
LDFLAGS="" cmake -B ../StormLib/build -S ../StormLib
|
||||
$(MAKE) -C ../StormLib/build
|
||||
|
||||
.PHONY: ExporterTest
|
||||
ExporterTest:
|
||||
$(MAKE) -C ExporterTest
|
||||
|
||||
.PHONY: ZAPDUtils
|
||||
ZAPDUtils:
|
||||
$(MAKE) -C ZAPDUtils
|
||||
|
||||
|
||||
# Linking
|
||||
ZAPD.out: $(O_FILES) lib/libgfxd/libgfxd.a ExporterTest ZAPDUtils StormLib
|
||||
$(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a ../StormLib/build/libstorm.a $(EXPORTERS) $(LDFLAGS) $(OUTPUT_OPTION)
|
||||
@@ -0,0 +1,492 @@
|
||||
set(PROJECT_NAME ZAPD)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
#set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use")
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
################################################################################
|
||||
# Source groups
|
||||
################################################################################
|
||||
set(Header_Files
|
||||
"../lib/tinyxml2/tinyxml2.h"
|
||||
"CRC32.h"
|
||||
"Declaration.h"
|
||||
"FileWorker.h"
|
||||
"GameConfig.h"
|
||||
"Globals.h"
|
||||
"ImageBackend.h"
|
||||
"OutputFormatter.h"
|
||||
"WarningHandler.h"
|
||||
)
|
||||
source_group("Header Files" FILES ${Header_Files})
|
||||
|
||||
set(Header_Files__Libraries
|
||||
"../../libultraship/libultraship/Lib/stb/stb_image.h"
|
||||
"../../libultraship/libultraship/Lib/stb/stb_image_write.h"
|
||||
"ctpl_stl.h"
|
||||
)
|
||||
source_group("Header Files\\Libraries" FILES ${Header_Files__Libraries})
|
||||
|
||||
set(Header_Files__Libraries__elfio
|
||||
"../lib/elfio/elfio/elf_types.hpp"
|
||||
"../lib/elfio/elfio/elfio.hpp"
|
||||
"../lib/elfio/elfio/elfio_dump.hpp"
|
||||
"../lib/elfio/elfio/elfio_dynamic.hpp"
|
||||
"../lib/elfio/elfio/elfio_header.hpp"
|
||||
"../lib/elfio/elfio/elfio_note.hpp"
|
||||
"../lib/elfio/elfio/elfio_relocation.hpp"
|
||||
"../lib/elfio/elfio/elfio_section.hpp"
|
||||
"../lib/elfio/elfio/elfio_segment.hpp"
|
||||
"../lib/elfio/elfio/elfio_strings.hpp"
|
||||
"../lib/elfio/elfio/elfio_symbols.hpp"
|
||||
"../lib/elfio/elfio/elfio_utils.hpp"
|
||||
)
|
||||
source_group("Header Files\\Libraries\\elfio" FILES ${Header_Files__Libraries__elfio})
|
||||
|
||||
set(Header_Files__Libraries__libgfxd
|
||||
"../lib/libgfxd/gbi.h"
|
||||
"../lib/libgfxd/gfxd.h"
|
||||
"../lib/libgfxd/priv.h"
|
||||
)
|
||||
source_group("Header Files\\Libraries\\libgfxd" FILES ${Header_Files__Libraries__libgfxd})
|
||||
|
||||
set(Header_Files__Yaz0
|
||||
"yaz0/readwrite.h"
|
||||
"yaz0/yaz0.h"
|
||||
)
|
||||
source_group("Header Files\\Yaz0" FILES ${Header_Files__Yaz0})
|
||||
|
||||
set(Header_Files__Z64
|
||||
"OtherStructs/SkinLimbStructs.h"
|
||||
"Overlays/ZOverlay.h"
|
||||
"ZAnimation.h"
|
||||
"ZArray.h"
|
||||
"ZAudio.h"
|
||||
"ZBackground.h"
|
||||
"ZBlob.h"
|
||||
"ZCollision.h"
|
||||
"ZCutscene.h"
|
||||
"ZCutsceneMM.h"
|
||||
"ZDisplayList.h"
|
||||
"ZFile.h"
|
||||
"ZLimb.h"
|
||||
"ZMtx.h"
|
||||
"ZPath.h"
|
||||
"ZPlayerAnimationData.h"
|
||||
"ZResource.h"
|
||||
"ZRom.h"
|
||||
"ZScalar.h"
|
||||
"ZSkeleton.h"
|
||||
"ZString.h"
|
||||
"ZSymbol.h"
|
||||
"ZText.h"
|
||||
"ZTexture.h"
|
||||
"ZTextureAnimation.h"
|
||||
"ZVector.h"
|
||||
"ZVtx.h"
|
||||
)
|
||||
source_group("Header Files\\Z64" FILES ${Header_Files__Z64})
|
||||
|
||||
set(Header_Files__Z64__ZRoom
|
||||
"ZRoom/ZRoom.h"
|
||||
"ZRoom/ZRoomCommand.h"
|
||||
)
|
||||
source_group("Header Files\\Z64\\ZRoom" FILES ${Header_Files__Z64__ZRoom})
|
||||
|
||||
set(Header_Files__Z64__ZRoom__Commands
|
||||
"ZRoom/Commands/EndMarker.h"
|
||||
"ZRoom/Commands/SetActorCutsceneList.h"
|
||||
"ZRoom/Commands/SetActorList.h"
|
||||
"ZRoom/Commands/SetAlternateHeaders.h"
|
||||
"ZRoom/Commands/SetAnimatedMaterialList.h"
|
||||
"ZRoom/Commands/SetCameraSettings.h"
|
||||
"ZRoom/Commands/SetCollisionHeader.h"
|
||||
"ZRoom/Commands/SetCsCamera.h"
|
||||
"ZRoom/Commands/SetCutscenes.h"
|
||||
"ZRoom/Commands/SetEchoSettings.h"
|
||||
"ZRoom/Commands/SetEntranceList.h"
|
||||
"ZRoom/Commands/SetExitList.h"
|
||||
"ZRoom/Commands/SetLightingSettings.h"
|
||||
"ZRoom/Commands/SetLightList.h"
|
||||
"ZRoom/Commands/SetMesh.h"
|
||||
"ZRoom/Commands/SetMinimapChests.h"
|
||||
"ZRoom/Commands/SetMinimapList.h"
|
||||
"ZRoom/Commands/SetObjectList.h"
|
||||
"ZRoom/Commands/SetPathways.h"
|
||||
"ZRoom/Commands/SetRoomBehavior.h"
|
||||
"ZRoom/Commands/SetRoomList.h"
|
||||
"ZRoom/Commands/SetSkyboxModifier.h"
|
||||
"ZRoom/Commands/SetSkyboxSettings.h"
|
||||
"ZRoom/Commands/SetSoundSettings.h"
|
||||
"ZRoom/Commands/SetSpecialObjects.h"
|
||||
"ZRoom/Commands/SetStartPositionList.h"
|
||||
"ZRoom/Commands/SetTimeSettings.h"
|
||||
"ZRoom/Commands/SetTransitionActorList.h"
|
||||
"ZRoom/Commands/SetWind.h"
|
||||
"ZRoom/Commands/SetWorldMapVisited.h"
|
||||
"ZRoom/Commands/Unused09.h"
|
||||
"ZRoom/Commands/Unused1D.h"
|
||||
"ZRoom/Commands/ZRoomCommandUnk.h"
|
||||
)
|
||||
source_group("Header Files\\Z64\\ZRoom\\Commands" FILES ${Header_Files__Z64__ZRoom__Commands})
|
||||
|
||||
set(Resource_Files
|
||||
"../../OTRExporter/CFG/SymbolMap_OoTMqDbg.txt"
|
||||
)
|
||||
source_group("Resource Files" FILES ${Resource_Files})
|
||||
|
||||
set(Source_Files
|
||||
"Declaration.cpp"
|
||||
"FileWorker.cpp"
|
||||
"GameConfig.cpp"
|
||||
"Globals.cpp"
|
||||
"ImageBackend.cpp"
|
||||
"Main.cpp"
|
||||
"OutputFormatter.cpp"
|
||||
"WarningHandler.cpp"
|
||||
)
|
||||
source_group("Source Files" FILES ${Source_Files})
|
||||
|
||||
set(Source_Files__Libraries__libgfxd
|
||||
"../lib/libgfxd/gfxd.c"
|
||||
"../lib/libgfxd/uc.c"
|
||||
"../lib/libgfxd/uc_f3d.c"
|
||||
"../lib/libgfxd/uc_f3db.c"
|
||||
"../lib/libgfxd/uc_f3dex.c"
|
||||
"../lib/libgfxd/uc_f3dex2.c"
|
||||
"../lib/libgfxd/uc_f3dexb.c"
|
||||
)
|
||||
source_group("Source Files\\Libraries\\libgfxd" FILES ${Source_Files__Libraries__libgfxd})
|
||||
|
||||
set(Source_Files__Yaz0
|
||||
"yaz0/yaz0.cpp"
|
||||
)
|
||||
source_group("Source Files\\Yaz0" FILES ${Source_Files__Yaz0})
|
||||
|
||||
set(Source_Files__Z64
|
||||
"OtherStructs/SkinLimbStructs.cpp"
|
||||
"Overlays/ZOverlay.cpp"
|
||||
"ZAnimation.cpp"
|
||||
"ZArray.cpp"
|
||||
"ZAudio.cpp"
|
||||
"ZAudioDecode.cpp"
|
||||
"ZBackground.cpp"
|
||||
"ZBlob.cpp"
|
||||
"ZCollision.cpp"
|
||||
"ZCutscene.cpp"
|
||||
"ZCutsceneMM.cpp"
|
||||
"ZDisplayList.cpp"
|
||||
"ZFile.cpp"
|
||||
"ZLimb.cpp"
|
||||
"ZMtx.cpp"
|
||||
"ZPath.cpp"
|
||||
"ZPlayerAnimationData.cpp"
|
||||
"ZResource.cpp"
|
||||
"ZRom.cpp"
|
||||
"ZScalar.cpp"
|
||||
"ZSkeleton.cpp"
|
||||
"ZString.cpp"
|
||||
"ZSymbol.cpp"
|
||||
"ZText.cpp"
|
||||
"ZTexture.cpp"
|
||||
"ZTextureAnimation.cpp"
|
||||
"ZVector.cpp"
|
||||
"ZVtx.cpp"
|
||||
)
|
||||
source_group("Source Files\\Z64" FILES ${Source_Files__Z64})
|
||||
|
||||
set(Source_Files__Z64__ZRoom
|
||||
"ZRoom/ZRoom.cpp"
|
||||
"ZRoom/ZRoomCommand.cpp"
|
||||
)
|
||||
source_group("Source Files\\Z64\\ZRoom" FILES ${Source_Files__Z64__ZRoom})
|
||||
|
||||
set(Source_Files__Z64__ZRoom__Commands
|
||||
"ZRoom/Commands/EndMarker.cpp"
|
||||
"ZRoom/Commands/SetActorCutsceneList.cpp"
|
||||
"ZRoom/Commands/SetActorList.cpp"
|
||||
"ZRoom/Commands/SetAlternateHeaders.cpp"
|
||||
"ZRoom/Commands/SetAnimatedMaterialList.cpp"
|
||||
"ZRoom/Commands/SetCameraSettings.cpp"
|
||||
"ZRoom/Commands/SetCollisionHeader.cpp"
|
||||
"ZRoom/Commands/SetCsCamera.cpp"
|
||||
"ZRoom/Commands/SetCutscenes.cpp"
|
||||
"ZRoom/Commands/SetEchoSettings.cpp"
|
||||
"ZRoom/Commands/SetEntranceList.cpp"
|
||||
"ZRoom/Commands/SetExitList.cpp"
|
||||
"ZRoom/Commands/SetLightingSettings.cpp"
|
||||
"ZRoom/Commands/SetLightList.cpp"
|
||||
"ZRoom/Commands/SetMesh.cpp"
|
||||
"ZRoom/Commands/SetMinimapChests.cpp"
|
||||
"ZRoom/Commands/SetMinimapList.cpp"
|
||||
"ZRoom/Commands/SetObjectList.cpp"
|
||||
"ZRoom/Commands/SetPathways.cpp"
|
||||
"ZRoom/Commands/SetRoomBehavior.cpp"
|
||||
"ZRoom/Commands/SetRoomList.cpp"
|
||||
"ZRoom/Commands/SetSkyboxModifier.cpp"
|
||||
"ZRoom/Commands/SetSkyboxSettings.cpp"
|
||||
"ZRoom/Commands/SetSoundSettings.cpp"
|
||||
"ZRoom/Commands/SetSpecialObjects.cpp"
|
||||
"ZRoom/Commands/SetStartPositionList.cpp"
|
||||
"ZRoom/Commands/SetTimeSettings.cpp"
|
||||
"ZRoom/Commands/SetTransitionActorList.cpp"
|
||||
"ZRoom/Commands/SetWind.cpp"
|
||||
"ZRoom/Commands/SetWorldMapVisited.cpp"
|
||||
"ZRoom/Commands/Unused09.cpp"
|
||||
"ZRoom/Commands/Unused1D.cpp"
|
||||
"ZRoom/Commands/ZRoomCommandUnk.cpp"
|
||||
)
|
||||
source_group("Source Files\\Z64\\ZRoom\\Commands" FILES ${Source_Files__Z64__ZRoom__Commands})
|
||||
|
||||
set(ALL_FILES
|
||||
${Header_Files}
|
||||
${Header_Files__Libraries}
|
||||
${Header_Files__Libraries__elfio}
|
||||
${Header_Files__Libraries__libgfxd}
|
||||
${Header_Files__Yaz0}
|
||||
${Header_Files__Z64}
|
||||
${Header_Files__Z64__ZRoom}
|
||||
${Header_Files__Z64__ZRoom__Commands}
|
||||
${Resource_Files}
|
||||
${Source_Files}
|
||||
${Source_Files__Libraries__libgfxd}
|
||||
${Source_Files__Yaz0}
|
||||
${Source_Files__Z64}
|
||||
${Source_Files__Z64__ZRoom}
|
||||
${Source_Files__Z64__ZRoom__Commands}
|
||||
${any__any}
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Target
|
||||
################################################################################
|
||||
add_executable(${PROJECT_NAME} ${ALL_FILES})
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||
endif()
|
||||
################################################################################
|
||||
# Includes for CMake from *.props
|
||||
################################################################################
|
||||
|
||||
set(ROOT_NAMESPACE ZAPD)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
endif()
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
OUTPUT_NAME "ZAPD.out"
|
||||
)
|
||||
endif()
|
||||
################################################################################
|
||||
# MSVC runtime library
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||
$<$<CONFIG:Debug>:
|
||||
MultiThreadedDebug
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
MultiThreaded
|
||||
>
|
||||
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
||||
)
|
||||
endif()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
||||
endif()
|
||||
################################################################################
|
||||
# Compile definitions
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
"_MBCS"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_CRT_SECURE_NO_WARNINGS"
|
||||
">"
|
||||
"_MBCS"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Compile and link options
|
||||
################################################################################
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/ZAPDUtils
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/lib/tinyxml2
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/lib/libgfxd
|
||||
${PNG_PNG_INCLUDE_DIR}/
|
||||
.
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/Od;
|
||||
/RTC1
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/Oi;
|
||||
/Gy
|
||||
>
|
||||
/permissive-;
|
||||
/sdl;
|
||||
/W3;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/Od
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/O2;
|
||||
/Oi;
|
||||
/Gy
|
||||
>
|
||||
/permissive-;
|
||||
/sdl;
|
||||
/W3;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
endif()
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/PROFILE
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/OPT:REF;
|
||||
/OPT:ICF
|
||||
>
|
||||
/DEBUG:FULL
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/PROFILE
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/OPT:REF;
|
||||
/OPT:ICF
|
||||
>
|
||||
/DEBUG:FULL
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
-Wall -Wextra -Wno-error
|
||||
-Wno-unused-parameter
|
||||
-Wno-unused-function
|
||||
-Wno-unused-variable
|
||||
-Wno-missing-field-initializers
|
||||
-Wno-parentheses
|
||||
-Wno-narrowing
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>
|
||||
-pthread
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
-pthread
|
||||
)
|
||||
else()
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
-pthread
|
||||
-Wl,-export-dynamic
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Dependencies
|
||||
################################################################################
|
||||
add_dependencies(${PROJECT_NAME}
|
||||
OTRExporter
|
||||
ZAPDUtils
|
||||
libultraship
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
"ZAPDUtils;"
|
||||
"-WHOLEARCHIVE:$<TARGET_LINKER_FILE_DIR:OTRExporter>/$<TARGET_LINKER_FILE_NAME:OTRExporter>"
|
||||
"libultraship;"
|
||||
storm
|
||||
PNG::PNG
|
||||
)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
"ZAPDUtils;"
|
||||
-Wl,-force_load $<TARGET_LINKER_FILE_DIR:OTRExporter>/$<TARGET_LINKER_FILE_NAME:OTRExporter>
|
||||
"libultraship;"
|
||||
PNG::PNG
|
||||
${CMAKE_DL_LIBS}
|
||||
Threads::Threads
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
"ZAPDUtils;"
|
||||
-Wl,--whole-archive $<TARGET_LINKER_FILE_DIR:OTRExporter>/$<TARGET_LINKER_FILE_NAME:OTRExporter> -Wl,--no-whole-archive
|
||||
"libultraship;"
|
||||
PNG::PNG
|
||||
Threads::Threads
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
"ZAPDUtils;"
|
||||
"libultraship;"
|
||||
PNG::PNG
|
||||
)
|
||||
else()
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
"ZAPDUtils;"
|
||||
-Wl,--whole-archive $<TARGET_LINKER_FILE_DIR:OTRExporter>/$<TARGET_LINKER_FILE_NAME:OTRExporter> -Wl,--no-whole-archive
|
||||
"libultraship;"
|
||||
PNG::PNG
|
||||
${CMAKE_DL_LIBS}
|
||||
Threads::Threads
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||
add_library(pathconf OBJECT pathconf.c)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE "${ADDITIONAL_LIBRARY_DEPENDENCIES}" $<TARGET_OBJECTS:pathconf> )
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE "${ADDITIONAL_LIBRARY_DEPENDENCIES}")
|
||||
endif()
|
||||
@@ -359,12 +359,6 @@
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\OTRGui\build\ZERO_CHECK.vcxproj">
|
||||
<Project>{02d10590-9542-3f55-aaf8-6055677e2a2a}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\OTRExporter\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\OTRExporter\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
|
||||
|
||||
@@ -348,11 +348,14 @@ std::string ZResource::GetSourceOutputHeader([[maybe_unused]] const std::string&
|
||||
str += StringHelper::Sprintf("#define d%s \"__OTR__%s/%s\"", name.c_str(), outName.c_str(), nameStr.c_str());
|
||||
|
||||
if (nameSet && nameSet->find(name) == nameSet->end()) {
|
||||
str += StringHelper::Sprintf(R"(
|
||||
#ifdef _WIN32
|
||||
str += StringHelper::Sprintf("\nstatic const __declspec(align(2)) char %s[] = d%s;", name.c_str(), name.c_str());
|
||||
static const __declspec(align(2)) char %s[] = d%s;
|
||||
#else
|
||||
str += StringHelper::Sprintf("\nstatic const char %s[] __attribute__((aligned (2))) = d%s;", name.c_str(), name.c_str());
|
||||
static const char %s[] __attribute__((aligned (2))) = d%s;
|
||||
#endif
|
||||
)", name.c_str(), name.c_str(), name.c_str(), name.c_str());
|
||||
|
||||
if (nameSet) {
|
||||
nameSet->insert(name);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
long pathconf(const char *path, int name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30320.27
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPD", "ZAPD\ZAPD.vcxproj", "{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExporterExample", "ExporterTest\ExporterTest.vcxproj", "{65608EB0-1A47-45AD-AB66-192FB64C762C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPDUtils", "ZAPDUtils\ZAPDUtils.vcxproj", "{A2E01C3E-D647-45D1-9788-043DEBC1A908}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
MinSizeRel|x64 = MinSizeRel|x64
|
||||
MinSizeRel|x86 = MinSizeRel|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
RelWithDebInfo|x64 = RelWithDebInfo|x64
|
||||
RelWithDebInfo|x86 = RelWithDebInfo|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.Build.0 = Debug|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.MinSizeRel|x64.ActiveCfg = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.MinSizeRel|x64.Build.0 = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.MinSizeRel|x86.ActiveCfg = Release|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.MinSizeRel|x86.Build.0 = Release|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.ActiveCfg = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.Build.0 = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.Build.0 = Release|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.RelWithDebInfo|x86.Build.0 = Release|Win32
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.Debug|x64.Build.0 = Debug|x64
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.MinSizeRel|x64.ActiveCfg = Debug|x64
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.MinSizeRel|x64.Build.0 = Debug|x64
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.MinSizeRel|x86.ActiveCfg = Debug|Win32
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.MinSizeRel|x86.Build.0 = Debug|Win32
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.Release|x64.ActiveCfg = Release|x64
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.Release|x64.Build.0 = Release|x64
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.Release|x86.Build.0 = Release|Win32
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
|
||||
{65608EB0-1A47-45AD-AB66-192FB64C762C}.RelWithDebInfo|x86.Build.0 = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.Build.0 = Debug|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.MinSizeRel|x64.ActiveCfg = Debug|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.MinSizeRel|x64.Build.0 = Debug|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.MinSizeRel|x86.ActiveCfg = Debug|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.MinSizeRel|x86.Build.0 = Debug|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.ActiveCfg = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.Build.0 = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.Build.0 = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.RelWithDebInfo|x64.ActiveCfg = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.RelWithDebInfo|x64.Build.0 = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.RelWithDebInfo|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {C2E1CC72-7A50-3249-AFD5-DFF6FE25CDCA}
|
||||
EndGlobalSection
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,218 @@
|
||||
set(PROJECT_NAME ZAPDUtils)
|
||||
|
||||
################################################################################
|
||||
# Source groups
|
||||
################################################################################
|
||||
set(Header_Files
|
||||
"Color3b.h"
|
||||
"StrHash.h"
|
||||
"Vec2f.h"
|
||||
"Vec3f.h"
|
||||
"Vec3s.h"
|
||||
)
|
||||
source_group("Header Files" FILES ${Header_Files})
|
||||
|
||||
set(Header_Files__Utils
|
||||
"Utils/BinaryReader.h"
|
||||
"Utils/BinaryWriter.h"
|
||||
"Utils/BitConverter.h"
|
||||
"Utils/Directory.h"
|
||||
"Utils/File.h"
|
||||
"Utils/MemoryStream.h"
|
||||
"Utils/Path.h"
|
||||
"Utils/Stream.h"
|
||||
"Utils/StringHelper.h"
|
||||
)
|
||||
source_group("Header Files\\Utils" FILES ${Header_Files__Utils})
|
||||
|
||||
set(Source_Files__Libraries
|
||||
"../lib/tinyxml2/tinyxml2.cpp"
|
||||
)
|
||||
source_group("Source Files\\Libraries" FILES ${Source_Files__Libraries})
|
||||
|
||||
set(Source_Files__Utils
|
||||
"Utils/BinaryReader.cpp"
|
||||
"Utils/BinaryWriter.cpp"
|
||||
"Utils/MemoryStream.cpp"
|
||||
"Utils/StringHelper.cpp"
|
||||
)
|
||||
source_group("Source Files\\Utils" FILES ${Source_Files__Utils})
|
||||
|
||||
set(ALL_FILES
|
||||
${Header_Files}
|
||||
${Header_Files__Utils}
|
||||
${Source_Files__Libraries}
|
||||
${Source_Files__Utils}
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Target
|
||||
################################################################################
|
||||
add_library(${PROJECT_NAME} STATIC ${ALL_FILES})
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||
endif()
|
||||
|
||||
set(ROOT_NAMESPACE ZAPDUtils)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
VS_GLOBAL_KEYWORD "Win32Proj"
|
||||
)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
################################################################################
|
||||
# MSVC runtime library
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||
$<$<CONFIG:Debug>:
|
||||
MultiThreadedDebug
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
MultiThreaded
|
||||
>
|
||||
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||
MultiThreaded
|
||||
)
|
||||
endif()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
||||
endif()
|
||||
################################################################################
|
||||
# Compile definitions
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG;"
|
||||
"_MBCS"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG;"
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
">"
|
||||
"_CONSOLE;"
|
||||
"_CRT_SECURE_NO_WARNINGS"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
"WIN32;"
|
||||
"_CONSOLE;"
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
"_CONSOLE;"
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Compile and link options
|
||||
################################################################################
|
||||
if(MSVC)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:
|
||||
/Oi;
|
||||
/Gy
|
||||
>
|
||||
/permissive-;
|
||||
/MP;
|
||||
/sdl;
|
||||
/W3;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/O2;
|
||||
/Ot
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/Gy
|
||||
>
|
||||
/permissive-;
|
||||
/MP;
|
||||
/Oi;
|
||||
/sdl;
|
||||
/W3;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
endif()
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:
|
||||
/OPT:REF;
|
||||
/OPT:ICF
|
||||
>
|
||||
/SUBSYSTEM:CONSOLE
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:
|
||||
/OPT:REF;
|
||||
/OPT:ICF
|
||||
>
|
||||
/SUBSYSTEM:CONSOLE
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
-Wall -Wextra -Wno-error
|
||||
-Wno-unused-parameter
|
||||
-Wno-unused-function
|
||||
-Wno-unused-variable
|
||||
-Wno-missing-field-initializers
|
||||
-Wno-parentheses
|
||||
-Wno-narrowing
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>
|
||||
)
|
||||
endif()
|
||||
################################################################################
|
||||
# Dependencies
|
||||
################################################################################
|
||||
# Link with other targets.
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
# Only used for standalone compilation, usually inherits these from the main makefile
|
||||
CXX ?= g++
|
||||
CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17
|
||||
|
||||
SRC_DIRS := $(shell find . -type d -not -path "*build*")
|
||||
CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp))
|
||||
H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h))
|
||||
|
||||
O_FILES := $(foreach f,$(CPP_FILES:.cpp=.o),build/$f)
|
||||
LIB := ZAPDUtils.a
|
||||
|
||||
# create build directories
|
||||
$(shell mkdir -p $(foreach dir,$(SRC_DIRS),build/$(dir)))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
clean:
|
||||
rm -rf build $(LIB)
|
||||
|
||||
format:
|
||||
clang-format-11 -i $(CPP_FILES) $(H_FILES)
|
||||
|
||||
.PHONY: all clean format
|
||||
|
||||
build/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(OPTFLAGS) -c $(OUTPUT_OPTION) $<
|
||||
|
||||
$(LIB): $(O_FILES)
|
||||
$(AR) rcs $@ $^
|
||||
@@ -18,6 +18,16 @@ void BinaryReader::Close()
|
||||
stream->Close();
|
||||
}
|
||||
|
||||
void BinaryReader::SetEndianness(Endianness endianness)
|
||||
{
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
||||
Endianness BinaryReader::GetEndianness() const
|
||||
{
|
||||
return endianness;
|
||||
}
|
||||
|
||||
void BinaryReader::Seek(uint32_t offset, SeekOffsetType seekType)
|
||||
{
|
||||
stream->Seek(offset, seekType);
|
||||
@@ -28,11 +38,16 @@ uint32_t BinaryReader::GetBaseAddress()
|
||||
return stream->GetBaseAddress();
|
||||
}
|
||||
|
||||
void BinaryReader::Read([[maybe_unused]] char* buffer, int32_t length)
|
||||
void BinaryReader::Read(int32_t length)
|
||||
{
|
||||
stream->Read(length);
|
||||
}
|
||||
|
||||
void BinaryReader::Read(char* buffer, int32_t length)
|
||||
{
|
||||
stream->Read(buffer, length);
|
||||
}
|
||||
|
||||
char BinaryReader::ReadChar()
|
||||
{
|
||||
return (char)stream->ReadByte();
|
||||
@@ -53,6 +68,10 @@ int16_t BinaryReader::ReadInt16()
|
||||
int16_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(int16_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP16(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -61,6 +80,10 @@ int32_t BinaryReader::ReadInt32()
|
||||
int32_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(int32_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP32(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -69,6 +92,10 @@ uint16_t BinaryReader::ReadUInt16()
|
||||
uint16_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(uint16_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP16(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -77,6 +104,10 @@ uint32_t BinaryReader::ReadUInt32()
|
||||
uint32_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(uint32_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP32(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -85,6 +116,10 @@ uint64_t BinaryReader::ReadUInt64()
|
||||
uint64_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(uint64_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP64(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -94,6 +129,15 @@ float BinaryReader::ReadSingle()
|
||||
|
||||
stream->Read((char*)&result, sizeof(float));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
{
|
||||
float tmp;
|
||||
char* dst = (char*)&tmp;
|
||||
char* src = (char*)&result;
|
||||
dst[3] = src[0]; dst[2] = src[1]; dst[1] = src[2]; dst[0] = src[3];
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
if (std::isnan(result))
|
||||
throw std::runtime_error("BinaryReader::ReadSingle(): Error reading stream");
|
||||
|
||||
@@ -105,6 +149,17 @@ double BinaryReader::ReadDouble()
|
||||
double result = NAN;
|
||||
|
||||
stream->Read((char*)&result, sizeof(double));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
{
|
||||
double tmp;
|
||||
char* dst = (char*)&tmp;
|
||||
char* src = (char*)&result;
|
||||
dst[7] = src[0]; dst[6] = src[1]; dst[5] = src[2]; dst[4] = src[3];
|
||||
dst[3] = src[4]; dst[2] = src[5]; dst[1] = src[6]; dst[0] = src[7];
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
if (std::isnan(result))
|
||||
throw std::runtime_error("BinaryReader::ReadDouble(): Error reading stream");
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "../Vec2f.h"
|
||||
#include "../Vec3f.h"
|
||||
#include "../Vec3s.h"
|
||||
#include "BitConverter.h"
|
||||
#include "Stream.h"
|
||||
|
||||
class BinaryReader
|
||||
@@ -18,9 +19,13 @@ public:
|
||||
|
||||
void Close();
|
||||
|
||||
void SetEndianness(Endianness endianness);
|
||||
Endianness GetEndianness() const;
|
||||
|
||||
void Seek(uint32_t offset, SeekOffsetType seekType);
|
||||
uint32_t GetBaseAddress();
|
||||
|
||||
void Read(int32_t length);
|
||||
void Read(char* buffer, int32_t length);
|
||||
char ReadChar();
|
||||
int8_t ReadByte();
|
||||
@@ -41,4 +46,5 @@ public:
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Stream> stream;
|
||||
Endianness endianness = Endianness::Native;
|
||||
};
|
||||
@@ -10,6 +10,11 @@ BinaryWriter::BinaryWriter(std::shared_ptr<Stream> nStream)
|
||||
stream = nStream;
|
||||
}
|
||||
|
||||
void BinaryWriter::SetEndianness(Endianness endianness)
|
||||
{
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
||||
void BinaryWriter::Close()
|
||||
{
|
||||
stream->Close();
|
||||
@@ -47,16 +52,25 @@ void BinaryWriter::Write(uint8_t value)
|
||||
|
||||
void BinaryWriter::Write(int16_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP16(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(int16_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint16_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP16(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(int32_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP32(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(int32_t));
|
||||
}
|
||||
|
||||
@@ -68,33 +82,61 @@ void BinaryWriter::Write(int32_t valueA, int32_t valueB)
|
||||
|
||||
void BinaryWriter::Write(uint32_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP32(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(int64_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP64(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(int64_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint64_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP64(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(float value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
{
|
||||
float tmp;
|
||||
char* dst = (char*)&tmp;
|
||||
char* src = (char*)&value;
|
||||
dst[3] = src[0]; dst[2] = src[1]; dst[1] = src[2]; dst[0] = src[3];
|
||||
value = tmp;
|
||||
}
|
||||
|
||||
stream->Write((char*)&value, sizeof(float));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(double value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
{
|
||||
double tmp;
|
||||
char* dst = (char*)&tmp;
|
||||
char* src = (char*)&value;
|
||||
dst[7] = src[0]; dst[6] = src[1]; dst[5] = src[2]; dst[4] = src[3];
|
||||
dst[3] = src[4]; dst[2] = src[5]; dst[1] = src[6]; dst[0] = src[7];
|
||||
value = tmp;
|
||||
}
|
||||
|
||||
stream->Write((char*)&value, sizeof(double));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(const std::string& str)
|
||||
{
|
||||
int strLen = str.size();
|
||||
stream->Write((char*)&strLen, sizeof(int));
|
||||
Write(strLen);
|
||||
|
||||
for (char c : str)
|
||||
stream->WriteByte(c);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "BitConverter.h"
|
||||
#include "Stream.h"
|
||||
|
||||
class BinaryWriter
|
||||
@@ -12,6 +13,8 @@ public:
|
||||
BinaryWriter(Stream* nStream);
|
||||
BinaryWriter(std::shared_ptr<Stream> nStream);
|
||||
|
||||
void SetEndianness(Endianness endianness);
|
||||
|
||||
std::shared_ptr<Stream> GetStream();
|
||||
uint64_t GetBaseAddress();
|
||||
uint64_t GetLength();
|
||||
@@ -34,4 +37,5 @@ public:
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Stream> stream;
|
||||
Endianness endianness = Endianness::Native;
|
||||
};
|
||||
@@ -5,6 +5,28 @@
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define BSWAP16 _byteswap_ushort
|
||||
#define BSWAP32 _byteswap_ulong
|
||||
#define BSWAP64 _byteswap_uint64
|
||||
#else
|
||||
#define BSWAP16 __builtin_bswap16
|
||||
#define BSWAP32 __builtin_bswap32
|
||||
#define BSWAP64 __builtin_bswap64
|
||||
#endif
|
||||
|
||||
enum class Endianness
|
||||
{
|
||||
Little = 0,
|
||||
Big = 1,
|
||||
|
||||
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
|
||||
Native = Big,
|
||||
#else
|
||||
Native = Little,
|
||||
#endif
|
||||
};
|
||||
|
||||
class BitConverter
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "StringHelper.h"
|
||||
#include <iostream>
|
||||
|
||||
#if __has_include(<filesystem>)
|
||||
#include <filesystem>
|
||||
@@ -12,8 +13,6 @@ namespace fs = std::filesystem;
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#endif
|
||||
|
||||
#include "StringHelper.h"
|
||||
|
||||
#undef GetCurrentDirectory
|
||||
#undef CreateDirectory
|
||||
|
||||
@@ -21,7 +20,7 @@ class Directory
|
||||
{
|
||||
public:
|
||||
#ifndef PATH_HACK
|
||||
static std::string GetCurrentDirectory() { return fs::current_path().u8string().c_str(); }
|
||||
static std::string GetCurrentDirectory() { return fs::current_path().string(); }
|
||||
#endif
|
||||
|
||||
static bool Exists(const fs::path& path) { return fs::exists(path); }
|
||||
|
||||
@@ -10,13 +10,6 @@ enum class SeekOffsetType
|
||||
End
|
||||
};
|
||||
|
||||
// TODO: Eventually account for endianess in binaryreader and binarywriter
|
||||
enum class Endianess
|
||||
{
|
||||
Little = 0,
|
||||
Big = 1,
|
||||
};
|
||||
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -9,22 +9,18 @@
|
||||
|
||||
std::vector<std::string> StringHelper::Split(std::string s, const std::string& delimiter)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
|
||||
std::string token;
|
||||
std::vector<std::string> res;
|
||||
|
||||
size_t pos = 0;
|
||||
std::string token;
|
||||
while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {
|
||||
token = s.substr(pos_start, pos_end - pos_start);
|
||||
pos_start = pos_end + delim_len;
|
||||
res.push_back(token);
|
||||
}
|
||||
|
||||
while ((pos = s.find(delimiter)) != std::string::npos)
|
||||
{
|
||||
token = s.substr(0, pos);
|
||||
result.push_back(token);
|
||||
s.erase(0, pos + delimiter.length());
|
||||
}
|
||||
|
||||
if (s.length() != 0)
|
||||
result.push_back(s);
|
||||
|
||||
return result;
|
||||
res.push_back(s.substr(pos_start));
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string StringHelper::Strip(std::string s, const std::string& delimiter)
|
||||
@@ -68,7 +64,11 @@ void StringHelper::ReplaceOriginal(std::string& str, const std::string& from, co
|
||||
|
||||
bool StringHelper::StartsWith(const std::string& s, const std::string& input)
|
||||
{
|
||||
#if __cplusplus >= 202002L
|
||||
return s.starts_with(input.c_str());
|
||||
#else
|
||||
return s.rfind(input, 0) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool StringHelper::Contains(const std::string& s, const std::string& input)
|
||||
@@ -127,4 +127,4 @@ bool StringHelper::IEquals(const std::string& a, const std::string& b)
|
||||
{
|
||||
return std::equal(a.begin(), a.end(), b.begin(), b.end(),
|
||||
[](char a, char b) { return tolower(a) == tolower(b); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct Vec3f
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
@@ -186,12 +186,6 @@
|
||||
<ClCompile Include="Utils\MemoryStream.cpp" />
|
||||
<ClCompile Include="Utils\StringHelper.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\OTRGui\build\ZERO_CHECK.vcxproj">
|
||||
<Project>{02d10590-9542-3f55-aaf8-6055677e2a2a}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
@@ -489,7 +489,7 @@ Current supported types are `Vec3s`, `Vec3i` or `Vec3f`.
|
||||
- Example:
|
||||
|
||||
```xml
|
||||
<Array Name="D_04002040" Count="24" Offset="0x2040">
|
||||
<Array Name="gLinkPauseChildDekuShieldJointTable" Count="24" Offset="0x2040">
|
||||
<Vector Type="s16" Dimensions="3" />
|
||||
</Array>
|
||||
```
|
||||
@@ -497,7 +497,7 @@ Current supported types are `Vec3s`, `Vec3i` or `Vec3f`.
|
||||
Will be extracted as:
|
||||
|
||||
```c
|
||||
Vec3s D_04002040[24] = {
|
||||
Vec3s gLinkPauseChildDekuShieldJointTable[24] = {
|
||||
{ -37, 2346, 93 },
|
||||
{ 0, 11995, 0 },
|
||||
{ -16385, -305, -16333 },
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
curl -sSfLO "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
|
||||
chmod a+x linuxdeploy*.AppImage
|
||||
curl -sSfLO "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
|
||||
chmod a+x appimagetool*.AppImage
|
||||
|
||||
mkdir -p AppDir/usr/bin
|
||||
cp appimage/{soh.desktop,soh.sh} AppDir/
|
||||
cp soh/macosx/sohIcon.png AppDir/soh.png
|
||||
curl -sSfL https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt -o AppDir/usr/bin/gamecontrollerdb.txt
|
||||
|
||||
mkdir -p AppDir/usr/share/applications
|
||||
mkdir -p AppDir/usr/share/icons/hicolor/scalable/apps
|
||||
mkdir -p AppDir/usr/lib
|
||||
|
||||
mv AppDir/soh.sh AppDir/usr/bin
|
||||
cp -r build/* AppDir/usr/bin
|
||||
|
||||
chmod +x AppDir/usr/bin/{soh.elf,OTRGui,soh.sh}
|
||||
|
||||
cd AppDir && ln -s ./usr/bin/soh.sh ./AppRun && cd ..
|
||||
|
||||
export UPD_INFO="gh-releases-zsync|HarbourMasters|Shipwright-linux|develop|SOH-Linux.AppImage.zsync"
|
||||
./linuxdeploy-x86_64.AppImage --appimage-extract-and-run \
|
||||
--appdir=./AppDir/ \
|
||||
-d ./AppDir/soh.desktop \
|
||||
-i ./AppDir/soh.png \
|
||||
-e ./AppDir/usr/bin/soh.elf
|
||||
|
||||
cd /soh
|
||||
|
||||
./appimagetool-x86_64.AppImage --appimage-extract-and-run ./AppDir "SOH-Linux.AppImage"
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/bin/bash
|
||||
HERE="$(dirname "$(readlink -f "${0}")")"/../..
|
||||
|
||||
export PATH="$HERE"/bin:"$HERE"/usr/bin:"$PATH"
|
||||
export LD_LIBRARY_PATH="$HERE"/usr/lib:"$LD_LIBRARY_PATH"
|
||||
|
||||
while [[ ! -e "$PWD"/oot.otr ]]; do
|
||||
export ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)"
|
||||
ln -s "$HERE"/usr/bin/{assets,soh.elf,OTRGui} "$ASSETDIR"
|
||||
export OLDPWD="$PWD"
|
||||
mkdir -p "$ASSETDIR"/tmp
|
||||
mkdir -p "$ASSETDIR"/Extract/assets
|
||||
if [ -e "$PWD"/*.*64 ]; then
|
||||
ln -s "$OLDPWD"/*.*64 "$ASSETDIR"/tmp/rom.z64
|
||||
cp -r "$ASSETDIR"/assets/game/ship_of_harkinian "$ASSETDIR"/Extract/assets/
|
||||
cd "$ASSETDIR"
|
||||
case $(sha1sum -b "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }') in
|
||||
cee6bc3c2a634b41728f2af8da54d9bf8cc14099)
|
||||
ROM=GC_NMQ_D;;
|
||||
0227d7c0074f2d0ac935631990da8ec5914597b4)
|
||||
ROM=GC_NMQ_PAL_F;;
|
||||
*)
|
||||
echo -e "\nrom hash does not match\n"
|
||||
exit;;
|
||||
esac
|
||||
echo "Processing..."
|
||||
assets/extractor/ZAPD.out ed -eh -i assets/extractor/xmls/"${ROM}" -b tmp/rom.z64 -fl assets/extractor/filelists -o placeholder -osf placeholder -gsf 1 -rconf assets/extractor/Config_"${ROM}".xml -se OTR > /dev/null 2>&1
|
||||
cp "$ASSETDIR"/oot.otr "$OLDPWD"
|
||||
echo "Restart $APPIMAGE to play!"
|
||||
sleep 3
|
||||
rm -r "$ASSETDIR"
|
||||
break
|
||||
else
|
||||
echo -e "\nPlace ROM in this folder\n"
|
||||
exit
|
||||
fi
|
||||
done
|
||||
cd "$OWD"
|
||||
ln -s "$HERE"/usr/bin/gamecontrollerdb.txt "$PWD"
|
||||
"$HERE"/usr/bin/soh.elf
|
||||
unlink "$PWD"/gamecontrollerdb.txt
|
||||
exit
|
||||
@@ -1,148 +0,0 @@
|
||||
# Only used for standalone compilation, usually inherits these from the main makefile
|
||||
|
||||
CXX ?= g++
|
||||
CC ?= gcc
|
||||
AR := ar
|
||||
FORMAT := clang-format-11
|
||||
UNAME := $(shell uname)
|
||||
|
||||
ASAN ?= 0
|
||||
DEBUG ?= 1
|
||||
OPTFLAGS ?= -O0
|
||||
LTO ?= 0
|
||||
|
||||
# flag to save whether the compiler being used is clang or gcc by checking CXX --version
|
||||
CXX_IS_CLANG ?= $(shell $(CXX) --version | grep -c clang)
|
||||
ifeq ($(CXX_IS_CLANG),1)
|
||||
MXX := $(CXX)
|
||||
else
|
||||
MXX ?= clang++
|
||||
endif
|
||||
|
||||
|
||||
WARN := -Wall -Wextra -Werror \
|
||||
-Wno-unused-variable \
|
||||
-Wno-unused-parameter \
|
||||
-Wno-unused-function \
|
||||
-Wno-parentheses \
|
||||
-Wno-narrowing \
|
||||
-Wno-missing-field-initializers \
|
||||
-Wno-error=multichar \
|
||||
-Wno-unused-command-line-argument \
|
||||
-Wno-delete-non-abstract-non-virtual-dtor \
|
||||
-Wno-unused-private-field \
|
||||
-Wno-deprecated-copy-with-user-provided-copy \
|
||||
-Wno-deprecated-declarations \
|
||||
-Wno-unknown-warning-option
|
||||
|
||||
CWARN :=
|
||||
CXXWARN := -Wno-deprecated-enum-enum-conversion -Wno-deprecated-copy
|
||||
|
||||
ifneq ($(CXX_IS_CLANG),1)
|
||||
WARN += -Wno-error=stringop-overflow
|
||||
CXXWARN += -Wno-error=maybe-uninitialized
|
||||
endif
|
||||
|
||||
CXXFLAGS := $(WARN) $(CXXWARN) -std=c++20 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0
|
||||
CFLAGS := $(WARN) $(CWARN) -std=c99 -D_GNU_SOURCE -DENABLE_OPENGL -DSPDLOG_ACTIVE_LEVEL=0
|
||||
CPPFLAGS := -MMD
|
||||
|
||||
MMFLAGS := -Wno-deprecated-declarations -ObjC++ -fobjc-weak -fobjc-arc
|
||||
|
||||
# if not using clang, ask clang to use gcc standard library
|
||||
ifneq ($(CXX_IS_CLANG),1)
|
||||
STD_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | head -n 1)
|
||||
CXX_ISYSTEM=$(shell ${CXX} -xc++ -E -v - < /dev/null 2>&1 | grep "> search starts here" -A2 | tail -n 2 | tail -n 1)
|
||||
MMFLAGS += -stdlib++-isystem ${STD_ISYSTEM} -cxx-isystem ${CXX_ISYSTEM}
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin) #APPLE
|
||||
CPPFLAGS += $(shell pkg-config --cflags sdl2 glew) -framework OpenGL -framework Foundation
|
||||
endif
|
||||
|
||||
ifneq ($(DEBUG),0)
|
||||
CXXFLAGS += -g -D_DEBUG
|
||||
CFLAGS += -g -D_DEBUG
|
||||
endif
|
||||
|
||||
ifneq ($(ASAN),0)
|
||||
CXXFLAGS += -fsanitize=address
|
||||
CFLAGS += -fsanitize=address
|
||||
endif
|
||||
|
||||
ifneq ($(LTO),0)
|
||||
CXXFLAGS += -flto
|
||||
CFLAGS += -flto
|
||||
endif
|
||||
|
||||
SRC_DIRS := $(shell find . -type d -not -path "*build*")
|
||||
|
||||
CXX_FILES := \
|
||||
$(shell find libultraship/Factories -name "*.cpp") \
|
||||
$(shell find libultraship/Lib/Fast3D -name "*.cpp") \
|
||||
$(shell find libultraship -maxdepth 1 -name "*.cpp") \
|
||||
$(shell find libultraship/Lib/ImGui -maxdepth 1 -name "*.cpp") \
|
||||
$(shell find libultraship/Lib/Mercury -maxdepth 1 -name "*.cpp") \
|
||||
libultraship/Lib/ImGui/backends/imgui_impl_opengl3.cpp \
|
||||
libultraship/Lib/ImGui/backends/imgui_impl_sdl.cpp \
|
||||
libultraship/Lib/StrHash64.cpp \
|
||||
libultraship/Lib/tinyxml2/tinyxml2.cpp
|
||||
|
||||
C_FILES := \
|
||||
libultraship/mixer.c \
|
||||
libultraship/Lib/stb/stb_impl.c
|
||||
|
||||
MM_FILES := \
|
||||
libultraship/OSXFolderManager.mm
|
||||
|
||||
FMT_FILES := $(shell find libultraship/ -type f \( -name "*.cpp" -o -name "*.h" \) -a -not -path "libultraship/Lib/*")
|
||||
|
||||
O_FILES := \
|
||||
$(CXX_FILES:%.cpp=build/%.o) \
|
||||
$(C_FILES:%.c=build/%.o)
|
||||
|
||||
ifeq ($(UNAME), Darwin) #APPLE
|
||||
O_FILES += $(MM_FILES:%.mm=build/%.o)
|
||||
endif
|
||||
|
||||
D_FILES := $(O_FILES:%.o=%.d)
|
||||
|
||||
LIB := libultraship.a
|
||||
|
||||
INC_DIRS := $(addprefix -I, \
|
||||
../ZAPDTR/ZAPDUtils \
|
||||
libultraship/Lib/Fast3D/U64 \
|
||||
libultraship/Lib/spdlog \
|
||||
libultraship/Lib/spdlog/include \
|
||||
libultraship/Lib/ImGui \
|
||||
libultraship/Lib/Mercury \
|
||||
libultraship \
|
||||
../StormLib/src \
|
||||
)
|
||||
|
||||
# create build directories
|
||||
$(shell mkdir -p $(SRC_DIRS:%=build/%))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
clean:
|
||||
rm -rf build $(LIB)
|
||||
|
||||
format:
|
||||
$(FORMAT) -i $(FMT_FILES)
|
||||
|
||||
.PHONY: all clean format
|
||||
|
||||
build/%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@
|
||||
|
||||
build/%.o: %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@
|
||||
|
||||
build/%.o: %.mm
|
||||
$(MXX) $(MMFLAGS) $(CXXFLAGS) $(OPTFLAGS) $(INC_DIRS) -c $< -o $@
|
||||
|
||||
$(LIB): $(O_FILES)
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
-include $(D_FILES)
|
||||
@@ -1,29 +0,0 @@
|
||||
#include "OTRArchive.h"
|
||||
|
||||
void SaveTest()
|
||||
{
|
||||
auto archPtr = OtrLib::OTRArchive::CreateArchive("myarch.mpq");
|
||||
auto arch = archPtr.get();
|
||||
|
||||
char data[] = "ABCDEFG!";
|
||||
|
||||
arch->AddFile("test.txt", (uintptr_t)data, sizeof(data));
|
||||
}
|
||||
|
||||
void LoadTest()
|
||||
{
|
||||
std::shared_ptr<OtrLib::OTRArchive> archPtr(new OtrLib::OTRArchive("myarch.mpq"));
|
||||
|
||||
archPtr->LoadFile("(crcfile)");
|
||||
|
||||
int bp = 0;
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
LoadTest();
|
||||
//SaveTest();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -1,152 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{3c4a8151-48d1-4518-be1a-24016a5b800f}</ProjectGuid>
|
||||
<RootNamespace>TestApp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir)..\otrlib;$(ProjectDir)..\..\ZAPD\ZAPDUtils;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)x64\Debug;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>otrlib.lib;ZAPDUtils.lib;StormLibDUS.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Main.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,64 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30320.27
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libultraship", "libultraship\libultraship.vcxproj", "{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestApp", "TestApp\TestApp.vcxproj", "{3C4A8151-48D1-4518-BE1A-24016A5B800F}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8} = {6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPD", "..\ZAPDTR\ZAPD\ZAPD.vcxproj", "{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZAPDUtils", "..\ZAPDTR\ZAPDUtils\ZAPDUtils.vcxproj", "{A2E01C3E-D647-45D1-9788-043DEBC1A908}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x64.Build.0 = Debug|x64
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x64.ActiveCfg = Release|x64
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x64.Build.0 = Release|x64
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6DA9B521-65B7-41E2-8F8A-F0451CC18ED8}.Release|x86.Build.0 = Release|Win32
|
||||
{3C4A8151-48D1-4518-BE1A-24016A5B800F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3C4A8151-48D1-4518-BE1A-24016A5B800F}.Debug|x64.Build.0 = Debug|x64
|
||||
{3C4A8151-48D1-4518-BE1A-24016A5B800F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{3C4A8151-48D1-4518-BE1A-24016A5B800F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{3C4A8151-48D1-4518-BE1A-24016A5B800F}.Release|x64.ActiveCfg = Release|x64
|
||||
{3C4A8151-48D1-4518-BE1A-24016A5B800F}.Release|x64.Build.0 = Release|x64
|
||||
{3C4A8151-48D1-4518-BE1A-24016A5B800F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{3C4A8151-48D1-4518-BE1A-24016A5B800F}.Release|x86.Build.0 = Release|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x64.Build.0 = Debug|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.ActiveCfg = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x64.Build.0 = Release|x64
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}.Release|x86.Build.0 = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x64.Build.0 = Debug|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Debug|x86.Build.0 = Debug|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.ActiveCfg = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x64.Build.0 = Release|x64
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.ActiveCfg = Release|Win32
|
||||
{A2E01C3E-D647-45D1-9788-043DEBC1A908}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DCE19FF1-37C0-49CD-915A-DD695E15F00B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -6,6 +6,10 @@
|
||||
#include "Lib/StrHash64.h"
|
||||
#include <filesystem>
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include "SwitchImpl.h"
|
||||
#endif
|
||||
|
||||
namespace Ship {
|
||||
Archive::Archive(const std::string& MainPath, bool enableWriting) : Archive(MainPath, "", enableWriting)
|
||||
{
|
||||
@@ -35,7 +39,7 @@ namespace Ship {
|
||||
std::copy(archivePath.begin(), archivePath.end(), t_filename);
|
||||
|
||||
bool success = SFileCreateArchive(t_filename, MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_ARCHIVE_V2, fileCapacity, &archive->mainMPQ);
|
||||
int error = GetLastError();
|
||||
int32_t error = GetLastError();
|
||||
|
||||
delete[] t_filename;
|
||||
|
||||
@@ -46,7 +50,7 @@ namespace Ship {
|
||||
}
|
||||
else
|
||||
{
|
||||
SPDLOG_ERROR("({}) We tried to create an archive, but it has fallen and cannot get up.");
|
||||
SPDLOG_ERROR("({}) We tried to create an archive, but it has fallen and cannot get up.", error);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -61,14 +65,8 @@ namespace Ship {
|
||||
|
||||
bool attempt = SFileOpenFileEx(mainMPQ, filePath.c_str(), 0, &fileHandle);
|
||||
|
||||
//if (!attempt)
|
||||
//{
|
||||
//std::string filePathAlt = StringHelper::Replace(filePath, "/", "\\");
|
||||
//attempt |= SFileOpenFileEx(mainMPQ, filePathAlt.c_str(), 0, &fileHandle);
|
||||
//}
|
||||
|
||||
if (!attempt) {
|
||||
printf("({%i}) Failed to open file {%s} from mpq archive {%s}", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||
SPDLOG_ERROR("({}) Failed to open file {} from mpq archive {}.", GetLastError(), filePath.c_str(), MainPath.c_str());
|
||||
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
|
||||
FileToLoad->bHasLoadError = true;
|
||||
return FileToLoad;
|
||||
@@ -327,13 +325,21 @@ namespace Ship {
|
||||
#ifdef _WIN32
|
||||
std::wstring wfullPath = std::filesystem::absolute(MainPath).wstring();
|
||||
#endif
|
||||
#if defined(__SWITCH__)
|
||||
std::string fullPath = MainPath;
|
||||
#else
|
||||
std::string fullPath = std::filesystem::absolute(MainPath).string();
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!SFileOpenArchive(wfullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) {
|
||||
#else
|
||||
if (!SFileOpenArchive(fullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) {
|
||||
#endif
|
||||
|
||||
#ifdef __SWITCH__
|
||||
Switch::ThrowMissingOTR(fullPath);
|
||||
#endif
|
||||
SPDLOG_ERROR("({}) Failed to open main mpq file {}.", GetLastError(), fullPath.c_str());
|
||||
return false;
|
||||
}
|
||||
@@ -362,7 +368,11 @@ namespace Ship {
|
||||
|
||||
bool Archive::LoadPatchMPQ(const std::string& path) {
|
||||
HANDLE patchHandle = NULL;
|
||||
#if defined(__SWITCH__)
|
||||
std::string fullPath = path;
|
||||
#else
|
||||
std::string fullPath = std::filesystem::absolute(path).string();
|
||||
#endif
|
||||
if (mpqHandles.contains(fullPath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Resource.h"
|
||||
//#include "Lib/StrHash64.h"
|
||||
#include "StormLib.h"
|
||||
|
||||
|
||||
|
||||
@@ -14,3 +14,11 @@ namespace Ship {
|
||||
constexpr int GetSampleRate() const { return 44100; }
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "WasapiAudioPlayer.h"
|
||||
#elif defined(__linux)
|
||||
#include "PulseAudioPlayer.h"
|
||||
#endif
|
||||
|
||||
#include "SDLAudioPlayer.h"
|
||||
|
||||
@@ -0,0 +1,721 @@
|
||||
set(PROJECT_NAME libultraship)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
enable_language(OBJCXX)
|
||||
#set(CMAKE_OBJCXX_FLAGS "-Wno-deprecated-declarations -ObjC++")
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Source groups
|
||||
################################################################################
|
||||
set(Header_Files__Resources__Factories
|
||||
"Factories/AnimationFactory.h"
|
||||
"Factories/ArrayFactory.h"
|
||||
"Factories/AudioFactory.h"
|
||||
"Factories/BlobFactory.h"
|
||||
"Factories/CollisionHeaderFactory.h"
|
||||
"Factories/CutsceneFactory.h"
|
||||
"Factories/DisplayListFactory.h"
|
||||
"Factories/MaterialFactory.h"
|
||||
"Factories/MtxFactory.h"
|
||||
"Factories/PathFactory.h"
|
||||
"Factories/PlayerAnimationFactory.h"
|
||||
"Factories/ResourceLoader.h"
|
||||
"Factories/SceneFactory.h"
|
||||
"Factories/SkeletonFactory.h"
|
||||
"Factories/SkeletonLimbFactory.h"
|
||||
"Factories/TextFactory.h"
|
||||
"Factories/TextureFactory.h"
|
||||
"Factories/VtxFactory.h"
|
||||
)
|
||||
source_group("Header Files\\Resources\\Factories" FILES ${Header_Files__Resources__Factories})
|
||||
|
||||
set(Header_Files__Resources__Files
|
||||
"Animation.h"
|
||||
"Array.h"
|
||||
"Audio.h"
|
||||
"Blob.h"
|
||||
"CollisionHeader.h"
|
||||
"Cutscene.h"
|
||||
"DisplayList.h"
|
||||
"Material.h"
|
||||
"Matrix.h"
|
||||
"Model.h"
|
||||
"Path.h"
|
||||
"PlayerAnimation.h"
|
||||
"Scene.h"
|
||||
"Skeleton.h"
|
||||
"SkeletonLimb.h"
|
||||
"Text.h"
|
||||
"Texture.h"
|
||||
"Vertex.h"
|
||||
)
|
||||
source_group("Header Files\\Resources\\Files" FILES ${Header_Files__Resources__Files})
|
||||
|
||||
set(Source_Files__Audio
|
||||
"abi.h"
|
||||
"AudioPlayer.h"
|
||||
"mixer.c"
|
||||
"mixer.h"
|
||||
"SDLAudioPlayer.cpp"
|
||||
"SDLAudioPlayer.h"
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(Source_Files__Audio__extra
|
||||
"WasapiAudioPlayer.cpp"
|
||||
"WasapiAudioPlayer.h"
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(Source_Files__Audio__extra
|
||||
"PulseAudioPlayer.cpp"
|
||||
"PulseAudioPlayer.h"
|
||||
)
|
||||
endif ()
|
||||
|
||||
source_group("Source Files\\Audio" FILES ${Source_Files__Audio} ${Source_Files__Audio__extra})
|
||||
|
||||
set(Source_Files__Controller
|
||||
"ControlDeck.cpp"
|
||||
"ControlDeck.h"
|
||||
"Controller.cpp"
|
||||
"Controller.h"
|
||||
"ControllerAttachment.cpp"
|
||||
"ControllerAttachment.h"
|
||||
"InputEditor.cpp"
|
||||
"InputEditor.h"
|
||||
"KeyboardController.cpp"
|
||||
"KeyboardController.h"
|
||||
"UltraController.h"
|
||||
"DummyController.cpp"
|
||||
"DummyController.h"
|
||||
)
|
||||
|
||||
if (NOT CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
list(APPEND Source_Files__Controller
|
||||
"SDLController.cpp"
|
||||
"SDLController.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
source_group("Source Files\\Controller" FILES ${Source_Files__Controller})
|
||||
|
||||
set(Source_Files__Controller__Attachment
|
||||
"ControllerAttachment.cpp"
|
||||
"ControllerAttachment.h"
|
||||
"MemoryPack.cpp"
|
||||
"MemoryPack.h"
|
||||
"RumblePack.cpp"
|
||||
"RumblePack.h"
|
||||
)
|
||||
source_group("Source Files\\Controller\\Attachment" FILES ${Source_Files__Controller__Attachment})
|
||||
|
||||
set(Source_Files__CustomImpl
|
||||
"GameOverlay.cpp"
|
||||
"GameOverlay.h"
|
||||
"Console.cpp"
|
||||
"Console.h"
|
||||
"ImGuiImpl.cpp"
|
||||
"ImGuiImpl.h"
|
||||
)
|
||||
source_group("Source Files\\CustomImpl" FILES ${Source_Files__CustomImpl})
|
||||
|
||||
set(Source_Files__CustomImpl__Hooks
|
||||
"Hooks.cpp"
|
||||
"Hooks.h"
|
||||
)
|
||||
source_group("Source Files\\CustomImpl\\Hooks" FILES ${Source_Files__CustomImpl__Hooks})
|
||||
|
||||
set(Source_Files__CustomImpl__Utils
|
||||
"Utils.cpp"
|
||||
"Utils.h"
|
||||
)
|
||||
source_group("Source Files\\CustomImpl\\Utils" FILES ${Source_Files__CustomImpl__Utils})
|
||||
|
||||
set(Source_Files__Globals
|
||||
"Cvar.cpp"
|
||||
"Cvar.h"
|
||||
"LUSMacros.h"
|
||||
"Window.cpp"
|
||||
"Window.h"
|
||||
)
|
||||
source_group("Source Files\\Globals" FILES ${Source_Files__Globals})
|
||||
|
||||
set(Source_Files__Lib
|
||||
"Lib/mINI/src/mini/ini.h"
|
||||
"Lib/StrHash64.cpp"
|
||||
"Lib/StrHash64.h"
|
||||
"Lib/tinyxml2/tinyxml2.cpp"
|
||||
"stox.cpp"
|
||||
"stox.h"
|
||||
)
|
||||
source_group("Source Files\\Lib" FILES ${Source_Files__Lib})
|
||||
|
||||
set(Source_Files__Lib__Fast3D
|
||||
"Lib/Fast3D/gfx_cc.cpp"
|
||||
"Lib/Fast3D/gfx_cc.h"
|
||||
"Lib/Fast3D/gfx_pc.cpp"
|
||||
"Lib/Fast3D/gfx_pc.h"
|
||||
"Lib/Fast3D/gfx_rendering_api.h"
|
||||
"Lib/Fast3D/gfx_screen_config.h"
|
||||
"Lib/Fast3D/gfx_window_manager_api.h"
|
||||
)
|
||||
|
||||
if (NOT CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
list(APPEND Source_Files__Lib__Fast3D
|
||||
"Lib/Fast3D/gfx_opengl.cpp"
|
||||
"Lib/Fast3D/gfx_opengl.h"
|
||||
"Lib/Fast3D/gfx_sdl.h"
|
||||
"Lib/Fast3D/gfx_sdl2.cpp"
|
||||
)
|
||||
endif()
|
||||
source_group("Source Files\\Lib\\Fast3D" FILES ${Source_Files__Lib__Fast3D})
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(Source_Files__Lib__Fast3D__extra
|
||||
"Lib/Fast3D/gfx_direct3d11.cpp"
|
||||
"Lib/Fast3D/gfx_direct3d11.h"
|
||||
"Lib/Fast3D/gfx_direct3d12.cpp"
|
||||
"Lib/Fast3D/gfx_direct3d12.h"
|
||||
"Lib/Fast3D/gfx_direct3d12_guids.h"
|
||||
"Lib/Fast3D/gfx_direct3d_common.cpp"
|
||||
"Lib/Fast3D/gfx_direct3d_common.h"
|
||||
"Lib/Fast3D/gfx_dxgi.cpp"
|
||||
"Lib/Fast3D/gfx_dxgi.h"
|
||||
)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(Source_Files__Lib__Fast3D__extra
|
||||
"Lib/Fast3D/gfx_glx.cpp"
|
||||
"Lib/Fast3D/gfx_glx.h"
|
||||
)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
set(Source_Files__Lib__Fast3D__extra
|
||||
"Lib/Fast3D/gfx_wiiu.cpp"
|
||||
"Lib/Fast3D/gfx_wiiu.h"
|
||||
"Lib/Fast3D/gfx_gx2.cpp"
|
||||
"Lib/Fast3D/gfx_gx2.h"
|
||||
"Lib/Fast3D/gx2_shader_gen.c"
|
||||
"Lib/Fast3D/gx2_shader_gen.h"
|
||||
)
|
||||
endif()
|
||||
source_group("Source Files\\Lib\\Fast3D\\extra" FILES ${Source_Files__Lib__Fast3D__extra})
|
||||
|
||||
set(Source_Files__Lib__ImGui
|
||||
"Lib/ImGui/imconfig.h"
|
||||
"Lib/ImGui/imgui.cpp"
|
||||
"Lib/ImGui/imgui.h"
|
||||
"Lib/ImGui/imgui_demo.cpp"
|
||||
"Lib/ImGui/imgui_draw.cpp"
|
||||
"Lib/ImGui/imgui_internal.h"
|
||||
"Lib/ImGui/imgui_tables.cpp"
|
||||
"Lib/ImGui/imgui_widgets.cpp"
|
||||
"Lib/ImGui/imstb_rectpack.h"
|
||||
"Lib/ImGui/imstb_textedit.h"
|
||||
"Lib/ImGui/imstb_truetype.h"
|
||||
)
|
||||
|
||||
if (NOT CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
list(APPEND Source_Files__Lib__ImGui
|
||||
"Lib/ImGui/backends/imgui_impl_opengl3.cpp"
|
||||
"Lib/ImGui/backends/imgui_impl_opengl3.h"
|
||||
"Lib/ImGui/backends/imgui_impl_sdl.cpp"
|
||||
"Lib/ImGui/backends/imgui_impl_sdl.h"
|
||||
)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(Source_Files__Lib__ImGui__Windows
|
||||
"Lib/ImGui/backends/imgui_impl_dx11.cpp"
|
||||
"Lib/ImGui/backends/imgui_impl_dx11.h"
|
||||
"Lib/ImGui/backends/imgui_impl_win32.cpp"
|
||||
"Lib/ImGui/backends/imgui_impl_win32.h"
|
||||
)
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
set(Source_Files__Lib__ImGui__WiiU
|
||||
"Lib/ImGui/backends/wiiu/imgui_impl_wiiu.cpp"
|
||||
"Lib/ImGui/backends/wiiu/imgui_impl_wiiu.h"
|
||||
"Lib/ImGui/backends/wiiu/imgui_impl_gx2.cpp"
|
||||
"Lib/ImGui/backends/wiiu/imgui_impl_gx2.h"
|
||||
)
|
||||
endif ()
|
||||
source_group("Source Files\\Lib\\ImGui" FILES
|
||||
${Source_Files__Lib__ImGui}
|
||||
${Source_Files__Lib__ImGui__Windows}
|
||||
${Source_Files__Lib__ImGui__WiiU}
|
||||
)
|
||||
|
||||
set(Source_Files__Lib__Mercury
|
||||
"Lib/Mercury/Mercury.cpp"
|
||||
"Lib/Mercury/Mercury.h"
|
||||
)
|
||||
source_group("Source Files\\Lib\\Mercury" FILES ${Source_Files__Lib__Mercury})
|
||||
|
||||
set(Source_Files__Lib__stb
|
||||
"Lib/stb/stb_image.h"
|
||||
"Lib/stb/stb_image_write.h"
|
||||
"Lib/stb/stb_impl.c"
|
||||
)
|
||||
source_group("Source Files\\Lib\\stb" FILES ${Source_Files__Lib__stb})
|
||||
|
||||
set(Source_Files__Lib__dr_libs
|
||||
"Lib/dr_libs/mp3.h"
|
||||
"Lib/dr_libs/wav.h"
|
||||
)
|
||||
source_group("Source Files\\Lib\\dr_libs" FILES ${Source_Files__Lib__dr_libs})
|
||||
|
||||
set(Source_Files__Lib__tinyxml2
|
||||
"Lib/tinyxml2/tinyxml2.h"
|
||||
)
|
||||
source_group("Source Files\\Lib\\tinyxml2" FILES ${Source_Files__Lib__tinyxml2})
|
||||
|
||||
set(Source_Files__Logging
|
||||
"luslog.cpp"
|
||||
"luslog.h"
|
||||
)
|
||||
source_group("Source Files\\Logging" FILES ${Source_Files__Logging})
|
||||
|
||||
set(Source_Files__Resources
|
||||
"GameVersions.h"
|
||||
"Resource.cpp"
|
||||
"Resource.h"
|
||||
"ResourceMgr.cpp"
|
||||
"ResourceMgr.h"
|
||||
)
|
||||
source_group("Source Files\\Resources" FILES ${Source_Files__Resources})
|
||||
|
||||
set(Source_Files__Resources__Factories
|
||||
"Factories/AnimationFactory.cpp"
|
||||
"Factories/ArrayFactory.cpp"
|
||||
"Factories/AudioFactory.cpp"
|
||||
"Factories/BlobFactory.cpp"
|
||||
"Factories/CollisionHeaderFactory.cpp"
|
||||
"Factories/CutsceneFactory.cpp"
|
||||
"Factories/DisplayListFactory.cpp"
|
||||
"Factories/MaterialFactory.cpp"
|
||||
"Factories/MtxFactory.cpp"
|
||||
"Factories/PathFactory.cpp"
|
||||
"Factories/PlayerAnimationFactory.cpp"
|
||||
"Factories/ResourceLoader.cpp"
|
||||
"Factories/SceneFactory.cpp"
|
||||
"Factories/SkeletonFactory.cpp"
|
||||
"Factories/SkeletonLimbFactory.cpp"
|
||||
"Factories/TextFactory.cpp"
|
||||
"Factories/TextureFactory.cpp"
|
||||
"Factories/VtxFactory.cpp"
|
||||
)
|
||||
source_group("Source Files\\Resources\\Factories" FILES ${Source_Files__Resources__Factories})
|
||||
|
||||
set(Source_Files__Resources__Files
|
||||
"Animation.cpp"
|
||||
"Array.cpp"
|
||||
"Audio.cpp"
|
||||
"Blob.cpp"
|
||||
"CollisionHeader.cpp"
|
||||
"Cutscene.cpp"
|
||||
"DisplayList.cpp"
|
||||
"Material.cpp"
|
||||
"Matrix.cpp"
|
||||
"Model.cpp"
|
||||
"Path.cpp"
|
||||
"PlayerAnimation.cpp"
|
||||
"Scene.cpp"
|
||||
"Skeleton.cpp"
|
||||
"SkeletonLimb.cpp"
|
||||
"Text.cpp"
|
||||
"Texture.cpp"
|
||||
"Vertex.cpp"
|
||||
)
|
||||
source_group("Source Files\\Resources\\Files" FILES ${Source_Files__Resources__Files})
|
||||
|
||||
set(Source_Files__Resources__mpq
|
||||
"Archive.cpp"
|
||||
"Archive.h"
|
||||
"File.cpp"
|
||||
"File.h"
|
||||
)
|
||||
source_group("Source Files\\Resources\\mpq" FILES ${Source_Files__Resources__mpq})
|
||||
|
||||
set(Source_Files__Crash_Handler
|
||||
"CrashHandler.cpp"
|
||||
"CrashHandler.h"
|
||||
)
|
||||
source_group("Source Files\\Crash Handler" FILES ${Source_Files__Crash_Handler})
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(Source_Files__Darwin
|
||||
"OSXFolderManager.mm"
|
||||
"OSXFolderManager.h"
|
||||
)
|
||||
source_group("Source Files\\Darwin" FILES ${Source_Files__Darwin})
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
|
||||
set(Source_Files__NintendoSwitch
|
||||
"SwitchImpl.cpp"
|
||||
"SwitchImpl.h"
|
||||
)
|
||||
source_group("Source Files\\NintendoSwitch" FILES ${Source_Files__NintendoSwitch})
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
set(Source_Files__CafeOS
|
||||
"WiiUController.cpp"
|
||||
"WiiUController.h"
|
||||
"WiiUGamepad.cpp"
|
||||
"WiiUGamepad.h"
|
||||
"WiiUImpl.cpp"
|
||||
"WiiUImpl.h"
|
||||
)
|
||||
source_group("Source Files\\CafeOS" FILES ${Source_Files__CafeOS})
|
||||
endif()
|
||||
|
||||
set(ALL_FILES
|
||||
${Header_Files__Resources__Factories}
|
||||
${Header_Files__Resources__Files}
|
||||
${Source_Files__Audio}
|
||||
${Source_Files__Audio__extra}
|
||||
${Source_Files__Controller}
|
||||
${Source_Files__Controller__Attachment}
|
||||
${Source_Files__CustomImpl}
|
||||
${Source_Files__CustomImpl__Hooks}
|
||||
${Source_Files__CustomImpl__Utils}
|
||||
${Source_Files__Globals}
|
||||
${Source_Files__Lib}
|
||||
${Source_Files__Lib__Fast3D}
|
||||
${Source_Files__Lib__Fast3D__extra}
|
||||
${Source_Files__Lib__ImGui}
|
||||
${Source_Files__Lib__ImGui__Windows}
|
||||
${Source_Files__Lib__ImGui__WiiU}
|
||||
${Source_Files__Lib__Mercury}
|
||||
${Source_Files__Lib__stb}
|
||||
${Source_Files__Lib__dr_libs}
|
||||
${Source_Files__Lib__tinyxml2}
|
||||
${Source_Files__Logging}
|
||||
${Source_Files__Resources}
|
||||
${Source_Files__Resources__Factories}
|
||||
${Source_Files__Resources__Files}
|
||||
${Source_Files__Resources__mpq}
|
||||
${Source_Files__Crash_Handler}
|
||||
${Source_Files__Darwin}
|
||||
${Source_Files__NintendoSwitch}
|
||||
${Source_Files__CafeOS}
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Target
|
||||
################################################################################
|
||||
add_library(${PROJECT_NAME} STATIC ${ALL_FILES})
|
||||
|
||||
if (NOT TARGET storm)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../StormLib ${CMAKE_BINARY_DIR}/StormLib EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||
endif()
|
||||
|
||||
set(ROOT_NAMESPACE libultraship)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
VS_GLOBAL_KEYWORD "Win32Proj"
|
||||
)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
################################################################################
|
||||
# MSVC runtime library
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||
$<$<CONFIG:Debug>:
|
||||
MultiThreadedDebug
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
MultiThreaded
|
||||
>
|
||||
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||
$<$<CONFIG:Debug>:
|
||||
MultiThreadedDebug
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
MultiThreaded
|
||||
>
|
||||
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
||||
)
|
||||
endif()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
||||
endif()
|
||||
################################################################################
|
||||
# Compile definitions
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
"SPDLOG_ACTIVE_LEVEL=0;"
|
||||
"WIN32;"
|
||||
"_CONSOLE;"
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
"ENABLE_DX11;"
|
||||
"ENABLE_OPENGL;"
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
"SPDLOG_ACTIVE_LEVEL=0;"
|
||||
"WIN32;"
|
||||
"_CONSOLE;"
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
"ENABLE_OPENGL;"
|
||||
"ENABLE_DX11;"
|
||||
"UNICODE;"
|
||||
"_UNICODE"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
endif()
|
||||
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
"SPDLOG_ACTIVE_LEVEL=3;"
|
||||
"SPDLOG_NO_THREAD_ID;"
|
||||
"SPDLOG_NO_TLS;"
|
||||
"STBI_NO_THREAD_LOCALS;"
|
||||
)
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_DEBUG"
|
||||
">"
|
||||
"$<$<CONFIG:Release>:"
|
||||
"NDEBUG"
|
||||
">"
|
||||
"ENABLE_OPENGL;"
|
||||
"SPDLOG_ACTIVE_LEVEL=0;"
|
||||
)
|
||||
endif()
|
||||
################################################################################
|
||||
# Compile and link options
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
find_package(SDL2)
|
||||
find_package(GLEW)
|
||||
find_package(X11)
|
||||
if (NOT GLEW_FOUND)
|
||||
include (FetchContent)
|
||||
FetchContent_Declare(
|
||||
glew
|
||||
GIT_REPOSITORY https://github.com/Perlmint/glew-cmake.git
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../external/glew
|
||||
)
|
||||
FetchContent_MakeAvailable(glew)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/glew/build/cmake ${CMAKE_BINARY_DIR}/glew EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
if (NOT GLEW_FOUND)
|
||||
set(GLEW-INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/../../external/glew/include)
|
||||
else()
|
||||
set(GLEW-INCLUDE ${GLEW_INCLUDE_DIRS})
|
||||
endif()
|
||||
set(SDL2-INCLUDE ${SDL2_INCLUDE_DIRS})
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||
find_package(SDL2)
|
||||
else()
|
||||
find_package(SDL2)
|
||||
find_package(GLEW)
|
||||
set(GLEW-INCLUDE ${GLEW_INCLUDE_DIRS})
|
||||
set(SDL2-INCLUDE ${SDL2_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Lib/spdlog/include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Lib/Fast3D/U64/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Lib/Fast3D/U64/PR
|
||||
${SDL2-INCLUDE}
|
||||
${GLEW-INCLUDE}
|
||||
${SWITCH-INCLUDE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Lib/ImGui/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/ZAPDUtils
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../StormLib/src
|
||||
.
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/Od;
|
||||
/Oi-
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/std:c++latest;
|
||||
/Oi;
|
||||
/Gy
|
||||
>
|
||||
/permissive-;
|
||||
/MP;
|
||||
/sdl;
|
||||
/W3;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/Od;
|
||||
/Oi-;
|
||||
/W2
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/Oi;
|
||||
/Gy;
|
||||
/W3
|
||||
>
|
||||
/permissive-;
|
||||
/MP;
|
||||
/sdl;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
endif()
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:
|
||||
/OPT:REF;
|
||||
/OPT:ICF
|
||||
>
|
||||
/SUBSYSTEM:CONSOLE
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Release>:
|
||||
/OPT:REF;
|
||||
/OPT:ICF
|
||||
>
|
||||
/SUBSYSTEM:CONSOLE
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-error
|
||||
-Wno-unused-variable
|
||||
-Wno-unused-parameter
|
||||
-Wno-unused-function
|
||||
-Wno-parentheses
|
||||
-Wno-narrowing
|
||||
-Wno-missing-field-initializers
|
||||
)
|
||||
endif()
|
||||
################################################################################
|
||||
# Dependencies
|
||||
################################################################################
|
||||
# Link with other targets.
|
||||
|
||||
find_package(OpenGL QUIET)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
find_package(X11)
|
||||
find_package(PulseAudio)
|
||||
endif()
|
||||
|
||||
if (NOT GLEW_FOUND)
|
||||
set(GLEW-LIB glew_s)
|
||||
else()
|
||||
set(GLEW-LIB GLEW::GLEW)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
"GLEW::GLEW;"
|
||||
"opengl32;"
|
||||
"storm;"
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
"GLEW::GLEW;"
|
||||
"opengl32;"
|
||||
"storm;"
|
||||
)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
find_package(SDL2)
|
||||
find_package(GLEW)
|
||||
find_package(OpenGL QUIET)
|
||||
find_Library(OSX_FOUNDATION Foundation)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
"storm;"
|
||||
SDL2::SDL2
|
||||
GLEW::GLEW
|
||||
${OPENGL_opengl_LIBRARY}
|
||||
${CMAKE_DL_LIBS}
|
||||
Threads::Threads
|
||||
${OSX_FOUNDATION}
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
storm
|
||||
SDL2::SDL2
|
||||
Threads::Threads
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
find_package(SDL2 REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
storm
|
||||
SDL2::SDL2-static
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${DEVKITPRO}/portlibs/wiiu/include/
|
||||
)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
SDL2::SDL2
|
||||
${PULSEAUDIO_LIBRARY}
|
||||
${GLEW-LIB}
|
||||
${OPENGL_glx_LIBRARY}
|
||||
${OPENGL_opengl_LIBRARY}
|
||||
${X11_LIBRARIES}
|
||||
storm
|
||||
)
|
||||
endif()
|
||||
@@ -1,145 +1,133 @@
|
||||
#include "Console.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "Cvar.h"
|
||||
#include "GlobalCtx2.h"
|
||||
#include "ImGuiImpl.h"
|
||||
#include "Lib/ImGui/imgui.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "Lib/ImGui/imgui_internal.h"
|
||||
#include "Utils.h"
|
||||
#include <sstream>
|
||||
|
||||
std::map<ImGuiKey, std::string> Bindings;
|
||||
std::map<ImGuiKey, std::string> BindingToggle;
|
||||
|
||||
static bool HelpCommand(const std::vector<std::string>&) {
|
||||
INFO("SoH Commands:");
|
||||
for(const auto& cmd : SohImGui::console->Commands) {
|
||||
INFO("%s", (" - " + cmd.first).c_str());
|
||||
namespace Ship {
|
||||
std::string BuildUsage(const CommandEntry& entry) {
|
||||
std::string usage;
|
||||
for (const auto& arg : entry.arguments)
|
||||
usage += StringHelper::Sprintf(arg.optional ? "[%s] " : "<%s> ", arg.info.c_str());
|
||||
return usage;
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static bool ClearCommand(const std::vector<std::string>&) {
|
||||
SohImGui::console->Log[SohImGui::console->selected_channel].clear();
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
bool Console::HelpCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args) {
|
||||
Console->SendInfoMessage("SoH Commands:");
|
||||
for (const auto& cmd : Console->Commands) {
|
||||
Console->SendInfoMessage(" - " + cmd.first);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
std::string toLowerCase(std::string in) {
|
||||
std::string cpy(in);
|
||||
std::transform(cpy.begin(), cpy.end(), cpy.begin(), ::tolower);
|
||||
return cpy;
|
||||
}
|
||||
bool Console::ClearCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args) {
|
||||
Console->ClearLogs(Console->GetCurrentChannel());
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static bool BindCommand(const std::vector<std::string>& args) {
|
||||
if(args.size() > 2) {
|
||||
const ImGuiIO* io = &ImGui::GetIO();;
|
||||
for (size_t k = 0; k < std::size(io->KeysData); k++) {
|
||||
std::string key(ImGui::GetKeyName(k));
|
||||
bool Console::BindCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args) {
|
||||
if (args.size() > 2) {
|
||||
const ImGuiIO* io = &ImGui::GetIO();;
|
||||
for (size_t k = 0; k < std::size(io->KeysData); k++) {
|
||||
std::string key(ImGui::GetKeyName(k));
|
||||
|
||||
if(toLowerCase(args[1]) == toLowerCase(key)) {
|
||||
std::vector<std::string> tmp;
|
||||
const char* const delim = " ";
|
||||
std::ostringstream imploded;
|
||||
std::copy(args.begin() + 2, args.end(), std::ostream_iterator<std::string>(imploded, delim));
|
||||
Bindings[k] = imploded.str();
|
||||
INFO("Binding '%s' to %s", args[1].c_str(), Bindings[k].c_str());
|
||||
break;
|
||||
if (toLowerCase(args[1]) == toLowerCase(key)) {
|
||||
std::vector<std::string> tmp;
|
||||
const char* const delim = " ";
|
||||
std::ostringstream imploded;
|
||||
std::copy(args.begin() + 2, args.end(), std::ostream_iterator<std::string>(imploded, delim));
|
||||
Console->Bindings[k] = imploded.str();
|
||||
Console->SendInfoMessage("Binding '%s' to %s", args[1].c_str(), Console->Bindings[k].c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
bool Console::BindToggleCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args) {
|
||||
if (args.size() > 2) {
|
||||
const ImGuiIO* io = &ImGui::GetIO();;
|
||||
for (size_t k = 0; k < std::size(io->KeysData); k++) {
|
||||
std::string key(ImGui::GetKeyName(k));
|
||||
|
||||
if (toLowerCase(args[1]) == toLowerCase(key)) {
|
||||
Console->BindingToggle[k] = args[2];
|
||||
Console->SendInfoMessage("Binding toggle '%s' to %s", args[1].c_str(), Console->BindingToggle[k].c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
void Console::Init() {
|
||||
this->inputBuffer = new char[MAX_BUFFER_SIZE];
|
||||
strcpy(this->inputBuffer, "");
|
||||
this->filterBuffer = new char[MAX_BUFFER_SIZE];
|
||||
strcpy(this->filterBuffer, "");
|
||||
AddCommand("help", { HelpCommand, "Shows all the commands" });
|
||||
AddCommand("clear", { ClearCommand, "Clear the console history" });
|
||||
AddCommand("bind", { BindCommand, "Binds key to commands" });
|
||||
AddCommand("bind-toggle", { BindToggleCommand, "Bind key as a bool toggle" });
|
||||
}
|
||||
|
||||
void Console::Update() {
|
||||
for (auto [key, cmd] : Bindings) {
|
||||
if (ImGui::IsKeyPressed(key)) Dispatch(cmd);
|
||||
}
|
||||
for (auto [key, var] : BindingToggle) {
|
||||
if (ImGui::IsKeyPressed(key)) {
|
||||
CVar* cvar = CVar_Get(var.c_str());
|
||||
Dispatch("set " + var + " " + std::to_string(cvar == nullptr ? 0 : !static_cast<bool>(cvar->value.valueS32)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static bool BindToggleCommand(const std::vector<std::string>& args) {
|
||||
if (args.size() > 2) {
|
||||
const ImGuiIO* io = &ImGui::GetIO();;
|
||||
for (size_t k = 0; k < std::size(io->KeysData); k++) {
|
||||
std::string key(ImGui::GetKeyName(k));
|
||||
|
||||
if (toLowerCase(args[1]) == toLowerCase(key)) {
|
||||
BindingToggle[k] = args[2];
|
||||
INFO("Binding toggle '%s' to %s", args[1].c_str(), BindingToggle[k].c_str());
|
||||
break;
|
||||
}
|
||||
void Console::Draw() {
|
||||
if (!this->opened) {
|
||||
CVar_SetS32("gConsoleEnabled", 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
std::string BuildUsage(const CommandEntry& entry) {
|
||||
std::string usage;
|
||||
for (const auto& arg : entry.arguments)
|
||||
usage += StringHelper::Sprintf(arg.optional ? "[%s] " : "<%s> ", arg.info.c_str());
|
||||
return usage;
|
||||
}
|
||||
bool input_focus = false;
|
||||
|
||||
void Console::Init() {
|
||||
this->InputBuffer = new char[MAX_BUFFER_SIZE];
|
||||
strcpy(this->InputBuffer, "");
|
||||
this->FilterBuffer = new char[MAX_BUFFER_SIZE];
|
||||
strcpy(this->FilterBuffer, "");
|
||||
this->Commands["help"] = { HelpCommand, "Shows all the commands" };
|
||||
this->Commands["clear"] = { ClearCommand, "Clear the console history" };
|
||||
this->Commands["bind"] = { BindCommand, "Binds key to commands" };
|
||||
this->Commands["bind-toggle"] = { BindToggleCommand, "Bind key as a bool toggle" };
|
||||
}
|
||||
|
||||
void Console::Update() {
|
||||
for(auto [key, cmd] : Bindings) {
|
||||
if (ImGui::IsKeyPressed(key)) Dispatch(cmd);
|
||||
}
|
||||
for (auto [key, var] : BindingToggle) {
|
||||
if (ImGui::IsKeyPressed(key)) {
|
||||
CVar* cvar = CVar_Get(var.c_str());
|
||||
Dispatch("set " + var + " " + std::to_string(cvar == nullptr ? 0 : !static_cast<bool>(cvar->value.valueS32)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" uint8_t __enableGameInput;
|
||||
|
||||
void Console::Draw() {
|
||||
bool input_focus = false;
|
||||
__enableGameInput = true;
|
||||
if (!this->opened) return;
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||
ImGui::Begin("Console", nullptr, ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver);
|
||||
ImGui::Begin("Console", &this->opened, ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
const ImVec2 pos = ImGui::GetWindowPos();
|
||||
const ImVec2 size = ImGui::GetWindowSize();
|
||||
|
||||
__enableGameInput = !ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows);
|
||||
|
||||
// SohImGui::ShowCursor(ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows | ImGuiHoveredFlags_RectOnly), SohImGui::Dialogues::dConsole);
|
||||
|
||||
// Renders autocomplete window
|
||||
if(this->OpenAutocomplete) {
|
||||
if (this->openAutocomplete) {
|
||||
ImGui::SetNextWindowSize(ImVec2(350, std::min(static_cast<int>(this->Autocomplete.size()), 3) * 20.f), ImGuiCond_Once);
|
||||
ImGui::SetNextWindowPos(ImVec2(pos.x + 8, pos.y + size.y - 1));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(3, 3));
|
||||
ImGui::Begin("##WndAutocomplete", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove );
|
||||
ImGui::Begin("##WndAutocomplete", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove);
|
||||
ImGui::BeginChild("AC_Child", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(.3f, .3f, .3f, 1.0f));
|
||||
if (ImGui::BeginTable("AC_History", 1)) {
|
||||
for (const auto &cmd : this->Autocomplete) {
|
||||
std::string usage = BuildUsage(this->Commands[cmd]);
|
||||
for (const auto& cmd : this->Autocomplete) {
|
||||
std::string usage = BuildUsage(this->Commands[cmd]);
|
||||
std::string preview = cmd + " - " + this->Commands[cmd].description;
|
||||
std::string autocomplete = (usage == NULLSTR ? cmd : usage);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
if (ImGui::Selectable(preview.c_str())) {
|
||||
memset(this->InputBuffer, 0, MAX_BUFFER_SIZE);
|
||||
memcpy(this->InputBuffer, autocomplete.c_str(), sizeof(char) * autocomplete.size());
|
||||
this->OpenAutocomplete = false;
|
||||
memset(this->inputBuffer, 0, MAX_BUFFER_SIZE);
|
||||
memcpy(this->inputBuffer, autocomplete.c_str(), sizeof(char) * autocomplete.size());
|
||||
this->openAutocomplete = false;
|
||||
input_focus = true;
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
this->OpenAutocomplete = false;
|
||||
this->openAutocomplete = false;
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::EndChild();
|
||||
@@ -149,7 +137,7 @@ void Console::Draw() {
|
||||
|
||||
if (ImGui::BeginPopupContextWindow("Context Menu")) {
|
||||
if (ImGui::MenuItem("Copy Text")) {
|
||||
ImGui::SetClipboardText(this->Log[this->selected_channel][this->selectedId].text.c_str());
|
||||
ImGui::SetClipboardText(this->Log[this->currentChannel][this->selectedId].text.c_str());
|
||||
this->selectedId = -1;
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
@@ -159,172 +147,270 @@ void Console::Draw() {
|
||||
}
|
||||
|
||||
// Renders top bar filters
|
||||
if (ImGui::Button("Clear")) this->Log[this->selected_channel].clear();
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(150);
|
||||
if (ImGui::BeginCombo("##channel", this->selected_channel.c_str())) {
|
||||
for (const auto& channel : log_channels) {
|
||||
const bool is_selected = (channel == std::string(this->selected_channel));
|
||||
if (ImGui::Selectable(channel.c_str(), is_selected))
|
||||
this->selected_channel = channel;
|
||||
if (is_selected) ImGui::SetItemDefaultFocus();
|
||||
if (ImGui::Button("Clear")) this->Log[this->currentChannel].clear();
|
||||
|
||||
if (CVar_GetS32("gSinkEnabled", 0)) {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(150);
|
||||
if (ImGui::BeginCombo("##channel", this->currentChannel.c_str())) {
|
||||
for (const auto& channel : LogChannels) {
|
||||
const bool is_selected = (channel == std::string(this->currentChannel));
|
||||
if (ImGui::Selectable(channel.c_str(), is_selected))
|
||||
this->currentChannel = channel;
|
||||
if (is_selected) ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
} else {
|
||||
this->currentChannel = "Console";
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(150);
|
||||
if (ImGui::BeginCombo("##level", this->level_filter.c_str())) {
|
||||
for (const auto& filter : priority_filters) {
|
||||
const bool is_selected = (filter == std::string(this->level_filter));
|
||||
if (ImGui::Selectable(filter.c_str(), is_selected))
|
||||
{
|
||||
this->level_filter = filter;
|
||||
if (is_selected) ImGui::SetItemDefaultFocus();
|
||||
|
||||
if (this->currentChannel != "Console") {
|
||||
if (ImGui::BeginCombo("##level", spdlog::level::to_string_view(this->levelFilter).data())) {
|
||||
for (const auto& priority_filter : PriorityFilters) {
|
||||
const bool is_selected = priority_filter == this->levelFilter;
|
||||
if (ImGui::Selectable(spdlog::level::to_string_view(priority_filter).data(), is_selected))
|
||||
{
|
||||
this->levelFilter = priority_filter;
|
||||
if (is_selected) ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
} else {
|
||||
this->levelFilter = spdlog::level::trace;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(-1);
|
||||
if (ImGui::InputTextWithHint("##input", "Filter", this->FilterBuffer, MAX_BUFFER_SIZE))this->filter = std::string(this->FilterBuffer);
|
||||
if (ImGui::InputTextWithHint("##input", "Filter", this->filterBuffer, MAX_BUFFER_SIZE))this->filter = std::string(this->filterBuffer);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
// Renders console history
|
||||
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(.3f, .3f, .3f, 1.0f));
|
||||
if (ImGui::BeginTable("History", 1)) {
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(.3f, .3f, .3f, 1.0f));
|
||||
if (ImGui::BeginTable("History", 1)) {
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
|
||||
if (this->selectedId < (int)this->Log.size() - 1) ++this->selectedId;
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
|
||||
if (this->selectedId > 0) --this->selectedId;
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
|
||||
if (this->selectedId < (int)this->Log.size() - 1)++this->selectedId;
|
||||
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
|
||||
if (this->selectedId > 0)--this->selectedId;
|
||||
|
||||
const std::vector<ConsoleLine> channel = this->Log[this->selected_channel];
|
||||
for (int i = 0; i < static_cast<int>(channel.size()); i++) {
|
||||
ConsoleLine line = channel[i];
|
||||
if(!this->filter.empty() && line.text.find(this->filter) == std::string::npos) continue;
|
||||
if(this->level_filter != NULLSTR && line.priority != (std::find(priority_filters.begin(), priority_filters.end(), this->level_filter) - priority_filters.begin()) - 1) continue;
|
||||
std::string id = line.text + "##" + std::to_string(i);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
const bool is_selected = (this->selectedId == i) || std::find(this->selectedEntries.begin(), this->selectedEntries.end(), i) != this->selectedEntries.end();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, this->priority_colors[line.priority]);
|
||||
if (ImGui::Selectable(id.c_str(), is_selected)) {
|
||||
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_LeftCtrl)) && !is_selected)
|
||||
this->selectedEntries.push_back(i);
|
||||
const std::vector<ConsoleLine> channel = this->Log[this->currentChannel];
|
||||
for (int i = 0; i < static_cast<int>(channel.size()); i++) {
|
||||
ConsoleLine line = channel[i];
|
||||
if (!this->filter.empty() && line.text.find(this->filter) == std::string::npos) continue;
|
||||
if (this->levelFilter > line.priority) continue;
|
||||
std::string id = line.text + "##" + std::to_string(i);
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
const bool is_selected = (this->selectedId == i) || std::find(this->selectedEntries.begin(), this->selectedEntries.end(), i) != this->selectedEntries.end();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, this->PriorityColours[line.priority]);
|
||||
if (ImGui::Selectable(id.c_str(), is_selected)) {
|
||||
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_LeftCtrl)) && !is_selected)
|
||||
this->selectedEntries.push_back(i);
|
||||
|
||||
else this->selectedEntries.clear();
|
||||
this->selectedId = is_selected ? -1 : i;
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
if (is_selected) ImGui::SetItemDefaultFocus();
|
||||
else this->selectedEntries.clear();
|
||||
this->selectedId = is_selected ? -1 : i;
|
||||
}
|
||||
ImGui::EndTable();
|
||||
ImGui::PopStyleColor();
|
||||
if (is_selected) ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
|
||||
ImGui::SetScrollHereY(1.0f);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
|
||||
ImGui::SetScrollHereY(1.0f);
|
||||
ImGui::EndChild();
|
||||
|
||||
// Renders input textfield
|
||||
constexpr ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackEdit |
|
||||
ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
|
||||
ImGui::PushItemWidth(-1);
|
||||
if(ImGui::InputTextWithHint("CMDInput", ">", this->InputBuffer, MAX_BUFFER_SIZE, flags, &Console::CallbackStub, this)) {
|
||||
input_focus = true;
|
||||
if(this->InputBuffer[0] != '\0' && this->InputBuffer[0] != ' ')
|
||||
this->Dispatch(std::string(this->InputBuffer));
|
||||
memset(this->InputBuffer, 0, MAX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
if(this->CMDHint != NULLSTR) {
|
||||
if (ImGui::IsItemFocused()) {
|
||||
ImGui::SetNextWindowPos(ImVec2(pos.x, pos.y + size.y));
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
||||
ImGui::TextUnformatted(this->CMDHint.c_str());
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
if (this->currentChannel == "Console") {
|
||||
// Renders input textfield
|
||||
constexpr ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackEdit |
|
||||
ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;
|
||||
#ifdef __WIIU__
|
||||
ImGui::PushItemWidth(-53.0f * 2.0f);
|
||||
#else
|
||||
ImGui::PushItemWidth(-53.0f);
|
||||
#endif
|
||||
if (ImGui::InputTextWithHint("##CMDInput", ">", this->inputBuffer, MAX_BUFFER_SIZE, flags, &Console::CallbackStub, this)) {
|
||||
input_focus = true;
|
||||
if (this->inputBuffer[0] != '\0' && this->inputBuffer[0] != ' ')
|
||||
this->Dispatch(std::string(this->inputBuffer));
|
||||
memset(this->inputBuffer, 0, MAX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
if (this->cmdHint != NULLSTR) {
|
||||
if (ImGui::IsItemFocused()) {
|
||||
ImGui::SetNextWindowPos(ImVec2(pos.x, pos.y + size.y));
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
||||
ImGui::TextUnformatted(this->cmdHint.c_str());
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
#ifdef __WIIU__
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 50 * 2.0f);
|
||||
#else
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetContentRegionAvail().x - 50);
|
||||
#endif
|
||||
if (ImGui::Button("Submit") && !input_focus && this->inputBuffer[0] != '\0' && this->inputBuffer[0] != ' ') {
|
||||
this->Dispatch(std::string(this->inputBuffer));
|
||||
memset(this->inputBuffer, 0, MAX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
ImGui::SetItemDefaultFocus();
|
||||
if (input_focus) ImGui::SetKeyboardFocusHere(-1);
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
||||
ImGui::SetItemDefaultFocus();
|
||||
if (input_focus) ImGui::SetKeyboardFocusHere(-1);
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void Console::Dispatch(const std::string& line) {
|
||||
this->CMDHint = NULLSTR;
|
||||
this->History.push_back(line);
|
||||
this->Log[this->selected_channel].push_back({ "> " + line } );
|
||||
const std::vector<std::string> cmd_args = StringHelper::Split(line, " ");
|
||||
if (this->Commands.contains(cmd_args[0])) {
|
||||
const CommandEntry entry = this->Commands[cmd_args[0]];
|
||||
if(!entry.handler(cmd_args) && !entry.arguments.empty())
|
||||
this->Log[this->selected_channel].push_back({ "[SOH] Usage: " + cmd_args[0] + " " + BuildUsage(entry), ERROR_LVL});
|
||||
return;
|
||||
ImGui::End();
|
||||
}
|
||||
this->Log[this->selected_channel].push_back({ "[SOH] Command not found", ERROR_LVL });
|
||||
}
|
||||
|
||||
int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
|
||||
const auto instance = static_cast<Console*>(data->UserData);
|
||||
const bool empty_history = instance->History.empty();
|
||||
const int history_index = instance->HistoryIndex;
|
||||
std::string history;
|
||||
void Console::Dispatch(const std::string& line) {
|
||||
this->cmdHint = NULLSTR;
|
||||
this->History.push_back(line);
|
||||
SendInfoMessage("> " + line);
|
||||
const std::vector<std::string> cmd_args = StringHelper::Split(line, " ");
|
||||
if (this->Commands.contains(cmd_args[0])) {
|
||||
const CommandEntry entry = this->Commands[cmd_args[0]];
|
||||
if (!entry.handler(shared_from_this(), cmd_args) && !entry.arguments.empty()) {
|
||||
SendErrorMessage("[SOH] Usage: " + cmd_args[0] + " " + BuildUsage(entry));
|
||||
}
|
||||
|
||||
switch(data->EventKey) {
|
||||
return;
|
||||
}
|
||||
SendErrorMessage("[SOH] Command not found");
|
||||
}
|
||||
|
||||
int Console::CallbackStub(ImGuiInputTextCallbackData* data) {
|
||||
const auto instance = static_cast<Console*>(data->UserData);
|
||||
const bool empty_history = instance->History.empty();
|
||||
const int history_index = instance->historyIndex;
|
||||
std::string history;
|
||||
|
||||
switch (data->EventKey) {
|
||||
case ImGuiKey_Tab:
|
||||
instance->Autocomplete.clear();
|
||||
for (auto& [cmd, entry] : instance->Commands)
|
||||
if (cmd.find(std::string(data->Buf)) != std::string::npos) instance->Autocomplete.push_back(cmd);
|
||||
instance->OpenAutocomplete = !instance->Autocomplete.empty();
|
||||
instance->CMDHint = NULLSTR;
|
||||
instance->openAutocomplete = !instance->Autocomplete.empty();
|
||||
instance->cmdHint = NULLSTR;
|
||||
break;
|
||||
case ImGuiKey_UpArrow:
|
||||
if (empty_history) break;
|
||||
if(history_index < static_cast<int>(instance->History.size()) - 1) instance->HistoryIndex += 1;
|
||||
if (history_index < static_cast<int>(instance->History.size()) - 1) instance->historyIndex += 1;
|
||||
data->DeleteChars(0, data->BufTextLen);
|
||||
data->InsertChars(0, instance->History[instance->HistoryIndex].c_str());
|
||||
instance->CMDHint = NULLSTR;
|
||||
data->InsertChars(0, instance->History[instance->historyIndex].c_str());
|
||||
instance->cmdHint = NULLSTR;
|
||||
break;
|
||||
case ImGuiKey_DownArrow:
|
||||
if (empty_history) break;
|
||||
if (history_index > -1) instance->HistoryIndex -= 1;
|
||||
if (history_index > -1) instance->historyIndex -= 1;
|
||||
data->DeleteChars(0, data->BufTextLen);
|
||||
if(history_index >= 0)
|
||||
if (history_index >= 0)
|
||||
data->InsertChars(0, instance->History[history_index].c_str());
|
||||
instance->CMDHint = NULLSTR;
|
||||
instance->cmdHint = NULLSTR;
|
||||
break;
|
||||
case ImGuiKey_Escape:
|
||||
instance->HistoryIndex = -1;
|
||||
instance->historyIndex = -1;
|
||||
data->DeleteChars(0, data->BufTextLen);
|
||||
instance->OpenAutocomplete = false;
|
||||
instance->CMDHint = NULLSTR;
|
||||
instance->openAutocomplete = false;
|
||||
instance->cmdHint = NULLSTR;
|
||||
break;
|
||||
default:
|
||||
instance->OpenAutocomplete = false;
|
||||
instance->openAutocomplete = false;
|
||||
for (auto& [cmd, entry] : instance->Commands) {
|
||||
const std::vector<std::string> cmd_args = StringHelper::Split(std::string(data->Buf), " ");
|
||||
if (data->BufTextLen > 2 && !cmd_args.empty() && cmd.find(cmd_args[0]) != std::string::npos) {
|
||||
instance->CMDHint = cmd + " " + BuildUsage(entry);
|
||||
instance->cmdHint = cmd + " " + BuildUsage(entry);
|
||||
break;
|
||||
}
|
||||
instance->CMDHint = NULLSTR;
|
||||
instance->cmdHint = NULLSTR;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Console::Append(const std::string& channel, Priority priority, const char* fmt, ...) {
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
this->Log[channel].push_back({ std::string(buf), priority });
|
||||
}
|
||||
void Console::Append(const std::string& channel, spdlog::level::level_enum priority, const char* fmt, va_list args) {
|
||||
char buf[2048];
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
this->Log[channel].push_back({ std::string(buf), priority });
|
||||
}
|
||||
|
||||
void Console::Append(const std::string& channel, spdlog::level::level_enum priority, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
Append(channel, priority, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void Console::SendInfoMessage(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
Append("Console", spdlog::level::info, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void Console::SendErrorMessage(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
Append("Console", spdlog::level::err, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void Console::SendInfoMessage(const std::string& str) {
|
||||
Append("Console", spdlog::level::info, str.c_str());
|
||||
}
|
||||
|
||||
void Console::SendErrorMessage(const std::string& str) {
|
||||
Append("Console", spdlog::level::err, str.c_str());
|
||||
}
|
||||
|
||||
void Console::ClearLogs(std::string channel) {
|
||||
Log[channel].clear();
|
||||
}
|
||||
|
||||
void Console::ClearLogs() {
|
||||
for (auto [key, var] : Log) {
|
||||
var.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool Console::HasCommand(const std::string& command) {
|
||||
for (const auto& Command : Commands) {
|
||||
if (Command.first == command) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Console::AddCommand(const std::string& command, CommandEntry entry) {
|
||||
if (!HasCommand(command)) {
|
||||
Commands[command] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Console::GetCurrentChannel() {
|
||||
return currentChannel;
|
||||
}
|
||||
|
||||
bool Console::IsOpened() {
|
||||
return opened;
|
||||
}
|
||||
|
||||
void Console::Close() {
|
||||
opened = false;
|
||||
}
|
||||
|
||||
void Console::Open() {
|
||||
opened = true;
|
||||
}
|
||||
}
|
||||
@@ -6,76 +6,96 @@
|
||||
#include <functional>
|
||||
|
||||
#include "Lib/ImGui/imgui.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
#define LOG(msg, ...) SohImGui::console->Append("Main", Priority::LOG_LVL, msg, ##__VA_ARGS__)
|
||||
#define INFO(msg, ...) SohImGui::console->Append("Main", Priority::INFO_LVL, msg, ##__VA_ARGS__)
|
||||
#define WARNING(msg, ...) SohImGui::console->Append("Main", Priority::WARNING_LVL, msg, ##__VA_ARGS__)
|
||||
#define ERROR(msg, ...) SohImGui::console->Append("Main", Priority::ERROR_LVL, msg, ##__VA_ARGS__)
|
||||
#define CMD_SUCCESS true
|
||||
#define CMD_FAILED false
|
||||
#define MAX_BUFFER_SIZE 255
|
||||
#define NULLSTR "None"
|
||||
namespace Ship {
|
||||
#define CMD_SUCCESS true
|
||||
#define CMD_FAILED false
|
||||
#define MAX_BUFFER_SIZE 255
|
||||
#define NULLSTR "None"
|
||||
|
||||
typedef std::function<bool(std::vector<std::string> args)> CommandHandler;
|
||||
class Console;
|
||||
typedef std::function<bool(std::shared_ptr<Console> Console, std::vector<std::string> args)> CommandHandler;
|
||||
|
||||
enum Priority {
|
||||
INFO_LVL,
|
||||
LOG_LVL,
|
||||
WARNING_LVL,
|
||||
ERROR_LVL
|
||||
};
|
||||
|
||||
enum class ArgumentType {
|
||||
TEXT, NUMBER, PLAYER_POS, PLAYER_ROT
|
||||
};
|
||||
|
||||
struct CommandArgument {
|
||||
std::string info;
|
||||
ArgumentType type = ArgumentType::NUMBER;
|
||||
bool optional = false;
|
||||
};
|
||||
|
||||
struct CommandEntry {
|
||||
CommandHandler handler;
|
||||
std::string description;
|
||||
std::vector<CommandArgument> arguments;
|
||||
};
|
||||
|
||||
struct ConsoleLine {
|
||||
std::string text;
|
||||
Priority priority = Priority::INFO_LVL;
|
||||
std::string channel = "Main";
|
||||
};
|
||||
|
||||
class Console {
|
||||
int selectedId = -1;
|
||||
std::vector<int> selectedEntries;
|
||||
std::string filter;
|
||||
std::string level_filter = NULLSTR;
|
||||
std::vector<std::string> log_channels = { "Main", "SoH Logging"};
|
||||
std::vector<std::string> priority_filters = { "None", "Info", "Log", "Warning", "Error" };
|
||||
std::vector<ImVec4> priority_colors = {
|
||||
ImVec4(1.0f, 1.0f, 1.0f, 1.0f),
|
||||
ImVec4(0.2f, 1.0f, 0.2f, 1.0f),
|
||||
ImVec4(0.9f, 0.8f, 0.4f, 0.01f),
|
||||
ImVec4(1.0f, 0.2f, 0.2f, 1.0f)
|
||||
enum class ArgumentType {
|
||||
TEXT, NUMBER, PLAYER_POS, PLAYER_ROT
|
||||
};
|
||||
public:
|
||||
std::map<std::string, std::vector<ConsoleLine>> Log;
|
||||
std::map<std::string, CommandEntry> Commands;
|
||||
std::vector<std::string> Autocomplete;
|
||||
std::vector<std::string> History;
|
||||
std::string CMDHint = NULLSTR;
|
||||
char* FilterBuffer = nullptr;
|
||||
char* InputBuffer = nullptr;
|
||||
bool OpenAutocomplete = false;
|
||||
int HistoryIndex = -1;
|
||||
std::string selected_channel = "Main";
|
||||
bool opened = false;
|
||||
void Init();
|
||||
void Update();
|
||||
void Draw();
|
||||
void Append(const std::string& channel, Priority priority, const char* fmt, ...) IM_FMTARGS(4);
|
||||
void Dispatch(const std::string& line);
|
||||
static int CallbackStub(ImGuiInputTextCallbackData* data);
|
||||
};
|
||||
|
||||
struct CommandArgument {
|
||||
std::string info;
|
||||
ArgumentType type = ArgumentType::NUMBER;
|
||||
bool optional = false;
|
||||
};
|
||||
|
||||
struct CommandEntry {
|
||||
CommandHandler handler;
|
||||
std::string description;
|
||||
std::vector<CommandArgument> arguments;
|
||||
};
|
||||
|
||||
struct ConsoleLine {
|
||||
std::string text;
|
||||
spdlog::level::level_enum priority = spdlog::level::info;
|
||||
std::string channel = "Console";
|
||||
};
|
||||
|
||||
class Console : public std::enable_shared_from_this<Console> {
|
||||
private:
|
||||
static int CallbackStub(ImGuiInputTextCallbackData* data);
|
||||
static bool ClearCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args);
|
||||
static bool HelpCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args);
|
||||
static bool BindCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args);
|
||||
static bool BindToggleCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args);
|
||||
|
||||
bool opened = false;
|
||||
int selectedId = -1;
|
||||
int historyIndex = -1;
|
||||
std::vector<int> selectedEntries;
|
||||
std::string filter;
|
||||
std::string currentChannel = "Console";
|
||||
bool openAutocomplete = false;
|
||||
char* inputBuffer = nullptr;
|
||||
char* filterBuffer = nullptr;
|
||||
std::string cmdHint = NULLSTR;
|
||||
spdlog::level::level_enum levelFilter = spdlog::level::trace;
|
||||
|
||||
std::vector<std::string> History;
|
||||
std::vector<std::string> Autocomplete;
|
||||
std::map<ImGuiKey, std::string> Bindings;
|
||||
std::map<ImGuiKey, std::string> BindingToggle;
|
||||
std::map<std::string, CommandEntry> Commands;
|
||||
std::map<std::string, std::vector<ConsoleLine>> Log;
|
||||
const std::vector<std::string> LogChannels = { "Console", "Logs" };
|
||||
const std::vector<spdlog::level::level_enum> PriorityFilters = { spdlog::level::off, spdlog::level::critical, spdlog::level::err, spdlog::level::warn, spdlog::level::info, spdlog::level::debug, spdlog::level::trace };
|
||||
const std::vector<ImVec4> PriorityColours = {
|
||||
ImVec4(0.8f, 0.8f, 0.8f, 1.0f), // TRACE
|
||||
ImVec4(0.9f, 0.9f, 0.9f, 1.0f), // DEBUG
|
||||
ImVec4(1.0f, 1.0f, 1.0f, 1.0f), // INFO
|
||||
ImVec4(1.0f, 0.875f, 0.125f, 1.0f), // WARN
|
||||
ImVec4(0.65f, 0.18f, 0.25, 1.0f), // ERROR
|
||||
ImVec4(0.95f, 0.11f, 0.25, 1.0f), // CRITICAL
|
||||
ImVec4(0.0f, 0.0f, 0.0f, 0.0f) // OFF
|
||||
};
|
||||
protected:
|
||||
void Append(const std::string& channel, spdlog::level::level_enum priority, const char* fmt, va_list args);
|
||||
|
||||
public:
|
||||
void ClearLogs(std::string channel);
|
||||
void ClearLogs();
|
||||
void Init();
|
||||
void Update();
|
||||
void Draw();
|
||||
void Dispatch(const std::string& line);
|
||||
void SendInfoMessage(const char* fmt, ...);
|
||||
void SendErrorMessage(const char* fmt, ...);
|
||||
void SendInfoMessage(const std::string& str);
|
||||
void SendErrorMessage(const std::string& str);
|
||||
void Append(const std::string& channel, spdlog::level::level_enum priority, const char* fmt, ...);
|
||||
bool HasCommand(const std::string& command);
|
||||
void AddCommand(const std::string& command, CommandEntry entry);
|
||||
std::string GetCurrentChannel();
|
||||
bool IsOpened();
|
||||
void Close();
|
||||
void Open();
|
||||
};
|
||||
}
|
||||
@@ -2,145 +2,286 @@
|
||||
|
||||
#include "Window.h"
|
||||
#include "Controller.h"
|
||||
#include "DisconnectedController.h"
|
||||
#include "DummyController.h"
|
||||
#include <Utils/StringHelper.h>
|
||||
#include "Cvar.h"
|
||||
#include "Lib/ImGui/imgui.h"
|
||||
|
||||
#ifndef __WIIU__
|
||||
#include "KeyboardController.h"
|
||||
#include "SDLController.h"
|
||||
#include <Utils/StringHelper.h>
|
||||
#else
|
||||
#include "WiiUGamepad.h"
|
||||
#include "WiiUController.h"
|
||||
#endif
|
||||
|
||||
uint8_t* controllerBits;
|
||||
namespace Ship {
|
||||
|
||||
void Ship::ControlDeck::Init(uint8_t* bits) {
|
||||
ScanPhysicalDevices();
|
||||
controllerBits = bits;
|
||||
}
|
||||
void ControlDeck::Init(uint8_t* bits) {
|
||||
ScanPhysicalDevices();
|
||||
controllerBits = bits;
|
||||
}
|
||||
|
||||
void Ship::ControlDeck::ScanPhysicalDevices() {
|
||||
void ControlDeck::ScanPhysicalDevices() {
|
||||
|
||||
virtualDevices.clear();
|
||||
physicalDevices.clear();
|
||||
virtualDevices.clear();
|
||||
physicalDevices.clear();
|
||||
|
||||
for (int i = 0; i < SDL_NumJoysticks(); i++) {
|
||||
if (SDL_IsGameController(i)) {
|
||||
auto sdl = std::make_shared<SDLController>(i);
|
||||
sdl->Open();
|
||||
physicalDevices.push_back(sdl);
|
||||
#ifndef __WIIU__
|
||||
for (int32_t i = 0; i < SDL_NumJoysticks(); i++) {
|
||||
if (SDL_IsGameController(i)) {
|
||||
auto sdl = std::make_shared<SDLController>(i);
|
||||
sdl->Open();
|
||||
physicalDevices.push_back(sdl);
|
||||
}
|
||||
}
|
||||
|
||||
physicalDevices.push_back(std::make_shared<DummyController>("Auto", "Auto", true));
|
||||
physicalDevices.push_back(std::make_shared<KeyboardController>());
|
||||
#else
|
||||
physicalDevices.push_back(std::make_shared<DummyController>("Auto", "Auto", true));
|
||||
|
||||
auto gamepad = std::make_shared<Ship::WiiUGamepad>();
|
||||
gamepad->Open();
|
||||
physicalDevices.push_back(gamepad);
|
||||
|
||||
for (int32_t i = 0; i < 4; i++) {
|
||||
auto controller = std::make_shared<Ship::WiiUController>((WPADChan) i);
|
||||
controller->Open();
|
||||
physicalDevices.push_back(controller);
|
||||
}
|
||||
#endif
|
||||
|
||||
physicalDevices.push_back(std::make_shared<DummyController>("Disconnected", "None", false));
|
||||
|
||||
for (const auto device : physicalDevices) {
|
||||
for (int32_t i = 0; i < MAXCONTROLLERS; i++) {
|
||||
device->CreateDefaultBinding(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < MAXCONTROLLERS; i++) {
|
||||
virtualDevices.push_back(i == 0 ? 0 : static_cast<int>(physicalDevices.size()) - 1);
|
||||
}
|
||||
|
||||
LoadControllerSettings();
|
||||
}
|
||||
|
||||
void ControlDeck::SetPhysicalDevice(int32_t slot, int32_t deviceSlot) {
|
||||
const std::shared_ptr<Controller> backend = physicalDevices[deviceSlot];
|
||||
virtualDevices[slot] = deviceSlot;
|
||||
*controllerBits |= (backend->Connected()) << slot;
|
||||
}
|
||||
|
||||
void ControlDeck::WriteToPad(OSContPad* pad) const {
|
||||
for (size_t i = 0; i < virtualDevices.size(); i++) {
|
||||
const std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
|
||||
|
||||
// If the controller backend is "Auto" we need to get the real device
|
||||
// we search for the real device to read input from it
|
||||
if (backend->GetGuid() == "Auto") {
|
||||
for (const auto& device : physicalDevices) {
|
||||
if(ShouldBlockGameInput(device->GetGuid())) {
|
||||
device->Read(nullptr, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
device->Read(&pad[i], i);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ShouldBlockGameInput(backend->GetGuid())) {
|
||||
backend->Read(nullptr, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
backend->Read(&pad[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
physicalDevices.push_back(std::make_shared<KeyboardController>());
|
||||
physicalDevices.push_back(std::make_shared<DisconnectedController>());
|
||||
#define NESTED(key, ...) StringHelper::Sprintf("Controllers.%s.Slot_%d." key, device->GetGuid().c_str(), virtualSlot, __VA_ARGS__)
|
||||
|
||||
for (const auto& device : physicalDevices) {
|
||||
for (int i = 0; i < MAXCONTROLLERS; i++) {
|
||||
device->CreateDefaultBinding(i);
|
||||
}
|
||||
}
|
||||
void ControlDeck::LoadControllerSettings() {
|
||||
std::shared_ptr<Mercury> Config = Window::GetInstance()->GetConfig();
|
||||
|
||||
for (int i = 0; i < MAXCONTROLLERS; i++) {
|
||||
virtualDevices.push_back(i == 0 ? 0 : static_cast<int>(physicalDevices.size()) - 1);
|
||||
}
|
||||
for (auto const& val : Config->rjson["Controllers"]["Deck"].items()) {
|
||||
int32_t slot = std::stoi(val.key().substr(5));
|
||||
|
||||
LoadControllerSettings();
|
||||
}
|
||||
|
||||
void Ship::ControlDeck::SetPhysicalDevice(int slot, int deviceSlot) {
|
||||
const std::shared_ptr<Controller> backend = physicalDevices[deviceSlot];
|
||||
virtualDevices[slot] = deviceSlot;
|
||||
*controllerBits |= (backend->Connected()) << slot;
|
||||
}
|
||||
|
||||
void Ship::ControlDeck::WriteToPad(OSContPad* pad) const {
|
||||
for (size_t i = 0; i < virtualDevices.size(); i++) {
|
||||
physicalDevices[virtualDevices[i]]->Read(&pad[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
#define NESTED(key, ...) StringHelper::Sprintf("Controllers.%s.Slot_%d." key, device->GetGuid().c_str(), slot, __VA_ARGS__)
|
||||
|
||||
void Ship::ControlDeck::LoadControllerSettings() {
|
||||
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
|
||||
|
||||
for (auto const& val : Config->rjson["Controllers"]["Deck"].items()) {
|
||||
int slot = std::stoi(val.key().substr(5));
|
||||
|
||||
for (size_t dev = 0; dev < physicalDevices.size(); dev++) {
|
||||
std::string guid = physicalDevices[dev]->GetGuid();
|
||||
if(guid != val.value()) continue;
|
||||
|
||||
virtualDevices[slot] = dev;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < virtualDevices.size(); i++) {
|
||||
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
|
||||
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
|
||||
}
|
||||
|
||||
for (const auto& device : physicalDevices) {
|
||||
|
||||
std::string guid = device->GetGuid();
|
||||
|
||||
for (int slot = 0; slot < MAXCONTROLLERS; slot++) {
|
||||
|
||||
if (!(Config->rjson["Controllers"].contains(guid) && Config->rjson["Controllers"][guid].contains(StringHelper::Sprintf("Slot_%d", slot)))) continue;
|
||||
|
||||
auto& profile = device->profiles[slot];
|
||||
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];
|
||||
|
||||
profile.Mappings.clear();
|
||||
profile.Thresholds.clear();
|
||||
profile.UseRumble = Config->getBool(NESTED("Rumble.Enabled", ""));
|
||||
profile.RumbleStrength = Config->getFloat(NESTED("Rumble.Strength", ""));
|
||||
profile.UseGyro = Config->getBool(NESTED("Gyro.Enabled", ""));
|
||||
|
||||
for (auto const& val : rawProfile["Thresholds"].items()) {
|
||||
profile.Thresholds[static_cast<ControllerThresholds>(std::stoi(val.key()))] = val.value();
|
||||
}
|
||||
|
||||
for (auto const& val : rawProfile["Mappings"].items()) {
|
||||
device->SetButtonMapping(slot, std::stoi(val.key().substr(4)), val.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Ship::ControlDeck::SaveControllerSettings() {
|
||||
std::shared_ptr<Mercury> Config = GlobalCtx2::GetInstance()->GetConfig();
|
||||
|
||||
for (size_t i = 0; i < virtualDevices.size(); i++) {
|
||||
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
|
||||
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
|
||||
}
|
||||
|
||||
for (const auto& device : physicalDevices) {
|
||||
|
||||
int slot = 0;
|
||||
std::string guid = device->GetGuid();
|
||||
|
||||
for (const auto& profile : device->profiles) {
|
||||
|
||||
if (!device->Connected()) continue;
|
||||
|
||||
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", slot)];
|
||||
Config->setBool(NESTED("Rumble.Enabled", ""), profile.UseRumble);
|
||||
Config->setFloat(NESTED("Rumble.Strength", ""), profile.RumbleStrength);
|
||||
Config->setBool(NESTED("Gyro.Enabled", ""), profile.UseGyro);
|
||||
|
||||
for (auto const& val : rawProfile["Mappings"].items()) {
|
||||
Config->setInt(NESTED("Mappings.%s", val.key().c_str()), -1);
|
||||
}
|
||||
|
||||
for (auto const& [key, val] : profile.Thresholds) {
|
||||
Config->setFloat(NESTED("Thresholds.%d", key), val);
|
||||
}
|
||||
|
||||
for (auto const& [key, val] : profile.Mappings) {
|
||||
Config->setInt(NESTED("Mappings.BTN_%d", val), key);
|
||||
}
|
||||
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
|
||||
Config->save();
|
||||
for (size_t dev = 0; dev < physicalDevices.size(); dev++) {
|
||||
std::string guid = physicalDevices[dev]->GetGuid();
|
||||
if (guid != val.value()) continue;
|
||||
|
||||
virtualDevices[slot] = dev;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < virtualDevices.size(); i++) {
|
||||
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
|
||||
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
|
||||
}
|
||||
|
||||
for (const auto device : physicalDevices) {
|
||||
|
||||
std::string guid = device->GetGuid();
|
||||
|
||||
for (int32_t virtualSlot = 0; virtualSlot < MAXCONTROLLERS; virtualSlot++) {
|
||||
|
||||
if (!(Config->rjson["Controllers"].contains(guid) && Config->rjson["Controllers"][guid].contains(StringHelper::Sprintf("Slot_%d", virtualSlot)))) continue;
|
||||
|
||||
auto profile = device->getProfile(virtualSlot);
|
||||
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", virtualSlot)];
|
||||
|
||||
profile->Mappings.clear();
|
||||
profile->AxisDeadzones.clear();
|
||||
profile->AxisDeadzones.clear();
|
||||
profile->GyroData.clear();
|
||||
|
||||
profile->Version = Config->getInt(NESTED("Version", ""), DEVICE_PROFILE_VERSION_V0);
|
||||
|
||||
switch (profile->Version) {
|
||||
|
||||
case DEVICE_PROFILE_VERSION_V0:
|
||||
|
||||
// Load up defaults for the things we can't load.
|
||||
device->CreateDefaultBinding(virtualSlot);
|
||||
|
||||
profile->UseRumble = Config->getBool(NESTED("Rumble.Enabled", ""));
|
||||
profile->RumbleStrength = Config->getFloat(NESTED("Rumble.Strength", ""));
|
||||
profile->UseGyro = Config->getBool(NESTED("Gyro.Enabled", ""));
|
||||
|
||||
for (auto const& val : rawProfile["Mappings"].items()) {
|
||||
device->SetButtonMapping(virtualSlot, std::stoi(val.key().substr(4)), val.value());
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DEVICE_PROFILE_VERSION_V1:
|
||||
profile->UseRumble = Config->getBool(NESTED("Rumble.Enabled", ""));
|
||||
profile->RumbleStrength = Config->getFloat(NESTED("Rumble.Strength", ""));
|
||||
profile->UseGyro = Config->getBool(NESTED("Gyro.Enabled", ""));
|
||||
|
||||
for (auto const& val : rawProfile["AxisDeadzones"].items()) {
|
||||
profile->AxisDeadzones[std::stoi(val.key())] = val.value();
|
||||
}
|
||||
|
||||
for (auto const& val : rawProfile["AxisMinimumPress"].items()) {
|
||||
profile->AxisMinimumPress[std::stoi(val.key())] = val.value();
|
||||
}
|
||||
|
||||
for (auto const& val : rawProfile["GyroData"].items()) {
|
||||
profile->GyroData[std::stoi(val.key())] = val.value();
|
||||
}
|
||||
|
||||
for (auto const& val : rawProfile["Mappings"].items()) {
|
||||
device->SetButtonMapping(virtualSlot, std::stoi(val.key().substr(4)), val.value());
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Version is invalid.
|
||||
default:
|
||||
device->CreateDefaultBinding(virtualSlot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControlDeck::SaveControllerSettings() {
|
||||
std::shared_ptr<Mercury> Config = Window::GetInstance()->GetConfig();
|
||||
|
||||
for (size_t i = 0; i < virtualDevices.size(); i++) {
|
||||
std::shared_ptr<Controller> backend = physicalDevices[virtualDevices[i]];
|
||||
Config->setString(StringHelper::Sprintf("Controllers.Deck.Slot_%d", (int)i), backend->GetGuid());
|
||||
}
|
||||
|
||||
for (const auto& device : physicalDevices) {
|
||||
|
||||
int32_t virtualSlot = 0;
|
||||
std::string guid = device->GetGuid();
|
||||
|
||||
for (int32_t virtualSlot = 0; virtualSlot < MAXCONTROLLERS; virtualSlot++) {
|
||||
auto profile = device->getProfile(virtualSlot);
|
||||
|
||||
if (!device->Connected()) continue;
|
||||
|
||||
auto rawProfile = Config->rjson["Controllers"][guid][StringHelper::Sprintf("Slot_%d", virtualSlot)];
|
||||
Config->setInt(NESTED("Version", ""), profile->Version);
|
||||
Config->setBool(NESTED("Rumble.Enabled", ""), profile->UseRumble);
|
||||
Config->setFloat(NESTED("Rumble.Strength", ""), profile->RumbleStrength);
|
||||
Config->setBool(NESTED("Gyro.Enabled", ""), profile->UseGyro);
|
||||
|
||||
for (auto const& val : rawProfile["Mappings"].items()) {
|
||||
Config->setInt(NESTED("Mappings.%s", val.key().c_str()), -1);
|
||||
}
|
||||
|
||||
for (auto const& [key, val] : profile->AxisDeadzones) {
|
||||
Config->setFloat(NESTED("AxisDeadzones.%d", key), val);
|
||||
}
|
||||
|
||||
for (auto const& [key, val] : profile->AxisMinimumPress) {
|
||||
Config->setFloat(NESTED("AxisMinimumPress.%d", key), val);
|
||||
}
|
||||
|
||||
for (auto const& [key, val] : profile->GyroData) {
|
||||
Config->setFloat(NESTED("GyroData.%d", key), val);
|
||||
}
|
||||
|
||||
for (auto const& [key, val] : profile->Mappings) {
|
||||
Config->setInt(NESTED("Mappings.BTN_%d", val), key);
|
||||
}
|
||||
|
||||
virtualSlot++;
|
||||
}
|
||||
}
|
||||
|
||||
Config->save();
|
||||
}
|
||||
|
||||
std::shared_ptr<Controller> ControlDeck::GetPhysicalDevice(int32_t deviceSlot) {
|
||||
return physicalDevices[deviceSlot];
|
||||
}
|
||||
|
||||
size_t ControlDeck::GetNumPhysicalDevices() {
|
||||
return physicalDevices.size();
|
||||
}
|
||||
|
||||
int32_t ControlDeck::GetVirtualDevice(int32_t slot) {
|
||||
return virtualDevices[slot];
|
||||
}
|
||||
|
||||
size_t ControlDeck::GetNumVirtualDevices() {
|
||||
return virtualDevices.size();
|
||||
}
|
||||
|
||||
std::shared_ptr<Controller> ControlDeck::GetPhysicalDeviceFromVirtualSlot(int32_t slot) {
|
||||
return GetPhysicalDevice(GetVirtualDevice(slot));
|
||||
}
|
||||
|
||||
uint8_t* ControlDeck::GetControllerBits() {
|
||||
return controllerBits;
|
||||
}
|
||||
|
||||
void ControlDeck::BlockGameInput() {
|
||||
shouldBlockGameInput = true;
|
||||
}
|
||||
|
||||
void ControlDeck::UnblockGameInput() {
|
||||
shouldBlockGameInput = false;
|
||||
}
|
||||
|
||||
bool ControlDeck::ShouldBlockGameInput(std::string inputDeviceGuid) const {
|
||||
// We block controller input if F1 menu is open and control navigation is on.
|
||||
// This is because we don't want controller inputs to affect the game
|
||||
bool shouldBlockControllerInput = CVar_GetS32("gOpenMenuBar", 0) && CVar_GetS32("gControlNav", 0);
|
||||
|
||||
// We block keyboard input if you're currently typing into a textfield.
|
||||
// This is because we don't want your keyboard typing to affect the game.
|
||||
ImGuiIO io = ImGui::GetIO();
|
||||
bool shouldBlockKeyboardInput = io.WantCaptureKeyboard;
|
||||
|
||||
bool inputDeviceIsKeyboard = inputDeviceGuid == "Keyboard";
|
||||
return shouldBlockGameInput || (inputDeviceIsKeyboard ? shouldBlockKeyboardInput : shouldBlockControllerInput);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,31 @@
|
||||
|
||||
#include "Controller.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "Lib/Mercury/Mercury.h"
|
||||
|
||||
namespace Ship {
|
||||
|
||||
class ControlDeck {
|
||||
public:
|
||||
std::vector<int> virtualDevices;
|
||||
std::vector<std::shared_ptr<Controller>> physicalDevices = {};
|
||||
void Init(uint8_t* controllerBits);
|
||||
void ScanPhysicalDevices();
|
||||
void WriteToPad(OSContPad* pad) const;
|
||||
void LoadControllerSettings();
|
||||
void SaveControllerSettings();
|
||||
void SetPhysicalDevice(int slot, int deviceSlot);
|
||||
void SetPhysicalDevice(int32_t slot, int32_t deviceSlot);
|
||||
std::shared_ptr<Controller> GetPhysicalDevice(int32_t deviceSlot);
|
||||
std::shared_ptr<Controller> GetPhysicalDeviceFromVirtualSlot(int32_t slot);
|
||||
size_t GetNumPhysicalDevices();
|
||||
int32_t GetVirtualDevice(int32_t slot);
|
||||
size_t GetNumVirtualDevices();
|
||||
uint8_t* GetControllerBits();
|
||||
void BlockGameInput();
|
||||
void UnblockGameInput();
|
||||
bool ShouldBlockGameInput(std::string inputDeviceGuid) const;
|
||||
private:
|
||||
std::vector<int32_t> virtualDevices = {};
|
||||
std::vector<std::shared_ptr<Controller>> physicalDevices = {};
|
||||
uint8_t* controllerBits = nullptr;
|
||||
bool shouldBlockGameInput = false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "Controller.h"
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include "Cvar.h"
|
||||
#if __APPLE__
|
||||
#include <SDL_events.h>
|
||||
#else
|
||||
@@ -9,72 +10,137 @@
|
||||
|
||||
namespace Ship {
|
||||
|
||||
Controller::Controller() : isRumbling(false), wStickX(0), wStickY(0), wGyroX(0), wGyroY(0), dwPressedButtons(0){
|
||||
Controller::Controller() : isRumbling(false) {
|
||||
Attachment = nullptr;
|
||||
profiles.resize(MAXCONTROLLERS);
|
||||
for(int slot = 0; slot < MAXCONTROLLERS; slot++) {
|
||||
dwPressedButtons.push_back(0);
|
||||
|
||||
for(int32_t virtualSlot = 0; virtualSlot < MAXCONTROLLERS; virtualSlot++) {
|
||||
profiles[virtualSlot] = std::make_shared<DeviceProfile>();
|
||||
ButtonData[virtualSlot] = std::make_shared<Buttons>();
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::Read(OSContPad* pad, int32_t slot) {
|
||||
ReadFromSource(slot);
|
||||
void Controller::Read(OSContPad* pad, int32_t virtualSlot) {
|
||||
ReadFromSource(virtualSlot);
|
||||
|
||||
OSContPad padToBuffer = { 0 };
|
||||
|
||||
#ifndef __WIIU__
|
||||
SDL_PumpEvents();
|
||||
#endif
|
||||
|
||||
// Button Inputs
|
||||
pad->button |= dwPressedButtons[slot] & 0xFFFF;
|
||||
padToBuffer.button |= getPressedButtons(virtualSlot) & 0xFFFF;
|
||||
|
||||
// Stick Inputs
|
||||
if (wStickX == 0) {
|
||||
if (dwPressedButtons[slot] & BTN_STICKLEFT) {
|
||||
pad->stick_x = -128;
|
||||
} else if (dwPressedButtons[slot] & BTN_STICKRIGHT) {
|
||||
pad->stick_x = 127;
|
||||
if (getLeftStickX(virtualSlot) == 0) {
|
||||
if (getPressedButtons(virtualSlot) & BTN_STICKLEFT) {
|
||||
padToBuffer.stick_x = -128;
|
||||
} else if (getPressedButtons(virtualSlot) & BTN_STICKRIGHT) {
|
||||
padToBuffer.stick_x = 127;
|
||||
}
|
||||
} else {
|
||||
pad->stick_x = wStickX;
|
||||
padToBuffer.stick_x = getLeftStickX(virtualSlot);
|
||||
}
|
||||
|
||||
if (wStickY == 0) {
|
||||
if (dwPressedButtons[slot] & BTN_STICKDOWN) {
|
||||
pad->stick_y = -128;
|
||||
} else if (dwPressedButtons[slot] & BTN_STICKUP) {
|
||||
pad->stick_y = 127;
|
||||
if (getLeftStickY(virtualSlot) == 0) {
|
||||
if (getPressedButtons(virtualSlot) & BTN_STICKDOWN) {
|
||||
padToBuffer.stick_y = -128;
|
||||
} else if (getPressedButtons(virtualSlot) & BTN_STICKUP) {
|
||||
padToBuffer.stick_y = 127;
|
||||
}
|
||||
} else {
|
||||
pad->stick_y = wStickY;
|
||||
padToBuffer.stick_y = getLeftStickY(virtualSlot);
|
||||
}
|
||||
|
||||
// Stick Inputs
|
||||
if (wCamX == 0) {
|
||||
if (dwPressedButtons[slot] & BTN_VSTICKLEFT) {
|
||||
pad->cam_x = -128 * 10.0f;
|
||||
} else if (dwPressedButtons[slot] & BTN_VSTICKRIGHT) {
|
||||
pad->cam_x = 127 * 10.0f;
|
||||
if (getRightStickX(virtualSlot) == 0) {
|
||||
if (getPressedButtons(virtualSlot) & BTN_VSTICKLEFT) {
|
||||
padToBuffer.right_stick_x = -128;
|
||||
} else if (getPressedButtons(virtualSlot) & BTN_VSTICKRIGHT) {
|
||||
padToBuffer.right_stick_x = 127;
|
||||
}
|
||||
} else {
|
||||
pad->cam_x = wCamX;
|
||||
padToBuffer.right_stick_x = getRightStickX(virtualSlot);
|
||||
}
|
||||
|
||||
if (wCamY == 0) {
|
||||
if (dwPressedButtons[slot] & BTN_VSTICKDOWN) {
|
||||
pad->cam_y = -128 * 10.0f;
|
||||
} else if (dwPressedButtons[slot] & BTN_VSTICKUP) {
|
||||
pad->cam_y = 127 * 10.0f;
|
||||
if (getRightStickY(virtualSlot) == 0) {
|
||||
if (getPressedButtons(virtualSlot) & BTN_VSTICKDOWN) {
|
||||
padToBuffer.right_stick_y = -128;
|
||||
} else if (getPressedButtons(virtualSlot) & BTN_VSTICKUP) {
|
||||
padToBuffer.right_stick_y = 127;
|
||||
}
|
||||
} else {
|
||||
pad->cam_y = wCamY;
|
||||
padToBuffer.right_stick_y = getRightStickY(virtualSlot);
|
||||
}
|
||||
|
||||
// Gyro
|
||||
pad->gyro_x = wGyroX;
|
||||
pad->gyro_y = wGyroY;
|
||||
padToBuffer.gyro_x = getGyroX(virtualSlot);
|
||||
padToBuffer.gyro_y = getGyroY(virtualSlot);
|
||||
|
||||
padBuffer.push_front(padToBuffer);
|
||||
if (pad != nullptr) {
|
||||
auto &padFromBuffer = padBuffer[std::min(padBuffer.size() - 1, (size_t)CVar_GetS32("gSimulatedInputLag", 0))];
|
||||
pad->button |= padFromBuffer.button;
|
||||
if (pad->stick_x == 0) pad->stick_x = padFromBuffer.stick_x;
|
||||
if (pad->stick_y == 0) pad->stick_y = padFromBuffer.stick_y;
|
||||
if (pad->gyro_x == 0) pad->gyro_x = padFromBuffer.gyro_x;
|
||||
if (pad->gyro_y == 0) pad->gyro_y = padFromBuffer.gyro_y;
|
||||
if (pad->right_stick_x == 0) pad->right_stick_x = padFromBuffer.right_stick_x;
|
||||
if (pad->right_stick_y == 0) pad->right_stick_y = padFromBuffer.right_stick_y;
|
||||
}
|
||||
|
||||
while (padBuffer.size() > 6) {
|
||||
padBuffer.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::SetButtonMapping(int slot, int32_t n64Button, int32_t dwScancode) {
|
||||
std::map<int32_t, int32_t>& Mappings = profiles[slot].Mappings;
|
||||
void Controller::SetButtonMapping(int32_t virtualSlot, int32_t n64Button, int32_t dwScancode) {
|
||||
std::map<int32_t, int32_t>& Mappings = getProfile(virtualSlot)->Mappings;
|
||||
std::erase_if(Mappings, [n64Button](const std::pair<int32_t, int32_t>& bin) { return bin.second == n64Button; });
|
||||
Mappings[dwScancode] = n64Button;
|
||||
}
|
||||
|
||||
int8_t& Controller::getLeftStickX(int32_t virtualSlot) {
|
||||
return ButtonData[virtualSlot]->leftStickX;
|
||||
}
|
||||
|
||||
int8_t& Controller::getLeftStickY(int32_t virtualSlot) {
|
||||
return ButtonData[virtualSlot]->leftStickY;
|
||||
}
|
||||
|
||||
int8_t& Controller::getRightStickX(int32_t virtualSlot) {
|
||||
return ButtonData[virtualSlot]->rightStickX;
|
||||
}
|
||||
|
||||
int8_t& Controller::getRightStickY(int32_t virtualSlot) {
|
||||
return ButtonData[virtualSlot]->rightStickY;
|
||||
}
|
||||
|
||||
int32_t& Controller::getPressedButtons(int32_t virtualSlot) {
|
||||
return ButtonData[virtualSlot]->pressedButtons;
|
||||
}
|
||||
|
||||
float& Controller::getGyroX(int32_t virtualSlot) {
|
||||
return ButtonData[virtualSlot]->gyroX;
|
||||
}
|
||||
|
||||
float& Controller::getGyroY(int32_t virtualSlot) {
|
||||
return ButtonData[virtualSlot]->gyroY;
|
||||
}
|
||||
|
||||
std::shared_ptr<DeviceProfile> Controller::getProfile(int32_t virtualSlot) {
|
||||
return profiles[virtualSlot];
|
||||
}
|
||||
|
||||
std::shared_ptr<ControllerAttachment> Controller::GetAttachment() {
|
||||
return Attachment;
|
||||
}
|
||||
|
||||
bool Controller::IsRumbling() {
|
||||
return isRumbling;
|
||||
}
|
||||
|
||||
std::string Controller::GetGuid() {
|
||||
return GUID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,79 +3,88 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "stdint.h"
|
||||
#include <cstdint>
|
||||
#include <queue>
|
||||
#include "UltraController.h"
|
||||
#include "ControllerAttachment.h"
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#define EXTENDED_SCANCODE_BIT (1 << 8)
|
||||
#define AXIS_SCANCODE_BIT (1 << 9)
|
||||
|
||||
namespace Ship {
|
||||
|
||||
enum ControllerThresholds {
|
||||
LEFT_STICK = 1,
|
||||
RIGHT_STICK = 2,
|
||||
LEFT_TRIGGER = 3,
|
||||
RIGHT_TRIGGER = 4,
|
||||
DRIFT_X = 5,
|
||||
DRIFT_Y = 6,
|
||||
SENSITIVITY = 7,
|
||||
GYRO_SENSITIVITY = 8
|
||||
enum GyroData {
|
||||
DRIFT_X,
|
||||
DRIFT_Y,
|
||||
GYRO_SENSITIVITY
|
||||
};
|
||||
|
||||
enum DeviceProfileVersion {
|
||||
DEVICE_PROFILE_VERSION_V0 = 0,
|
||||
DEVICE_PROFILE_VERSION_V1 = 1
|
||||
};
|
||||
|
||||
#define DEVICE_PROFILE_CURRENT_VERSION DEVICE_PROFILE_VERSION_V1
|
||||
|
||||
struct DeviceProfile {
|
||||
int32_t Version = 0;
|
||||
bool UseRumble = false;
|
||||
bool UseGyro = false;
|
||||
float RumbleStrength = 1.0f;
|
||||
std::unordered_map<ControllerThresholds, float> Thresholds;
|
||||
std::unordered_map<int32_t, float> AxisDeadzones;
|
||||
std::unordered_map<int32_t, float> AxisMinimumPress;
|
||||
std::unordered_map<int32_t, float> GyroData;
|
||||
std::map<int32_t, int32_t> Mappings;
|
||||
};
|
||||
|
||||
class Controller {
|
||||
public:
|
||||
virtual ~Controller() = default;
|
||||
Controller();
|
||||
void Read(OSContPad* pad, int32_t slot);
|
||||
virtual void ReadFromSource(int32_t slot) = 0;
|
||||
virtual void WriteToSource(int32_t slot, ControllerCallback* controller) = 0;
|
||||
virtual bool Connected() const = 0;
|
||||
virtual bool CanRumble() const = 0;
|
||||
virtual bool CanGyro() const = 0;
|
||||
virtual void CreateDefaultBinding(int32_t slot) = 0;
|
||||
bool isRumbling;
|
||||
std::vector<DeviceProfile> profiles;
|
||||
|
||||
virtual void ClearRawPress() = 0;
|
||||
virtual int32_t ReadRawPress() = 0;
|
||||
void SetButtonMapping(int slot, int32_t n64Button, int32_t dwScancode);
|
||||
std::shared_ptr<ControllerAttachment> GetAttachment() { return Attachment; }
|
||||
|
||||
std::string GetGuid() { return GUID; }
|
||||
virtual const char* GetButtonName(int slot, int n64Button) = 0;
|
||||
virtual const char* GetControllerName() = 0;
|
||||
|
||||
int8_t wStickX;
|
||||
int8_t wStickY;
|
||||
float wGyroX;
|
||||
float wGyroY;
|
||||
float wCamX;
|
||||
float wCamY;
|
||||
public:
|
||||
virtual ~Controller() = default;
|
||||
Controller();
|
||||
virtual void ReadFromSource(int32_t virtualSlot) = 0;
|
||||
virtual void WriteToSource(int32_t virtualSlot, ControllerCallback* controller) = 0;
|
||||
virtual bool Connected() const = 0;
|
||||
virtual bool CanRumble() const = 0;
|
||||
virtual bool CanGyro() const = 0;
|
||||
virtual void CreateDefaultBinding(int32_t virtualSlot) = 0;
|
||||
virtual void ClearRawPress() = 0;
|
||||
virtual int32_t ReadRawPress() = 0;
|
||||
virtual const std::string GetButtonName(int32_t virtualSlot, int32_t n64Button) = 0;
|
||||
virtual const std::string GetControllerName() = 0;
|
||||
void Read(OSContPad* pad, int32_t virtualSlot);
|
||||
void SetButtonMapping(int32_t virtualSlot, int32_t n64Button, int32_t dwScancode);
|
||||
std::shared_ptr<ControllerAttachment> GetAttachment();
|
||||
std::shared_ptr<DeviceProfile> getProfile(int32_t virtualSlot);
|
||||
int8_t& getLeftStickX(int32_t virtualSlot);
|
||||
int8_t& getLeftStickY(int32_t virtualSlot);
|
||||
int8_t& getRightStickX(int32_t virtualSlot);
|
||||
int8_t& getRightStickY(int32_t virtualSlot);
|
||||
int32_t& getPressedButtons(int32_t virtualSlot);
|
||||
float& getGyroX(int32_t virtualSlot);
|
||||
float& getGyroY(int32_t virtualSlot);
|
||||
bool IsRumbling();
|
||||
std::string GetGuid();
|
||||
|
||||
protected:
|
||||
std::vector<int32_t> dwPressedButtons;
|
||||
std::shared_ptr<ControllerAttachment> Attachment;
|
||||
std::string GUID;
|
||||
|
||||
bool isRumbling;
|
||||
|
||||
void LoadBinding();
|
||||
|
||||
private:
|
||||
std::shared_ptr<ControllerAttachment> Attachment;
|
||||
};
|
||||
struct Buttons {
|
||||
int32_t pressedButtons = 0;
|
||||
int8_t leftStickX = 0;
|
||||
int8_t leftStickY = 0;
|
||||
int8_t rightStickX = 0;
|
||||
int8_t rightStickY = 0;
|
||||
float gyroX = 0.0f;
|
||||
float gyroY = 0.0f;
|
||||
};
|
||||
|
||||
struct ControllerEntry {
|
||||
uint8_t* controllerBits;
|
||||
Controller* entryIO;
|
||||
std::unordered_map<int32_t, std::shared_ptr<DeviceProfile>> profiles;
|
||||
std::unordered_map<int32_t, std::shared_ptr<Buttons>> ButtonData = {};
|
||||
std::deque<OSContPad> padBuffer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,472 @@
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "CrashHandler.h"
|
||||
#include "Window.h"
|
||||
#include "ResourceMgr.h"
|
||||
#include "GameVersions.h"
|
||||
#include "Cvar.h"
|
||||
|
||||
#define WRITE_VAR_LINE(buff, len, varName, varValue) \
|
||||
append_str(buff, len, varName); \
|
||||
append_line(buff, len, varValue);
|
||||
#define WRITE_VAR(buff, len, varName, varValue) \
|
||||
append_str(buff, len, varName); \
|
||||
append_str(buff, len, varValue);
|
||||
|
||||
extern "C" void DeinitOTR(void);
|
||||
|
||||
static CrashHandlerCallback sCallbackFunc = nullptr;
|
||||
|
||||
static const char* GetGameVersionString() {
|
||||
if(Ship::Window::GetInstance()->GetResourceManager()->IsRunning()) {
|
||||
uint32_t version = Ship::Window::GetInstance()->GetResourceManager()->GetGameVersion();
|
||||
switch (version) {
|
||||
case OOT_NTSC_10:
|
||||
return "NTSC 1.0";
|
||||
case OOT_NTSC_11:
|
||||
return "NTSC 1.1";
|
||||
case OOT_NTSC_12:
|
||||
return "NTSC 1.2";
|
||||
case OOT_PAL_10:
|
||||
return "PAL 1.0";
|
||||
case OOT_PAL_11:
|
||||
return "PAL 1.1";
|
||||
case OOT_NTSC_JP_GC_CE:
|
||||
return "NTSC JP_GC_CE";
|
||||
case OOT_NTSC_JP_GC:
|
||||
return "NTSC_JP_GC";
|
||||
case OOT_NTSC_US_GC:
|
||||
return "NTSC_US_GC";
|
||||
case OOT_PAL_GC:
|
||||
return "PAL_GC";
|
||||
case OOT_NTSC_JP_MQ:
|
||||
return "NTSC_JP_MQ";
|
||||
case OOT_NTSC_US_MQ:
|
||||
return "NTSC_US_MQ";
|
||||
case OOT_PAL_MQ:
|
||||
return "PAL_MQ";
|
||||
case OOT_PAL_GC_DBG1:
|
||||
return "DBG_1";
|
||||
case OOT_PAL_GC_DBG2:
|
||||
return "DBG_2";
|
||||
case OOT_PAL_GC_MQ_DBG:
|
||||
return "MQ_DBG";
|
||||
case OOT_IQUE_TW:
|
||||
return "IQUE_TW";
|
||||
case OOT_IQUE_CN:
|
||||
return "IQUE_CN";
|
||||
case OOT_UNKNOWN:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
}
|
||||
return "ResourceMGR not ready";
|
||||
}
|
||||
|
||||
|
||||
static void append_str(char* buf, size_t* len, const char* str) {
|
||||
while (*str != '\0')
|
||||
buf[(*len)++] = *str++;
|
||||
}
|
||||
|
||||
static void append_line(char* buf, size_t* len, const char* str) {
|
||||
while (*str != '\0')
|
||||
buf[(*len)++] = *str++;
|
||||
buf[(*len)++] = '\n';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Prints common data relevant to the crash
|
||||
*
|
||||
* @param buffer
|
||||
*/
|
||||
static void CrashHandler_PrintCommon(char* buffer, size_t* curBufferPos) {
|
||||
WRITE_VAR_LINE(buffer, curBufferPos, "OTR Generated with: ", GetGameVersionString());
|
||||
if (sCallbackFunc != nullptr) {
|
||||
sCallbackFunc(buffer, curBufferPos);
|
||||
}
|
||||
|
||||
|
||||
SPDLOG_CRITICAL(buffer);
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
#include <cxxabi.h> // for __cxa_demangle
|
||||
#include <dlfcn.h> // for dladdr
|
||||
#include <execinfo.h>
|
||||
#include <unistd.h>
|
||||
#include <SDL.h>
|
||||
|
||||
|
||||
static void PrintRegisters(ucontext_t* ctx, char* buffer, size_t* pos) {
|
||||
char regbuffer[128];
|
||||
append_line(buffer, pos, "Registers:");
|
||||
#if defined(__x86_64__)
|
||||
snprintf(regbuffer, std::size(regbuffer), "RAX: 0x%016llX", ctx->uc_mcontext.gregs[REG_RAX]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "RDI: 0x%016llX", ctx->uc_mcontext.gregs[REG_RDI]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "RSI: 0x%016llX", ctx->uc_mcontext.gregs[REG_RSI]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "RDX: 0x%016llX", ctx->uc_mcontext.gregs[REG_RDX]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "RCX: 0x%016llX", ctx->uc_mcontext.gregs[REG_RCX]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "R8: 0x%016llX", ctx->uc_mcontext.gregs[REG_R8]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "R9: 0x%016llX", ctx->uc_mcontext.gregs[REG_R9]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "R10: 0x%016llX", ctx->uc_mcontext.gregs[REG_R10]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "R11: 0x%016llX", ctx->uc_mcontext.gregs[REG_R11]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "RSP: 0x%016llX", ctx->uc_mcontext.gregs[REG_RSP]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "RBX: 0x%016llX", ctx->uc_mcontext.gregs[REG_RBX]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "RBP: 0x%016llX", ctx->uc_mcontext.gregs[REG_RBP]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "R12: 0x%016llX", ctx->uc_mcontext.gregs[REG_R12]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "R13: 0x%016llX", ctx->uc_mcontext.gregs[REG_R13]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "R14: 0x%016llX", ctx->uc_mcontext.gregs[REG_R14]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "R15: 0x%016llX", ctx->uc_mcontext.gregs[REG_R15]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "RIP: 0x%016llX", ctx->uc_mcontext.gregs[REG_RIP]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer), "EFL: 0x%016llX", ctx->uc_mcontext.gregs[REG_EFL]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
#else
|
||||
snprintf(regbuffer, std::size(regbuffer),"EDI: 0x%08lX", ctx->uc_mcontext.gregs[REG_EDI]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer),"ESI: 0x%08lX", ctx->uc_mcontext.gregs[REG_ESI]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer),"EBP: 0x%08lX", ctx->uc_mcontext.gregs[REG_EBP]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer),"ESP: 0x%08lX", ctx->uc_mcontext.gregs[REG_ESP]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer),"EBX: 0x%08lX", ctx->uc_mcontext.gregs[REG_EBX]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer),"EDX: 0x%08lX", ctx->uc_mcontext.gregs[REG_EDX]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer),"ECX: 0x%08lX", ctx->uc_mcontext.gregs[REG_ECX]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer),"EAX: 0x%08lX", ctx->uc_mcontext.gregs[REG_EAX]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer),"EIP: 0x%08lX", ctx->uc_mcontext.gregs[REG_EIP]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
snprintf(regbuffer, std::size(regbuffer),"EFL: 0x%08lX", ctx->uc_mcontext.gregs[REG_EFL]);
|
||||
append_line(buffer, pos, regbuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ErrorHandler(int sig, siginfo_t* sigInfo, void* data) {
|
||||
constexpr size_t MAX_BUFF_SIZE = 32768;
|
||||
size_t curBufferPos = 0;
|
||||
char buffer[MAX_BUFF_SIZE];
|
||||
char intToCharBuffer[16];
|
||||
|
||||
std::array<void*, 4096> arr;
|
||||
ucontext_t* ctx = static_cast<ucontext_t*>(data);
|
||||
constexpr size_t nMaxFrames = arr.size();
|
||||
size_t size = backtrace(arr.data(), nMaxFrames);
|
||||
char** symbols = backtrace_symbols(arr.data(), nMaxFrames);
|
||||
|
||||
snprintf(intToCharBuffer, sizeof(intToCharBuffer), "Signal: %i", sig);
|
||||
append_line(buffer, &curBufferPos, intToCharBuffer);
|
||||
|
||||
switch (sig) {
|
||||
case SIGILL:
|
||||
append_line(buffer, &curBufferPos, "ILLEGAL INSTRUCTION");
|
||||
break;
|
||||
case SIGABRT:
|
||||
append_line(buffer, &curBufferPos, "ABORT");
|
||||
break;
|
||||
case SIGFPE:
|
||||
append_line(buffer, &curBufferPos, "ERRONEUS ARITHEMETIC OPERATION");
|
||||
break;
|
||||
case SIGSEGV:
|
||||
append_line(buffer, &curBufferPos, "INVALID ACCESS TO STORAGE");
|
||||
break;
|
||||
}
|
||||
|
||||
PrintRegisters(ctx, buffer, &curBufferPos);
|
||||
|
||||
append_line(buffer, &curBufferPos, "Traceback:");
|
||||
for (size_t i = 1; i < size; i++) {
|
||||
Dl_info info;
|
||||
int gotAddress = dladdr(arr[i], &info);
|
||||
std::string functionName(symbols[i]);
|
||||
|
||||
if (gotAddress != 0 && info.dli_sname != nullptr) {
|
||||
FILE* pipe;
|
||||
int32_t status;
|
||||
char* demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status);
|
||||
const char* nameFound = info.dli_sname;
|
||||
|
||||
if (status == 0) {
|
||||
nameFound = demangled;
|
||||
}
|
||||
#if 0
|
||||
char command[256];
|
||||
char addrLine[128];
|
||||
snprintf(command, sizeof(command), "addr2line -e soh.elf %s + 0x%lX", nameFound, (uintptr_t)arr[i] - (uintptr_t)info.dli_saddr);
|
||||
pipe = popen(command, "r");
|
||||
fgets(addrLine, 128, pipe);
|
||||
#endif
|
||||
|
||||
functionName = StringHelper::Sprintf("%s (+0x%X)", nameFound,
|
||||
(char*)arr[i] - (char*)info.dli_saddr);
|
||||
free(demangled);
|
||||
}
|
||||
snprintf(intToCharBuffer, sizeof(intToCharBuffer), "%i ", (int)i);
|
||||
WRITE_VAR_LINE(buffer, &curBufferPos, intToCharBuffer, functionName.c_str());
|
||||
}
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "SoH has crashed", "SoH Has crashed. Please upload the logs to the support channel in discord.", nullptr);
|
||||
free(symbols);
|
||||
CrashHandler_PrintCommon(buffer, &curBufferPos);
|
||||
|
||||
DeinitOTR();
|
||||
Ship::Window::GetInstance()->GetLogger()->flush();
|
||||
spdlog::shutdown();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void ShutdownHandler(int sig, siginfo_t* sigInfo, void* data) {
|
||||
DeinitOTR();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#elif _WIN32
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
#define WINDOWS_32_BIT
|
||||
#endif
|
||||
|
||||
static void PrintRegisters(CONTEXT* ctx, char* buffer, size_t* pos) {
|
||||
append_line(buffer, pos, "Registers: ");
|
||||
char regBuff[25];
|
||||
#if defined(_M_AMD64)
|
||||
sprintf_s(regBuff, std::size(regBuff), "RAX: 0x%016llX", ctx->Rax);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "RCX: 0x%016llX", ctx->Rcx);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "RDX: 0x%016llX", ctx->Rdx);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "RBX: 0x%016llX", ctx->Rbx);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "RSP: 0x%016llX", ctx->Rsp);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "RBP: 0x%016llX", ctx->Rbp);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "RSI: 0x%016llX", ctx->Rsi);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "RDI: 0x%016llX", ctx->Rdi);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "R9: 0x%016llX", ctx->R9);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "R10: 0x%016llX", ctx->R10);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "R11: 0x%016llX", ctx->R11);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "R12: 0x%016llX", ctx->R12);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "R13: 0x%016llX", ctx->R13);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "R14: 0x%016llX", ctx->R14);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "R15: 0x%016llX", ctx->R15);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "RIP: 0x%016llX", ctx->Rip);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "EFLAGS: 0x%08lX", ctx->EFlags);
|
||||
append_line(buffer, pos, regBuff);
|
||||
#elif WINDOWS_32_BIT
|
||||
sprintf_s(regBuff, std::size(regBuff), "EDI: 0x%08lX", ctx->Edi);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "ESI: 0x%08lX", ctx->Esi);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "EBX: 0x%08lX", ctx->Ebx);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "ECX: 0x%08lX", ctx->Ecx);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "EAX: 0x%08lX", ctx->Eax);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "EBP: 0x%08lX", ctx->Ebp);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "ESP: 0x%08lX", ctx->Esp);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "EFLAGS: 0x%08lX", ctx->EFlags);
|
||||
append_line(buffer, pos, regBuff);
|
||||
|
||||
sprintf_s(regBuff, std::size(regBuff), "EIP: 0x%08lX", ctx->Eip);
|
||||
append_line(buffer, pos, regBuff);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printStack(CONTEXT* ctx, char* logBuffer, size_t* pos) {
|
||||
BOOL result;
|
||||
HANDLE process;
|
||||
HANDLE thread;
|
||||
HMODULE hModule;
|
||||
ULONG frame;
|
||||
DWORD64 displacement;
|
||||
DWORD disp;
|
||||
|
||||
#if defined(_M_AMD64)
|
||||
STACKFRAME64 stack;
|
||||
memset(&stack, 0, sizeof(STACKFRAME64));
|
||||
#elif WINDOWS_32_BIT
|
||||
STACKFRAME stack;
|
||||
memset(&stack, 0, sizeof(STACKFRAME));
|
||||
stack.AddrPC.Offset = (*ctx).Eip;
|
||||
stack.AddrPC.Mode = AddrModeFlat;
|
||||
stack.AddrStack.Offset = (*ctx).Esp;
|
||||
stack.AddrStack.Mode = AddrModeFlat;
|
||||
stack.AddrFrame.Offset = (*ctx).Ebp;
|
||||
stack.AddrFrame.Mode = AddrModeFlat;
|
||||
#endif
|
||||
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME + sizeof(TCHAR)];
|
||||
char module[512];
|
||||
|
||||
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
|
||||
|
||||
CONTEXT ctx2;
|
||||
memcpy(&ctx2, ctx, sizeof(CONTEXT));
|
||||
|
||||
PrintRegisters(&ctx2, logBuffer, pos);
|
||||
|
||||
process = GetCurrentProcess();
|
||||
thread = GetCurrentThread();
|
||||
|
||||
SymSetOptions(SYMOPT_NO_IMAGE_SEARCH | SYMOPT_IGNORE_IMAGEDIR);
|
||||
SymInitialize(process, "debug", true);
|
||||
|
||||
|
||||
constexpr DWORD machineType =
|
||||
#if defined(_M_AMD64)
|
||||
IMAGE_FILE_MACHINE_AMD64;
|
||||
#elif WINDOWS_32_BIT
|
||||
IMAGE_FILE_MACHINE_I386;
|
||||
#endif
|
||||
|
||||
displacement = 0;
|
||||
for (frame = 0;; frame++) {
|
||||
result = StackWalk(machineType, process, thread, &stack, &ctx2, nullptr, SymFunctionTableAccess,
|
||||
SymGetModuleBase, nullptr);
|
||||
if (!result) {
|
||||
break;
|
||||
}
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
symbol->MaxNameLen = MAX_SYM_NAME;
|
||||
SymFromAddr(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol);
|
||||
#if defined(_M_AMD64)
|
||||
IMAGEHLP_LINE64 line;
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
#elif WINDOWS_32_BIT
|
||||
IMAGEHLP_LINE line;
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE);
|
||||
#endif
|
||||
if (SymGetLineFromAddr(process, stack.AddrPC.Offset, &disp, &line)) {
|
||||
char lineNumberStr[16];
|
||||
sprintf_s(lineNumberStr, sizeof(lineNumberStr), "Line: %d", line.LineNumber);
|
||||
append_str(logBuffer, pos, symbol->Name); append_str(logBuffer, pos, " in "); append_str(logBuffer, pos, line.FileName); append_line(logBuffer, pos, lineNumberStr);
|
||||
//SPDLOG_CRITICAL("{} in {}: line: {}: ", symbol->Name, line.FileName, line.LineNumber);
|
||||
}
|
||||
else {
|
||||
char addrString[20];
|
||||
sprintf_s(addrString, std::size(addrString), "0x%016llX", symbol->Address);
|
||||
WRITE_VAR(logBuffer, pos, "At ", symbol->Name); WRITE_VAR_LINE(logBuffer, pos, "Addr: ", addrString);
|
||||
//SPDLOG_CRITICAL("at {}, addr 0x{}", symbol->Name, addrString);
|
||||
hModule = nullptr;
|
||||
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
(LPCTSTR)(stack.AddrPC.Offset), &hModule);
|
||||
|
||||
if (hModule != nullptr) {
|
||||
GetModuleFileNameA(hModule, module, sizeof(module));
|
||||
}
|
||||
WRITE_VAR_LINE(logBuffer, pos, "In: ", module);
|
||||
// SPDLOG_CRITICAL("In {}", module);
|
||||
}
|
||||
}
|
||||
CrashHandler_PrintCommon(logBuffer, pos);
|
||||
Ship::Window::GetInstance()->GetLogger()->flush();
|
||||
spdlog::shutdown();
|
||||
DeinitOTR();
|
||||
}
|
||||
|
||||
extern "C" LONG seh_filter(struct _EXCEPTION_POINTERS* ex) {
|
||||
char exceptionString[20];
|
||||
constexpr size_t MAX_BUFF_SIZE = 32768;
|
||||
size_t curBufferPos = 0;
|
||||
char buffer[MAX_BUFF_SIZE];
|
||||
|
||||
|
||||
snprintf(exceptionString, std::size(exceptionString), "0x%x", ex->ExceptionRecord->ExceptionCode);
|
||||
|
||||
WRITE_VAR_LINE(buffer, &curBufferPos, "Exception: ", exceptionString);
|
||||
printStack(ex->ContextRecord, buffer, &curBufferPos);
|
||||
MessageBoxA(nullptr, "SoH Has crashed. Please upload the logs to the support channel in discord.", "Crash", MB_OK | MB_ICONERROR);
|
||||
CrashHandler_PrintCommon(buffer, &curBufferPos);
|
||||
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern "C" void CrashHandler_Init(CrashHandlerCallback callback) {
|
||||
#if defined(__linux__)
|
||||
struct sigaction action;
|
||||
struct sigaction shutdownAction;
|
||||
|
||||
action.sa_flags = SA_SIGINFO;
|
||||
action.sa_sigaction = ErrorHandler;
|
||||
|
||||
sigaction(SIGILL, &action, nullptr);
|
||||
sigaction(SIGABRT, &action, nullptr);
|
||||
sigaction(SIGFPE, &action, nullptr);
|
||||
sigaction(SIGSEGV, &action, nullptr);
|
||||
|
||||
shutdownAction.sa_flags = SA_SIGINFO;
|
||||
shutdownAction.sa_sigaction = ShutdownHandler;
|
||||
sigaction(SIGINT, &shutdownAction, nullptr);
|
||||
sigaction(SIGTERM, &shutdownAction, nullptr);
|
||||
sigaction(SIGQUIT, &shutdownAction, nullptr);
|
||||
sigaction(SIGKILL, &shutdownAction, nullptr);
|
||||
#elif _WIN32
|
||||
SetUnhandledExceptionFilter(seh_filter);
|
||||
#endif
|
||||
|
||||
sCallbackFunc = callback;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef CRASH_HANDLER_H
|
||||
#define CRASH_HANDLER_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef void(*CrashHandlerCallback)(char*, size_t*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void CrashHandler_Init(CrashHandlerCallback callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <excpt.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
LONG seh_filter(struct _EXCEPTION_POINTERS* ex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma comment(lib, "Dbghelp.lib")
|
||||
#endif
|
||||
|
||||
#endif // CRASH_HANDLER_H
|
||||
@@ -1,4 +1,103 @@
|
||||
#include "Cutscene.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
enum class CutsceneCommands
|
||||
{
|
||||
Cmd00 = 0x0000,
|
||||
SetCameraPos = 0x0001,
|
||||
SetCameraFocus = 0x0002,
|
||||
SpecialAction = 0x0003,
|
||||
SetLighting = 0x0004,
|
||||
SetCameraPosLink = 0x0005,
|
||||
SetCameraFocusLink = 0x0006,
|
||||
Cmd07 = 0x0007,
|
||||
Cmd08 = 0x0008,
|
||||
Cmd09 = 0x0009,
|
||||
Unknown = 0x001A,
|
||||
Textbox = 0x0013,
|
||||
SetActorAction0 = 0x000A,
|
||||
SetActorAction1 = 0x000F,
|
||||
SetActorAction2 = 0x000E,
|
||||
SetActorAction3 = 0x0019,
|
||||
SetActorAction4 = 0x001D,
|
||||
SetActorAction5 = 0x001E,
|
||||
SetActorAction6 = 0x002C,
|
||||
SetActorAction7 = 0x001F,
|
||||
SetActorAction8 = 0x0031,
|
||||
SetActorAction9 = 0x003E,
|
||||
SetActorAction10 = 0x008F,
|
||||
SetSceneTransFX = 0x002D,
|
||||
Nop = 0x000B,
|
||||
PlayBGM = 0x0056,
|
||||
StopBGM = 0x0057,
|
||||
FadeBGM = 0x007C,
|
||||
SetTime = 0x008C,
|
||||
Terminator = 0x03E8,
|
||||
End = 0xFFFF,
|
||||
Error = 0xFEAF,
|
||||
};
|
||||
|
||||
static inline uint32_t read_CMD_BBBB(BinaryReader* reader)
|
||||
{
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_BBH(BinaryReader* reader)
|
||||
{
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
// swap the half word to match endianness
|
||||
if (reader->GetEndianness() != Endianness::Native)
|
||||
{
|
||||
uint8_t* b = (uint8_t*)&v;
|
||||
uint8_t tmp = b[2];
|
||||
b[2] = b[3];
|
||||
b[3] = tmp;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_HBB(BinaryReader* reader)
|
||||
{
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
// swap the half word to match endianness
|
||||
if (reader->GetEndianness() != Endianness::Native)
|
||||
{
|
||||
uint8_t* b = (uint8_t*)&v;
|
||||
uint8_t tmp = b[0];
|
||||
b[0] = b[1];
|
||||
b[1] = tmp;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint32_t read_CMD_HH(BinaryReader* reader)
|
||||
{
|
||||
uint32_t v;
|
||||
reader->Read((char*)&v, sizeof(uint32_t));
|
||||
|
||||
// swap the half words to match endianness
|
||||
if (reader->GetEndianness() != Endianness::Native)
|
||||
{
|
||||
uint8_t* b = (uint8_t*)&v;
|
||||
uint8_t tmp = b[0];
|
||||
b[0] = b[1];
|
||||
b[1] = tmp;
|
||||
tmp = b[2];
|
||||
b[2] = b[3];
|
||||
b[3] = tmp;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void Ship::CutsceneV0::ParseFileBinary(BinaryReader* reader, Resource* res)
|
||||
{
|
||||
@@ -9,11 +108,413 @@ void Ship::CutsceneV0::ParseFileBinary(BinaryReader* reader, Resource* res)
|
||||
uint32_t numEntries = reader->ReadUInt32();
|
||||
cs->commands.reserve(numEntries);
|
||||
|
||||
for (uint32_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
uint32_t data = reader->ReadUInt32();
|
||||
uint16_t opcode = data >> 16;
|
||||
uint32_t numCommands = reader->ReadUInt32();
|
||||
cs->commands.push_back(numCommands);
|
||||
|
||||
cs->commands.push_back(data);
|
||||
// endFrame
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t commandId = reader->ReadUInt32();
|
||||
cs->commands.push_back(commandId);
|
||||
|
||||
switch (commandId)
|
||||
{
|
||||
case (uint32_t)CutsceneCommands::SetCameraPos:
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cs->commands.push_back(val);
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (uint32_t)CutsceneCommands::SetCameraFocus:
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cs->commands.push_back(val);
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SpecialAction:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetLighting:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetCameraPosLink:
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cs->commands.push_back(val);
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetCameraFocusLink:
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint32_t val = read_CMD_BBH(reader);
|
||||
int8_t continueFlag = ((int8_t*)&val)[0];
|
||||
|
||||
cs->commands.push_back(val);
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
|
||||
if (continueFlag == -1)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::Cmd09:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HBB(reader));
|
||||
cs->commands.push_back(read_CMD_BBH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x15:
|
||||
case (uint32_t)CutsceneCommands::Unknown:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (uint32_t)CutsceneCommands::Textbox:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetActorAction0:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction1:
|
||||
case 17:
|
||||
case 18:
|
||||
case 23:
|
||||
case 34:
|
||||
case 39:
|
||||
case 46:
|
||||
case 76:
|
||||
case 85:
|
||||
case 93:
|
||||
case 105:
|
||||
case 107:
|
||||
case 110:
|
||||
case 119:
|
||||
case 123:
|
||||
case 138:
|
||||
case 139:
|
||||
case 144:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction2:
|
||||
case 16:
|
||||
case 24:
|
||||
case 35:
|
||||
case 40:
|
||||
case 48:
|
||||
case 64:
|
||||
case 68:
|
||||
case 70:
|
||||
case 78:
|
||||
case 80:
|
||||
case 94:
|
||||
case 116:
|
||||
case 118:
|
||||
case 120:
|
||||
case 125:
|
||||
case 131:
|
||||
case 141:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction3:
|
||||
case 36:
|
||||
case 41:
|
||||
case 50:
|
||||
case 67:
|
||||
case 69:
|
||||
case 72:
|
||||
case 74:
|
||||
case 81:
|
||||
case 106:
|
||||
case 117:
|
||||
case 121:
|
||||
case 126:
|
||||
case 132:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction4:
|
||||
case 37:
|
||||
case 42:
|
||||
case 51:
|
||||
case 53:
|
||||
case 63:
|
||||
case 65:
|
||||
case 66:
|
||||
case 75:
|
||||
case 82:
|
||||
case 108:
|
||||
case 127:
|
||||
case 133:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction5:
|
||||
case 38:
|
||||
case 43:
|
||||
case 47:
|
||||
case 54:
|
||||
case 79:
|
||||
case 83:
|
||||
case 128:
|
||||
case 135:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction6:
|
||||
case 55:
|
||||
case 77:
|
||||
case 84:
|
||||
case 90:
|
||||
case 129:
|
||||
case 136:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction7:
|
||||
case 52:
|
||||
case 57:
|
||||
case 58:
|
||||
case 88:
|
||||
case 115:
|
||||
case 130:
|
||||
case 137:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction8:
|
||||
case 60:
|
||||
case 89:
|
||||
case 111:
|
||||
case 114:
|
||||
case 134:
|
||||
case 142:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction9:
|
||||
case (uint32_t)CutsceneCommands::SetActorAction10:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetSceneTransFX:
|
||||
{
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::PlayBGM:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::StopBGM:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::FadeBGM:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::SetTime:
|
||||
{
|
||||
uint32_t size = reader->ReadUInt32();
|
||||
cs->commands.push_back(size);
|
||||
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HBB(reader));
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (uint32_t)CutsceneCommands::Terminator:
|
||||
{
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
cs->commands.push_back(read_CMD_HH(reader));
|
||||
break;
|
||||
}
|
||||
case 0xFFFFFFFF: // CS_END
|
||||
{
|
||||
cs->commands.push_back(reader->ReadUInt32());
|
||||
return;
|
||||
}
|
||||
default:
|
||||
SPDLOG_TRACE("CutsceneV0: Unknown command {}\n", commandId);
|
||||
// error?
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
#include "Cvar.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <PR/ultra64/gbi.h>
|
||||
#include "imgui_internal.h"
|
||||
#include <Utils/File.h>
|
||||
#include "Window.h"
|
||||
|
||||
std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
||||
|
||||
extern "C" CVar* CVar_Get(const char* name) {
|
||||
CVar* CVar_Get(const char* name) {
|
||||
auto it = cvars.find(name);
|
||||
return (it != cvars.end()) ? it->second.get() : nullptr;
|
||||
}
|
||||
|
||||
extern "C" s32 CVar_GetS32(const char* name, s32 defaultValue) {
|
||||
extern "C" int32_t CVar_GetS32(const char* name, int32_t defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar) {
|
||||
if (cvar->type == CVAR_TYPE_S32)
|
||||
if (cvar->type == CVarType::S32)
|
||||
return cvar->value.valueS32;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ extern "C" float CVar_GetFloat(const char* name, float defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar) {
|
||||
if (cvar->type == CVAR_TYPE_FLOAT)
|
||||
if (cvar->type == CVarType::Float)
|
||||
return cvar->value.valueFloat;
|
||||
}
|
||||
|
||||
@@ -40,28 +40,68 @@ extern "C" const char* CVar_GetString(const char* name, const char* defaultValue
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar) {
|
||||
if (cvar->type == CVAR_TYPE_STRING)
|
||||
if (cvar->type == CVarType::String)
|
||||
return cvar->value.valueStr;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
extern "C" void CVar_SetS32(const char* name, s32 value) {
|
||||
extern "C" Color_RGB8 CVar_GetRGB(const char* name, Color_RGB8 defaultValue)
|
||||
{
|
||||
Color_RGBA8 defaultValueRGBA;
|
||||
defaultValueRGBA.r = defaultValue.r;
|
||||
defaultValueRGBA.g = defaultValue.g;
|
||||
defaultValueRGBA.b = defaultValue.b;
|
||||
defaultValueRGBA.a = 255;
|
||||
|
||||
Color_RGBA8 cvarGet = CVar_GetRGBA(name, defaultValueRGBA);
|
||||
Color_RGB8 result;
|
||||
|
||||
result.r = cvarGet.r;
|
||||
result.g = cvarGet.g;
|
||||
result.b = cvarGet.b;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" Color_RGBA8 CVar_GetRGBA(const char* name, Color_RGBA8 defaultValue) {
|
||||
CVar* cvar = CVar_Get(name);
|
||||
|
||||
if (cvar != nullptr) {
|
||||
if (cvar->type == CVarType::RGBA)
|
||||
return cvar->value.valueRGBA;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
extern "C" void CVar_SetRGBA(const char* name, Color_RGBA8 value)
|
||||
{
|
||||
auto& cvar = cvars[name];
|
||||
if (!cvar) {
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVAR_TYPE_S32;
|
||||
|
||||
cvar->type = CVarType::RGBA;
|
||||
cvar->value.valueRGBA = value;
|
||||
}
|
||||
|
||||
extern "C" void CVar_SetS32(const char* name, int32_t value) {
|
||||
auto& cvar = cvars[name];
|
||||
if (!cvar) {
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVarType::S32;
|
||||
cvar->value.valueS32 = value;
|
||||
}
|
||||
|
||||
void CVar_SetFloat(const char* name, float value) {
|
||||
extern "C" void CVar_SetFloat(const char* name, float value) {
|
||||
auto& cvar = cvars[name];
|
||||
if (!cvar) {
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVAR_TYPE_FLOAT;
|
||||
cvar->type = CVarType::Float;
|
||||
cvar->value.valueFloat = value;
|
||||
}
|
||||
|
||||
@@ -70,11 +110,20 @@ extern "C" void CVar_SetString(const char* name, const char* value) {
|
||||
if (!cvar) {
|
||||
cvar = std::make_unique<CVar>();
|
||||
}
|
||||
cvar->type = CVAR_TYPE_STRING;
|
||||
cvar->value.valueStr = ImStrdup(value);
|
||||
cvar->type = CVarType::String;
|
||||
#ifdef _MSC_VER
|
||||
cvar->value.valueStr = _strdup(value);
|
||||
#else
|
||||
cvar->value.valueStr = strdup(value);
|
||||
#endif
|
||||
}
|
||||
|
||||
extern "C" void CVar_RegisterS32(const char* name, s32 defaultValue) {
|
||||
extern "C" void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue) {
|
||||
if (!CVar_Get(name))
|
||||
CVar_SetRGBA(name, defaultValue);
|
||||
}
|
||||
|
||||
extern "C" void CVar_RegisterS32(const char* name, int32_t defaultValue) {
|
||||
if (!CVar_Get(name))
|
||||
CVar_SetS32(name, defaultValue);
|
||||
}
|
||||
@@ -88,3 +137,126 @@ extern "C" void CVar_RegisterString(const char* name, const char* defaultValue)
|
||||
if (!CVar_Get(name))
|
||||
CVar_SetString(name, defaultValue);
|
||||
}
|
||||
|
||||
template <typename Numeric> bool is_number(const std::string& s) {
|
||||
Numeric n;
|
||||
return ((std::istringstream(s) >> n >> std::ws).eof());
|
||||
}
|
||||
|
||||
void CVar_LoadLegacy() {
|
||||
auto cvarsConfig = Ship::Window::GetPathRelativeToAppDirectory("cvars.cfg");
|
||||
if (File::Exists(cvarsConfig)) {
|
||||
const auto lines = File::ReadAllLines(cvarsConfig);
|
||||
|
||||
for (const std::string& line : lines) {
|
||||
std::vector<std::string> cfg = StringHelper::Split(line, " = ");
|
||||
if (line.empty()) continue;
|
||||
if (cfg.size() < 2) continue;
|
||||
|
||||
if (cfg[1].find("\"") == std::string::npos && (cfg[1].find("#") != std::string::npos))
|
||||
{
|
||||
std::string value(cfg[1]);
|
||||
value.erase(std::remove_if(value.begin(), value.end(), [](char c) { return c == '#'; }), value.end());
|
||||
auto splitTest = StringHelper::Split(value, "\r")[0];
|
||||
|
||||
uint32_t val = std::stoul(splitTest, nullptr, 16);
|
||||
Color_RGBA8 clr;
|
||||
clr.r = val >> 24;
|
||||
clr.g = val >> 16;
|
||||
clr.b = val >> 8;
|
||||
clr.a = val & 0xFF;
|
||||
CVar_SetRGBA(cfg[0].c_str(), clr);
|
||||
}
|
||||
|
||||
if (cfg[1].find("\"") != std::string::npos) {
|
||||
std::string value(cfg[1]);
|
||||
value.erase(std::remove(value.begin(), value.end(), '\"'), value.end());
|
||||
#ifdef _MSC_VER
|
||||
CVar_SetString(cfg[0].c_str(), _strdup(value.c_str()));
|
||||
#else
|
||||
CVar_SetString(cfg[0].c_str(), strdup(value.c_str()));
|
||||
#endif
|
||||
}
|
||||
if (is_number<float>(cfg[1])) {
|
||||
CVar_SetFloat(cfg[0].c_str(), std::stof(cfg[1]));
|
||||
}
|
||||
if (is_number<int>(cfg[1])) {
|
||||
CVar_SetS32(cfg[0].c_str(), std::stoi(cfg[1]));
|
||||
}
|
||||
}
|
||||
|
||||
fs::remove(cvarsConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" void CVar_Load() {
|
||||
std::shared_ptr<Mercury> pConf = Ship::Window::GetInstance()->GetConfig();
|
||||
pConf->reload();
|
||||
|
||||
for (const auto& item : pConf->rjson["CVars"].items()) {
|
||||
auto value = item.value();
|
||||
switch (value.type()) {
|
||||
case nlohmann::detail::value_t::array:
|
||||
break;
|
||||
case nlohmann::detail::value_t::object:
|
||||
if (value["Type"].get<std::string>() == mercuryRGBAObjectType) {
|
||||
Color_RGBA8 clr;
|
||||
clr.r = value["R"].get<uint8_t>();
|
||||
clr.g = value["G"].get<uint8_t>();
|
||||
clr.b = value["B"].get<uint8_t>();
|
||||
clr.a = value["A"].get<uint8_t>();
|
||||
CVar_SetRGBA(item.key().c_str(), clr);
|
||||
}
|
||||
|
||||
break;
|
||||
case nlohmann::detail::value_t::string:
|
||||
CVar_SetString(item.key().c_str(), value.get<std::string>().c_str());
|
||||
break;
|
||||
case nlohmann::detail::value_t::boolean:
|
||||
CVar_SetS32(item.key().c_str(), value.get<bool>());
|
||||
break;
|
||||
case nlohmann::detail::value_t::number_unsigned:
|
||||
case nlohmann::detail::value_t::number_integer:
|
||||
CVar_SetS32(item.key().c_str(), value.get<int>());
|
||||
break;
|
||||
case nlohmann::detail::value_t::number_float:
|
||||
CVar_SetFloat(item.key().c_str(), value.get<float>());
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
if (item.key() == "gOpenMenuBar") {
|
||||
int bp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CVar_LoadLegacy();
|
||||
}
|
||||
|
||||
extern "C" void CVar_Save()
|
||||
{
|
||||
std::shared_ptr<Mercury> pConf = Ship::Window::GetInstance()->GetConfig();
|
||||
|
||||
for (const auto& cvar : cvars) {
|
||||
const std::string key = StringHelper::Sprintf("CVars.%s", cvar.first.c_str());
|
||||
|
||||
if (cvar.second->type == CVarType::String && cvar.second->value.valueStr != nullptr)
|
||||
pConf->setString(key, std::string(cvar.second->value.valueStr));
|
||||
else if (cvar.second->type == CVarType::S32)
|
||||
pConf->setInt(key, cvar.second->value.valueS32);
|
||||
else if (cvar.second->type == CVarType::Float)
|
||||
pConf->setFloat(key, cvar.second->value.valueFloat);
|
||||
else if (cvar.second->type == CVarType::RGBA)
|
||||
{
|
||||
auto keyStr = key.c_str();
|
||||
Color_RGBA8 clr = cvar.second->value.valueRGBA;
|
||||
pConf->setUInt(StringHelper::Sprintf("%s.R", keyStr), clr.r);
|
||||
pConf->setUInt(StringHelper::Sprintf("%s.G", keyStr), clr.g);
|
||||
pConf->setUInt(StringHelper::Sprintf("%s.B", keyStr), clr.b);
|
||||
pConf->setUInt(StringHelper::Sprintf("%s.A", keyStr), clr.a);
|
||||
pConf->setString(StringHelper::Sprintf("%s.Type", keyStr), mercuryRGBAObjectType);
|
||||
}
|
||||
}
|
||||
|
||||
pConf->save();
|
||||
}
|
||||
|
||||
@@ -1,37 +1,55 @@
|
||||
#ifndef _CVAR_H
|
||||
#define _CVAR_H
|
||||
|
||||
#include <PR/ultra64/gbi.h>
|
||||
#include "color.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum CVarType { CVAR_TYPE_S32, CVAR_TYPE_FLOAT, CVAR_TYPE_STRING } CVarType;
|
||||
#ifdef __cplusplus
|
||||
typedef enum class CVarType
|
||||
{
|
||||
S32,
|
||||
Float,
|
||||
String,
|
||||
RGBA
|
||||
} CVarType;
|
||||
|
||||
typedef struct CVar {
|
||||
const char* name;
|
||||
CVarType type;
|
||||
|
||||
union {
|
||||
s32 valueS32;
|
||||
int32_t valueS32;
|
||||
float valueFloat;
|
||||
const char* valueStr;
|
||||
Color_RGBA8 valueRGBA;
|
||||
} value;
|
||||
} CVar;
|
||||
|
||||
extern "C" CVar * CVar_Get(const char* name);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
//#include <ultra64.h>
|
||||
|
||||
CVar* CVar_Get(const char* name);
|
||||
s32 CVar_GetS32(const char* name, s32 defaultValue);
|
||||
float CVar_GetFloat(const char* name, float defaultValue);
|
||||
const char* CVar_GetString(const char* name, const char* defaultValue);
|
||||
void CVar_SetS32(const char* name, s32 value);
|
||||
void CVar_SetString(const char* name, const char* value);
|
||||
float CVar_GetFloat(const char* name, float defaultValue);
|
||||
void CVar_SetFloat(const char* name, float value);
|
||||
int32_t CVar_GetS32(const char* name, int32_t defaultValue);
|
||||
void CVar_SetS32(const char* name, int32_t value);
|
||||
const char* CVar_GetString(const char* name, const char* defaultValue);
|
||||
void CVar_SetString(const char* name, const char* value);
|
||||
Color_RGB8 CVar_GetRGB(const char* name, Color_RGB8 defaultValue);
|
||||
Color_RGBA8 CVar_GetRGBA(const char* name, Color_RGBA8 defaultValue);
|
||||
void CVar_SetRGBA(const char* name, Color_RGBA8 value);
|
||||
|
||||
void CVar_RegisterS32(const char* name, s32 defaultValue);
|
||||
void CVar_RegisterFloat(const char* name, float defaultValue);
|
||||
void CVar_RegisterString(const char* name, const char* defaultValue);
|
||||
void CVar_RegisterS32(const char* name, int32_t defaultValue);
|
||||
void CVar_RegisterFloat(const char* name, float defaultValue);
|
||||
void CVar_RegisterString(const char* name, const char* defaultValue);
|
||||
void CVar_RegisterRGBA(const char* name, Color_RGBA8 defaultValue);
|
||||
|
||||
void CVar_Load();
|
||||
void CVar_Save();
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
@@ -40,10 +58,8 @@ void CVar_RegisterString(const char* name, const char* defaultValue);
|
||||
#ifdef __cplusplus
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
extern std::map<std::string, std::unique_ptr<CVar>, std::less<>> cvars;
|
||||
void CVar_SetFloat(const char* name, float value);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include "Controller.h"
|
||||
|
||||
class DisconnectedController final : public Ship::Controller {
|
||||
public:
|
||||
DisconnectedController() {
|
||||
GUID = "Disconnected";
|
||||
}
|
||||
|
||||
std::map<std::vector<std::string>, int32_t> ReadButtonPress();
|
||||
void ReadFromSource(int32_t slot) override {}
|
||||
const char* GetControllerName() override { return "Disconnected"; }
|
||||
const char* GetButtonName(int slot, int n64Button) override { return "None"; }
|
||||
void WriteToSource(int32_t slot, ControllerCallback* controller) override { }
|
||||
bool Connected() const override { return false; }
|
||||
bool CanRumble() const override { return false; }
|
||||
bool CanGyro() const override { return false; }
|
||||
|
||||
void ClearRawPress() override {}
|
||||
int32_t ReadRawPress() override { return -1; }
|
||||
bool HasPadConf() const { return true; }
|
||||
std::optional<std::string> GetPadConfSection() { return "Unk"; }
|
||||
void CreateDefaultBinding(int32_t slot) override {}
|
||||
protected:
|
||||
std::string GetControllerType() { return "Unk"; }
|
||||
std::string GetConfSection() { return "Unk"; }
|
||||
std::string GetBindingConfSection() { return "Unk"; }
|
||||
};
|
||||
@@ -14,23 +14,25 @@ namespace Ship
|
||||
|
||||
while (true)
|
||||
{
|
||||
uint64_t data = reader->ReadUInt64();
|
||||
uint32_t w0 = reader->ReadUInt32();
|
||||
uint32_t w1 = reader->ReadUInt32();
|
||||
|
||||
if (sizeof(uintptr_t) < 8){
|
||||
dl->instructions.push_back(data);
|
||||
dl->instructions.push_back(((uint64_t) w0 << 32) | w1);
|
||||
|
||||
uint8_t opcode = data >> 24;
|
||||
uint8_t opcode = w0 >> 24;
|
||||
|
||||
// These are 128-bit commands, so read an extra 64 bits...
|
||||
if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR)
|
||||
dl->instructions.push_back(reader->ReadUInt64());
|
||||
if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR) {
|
||||
w0 = reader->ReadUInt32();
|
||||
w1 = reader->ReadUInt32();
|
||||
|
||||
dl->instructions.push_back(((uint64_t) w0 << 32) | w1);
|
||||
}
|
||||
|
||||
if (opcode == G_ENDDL)
|
||||
break;
|
||||
} else {
|
||||
uint32_t w0 = (uint32_t)data;
|
||||
uint32_t w1 = (uint32_t)(data >> 32);
|
||||
|
||||
dl->instructions.push_back(w0);
|
||||
dl->instructions.push_back(w1);
|
||||
|
||||
@@ -38,10 +40,8 @@ namespace Ship
|
||||
|
||||
if (opcode == G_SETTIMG_OTR || opcode == G_DL_OTR || opcode == G_VTX_OTR || opcode == G_BRANCH_Z_OTR || opcode == G_MARKER || opcode == G_MTX_OTR)
|
||||
{
|
||||
data = reader->ReadUInt64();
|
||||
|
||||
w0 = (uint32_t)data;
|
||||
w1 = (uint32_t)(data >> 32);
|
||||
w0 = reader->ReadUInt32();
|
||||
w1 = reader->ReadUInt32();
|
||||
|
||||
dl->instructions.push_back(w0);
|
||||
dl->instructions.push_back(w1);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "DummyController.h"
|
||||
|
||||
namespace Ship {
|
||||
DummyController::DummyController(const std::string& CUID, const std::string& KeyName, bool Connected) {
|
||||
GUID = CUID;
|
||||
isConnected = Connected;
|
||||
ButtonName = KeyName;
|
||||
}
|
||||
|
||||
void DummyController::ReadFromSource(int32_t virtualSlot) {
|
||||
|
||||
}
|
||||
|
||||
const std::string DummyController::GetControllerName() {
|
||||
return GUID;
|
||||
}
|
||||
|
||||
const std::string DummyController::GetButtonName(int32_t virtualSlot, int32_t n64Button) {
|
||||
return ButtonName;
|
||||
}
|
||||
|
||||
void DummyController::WriteToSource(int32_t virtualSlot, ControllerCallback* controller){
|
||||
|
||||
}
|
||||
|
||||
bool DummyController::Connected() const {
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
bool DummyController::CanRumble() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DummyController::CanGyro() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DummyController::CreateDefaultBinding(int32_t slot) {
|
||||
|
||||
}
|
||||
|
||||
std::string DummyController::GetControllerType() {
|
||||
return "Unk";
|
||||
}
|
||||
|
||||
std::string DummyController::GetConfSection() {
|
||||
return "Unk";
|
||||
}
|
||||
|
||||
std::string DummyController::GetBindingConfSection() {
|
||||
return "Unk";
|
||||
}
|
||||
|
||||
void DummyController::ClearRawPress() {
|
||||
|
||||
}
|
||||
|
||||
int32_t DummyController::ReadRawPress() {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include "Controller.h"
|
||||
|
||||
namespace Ship {
|
||||
class DummyController final : public Controller {
|
||||
public:
|
||||
DummyController(const std::string& CUID, const std::string& KeyName, bool Connected);
|
||||
std::map<std::vector<std::string>, int32_t> ReadButtonPress();
|
||||
void ReadFromSource(int32_t virtualSlot) override;
|
||||
const std::string GetControllerName() override;
|
||||
const std::string GetButtonName(int32_t virtualSlot, int32_t n64Button) override;
|
||||
void WriteToSource(int32_t slot, ControllerCallback* controller) override;
|
||||
bool Connected() const override;
|
||||
bool CanRumble() const override;
|
||||
bool CanGyro() const override;
|
||||
void ClearRawPress() override;
|
||||
int32_t ReadRawPress() override;
|
||||
bool HasPadConf() const;
|
||||
std::optional<std::string> GetPadConfSection();
|
||||
void CreateDefaultBinding(int32_t virtualSlot) override;
|
||||
protected:
|
||||
std::string ButtonName;
|
||||
bool isConnected = false;
|
||||
std::string GetControllerType();
|
||||
std::string GetConfSection();
|
||||
std::string GetBindingConfSection();
|
||||
};
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "Environment.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
std::map<std::string, std::string> environmentVars;
|
||||
|
||||
namespace SohUtils {
|
||||
void saveEnvironmentVar(const std::string& key, const std::string& value) {
|
||||
environmentVars[key] = value;
|
||||
}
|
||||
std::string getEnvironmentVar(const std::string& key) {
|
||||
return environmentVars[key];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace SohUtils {
|
||||
void saveEnvironmentVar(const std::string& key, const std::string& value);
|
||||
std::string getEnvironmentVar(const std::string& key);
|
||||
}
|
||||
@@ -25,12 +25,12 @@ namespace Ship
|
||||
auto memStream = std::make_shared<MemoryStream>(FileToLoad->buffer.get(), FileToLoad->dwBufferSize);
|
||||
auto reader = std::make_shared<BinaryReader>(memStream);
|
||||
|
||||
Endianess endianess = (Endianess)reader->ReadByte();
|
||||
Endianness endianness = (Endianness)reader->ReadByte();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
reader->ReadByte();
|
||||
|
||||
// OTRTODO: Setup the binaryreader to use the resource's endianess
|
||||
reader->SetEndianness(endianness);
|
||||
|
||||
ResourceType resourceType = (ResourceType)reader->ReadUInt32();
|
||||
Resource* result = nullptr;
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "GlobalCtx2.h"
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace Ship {
|
||||
class Archive;
|
||||
|
||||
@@ -4,222 +4,236 @@
|
||||
#include "File.h"
|
||||
#include "Archive.h"
|
||||
#include "ResourceMgr.h"
|
||||
#include "Console.h"
|
||||
#include "ImGuiImpl.h"
|
||||
#include "TextureMod.h"
|
||||
#include "Lib/ImGui/imgui_internal.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
void Ship::GameOverlay::LoadFont(const std::string& name, const std::string& path, float fontSize) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
std::shared_ptr<Archive> base = GlobalCtx2::GetInstance()->GetResourceManager()->GetArchive();
|
||||
std::shared_ptr<File> font = std::make_shared<File>();
|
||||
base->LoadFile(path, false, font);
|
||||
if (font->bIsLoaded) {
|
||||
char* font_data = new char[font->dwBufferSize];
|
||||
memcpy(font_data, font->buffer.get(), font->dwBufferSize);
|
||||
Fonts[name] = io.Fonts->AddFontFromMemoryTTF(font_data, font->dwBufferSize, fontSize);
|
||||
namespace Ship {
|
||||
bool GameOverlay::OverlayCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args) {
|
||||
if (args.size() < 3) {
|
||||
return CMD_FAILED;
|
||||
}
|
||||
|
||||
if (CVar_Get(args[2].c_str()) != nullptr) {
|
||||
const char* key = args[2].c_str();
|
||||
GameOverlay* overlay = SohImGui::GetGameOverlay();
|
||||
if (args[1] == "add") {
|
||||
if (!overlay->RegisteredOverlays.contains(key)) {
|
||||
overlay->RegisteredOverlays[key] = new Overlay({ OverlayType::TEXT, ImStrdup(key), -1.0f });
|
||||
SohImGui::GetConsole()->SendInfoMessage("Added overlay: %s", key);
|
||||
}
|
||||
else {
|
||||
SohImGui::GetConsole()->SendErrorMessage("Overlay already exists: %s", key);
|
||||
}
|
||||
}
|
||||
else if (args[1] == "remove") {
|
||||
if (overlay->RegisteredOverlays.contains(key)) {
|
||||
overlay->RegisteredOverlays.erase(key);
|
||||
SohImGui::GetConsole()->SendInfoMessage("Removed overlay: %s", key);
|
||||
}
|
||||
else {
|
||||
SohImGui::GetConsole()->SendErrorMessage("Overlay not found: %s", key);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
SohImGui::GetConsole()->SendErrorMessage("CVar {} does not exist", args[2].c_str());
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::TextDraw(float x, float y, bool shadow, ImVec4 color, const char* fmt, ...) {
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
void GameOverlay::LoadFont(const std::string& name, const std::string& path, float fontSize) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
std::shared_ptr<Archive> base = Window::GetInstance()->GetResourceManager()->GetArchive();
|
||||
std::shared_ptr<File> font = std::make_shared<File>();
|
||||
base->LoadFile(path, false, font);
|
||||
if (font->bIsLoaded) {
|
||||
char* font_data = new char[font->dwBufferSize];
|
||||
memcpy(font_data, font->buffer.get(), font->dwBufferSize);
|
||||
Fonts[name] = io.Fonts->AddFontFromMemoryTTF(font_data, font->dwBufferSize, fontSize);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||
ImGui::PushFont(Fonts[this->CurrentFont]);
|
||||
if (shadow) {
|
||||
ImGui::SetCursorPos(ImVec2(x + 1, y + 1));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(.0f, .0f, .0f, color.w));
|
||||
void GameOverlay::TextDraw(float x, float y, bool shadow, ImVec4 color, const char* fmt, ...) {
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||
ImGui::PushFont(Fonts[this->CurrentFont]);
|
||||
if (shadow) {
|
||||
ImGui::SetCursorPos(ImVec2(x + 1, y + 1));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(.0f, .0f, .0f, color.w));
|
||||
ImGui::Text(buf, args);
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SetCursorPos(ImVec2(x, y));
|
||||
ImGui::Text(buf, args);
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SetCursorPos(ImVec2(x, y));
|
||||
ImGui::Text(buf, args);
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::TextDrawNotification(float duration, bool shadow, const char* fmt, ...) {
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
this->RegisteredOverlays[StringHelper::Sprintf("NotificationID:%d%d", rand(), this->RegisteredOverlays.size())] = new Overlay({ OverlayType::NOTIFICATION, ImStrdup(buf), duration, duration });
|
||||
NeedsCleanup = true;
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::CleanupNotifications() {
|
||||
if(!NeedsCleanup) return;
|
||||
for (auto it = this->RegisteredOverlays.begin(); it != this->RegisteredOverlays.end(); ) {
|
||||
if (it->second->type == OverlayType::NOTIFICATION && it->second->duration <= 0.0f) {
|
||||
it = this->RegisteredOverlays.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
void GameOverlay::TextDrawNotification(float duration, bool shadow, const char* fmt, ...) {
|
||||
char buf[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
|
||||
buf[IM_ARRAYSIZE(buf) - 1] = 0;
|
||||
va_end(args);
|
||||
this->RegisteredOverlays[StringHelper::Sprintf("NotificationID:%d%d", rand(), this->RegisteredOverlays.size())] = new Overlay({ OverlayType::NOTIFICATION, ImStrdup(buf), duration, duration });
|
||||
NeedsCleanup = true;
|
||||
}
|
||||
NeedsCleanup = false;
|
||||
}
|
||||
|
||||
float Ship::GameOverlay::GetScreenWidth() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
return viewport->Size.x;
|
||||
}
|
||||
|
||||
float Ship::GameOverlay::GetScreenHeight() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
return viewport->Size.y;
|
||||
}
|
||||
|
||||
float Ship::GameOverlay::GetStringWidth(const char* text) {
|
||||
return CalculateTextSize(text).x;
|
||||
}
|
||||
|
||||
ImVec2 Ship::GameOverlay::CalculateTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) {
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
const char* text_display_end;
|
||||
if (hide_text_after_double_hash)
|
||||
text_display_end = ImGui::FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string
|
||||
else
|
||||
text_display_end = text_end;
|
||||
|
||||
GameOverlay* overlay = SohImGui::overlay;
|
||||
|
||||
ImFont* font = overlay->CurrentFont == "Default" ? g.Font : overlay->Fonts[overlay->CurrentFont];
|
||||
const float font_size = font->FontSize;
|
||||
if (text == text_display_end)
|
||||
return ImVec2(0.0f, font_size);
|
||||
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
|
||||
|
||||
// Round
|
||||
// FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
|
||||
// FIXME: Investigate using ceilf or e.g.
|
||||
// - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
|
||||
// - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html
|
||||
text_size.x = IM_FLOOR(text_size.x + 0.99999f);
|
||||
|
||||
return text_size;
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::Init() {
|
||||
this->LoadFont("Press Start 2P", "assets/ship_of_harkinian/fonts/PressStart2P-Regular.ttf", 12.0f);
|
||||
this->LoadFont("Fipps", "assets/ship_of_harkinian/fonts/Fipps-Regular.otf", 32.0f);
|
||||
const std::string DefaultFont = this->Fonts.begin()->first;
|
||||
if(!this->Fonts.empty()) {
|
||||
const std::string font = CVar_GetString("gOverlayFont", ImStrdup(DefaultFont.c_str()));
|
||||
for (auto& [name, _] : this->Fonts) {
|
||||
if (font.starts_with(name)) {
|
||||
this->CurrentFont = name;
|
||||
break;
|
||||
void GameOverlay::CleanupNotifications() {
|
||||
if (!NeedsCleanup) return;
|
||||
for (auto it = this->RegisteredOverlays.begin(); it != this->RegisteredOverlays.end(); ) {
|
||||
if (it->second->type == OverlayType::NOTIFICATION && it->second->duration <= 0.0f) {
|
||||
it = this->RegisteredOverlays.erase(it);
|
||||
}
|
||||
this->CurrentFont = DefaultFont;
|
||||
}
|
||||
}
|
||||
SohImGui::console->Commands["overlay"] = { OverlayCommand, "Draw an overlay using a cvar value" };
|
||||
}
|
||||
|
||||
void Ship::GameOverlay::DrawSettings() {
|
||||
ImGui::Text("Overlays Text Font");
|
||||
if (ImGui::BeginCombo("##TextFont", this->CurrentFont.c_str())) {
|
||||
for (auto& [name, font] : this->Fonts) {
|
||||
if (ImGui::Selectable(name.c_str(), name == this->CurrentFont)) {
|
||||
this->CurrentFont = name;
|
||||
CVar_SetString("gOverlayFont", ImStrdup(name.c_str()));
|
||||
SohImGui::needs_save = true;
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Ship::GameOverlay::Draw() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
|
||||
ImGui::SetNextWindowPos(viewport->Pos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(viewport->Size, ImGuiCond_Always);
|
||||
ImGui::Begin("SoHOverlay", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBackground |
|
||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs);
|
||||
|
||||
this->CleanupNotifications();
|
||||
|
||||
float textY = 50;
|
||||
float notY = 0;
|
||||
|
||||
for (auto &[key, overlay] : this->RegisteredOverlays) {
|
||||
|
||||
if (overlay->type == OverlayType::TEXT) {
|
||||
const char* text = ImStrdup(overlay->value);
|
||||
const CVar* var = CVar_Get(text);
|
||||
ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
switch (var->type) {
|
||||
case CVAR_TYPE_FLOAT:
|
||||
this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat);
|
||||
break;
|
||||
case CVAR_TYPE_S32:
|
||||
this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32);
|
||||
break;
|
||||
case CVAR_TYPE_STRING:
|
||||
this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr);
|
||||
break;
|
||||
}
|
||||
|
||||
free((void*) text);
|
||||
textY += 30;
|
||||
}
|
||||
|
||||
if (overlay->type == OverlayType::NOTIFICATION && overlay->duration > 0) {
|
||||
const char* text = overlay->value;
|
||||
const float duration = overlay->duration / overlay->fadeTime;
|
||||
|
||||
const ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, duration);
|
||||
const float textWidth = this->GetStringWidth(overlay->value);
|
||||
|
||||
this->TextDraw(GetScreenWidth() - textWidth - 40, GetScreenHeight() - 40 - notY, true, color, text);
|
||||
notY += 30;
|
||||
overlay->duration -= .05f;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
bool Ship::OverlayCommand(const std::vector<std::string>& args) {
|
||||
if (args.size() < 3) {
|
||||
return CMD_FAILED;
|
||||
}
|
||||
|
||||
if (CVar_Get(args[2].c_str()) != nullptr) {
|
||||
const char* key = args[2].c_str();
|
||||
GameOverlay* overlay = SohImGui::overlay;
|
||||
if (args[1] == "add") {
|
||||
if (!overlay->RegisteredOverlays.contains(key)) {
|
||||
overlay->RegisteredOverlays[key] = new Overlay({ OverlayType::TEXT, ImStrdup(key), -1.0f });
|
||||
INFO("Added overlay: %s ", key);
|
||||
} else {
|
||||
ERROR("Overlay already exists: %s", key);
|
||||
}
|
||||
} else if (args[1] == "remove") {
|
||||
if (overlay->RegisteredOverlays.contains(key)) {
|
||||
overlay->RegisteredOverlays.erase(key);
|
||||
INFO("Removed overlay: %s ", key);
|
||||
} else {
|
||||
ERROR("Overlay not found: %s ", key);
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ERROR("CVar %s does not exist", args[2].c_str());
|
||||
NeedsCleanup = false;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
float GameOverlay::GetScreenWidth() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
return viewport->Size.x;
|
||||
}
|
||||
|
||||
float GameOverlay::GetScreenHeight() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
return viewport->Size.y;
|
||||
}
|
||||
|
||||
float GameOverlay::GetStringWidth(const char* text) {
|
||||
return CalculateTextSize(text).x;
|
||||
}
|
||||
|
||||
ImVec2 GameOverlay::CalculateTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) {
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
const char* text_display_end;
|
||||
if (hide_text_after_double_hash)
|
||||
text_display_end = ImGui::FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string
|
||||
else
|
||||
text_display_end = text_end;
|
||||
|
||||
GameOverlay* overlay = SohImGui::GetGameOverlay();
|
||||
|
||||
ImFont* font = overlay->CurrentFont == "Default" ? g.Font : overlay->Fonts[overlay->CurrentFont];
|
||||
const float font_size = font->FontSize;
|
||||
if (text == text_display_end)
|
||||
return ImVec2(0.0f, font_size);
|
||||
ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
|
||||
|
||||
// Round
|
||||
// FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out.
|
||||
// FIXME: Investigate using ceilf or e.g.
|
||||
// - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
|
||||
// - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html
|
||||
text_size.x = IM_FLOOR(text_size.x + 0.99999f);
|
||||
|
||||
return text_size;
|
||||
}
|
||||
|
||||
void GameOverlay::Init() {
|
||||
this->LoadFont("Press Start 2P", "assets/ship_of_harkinian/fonts/PressStart2P-Regular.ttf", 12.0f);
|
||||
this->LoadFont("Fipps", "assets/ship_of_harkinian/fonts/Fipps-Regular.otf", 32.0f);
|
||||
const std::string DefaultFont = this->Fonts.begin()->first;
|
||||
if (!this->Fonts.empty()) {
|
||||
const std::string font = CVar_GetString("gOverlayFont", ImStrdup(DefaultFont.c_str()));
|
||||
for (auto& [name, _] : this->Fonts) {
|
||||
if (font.starts_with(name)) {
|
||||
this->CurrentFont = name;
|
||||
break;
|
||||
}
|
||||
this->CurrentFont = DefaultFont;
|
||||
}
|
||||
}
|
||||
|
||||
SohImGui::GetConsole()->AddCommand("overlay", { OverlayCommand, "Draw an overlay using a cvar value" });
|
||||
}
|
||||
|
||||
void GameOverlay::DrawSettings() {
|
||||
ImGui::Text("Overlays Text Font");
|
||||
if (ImGui::BeginCombo("##TextFont", this->CurrentFont.c_str())) {
|
||||
for (auto& [name, font] : this->Fonts) {
|
||||
if (ImGui::Selectable(name.c_str(), name == this->CurrentFont)) {
|
||||
this->CurrentFont = name;
|
||||
CVar_SetString("gOverlayFont", ImStrdup(name.c_str()));
|
||||
SohImGui::RequestCvarSaveOnNextTick();
|
||||
}
|
||||
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GameOverlay::Draw() {
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
|
||||
ImGui::SetNextWindowPos(viewport->Pos, ImGuiCond_Always);
|
||||
ImGui::SetNextWindowSize(viewport->Size, ImGuiCond_Always);
|
||||
ImGui::Begin("SoHOverlay", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBackground |
|
||||
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs);
|
||||
|
||||
this->CleanupNotifications();
|
||||
|
||||
float textY = 50;
|
||||
float notY = 0;
|
||||
|
||||
for (auto& [key, overlay] : this->RegisteredOverlays) {
|
||||
|
||||
if (overlay->type == OverlayType::TEXT) {
|
||||
const char* text = ImStrdup(overlay->value);
|
||||
const CVar* var = CVar_Get(text);
|
||||
ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
switch (var->type) {
|
||||
case CVarType::Float:
|
||||
this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat);
|
||||
break;
|
||||
case CVarType::S32:
|
||||
this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32);
|
||||
break;
|
||||
case CVarType::String:
|
||||
this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr);
|
||||
break;
|
||||
case CVarType::RGBA:
|
||||
this->TextDraw(30, textY, true, color, "#%08X", text, var->value.valueRGBA);
|
||||
break;
|
||||
}
|
||||
|
||||
free((void*)text);
|
||||
textY += 30;
|
||||
}
|
||||
|
||||
if (overlay->type == OverlayType::NOTIFICATION && overlay->duration > 0) {
|
||||
const char* text = overlay->value;
|
||||
const float duration = overlay->duration / overlay->fadeTime;
|
||||
|
||||
const ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, duration);
|
||||
#ifdef __WIIU__
|
||||
const float textWidth = this->GetStringWidth(overlay->value) * 2.0f;
|
||||
const float textOffset = 40.0f * 2.0f;
|
||||
#else
|
||||
const float textWidth = this->GetStringWidth(overlay->value);
|
||||
const float textOffset = 40.0f;
|
||||
#endif
|
||||
|
||||
this->TextDraw(GetScreenWidth() - textWidth - textOffset, GetScreenHeight() - textOffset - notY, true, color, text);
|
||||
notY += 30;
|
||||
overlay->duration -= .05f;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "Console.h"
|
||||
#include "Lib/ImGui/imgui.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
enum class OverlayType {
|
||||
TEXT, IMAGE, NOTIFICATION
|
||||
};
|
||||
|
||||
struct Overlay {
|
||||
OverlayType type;
|
||||
const char* value;
|
||||
float fadeTime;
|
||||
float duration;
|
||||
};
|
||||
|
||||
namespace Ship {
|
||||
|
||||
enum class OverlayType {
|
||||
TEXT, IMAGE, NOTIFICATION
|
||||
};
|
||||
|
||||
struct Overlay {
|
||||
OverlayType type;
|
||||
const char* value;
|
||||
float fadeTime;
|
||||
float duration;
|
||||
};
|
||||
|
||||
class GameOverlay {
|
||||
public:
|
||||
std::unordered_map<std::string, Overlay*> RegisteredOverlays;
|
||||
std::unordered_map<std::string, ImFont*> Fonts;
|
||||
std::string CurrentFont = "Default";
|
||||
static bool OverlayCommand(std::shared_ptr<Console> Console, const std::vector<std::string>& args);
|
||||
|
||||
void Init();
|
||||
void Draw();
|
||||
void DrawSettings();
|
||||
@@ -33,10 +34,12 @@ namespace Ship {
|
||||
void TextDraw(float x, float y, bool shadow, ImVec4 color, const char* text, ...);
|
||||
void TextDrawNotification(float duration, bool shadow, const char* fmt, ...);
|
||||
private:
|
||||
std::unordered_map<std::string, ImFont*> Fonts;
|
||||
std::unordered_map<std::string, Overlay*> RegisteredOverlays;
|
||||
std::string CurrentFont = "Default";
|
||||
bool NeedsCleanup = false;
|
||||
|
||||
void CleanupNotifications();
|
||||
void LoadFont(const std::string& name, const std::string& path, float fontSize);
|
||||
};
|
||||
|
||||
static bool OverlayCommand(const std::vector<std::string>& args);
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#include "GameSettings.h"
|
||||
|
||||
// Audio
|
||||
#include <cstddef>
|
||||
#include <PR/ultra64/types.h>
|
||||
#include <PR/ultra64/sptask.h>
|
||||
#include <PR/ultra64/pi.h>
|
||||
#include <PR/ultra64/message.h>
|
||||
|
||||
#include "Cvar.h"
|
||||
#include "GlobalCtx2.h"
|
||||
#include "ImGuiImpl.h"
|
||||
#include "../../soh/include/z64audio.h"
|
||||
#include "Hooks.h"
|
||||
#include "../../soh/soh/Enhancements/debugconsole.h"
|
||||
|
||||
#include "Window.h"
|
||||
#include "Lib/Fast3D/gfx_rendering_api.h"
|
||||
|
||||
#define ABS(var) var < 0 ? -(var) : var
|
||||
|
||||
using namespace Ship;
|
||||
|
||||
namespace Game {
|
||||
|
||||
bool DeSyncAudio = false;
|
||||
|
||||
void UpdateAudio() {
|
||||
Audio_SetGameVolume(SEQ_BGM_MAIN, CVar_GetFloat("gMainMusicVolume", 1));
|
||||
Audio_SetGameVolume(SEQ_BGM_SUB, CVar_GetFloat("gSubMusicVolume", 1));
|
||||
Audio_SetGameVolume(SEQ_FANFARE, CVar_GetFloat("gSFXMusicVolume", 1));
|
||||
Audio_SetGameVolume(SEQ_SFX, CVar_GetFloat("gFanfareVolume", 1));
|
||||
}
|
||||
|
||||
void LoadSettings() {
|
||||
DebugConsole_LoadCVars();
|
||||
}
|
||||
|
||||
void SaveSettings() {
|
||||
DebugConsole_SaveCVars();
|
||||
}
|
||||
|
||||
void InitSettings() {
|
||||
ModInternal::RegisterHook<ModInternal::AudioInit>(UpdateAudio);
|
||||
ModInternal::RegisterHook<ModInternal::GfxInit>([] {
|
||||
gfx_get_current_rendering_api()->set_texture_filter((FilteringMode) CVar_GetS32("gTextureFilter", FILTER_THREE_POINT));
|
||||
SohImGui::console->opened = CVar_GetS32("gConsoleEnabled", 0);
|
||||
SohImGui::controller->Opened = CVar_GetS32("gControllerConfigurationEnabled", 0);
|
||||
UpdateAudio();
|
||||
});
|
||||
}
|
||||
|
||||
void SetSeqPlayerVolume(SeqPlayers playerId, float volume) {
|
||||
Audio_SetGameVolume(playerId, volume);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
enum SeqPlayers {
|
||||
/* 0 */ SEQ_BGM_MAIN,
|
||||
/* 1 */ SEQ_FANFARE,
|
||||
/* 2 */ SEQ_SFX,
|
||||
/* 3 */ SEQ_BGM_SUB,
|
||||
/* 4 */ SEQ_MAX
|
||||
};
|
||||
|
||||
namespace Game {
|
||||
void InitSettings();
|
||||
void LoadSettings();
|
||||
void LoadPadSettings();
|
||||
void SaveSettings();
|
||||
void SetSeqPlayerVolume(SeqPlayers playerId, float volume);
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
#include "GlobalCtx2.h"
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "ResourceMgr.h"
|
||||
#include "Window.h"
|
||||
#include "spdlog/async.h"
|
||||
#include "spdlog/sinks/rotating_file_sink.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
#include "spdlog/sinks/sohconsole_sink.h"
|
||||
#include "ModManager.h"
|
||||
#ifdef __APPLE__
|
||||
#include "OSXFolderManager.h"
|
||||
#endif
|
||||
|
||||
namespace Ship {
|
||||
std::weak_ptr<GlobalCtx2> GlobalCtx2::Context;
|
||||
ModManager* INSTANCE;
|
||||
std::shared_ptr<GlobalCtx2> GlobalCtx2::GetInstance() {
|
||||
return Context.lock();
|
||||
}
|
||||
|
||||
std::shared_ptr<GlobalCtx2> GlobalCtx2::CreateInstance(const std::string& Name) {
|
||||
if (Context.expired()) {
|
||||
auto Shared = std::make_shared<GlobalCtx2>(Name);
|
||||
Context = Shared;
|
||||
Shared->InitWindow();
|
||||
return Shared;
|
||||
} else {
|
||||
SPDLOG_DEBUG("Trying to create a context when it already exists.");
|
||||
}
|
||||
|
||||
return GetInstance();
|
||||
}
|
||||
|
||||
std::string GlobalCtx2::GetAppDirectoryPath() {
|
||||
#ifdef __APPLE__
|
||||
FolderManager folderManager;
|
||||
std::string fpath = std::string(folderManager.pathForDirectory(NSApplicationSupportDirectory, NSUserDomainMask));
|
||||
fpath.append("/com.shipofharkinian.soh");
|
||||
return fpath;
|
||||
#endif
|
||||
|
||||
return ".";
|
||||
|
||||
}
|
||||
|
||||
std::string GlobalCtx2::GetPathRelativeToAppDirectory(const char* path) {
|
||||
return GlobalCtx2::GetAppDirectoryPath() + "/" + path;
|
||||
}
|
||||
|
||||
GlobalCtx2::GlobalCtx2(std::string Name) : Name(std::move(Name)) {
|
||||
|
||||
}
|
||||
|
||||
GlobalCtx2::~GlobalCtx2() {
|
||||
SPDLOG_INFO("destruct GlobalCtx2");
|
||||
INSTANCE->Exit();
|
||||
}
|
||||
|
||||
void GlobalCtx2::InitWindow() {
|
||||
InitLogging();
|
||||
Config = std::make_shared<Mercury>(GetPathRelativeToAppDirectory("shipofharkinian.json"));
|
||||
Config->reload();
|
||||
|
||||
MainPath = Config->getString("Game.Main Archive", GetPathRelativeToAppDirectory("oot.otr"));
|
||||
PatchesPath = Config->getString("Game.Patches Archive", GetAppDirectoryPath() + "/mods");
|
||||
|
||||
ResMan = std::make_shared<ResourceMgr>(GetInstance(), MainPath, PatchesPath);
|
||||
Win = std::make_shared<Window>(GetInstance());
|
||||
|
||||
if (!ResMan->DidLoadSuccessfully())
|
||||
{
|
||||
#ifdef _WIN32
|
||||
MessageBox(nullptr, L"Main OTR file not found!", L"Uh oh", MB_OK);
|
||||
#else
|
||||
SPDLOG_ERROR("Main OTR file not found!");
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
INSTANCE = new ModManager(ResMan);
|
||||
INSTANCE->Init();
|
||||
}
|
||||
|
||||
void GlobalCtx2::InitLogging() {
|
||||
try {
|
||||
auto logPath = GetPathRelativeToAppDirectory(("logs/" + GetName() + ".log").c_str());
|
||||
|
||||
// Setup Logging
|
||||
spdlog::init_thread_pool(8192, 1);
|
||||
auto SohConsoleSink = std::make_shared<spdlog::sinks::soh_sink_mt>();
|
||||
auto ConsoleSink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||
auto FileSink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logPath, 1024 * 1024 * 10, 10);
|
||||
SohConsoleSink->set_level(spdlog::level::trace);
|
||||
ConsoleSink->set_level(spdlog::level::trace);
|
||||
FileSink->set_level(spdlog::level::trace);
|
||||
std::vector<spdlog::sink_ptr> Sinks{ ConsoleSink, FileSink, SohConsoleSink };
|
||||
Logger = std::make_shared<spdlog::async_logger>(GetName(), Sinks.begin(), Sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block);
|
||||
GetLogger()->set_level(spdlog::level::trace);
|
||||
GetLogger()->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%@] [%l] %v");
|
||||
spdlog::register_logger(GetLogger());
|
||||
spdlog::set_default_logger(GetLogger());
|
||||
}
|
||||
catch (const spdlog::spdlog_ex& ex) {
|
||||
std::cout << "Log initialization failed: " << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalCtx2::WriteSaveFile(const std::filesystem::path& savePath, const uintptr_t addr, void* dramAddr, const size_t size) {
|
||||
std::ofstream saveFile = std::ofstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
|
||||
saveFile.seekp(addr);
|
||||
saveFile.write((char*)dramAddr, size);
|
||||
saveFile.close();
|
||||
}
|
||||
|
||||
void GlobalCtx2::ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size) {
|
||||
std::ifstream saveFile = std::ifstream(savePath, std::fstream::in | std::fstream::out | std::fstream::binary);
|
||||
|
||||
// If the file doesn't exist, initialize DRAM
|
||||
if (saveFile.good()) {
|
||||
saveFile.seekg(addr);
|
||||
saveFile.read((char*)dramAddr, size);
|
||||
} else {
|
||||
memset(dramAddr, 0, size);
|
||||
}
|
||||
|
||||
saveFile.close();
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef GLOBAL_CTX_2
|
||||
#define GLOBAL_CTX_2
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "Lib/Mercury/Mercury.h"
|
||||
|
||||
namespace Ship {
|
||||
class ResourceMgr;
|
||||
class Window;
|
||||
|
||||
class GlobalCtx2 {
|
||||
public:
|
||||
static std::shared_ptr<GlobalCtx2> GetInstance();
|
||||
static std::shared_ptr<GlobalCtx2> CreateInstance(const std::string& Name);
|
||||
|
||||
std::string GetName() { return Name; }
|
||||
std::shared_ptr<Window> GetWindow() { return Win; }
|
||||
std::shared_ptr<ResourceMgr> GetResourceManager() { return ResMan; }
|
||||
std::shared_ptr<spdlog::logger> GetLogger() { return Logger; }
|
||||
std::shared_ptr<Mercury> GetConfig() { return Config; }
|
||||
|
||||
static std::string GetAppDirectoryPath();
|
||||
static std::string GetPathRelativeToAppDirectory(const char* path);
|
||||
|
||||
void WriteSaveFile(const std::filesystem::path& savePath, uintptr_t addr, void* dramAddr, size_t size);
|
||||
void ReadSaveFile(std::filesystem::path savePath, uintptr_t addr, void* dramAddr, size_t size);
|
||||
|
||||
GlobalCtx2(std::string Name);
|
||||
~GlobalCtx2();
|
||||
|
||||
protected:
|
||||
void InitWindow();
|
||||
void InitLogging();
|
||||
|
||||
private:
|
||||
static std::weak_ptr <GlobalCtx2> Context;
|
||||
std::shared_ptr<spdlog::logger> Logger;
|
||||
std::shared_ptr<Window> Win;
|
||||
std::shared_ptr<Mercury> Config; // Config needs to be after the Window because we call the Window during it's destructor.
|
||||
std::shared_ptr<ResourceMgr> ResMan;
|
||||
std::string Name;
|
||||
std::string MainPath;
|
||||
std::string PatchesPath;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,10 +1,5 @@
|
||||
#include "Hooks.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdarg.h>
|
||||
#include <iostream>
|
||||
|
||||
void ModInternal_ExecuteAudioInitHooks() {
|
||||
ModInternal::ExecuteHooks<ModInternal::AudioInit>();
|
||||
namespace Ship {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "UltraController.h"
|
||||
#include "Controller.h"
|
||||
|
||||
#define DEFINE_HOOK(name, type) struct name { typedef std::function<type> fn; }
|
||||
|
||||
namespace ModInternal {
|
||||
namespace Ship {
|
||||
class Controller;
|
||||
|
||||
template <typename H>
|
||||
struct RegisteredHooks {
|
||||
@@ -29,22 +26,11 @@ namespace ModInternal {
|
||||
}
|
||||
|
||||
DEFINE_HOOK(ControllerRead, void(OSContPad* cont_pad));
|
||||
DEFINE_HOOK(ControllerRawInput, void(Ship::Controller* backend, uint32_t raw));
|
||||
DEFINE_HOOK(ControllerRawInput, void(Controller* backend, uint32_t raw));
|
||||
DEFINE_HOOK(AudioInit, void());
|
||||
DEFINE_HOOK(LoadTexture, void(const char* path, uint8_t** texture));
|
||||
DEFINE_HOOK(GfxInit, void());
|
||||
DEFINE_HOOK(ExitGame, void());
|
||||
|
||||
DEFINE_HOOK(LoadFile, void(uint32_t fileNum));
|
||||
DEFINE_HOOK(DeleteFile, void(uint32_t fileNum));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void ModInternal_ExecuteAudioInitHooks();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user