Browse Source

git subrepo clone https://github.com/HarbourMasters/libultraship.git

subrepo:
  subdir:   "libultraship"
  merged:   "a484cda98"
upstream:
  origin:   "https://github.com/HarbourMasters/libultraship.git"
  branch:   "main"
  commit:   "a484cda98"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
pull/1/head
M4xw 7 months ago
parent
commit
d24c8453db
  1. 356
      libultraship/.gitignore
  2. 12
      libultraship/.gitrepo
  3. 9
      libultraship/LICENSE
  4. 28
      libultraship/Makefile
  5. 29
      libultraship/TestApp/Main.cpp
  6. BIN
      libultraship/TestApp/StormLibDUS.lib
  7. 152
      libultraship/TestApp/TestApp.vcxproj
  8. 22
      libultraship/TestApp/TestApp.vcxproj.filters
  9. 64
      libultraship/libultraship.sln
  10. 72
      libultraship/libultraship/Animation.cpp
  11. 63
      libultraship/libultraship/Animation.h
  12. 357
      libultraship/libultraship/Archive.cpp
  13. 55
      libultraship/libultraship/Archive.h
  14. 61
      libultraship/libultraship/Array.cpp
  15. 85
      libultraship/libultraship/Array.h
  16. 15
      libultraship/libultraship/AudioPlayer.h
  17. 18
      libultraship/libultraship/Blob.cpp
  18. 19
      libultraship/libultraship/Blob.h
  19. 99
      libultraship/libultraship/CollisionHeader.cpp
  20. 85
      libultraship/libultraship/CollisionHeader.h
  21. 159
      libultraship/libultraship/ConfigFile.cpp
  22. 37
      libultraship/libultraship/ConfigFile.h
  23. 96
      libultraship/libultraship/Controller.cpp
  24. 45
      libultraship/libultraship/Controller.h
  25. 5
      libultraship/libultraship/ControllerAttachment.cpp
  26. 8
      libultraship/libultraship/ControllerAttachment.h
  27. 21
      libultraship/libultraship/Cutscene.cpp
  28. 28
      libultraship/libultraship/Cutscene.h
  29. 100
      libultraship/libultraship/Cvar.cpp
  30. 49
      libultraship/libultraship/Cvar.h
  31. 31
      libultraship/libultraship/DisplayList.cpp
  32. 23
      libultraship/libultraship/DisplayList.h
  33. 15
      libultraship/libultraship/Environment.cpp
  34. 8
      libultraship/libultraship/Environment.h
  35. 25
      libultraship/libultraship/Factories/AnimationFactory.cpp
  36. 11
      libultraship/libultraship/Factories/AnimationFactory.h
  37. 25
      libultraship/libultraship/Factories/ArrayFactory.cpp
  38. 11
      libultraship/libultraship/Factories/ArrayFactory.h
  39. 26
      libultraship/libultraship/Factories/BlobFactory.cpp
  40. 11
      libultraship/libultraship/Factories/BlobFactory.h
  41. 26
      libultraship/libultraship/Factories/CollisionHeaderFactory.cpp
  42. 11
      libultraship/libultraship/Factories/CollisionHeaderFactory.h
  43. 25
      libultraship/libultraship/Factories/CutsceneFactory.cpp
  44. 11
      libultraship/libultraship/Factories/CutsceneFactory.h
  45. 27
      libultraship/libultraship/Factories/DisplayListFactory.cpp
  46. 11
      libultraship/libultraship/Factories/DisplayListFactory.h
  47. 26
      libultraship/libultraship/Factories/MaterialFactory.cpp
  48. 11
      libultraship/libultraship/Factories/MaterialFactory.h
  49. 22
      libultraship/libultraship/Factories/MtxFactory.cpp
  50. 12
      libultraship/libultraship/Factories/MtxFactory.h
  51. 71
      libultraship/libultraship/Factories/OTRResourceLoader.cpp
  52. 25
      libultraship/libultraship/Factories/PathFactory.cpp
  53. 11
      libultraship/libultraship/Factories/PathFactory.h
  54. 27
      libultraship/libultraship/Factories/PlayerAnimationFactory.cpp
  55. 11
      libultraship/libultraship/Factories/PlayerAnimationFactory.h
  56. 105
      libultraship/libultraship/Factories/ResourceLoader.cpp
  57. 11
      libultraship/libultraship/Factories/ResourceLoader.h
  58. 26
      libultraship/libultraship/Factories/SceneFactory.cpp
  59. 11
      libultraship/libultraship/Factories/SceneFactory.h
  60. 26
      libultraship/libultraship/Factories/SkeletonFactory.cpp
  61. 11
      libultraship/libultraship/Factories/SkeletonFactory.h
  62. 26
      libultraship/libultraship/Factories/SkeletonLimbFactory.cpp
  63. 11
      libultraship/libultraship/Factories/SkeletonLimbFactory.h
  64. 26
      libultraship/libultraship/Factories/TextFactory.cpp
  65. 11
      libultraship/libultraship/Factories/TextFactory.h
  66. 26
      libultraship/libultraship/Factories/TextureFactory.cpp
  67. 11
      libultraship/libultraship/Factories/TextureFactory.h
  68. 22
      libultraship/libultraship/Factories/VtxFactory.cpp
  69. 12
      libultraship/libultraship/Factories/VtxFactory.h
  70. 1
      libultraship/libultraship/File.cpp
  71. 22
      libultraship/libultraship/File.h
  72. 133
      libultraship/libultraship/GameSettings.cpp
  73. 56
      libultraship/libultraship/GameSettings.h
  74. 85
      libultraship/libultraship/GlobalCtx2.cpp
  75. 41
      libultraship/libultraship/GlobalCtx2.h
  76. 56
      libultraship/libultraship/KeyboardController.cpp
  77. 23
      libultraship/libultraship/KeyboardController.h
  78. 3
      libultraship/libultraship/LUSMacros.h
  79. 12
      libultraship/libultraship/Lib/Fast3D/.gitrepo
  80. 19
      libultraship/libultraship/Lib/Fast3D/LICENSE.txt
  81. 33
      libultraship/libultraship/Lib/Fast3D/README.md
  82. 491
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/abi.h
  83. 177
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/controller.h
  84. 18
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/convert.h
  85. 45
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/exception.h
  86. 4637
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gbi.h
  87. 379
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gs2dex.h
  88. 8
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/gu.h
  89. 90
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/hardware.h
  90. 24
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/internal.h
  91. 6
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/interrupt.h
  92. 44
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/mbi.h
  93. 39
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/message.h
  94. 15
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/motor.h
  95. 137
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pfs.h
  96. 83
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/pi.h
  97. 33
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/printf.h
  98. 367
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/r4300.h
  99. 95
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rcp.h
  100. 51
      libultraship/libultraship/Lib/Fast3D/U64/PR/ultra64/rdp.h
  101. Some files were not shown because too many files have changed in this diff Show More

356
libultraship/.gitignore vendored

@ -0,0 +1,356 @@ @@ -0,0 +1,356 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
!otrlib/Lib/SDL/lib/x64
!otrlib/Lib/SDL/lib/x86
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
!libultraship/Lib/**
libultraship/DebugObj/*

12
libultraship/.gitrepo

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = https://github.com/HarbourMasters/libultraship.git
branch = main
commit = a484cda9802ed9c39b29e11a703fd0997f42a6af
parent = 39cc86c2608e2f75ace33fc7f43bc4f2ad743f1a
method = rebase
cmdver = 0.4.1

9
libultraship/LICENSE

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
Copyright (c) 2022 Harbour Masters
MIT License
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.

28
libultraship/Makefile

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
# Only used for standalone compilation, usually inherits these from the main makefile
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 := otrlib.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) -I ./ -I ../ZAPD/ZAPD -I ../ZAPD/ZAPDUtils -I ../../ZAPD/lib/tinyxml2 -I otrlib/Lib/spdlog/include -c $(OUTPUT_OPTION) $<
$(LIB): $(O_FILES)
$(AR) rcs $@ $^

29
libultraship/TestApp/Main.cpp

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
#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;
}

BIN
libultraship/TestApp/StormLibDUS.lib

Binary file not shown.

152
libultraship/TestApp/TestApp.vcxproj

@ -0,0 +1,152 @@ @@ -0,0 +1,152 @@
<?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>

22
libultraship/TestApp/TestApp.vcxproj.filters

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
<?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>

64
libultraship/libultraship.sln

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@

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

72
libultraship/libultraship/Animation.cpp

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
#include "Animation.h"
void Ship::AnimationV0::ParseFileBinary(BinaryReader* reader, Resource* res)
{
Animation* anim = (Animation*)res;
ResourceFile::ParseFileBinary(reader, res);
AnimationType animType = (AnimationType)reader->ReadUInt32();
anim->type = animType;
if (animType == AnimationType::Normal)
{
anim->frameCount = reader->ReadInt16();
uint32_t rotValuesCnt = reader->ReadUInt32();
anim->rotationValues.reserve(rotValuesCnt);
for (uint32_t i = 0; i < rotValuesCnt; i++)
anim->rotationValues.push_back(reader->ReadUInt16());
uint32_t rotIndCnt = reader->ReadUInt32();
anim->rotationIndices.reserve(rotIndCnt);
for (int i = 0; i < rotIndCnt; i++)
{
uint16_t x = reader->ReadUInt16();
uint16_t y = reader->ReadUInt16();
uint16_t z = reader->ReadUInt16();
anim->rotationIndices.push_back(RotationIndex(x, y, z));
}
anim->limit = reader->ReadInt16();
}
else if (animType == AnimationType::Curve)
{
anim->frameCount = reader->ReadInt16();
uint32_t refArrCnt = reader->ReadUInt32();
anim->refIndexArr.reserve(refArrCnt);
for (uint32_t i = 0; i < refArrCnt; i++)
anim->refIndexArr.push_back(reader->ReadUByte());
uint32_t transformDataCnt = reader->ReadUInt32();
anim->transformDataArr.reserve(transformDataCnt);
for (uint32_t i = 0; i < transformDataCnt; i++)
{
TransformData data;
data.unk_00 = reader->ReadUInt16();
data.unk_02 = reader->ReadInt16();
data.unk_04 = reader->ReadInt16();
data.unk_06 = reader->ReadInt16();
data.unk_08 = reader->ReadSingle();
anim->transformDataArr.push_back(data);
}
uint32_t copyValuesCnt = reader->ReadUInt32();
anim->copyValuesArr.reserve(copyValuesCnt);
for (uint32_t i = 0; i < copyValuesCnt; i++)
{
anim->copyValuesArr.push_back(reader->ReadInt16());
}
}
else if (animType == AnimationType::Link)
{
anim->frameCount = reader->ReadInt16();
anim->segPtr = reader->ReadUInt32();
}
else if (animType == AnimationType::Legacy)
{
SPDLOG_DEBUG("BEYTAH ANIMATION?!");
}
}

63
libultraship/libultraship/Animation.h

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
#pragma once
#include "Resource.h"
namespace Ship
{
enum class AnimationType
{
Normal = 0,
Link = 1,
Curve = 2,
Legacy = 3,
};
struct RotationIndex
{
uint16_t x, y, z;
RotationIndex(uint16_t nX, uint16_t nY, uint16_t nZ) : x(nX), y(nY), z(nZ) {}
};
class TransformData
{
public:
///* 0x0000 */ u16 unk_00; // appears to be flags
uint16_t unk_00;
///* 0x0002 */ s16 unk_02;
int16_t unk_02;
///* 0x0004 */ s16 unk_04;
int16_t unk_04;
///* 0x0006 */ s16 unk_06;
int16_t unk_06;
///* 0x0008 */ f32 unk_08;
float unk_08;
};
class AnimationV0 : public ResourceFile
{
public:
void ParseFileBinary(BinaryReader* reader, Resource* res) override;
};
class Animation : public Resource
{
public:
AnimationType type;
int16_t frameCount;
// NORMAL
std::vector<uint16_t> rotationValues;
std::vector<RotationIndex> rotationIndices;
int16_t limit = 0;
// CURVE
std::vector<uint8_t> refIndexArr;
std::vector<TransformData> transformDataArr;
std::vector<int16_t> copyValuesArr;
// LINK
uint32_t segPtr; // This is temp
};
}

357
libultraship/libultraship/Archive.cpp

@ -0,0 +1,357 @@ @@ -0,0 +1,357 @@
#include "Archive.h"
#include "Resource.h"
#include "File.h"
#include "spdlog/spdlog.h"
#include "Utils/StringHelper.h"
#include "Lib/StrHash64.h"
#include <filesystem>
namespace Ship {
Archive::Archive(const std::string& MainPath, bool enableWriting) : Archive(MainPath, "", enableWriting)
{
mainMPQ = nullptr;
}
Archive::Archive(const std::string& MainPath, const std::string& PatchesPath, bool enableWriting, bool genCRCMap) : MainPath(MainPath), PatchesPath(PatchesPath) {
mainMPQ = nullptr;
Load(enableWriting, genCRCMap);
}
Archive::~Archive() {
Unload();
}
bool Archive::IsMainMPQValid()
{
return mainMPQ != nullptr;
}
std::shared_ptr<Archive> Archive::CreateArchive(const std::string& archivePath, int fileCapacity)
{
Archive* archive = new Archive(archivePath, true);
TCHAR* t_filename = new TCHAR[archivePath.size() + 1];
t_filename[archivePath.size()] = 0;
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();
if (success) {
archive->mpqHandles[archivePath] = archive->mainMPQ;
return std::make_shared<Archive>(*archive);
} else {
SPDLOG_ERROR("({}) We tried to create an archive, but it has fallen and cannot get up.");
return nullptr;
}
}
std::shared_ptr<File> Archive::LoadFile(const std::string& filePath, bool includeParent, std::shared_ptr<File> FileToLoad) {
HANDLE fileHandle = NULL;
if (!SFileOpenFileEx(mainMPQ, filePath.c_str(), 0, &fileHandle)) {
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 nullptr;
}
DWORD dwFileSize = SFileGetFileSize(fileHandle, 0);
std::shared_ptr<char[]> fileData(new char[dwFileSize]);
DWORD dwBytes;
if (!SFileReadFile(fileHandle, fileData.get(), dwFileSize, &dwBytes, NULL)) {
SPDLOG_ERROR("({}) Failed to read file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
if (!SFileCloseFile(fileHandle)) {
SPDLOG_ERROR("({}) Failed to close file {} from mpq after read failure in archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
}
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
FileToLoad->bHasLoadError = true;
return nullptr;
}
if (!SFileCloseFile(fileHandle)) {
SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
}
if (FileToLoad == nullptr) {
FileToLoad = std::make_shared<File>();
FileToLoad->path = filePath;
}
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
FileToLoad->parent = includeParent ? shared_from_this() : nullptr;
FileToLoad->buffer = fileData;
FileToLoad->dwBufferSize = dwFileSize;
FileToLoad->bIsLoaded = true;
return FileToLoad;
}
std::shared_ptr<File> Archive::LoadPatchFile(const std::string& filePath, bool includeParent, std::shared_ptr<File> FileToLoad) {
HANDLE fileHandle = NULL;
HANDLE mpqHandle = NULL;
for(auto [path, handle] : mpqHandles) {
if (SFileOpenFileEx(mpqHandle, filePath.c_str(), 0, &fileHandle)) {
std::unique_lock Lock(FileToLoad->FileLoadMutex);
FileToLoad->bHasLoadError = false;
mpqHandle = handle;
}
}
if(!mpqHandle) {
FileToLoad->bHasLoadError = true;
return FileToLoad;
}
DWORD dwFileSize = SFileGetFileSize(fileHandle, 0);
std::shared_ptr<char[]> fileData(new char[dwFileSize]);
DWORD dwBytes;
if (!SFileReadFile(fileHandle, fileData.get(), dwFileSize, &dwBytes, NULL)) {
SPDLOG_ERROR("({}) Failed to read file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
if (!SFileCloseFile(fileHandle)) {
SPDLOG_ERROR("({}) Failed to close file {} from mpq after read failure in archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
}
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
FileToLoad->bHasLoadError = true;
return nullptr;
}
if (!SFileCloseFile(fileHandle)) {
SPDLOG_ERROR("({}) Failed to close file {} from mpq archive {}", GetLastError(), filePath.c_str(), MainPath.c_str());
}
if (FileToLoad == nullptr) {
FileToLoad = std::make_shared<File>();
FileToLoad->path = filePath;
}
std::unique_lock<std::mutex> Lock(FileToLoad->FileLoadMutex);
FileToLoad->parent = includeParent ? shared_from_this() : nullptr;
FileToLoad->buffer = fileData;
FileToLoad->dwBufferSize = dwFileSize;
FileToLoad->bIsLoaded = true;
return FileToLoad;
}
bool Archive::AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize) {
HANDLE hFile;
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
FILETIME t;
SystemTimeToFileTime(&sysTime, &t);
ULONGLONG stupidHack = static_cast<uint64_t>(t.dwHighDateTime) << (sizeof(t.dwHighDateTime) * 8) | t.dwLowDateTime;
if (!SFileCreateFile(mainMPQ, path.c_str(), stupidHack, dwFileSize, 0, MPQ_FILE_COMPRESS, &hFile)) {
SPDLOG_ERROR("({}) Failed to create file of {} bytes {} in archive {}", GetLastError(), dwFileSize, path.c_str(), MainPath.c_str());
return false;
}
if (!SFileWriteFile(hFile, (void*)fileData, dwFileSize, MPQ_COMPRESSION_ZLIB)) {
SPDLOG_ERROR("({}) Failed to write {} bytes to {} in archive {}", GetLastError(), dwFileSize, path.c_str(), MainPath.c_str());
if (!SFileCloseFile(hFile)) {
SPDLOG_ERROR("({}) Failed to close file {} after write failure in archive {}", GetLastError(), path.c_str(), MainPath.c_str());
}
return false;
}
if (!SFileFinishFile(hFile)) {
SPDLOG_ERROR("({}) Failed to finish file {} in archive {}", GetLastError(), path.c_str(), MainPath.c_str());
if (!SFileCloseFile(hFile)) {
SPDLOG_ERROR("({}) Failed to close file {} after finish failure in archive {}", GetLastError(), path.c_str(), MainPath.c_str());
}
return false;
}
// SFileFinishFile already frees the handle, so no need to close it again.
addedFiles.push_back(path);
hashes[CRC64(path.c_str())] = path;
return true;
}
bool Archive::RemoveFile(const std::string& path) {
// TODO: Notify the resource manager and child Files
if (!SFileRemoveFile(mainMPQ, path.c_str(), 0)) {
SPDLOG_ERROR("({}) Failed to remove file {} in archive {}", GetLastError(), path.c_str(), MainPath.c_str());
return false;
}
return true;
}
bool Archive::RenameFile(const std::string& oldPath, const std::string& newPath) {
// TODO: Notify the resource manager and child Files
if (!SFileRenameFile(mainMPQ, oldPath.c_str(), newPath.c_str())) {
SPDLOG_ERROR("({}) Failed to rename file {} to {} in archive {}", GetLastError(), oldPath.c_str(), newPath.c_str(), MainPath.c_str());
return false;
}
return true;
}
std::vector<SFILE_FIND_DATA> Archive::ListFiles(const std::string& searchMask) {
auto fileList = std::vector<SFILE_FIND_DATA>();
SFILE_FIND_DATA findContext;
HANDLE hFind;
hFind = SFileFindFirstFile(mainMPQ, searchMask.c_str(), &findContext, nullptr);
//if (hFind && GetLastError() != ERROR_NO_MORE_FILES) {
if (hFind != nullptr) {
fileList.push_back(findContext);
bool fileFound;
do {
fileFound = SFileFindNextFile(hFind, &findContext);
if (fileFound) {
fileList.push_back(findContext);
}
else if (!fileFound && GetLastError() != ERROR_NO_MORE_FILES)
//else if (!fileFound)
{
SPDLOG_ERROR("({}), Failed to search with mask {} in archive {}", GetLastError(), searchMask.c_str(), MainPath.c_str());
if (!SListFileFindClose(hFind)) {
SPDLOG_ERROR("({}) Failed to close file search {} after failure in archive {}", GetLastError(), searchMask.c_str(), MainPath.c_str());
}
return fileList;
}
} while (fileFound);
}
else if (GetLastError() != ERROR_NO_MORE_FILES) {
SPDLOG_ERROR("({}), Failed to search with mask {} in archive {}", GetLastError(), searchMask.c_str(), MainPath.c_str());
return fileList;
}
if (hFind != nullptr)
{
if (!SFileFindClose(hFind)) {
SPDLOG_ERROR("({}) Failed to close file search {} in archive {}", GetLastError(), searchMask.c_str(), MainPath.c_str());
}
}
return fileList;
}
bool Archive::HasFile(const std::string& filename) {
bool result = false;
auto start = std::chrono::steady_clock::now();
auto lst = ListFiles(filename);
for (const auto& item : lst) {
if (item.cFileName == filename) {
result = true;
break;
}
}
auto end = std::chrono::steady_clock::now();
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
return result;
}
std::string Archive::HashToString(uint64_t hash) {
return hashes[hash];
}
bool Archive::Load(bool enableWriting, bool genCRCMap) {
return LoadMainMPQ(enableWriting, genCRCMap) && LoadPatchMPQs();
}
bool Archive::Unload()
{
bool success = true;
for (const auto& mpqHandle : mpqHandles) {
if (!SFileCloseArchive(mpqHandle.second)) {
SPDLOG_ERROR("({}) Failed to close mpq {}", GetLastError(), mpqHandle.first.c_str());
success = false;
}
}
mainMPQ = nullptr;
return success;
}
bool Archive::LoadPatchMPQs() {
// OTRTODO: We also want to periodically scan the patch directories for new MPQs. When new MPQs are found we will load the contents to fileCache and then copy over to gameResourceAddresses
if (PatchesPath.length() > 0) {
if (std::filesystem::is_directory(PatchesPath)) {
for (const auto& p : std::filesystem::recursive_directory_iterator(PatchesPath)) {
if (StringHelper::IEquals(p.path().extension().string(), ".otr") || StringHelper::IEquals(p.path().extension().string(), ".mpq")) {
SPDLOG_ERROR("Reading {} mpq patch", p.path().string().c_str());
if (!LoadPatchMPQ(p.path().string())) {
return false;
}
}
}
}
}
return true;
}
bool Archive::LoadMainMPQ(bool enableWriting, bool genCRCMap) {
HANDLE mpqHandle = NULL;
std::string fullPath = std::filesystem::absolute(MainPath).string();
std::wstring wFileName = std::filesystem::absolute(MainPath).wstring();
if (!SFileOpenArchive(wFileName.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle)) {
SPDLOG_ERROR("({}) Failed to open main mpq file {}.", GetLastError(), fullPath.c_str());
return false;
}
mpqHandles[fullPath] = mpqHandle;
mainMPQ = mpqHandle;
if (genCRCMap) {
auto listFile = LoadFile("(listfile)", false);
std::vector<std::string> lines = StringHelper::Split(std::string(listFile->buffer.get(), listFile->dwBufferSize), "\n");
for (size_t i = 0; i < lines.size(); i++) {
std::string line = StringHelper::Strip(lines[i], "\r");
//uint64_t hash = StringHelper::StrToL(lines[i], 16);
uint64_t hash = CRC64(line.c_str());
hashes[hash] = line;
}
}
return true;
}
bool Archive::LoadPatchMPQ(const std::string& path) {
HANDLE patchHandle = NULL;
std::string fullPath = std::filesystem::absolute(path).string();
if (mpqHandles.contains(fullPath)) {
return true;
}
std::wstring wPath = std::filesystem::absolute(path).wstring();
if (!SFileOpenArchive(wPath.c_str(), 0, MPQ_OPEN_READ_ONLY, &patchHandle)) {
SPDLOG_ERROR("({}) Failed to open patch mpq file {} while applying to {}.", GetLastError(), path.c_str(), MainPath.c_str());
return false;
}
if (!SFileOpenPatchArchive(mainMPQ, wPath.c_str(), "", 0)) {
SPDLOG_ERROR("({}) Failed to apply patch mpq file {} to main mpq {}.", GetLastError(), path.c_str(), MainPath.c_str());
return false;
}
mpqHandles[fullPath] = patchHandle;
return true;
}
}

55
libultraship/libultraship/Archive.h

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
#pragma once
#undef _DLL
#include <string>
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
#include "Resource.h"
//#include "Lib/StrHash64.h"
#include "Lib/StormLib/StormLib.h"
namespace Ship
{
class File;
class Archive : public std::enable_shared_from_this<Archive>
{
public:
Archive(const std::string& MainPath, bool enableWriting);
Archive(const std::string& MainPath, const std::string& PatchesPath, bool enableWriting, bool genCRCMap = true);
~Archive();
bool IsMainMPQValid();
static std::shared_ptr<Archive> CreateArchive(const std::string& archivePath, int fileCapacity);
std::shared_ptr<File> LoadFile(const std::string& filePath, bool includeParent = true, std::shared_ptr<File> FileToLoad = nullptr);
std::shared_ptr<File> LoadPatchFile(const std::string& filePath, bool includeParent = true, std::shared_ptr<File> FileToLoad = nullptr);
bool AddFile(const std::string& path, uintptr_t fileData, DWORD dwFileSize);
bool RemoveFile(const std::string& path);
bool RenameFile(const std::string& oldPath, const std::string& newPath);
std::vector<SFILE_FIND_DATA> ListFiles(const std::string& searchMask);
bool HasFile(const std::string& searchMask);
std::string HashToString(uint64_t hash);
protected:
bool Load(bool enableWriting, bool genCRCMap);
bool Unload();
private:
std::string MainPath;
std::string PatchesPath;
std::map<std::string, HANDLE> mpqHandles;
std::vector<std::string> addedFiles;
std::map<uint64_t, std::string> hashes;
HANDLE mainMPQ;
bool LoadMainMPQ(bool enableWriting, bool genCRCMap);
bool LoadPatchMPQs();
bool LoadPatchMPQ(const std::string& path);
};
}

61
libultraship/libultraship/Array.cpp

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
#include "Array.h"
#include "Vertex.h"
namespace Ship
{
void ArrayV0::ParseFileBinary(BinaryReader* reader, Resource* res)
{
Array* arr = (Array*)res;
ResourceFile::ParseFileBinary(reader, res);
ZResourceType resType = (ZResourceType)reader->ReadUInt32();
uint32_t arrayCnt = reader->ReadUInt32();
for (uint32_t i = 0; i < arrayCnt; i++)
{
if (resType == ZResourceType::Vertex)
{
Vtx data;
data.x = reader->ReadInt16();
data.y = reader->ReadInt16();
data.z = reader->ReadInt16();
data.flag = reader->ReadUInt16();
data.s = reader->ReadInt16();
data.t = reader->ReadInt16();
data.r = reader->ReadUByte();
data.g = reader->ReadUByte();
data.b = reader->ReadUByte();
data.a = reader->ReadUByte();
arr->vertices.push_back(data);
}
else
{
ScalarType scalType = (ScalarType)reader->ReadUInt32();
int iter = 1;
if (resType == ZResourceType::Vector)
iter = reader->ReadUInt32();
for (int k = 0; k < iter; k++)
{
ScalarData data;
switch (scalType)
{
case ScalarType::ZSCALAR_S16:
data.s16 = reader->ReadInt16();
break;
case ScalarType::ZSCALAR_U16:
data.u16 = reader->ReadUInt16();
break;
// OTRTODO: IMPLEMENT OTHER TYPES!
}
arr->scalars.push_back(data);
}
}
}
}
}

85
libultraship/libultraship/Array.h

@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
#pragma once
#include "Resource.h"
#include "Vertex.h"
namespace Ship
{
typedef union ScalarData
{
uint8_t u8;
int8_t s8;
uint16_t u16;
int16_t s16;
uint32_t u32;
int32_t s32;
uint64_t u64;
int64_t s64;
float f32;
double f64;
} ScalarData;
enum class ScalarType
{
ZSCALAR_NONE,
ZSCALAR_S8,
ZSCALAR_U8,
ZSCALAR_X8,
ZSCALAR_S16,
ZSCALAR_U16,
ZSCALAR_X16,
ZSCALAR_S32,
ZSCALAR_U32,
ZSCALAR_X32,
ZSCALAR_S64,
ZSCALAR_U64,
ZSCALAR_X64,
ZSCALAR_F32,
ZSCALAR_F64
};
// OTRTODO: Replace this with something that can be shared between the exporter and importer...
enum class ZResourceType
{
Error,
Animation,
Array,
AltHeader,
Background,
Blob,
CollisionHeader,
Cutscene,
DisplayList,
Limb,
LimbTable,
Mtx,
Path,
PlayerAnimationData,
Room,
RoomCommand,
Scalar,
Scene,
Skeleton,
String,
Symbol,
Texture,
TextureAnimation,
TextureAnimationParams,
Vector,
Vertex,
};
class ArrayV0 : public ResourceFile
{
public:
void ParseFileBinary(BinaryReader* reader, Resource* res) override;
};
class Array : public Resource
{
public:
std::vector<ScalarData> scalars;
std::vector<Vtx> vertices;
};
}

15
libultraship/libultraship/AudioPlayer.h

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
#pragma once
#include "stdint.h"
namespace Ship {
class AudioPlayer {
public:
AudioPlayer() { };
virtual bool Init(void) = 0;
virtual int Buffered(void) = 0;
virtual int GetDesiredBuffered(void) = 0;
virtual void Play(const uint8_t* buf, uint32_t len) = 0;
};
}

18
libultraship/libultraship/Blob.cpp

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
#include "Blob.h"
namespace Ship
{
void BlobV0::ParseFileBinary(BinaryReader* reader, Resource* res)
{
Blob* blob = (Blob*)res;
ResourceFile::ParseFileBinary(reader, blob);
uint32_t dataSize = reader->ReadUInt32();
blob->data.reserve(dataSize);
for (uint32_t i = 0; i < dataSize; i++)