Compare commits
33 Commits
8e71f570c4
...
6632149f42
| Author | SHA1 | Date | |
|---|---|---|---|
| 6632149f42 | |||
|
|
2eaaa87b72 | ||
|
|
c005d19fa8 | ||
|
|
b5595d9855 | ||
|
|
aef7c2657d | ||
|
|
ecd897b4ac | ||
|
|
2eb0ee39fb | ||
|
|
130814d206 | ||
|
|
0576fb5bd4 | ||
|
|
298d5e9848 | ||
|
|
3ac572edeb | ||
|
|
ac33cd4524 | ||
|
|
ea39199201 | ||
|
|
b204858a90 | ||
|
|
f3427e77ba | ||
|
|
7b0fe25650 | ||
|
|
af82d9a78a | ||
|
|
3e311e5aec | ||
|
|
95349eaa5b | ||
|
|
22062c2a6e | ||
|
|
72846f4733 | ||
|
|
c056b45184 | ||
|
|
9dd0bd9897 | ||
|
|
4dd68a06e8 | ||
|
|
db9165295f | ||
|
|
8fe0e02e64 | ||
|
|
20964df102 | ||
|
|
2495fbfdef | ||
|
|
6e7a83d473 | ||
|
|
87cbdeeefc | ||
|
|
a90f1017f7 | ||
|
|
588d03ad8f | ||
|
|
b58561eb78 |
@ -4,3 +4,7 @@ SUBDIRS += libs \
|
|||||||
app \
|
app \
|
||||||
tools \
|
tools \
|
||||||
tests
|
tests
|
||||||
|
|
||||||
|
tests.depends = libs
|
||||||
|
app.depends = libs
|
||||||
|
tools.depends = libs
|
||||||
|
|||||||
@ -1,625 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE QtCreatorProject>
|
|
||||||
<!-- Written by QtCreator 15.0.0, 2025-04-04T21:57:41. -->
|
|
||||||
<qtcreator>
|
|
||||||
<data>
|
|
||||||
<variable>EnvironmentId</variable>
|
|
||||||
<value type="QByteArray">{40d992cb-ac11-4385-a22b-016f1b4251a7}</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
|
||||||
<value type="qlonglong">0</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
|
||||||
<value type="QString" key="language">Cpp</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
|
||||||
<value type="QString" key="language">QmlJS</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
|
|
||||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
|
|
||||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
|
||||||
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
|
||||||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
|
|
||||||
<value type="bool" key="AutoTest.Framework.Boost">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.CTest">false</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.Catch">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.GTest">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="bool" key="AutoTest.ApplyFilter">false</value>
|
|
||||||
<valuemap type="QVariantMap" key="AutoTest.CheckStates">
|
|
||||||
<value type="Qt::CheckState" key="1@G:/Projects/Qt/XPlor/tests/autotest_cod.h:AutoTest_COD">Unchecked</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
|
|
||||||
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
|
||||||
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
|
||||||
<valuemap type="QVariantMap" key="ClangTools">
|
|
||||||
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
|
||||||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
|
||||||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
|
||||||
<value type="int" key="ClangTools.ParallelJobs">16</value>
|
|
||||||
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
|
||||||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="CppEditor.QuickFix">
|
|
||||||
<value type="bool" key="UseGlobalSettings">true</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="QString" key="DeviceType">Desktop</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.8.2 MSVC2022 64bit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.8.2 MSVC2022 64bit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.682.win64_msvc2022_64_kit</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
|
||||||
<value type="int" key="EnableQmlDebugging">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_MSVC2022_64bit-Debug</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Debug</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_MSVC2022_64bit-Release</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Release</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
|
||||||
<value type="int" key="QtQuickCompiler">0</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
|
||||||
<value type="int" key="EnableQmlDebugging">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_MSVC2022_64bit-Profile</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Profile</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
|
||||||
<value type="int" key="QtQuickCompiler">0</value>
|
|
||||||
<value type="int" key="SeparateDebugInfo">0</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">G:/Projects/Qt/XPlor/app/app.pro</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Debug/app</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">G:/Projects/Qt/XPlor/tests/tests.pro</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_MSVC2022_64bit-Debug/tests</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Target.1</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="QString" key="DeviceType">Desktop</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.8.2 llvm-mingw 64-bit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.8.2 llvm-mingw 64-bit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.682.win64_llvm_mingw_kit</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
|
||||||
<value type="int" key="EnableQmlDebugging">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_llvm_mingw_64_bit-Debug</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_llvm_mingw_64_bit-Debug</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_llvm_mingw_64_bit-Release</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_llvm_mingw_64_bit-Release</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
|
||||||
<value type="int" key="QtQuickCompiler">0</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
|
||||||
<value type="int" key="EnableQmlDebugging">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_2_llvm_mingw_64_bit-Profile</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_2_llvm_mingw_64_bit-Profile</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
|
||||||
<value type="int" key="QtQuickCompiler">0</value>
|
|
||||||
<value type="int" key="SeparateDebugInfo">0</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">G:/Projects/Qt/XPlor/app/app.pro</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">G:/Projects/Qt/XPlor/tests/tests.pro</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Target.2</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="QString" key="DeviceType">Desktop</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 6.8.1 MSVC2022 64bit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 6.8.1 MSVC2022 64bit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt6.681.win64_msvc2022_64_kit</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
|
||||||
<value type="int" key="EnableQmlDebugging">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Debug</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Debug</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">G:\Projects\Qt\XPlor\build\Desktop_Qt_6_8_1_MSVC2022_64bit-Release</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Release</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
|
||||||
<value type="int" key="QtQuickCompiler">0</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">G:/Projects/Qt/XPlor/app/app.pro</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Debug/app</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">G:/Projects/Qt/XPlor/tests/tests.pro</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">G:/Projects/Qt/XPlor/build/Desktop_Qt_6_8_1_MSVC2022_64bit-Debug/tests</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
|
||||||
<value type="qlonglong">3</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
|
||||||
<value type="int">22</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Version</variable>
|
|
||||||
<value type="int">22</value>
|
|
||||||
</data>
|
|
||||||
</qtcreator>
|
|
||||||
16
app/app.pro
@ -19,6 +19,8 @@ SOURCES += \
|
|||||||
preferenceeditor.cpp \
|
preferenceeditor.cpp \
|
||||||
soundviewer.cpp \
|
soundviewer.cpp \
|
||||||
stringtableviewer.cpp \
|
stringtableviewer.cpp \
|
||||||
|
rumblegraphviewer.cpp \
|
||||||
|
rumblefileviewer.cpp \
|
||||||
techsetviewer.cpp \
|
techsetviewer.cpp \
|
||||||
xtreewidget.cpp \
|
xtreewidget.cpp \
|
||||||
xtreewidgetitem.cpp \
|
xtreewidgetitem.cpp \
|
||||||
@ -37,6 +39,8 @@ HEADERS += \
|
|||||||
preferenceeditor.h \
|
preferenceeditor.h \
|
||||||
soundviewer.h \
|
soundviewer.h \
|
||||||
stringtableviewer.h \
|
stringtableviewer.h \
|
||||||
|
rumblegraphviewer.h \
|
||||||
|
rumblefileviewer.h \
|
||||||
techsetviewer.h \
|
techsetviewer.h \
|
||||||
xtreewidget.h \
|
xtreewidget.h \
|
||||||
xtreewidgetitem.h \
|
xtreewidgetitem.h \
|
||||||
@ -55,21 +59,13 @@ FORMS += \
|
|||||||
preferenceeditor.ui \
|
preferenceeditor.ui \
|
||||||
soundviewer.ui \
|
soundviewer.ui \
|
||||||
stringtableviewer.ui \
|
stringtableviewer.ui \
|
||||||
|
rumblegraphviewer.ui \
|
||||||
|
rumblefileviewer.ui \
|
||||||
techsetviewer.ui \
|
techsetviewer.ui \
|
||||||
zonefileviewer.ui
|
zonefileviewer.ui
|
||||||
|
|
||||||
RESOURCES += ../data/data.qrc
|
RESOURCES += ../data/data.qrc
|
||||||
|
|
||||||
app.depends += \
|
|
||||||
libs/core \
|
|
||||||
libs/compression \
|
|
||||||
libs/encryption \
|
|
||||||
libs/fastfile \
|
|
||||||
libs/ddsfile \
|
|
||||||
libs/ipakfile \
|
|
||||||
libs/iwifile \
|
|
||||||
libs/zonefile
|
|
||||||
|
|
||||||
LIBS += \
|
LIBS += \
|
||||||
-L$$PWD/../third_party/devil_sdk/lib/ -lDevIL -lILU -lILUT \
|
-L$$PWD/../third_party/devil_sdk/lib/ -lDevIL -lILU -lILUT \
|
||||||
-L$$PWD/../third_party/zlib/lib/ -lzlib \
|
-L$$PWD/../third_party/zlib/lib/ -lzlib \
|
||||||
|
|||||||
@ -18,7 +18,7 @@ FastFileViewer::~FastFileViewer()
|
|||||||
void FastFileViewer::SetFastFile(std::shared_ptr<FastFile> aFastFile) {
|
void FastFileViewer::SetFastFile(std::shared_ptr<FastFile> aFastFile) {
|
||||||
mFastFile.swap(aFastFile);
|
mFastFile.swap(aFastFile);
|
||||||
|
|
||||||
ui->label_Title->setText(mFastFile->GetStem() + ".ff");
|
ui->label_Title->setText(mFastFile->GetStem());
|
||||||
ui->comboBox_Company->setCurrentIndex(mFastFile->GetCompany());
|
ui->comboBox_Company->setCurrentIndex(mFastFile->GetCompany());
|
||||||
ui->comboBox_FileType->setCurrentIndex(mFastFile->GetType());
|
ui->comboBox_FileType->setCurrentIndex(mFastFile->GetType());
|
||||||
ui->checkBox_Signed->setChecked(mFastFile->GetSignage() == SIGNAGE_SIGNED);
|
ui->checkBox_Signed->setChecked(mFastFile->GetSignage() == SIGNAGE_SIGNED);
|
||||||
|
|||||||
@ -10,6 +10,7 @@ LocalStringViewer::LocalStringViewer(QWidget *parent)
|
|||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
ui->tableWidget_Strings->setColumnCount(2);
|
ui->tableWidget_Strings->setColumnCount(2);
|
||||||
|
ui->tableWidget_Strings->setRowCount(0);
|
||||||
ui->tableWidget_Strings->setColumnWidth(0, 200);
|
ui->tableWidget_Strings->setColumnWidth(0, 200);
|
||||||
ui->tableWidget_Strings->horizontalHeader()->setStretchLastSection(true);
|
ui->tableWidget_Strings->horizontalHeader()->setStretchLastSection(true);
|
||||||
}
|
}
|
||||||
@ -37,10 +38,12 @@ void LocalStringViewer::SetFileNotes(const QString aFileNotes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LocalStringViewer::AddLocalString(LocalString aLocalString) {
|
void LocalStringViewer::AddLocalString(LocalString aLocalString) {
|
||||||
mLocalStrings << aLocalString;
|
mLocalStrings.append(aLocalString);
|
||||||
|
|
||||||
ui->tableWidget_Strings->setRowCount(mLocalStrings.size());
|
ui->tableWidget_Strings->setRowCount(mLocalStrings.size());
|
||||||
|
|
||||||
|
ui->groupBox_LocalStrViewer->setTitle(QString("Entries (%1)").arg(mLocalStrings.size()));
|
||||||
|
|
||||||
QTableWidgetItem *aliasItem = new QTableWidgetItem(aLocalString.alias);
|
QTableWidgetItem *aliasItem = new QTableWidgetItem(aLocalString.alias);
|
||||||
QTableWidgetItem *stringItem = new QTableWidgetItem(aLocalString.string);
|
QTableWidgetItem *stringItem = new QTableWidgetItem(aLocalString.string);
|
||||||
|
|
||||||
@ -53,7 +56,7 @@ void LocalStringViewer::SetZoneFile(std::shared_ptr<ZoneFile> aZoneFile) {
|
|||||||
ui->tableWidget_Strings->clear();
|
ui->tableWidget_Strings->clear();
|
||||||
|
|
||||||
ui->label_Title->setText(aZoneFile->GetStem().section('.', 0, 0) + ".str");
|
ui->label_Title->setText(aZoneFile->GetStem().section('.', 0, 0) + ".str");
|
||||||
for (LocalString localStr : aZoneFile->GetAssetMap().localStrings) {
|
for (const LocalString &localStr : aZoneFile->GetAssetMap().localStrings) {
|
||||||
AddLocalString(localStr);
|
AddLocalString(localStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -142,7 +142,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_LocalStrViewer">
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>400</width>
|
<width>400</width>
|
||||||
|
|||||||
@ -1,13 +1,19 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "aboutdialog.h"
|
#include "aboutdialog.h"
|
||||||
#include "fastfile.h"
|
#include "fastfile.h"
|
||||||
|
#include "highlighter_gsc.h"
|
||||||
|
#include "highlighter_cfg.h"
|
||||||
|
#include "highlighter_shock.h"
|
||||||
|
#include "highlighter_rumble.h"
|
||||||
#include "materialviewer.h"
|
#include "materialviewer.h"
|
||||||
#include "preferenceeditor.h"
|
#include "preferenceeditor.h"
|
||||||
|
#include "rumblefileviewer.h"
|
||||||
|
#include "rumblegraphviewer.h"
|
||||||
#include "soundviewer.h"
|
#include "soundviewer.h"
|
||||||
#include "stringtableviewer.h"
|
#include "stringtableviewer.h"
|
||||||
#include "techsetviewer.h"
|
#include "techsetviewer.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
#include "compression.h"
|
#include "fastfile_factory.h"
|
||||||
#include "iwifile.h"
|
#include "iwifile.h"
|
||||||
#include "ddsfile.h"
|
#include "ddsfile.h"
|
||||||
#include "statusbarmanager.h"
|
#include "statusbarmanager.h"
|
||||||
@ -143,9 +149,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
});
|
});
|
||||||
|
|
||||||
connect(mTreeWidget, &XTreeWidget::RawFileSelected, this, [this](std::shared_ptr<RawFile> rawFile, const QString aParentName) {
|
connect(mTreeWidget, &XTreeWidget::RawFileSelected, this, [this](std::shared_ptr<RawFile> rawFile, const QString aParentName) {
|
||||||
QPlainTextEdit *scriptEditor = new QPlainTextEdit(this);
|
QTabWidget *rawTabWidget = new QTabWidget(this);
|
||||||
|
rawTabWidget->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
||||||
|
|
||||||
|
QPlainTextEdit *scriptEditor = new QPlainTextEdit(rawTabWidget);
|
||||||
scriptEditor->setAcceptDrops(false);
|
scriptEditor->setAcceptDrops(false);
|
||||||
scriptEditor->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
scriptEditor->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
||||||
|
scriptEditor->setFont(QFont("Consolas"));
|
||||||
|
|
||||||
if (rawFile->contents.isEmpty()) {
|
if (rawFile->contents.isEmpty()) {
|
||||||
scriptEditor->setPlainText("EMPTY");
|
scriptEditor->setPlainText("EMPTY");
|
||||||
@ -156,15 +166,52 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
QString fileStem = rawFile->path.split('/').last();
|
QString fileStem = rawFile->path.split('/').last();
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete scriptEditor;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QScrollArea *scrollArea = new QScrollArea(ui->tabWidget);
|
const int tabStopSpaces = 4;
|
||||||
scrollArea->layout()->addWidget(scriptEditor);
|
QFontMetrics metrics(scriptEditor->font());
|
||||||
|
scriptEditor->setTabStopDistance(tabStopSpaces * metrics.horizontalAdvance(' '));
|
||||||
|
|
||||||
ui->tabWidget->addTab(scrollArea, fileStem);
|
QSyntaxHighlighter *highlighter;
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_GSCFile.png"));
|
if (fileStem.contains(".gsc")) {
|
||||||
|
highlighter = new Highlighter_GSC(scriptEditor->document());
|
||||||
|
} else if (fileStem.contains(".cfg")) {
|
||||||
|
highlighter = new Highlighter_CFG(scriptEditor->document());
|
||||||
|
} else if (fileStem.contains(".rmb")) {
|
||||||
|
highlighter = new Highlighter_Rumble(scriptEditor->document());
|
||||||
|
|
||||||
|
RumbleGraphViewer *rmbGraphViewer = new RumbleGraphViewer(this);
|
||||||
|
rmbGraphViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
||||||
|
rmbGraphViewer->SetRumbleGraphFile(rawFile);
|
||||||
|
|
||||||
|
rawTabWidget->addTab(rmbGraphViewer, "UI Editor");
|
||||||
|
rawTabWidget->addTab(scriptEditor, "Text Editor");
|
||||||
|
|
||||||
|
ui->tabWidget->addTab(rawTabWidget, fileStem);
|
||||||
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_RUMBLE));
|
||||||
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
|
return;
|
||||||
|
} else if (fileStem.contains(".shock")) {
|
||||||
|
highlighter = new Highlighter_Shock(scriptEditor->document());
|
||||||
|
} else if (rawFile->contents.left(6) == "RUMBLE") {
|
||||||
|
RumbleFileViewer *rmbFileViewer = new RumbleFileViewer(this);
|
||||||
|
rmbFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
||||||
|
rmbFileViewer->SetRumbleFile(rawFile);
|
||||||
|
|
||||||
|
rawTabWidget->addTab(rmbFileViewer, "UI Editor");
|
||||||
|
rawTabWidget->addTab(scriptEditor, "Text Editor");
|
||||||
|
|
||||||
|
ui->tabWidget->addTab(rawTabWidget, fileStem);
|
||||||
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_RUMBLE));
|
||||||
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->tabWidget->addTab(scriptEditor, fileStem);
|
||||||
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_RAW_FILE));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -177,12 +224,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
QString fileStem = image->materialName;
|
QString fileStem = image->materialName;
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete mImageWidget;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tabWidget->addTab(mImageWidget, fileStem);
|
ui->tabWidget->addTab(mImageWidget, fileStem);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_Image.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_IMAGE));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -190,24 +238,6 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
Q_UNUSED(menu);
|
Q_UNUSED(menu);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(mTreeWidget, &XTreeWidget::DDSFileSelected, this, [this](std::shared_ptr<DDSFile> ddsFile, const QString aParentName) {
|
|
||||||
DDSViewer *ddsViewer = new DDSViewer(this);
|
|
||||||
ddsViewer->setAcceptDrops(false);
|
|
||||||
ddsViewer->SetDDSFile(ddsFile);
|
|
||||||
ddsViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
|
||||||
|
|
||||||
QString fileStem = ddsFile->fileStem + ".dds";
|
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->tabWidget->addTab(ddsViewer, fileStem);
|
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_DDSFile.png"));
|
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(mTreeWidget, &XTreeWidget::MaterialSelected, this, [this](std::shared_ptr<Material> material, const QString aParentName) {
|
connect(mTreeWidget, &XTreeWidget::MaterialSelected, this, [this](std::shared_ptr<Material> material, const QString aParentName) {
|
||||||
MaterialViewer *matViewer = new MaterialViewer(this);
|
MaterialViewer *matViewer = new MaterialViewer(this);
|
||||||
matViewer->setAcceptDrops(false);
|
matViewer->setAcceptDrops(false);
|
||||||
@ -217,12 +247,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
QString fileStem = material->name;
|
QString fileStem = material->name;
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete matViewer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tabWidget->addTab(matViewer, fileStem);
|
ui->tabWidget->addTab(matViewer, fileStem);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_Material.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_MATERIAL));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -235,12 +266,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
QString fileStem = ddsFile->fileStem + ".dds";
|
QString fileStem = ddsFile->fileStem + ".dds";
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete ddsViewer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tabWidget->addTab(ddsViewer, fileStem);
|
ui->tabWidget->addTab(ddsViewer, fileStem);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_DDSFile.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_IMAGE));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -253,12 +285,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
QString fileStem = iwiFile->fileStem + ".iwi";
|
QString fileStem = iwiFile->fileStem + ".iwi";
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete iwiViewer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tabWidget->addTab(iwiViewer, fileStem);
|
ui->tabWidget->addTab(iwiViewer, fileStem);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_IWIFile.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_IMAGE));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -268,15 +301,16 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
fastFileViewer->SetFastFile(aFastFile);
|
fastFileViewer->SetFastFile(aFastFile);
|
||||||
fastFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
fastFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
||||||
|
|
||||||
QString fileStem = aFastFile->GetStem() + ".ff";
|
QString fileStem = aFastFile->GetStem();
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete fastFileViewer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tabWidget->addTab(fastFileViewer, fileStem);
|
ui->tabWidget->addTab(fastFileViewer, fileStem);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_FastFile.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_FAST_FILE));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -286,9 +320,10 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
zoneFileViewer->SetZoneFile(aZoneFile);
|
zoneFileViewer->SetZoneFile(aZoneFile);
|
||||||
zoneFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
zoneFileViewer->setProperty("PARENT_NAME", QVariant::fromValue(aParentName));
|
||||||
|
|
||||||
QString fileStem = aZoneFile->GetStem() + ".zone";
|
QString fileStem = aZoneFile->GetBaseStem() + ".zone";
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete zoneFileViewer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,7 +341,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
scrollArea->setWidget(containerWidget);
|
scrollArea->setWidget(containerWidget);
|
||||||
|
|
||||||
ui->tabWidget->addTab(scrollArea, fileStem);
|
ui->tabWidget->addTab(scrollArea, fileStem);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_ZoneFile.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_ZONE_FILE));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -319,12 +354,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
QString fileStem = aZoneFile->GetStem() + ".str";
|
QString fileStem = aZoneFile->GetStem() + ".str";
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete localStrViewer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tabWidget->addTab(localStrViewer, fileStem);
|
ui->tabWidget->addTab(localStrViewer, fileStem);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_String.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_LOCAL_STRING));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -337,12 +373,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
QString fileStem = aTechSet->name;
|
QString fileStem = aTechSet->name;
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete techSetViewer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tabWidget->addTab(techSetViewer, aTechSet->name);
|
ui->tabWidget->addTab(techSetViewer, aTechSet->name);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_TechSetFile.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_TECH_SET));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -355,12 +392,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
QString fileStem = aStrTable->name;
|
QString fileStem = aStrTable->name;
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete strTableViewer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tabWidget->addTab(strTableViewer, fileStem);
|
ui->tabWidget->addTab(strTableViewer, fileStem);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_StringTable.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_STRING_TABLE));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -373,12 +411,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
QString fileStem = aSound->path.split('/').last();
|
QString fileStem = aSound->path.split('/').last();
|
||||||
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
for (int i = 0; i < ui->tabWidget->count(); i++) {
|
||||||
if (ui->tabWidget->tabText(i) == fileStem) {
|
if (ui->tabWidget->tabText(i) == fileStem) {
|
||||||
|
delete soundViewer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tabWidget->addTab(soundViewer, fileStem);
|
ui->tabWidget->addTab(soundViewer, fileStem);
|
||||||
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, QIcon(":/icons/icons/Icon_Sound.png"));
|
ui->tabWidget->setTabIcon(ui->tabWidget->count() - 1, ZoneFile::AssetTypeToIcon(ASSET_SOUND));
|
||||||
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -475,13 +514,13 @@ void MainWindow::Reset() {
|
|||||||
and opens the selected file.
|
and opens the selected file.
|
||||||
*/
|
*/
|
||||||
bool MainWindow::OpenFastFile(const QString aFastFilePath) {
|
bool MainWindow::OpenFastFile(const QString aFastFilePath) {
|
||||||
const QString fastFileStem = aFastFilePath.section("/", -1, -1).section('.', 0, 0);
|
const QString fastFileStem = aFastFilePath.section("/", -1, -1);
|
||||||
if (mTreeWidget->HasFastFile(fastFileStem)) {
|
if (mTreeWidget->HasFastFile(fastFileStem)) {
|
||||||
LogManager::instance().addError("Can't add duplicate file!");
|
LogManager::instance().addError("Can't add duplicate file!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FastFile> fastFile = FastFile::Open(aFastFilePath);
|
std::shared_ptr<FastFile> fastFile = FastFileFactory::Create(aFastFilePath);
|
||||||
fastFile->SetStem(fastFileStem);
|
fastFile->SetStem(fastFileStem);
|
||||||
mTreeWidget->AddFastFile(fastFile);
|
mTreeWidget->AddFastFile(fastFile);
|
||||||
|
|
||||||
|
|||||||
@ -20,18 +20,11 @@ void MaterialViewer::SetMaterial(std::shared_ptr<Material> aMaterial) {
|
|||||||
ui->lineEdit_Name->setText(aMaterial->name);
|
ui->lineEdit_Name->setText(aMaterial->name);
|
||||||
ui->lineEdit_RefPtr->setText(ToHexStr(aMaterial->refNamePtr));
|
ui->lineEdit_RefPtr->setText(ToHexStr(aMaterial->refNamePtr));
|
||||||
ui->lineEdit_RefName->setText(aMaterial->refName);
|
ui->lineEdit_RefName->setText(aMaterial->refName);
|
||||||
ui->lineEdit_Unknowns->setText(ToHexStr(aMaterial->unknownA[0])
|
QString unknownStr = "";
|
||||||
+ ToHexStr(aMaterial->unknownA[1])
|
foreach (quint32 unknownPtr, aMaterial->pointers) {
|
||||||
+ ToHexStr(aMaterial->unknownA[2])
|
unknownStr += ToHexStr(unknownPtr) + "\n";
|
||||||
+ ToHexStr(aMaterial->unknownA[3])
|
}
|
||||||
+ ToHexStr(aMaterial->unknownA[4])
|
ui->lineEdit_Unknowns->setText(unknownStr);
|
||||||
+ ToHexStr(aMaterial->unknownA[5])
|
|
||||||
+ ToHexStr(aMaterial->unknownA[6])
|
|
||||||
+ ToHexStr(aMaterial->unknownA[7])
|
|
||||||
+ ToHexStr(aMaterial->unknownA[8])
|
|
||||||
+ ToHexStr(aMaterial->unknownA[9])
|
|
||||||
+ ToHexStr(aMaterial->unknownA[10])
|
|
||||||
+ ToHexStr(aMaterial->unknownA[11]));
|
|
||||||
ui->lineEdit_StateA->setText(ToHexStr(aMaterial->stateBits[0]));
|
ui->lineEdit_StateA->setText(ToHexStr(aMaterial->stateBits[0]));
|
||||||
ui->lineEdit_StateA->setText(ToHexStr(aMaterial->stateBits[1]));
|
ui->lineEdit_StateA->setText(ToHexStr(aMaterial->stateBits[1]));
|
||||||
ui->spinBox_TextureCount->setValue(aMaterial->textureCount);
|
ui->spinBox_TextureCount->setValue(aMaterial->textureCount);
|
||||||
|
|||||||
58
app/rumblefileviewer.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include "rumblefileviewer.h"
|
||||||
|
#include "ui_rumblefileviewer.h"
|
||||||
|
|
||||||
|
RumbleFileViewer::RumbleFileViewer(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, ui(new Ui::RumbleFileViewer)
|
||||||
|
, mPropertyCount()
|
||||||
|
, mRumbleFile(nullptr) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->tableWidget_Properties->setColumnCount(2);
|
||||||
|
ui->tableWidget_Properties->setRowCount(0);
|
||||||
|
ui->tableWidget_Properties->setColumnWidth(0, 200);
|
||||||
|
ui->tableWidget_Properties->horizontalHeader()->setStretchLastSection(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RumbleFileViewer::~RumbleFileViewer() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RumbleFileViewer::SetRumbleFile(std::shared_ptr<RawFile> aRumbleFile) {
|
||||||
|
mRumbleFile = aRumbleFile;
|
||||||
|
|
||||||
|
ui->tableWidget_Properties->clear();
|
||||||
|
|
||||||
|
const QString magic = aRumbleFile->contents.left(6);
|
||||||
|
if (magic != "RUMBLE") {
|
||||||
|
qDebug() << "Rumble file has invalid magic: " << magic;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int firstIndex = 0;
|
||||||
|
int secondIndex = 0;
|
||||||
|
int thirdIndex = 0;
|
||||||
|
|
||||||
|
int startIndex = 0;
|
||||||
|
for (int i = 0; i < aRumbleFile->contents.count("\\") / 2; i++) {
|
||||||
|
ui->tableWidget_Properties->setRowCount(i + 1);
|
||||||
|
ui->spinBox_Entries->setValue(i + 1);
|
||||||
|
|
||||||
|
firstIndex = aRumbleFile->contents.indexOf("\\", startIndex);
|
||||||
|
secondIndex = aRumbleFile->contents.indexOf("\\", firstIndex + 1);
|
||||||
|
thirdIndex = aRumbleFile->contents.indexOf("\\", secondIndex + 1);
|
||||||
|
if (thirdIndex == -1) {
|
||||||
|
thirdIndex = aRumbleFile->contents.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString keyStr = aRumbleFile->contents.mid(firstIndex + 1, secondIndex - firstIndex - 1);
|
||||||
|
QTableWidgetItem *keyItem = new QTableWidgetItem(keyStr);
|
||||||
|
ui->tableWidget_Properties->setItem(i, 0, keyItem);
|
||||||
|
|
||||||
|
const QString valStr = aRumbleFile->contents.mid(secondIndex + 1, thirdIndex - secondIndex - 1);
|
||||||
|
QTableWidgetItem *valueItem = new QTableWidgetItem(valStr);
|
||||||
|
ui->tableWidget_Properties->setItem(i, 1, valueItem);
|
||||||
|
|
||||||
|
startIndex = thirdIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
app/rumblefileviewer.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef RUMBLEFILEVIEWER_H
|
||||||
|
#define RUMBLEFILEVIEWER_H
|
||||||
|
|
||||||
|
#include "asset_structs.h"
|
||||||
|
#include "zonefile.h"
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RumbleFileViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RumbleFileViewer : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RumbleFileViewer(QWidget *parent = nullptr);
|
||||||
|
~RumbleFileViewer();
|
||||||
|
|
||||||
|
void SetRumbleFile(std::shared_ptr<RawFile> aRumbleFile);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::RumbleFileViewer *ui;
|
||||||
|
quint32 mPropertyCount;
|
||||||
|
std::shared_ptr<RawFile> mRumbleFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RUMBLEFILEVIEWER_H
|
||||||
153
app/rumblefileviewer.ui
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>RumbleFileViewer</class>
|
||||||
|
<widget class="QWidget" name="RumbleFileViewer">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>841</width>
|
||||||
|
<height>457</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>841</width>
|
||||||
|
<height>457</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_Title">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
<pointsize>16</pointsize>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Rumble File Viewer</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>325</width>
|
||||||
|
<height>398</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>325</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Header</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="2" column="0" colspan="3">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" colspan="2">
|
||||||
|
<widget class="QSpinBox" name="spinBox_Entries">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Entries:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_LocalStrViewer">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>400</width>
|
||||||
|
<height>400</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Properties</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QTableWidget" name="tableWidget_Properties">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
54
app/rumblegraphviewer.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "rumblegraphviewer.h"
|
||||||
|
#include "ui_rumblegraphviewer.h"
|
||||||
|
|
||||||
|
RumbleGraphViewer::RumbleGraphViewer(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, ui(new Ui::RumbleGraphViewer),
|
||||||
|
mEntryCount(),
|
||||||
|
mRumbleGraphFile(nullptr) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->tableWidget_Entries->setColumnCount(2);
|
||||||
|
ui->tableWidget_Entries->setHorizontalHeaderLabels({ "X", "Y" });
|
||||||
|
ui->tableWidget_Entries->setRowCount(0);
|
||||||
|
ui->tableWidget_Entries->setColumnWidth(0, 200);
|
||||||
|
ui->tableWidget_Entries->horizontalHeader()->setStretchLastSection(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RumbleGraphViewer::~RumbleGraphViewer() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RumbleGraphViewer::SetRumbleGraphFile(const std::shared_ptr<RawFile> aRawFile) {
|
||||||
|
mRumbleGraphFile = aRawFile;
|
||||||
|
|
||||||
|
QDataStream rawFileStream(mRumbleGraphFile->contents.toLatin1());
|
||||||
|
|
||||||
|
QByteArray magic(15, Qt::Uninitialized);
|
||||||
|
rawFileStream.readRawData(magic.data(), 15);
|
||||||
|
|
||||||
|
rawFileStream.skipRawData(4);
|
||||||
|
|
||||||
|
char sectionChar;
|
||||||
|
rawFileStream >> sectionChar;
|
||||||
|
int sectionCount = sectionChar - '0';
|
||||||
|
ui->tableWidget_Entries->setRowCount(sectionCount);
|
||||||
|
ui->spinBox_Entries->setValue(sectionCount);
|
||||||
|
ui->groupBox_LocalStrViewer->setTitle(QString("Entries (%1)").arg(sectionCount));
|
||||||
|
|
||||||
|
rawFileStream.skipRawData(2);
|
||||||
|
|
||||||
|
for (int i = 0; i < sectionCount; i++) {
|
||||||
|
QByteArray xVal(6, Qt::Uninitialized), yVal(6, Qt::Uninitialized);
|
||||||
|
rawFileStream.readRawData(xVal.data(), 6);
|
||||||
|
rawFileStream.skipRawData(1);
|
||||||
|
rawFileStream.readRawData(yVal.data(), 6);
|
||||||
|
rawFileStream.skipRawData(2);
|
||||||
|
|
||||||
|
QTableWidgetItem *xItem = new QTableWidgetItem(xVal);
|
||||||
|
QTableWidgetItem *yItem = new QTableWidgetItem(yVal);
|
||||||
|
|
||||||
|
ui->tableWidget_Entries->setItem(i, 0, xItem);
|
||||||
|
ui->tableWidget_Entries->setItem(i, 1, yItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
app/rumblegraphviewer.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef RUMBLEGRAPHVIEWER_H
|
||||||
|
#define RUMBLEGRAPHVIEWER_H
|
||||||
|
|
||||||
|
#include "asset_structs.h"
|
||||||
|
#include "zonefile.h"
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RumbleGraphViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RumbleGraphViewer : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RumbleGraphViewer(QWidget *parent = nullptr);
|
||||||
|
~RumbleGraphViewer();
|
||||||
|
|
||||||
|
void SetEntryCount(quint32 aCount);
|
||||||
|
void SetRumbleGraphFile(const std::shared_ptr<RawFile> aRawFile);
|
||||||
|
void SetZoneFile(std::shared_ptr<ZoneFile> aZoneFile);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::RumbleGraphViewer *ui;
|
||||||
|
quint32 mEntryCount;
|
||||||
|
std::shared_ptr<RawFile> mRumbleGraphFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RUMBLEGRAPHVIEWER_H
|
||||||
153
app/rumblegraphviewer.ui
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>RumbleGraphViewer</class>
|
||||||
|
<widget class="QWidget" name="RumbleGraphViewer">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>841</width>
|
||||||
|
<height>457</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>841</width>
|
||||||
|
<height>457</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_Title">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
<pointsize>16</pointsize>
|
||||||
|
<bold>true</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Rumble Graph File </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>325</width>
|
||||||
|
<height>398</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>325</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Header</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Entry Count: </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" colspan="2">
|
||||||
|
<widget class="QSpinBox" name="spinBox_Entries">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="3">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_LocalStrViewer">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>400</width>
|
||||||
|
<height>400</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
<pointsize>9</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Entries</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QTableWidget" name="tableWidget_Entries">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@ -16,6 +16,7 @@ XTreeWidget::XTreeWidget(QWidget *parent)
|
|||||||
header()->hide();
|
header()->hide();
|
||||||
setMinimumWidth(350);
|
setMinimumWidth(350);
|
||||||
setSortingEnabled(true);
|
setSortingEnabled(true);
|
||||||
|
setIconSize(QSize(16, 16));
|
||||||
|
|
||||||
header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||||
|
|
||||||
@ -38,36 +39,44 @@ XTreeWidget::~XTreeWidget() {
|
|||||||
|
|
||||||
void XTreeWidget::AddFastFile(std::shared_ptr<FastFile> aFastFile) {
|
void XTreeWidget::AddFastFile(std::shared_ptr<FastFile> aFastFile) {
|
||||||
XTreeWidgetItem *fastFileItem = new XTreeWidgetItem(this);
|
XTreeWidgetItem *fastFileItem = new XTreeWidgetItem(this);
|
||||||
fastFileItem->setText(0, aFastFile->GetStem() + ".ff");
|
fastFileItem->setText(0, aFastFile->GetStem());
|
||||||
fastFileItem->setIcon(0, QIcon(":/icons/icons/Icon_FastFile.png"));
|
fastFileItem->setIcon(0, Utils::CreateAssetIcon("FF"));
|
||||||
if (aFastFile->GetPlatform() == "PC") {
|
if (aFastFile->GetPlatform() == "PC") {
|
||||||
fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_PC.png"));
|
fastFileItem->setIcon(1, Utils::CreateAssetIcon("PC"));
|
||||||
} else if (aFastFile->GetPlatform() == "360") {
|
} else if (aFastFile->GetPlatform() == "360") {
|
||||||
fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_Xbox.png"));
|
fastFileItem->setIcon(1, Utils::CreateAssetIcon("360"));
|
||||||
|
} else if (aFastFile->GetPlatform() == "PS3") {
|
||||||
|
fastFileItem->setIcon(1, Utils::CreateAssetIcon("PS3"));
|
||||||
} else if (aFastFile->GetPlatform() == "Wii") {
|
} else if (aFastFile->GetPlatform() == "Wii") {
|
||||||
fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_Wii.png"));
|
fastFileItem->setIcon(1, Utils::CreateAssetIcon("WII"));
|
||||||
} else if (aFastFile->GetPlatform() == "WiiU") {
|
} else if (aFastFile->GetPlatform() == "WiiU") {
|
||||||
fastFileItem->setIcon(1, QIcon(":/icons/icons/Icon_WiiU.png"));
|
fastFileItem->setIcon(1, Utils::CreateAssetIcon("WU"));
|
||||||
}
|
}
|
||||||
if (aFastFile->GetGame() == "COD2") {
|
if (aFastFile->GetGame() == "COD2") {
|
||||||
fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD2.png"));
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(2));
|
||||||
} if (aFastFile->GetGame() == "COD4") {
|
} if (aFastFile->GetGame() == "COD4") {
|
||||||
fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD4.png"));
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(4));
|
||||||
} else if (aFastFile->GetGame() == "COD5") {
|
} else if (aFastFile->GetGame() == "COD5") {
|
||||||
fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD5.png"));
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(5));
|
||||||
} else if (aFastFile->GetGame() == "COD6") {
|
} else if (aFastFile->GetGame() == "COD6") {
|
||||||
fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD6.png"));
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(6));
|
||||||
} else if (aFastFile->GetGame() == "COD7") {
|
} else if (aFastFile->GetGame() == "COD7") {
|
||||||
fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD7.png"));
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(7));
|
||||||
} else if (aFastFile->GetGame() == "COD8") {
|
} else if (aFastFile->GetGame() == "COD8") {
|
||||||
fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD8.png"));
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(8));
|
||||||
} else if (aFastFile->GetGame() == "COD9") {
|
} else if (aFastFile->GetGame() == "COD9") {
|
||||||
fastFileItem->setIcon(2, QIcon(":/icons/icons/Icon_COD9.png"));
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(9));
|
||||||
|
} else if (aFastFile->GetGame() == "COD10") {
|
||||||
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(10));
|
||||||
|
} else if (aFastFile->GetGame() == "COD11") {
|
||||||
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(11));
|
||||||
|
} else if (aFastFile->GetGame() == "COD12") {
|
||||||
|
fastFileItem->setIcon(2, Utils::CreateGameIcon(12));
|
||||||
}
|
}
|
||||||
|
|
||||||
AddZoneFile(aFastFile->GetZoneFile(), fastFileItem);
|
AddZoneFile(aFastFile->GetZoneFile(), fastFileItem);
|
||||||
|
|
||||||
mFastFiles[aFastFile->GetStem().section(".", 0, 0)] = aFastFile;
|
mFastFiles[aFastFile->GetStem()] = aFastFile;
|
||||||
|
|
||||||
resizeColumnToContents(1);
|
resizeColumnToContents(1);
|
||||||
setSortingEnabled(true);
|
setSortingEnabled(true);
|
||||||
@ -81,42 +90,52 @@ void XTreeWidget::AddZoneFile(std::shared_ptr<ZoneFile> aZoneFile, XTreeWidgetIt
|
|||||||
} else {
|
} else {
|
||||||
zoneItem = new XTreeWidgetItem(this);
|
zoneItem = new XTreeWidgetItem(this);
|
||||||
}
|
}
|
||||||
zoneItem->setIcon(0, QIcon(":/icons/icons/Icon_ZoneFile.png"));
|
zoneItem->setIcon(0, ZoneFile::AssetTypeToIcon(ASSET_ZONE_FILE));
|
||||||
zoneItem->setText(0, aZoneFile->GetStem() + ".zone");
|
zoneItem->setText(0, aZoneFile->GetBaseStem() + ".zone");
|
||||||
|
|
||||||
auto assetMap = aZoneFile->GetAssetMap();
|
auto assetMap = aZoneFile->GetAssetMap();
|
||||||
|
|
||||||
if (!assetMap.localStrings.isEmpty()) {
|
if (!assetMap.localStrings.isEmpty()) {
|
||||||
|
QIcon localStrIcon = ZoneFile::AssetTypeToIcon(ASSET_LOCAL_STRING);
|
||||||
|
|
||||||
XTreeWidgetItem *localStrRoot = new XTreeWidgetItem(zoneItem);
|
XTreeWidgetItem *localStrRoot = new XTreeWidgetItem(zoneItem);
|
||||||
localStrRoot->setText(0, "String Files");
|
localStrRoot->setText(0, "String Files");
|
||||||
localStrRoot->setIcon(0, QIcon(":/icons/icons/Icon_StringFile.png"));
|
localStrRoot->setIcon(0, localStrIcon);
|
||||||
|
localStrRoot->SetCategory(CATEGORY_TYPE);
|
||||||
|
|
||||||
XTreeWidgetItem *localStrItem = new XTreeWidgetItem(localStrRoot);
|
XTreeWidgetItem *localStrItem = new XTreeWidgetItem(localStrRoot);
|
||||||
localStrItem->setText(0, aZoneFile->GetStem().section('.', 0, 0) + ".str");
|
localStrItem->setText(0, aZoneFile->GetStem().section('.', 0, 0) + ".str");
|
||||||
localStrItem->setIcon(0, QIcon(":/icons/icons/Icon_StringFile.png"));
|
localStrItem->setIcon(0, localStrIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!assetMap.techSets.isEmpty()) {
|
if (!assetMap.techSets.isEmpty()) {
|
||||||
|
QIcon techSetIcon = ZoneFile::AssetTypeToIcon(ASSET_TECH_SET);
|
||||||
|
|
||||||
XTreeWidgetItem *techSetRoot = new XTreeWidgetItem(zoneItem);
|
XTreeWidgetItem *techSetRoot = new XTreeWidgetItem(zoneItem);
|
||||||
techSetRoot->setText(0, "Tech Sets");
|
techSetRoot->setText(0, "Tech Sets");
|
||||||
techSetRoot->setIcon(0, QIcon(":/icons/icons/Icon_TechSetFile.png"));
|
techSetRoot->setIcon(0, techSetIcon);
|
||||||
|
techSetRoot->SetCategory(CATEGORY_TYPE);
|
||||||
|
|
||||||
for (TechSet techSet : assetMap.techSets) {
|
for (TechSet techSet : assetMap.techSets) {
|
||||||
XTreeWidgetItem *techSetItem = new XTreeWidgetItem(techSetRoot);
|
XTreeWidgetItem *techSetItem = new XTreeWidgetItem(techSetRoot);
|
||||||
techSetItem->setText(0, techSet.name);
|
techSetItem->setText(0, techSet.name);
|
||||||
techSetItem->setIcon(0, QIcon(":/icons/icons/Icon_TechSetFile.png"));
|
techSetItem->setIcon(0, techSetIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!assetMap.rawFiles.isEmpty()) {
|
if (!assetMap.rawFiles.isEmpty()) {
|
||||||
|
QIcon rawFileIcon = ZoneFile::AssetTypeToIcon(ASSET_RAW_FILE);
|
||||||
|
|
||||||
XTreeWidgetItem *rawFileRoot = new XTreeWidgetItem(zoneItem);
|
XTreeWidgetItem *rawFileRoot = new XTreeWidgetItem(zoneItem);
|
||||||
rawFileRoot->setText(0, "Raw Files");
|
rawFileRoot->setText(0, "Raw Files");
|
||||||
rawFileRoot->setIcon(0, QIcon(":/icons/icons/Icon_GSCFile.png"));
|
rawFileRoot->setIcon(0, rawFileIcon);
|
||||||
|
rawFileRoot->SetCategory(CATEGORY_TYPE);
|
||||||
for (RawFile rawFile : assetMap.rawFiles) {
|
for (RawFile rawFile : assetMap.rawFiles) {
|
||||||
if (!rawFile.length) { continue; }
|
if (!rawFile.length) { continue; }
|
||||||
|
|
||||||
XTreeWidgetItem *tempItem = rawFileRoot;
|
XTreeWidgetItem *tempItem = rawFileRoot;
|
||||||
for (const QString &pathPart : rawFile.path.split('/')) {
|
const QStringList pathParts = rawFile.path.split('/');
|
||||||
|
for (const QString &pathPart : pathParts) {
|
||||||
bool childFound = false;
|
bool childFound = false;
|
||||||
for (int i = 0; i < tempItem->childCount(); i++) {
|
for (int i = 0; i < tempItem->childCount(); i++) {
|
||||||
QTreeWidgetItem *rawChildItem = tempItem->child(i);
|
QTreeWidgetItem *rawChildItem = tempItem->child(i);
|
||||||
@ -129,25 +148,30 @@ void XTreeWidget::AddZoneFile(std::shared_ptr<ZoneFile> aZoneFile, XTreeWidgetIt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pathPart.contains(".gsc")) {
|
const QString rawFileStr = QString("%1 [%2-%3]").arg(pathPart).arg(rawFile.startPos).arg(rawFile.endPos);
|
||||||
|
//rawFileStr = pathPart;
|
||||||
|
if (pathPart == pathParts.last()) {
|
||||||
XTreeWidgetItem *rawFileItem = new XTreeWidgetItem(tempItem);
|
XTreeWidgetItem *rawFileItem = new XTreeWidgetItem(tempItem);
|
||||||
rawFileItem->setText(0, pathPart);
|
rawFileItem->setText(0, rawFileStr);
|
||||||
|
|
||||||
tempItem = rawFileItem;
|
tempItem = rawFileItem;
|
||||||
} else if (!childFound) {
|
} else if (!childFound) {
|
||||||
tempItem = new XTreeWidgetItem(tempItem);
|
tempItem = new XTreeWidgetItem(tempItem);
|
||||||
tempItem->setText(0, pathPart);
|
tempItem->setText(0, rawFileStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
tempItem->setIcon(0, QIcon(":/icons/icons/Icon_GSCFile.png"));
|
tempItem->setIcon(0, rawFileIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!assetMap.menuFiles.isEmpty()) {
|
if (!assetMap.menuFiles.isEmpty()) {
|
||||||
|
QIcon menuFileIcon = ZoneFile::AssetTypeToIcon(ASSET_MENU);
|
||||||
|
|
||||||
XTreeWidgetItem *menuRoot = new XTreeWidgetItem(zoneItem);
|
XTreeWidgetItem *menuRoot = new XTreeWidgetItem(zoneItem);
|
||||||
menuRoot->setText(0, "Menu Files");
|
menuRoot->setText(0, "Menu Files");
|
||||||
menuRoot->setIcon(0, QIcon(":/icons/icons/Icon_MenuFile.png"));
|
menuRoot->setIcon(0, menuFileIcon);
|
||||||
|
menuRoot->SetCategory(CATEGORY_TYPE);
|
||||||
|
|
||||||
int menuIndex = 1;
|
int menuIndex = 1;
|
||||||
for (MenuFile menuFile : assetMap.menuFiles) {
|
for (MenuFile menuFile : assetMap.menuFiles) {
|
||||||
@ -155,65 +179,80 @@ void XTreeWidget::AddZoneFile(std::shared_ptr<ZoneFile> aZoneFile, XTreeWidgetIt
|
|||||||
menuFileRoot->setText(0, QString("Menu %1").arg(menuIndex));
|
menuFileRoot->setText(0, QString("Menu %1").arg(menuIndex));
|
||||||
for (Menu menu : menuFile.menuDefs) {
|
for (Menu menu : menuFile.menuDefs) {
|
||||||
XTreeWidgetItem *menuItem = new XTreeWidgetItem(menuFileRoot);
|
XTreeWidgetItem *menuItem = new XTreeWidgetItem(menuFileRoot);
|
||||||
menuItem->setText(0, menu.name);
|
menuItem->setText(0, menu.filePath);
|
||||||
menuItem->setIcon(0, QIcon(":/icons/icons/Icon_MenuFile.png"));
|
menuItem->setIcon(0, menuFileIcon);
|
||||||
}
|
}
|
||||||
menuIndex++;
|
menuIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!assetMap.images.isEmpty()) {
|
if (!assetMap.images.isEmpty()) {
|
||||||
|
QIcon imageIcon = ZoneFile::AssetTypeToIcon(ASSET_IMAGE);
|
||||||
|
|
||||||
XTreeWidgetItem *imageRoot = new XTreeWidgetItem(zoneItem);
|
XTreeWidgetItem *imageRoot = new XTreeWidgetItem(zoneItem);
|
||||||
imageRoot->setText(0, "Images");
|
imageRoot->setText(0, "Images");
|
||||||
imageRoot->setIcon(0, QIcon(":/icons/icons/Icon_Image.png"));
|
imageRoot->setIcon(0, imageIcon);
|
||||||
|
imageRoot->SetCategory(CATEGORY_TYPE);
|
||||||
|
|
||||||
for (Image image : assetMap.images) {
|
for (Image image : assetMap.images) {
|
||||||
XTreeWidgetItem *imageItem = new XTreeWidgetItem(imageRoot);
|
XTreeWidgetItem *imageItem = new XTreeWidgetItem(imageRoot);
|
||||||
imageItem->setText(0, image.materialName);
|
imageItem->setText(0, image.materialName);
|
||||||
imageItem->setIcon(0, QIcon(":/icons/icons/Icon_Image.png"));
|
imageItem->setIcon(0, imageIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!assetMap.models.isEmpty()) {
|
if (!assetMap.models.isEmpty()) {
|
||||||
|
QIcon modelIcon = ZoneFile::AssetTypeToIcon(ASSET_MODEL);
|
||||||
|
|
||||||
XTreeWidgetItem *modelsRoot = new XTreeWidgetItem(zoneItem);
|
XTreeWidgetItem *modelsRoot = new XTreeWidgetItem(zoneItem);
|
||||||
modelsRoot->setText(0, "Models");
|
modelsRoot->setText(0, "Models");
|
||||||
modelsRoot->setIcon(0, QIcon(":/icons/icons/Icon_Model.png"));
|
modelsRoot->setIcon(0, modelIcon);
|
||||||
|
modelsRoot->SetCategory(CATEGORY_TYPE);
|
||||||
|
|
||||||
for (Model model: assetMap.models) {
|
for (Model model: assetMap.models) {
|
||||||
XTreeWidgetItem *modelItem = new XTreeWidgetItem(modelsRoot);
|
XTreeWidgetItem *modelItem = new XTreeWidgetItem(modelsRoot);
|
||||||
modelItem->setText(0, model.modelName);
|
modelItem->setText(0, model.modelName);
|
||||||
modelItem->setIcon(0, QIcon(":/icons/icons/Icon_Model.png"));
|
modelItem->setIcon(0, modelIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!assetMap.materials.isEmpty()) {
|
if (!assetMap.materials.isEmpty()) {
|
||||||
|
QIcon materialIcon = ZoneFile::AssetTypeToIcon(ASSET_MATERIAL);
|
||||||
|
|
||||||
XTreeWidgetItem *materialsRoot = new XTreeWidgetItem(zoneItem);
|
XTreeWidgetItem *materialsRoot = new XTreeWidgetItem(zoneItem);
|
||||||
materialsRoot->setText(0, "Materials");
|
materialsRoot->setText(0, "Materials");
|
||||||
materialsRoot->setIcon(0, QIcon(":/icons/icons/Icon_Material.png"));
|
materialsRoot->setIcon(0, materialIcon);
|
||||||
|
materialsRoot->SetCategory(CATEGORY_TYPE);
|
||||||
|
|
||||||
for (Material material: assetMap.materials) {
|
for (Material material: assetMap.materials) {
|
||||||
XTreeWidgetItem *materialItem = new XTreeWidgetItem(materialsRoot);
|
XTreeWidgetItem *materialItem = new XTreeWidgetItem(materialsRoot);
|
||||||
materialItem->setText(0, material.name);
|
materialItem->setText(0, material.name);
|
||||||
materialItem->setIcon(0, QIcon(":/icons/icons/Icon_Material.png"));
|
materialItem->setIcon(0, materialIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!assetMap.stringTables.isEmpty()) {
|
if (!assetMap.stringTables.isEmpty()) {
|
||||||
|
QIcon stringTableIcon = ZoneFile::AssetTypeToIcon(ASSET_STRING_TABLE);
|
||||||
|
|
||||||
XTreeWidgetItem *strTableRoot = new XTreeWidgetItem(zoneItem);
|
XTreeWidgetItem *strTableRoot = new XTreeWidgetItem(zoneItem);
|
||||||
strTableRoot->setText(0, "String Tables");
|
strTableRoot->setText(0, "String Tables");
|
||||||
strTableRoot->setIcon(0, QIcon(":/icons/icons/Icon_StringTable.png"));
|
strTableRoot->setIcon(0, stringTableIcon);
|
||||||
|
strTableRoot->SetCategory(CATEGORY_TYPE);
|
||||||
|
|
||||||
for (StringTable strTable: assetMap.stringTables) {
|
for (StringTable strTable: assetMap.stringTables) {
|
||||||
XTreeWidgetItem *modelItem = new XTreeWidgetItem(strTableRoot);
|
XTreeWidgetItem *modelItem = new XTreeWidgetItem(strTableRoot);
|
||||||
modelItem->setText(0, strTable.name);
|
modelItem->setText(0, strTable.name);
|
||||||
modelItem->setIcon(0, QIcon(":/icons/icons/Icon_StringTable.png"));
|
modelItem->setIcon(0, stringTableIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!assetMap.sounds.isEmpty()) {
|
if (!assetMap.sounds.isEmpty()) {
|
||||||
|
QIcon soundIcon = ZoneFile::AssetTypeToIcon(ASSET_SOUND);
|
||||||
|
|
||||||
XTreeWidgetItem *soundsRoot = new XTreeWidgetItem(zoneItem);
|
XTreeWidgetItem *soundsRoot = new XTreeWidgetItem(zoneItem);
|
||||||
soundsRoot->setText(0, "Sounds");
|
soundsRoot->setText(0, "Sounds");
|
||||||
soundsRoot->setIcon(0, QIcon(":/icons/icons/Icon_Sound.png"));
|
soundsRoot->setIcon(0, soundIcon);
|
||||||
|
soundsRoot->SetCategory(CATEGORY_TYPE);
|
||||||
for (SoundAsset soundAsset : assetMap.sounds) {
|
for (SoundAsset soundAsset : assetMap.sounds) {
|
||||||
for (Sound sound : soundAsset.sounds) {
|
for (Sound sound : soundAsset.sounds) {
|
||||||
XTreeWidgetItem *tempItem = soundsRoot;
|
XTreeWidgetItem *tempItem = soundsRoot;
|
||||||
@ -245,16 +284,16 @@ void XTreeWidget::AddZoneFile(std::shared_ptr<ZoneFile> aZoneFile, XTreeWidgetIt
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
tempItem->setIcon(0, QIcon(":/icons/icons/Icon_Sound.png"));
|
tempItem->setIcon(0, soundIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mZoneFiles[aZoneFile->GetStem().section(".", 0, 0)] = aZoneFile;
|
mZoneFiles[aZoneFile->GetBaseStem() + ".zone"] = aZoneFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XTreeWidget::CloseFastFile(const QString aFFName) {
|
void XTreeWidget::CloseFastFile(const QString aFFName) {
|
||||||
const QString fileStem = aFFName.section(".", 0, 0);
|
const QString fileStem = aFFName;
|
||||||
emit ItemClosed(fileStem);
|
emit ItemClosed(fileStem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +394,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) {
|
|||||||
iwiFile->SaveJPG();
|
iwiFile->SaveJPG();
|
||||||
});
|
});
|
||||||
} else if (activeText.contains(".ff")) {
|
} else if (activeText.contains(".ff")) {
|
||||||
const QString fileStem = activeText.replace(".zone", "");
|
const QString fileStem = activeText;
|
||||||
|
|
||||||
QMenu *closeMultipleAction = new QMenu("Close Multiple Tabs");
|
QMenu *closeMultipleAction = new QMenu("Close Multiple Tabs");
|
||||||
|
|
||||||
@ -379,7 +418,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) {
|
|||||||
auto childItem = invisibleRootItem()->child(i);
|
auto childItem = invisibleRootItem()->child(i);
|
||||||
if (childItem == activeItem) { continue; }
|
if (childItem == activeItem) { continue; }
|
||||||
|
|
||||||
const QString fileStem = childItem->text(0).replace(".ff", "");
|
const QString fileStem = childItem->text(0);
|
||||||
if (!mFastFiles.contains(fileStem)) {
|
if (!mFastFiles.contains(fileStem)) {
|
||||||
qDebug() << "Error: Could not find " << fileStem << " in Fast File map!";
|
qDebug() << "Error: Could not find " << fileStem << " in Fast File map!";
|
||||||
return;
|
return;
|
||||||
@ -401,7 +440,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) {
|
|||||||
auto childItem = invisibleRootItem()->child(i);
|
auto childItem = invisibleRootItem()->child(i);
|
||||||
if (childItem == activeItem) { return; }
|
if (childItem == activeItem) { return; }
|
||||||
|
|
||||||
const QString fileStem = childItem->text(0).replace(".ff", "");
|
const QString fileStem = childItem->text(0);
|
||||||
if (!mFastFiles.contains(fileStem)) {
|
if (!mFastFiles.contains(fileStem)) {
|
||||||
qDebug() << "Error: Could not find " << fileStem << " in Fast File map!";
|
qDebug() << "Error: Could not find " << fileStem << " in Fast File map!";
|
||||||
return;
|
return;
|
||||||
@ -428,7 +467,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString fileStem = childItem->text(0).replace(".ff", "");
|
const QString fileStem = childItem->text(0);
|
||||||
if (!mFastFiles.contains(fileStem)) {
|
if (!mFastFiles.contains(fileStem)) {
|
||||||
qDebug() << "Error: Could not find " << fileStem << " in Fast File map!";
|
qDebug() << "Error: Could not find " << fileStem << " in Fast File map!";
|
||||||
return;
|
return;
|
||||||
@ -448,7 +487,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) {
|
|||||||
connect(closeAction, &QAction::triggered, this, [this, &activeItem, &activeText](bool checked) {
|
connect(closeAction, &QAction::triggered, this, [this, &activeItem, &activeText](bool checked) {
|
||||||
Q_UNUSED(checked);
|
Q_UNUSED(checked);
|
||||||
|
|
||||||
const QString fileStem = activeItem->text(0).replace(".ff", "");
|
const QString fileStem = activeItem->text(0);
|
||||||
|
|
||||||
mFastFiles.remove(fileStem);
|
mFastFiles.remove(fileStem);
|
||||||
CloseFastFile(activeText);
|
CloseFastFile(activeText);
|
||||||
@ -482,7 +521,7 @@ void XTreeWidget::PrepareContextMenu(const QPoint &pos) {
|
|||||||
fastFile->GetZoneFile()->SaveZoneFile(zoneFilePath);
|
fastFile->GetZoneFile()->SaveZoneFile(zoneFilePath);
|
||||||
});
|
});
|
||||||
} else if (activeText.contains(".zone")) {
|
} else if (activeText.contains(".zone")) {
|
||||||
const QString fileStem = activeText.replace(".zone", "");
|
const QString fileStem = activeText;
|
||||||
if (!mZoneFiles.contains(fileStem)) {
|
if (!mZoneFiles.contains(fileStem)) {
|
||||||
qDebug() << "Error: Could not find " << fileStem << " in Zone File map!";
|
qDebug() << "Error: Could not find " << fileStem << " in Zone File map!";
|
||||||
return;
|
return;
|
||||||
@ -612,63 +651,39 @@ void XTreeWidget::ItemSelectionChanged() {
|
|||||||
QString selectedText = selectedItem->text(0);
|
QString selectedText = selectedItem->text(0);
|
||||||
emit ItemSelected(selectedText);
|
emit ItemSelected(selectedText);
|
||||||
|
|
||||||
const QString fileStem = selectedText.section(".", 0, 0);
|
|
||||||
|
|
||||||
XTreeWidgetItem *parentItem = dynamic_cast<XTreeWidgetItem*>(selectedItem->parent());
|
XTreeWidgetItem *parentItem = dynamic_cast<XTreeWidgetItem*>(selectedItem->parent());
|
||||||
|
|
||||||
if (selectedText.contains(".dds")) {
|
if (selectedText.contains(".dds")) {
|
||||||
if (!mDDSFiles.contains(fileStem)) {
|
if (!mDDSFiles.contains(selectedText)) {
|
||||||
LogManager::instance().addError("Could not find " + fileStem + " in DDS map!");
|
LogManager::instance().addError("Could not find " + selectedText + " in DDS map!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::shared_ptr<DDSFile> ddsFile = mDDSFiles[fileStem];
|
std::shared_ptr<DDSFile> ddsFile = mDDSFiles[selectedText];
|
||||||
emit DDSFileSelected(ddsFile, fileStem);
|
emit DDSFileSelected(ddsFile, selectedText);
|
||||||
} else if (selectedText.contains(".iwi")) {
|
} else if (selectedText.contains(".iwi")) {
|
||||||
if (!mIWIFiles.contains(fileStem)) {
|
if (!mIWIFiles.contains(selectedText)) {
|
||||||
LogManager::instance().addError("Could not find " + fileStem + " in IWI map!");
|
LogManager::instance().addError("Could not find " + selectedText + " in IWI map!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit IWIFileSelected(mIWIFiles[fileStem], fileStem);
|
emit IWIFileSelected(mIWIFiles[selectedText], selectedText);
|
||||||
} else if (selectedText.contains(".ff")) {
|
} else if (selectedText.contains(".ff")) {
|
||||||
if (!mFastFiles.contains(fileStem)) {
|
if (!mFastFiles.contains(selectedText)) {
|
||||||
LogManager::instance().addError("Could not find " + fileStem + " in Fast File map!");
|
LogManager::instance().addError("Could not find " + selectedText + " in Fast File map!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit FastFileSelected(mFastFiles[fileStem], fileStem);
|
emit FastFileSelected(mFastFiles[selectedText], selectedText);
|
||||||
} else if (selectedText.contains(".zone")) {
|
} else if (selectedText.contains(".zone")) {
|
||||||
if (!mZoneFiles.contains(fileStem)) {
|
if (!mZoneFiles.contains(selectedText)) {
|
||||||
LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!");
|
LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit ZoneFileSelected(mZoneFiles[fileStem], fileStem);
|
emit ZoneFileSelected(mZoneFiles[selectedText], selectedText);
|
||||||
} else if (selectedText.contains(".str")) {
|
} else if (selectedText.contains(".str")) {
|
||||||
if (!mZoneFiles.contains(fileStem)) {
|
if (!mZoneFiles.contains(selectedText.replace(".str", ".zone"))) {
|
||||||
LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!");
|
LogManager::instance().addError("Could not find " + selectedText + " in Zone File map!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit LocalStringSelected(mZoneFiles[fileStem], fileStem);
|
emit LocalStringSelected(mZoneFiles[selectedText], selectedText);
|
||||||
} else if (selectedText.contains(".gsc")) {
|
|
||||||
XTreeWidgetItem *zoneRoot = selectedItem;
|
|
||||||
if (!zoneRoot) { return; }
|
|
||||||
|
|
||||||
while (!zoneRoot->text(0).contains(".zone")) {
|
|
||||||
zoneRoot = dynamic_cast<XTreeWidgetItem*>(zoneRoot->parent());
|
|
||||||
if (!zoneRoot) { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString fileStem = zoneRoot->text(0).section('.', 0, 0);
|
|
||||||
if (!mZoneFiles.contains(fileStem)) {
|
|
||||||
LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<RawFile> rawFiles = mZoneFiles[fileStem]->GetAssetMap().rawFiles;
|
|
||||||
for (RawFile rawFile : rawFiles) {
|
|
||||||
if (rawFile.path.contains(selectedText)) {
|
|
||||||
emit RawFileSelected(std::make_shared<RawFile>(rawFile), fileStem);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (parentItem && (parentItem->text(0) == "Images")) {
|
} else if (parentItem && (parentItem->text(0) == "Images")) {
|
||||||
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
|
XTreeWidgetItem *grandpaItem = dynamic_cast<XTreeWidgetItem*>(parentItem->parent());
|
||||||
if (grandpaItem && grandpaItem->text(0).contains(".zone")) {
|
if (grandpaItem && grandpaItem->text(0).contains(".zone")) {
|
||||||
@ -738,6 +753,32 @@ void XTreeWidget::ItemSelectionChanged() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (selectedItem->GetCategory() != CATEGORY_TYPE) {
|
||||||
|
XTreeWidgetItem *zoneRoot = selectedItem;
|
||||||
|
|
||||||
|
bool zoneChild = false;
|
||||||
|
while (zoneRoot) {
|
||||||
|
zoneRoot = dynamic_cast<XTreeWidgetItem*>(zoneRoot->parent());
|
||||||
|
if (zoneRoot->text(0).contains("Raw Files")) {
|
||||||
|
zoneChild = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!zoneChild) { return; }
|
||||||
|
const QString fileStem = zoneRoot->parent()->text(0);
|
||||||
|
|
||||||
|
if (!mZoneFiles.contains(fileStem)) {
|
||||||
|
LogManager::instance().addError("Could not find " + fileStem + " in Zone File map!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<RawFile> rawFiles = mZoneFiles[fileStem]->GetAssetMap().rawFiles;
|
||||||
|
for (RawFile rawFile : rawFiles) {
|
||||||
|
if (rawFile.path.split('/').last() == selectedText) {
|
||||||
|
emit RawFileSelected(std::make_shared<RawFile>(rawFile), fileStem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -778,7 +819,7 @@ void XTreeWidget::AddIWIFile(std::shared_ptr<IWIFile> aIWIFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
XTreeWidgetItem *iwiItem = new XTreeWidgetItem(this);
|
XTreeWidgetItem *iwiItem = new XTreeWidgetItem(this);
|
||||||
iwiItem->setIcon(0, QIcon(":/icons/icons/Icon_IWIFile.png"));
|
iwiItem->setIcon(0, ZoneFile::AssetTypeToIcon(ASSET_IMAGE));
|
||||||
iwiItem->setText(0, iwiFileName);
|
iwiItem->setText(0, iwiFileName);
|
||||||
mIWIFiles[aIWIFile->fileStem.section(".", 0, 0)] = aIWIFile;
|
mIWIFiles[aIWIFile->fileStem.section(".", 0, 0)] = aIWIFile;
|
||||||
}
|
}
|
||||||
@ -794,7 +835,7 @@ void XTreeWidget::AddDDSFile(std::shared_ptr<DDSFile> aDDSFile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
XTreeWidgetItem *ddsItem = new XTreeWidgetItem(this);
|
XTreeWidgetItem *ddsItem = new XTreeWidgetItem(this);
|
||||||
ddsItem->setIcon(0, QIcon(":/icons/icons/Icon_DDSFile.png"));
|
ddsItem->setIcon(0, ZoneFile::AssetTypeToIcon(ASSET_IMAGE));
|
||||||
ddsItem->setText(0, ddsFileName);
|
ddsItem->setText(0, ddsFileName);
|
||||||
mDDSFiles[aDDSFile->fileStem.section(".", 0, 0)] = aDDSFile;
|
mDDSFiles[aDDSFile->fileStem.section(".", 0, 0)] = aDDSFile;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,8 +8,10 @@
|
|||||||
#include "fastfile.h"
|
#include "fastfile.h"
|
||||||
#include "xtreewidgetitem.h"
|
#include "xtreewidgetitem.h"
|
||||||
#include "zonefile.h"
|
#include "zonefile.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
class XTreeWidget : public QTreeWidget
|
class XTreeWidget : public QTreeWidget
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,15 +1,29 @@
|
|||||||
#include "xtreewidgetitem.h"
|
#include "xtreewidgetitem.h"
|
||||||
|
|
||||||
XTreeWidgetItem::XTreeWidgetItem(QTreeWidget *parent, bool group)
|
XTreeWidgetItem::XTreeWidgetItem(QTreeWidget *parent, bool group)
|
||||||
: QTreeWidgetItem(parent), isGroup(group) {
|
: QTreeWidgetItem(parent)
|
||||||
|
, isGroup(group)
|
||||||
|
, mCategory(CATEGORY_NONE) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XTreeWidgetItem::XTreeWidgetItem(QTreeWidgetItem *parent, bool group)
|
XTreeWidgetItem::XTreeWidgetItem(QTreeWidgetItem *parent, bool group)
|
||||||
: QTreeWidgetItem(parent), isGroup(group) {
|
: QTreeWidgetItem(parent)
|
||||||
|
, isGroup(group)
|
||||||
|
, mCategory(CATEGORY_NONE) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XTreeWidgetItem::SetCategory(TREE_CATEGORY category)
|
||||||
|
{
|
||||||
|
mCategory = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
TREE_CATEGORY XTreeWidgetItem::GetCategory()
|
||||||
|
{
|
||||||
|
return mCategory;
|
||||||
|
}
|
||||||
|
|
||||||
bool XTreeWidgetItem::operator<(const QTreeWidgetItem &other) const {
|
bool XTreeWidgetItem::operator<(const QTreeWidgetItem &other) const {
|
||||||
// Attempt to cast the other item to our custom type.
|
// Attempt to cast the other item to our custom type.
|
||||||
const XTreeWidgetItem* otherItem = dynamic_cast<const XTreeWidgetItem*>(&other);
|
const XTreeWidgetItem* otherItem = dynamic_cast<const XTreeWidgetItem*>(&other);
|
||||||
|
|||||||
@ -4,6 +4,12 @@
|
|||||||
#include <QTreeWidget>
|
#include <QTreeWidget>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
|
|
||||||
|
enum TREE_CATEGORY {
|
||||||
|
CATEGORY_NONE = 0x00,
|
||||||
|
CATEGORY_FILE = 0x01,
|
||||||
|
CATEGORY_TYPE = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
// Custom item class
|
// Custom item class
|
||||||
class XTreeWidgetItem : public QTreeWidgetItem
|
class XTreeWidgetItem : public QTreeWidgetItem
|
||||||
{
|
{
|
||||||
@ -15,9 +21,15 @@ public:
|
|||||||
XTreeWidgetItem(QTreeWidget *parent, bool group = false);
|
XTreeWidgetItem(QTreeWidget *parent, bool group = false);
|
||||||
XTreeWidgetItem(QTreeWidgetItem *parent, bool group = false);
|
XTreeWidgetItem(QTreeWidgetItem *parent, bool group = false);
|
||||||
|
|
||||||
|
void SetCategory(TREE_CATEGORY category);
|
||||||
|
TREE_CATEGORY GetCategory();
|
||||||
|
|
||||||
// Override the less-than operator to customize sorting.
|
// Override the less-than operator to customize sorting.
|
||||||
bool operator<(const QTreeWidgetItem &other) const override;
|
bool operator<(const QTreeWidgetItem &other) const override;
|
||||||
XTreeWidgetItem &operator =(const XTreeWidgetItem &other);
|
XTreeWidgetItem &operator =(const XTreeWidgetItem &other);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TREE_CATEGORY mCategory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,34 +1,86 @@
|
|||||||
#include "zonefileviewer.h"
|
#include "zonefileviewer.h"
|
||||||
#include "ui_zonefileviewer.h"
|
#include "ui_zonefileviewer.h"
|
||||||
|
|
||||||
|
#include "statusbarmanager.h"
|
||||||
|
|
||||||
ZoneFileViewer::ZoneFileViewer(QWidget *parent)
|
ZoneFileViewer::ZoneFileViewer(QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, ui(new Ui::ZoneFileViewer) {
|
, ui(new Ui::ZoneFileViewer) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
aZoneFile = nullptr;
|
mZoneFile = nullptr;
|
||||||
|
|
||||||
ui->tableWidget_RecordCounts->setColumnCount(4);
|
ui->tableWidget_RecordCounts->setColumnCount(3);
|
||||||
ui->tableWidget_RecordCounts->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count", "Icon" });
|
ui->tableWidget_RecordCounts->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count" });
|
||||||
ui->tableWidget_RecordCounts->horizontalHeader()->setStretchLastSection(true);
|
ui->tableWidget_RecordCounts->horizontalHeader()->setStretchLastSection(true);
|
||||||
|
|
||||||
ui->tableWidget_RecordOrder->setColumnCount(4);
|
ui->tableWidget_RecordOrder->setColumnCount(3);
|
||||||
ui->tableWidget_RecordOrder->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count", "Icon" });
|
ui->tableWidget_RecordOrder->setHorizontalHeaderLabels({ "Identifier", "Asset", "Count" });
|
||||||
ui->tableWidget_RecordOrder->horizontalHeader()->setStretchLastSection(true);
|
ui->tableWidget_RecordOrder->horizontalHeader()->setStretchLastSection(true);
|
||||||
|
|
||||||
|
connect(ui->lineEdit_TagSearch, &QLineEdit::textChanged, this, &ZoneFileViewer::SortTags);
|
||||||
|
connect(ui->tableWidget_RecordCounts, &QTableWidget::itemSelectionChanged, this, &ZoneFileViewer::HighlightRecordInOrder);
|
||||||
|
connect(ui->listWidget_Tags, &QListWidget::currentTextChanged, this, [this](const QString &aCurrentText) {
|
||||||
|
StatusBarManager::instance().updateStatus(QString("Selected tag '%1' with index %2").arg(aCurrentText).arg(mZoneFile->GetTags().indexOf(aCurrentText)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneFileViewer::~ZoneFileViewer() {
|
ZoneFileViewer::~ZoneFileViewer() {
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZoneFileViewer::HighlightRecordInOrder() {
|
||||||
|
ui->tableWidget_RecordOrder->clearSelection();
|
||||||
|
|
||||||
|
foreach (auto selectedItem, ui->tableWidget_RecordCounts->selectedItems()) {
|
||||||
|
int selectedRow = selectedItem->row();
|
||||||
|
const QString assetId = ui->tableWidget_RecordCounts->item(selectedRow, 0)->text();
|
||||||
|
|
||||||
|
for (int i = 0; i < ui->tableWidget_RecordOrder->rowCount(); i++) {
|
||||||
|
const QString testAssetId = ui->tableWidget_RecordOrder->item(i, 0)->text();
|
||||||
|
if (testAssetId != assetId) { continue; }
|
||||||
|
|
||||||
|
ui->tableWidget_RecordOrder->selectRow(i);
|
||||||
|
ui->tableWidget_RecordOrder->item(i, 0)->setSelected(true);
|
||||||
|
ui->tableWidget_RecordOrder->item(i, 1)->setSelected(true);
|
||||||
|
ui->tableWidget_RecordOrder->item(i, 2)->setSelected(true);
|
||||||
|
ui->tableWidget_RecordOrder->item(i, 3)->setSelected(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneFileViewer::SortTags(const QString &aSearchText) {
|
||||||
|
ui->listWidget_Tags->clear();
|
||||||
|
|
||||||
|
const QStringList tags = mZoneFile->GetTags();
|
||||||
|
if (aSearchText.isEmpty()) {
|
||||||
|
ui->listWidget_Tags->addItems(tags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList sortedTags;
|
||||||
|
foreach (const QString tag, tags) {
|
||||||
|
if (tag.contains(aSearchText)) {
|
||||||
|
sortedTags << tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusBarManager::instance().updateStatus(QString("Found %1 tags.").arg(sortedTags.size()));
|
||||||
|
ui->listWidget_Tags->addItems(sortedTags);
|
||||||
|
}
|
||||||
|
|
||||||
void ZoneFileViewer::SetZoneFile(std::shared_ptr<ZoneFile> aZoneFile) {
|
void ZoneFileViewer::SetZoneFile(std::shared_ptr<ZoneFile> aZoneFile) {
|
||||||
|
mZoneFile = aZoneFile;
|
||||||
|
|
||||||
ui->tableWidget_RecordCounts->clearContents();
|
ui->tableWidget_RecordCounts->clearContents();
|
||||||
ui->tableWidget_RecordOrder->clearContents();
|
ui->tableWidget_RecordOrder->clearContents();
|
||||||
ui->listWidget_Tags->clear();
|
ui->listWidget_Tags->clear();
|
||||||
|
|
||||||
const QStringList tags = aZoneFile->GetTags();
|
const QStringList tags = mZoneFile->GetTags();
|
||||||
ui->listWidget_Tags->addItems(tags);
|
ui->listWidget_Tags->addItems(tags);
|
||||||
ui->label_Title->setText(aZoneFile->GetStem() + ".zone");
|
ui->label_Title->setText(mZoneFile->GetBaseStem() + ".zone");
|
||||||
|
|
||||||
|
ui->groupBox_Tags->setTitle(QString("Tags (%1)").arg(tags.size()));
|
||||||
|
|
||||||
if (tags.isEmpty()) {
|
if (tags.isEmpty()) {
|
||||||
ui->groupBox_Tags->hide();
|
ui->groupBox_Tags->hide();
|
||||||
@ -36,88 +88,67 @@ void ZoneFileViewer::SetZoneFile(std::shared_ptr<ZoneFile> aZoneFile) {
|
|||||||
ui->groupBox_Tags->show();
|
ui->groupBox_Tags->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString lastAsset = "";
|
|
||||||
QString lastRecord = "";
|
|
||||||
QIcon assetIcon;
|
|
||||||
int consecutiveCount = 1;
|
|
||||||
int consecutiveIndex = 0;
|
|
||||||
const QStringList records = aZoneFile->GetRecords();
|
|
||||||
QMap<QString, int> recordCounts = QMap<QString, int>();
|
QMap<QString, int> recordCounts = QMap<QString, int>();
|
||||||
for (const QString &record : records) {
|
QVector<QPair<QString, int>> assetOccurances = QVector<QPair<QString, int>>();
|
||||||
lastRecord = record;
|
for (const QString &record : mZoneFile->GetRecords()) {
|
||||||
if (record == "ffffffff") { break; }
|
|
||||||
if (!recordCounts.contains(record)) {
|
if (!recordCounts.contains(record)) {
|
||||||
recordCounts[record] = 0;
|
recordCounts[record] = 0;
|
||||||
}
|
}
|
||||||
recordCounts[record]++;
|
recordCounts[record]++;
|
||||||
|
|
||||||
QString assetType = aZoneFile->AssetTypeToString(record);
|
if (!assetOccurances.isEmpty() && assetOccurances.last().first == record) {
|
||||||
|
assetOccurances.last().second++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPair<QString, int> assetOccurance(record, 1);
|
||||||
|
assetOccurances << assetOccurance;
|
||||||
|
}
|
||||||
|
ui->tableWidget_RecordOrder->setRowCount(assetOccurances.size());
|
||||||
|
|
||||||
|
int assetIndex = 0;
|
||||||
|
foreach (auto assetOccurance, assetOccurances) {
|
||||||
|
const QString record = assetOccurance.first;
|
||||||
|
AssetType assetType = mZoneFile->AssetStrToEnum(record);
|
||||||
|
int assetCount = assetOccurance.second;
|
||||||
|
|
||||||
|
QIcon assetIcon = mZoneFile->AssetTypeToIcon(assetType);
|
||||||
if (assetIcon.isNull()) {
|
if (assetIcon.isNull()) {
|
||||||
qDebug() << "Icon is null for record: " << record;
|
qDebug() << "Icon is null for record: " << record;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastAsset.isEmpty()) {
|
QTableWidgetItem *recordItem = new QTableWidgetItem(record.toUpper());
|
||||||
lastAsset = assetType;
|
QTableWidgetItem *recordStrItem = new QTableWidgetItem(mZoneFile->AssetEnumToStr(assetType));
|
||||||
lastRecord = record;
|
QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(assetCount));
|
||||||
} else if (lastAsset == assetType) {
|
recordItem->setIcon(assetIcon);
|
||||||
consecutiveCount++;
|
|
||||||
} else {
|
|
||||||
ui->tableWidget_RecordOrder->setRowCount(consecutiveIndex + 1);
|
|
||||||
|
|
||||||
QTableWidgetItem *recordItem = new QTableWidgetItem(lastRecord.toUpper());
|
ui->tableWidget_RecordOrder->setItem(assetIndex, 0, recordItem);
|
||||||
QTableWidgetItem *recordStrItem = new QTableWidgetItem(lastAsset);
|
ui->tableWidget_RecordOrder->setItem(assetIndex, 1, recordStrItem);
|
||||||
QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(consecutiveCount));
|
ui->tableWidget_RecordOrder->setItem(assetIndex, 2, recordCountItem);
|
||||||
QTableWidgetItem *recordIconItem = new QTableWidgetItem();
|
|
||||||
assetIcon = aZoneFile->AssetStrToIcon(lastAsset);
|
|
||||||
recordIconItem->setIcon(assetIcon);
|
|
||||||
|
|
||||||
ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 0, recordItem);
|
assetIndex++;
|
||||||
ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 1, recordStrItem);
|
|
||||||
ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 2, recordCountItem);
|
|
||||||
ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 3, recordIconItem);
|
|
||||||
|
|
||||||
consecutiveCount = 1;
|
|
||||||
consecutiveIndex++;
|
|
||||||
lastAsset = assetType;
|
|
||||||
lastRecord = record;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ui->tableWidget_RecordOrder->setRowCount(consecutiveIndex + 1);
|
|
||||||
|
|
||||||
QTableWidgetItem *recordItem = new QTableWidgetItem(lastRecord.toUpper());
|
|
||||||
QTableWidgetItem *recordStrItem = new QTableWidgetItem(lastAsset);
|
|
||||||
QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(consecutiveCount));
|
|
||||||
QTableWidgetItem *recordIconItem = new QTableWidgetItem();
|
|
||||||
assetIcon = aZoneFile->AssetStrToIcon(lastAsset);
|
|
||||||
recordIconItem->setIcon(assetIcon);
|
|
||||||
|
|
||||||
ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 0, recordItem);
|
|
||||||
ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 1, recordStrItem);
|
|
||||||
ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 2, recordCountItem);
|
|
||||||
ui->tableWidget_RecordOrder->setItem(consecutiveIndex, 3, recordIconItem);
|
|
||||||
|
|
||||||
int recordIndex = 0;
|
int recordIndex = 0;
|
||||||
for (const QString &record : recordCounts.keys()) {
|
for (const QString &record : recordCounts.keys()) {
|
||||||
int recordCount = recordCounts[record];
|
int recordCount = recordCounts[record];
|
||||||
|
|
||||||
QString assetType = aZoneFile->AssetTypeToString(record);
|
AssetType assetType = mZoneFile->AssetStrToEnum(record);
|
||||||
assetIcon = aZoneFile->AssetStrToIcon(assetType);
|
QIcon assetIcon = mZoneFile->AssetTypeToIcon(assetType);
|
||||||
if (assetIcon.isNull()) {
|
if (assetIcon.isNull()) {
|
||||||
qDebug() << "Icon is null for record: " << record;
|
qDebug() << "Icon is null for record: " << record;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->tableWidget_RecordCounts->setRowCount(recordIndex + 1);
|
ui->tableWidget_RecordCounts->setRowCount(recordIndex + 1);
|
||||||
|
|
||||||
QTableWidgetItem *recordCountStrItem = new QTableWidgetItem(assetType);
|
|
||||||
QTableWidgetItem *recordItem = new QTableWidgetItem(record.toUpper());
|
QTableWidgetItem *recordItem = new QTableWidgetItem(record.toUpper());
|
||||||
|
QTableWidgetItem *recordCountStrItem = new QTableWidgetItem(mZoneFile->AssetEnumToStr(assetType));
|
||||||
QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(recordCount));
|
QTableWidgetItem *recordCountItem = new QTableWidgetItem(QString::number(recordCount));
|
||||||
QTableWidgetItem *recordIconItem = new QTableWidgetItem();
|
recordItem->setIcon(assetIcon);
|
||||||
recordIconItem->setIcon(assetIcon);
|
|
||||||
|
|
||||||
ui->tableWidget_RecordCounts->setItem(recordIndex, 0, recordItem);
|
ui->tableWidget_RecordCounts->setItem(recordIndex, 0, recordItem);
|
||||||
ui->tableWidget_RecordCounts->setItem(recordIndex, 1, recordCountStrItem);
|
ui->tableWidget_RecordCounts->setItem(recordIndex, 1, recordCountStrItem);
|
||||||
ui->tableWidget_RecordCounts->setItem(recordIndex, 2, recordCountItem);
|
ui->tableWidget_RecordCounts->setItem(recordIndex, 2, recordCountItem);
|
||||||
ui->tableWidget_RecordCounts->setItem(recordIndex, 3, recordIconItem);
|
|
||||||
|
|
||||||
recordIndex++;
|
recordIndex++;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,9 +19,15 @@ public:
|
|||||||
~ZoneFileViewer();
|
~ZoneFileViewer();
|
||||||
|
|
||||||
void SetZoneFile(std::shared_ptr<ZoneFile> aZoneFile);
|
void SetZoneFile(std::shared_ptr<ZoneFile> aZoneFile);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void SortTags(const QString &aSearchText);
|
||||||
|
|
||||||
|
void HighlightRecordInOrder();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ZoneFileViewer *ui;
|
Ui::ZoneFileViewer *ui;
|
||||||
std::shared_ptr<ZoneFile> aZoneFile;
|
std::shared_ptr<ZoneFile> mZoneFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ZONEFILEVIEWER_H
|
#endif // ZONEFILEVIEWER_H
|
||||||
|
|||||||
@ -61,7 +61,14 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QListWidget" name="listWidget_Tags"/>
|
<widget class="QListWidget" name="listWidget_Tags">
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@ -73,7 +80,20 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTableWidget" name="tableWidget_RecordCounts"/>
|
<widget class="QTableWidget" name="tableWidget_RecordCounts">
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::SelectionMode::SingleSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
@ -85,7 +105,17 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTableWidget" name="tableWidget_RecordOrder"/>
|
<widget class="QTableWidget" name="tableWidget_RecordOrder">
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::SelectionMode::NoSelection</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|||||||
396
bink.h
@ -1,396 +0,0 @@
|
|||||||
/* xoreos - A reimplementation of BioWare's Aurora engine
|
|
||||||
*
|
|
||||||
* xoreos is the legal property of its developers, whose names
|
|
||||||
* can be found in the AUTHORS file distributed with this source
|
|
||||||
* distribution.
|
|
||||||
*
|
|
||||||
* xoreos is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 3
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* xoreos is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with xoreos. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
* Decoding RAD Game Tools' Bink videos.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Based on the Bink implementation in FFmpeg (<https://ffmpeg.org/)>,
|
|
||||||
* which is released under the terms of version 2 or later of the GNU
|
|
||||||
* Lesser General Public License.
|
|
||||||
*
|
|
||||||
* The original copyright notes in the files
|
|
||||||
* - libavformat/bink.c
|
|
||||||
* - libavcodec/bink.c
|
|
||||||
* - libavcodec/binkdata.h
|
|
||||||
* - libavcodec/binkdsp.c
|
|
||||||
* - libavcodec/binkdsp.h
|
|
||||||
* - libavcodec/binkaudio.c
|
|
||||||
* read as follows:
|
|
||||||
*
|
|
||||||
* Bink demuxer
|
|
||||||
* Copyright (c) 2008-2010 Peter Ross (pross@xvid.org)
|
|
||||||
* Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
|
|
||||||
*
|
|
||||||
* Bink video decoder
|
|
||||||
* Copyright (c) 2009 Konstantin Shishkov
|
|
||||||
* Copyright (C) 2011 Peter Ross <pross@xvid.org>
|
|
||||||
*
|
|
||||||
* Bink video decoder
|
|
||||||
* Copyright (C) 2009 Konstantin Shishkov
|
|
||||||
*
|
|
||||||
* Bink DSP routines
|
|
||||||
* Copyright (c) 2009 Konstantin Shishkov
|
|
||||||
*
|
|
||||||
* Bink Audio decoder
|
|
||||||
* Copyright (c) 2007-2011 Peter Ross (pross@xvid.org)
|
|
||||||
* Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
|
|
||||||
*
|
|
||||||
* FFmpeg is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* FFmpeg is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with FFmpeg; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef VIDEO_BINK_H
|
|
||||||
#define VIDEO_BINK_H
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "src/common/types.h"
|
|
||||||
#include "src/common/rational.h"
|
|
||||||
|
|
||||||
#include "src/video/decoder.h"
|
|
||||||
|
|
||||||
namespace Common {
|
|
||||||
class SeekableReadStream;
|
|
||||||
class BitStream;
|
|
||||||
class Huffman;
|
|
||||||
|
|
||||||
class RDFT;
|
|
||||||
class DCT;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Sound {
|
|
||||||
class PacketizedAudioStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Video {
|
|
||||||
|
|
||||||
/** A decoder for RAD Game Tools' Bink videos. */
|
|
||||||
class Bink : public VideoDecoder {
|
|
||||||
public:
|
|
||||||
Bink(Common::SeekableReadStream *bink);
|
|
||||||
~Bink();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void decodeNextTrackFrame(VideoTrack &track);
|
|
||||||
void checkAudioBuffer(AudioTrack &track, const Common::Timestamp &endTime);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const int kAudioChannelsMax = 2;
|
|
||||||
static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11);
|
|
||||||
|
|
||||||
enum AudioCodec {
|
|
||||||
kAudioCodecDCT,
|
|
||||||
kAudioCodecRDFT
|
|
||||||
};
|
|
||||||
|
|
||||||
/** An audio track. */
|
|
||||||
struct AudioInfo {
|
|
||||||
uint16_t flags;
|
|
||||||
|
|
||||||
uint32_t sampleRate;
|
|
||||||
uint8_t channels;
|
|
||||||
|
|
||||||
uint32_t outSampleRate;
|
|
||||||
uint8_t outChannels;
|
|
||||||
|
|
||||||
AudioCodec codec;
|
|
||||||
|
|
||||||
bool first;
|
|
||||||
|
|
||||||
uint32_t frameLen;
|
|
||||||
uint32_t overlapLen;
|
|
||||||
|
|
||||||
uint32_t blockSize;
|
|
||||||
|
|
||||||
uint32_t bandCount;
|
|
||||||
uint32_t *bands;
|
|
||||||
|
|
||||||
float root;
|
|
||||||
|
|
||||||
float coeffs[16 * kAudioBlockSizeMax];
|
|
||||||
int16_t prevCoeffs[kAudioBlockSizeMax];
|
|
||||||
|
|
||||||
float *coeffsPtr[kAudioChannelsMax];
|
|
||||||
|
|
||||||
Common::RDFT *rdft;
|
|
||||||
Common::DCT *dct;
|
|
||||||
|
|
||||||
AudioInfo();
|
|
||||||
AudioInfo(const AudioInfo &audioInfo) = default;
|
|
||||||
~AudioInfo();
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A video frame. */
|
|
||||||
struct VideoFrame {
|
|
||||||
bool keyFrame;
|
|
||||||
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t size;
|
|
||||||
|
|
||||||
Common::BitStream *bits;
|
|
||||||
|
|
||||||
VideoFrame();
|
|
||||||
VideoFrame(const VideoFrame &videoFrame) = default;
|
|
||||||
~VideoFrame();
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unique_ptr<Common::SeekableReadStream> _bink;
|
|
||||||
|
|
||||||
std::vector<AudioInfo> _audioTracks; ///< All audio tracks.
|
|
||||||
std::vector<VideoFrame> _frames; ///< All video frames.
|
|
||||||
|
|
||||||
uint32_t _audioTrack; ///< Audio track to use.
|
|
||||||
|
|
||||||
/** Load a Bink file. */
|
|
||||||
void load();
|
|
||||||
|
|
||||||
class BinkVideoTrack : public FixedRateVideoTrack {
|
|
||||||
public:
|
|
||||||
BinkVideoTrack(uint32_t width, uint32_t height, uint32_t frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32_t id);
|
|
||||||
|
|
||||||
uint32_t getWidth() const { return _width; }
|
|
||||||
uint32_t getHeight() const { return _height; }
|
|
||||||
int getCurFrame() const { return _curFrame; }
|
|
||||||
int getFrameCount() const { return _frameCount; }
|
|
||||||
|
|
||||||
/** Decode a video packet. */
|
|
||||||
void decodePacket(Graphics::Surface &surface, VideoFrame &frame);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Common::Rational getFrameRate() const { return _frameRate; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
/** A decoder state. */
|
|
||||||
struct DecodeContext {
|
|
||||||
VideoFrame *video;
|
|
||||||
|
|
||||||
uint32_t planeIdx;
|
|
||||||
|
|
||||||
uint32_t blockX;
|
|
||||||
uint32_t blockY;
|
|
||||||
|
|
||||||
byte *dest;
|
|
||||||
byte *prev;
|
|
||||||
|
|
||||||
byte *destStart, *destEnd;
|
|
||||||
byte *prevStart, *prevEnd;
|
|
||||||
|
|
||||||
uint32_t pitch;
|
|
||||||
|
|
||||||
int coordMap[64];
|
|
||||||
int coordScaledMap1[64];
|
|
||||||
int coordScaledMap2[64];
|
|
||||||
int coordScaledMap3[64];
|
|
||||||
int coordScaledMap4[64];
|
|
||||||
};
|
|
||||||
|
|
||||||
/** IDs for different data types used in Bink video codec. */
|
|
||||||
enum Source {
|
|
||||||
kSourceBlockTypes = 0, ///< 8x8 block types.
|
|
||||||
kSourceSubBlockTypes , ///< 16x16 block types (a subset of 8x8 block types).
|
|
||||||
kSourceColors , ///< Pixel values used for different block types.
|
|
||||||
kSourcePattern , ///< 8-bit values for 2-color pattern fill.
|
|
||||||
kSourceXOff , ///< X components of motion value.
|
|
||||||
kSourceYOff , ///< Y components of motion value.
|
|
||||||
kSourceIntraDC , ///< DC values for intrablocks with DCT.
|
|
||||||
kSourceInterDC , ///< DC values for interblocks with DCT.
|
|
||||||
kSourceRun , ///< Run lengths for special fill block.
|
|
||||||
|
|
||||||
kSourceMAX
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Bink video block types. */
|
|
||||||
enum BlockType {
|
|
||||||
kBlockSkip = 0, ///< Skipped block.
|
|
||||||
kBlockScaled , ///< Block has size 16x16.
|
|
||||||
kBlockMotion , ///< Block is copied from previous frame with some offset.
|
|
||||||
kBlockRun , ///< Block is composed from runs of colors with custom scan order.
|
|
||||||
kBlockResidue , ///< Motion block with some difference added.
|
|
||||||
kBlockIntra , ///< Intra DCT block.
|
|
||||||
kBlockFill , ///< Block is filled with single color.
|
|
||||||
kBlockInter , ///< Motion block with DCT applied to the difference.
|
|
||||||
kBlockPattern , ///< Block is filled with two colors following custom pattern.
|
|
||||||
kBlockRaw ///< Uncoded 8x8 block.
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Data structure for decoding and translating Huffman'd data. */
|
|
||||||
struct Huffman {
|
|
||||||
int index; ///< Index of the Huffman codebook to use.
|
|
||||||
byte symbols[16]; ///< Huffman symbol => Bink symbol translation list.
|
|
||||||
|
|
||||||
Huffman();
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Data structure used for decoding a single Bink data type. */
|
|
||||||
struct Bundle {
|
|
||||||
int countLengths[2]; ///< Lengths of number of entries to decode (in bits).
|
|
||||||
int countLength; ///< Length of number of entries to decode (in bits) for the current plane.
|
|
||||||
|
|
||||||
Huffman huffman; ///< Huffman codebook.
|
|
||||||
|
|
||||||
std::unique_ptr<byte[]> data; ///< Buffer for decoded symbols.
|
|
||||||
|
|
||||||
byte *dataEnd; ///< Pointer to the data end end.
|
|
||||||
byte *curDec; ///< Pointer to the data that wasn't yet decoded.
|
|
||||||
byte *curPtr; ///< Pointer to the data that wasn't yet read.
|
|
||||||
|
|
||||||
Bundle();
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t _width;
|
|
||||||
uint32_t _height;
|
|
||||||
|
|
||||||
int _curFrame; ///< Current Frame.
|
|
||||||
int _frameCount;
|
|
||||||
|
|
||||||
Common::Rational _frameRate; ///< The frame rate of the video.
|
|
||||||
|
|
||||||
bool _swapPlanes; ///< Are the planes ordered (A)YVU instead of (A)YUV?
|
|
||||||
bool _hasAlpha; ///< Do video frames have alpha?
|
|
||||||
|
|
||||||
uint32_t _id; ///< The BIK FourCC.
|
|
||||||
|
|
||||||
Bundle _bundles[kSourceMAX]; ///< Bundles for decoding all data types.
|
|
||||||
|
|
||||||
std::unique_ptr<Common::Huffman> _huffman[16]; ///< The 16 Huffman codebooks used in Bink decoding.
|
|
||||||
|
|
||||||
/** Huffman codebooks to use for decoding high nibbles in color data types. */
|
|
||||||
Huffman _colHighHuffman[16];
|
|
||||||
/** Value of the last decoded high nibble in color data types. */
|
|
||||||
int _colLastVal;
|
|
||||||
|
|
||||||
std::unique_ptr<byte[]> _curPlanes[4]; ///< The 4 color planes, YUVA, current frame.
|
|
||||||
std::unique_ptr<byte[]> _oldPlanes[4]; ///< The 4 color planes, YUVA, last frame.
|
|
||||||
|
|
||||||
/** Initialize the bundles. */
|
|
||||||
void initBundles();
|
|
||||||
|
|
||||||
/** Initialize the Huffman decoders. */
|
|
||||||
void initHuffman();
|
|
||||||
|
|
||||||
/** Decode a video packet. */
|
|
||||||
void videoPacket(VideoFrame &video);
|
|
||||||
|
|
||||||
/** Decode a plane. */
|
|
||||||
void decodePlane(VideoFrame &video, int planeIdx, bool isChroma);
|
|
||||||
|
|
||||||
/** Read/Initialize a bundle for decoding a plane. */
|
|
||||||
void readBundle(VideoFrame &video, Source source);
|
|
||||||
|
|
||||||
/** Read the symbols for a Huffman code. */
|
|
||||||
void readHuffman(VideoFrame &video, Huffman &huffman);
|
|
||||||
/** Merge two Huffman symbol lists. */
|
|
||||||
void mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size);
|
|
||||||
|
|
||||||
/** Read and translate a symbol out of a Huffman code. */
|
|
||||||
byte getHuffmanSymbol(VideoFrame &video, Huffman &huffman);
|
|
||||||
|
|
||||||
/** Get a direct value out of a bundle. */
|
|
||||||
int32_t getBundleValue(Source source);
|
|
||||||
/** Read a count value out of a bundle. */
|
|
||||||
uint32_t readBundleCount(VideoFrame &video, Bundle &bundle);
|
|
||||||
|
|
||||||
// Handle the block types
|
|
||||||
void blockSkip (DecodeContext &ctx);
|
|
||||||
void blockScaledSkip (DecodeContext &ctx);
|
|
||||||
void blockScaledRun (DecodeContext &ctx);
|
|
||||||
void blockScaledIntra (DecodeContext &ctx);
|
|
||||||
void blockScaledFill (DecodeContext &ctx);
|
|
||||||
void blockScaledPattern(DecodeContext &ctx);
|
|
||||||
void blockScaledRaw (DecodeContext &ctx);
|
|
||||||
void blockScaled (DecodeContext &ctx);
|
|
||||||
void blockMotion (DecodeContext &ctx);
|
|
||||||
void blockRun (DecodeContext &ctx);
|
|
||||||
void blockResidue (DecodeContext &ctx);
|
|
||||||
void blockIntra (DecodeContext &ctx);
|
|
||||||
void blockFill (DecodeContext &ctx);
|
|
||||||
void blockInter (DecodeContext &ctx);
|
|
||||||
void blockPattern (DecodeContext &ctx);
|
|
||||||
void blockRaw (DecodeContext &ctx);
|
|
||||||
|
|
||||||
// Read the bundles
|
|
||||||
void readRuns (VideoFrame &video, Bundle &bundle);
|
|
||||||
void readMotionValues(VideoFrame &video, Bundle &bundle);
|
|
||||||
void readBlockTypes (VideoFrame &video, Bundle &bundle);
|
|
||||||
void readPatterns (VideoFrame &video, Bundle &bundle);
|
|
||||||
void readColors (VideoFrame &video, Bundle &bundle);
|
|
||||||
void readDCS (VideoFrame &video, Bundle &bundle, int startBits, bool hasSign);
|
|
||||||
void readDCTCoeffs (VideoFrame &video, int16_t *block, bool isIntra);
|
|
||||||
void readResidue (VideoFrame &video, int16_t *block, int masksCount);
|
|
||||||
|
|
||||||
// Bink video IDCT
|
|
||||||
void IDCT(int16_t *block);
|
|
||||||
void IDCTPut(DecodeContext &ctx, int16_t *block);
|
|
||||||
void IDCTAdd(DecodeContext &ctx, int16_t *block);
|
|
||||||
};
|
|
||||||
|
|
||||||
class BinkAudioTrack : public AudioTrack {
|
|
||||||
public:
|
|
||||||
BinkAudioTrack(size_t index, AudioInfo &audio);
|
|
||||||
~BinkAudioTrack();
|
|
||||||
|
|
||||||
bool canBufferData() const;
|
|
||||||
|
|
||||||
/** Decode audio data up to endTime. */
|
|
||||||
void decodeAudio(Common::SeekableReadStream& bink, const std::vector<VideoFrame>& frames, const std::vector<AudioInfo>& audioTracks, const Common::Timestamp& endTime);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Sound::AudioStream *getAudioStream() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_t _index;
|
|
||||||
AudioInfo &_info;
|
|
||||||
Sound::PacketizedAudioStream *_audioStream;
|
|
||||||
uint32_t _curFrame;
|
|
||||||
Common::Timestamp _audioBuffered;
|
|
||||||
|
|
||||||
float getFloat(Common::BitStream &bits);
|
|
||||||
|
|
||||||
/** Decode an audio block. */
|
|
||||||
void audioBlock(Common::BitStream &bits, int16_t *out);
|
|
||||||
/** Decode a DCT'd audio block. */
|
|
||||||
void audioBlockDCT(Common::BitStream &bits);
|
|
||||||
/** Decode a RDFT'd audio block. */
|
|
||||||
void audioBlockRDFT(Common::BitStream &bits);
|
|
||||||
|
|
||||||
void readAudioCoeffs(Common::BitStream &bits, float *coeffs);
|
|
||||||
|
|
||||||
static void floatToInt16Interleave(int16_t *dst, const float **src, uint32_t length, uint8_t channels);
|
|
||||||
};
|
|
||||||
|
|
||||||
void initAudioTrack(AudioInfo &audio);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // End of namespace Video
|
|
||||||
|
|
||||||
#endif // VIDEO_BINK_H
|
|
||||||
@ -1,26 +1,4 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="/obj">
|
|
||||||
<file>obj/defaultactor_LOD0.XMODEL_BIN</file>
|
|
||||||
<file>obj/defaultactor_LOD0.XMODEL_EXPORT</file>
|
|
||||||
<file>obj/defaultactor_LOD0.bin</file>
|
|
||||||
<file>obj/defaultactor_LOD0.cast</file>
|
|
||||||
<file>obj/defaultactor_LOD0.gltf</file>
|
|
||||||
<file>obj/defaultactor_LOD0.ma</file>
|
|
||||||
<file>obj/defaultactor_LOD0.mesh.ascii</file>
|
|
||||||
<file>obj/defaultactor_LOD0.obj</file>
|
|
||||||
<file>obj/defaultactor_LOD0.semodel</file>
|
|
||||||
<file>obj/defaultactor_LOD0.smd</file>
|
|
||||||
<file>obj/defaultactor_LOD0_BIND.mel</file>
|
|
||||||
<file>obj/defaultactor_LOD0_cosmetics.mel</file>
|
|
||||||
<file>obj/diffusemap.png</file>
|
|
||||||
<file>obj/mtl_body_default_character.mtl</file>
|
|
||||||
<file>obj/mtl_body_default_character_images.txt</file>
|
|
||||||
<file>obj/normalmap.png</file>
|
|
||||||
</qresource>
|
|
||||||
<qresource prefix="/d3dbsp">
|
|
||||||
<file>d3dbsp/asset_viewer.d3dbsp</file>
|
|
||||||
<file>d3dbsp/barebones.d3dbsp</file>
|
|
||||||
</qresource>
|
|
||||||
<qresource prefix="/images">
|
<qresource prefix="/images">
|
||||||
<file>images/XPlor.png</file>
|
<file>images/XPlor.png</file>
|
||||||
<file>images/copy.svg</file>
|
<file>images/copy.svg</file>
|
||||||
@ -34,28 +12,6 @@
|
|||||||
<file>images/save.svg</file>
|
<file>images/save.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/icons">
|
<qresource prefix="/icons">
|
||||||
<file>icons/Icon_COD4.png</file>
|
|
||||||
<file>icons/Icon_COD5.png</file>
|
|
||||||
<file>icons/Icon_COD6.png</file>
|
|
||||||
<file>icons/Icon_COD7.png</file>
|
|
||||||
<file>icons/Icon_COD8.png</file>
|
|
||||||
<file>icons/Icon_COD9.png</file>
|
|
||||||
<file>icons/Icon_DDSFile.png</file>
|
|
||||||
<file>icons/Icon_FastFile.png</file>
|
|
||||||
<file>icons/Icon_IWIFile.png</file>
|
|
||||||
<file>icons/Icon_PC.png</file>
|
|
||||||
<file>icons/Icon_Playstation.png</file>
|
|
||||||
<file>icons/Icon_Xbox.png</file>
|
|
||||||
<file>icons/Icon_ZoneFile.png</file>
|
|
||||||
<file>icons/Icon_GSCFile.png</file>
|
|
||||||
<file>icons/Icon_StringFile.png</file>
|
|
||||||
<file>icons/Icon_TechSetFile.png</file>
|
|
||||||
<file>icons/Icon_WAVFile.png</file>
|
|
||||||
<file>icons/Icon_MenuFile.png</file>
|
|
||||||
<file>icons/Icon_Image.png</file>
|
|
||||||
<file>icons/Icon_Model.png</file>
|
|
||||||
<file>icons/Icon_StringTable.png</file>
|
|
||||||
<file>icons/Icon_Sound.png</file>
|
|
||||||
<file>icons/Icon_Pause.png</file>
|
<file>icons/Icon_Pause.png</file>
|
||||||
<file>icons/Icon_Play.png</file>
|
<file>icons/Icon_Play.png</file>
|
||||||
<file>icons/Icon_SkipBack.png</file>
|
<file>icons/Icon_SkipBack.png</file>
|
||||||
@ -71,21 +27,5 @@
|
|||||||
<file>icons/Icon_Paste.png</file>
|
<file>icons/Icon_Paste.png</file>
|
||||||
<file>icons/Icon_Save.png</file>
|
<file>icons/Icon_Save.png</file>
|
||||||
<file>icons/Icon_OpenFile.png</file>
|
<file>icons/Icon_OpenFile.png</file>
|
||||||
<file>icons/Icon_COD2.png</file>
|
|
||||||
<file>icons/Icon_Material.png</file>
|
|
||||||
<file>icons/Icon_Animation.png</file>
|
|
||||||
<file>icons/Icon_BSP.png</file>
|
|
||||||
<file>icons/Icon_ColMapSp.png</file>
|
|
||||||
<file>icons/Icon_Effect.png</file>
|
|
||||||
<file>icons/Icon_GameMapSp.png</file>
|
|
||||||
<file>icons/Icon_Font.png</file>
|
|
||||||
<file>icons/Icon_FXMap.png</file>
|
|
||||||
<file>icons/Icon_LightDef.png</file>
|
|
||||||
<file>icons/Icon_Weapon.png</file>
|
|
||||||
<file>icons/Icon_RawFile.png</file>
|
|
||||||
<file>icons/Icon_Destructible.png</file>
|
|
||||||
<file>icons/Icon_PhysPreset.png</file>
|
|
||||||
<file>icons/Icon_Wii.png</file>
|
|
||||||
<file>icons/Icon_WiiU.png</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
BIN
data/icons/Icon.psd
Normal file
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 855 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
@ -234,7 +234,7 @@
|
|||||||
"WEIGHTS_0": 6
|
"WEIGHTS_0": 6
|
||||||
},
|
},
|
||||||
"indices": 1,
|
"indices": 1,
|
||||||
"material": 0,
|
ASSET_MATERIAL: 0,
|
||||||
"mode": 4
|
"mode": 4
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -250,7 +250,7 @@
|
|||||||
"WEIGHTS_0": 12
|
"WEIGHTS_0": 12
|
||||||
},
|
},
|
||||||
"indices": 7,
|
"indices": 7,
|
||||||
"material": 0,
|
ASSET_MATERIAL: 0,
|
||||||
"mode": 4
|
"mode": 4
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 146 B |
670
enums.h
@ -1,670 +0,0 @@
|
|||||||
#ifndef ENUMS_H
|
|
||||||
#define ENUMS_H
|
|
||||||
|
|
||||||
#include "qtypes.h"
|
|
||||||
enum LUMP_TYPE
|
|
||||||
{
|
|
||||||
LUMP_MATERIALS = 0x0,
|
|
||||||
LUMP_LIGHTBYTES = 0x1,
|
|
||||||
LUMP_LIGHTGRIDENTRIES = 0x2,
|
|
||||||
LUMP_LIGHTGRIDCOLORS = 0x3,
|
|
||||||
LUMP_PLANES = 0x4,
|
|
||||||
LUMP_BRUSHSIDES = 0x5,
|
|
||||||
LUMP_BRUSHSIDEEDGECOUNTS = 0x6,
|
|
||||||
LUMP_BRUSHEDGES = 0x7,
|
|
||||||
LUMP_BRUSHES = 0x8,
|
|
||||||
LUMP_TRIANGLES = 0x9,
|
|
||||||
LUMP_DRAWVERTS = 0xA,
|
|
||||||
LUMP_DRAWINDICES = 0xB,
|
|
||||||
LUMP_CULLGROUPS = 0xC,
|
|
||||||
LUMP_CULLGROUPINDICES = 0xD,
|
|
||||||
LUMP_OBSOLETE_1 = 0xE,
|
|
||||||
LUMP_OBSOLETE_2 = 0xF,
|
|
||||||
LUMP_OBSOLETE_3 = 0x10,
|
|
||||||
LUMP_OBSOLETE_4 = 0x11,
|
|
||||||
LUMP_OBSOLETE_5 = 0x12,
|
|
||||||
LUMP_PORTALVERTS = 0x13,
|
|
||||||
LUMP_OBSOLETE_6 = 0x14,
|
|
||||||
LUMP_UINDS = 0x15,
|
|
||||||
LUMP_BRUSHVERTSCOUNTS = 0x16,
|
|
||||||
LUMP_BRUSHVERTS = 0x17,
|
|
||||||
LUMP_AABBTREES = 0x18,
|
|
||||||
LUMP_CELLS = 0x19,
|
|
||||||
LUMP_PORTALS = 0x1A,
|
|
||||||
LUMP_NODES = 0x1B,
|
|
||||||
LUMP_LEAFS = 0x1C,
|
|
||||||
LUMP_LEAFBRUSHES = 0x1D,
|
|
||||||
LUMP_LEAFSURFACES = 0x1E,
|
|
||||||
LUMP_COLLISIONVERTS = 0x1F,
|
|
||||||
LUMP_COLLISIONTRIS = 0x20,
|
|
||||||
LUMP_COLLISIONEDGEWALKABLE = 0x21,
|
|
||||||
LUMP_COLLISIONBORDERS = 0x22,
|
|
||||||
LUMP_COLLISIONPARTITIONS = 0x23,
|
|
||||||
LUMP_COLLISIONAABBS = 0x24,
|
|
||||||
LUMP_MODELS = 0x25,
|
|
||||||
LUMP_VISIBILITY = 0x26,
|
|
||||||
LUMP_ENTITIES = 0x27,
|
|
||||||
LUMP_PATHCONNECTIONS = 0x28,
|
|
||||||
LUMP_REFLECTION_PROBES = 0x29,
|
|
||||||
LUMP_VERTEX_LAYER_DATA = 0x2A,
|
|
||||||
LUMP_PRIMARY_LIGHTS = 0x2B,
|
|
||||||
LUMP_LIGHTGRIDHEADER = 0x2C,
|
|
||||||
LUMP_LIGHTGRIDROWS = 0x2D,
|
|
||||||
LUMP_OBSOLETE_10 = 0x2E,
|
|
||||||
|
|
||||||
//Obsolete in BO1/////////////////
|
|
||||||
LUMP_UNLAYERED_TRIANGLES = 0x2F,
|
|
||||||
LUMP_UNLAYERED_DRAWVERTS = 0x30,
|
|
||||||
LUMP_UNLAYERED_DRAWINDICES = 0x31,
|
|
||||||
LUMP_UNLAYERED_CULLGROUPS = 0x32,
|
|
||||||
LUMP_UNLAYERED_AABBTREES = 0x33,
|
|
||||||
//////////////////////////////////
|
|
||||||
|
|
||||||
LUMP_WATERHEADER = 0x34,
|
|
||||||
LUMP_WATERCELLS = 0x35,
|
|
||||||
LUMP_WATERCELLDATA = 0x36,
|
|
||||||
LUMP_BURNABLEHEADER = 0x37,
|
|
||||||
LUMP_BURNABLECELLS = 0x38,
|
|
||||||
LUMP_BURNABLECELLDATA = 0x39,
|
|
||||||
LUMP_SIMPLELIGHTMAPBYTES = 0x3A,
|
|
||||||
LUMP_LODCHAINS = 0x3B,
|
|
||||||
LUMP_LODINFOS = 0x3C,
|
|
||||||
LUMP_LODSURFACES = 0x3D,
|
|
||||||
LUMP_LIGHTREGIONS = 0x3E,
|
|
||||||
LUMP_LIGHTREGION_HULLS = 0x3F,
|
|
||||||
LUMP_LIGHTREGION_AXES = 0x40,
|
|
||||||
LUMP_WIILIGHTGRID = 0x41,
|
|
||||||
LUMP_LIGHTGRID2D_LIGHTS = 0x42,
|
|
||||||
LUMP_LIGHTGRID2D_INDICES = 0x43,
|
|
||||||
LUMP_LIGHTGRID2D_POINTS = 0x44,
|
|
||||||
LUMP_LIGHTGRID2D_CELLS = 0x45,
|
|
||||||
LUMP_LIGHT_CORONAS = 0x46,
|
|
||||||
|
|
||||||
//BO Specific/////////////////////////
|
|
||||||
LUMP_SHADOWMAP_VOLUMES = 0x47,
|
|
||||||
LUMP_SHADOWMAP_VOLUME_PLANES = 0x48,
|
|
||||||
LUMP_EXPOSURE_VOLUMES = 0x49,
|
|
||||||
LUMP_EXPOSURE_VOLUME_PLANES = 0x4A,
|
|
||||||
LUMP_OCCLUDERS = 0x4B,
|
|
||||||
LUMP_OUTDOORBOUNDS = 0x4C,
|
|
||||||
LUMP_HERO_ONLY_LIGHTS = 0x4D,
|
|
||||||
//////////////////////////////////////
|
|
||||||
|
|
||||||
INFO_LUMP_TYPE_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum BSPVERSION_TYPE
|
|
||||||
{
|
|
||||||
BSPVERSION_COD_WAW = 31,
|
|
||||||
BSPVERSION_COD_BO = 45
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_ITEM_TYPE {
|
|
||||||
ITEM_TYPE_TEXT = 0, // simple text
|
|
||||||
ITEM_TYPE_BUTTON = 1, // button, basically text with a border
|
|
||||||
ITEM_TYPE_RADIOBUTTON = 2, // toggle button, may be grouped
|
|
||||||
ITEM_TYPE_CHECKBOX = 3, // check box
|
|
||||||
ITEM_TYPE_EDITFIELD = 4, // editable text, associated with a dvar
|
|
||||||
ITEM_TYPE_COMBO = 5, // drop down list
|
|
||||||
ITEM_TYPE_LISTBOX = 6, // scrollable list
|
|
||||||
ITEM_TYPE_MODEL = 7, // model
|
|
||||||
ITEM_TYPE_OWNERDRAW = 8, // owner draw, name specs what it is
|
|
||||||
ITEM_TYPE_NUMERICFIELD = 9, // editable text, associated with a dvar
|
|
||||||
ITEM_TYPE_SLIDER = 10, // mouse speed, volume, etc.
|
|
||||||
ITEM_TYPE_YESNO = 11, // yes no dvar setting
|
|
||||||
ITEM_TYPE_MULTI = 12, // multiple list setting, enumerated
|
|
||||||
ITEM_TYPE_DVARENUM = 13, // multiple list setting, enumerated from a dvar
|
|
||||||
ITEM_TYPE_BIND = 14, // bind
|
|
||||||
ITEM_TYPE_MENUMODEL = 15, // special menu model
|
|
||||||
ITEM_TYPE_VALIDFILEFIELD = 16, // text must be valid for use in a dos filename
|
|
||||||
ITEM_TYPE_DECIMALFIELD = 17, // editable text, associated with a dvar, which allows decimal input
|
|
||||||
ITEM_TYPE_UPREDITFIELD = 18, // editable text, associated with a dvar
|
|
||||||
ITEM_TYPE_GAME_MESSAGE_WINDOW = 19, // game message window
|
|
||||||
ITEM_TYPE_SCALEFORM = 20, // Flash movie for Scaleform GFx
|
|
||||||
ITEM_TYPE_BIND2 = 21, // bind2
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_ITEM_H_ALIGN {
|
|
||||||
ITEM_ALIGN_LEFT = 0, // aligns left of text to left of containing rectangle
|
|
||||||
ITEM_ALIGN_CENTER = 1, // aligns center of text to center of containing rectangle
|
|
||||||
ITEM_ALIGN_RIGHT = 2, // aligns right of text to right of containing rectangle
|
|
||||||
ITEM_ALIGN_X_MASK = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_ITEM_V_ALIGN {
|
|
||||||
ITEM_ALIGN_LEGACY = 0, // aligns bottom of text to top of containing rectangle
|
|
||||||
ITEM_ALIGN_TOP = 4, // aligns top of text to top of containing rectangle
|
|
||||||
ITEM_ALIGN_MIDDLE = 8, // aligns middle of text to middle of containing rectangle
|
|
||||||
ITEM_ALIGN_BOTTOM = 12, // aligns bottom of text to bottom of containing rectangle
|
|
||||||
ITEM_ALIGN_Y_MASK = 12,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_ITEM_ALIGN {
|
|
||||||
ITEM_ALIGN_LEGACY_LEFT = 0,
|
|
||||||
ITEM_ALIGN_LEGACY_CENTER = 1,
|
|
||||||
ITEM_ALIGN_LEGACY_RIGHT = 2,
|
|
||||||
ITEM_ALIGN_TOP_LEFT = 4,
|
|
||||||
ITEM_ALIGN_TOP_CENTER = 5,
|
|
||||||
ITEM_ALIGN_TOP_RIGHT = 6,
|
|
||||||
ITEM_ALIGN_MIDDLE_LEFT = 8,
|
|
||||||
ITEM_ALIGN_MIDDLE_CENTER = 9,
|
|
||||||
ITEM_ALIGN_MIDDLE_RIGHT = 10,
|
|
||||||
ITEM_ALIGN_BOTTOM_LEFT = 12,
|
|
||||||
ITEM_ALIGN_BOTTOM_CENTER = 13,
|
|
||||||
ITEM_ALIGN_BOTTOM_RIGHT = 14
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_ITEM_TEXTSTYLE {
|
|
||||||
ITEM_TEXTSTYLE_NORMAL = 0, // normal text
|
|
||||||
ITEM_TEXTSTYLE_BLINK = 1, // fast blinking
|
|
||||||
ITEM_TEXTSTYLE_SHADOWED = 3, // drop shadow ( need a color for this )
|
|
||||||
ITEM_TEXTSTYLE_SHADOWEDMORE = 6, // drop shadow ( need a color for this )
|
|
||||||
ITEM_TEXTSTYLE_MONOSPACE = 128
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_WINDOW_BORDER {
|
|
||||||
WINDOW_BORDER_NONE = 0, // no border
|
|
||||||
WINDOW_BORDER_FULL = 1, // full border based on border color ( single pixel )
|
|
||||||
WINDOW_BORDER_HORZ = 2, // horizontal borders only
|
|
||||||
WINDOW_BORDER_VERT = 3, // vertical borders only
|
|
||||||
WINDOW_BORDER_KCGRADIENT = 4, // horizontal border using the gradient bars
|
|
||||||
WINDOW_BORDER_RAISED = 5, // darken the bottom and right sides of the border
|
|
||||||
WINDOW_BORDER_SUNKEN = 6 // darken the top and left sides of the border
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_WINDOW_STYLE {
|
|
||||||
WINDOW_STYLE_EMPTY = 0, // no background
|
|
||||||
WINDOW_STYLE_FILLED = 1, // filled with background color
|
|
||||||
WINDOW_STYLE_GRADIENT = 2, // gradient bar based on background color
|
|
||||||
WINDOW_STYLE_SHADER = 3, // shader based on background color
|
|
||||||
WINDOW_STYLE_TEAMCOLOR = 4, // team color
|
|
||||||
WINDOW_STYLE_DVAR_SHADER = 5, // draws the shader specified by the dvar
|
|
||||||
WINDOW_STYLE_LOADBAR = 6, // shader based on background color
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_MODE {
|
|
||||||
MODE_BOTTOMUP_ALIGN_TOP = 0, // text appears on bottom of list and moves up to specified Y coordinate as old text fades out
|
|
||||||
MODE_BOTTOMUP_ALIGN_BOTTOM = 1, // text appears on bottom of list and moves away from specified Y coordinate as new text pushes it up
|
|
||||||
MODE_TOPDOWN_ALIGN_TOP = 2, // text appears on top of list and moves away from specified Y coordinate as new text pushes it down
|
|
||||||
MODE_TOPDOWN_ALIGN_BOTTOM = 3 // text appears on top of list and moves down to specified Y coordinate as old text fades out
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_BOOL {
|
|
||||||
MENU_TRUE = 1,
|
|
||||||
MENU_FALSE = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_ORIENTATION {
|
|
||||||
HUD_VERTICAL = 0x00,
|
|
||||||
HUD_HORIZONTAL = 0x01
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_RANGETYPE {
|
|
||||||
RANGETYPE_ABSOLUTE = 0,
|
|
||||||
RANGETYPE_RELATIVE = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// list box element types
|
|
||||||
enum MENU_LIST_BOX {
|
|
||||||
LISTBOX_TEXT = 0x00,
|
|
||||||
LISTBOX_IMAGE = 0x01
|
|
||||||
};
|
|
||||||
|
|
||||||
// list feeders
|
|
||||||
enum MENU_FEEDERS {
|
|
||||||
FEEDER_HEADS = 0x00, // model heads
|
|
||||||
FEEDER_MAPS = 0x01, // text maps based on game type
|
|
||||||
FEEDER_SERVERS = 0x02, // servers
|
|
||||||
FEEDER_CLAN_MEMBERS = 0x03, // clan names
|
|
||||||
FEEDER_ALLMAPS = 0x04, // all maps available, in graphic format
|
|
||||||
FEEDER_REDTEAM_LIST = 0x05, // red team members
|
|
||||||
FEEDER_BLUETEAM_LIST = 0x06, // blue team members
|
|
||||||
FEEDER_PLAYER_LIST = 0x07, // players
|
|
||||||
FEEDER_TEAM_LIST = 0x08, // team members for team voting
|
|
||||||
FEEDER_MODS = 0x09, // team members for team voting
|
|
||||||
FEEDER_DEMOS = 0x0a, // team members for team voting
|
|
||||||
FEEDER_SCOREBOARD = 0x0b, // team members for team voting
|
|
||||||
FEEDER_Q3HEADS = 0x0c, // model heads
|
|
||||||
FEEDER_SERVERSTATUS = 0x0d, // server status
|
|
||||||
FEEDER_FINDPLAYER = 0x0e, // find player
|
|
||||||
FEEDER_CINEMATICS = 0x0f, // cinematics
|
|
||||||
FEEDER_SAVEGAMES = 0x10, // savegames
|
|
||||||
FEEDER_PICKSPAWN = 0x11, // pickspawn
|
|
||||||
FEEDER_LOBBY_MEMBERS = 0x12, // list of players in your party
|
|
||||||
FEEDER_LOBBY_MEMBERS_TALK = 0x13, // icon for whether they are speaking or not
|
|
||||||
FEEDER_MUTELIST = 0x14, // list of musted players
|
|
||||||
FEEDER_PLAYERSTALKING = 0x15, // list of players who are currently talking
|
|
||||||
FEEDER_SPLITSCREENPLAYERS = 0x16, // list of all players who are playing splitscreen
|
|
||||||
FEEDER_LOBBY_MEMBERS_READY = 0x17, // icon for whether they are ready or not
|
|
||||||
FEEDER_PLAYER_PROFILES = 0x18, // player profiles
|
|
||||||
FEEDER_PARTY_MEMBERS = 0x19, // list of players in your party
|
|
||||||
FEEDER_PARTY_MEMBERS_TALK = 0x1a, // icon for whether they are speaking or not
|
|
||||||
FEEDER_PARTY_MEMBERS_READY = 0x1b, // icon for whether they are ready or not
|
|
||||||
FEEDER_PLAYLISTS = 0x1c, // list of all playlists
|
|
||||||
FEEDER_GAMEMODES = 0x1d, // list of all game type modes, including any player custom modes
|
|
||||||
FEEDER_CATEGORIES = 0x1e, // list of all categories
|
|
||||||
FEEDER_LEADERBOARD = 0x1f, // list of rows for a leaderboard
|
|
||||||
FEEDER_MYTEAM_MEMBERS = 0x20, // list of marine team members
|
|
||||||
FEEDER_MYTEAM_MEMBERS_TALK = 0x21, // icon for whether they are speaking
|
|
||||||
FEEDER_ENEMY_MEMBERS = 0x22, // list of opfor team members
|
|
||||||
FEEDER_ENEMY_MEMBERS_TALK = 0x23, // icon for whether they are speaking
|
|
||||||
FEEDER_LOBBY_MEMBERS_STAT = 0x24, // last round stats for lobby members
|
|
||||||
FEEDER_MYTEAM_MEMBERS_STAT = 0x25, // last round stats for marine team members
|
|
||||||
FEEDER_ENEMY_MEMBERS_STAT = 0x26, // last round stats for opfor team members
|
|
||||||
FEEDER_ONLINEFRIENDS = 0x27, // list of your online friends
|
|
||||||
FEEDER_LOBBY_MEMBERS_RANK = 0x28, // rank icon
|
|
||||||
FEEDER_PARTY_MEMBERS_RANK = 0x29, // rank icon
|
|
||||||
FEEDER_ENEMY_MEMBERS_RANK = 0x2a, // rank icon
|
|
||||||
FEEDER_MYTEAM_MEMBERS_RANK = 0x2b, // rank icon
|
|
||||||
FEEDER_TESTMAPS = 0x2c, // department test maps
|
|
||||||
FEEDER_SYSTEMLINK_LOBBY_MEMBERS = 0x2d, // list of players in a system link lobby
|
|
||||||
FEEDER_LOBBY_MEMBERS_CONTROLLER = 0x2e, // icon for controller quadrant for splitscreen
|
|
||||||
FEEDER_PARTY_MEMBERS_CONTROLLER = 0x2f, // icon for controller quadrant for splitscreen
|
|
||||||
FEEDER_MYTEAM_MEMBERS_SQUAD = 0x30, // squad icon
|
|
||||||
FEEDER_ENEMY_MEMBERS_SQUAD = 0x31, // squad icon
|
|
||||||
FEEDER_INGAME_SQUAD_MEMBERS = 0x32, // Squad members displayed in MP 'Pause' menu
|
|
||||||
FEEDER_INGAME_SQUAD_MEMBERS_FULL = 0x33, // Squad members' name, rank, talk, leader displayed in PC MP 'Pause' menu
|
|
||||||
FEEDER_INGAME_SQUAD_NAMES = 0x34, // Squad names displayed in MP 'Join Squad' menu
|
|
||||||
FEEDER_INGAME_SQUAD_NAMES2 = 0x35, // Squad names displayed in MP 'Pause' menu
|
|
||||||
FEEDER_INGAME_SQUAD_NAMES_FULL = 0x36, // Squad names, lock, invite displayed in PC MP 'Pause' menu
|
|
||||||
FEEDER_CUSTOM_GAMETYPES = 0x37, // list of all the gametypes for custom matches
|
|
||||||
FEEDER_INGAME_SQUAD_MEMBER_RANK = 0x38, // Squad members' rank displayed in MP 'Pause' menu
|
|
||||||
FEEDER_INGAME_SQUAD_MEMBER_TALK = 0x39, // Squad members' talk icon displayed in MP 'Pause' menu
|
|
||||||
FEEDER_INGAME_SQUAD_LOCKED = 0x3a, // Squad lock icon displayed in MP 'Pause' menu
|
|
||||||
FEEDER_INGAME_SQUAD_MEMBER_INVITED = 0x3b, // Squad invite icon displayed in MP 'Pause' menu
|
|
||||||
FEEDER_INGAME_SQUAD_INVITE = 0x3c, // Squad invite icon displayed in MP 'Join Squad' menu
|
|
||||||
FEEDER_INGAME_SQUAD_LEADER = 0x3d, // Squad leader icon displayled in MP 'Pause' menu
|
|
||||||
FEEDER_FRIENDS = 0x3e, // list of your friends
|
|
||||||
FEEDER_PENDINGFRIENDS = 0x3f, // list of your pending friends
|
|
||||||
FEEDER_INVITES = 0x40, // list of the game invites from your friends
|
|
||||||
};
|
|
||||||
|
|
||||||
// display flags
|
|
||||||
enum MENU_DISPLAY_FLAG {
|
|
||||||
CG_SHOW_BLUE_TEAM_HAS_REDFLAG = 0x00000001,
|
|
||||||
CG_SHOW_RED_TEAM_HAS_BLUEFLAG = 0x00000002,
|
|
||||||
CG_SHOW_ANYTEAMGAME = 0x00000004,
|
|
||||||
CG_SHOW_CTF = 0x00000020,
|
|
||||||
CG_SHOW_OBELISK = 0x00000040,
|
|
||||||
CG_SHOW_HEALTHCRITICAL = 0x00000080,
|
|
||||||
CG_SHOW_SINGLEPLAYER = 0x00000100,
|
|
||||||
CG_SHOW_TOURNAMENT = 0x00000200,
|
|
||||||
CG_SHOW_DURINGINCOMINGVOICE = 0x00000400,
|
|
||||||
CG_SHOW_IF_PLAYER_HAS_FLAG = 0x00000800,
|
|
||||||
CG_SHOW_LANPLAYONLY = 0x00001000,
|
|
||||||
CG_SHOW_MINED = 0x00002000,
|
|
||||||
CG_SHOW_HEALTHOK = 0x00004000,
|
|
||||||
CG_SHOW_TEAMINFO = 0x00008000,
|
|
||||||
CG_SHOW_NOTEAMINFO = 0x00010000,
|
|
||||||
CG_SHOW_OTHERTEAMHASFLAG = 0x00020000,
|
|
||||||
CG_SHOW_YOURTEAMHASENEMYFLAG = 0x00040000,
|
|
||||||
CG_SHOW_ANYNONTEAMGAME = 0x00080000,
|
|
||||||
CG_SHOW_TEXTASINT = 0x00200000,
|
|
||||||
CG_SHOW_HIGHLIGHTED = 0x00100000,
|
|
||||||
CG_SHOW_NOT_V_CLEAR = 0x02000000,
|
|
||||||
CG_SHOW_2DONLY = 0x10000000
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_UI_FLAG{
|
|
||||||
UI_SHOW_LEADER = 0x00000001,
|
|
||||||
UI_SHOW_NOTLEADER = 0x00000002,
|
|
||||||
UI_SHOW_FAVORITESERVERS = 0x00000004,
|
|
||||||
UI_SHOW_ANYNONTEAMGAME = 0x00000008,
|
|
||||||
UI_SHOW_ANYTEAMGAME = 0x00000010,
|
|
||||||
UI_SHOW_NEWHIGHSCORE = 0x00000020,
|
|
||||||
UI_SHOW_DEMOAVAILABLE = 0x00000040,
|
|
||||||
UI_SHOW_NEWBESTTIME = 0x00000080,
|
|
||||||
UI_SHOW_FFA = 0x00000100,
|
|
||||||
UI_SHOW_NOTFFA = 0x00000200,
|
|
||||||
UI_SHOW_NETANYNONTEAMGAME = 0x00000400,
|
|
||||||
UI_SHOW_NETANYTEAMGAME = 0x00000800,
|
|
||||||
UI_SHOW_NOTFAVORITESERVERS = 0x00001000
|
|
||||||
};
|
|
||||||
|
|
||||||
// font types
|
|
||||||
enum MENU_FONT_TYPE{
|
|
||||||
UI_FONT_DEFAULT = 0, // auto-chose betwen big/reg/small
|
|
||||||
UI_FONT_NORMAL = 1,
|
|
||||||
UI_FONT_BIG = 2,
|
|
||||||
UI_FONT_SMALL = 3,
|
|
||||||
UI_FONT_BOLD = 4,
|
|
||||||
UI_FONT_CONSOLE = 5,
|
|
||||||
UI_FONT_OBJECTIVE = 6,
|
|
||||||
UI_FONT_MAX = 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
// owner draw types
|
|
||||||
// ideally these should be done outside of this file but
|
|
||||||
// this makes it much easier for the macro expansion to
|
|
||||||
// convert them for the designers ( from the .menu files )
|
|
||||||
enum MENU_OWNER_DRAW_TYPE {
|
|
||||||
CG_OWNERDRAW_BASE = 1,
|
|
||||||
CG_PLAYER_AMMO_VALUE = 5,
|
|
||||||
CG_PLAYER_AMMO_BACKDROP = 6,
|
|
||||||
CG_PLAYER_HEAT_VALUE = 7,
|
|
||||||
CG_PLAYER_STANCE = 20,
|
|
||||||
CG_SPECTATORS = 60,
|
|
||||||
CG_HOLD_BREATH_HINT = 71,
|
|
||||||
CG_CURSORHINT = 72,
|
|
||||||
CG_PLAYER_POWERUP = 73,
|
|
||||||
CG_PLAYER_HOLDABLE = 74,
|
|
||||||
CG_PLAYER_INVENTORY = 75,
|
|
||||||
CG_CURSORHINT_STATUS = 78, // like 'health' bar when pointing at a func_explosive
|
|
||||||
CG_PLAYER_BAR_HEALTH = 79,
|
|
||||||
CG_MANTLE_HINT = 80,
|
|
||||||
CG_PLAYER_WEAPON_NAME = 81,
|
|
||||||
CG_PLAYER_WEAPON_NAME_BACK = 82,
|
|
||||||
CG_CENTER_MESSAGE = 90, // for things like "You were killed by ..."
|
|
||||||
CG_TANK_BODY_DIR = 95,
|
|
||||||
CG_TANK_BARREL_DIR = 96,
|
|
||||||
CG_DEADQUOTE = 97,
|
|
||||||
CG_PLAYER_BAR_HEALTH_BACK = 98,
|
|
||||||
CG_MISSION_OBJECTIVE_HEADER = 99,
|
|
||||||
CG_MISSION_OBJECTIVE_LIST = 100,
|
|
||||||
CG_MISSION_OBJECTIVE_BACKDROP = 101,
|
|
||||||
CG_PAUSED_MENU_LINE = 102,
|
|
||||||
CG_OFFHAND_WEAPON_ICON_FRAG = 103,
|
|
||||||
CG_OFFHAND_WEAPON_ICON_SMOKEFLASH = 104,
|
|
||||||
CG_OFFHAND_WEAPON_AMMO_FRAG = 105,
|
|
||||||
CG_OFFHAND_WEAPON_AMMO_SMOKEFLASH = 106,
|
|
||||||
CG_OFFHAND_WEAPON_NAME_FRAG = 107,
|
|
||||||
CG_OFFHAND_WEAPON_NAME_SMOKEFLASH = 108,
|
|
||||||
CG_OFFHAND_WEAPON_SELECT_FRAG = 109,
|
|
||||||
CG_OFFHAND_WEAPON_SELECT_SMOKEFLASH = 110,
|
|
||||||
CG_SAVING = 111,
|
|
||||||
CG_PLAYER_LOW_HEALTH_OVERLAY = 112,
|
|
||||||
CG_INVALID_CMD_HINT = 113,
|
|
||||||
CG_PLAYER_SPRINT_METER = 114,
|
|
||||||
CG_PLAYER_SPRINT_BACK = 115,
|
|
||||||
CG_PLAYER_WEAPON_BACKGROUND = 116,
|
|
||||||
CG_PLAYER_WEAPON_AMMO_CLIP_GRAPHIC = 117,
|
|
||||||
CG_PLAYER_WEAPON_PRIMARY_ICON = 118,
|
|
||||||
CG_PLAYER_WEAPON_AMMO_STOCK = 119,
|
|
||||||
CG_PLAYER_WEAPON_LOW_AMMO_WARNING = 120,
|
|
||||||
CG_BATTLE_COMPASS_MARKERS = 122,
|
|
||||||
CG_BATTLE_FULLMAP_MARKERS = 123,
|
|
||||||
CG_SUCCESSFUL_CMD_HINT = 130,
|
|
||||||
CG_WAR_TEXT = 135,
|
|
||||||
CG_PLAYER_COMPASS_TICKERTAPE = 145,
|
|
||||||
CG_PLAYER_COMPASS_TICKERTAPE_NO_OBJ = 146,
|
|
||||||
CG_PLAYER_COMPASS_DOGS = 147,
|
|
||||||
CG_PLAYER_COMPASS_ARTILLERY_ICON = 148,
|
|
||||||
CG_PLAYER_COMPASS_SQUAD_OBJECTIVE = 149,
|
|
||||||
CG_PLAYER_COMPASS_PLAYER = 150,
|
|
||||||
CG_PLAYER_COMPASS_BACK = 151,
|
|
||||||
CG_PLAYER_COMPASS_POINTERS = 152,
|
|
||||||
CG_PLAYER_COMPASS_ACTORS = 153,
|
|
||||||
CG_PLAYER_COMPASS_TANKS = 154,
|
|
||||||
CG_PLAYER_COMPASS_HELICOPTERS = 155,
|
|
||||||
CG_PLAYER_COMPASS_PLANES = 156,
|
|
||||||
CG_PLAYER_COMPASS_AUTOMOBILES = 157,
|
|
||||||
CG_PLAYER_COMPASS_FRIENDS = 158,
|
|
||||||
CG_PLAYER_COMPASS_MAP = 159,
|
|
||||||
CG_PLAYER_COMPASS_NORTHCOORD = 160,
|
|
||||||
CG_PLAYER_COMPASS_EASTCOORD = 161,
|
|
||||||
CG_PLAYER_COMPASS_NCOORD_SCROLL = 162,
|
|
||||||
CG_PLAYER_COMPASS_ECOORD_SCROLL = 163,
|
|
||||||
CG_PLAYER_COMPASS_GOALDISTANCE = 164,
|
|
||||||
CG_PLAYER_ACTIONSLOT_DPAD = 165,
|
|
||||||
CG_PLAYER_ACTIONSLOT_1 = 166,
|
|
||||||
CG_PLAYER_ACTIONSLOT_2 = 167,
|
|
||||||
CG_PLAYER_ACTIONSLOT_3 = 168,
|
|
||||||
CG_PLAYER_ACTIONSLOT_4 = 169,
|
|
||||||
CG_PLAYER_COMPASS_ENEMIES = 170,
|
|
||||||
CG_PLAYER_FULLMAP_DOGS = 176,
|
|
||||||
CG_PLAYER_FULLMAP_VEHICLES = 177,
|
|
||||||
CG_PLAYER_FULLMAP_ARTILLERY_ICON = 178,
|
|
||||||
CG_PLAYER_FULLMAP_SQUAD_OBJECTIVE = 179,
|
|
||||||
CG_PLAYER_FULLMAP_BACK = 180,
|
|
||||||
CG_PLAYER_FULLMAP_MAP = 181,
|
|
||||||
CG_PLAYER_FULLMAP_POINTERS = 182,
|
|
||||||
CG_PLAYER_FULLMAP_PLAYER = 183,
|
|
||||||
CG_PLAYER_FULLMAP_ACTORS = 184,
|
|
||||||
CG_PLAYER_FULLMAP_FRIENDS = 185,
|
|
||||||
CG_PLAYER_FULLMAP_LOCATION_SELECTOR = 186,
|
|
||||||
CG_PLAYER_FULLMAP_BORDER = 187,
|
|
||||||
CG_PLAYER_FULLMAP_ENEMIES = 188,
|
|
||||||
CG_PLAYER_COMPASS = 189,
|
|
||||||
CG_VEHICLE_RETICLE = 190,
|
|
||||||
CG_HUD_TARGETS_VEHICLE = 191,
|
|
||||||
CG_HUD_TARGETS_JAVELIN = 192,
|
|
||||||
CG_TALKER1 = 193,
|
|
||||||
CG_TALKER2 = 194,
|
|
||||||
CG_TALKER3 = 195,
|
|
||||||
CG_TALKER4 = 196,
|
|
||||||
CG_FRIENDLYARROWS = 197,
|
|
||||||
CG_FRIENDLYNAMES = 198,
|
|
||||||
UI_OWNERDRAW_BASE = 200,
|
|
||||||
UI_HANDICAP = 200,
|
|
||||||
UI_EFFECTS = 201,
|
|
||||||
UI_PLAYERMODEL = 202,
|
|
||||||
UI_GAMETYPE = 205,
|
|
||||||
UI_SKILL = 207,
|
|
||||||
UI_NETSOURCE = 220,
|
|
||||||
UI_NETFILTER = 222,
|
|
||||||
UI_VOTE_KICK = 238,
|
|
||||||
UI_NETGAMETYPE = 245,
|
|
||||||
UI_SERVERREFRESHDATE = 247,
|
|
||||||
UI_SERVERMOTD = 248,
|
|
||||||
UI_GLINFO = 249,
|
|
||||||
UI_KEYBINDSTATUS = 250,
|
|
||||||
UI_JOINGAMETYPE = 253,
|
|
||||||
UI_MAPPREVIEW = 254,
|
|
||||||
UI_MENUMODEL = 257,
|
|
||||||
UI_SAVEGAME_SHOT = 258,
|
|
||||||
UI_SAVEGAMENAME = 262,
|
|
||||||
UI_SAVEGAMEINFO = 263,
|
|
||||||
UI_LOADPROFILING = 264,
|
|
||||||
UI_RECORDLEVEL = 265,
|
|
||||||
UI_AMITALKING = 266,
|
|
||||||
UI_TALKER1 = 267,
|
|
||||||
UI_TALKER2 = 268,
|
|
||||||
UI_TALKER3 = 269,
|
|
||||||
UI_TALKER4 = 270,
|
|
||||||
UI_PARTYSTATUS = 271,
|
|
||||||
UI_LOGGEDINUSER = 272,
|
|
||||||
UI_RESERVEDSLOTS = 273,
|
|
||||||
UI_PLAYLISTNAME = 274,
|
|
||||||
UI_PLAYLISTDESCRIPTION = 275,
|
|
||||||
UI_USERNAME = 276,
|
|
||||||
UI_CINEMATIC = 277,
|
|
||||||
UI_TOTALONLINE = 278,
|
|
||||||
UI_CATEGORYNAME = 279,
|
|
||||||
UI_CATEGORYDESCRIPTION = 280,
|
|
||||||
UI_PLAYLISTICON = 281,
|
|
||||||
UI_CATEGORYICON = 282,
|
|
||||||
UI_GAMETYPE_MAPNAME = 283,
|
|
||||||
CG_HUD_WAR_MOMENTUM_PROGRESS = 284,
|
|
||||||
CG_HUD_WAR_MOMENTUM_MULTIPLIER = 285,
|
|
||||||
CG_HUD_WAR_MOMENTUM_MULTIPLIER_DETAIL = 286,
|
|
||||||
CG_HUD_WAR_MOMENTUM_MULTIPLIER_BLITZKRIEG = 287,
|
|
||||||
CG_COMPETITIVE_MODE_SCORES = 288,
|
|
||||||
UI_LOAD_STATUS_SCREEN = 289,
|
|
||||||
UI_LEADERBOARD_GAMEMODE = 290,
|
|
||||||
CG_PLAYER_ACTIONSLOT_BACK_1 = 290,
|
|
||||||
CG_PLAYER_ACTIONSLOT_BACK_2 = 291,
|
|
||||||
CG_PLAYER_ACTIONSLOT_BACK_3 = 292,
|
|
||||||
CG_PLAYER_ACTIONSLOT_BACK_4 = 293,
|
|
||||||
CG_PLAYER_ACTIONSLOT_ARROW_1 = 294,
|
|
||||||
CG_PLAYER_ACTIONSLOT_ARROW_2 = 295,
|
|
||||||
CG_PLAYER_ACTIONSLOT_ARROW_3 = 296,
|
|
||||||
CG_PLAYER_ACTIONSLOT_ARROW_4 = 297,
|
|
||||||
UI_DIFFICULTY_INFO = 298,
|
|
||||||
UI_DIFFICULTY_ICON = 299,
|
|
||||||
UI_LOBBY_CHAT = 300
|
|
||||||
};
|
|
||||||
|
|
||||||
// Edge relative placement values for rect->h_align and rect->v_align
|
|
||||||
enum MENU_H_ALIGNMENT {
|
|
||||||
HORIZONTAL_ALIGN_SUBLEFT = 0, // left edge of a 4:3 screen (safe area not included)
|
|
||||||
HORIZONTAL_ALIGN_LEFT = 1, // left viewable (safe area) edge
|
|
||||||
HORIZONTAL_ALIGN_CENTER = 2, // center of the screen (reticle)
|
|
||||||
HORIZONTAL_ALIGN_RIGHT = 3, // right viewable (safe area) edge
|
|
||||||
HORIZONTAL_ALIGN_FULLSCREEN = 4, // disregards safe area
|
|
||||||
HORIZONTAL_ALIGN_NOSCALE = 5, // uses exact parameters - neither adjusts for safe area nor scales for screen size
|
|
||||||
HORIZONTAL_ALIGN_TO640 = 6, // scales a real-screen resolution x down into the 0 - 640 range
|
|
||||||
HORIZONTAL_ALIGN_CENTER_SAFEAREA = 7, // center of the safearea
|
|
||||||
HORIZONTAL_ALIGN_MAX = HORIZONTAL_ALIGN_CENTER_SAFEAREA,
|
|
||||||
HORIZONTAL_ALIGN_DEFAULT = HORIZONTAL_ALIGN_SUBLEFT
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_V_ALIGNMENT {
|
|
||||||
VERTICAL_ALIGN_SUBTOP = 0, // top edge of the 4:3 screen (safe area not included)
|
|
||||||
VERTICAL_ALIGN_TOP = 1, // top viewable (safe area) edge
|
|
||||||
VERTICAL_ALIGN_CENTER = 2, // center of the screen (reticle)
|
|
||||||
VERTICAL_ALIGN_BOTTOM = 3, // bottom viewable (safe area) edge
|
|
||||||
VERTICAL_ALIGN_FULLSCREEN = 4, // disregards safe area
|
|
||||||
VERTICAL_ALIGN_NOSCALE = 5, // uses exact parameters - neither adjusts for safe area nor scales for screen size
|
|
||||||
VERTICAL_ALIGN_TO480 = 6, // scales a real-screen resolution y down into the 0 - 480 range
|
|
||||||
VERTICAL_ALIGN_CENTER_SAFEAREA = 7, // center of the save area
|
|
||||||
VERTICAL_ALIGN_MAX = VERTICAL_ALIGN_CENTER_SAFEAREA,
|
|
||||||
VERTICAL_ALIGN_DEFAULT = VERTICAL_ALIGN_SUBTOP
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MENU_BUTTON {
|
|
||||||
BUTTON_A = 1,
|
|
||||||
BUTTON_B = 2,
|
|
||||||
BUTTON_X = 3,
|
|
||||||
BUTTON_Y = 4,
|
|
||||||
BUTTON_LSHLDR = 5,
|
|
||||||
BUTTON_RSHLDR = 6,
|
|
||||||
BUTTON_START = 14,
|
|
||||||
BUTTON_BACK = 15,
|
|
||||||
BUTTON_LSTICK = 16,
|
|
||||||
BUTTON_RSTICK = 17,
|
|
||||||
BUTTON_LTRIG = 18,
|
|
||||||
BUTTON_RTRIG = 19,
|
|
||||||
DPAD_UP = 20,
|
|
||||||
DPAD_DOWN = 21,
|
|
||||||
DPAD_LEFT = 22,
|
|
||||||
DPAD_RIGHT = 23,
|
|
||||||
APAD_UP = 28,
|
|
||||||
APAD_DOWN = 29,
|
|
||||||
APAD_LEFT = 30,
|
|
||||||
APAD_RIGHT = 31
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ASSET_TYPE {
|
|
||||||
ASSET_UNKNOWN = 0,
|
|
||||||
ASSET_ANIMATION = 4, // x_anim PARTIALLY VERIFIED
|
|
||||||
ASSET_MODEL = 5, // xmodel PARTIALLY VERIFIED
|
|
||||||
ASSET_MATERIAL = 6, // material VERIFIED
|
|
||||||
ASSET_BIK_FILE = 7, // .bik file PARTIALLY VERIFIED
|
|
||||||
ASSET_SOUND = 9, // loaded_sound VERIFIED
|
|
||||||
ASSET_COLLISION_MAP = 12, // collision_map PARTIALLY VERIFIED
|
|
||||||
ASSET_SHADER = 13, // shader PARTIALLY VERIFIED
|
|
||||||
ASSET_D3DBSP_DUMP = 17, // d3dbsp dump VERIFIED
|
|
||||||
ASSET_FONT = 20, // font PARTIALLY VERIFIED
|
|
||||||
ASSET_MENU = 21, // menu_file VERIFIED
|
|
||||||
ASSET_LOCAL_STRING = 23, // localized string VERIFIED
|
|
||||||
ASSET_WEAPON = 24, // weapon VERIFIED
|
|
||||||
ASSET_EFFECT = 26, // fx VERIFIED
|
|
||||||
ASSET_RAW_FILE = 32, // raw_file VERIFIED
|
|
||||||
ASSET_STRING_TABLE = 33 // string_table PARTIALLY VERIFIED
|
|
||||||
};
|
|
||||||
|
|
||||||
// Change this depending on the platform
|
|
||||||
// PC
|
|
||||||
#define DEVMAP_LEVEL_FIRST "devmap intro_pac"
|
|
||||||
#define DEVMAP "devmap"
|
|
||||||
// Not PC
|
|
||||||
// #define DEVMAP_LEVEL_FIRST "map intro_pac"
|
|
||||||
// #define DEVMAP "map"
|
|
||||||
|
|
||||||
// Remove this to restore full frontend instead of limited EPD frontend
|
|
||||||
#define COOP_EPD 0
|
|
||||||
|
|
||||||
// LDS - This enables a German SKU with Nazi Zombies enabled *SHOULD BE SET TO 0 IF NOT APPROVED*
|
|
||||||
#define GERMAN_ZOMBIE_BUILD 0
|
|
||||||
|
|
||||||
#define DEVMAP_LEVEL_TRAINING "devmap training"
|
|
||||||
#define LEVEL_FIRST "intro_pac"
|
|
||||||
#define LEVEL_TRAINING "training"
|
|
||||||
#define FIRST_PLAYABLE_CAMPAIGN_LEVEL "mak"
|
|
||||||
#define FIRST_PLAYABLE_ZOMBIE_LEVEL "nazi_zombie_prototype"
|
|
||||||
|
|
||||||
// Size define for the hud compass
|
|
||||||
// These are used for both the dynamic & non-dynamic compass drawing
|
|
||||||
// If these are changed, the cgame should be recompiled
|
|
||||||
#define COMPASS_SIZE 160
|
|
||||||
#define MINIMAP_X 11.5
|
|
||||||
#define MINIMAP_Y 5
|
|
||||||
#define MINIMAP_W 89.5
|
|
||||||
#define MINIMAP_H 89.5
|
|
||||||
|
|
||||||
#define COMPASS_SIZE_MP 125
|
|
||||||
#define MINIMAP_X_MP 0
|
|
||||||
#define MINIMAP_Y_MP 12
|
|
||||||
#define MINIMAP_W_MP 102
|
|
||||||
#define MINIMAP_H_MP 102
|
|
||||||
|
|
||||||
#define FULLSCREEN 0 0 640 480
|
|
||||||
#define FULLSCREEN_WIDE -107 0 854 480
|
|
||||||
|
|
||||||
// PC
|
|
||||||
#define ORIGIN_TITLE 30 34
|
|
||||||
// Not PC
|
|
||||||
// #define ORIGIN_TITLE 0 0
|
|
||||||
|
|
||||||
#define ORIGIN_TITLE_SS 104 120
|
|
||||||
|
|
||||||
#define FONTSCALE_SMALL 0.3095 //0.3750 // <-- COD4 // COD5 --> 0.30952//0.35897//0.24138 //14 pt //0.2900 //0.2750 // 18
|
|
||||||
#define FONTSCALE_LOBBY 0.26 // <--Slate // 0.3010 <-- Slate Compressed // 0.3750 // <-- COD4 CONDUIT ITC small
|
|
||||||
#define FONTSCALE_NORMAL 0.3810 //0.35897//0.4583
|
|
||||||
#define FONTSCALE_BOLD 0.5476 //0.4583
|
|
||||||
#define FONTSCALE_BIG 0.5476 //0.5833
|
|
||||||
#define FONTSCALE_EXTRABIG 1 //1.0000
|
|
||||||
|
|
||||||
// new settings
|
|
||||||
#define TEXTSIZE_SMALL FONTSCALE_SMALL
|
|
||||||
#define TEXTSIZE_SMALL_SS (FONTSCALE_SMALL*2)
|
|
||||||
#define TEXTSIZE_DEFAULT FONTSCALE_NORMAL
|
|
||||||
#define TEXTSIZE_DEFAULT_SS (FONTSCALE_NORMAL*2)
|
|
||||||
#define TEXTSIZE_TITLE FONTSCALE_BIG
|
|
||||||
#define TEXTSIZE_TITLE_SS 1
|
|
||||||
|
|
||||||
#define TEXTSIZE_BOLD TEXTSIZE_DEFAULT
|
|
||||||
#define TEXTSIZE_BIG TEXTSIZE_TITLE
|
|
||||||
|
|
||||||
//#define COLOR_TITLE 1 0.8 0.4 1
|
|
||||||
#define COLOR_TITLE 1 1 1 1
|
|
||||||
#define COLOR_HEADER 0.69 0.69 0.69 1
|
|
||||||
#define COLOR_FOCUSED 0.95294 0.72156 0.21176 1 //1 0.788 0.129 1
|
|
||||||
//#define COLOR_FOCUS_YELLOW 0.95294 0.72156 0.21176 1
|
|
||||||
#define COLOR_UNFOCUSED 0.4823 0.4823 0.4823 1
|
|
||||||
//#define COLOR_DISABLED 0.35 0.35 0.35 1
|
|
||||||
#define COLOR_SAFEAREA 0 0 1 1
|
|
||||||
|
|
||||||
#define COLOR_INFO_YELLOW COLOR_FOCUSED//1 0.84706 0 1
|
|
||||||
#define COLOR_TEXT 0.84313 0.84313 0.84313 1
|
|
||||||
#define COLOR_DISABLED 0.34118 0.36863 0.37647 1
|
|
||||||
#define COLOR_TITLEBAR 0.14510 0.16078 0.16862 0.3//1
|
|
||||||
#define COLOR_RED_TEXT 0.69020 0.00784 0.00784 1
|
|
||||||
|
|
||||||
#define COLOR_FADEOUT 0.09412 0.09412 0.04912 0.65
|
|
||||||
|
|
||||||
#define COLOR_BODY_TEXT 0.62745 0.66667 0.67451 1
|
|
||||||
|
|
||||||
#define COLOR_USMC 0 0.0196 0.41
|
|
||||||
#define COLOR_JPN 0.53 0.027 0.027
|
|
||||||
#define COLOR_USSR 0.368 0.035 0.035
|
|
||||||
#define COLOR_GER 0.937 0.9 0.607
|
|
||||||
|
|
||||||
#define DEFAULT_MP_CFG "default_mp.cfg"
|
|
||||||
#define SPLITSCREEN_MP_CFG "default_splitscreen.cfg"
|
|
||||||
#define SYSTEMLINK_MP_CFG "default_systemlink.cfg"
|
|
||||||
#define XBOXLIVE_MP_CFG "default_xboxlive.cfg"
|
|
||||||
|
|
||||||
#define MAX_RANK int(tableLookup( "mp/rankTable.csv", 0, "maxrank", 1))
|
|
||||||
#define MAX_PRESTIGE int(tableLookup( "mp/rankIconTable.csv", 0, "maxprestige", 1))
|
|
||||||
|
|
||||||
#define PRESTIGE_AVAIL (stat(2326) < MAX_PRESTIGE && stat(2301) == int(tableLookup("mp/rankTable.csv",0,MAX_RANK,7)))
|
|
||||||
#define PRESTIGE_NEXT (stat(2326) < MAX_PRESTIGE && stat(252) == MAX_RANK)
|
|
||||||
#define PRESTIGE_FINISH (stat(2326) == MAX_PRESTIGE)
|
|
||||||
|
|
||||||
#define CAN_RANK_UP (stat(252) < MAX_RANK || stat(2326) < MAX_PRESTIGE)
|
|
||||||
|
|
||||||
// Bink constants
|
|
||||||
const quint32 BINK_SURFACE32RGBA = 6;
|
|
||||||
|
|
||||||
#endif // ENUMS_H
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
#include "compression.h"
|
#include "compression.h"
|
||||||
//#include "lzokay.h"
|
#include "minilzo.h"
|
||||||
|
|
||||||
#define XBOXAPI __declspec(dllimport)
|
#define XBOXAPI __declspec(dllimport)
|
||||||
#include "xcompress.h"
|
#include "xcompress.h"
|
||||||
@ -13,8 +13,8 @@ QByteArray Compression::CompressXMem(const QByteArray &data)
|
|||||||
{
|
{
|
||||||
XMEMCODEC_PARAMETERS_LZX lzxParams = {};
|
XMEMCODEC_PARAMETERS_LZX lzxParams = {};
|
||||||
lzxParams.Flags = 0;
|
lzxParams.Flags = 0;
|
||||||
lzxParams.WindowSize = XCOMPRESS_LZX_BLOCK_SIZE;
|
lzxParams.WindowSize = 0x20000;
|
||||||
lzxParams.CompressionPartitionSize = XCOMPRESS_LZX_BLOCK_SIZE;
|
lzxParams.CompressionPartitionSize = 0x80000;
|
||||||
|
|
||||||
XMEMCOMPRESSION_CONTEXT ctx = nullptr;
|
XMEMCOMPRESSION_CONTEXT ctx = nullptr;
|
||||||
if (FAILED(XMemCreateCompressionContext(XMEMCODEC_LZX, &lzxParams, 0, &ctx)) || !ctx)
|
if (FAILED(XMemCreateCompressionContext(XMEMCODEC_LZX, &lzxParams, 0, &ctx)) || !ctx)
|
||||||
@ -34,25 +34,35 @@ QByteArray Compression::CompressXMem(const QByteArray &data)
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray Compression::DecompressXMem(const QByteArray &data)
|
QByteArray Compression::DecompressXMem(const QByteArray &data, int flags, int windowSize, int partSize)
|
||||||
{
|
{
|
||||||
|
if (data.isEmpty())
|
||||||
|
return {};
|
||||||
|
|
||||||
XMEMCODEC_PARAMETERS_LZX lzxParams = {};
|
XMEMCODEC_PARAMETERS_LZX lzxParams = {};
|
||||||
lzxParams.Flags = 0;
|
lzxParams.Flags = flags;
|
||||||
lzxParams.WindowSize = XCOMPRESS_LZX_BLOCK_SIZE;
|
lzxParams.WindowSize = windowSize;
|
||||||
lzxParams.CompressionPartitionSize = XCOMPRESS_LZX_BLOCK_SIZE;
|
lzxParams.CompressionPartitionSize = partSize;
|
||||||
|
|
||||||
XMEMDECOMPRESSION_CONTEXT ctx = nullptr;
|
XMEMDECOMPRESSION_CONTEXT ctx = nullptr;
|
||||||
if (FAILED(XMemCreateDecompressionContext(XMEMCODEC_LZX, &lzxParams, 0, &ctx)) || !ctx)
|
if (FAILED(XMemCreateDecompressionContext(XMEMCODEC_LZX, &lzxParams, 0, &ctx)) || !ctx)
|
||||||
return QByteArray();
|
return {};
|
||||||
|
|
||||||
QByteArray output(data.size(), 0);
|
// Allocate large enough buffer for decompression (16 MB is a safe upper bound)
|
||||||
SIZE_T actualSize = data.size();
|
const SIZE_T kMaxOutSize = 16 * 1024 * 1024;
|
||||||
|
QByteArray output(static_cast<int>(kMaxOutSize), Qt::Uninitialized);
|
||||||
|
SIZE_T actualSize = kMaxOutSize;
|
||||||
|
|
||||||
|
HRESULT hr = XMemDecompress(ctx,
|
||||||
|
output.data(), &actualSize,
|
||||||
|
data.constData(), data.size() + 16);
|
||||||
|
|
||||||
HRESULT hr = XMemDecompress(ctx, output.data(), &actualSize, data.constData(), data.size());
|
|
||||||
XMemDestroyDecompressionContext(ctx);
|
XMemDestroyDecompressionContext(ctx);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr)) {
|
||||||
return QByteArray();
|
qWarning() << "XMemDecompress failed with HRESULT:" << hr;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
output.resize(static_cast<int>(actualSize));
|
output.resize(static_cast<int>(actualSize));
|
||||||
return output;
|
return output;
|
||||||
@ -68,6 +78,46 @@ quint32 Compression::CalculateAdler32Checksum(const QByteArray &data) {
|
|||||||
return adler;
|
return adler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qint64 Compression::FindZlibOffset(const QByteArray &bytes)
|
||||||
|
{
|
||||||
|
static const QByteArray iwffs("IWffs");
|
||||||
|
auto idx = bytes.indexOf(iwffs);
|
||||||
|
if (idx != -1)
|
||||||
|
return idx + 0x4000;
|
||||||
|
|
||||||
|
const char header = 0x78; // z-lib: 0x78 [FLG]
|
||||||
|
int pos = -1;
|
||||||
|
while ((pos = bytes.indexOf(header, pos + 1)) != -1)
|
||||||
|
{
|
||||||
|
QByteArray window = bytes.mid(pos, 0x20);
|
||||||
|
if (!window.contains(QByteArray::fromHex("000000")) &&
|
||||||
|
!window.contains(QByteArray::fromHex("FFFFFF")))
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Compression::StripHashBlocks(const QByteArray &raw,
|
||||||
|
int dataChunkSize,
|
||||||
|
int hashChunkSize)
|
||||||
|
{
|
||||||
|
QByteArray cleaned;
|
||||||
|
cleaned.reserve(raw.size()); // upper bound
|
||||||
|
|
||||||
|
int p = 0;
|
||||||
|
while (p < raw.size())
|
||||||
|
{
|
||||||
|
const int chunk = qMin(dataChunkSize, raw.size() - p);
|
||||||
|
cleaned.append(raw.constData() + p, chunk);
|
||||||
|
p += chunk;
|
||||||
|
|
||||||
|
// skip hash bytes if they are still inside the buffer
|
||||||
|
if (p < raw.size())
|
||||||
|
p += qMin(hashChunkSize, raw.size() - p);
|
||||||
|
}
|
||||||
|
return cleaned;
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray Compression::DecompressZLIB(const QByteArray &aCompressedData) {
|
QByteArray Compression::DecompressZLIB(const QByteArray &aCompressedData) {
|
||||||
if (aCompressedData.isEmpty()) {
|
if (aCompressedData.isEmpty()) {
|
||||||
return {};
|
return {};
|
||||||
@ -95,22 +145,23 @@ QByteArray Compression::DecompressZLIB(const QByteArray &aCompressedData) {
|
|||||||
|
|
||||||
ret = inflate(&strm, Z_NO_FLUSH);
|
ret = inflate(&strm, Z_NO_FLUSH);
|
||||||
|
|
||||||
if (strm.avail_out < buffer.size()) { // Data has been written to the buffer
|
if (strm.avail_out < buffer.size()) {
|
||||||
decompressed.append(buffer.constData(), buffer.size() - strm.avail_out);
|
decompressed.append(buffer.constData(), buffer.size() - strm.avail_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == Z_STREAM_END) {
|
if (ret == Z_STREAM_END) {
|
||||||
break; // Proper end of the data stream
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == Z_BUF_ERROR && strm.avail_out == 0) {
|
if (ret == Z_BUF_ERROR && strm.avail_out == 0) {
|
||||||
// Buffer was completely used, resize it
|
buffer.resize(buffer.size() * 2);
|
||||||
int newSize = buffer.size() * 2; // Double the buffer size
|
|
||||||
buffer.resize(newSize);
|
|
||||||
} else if (ret != Z_OK) {
|
} else if (ret != Z_OK) {
|
||||||
qWarning() << "Zlib error:" << zError(ret);
|
size_t errorOffset = strm.total_in;
|
||||||
|
qWarning() << "Zlib error:" << zError(ret)
|
||||||
|
<< "at offset" << errorOffset
|
||||||
|
<< "of" << aCompressedData.size() << "bytes";
|
||||||
inflateEnd(&strm);
|
inflateEnd(&strm);
|
||||||
return {}; // Return on other errors
|
return decompressed;
|
||||||
}
|
}
|
||||||
} while (ret != Z_STREAM_END);
|
} while (ret != Z_STREAM_END);
|
||||||
|
|
||||||
@ -118,6 +169,7 @@ QByteArray Compression::DecompressZLIB(const QByteArray &aCompressedData) {
|
|||||||
return decompressed;
|
return decompressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QByteArray Compression::CompressZLIB(const QByteArray &aData) {
|
QByteArray Compression::CompressZLIB(const QByteArray &aData) {
|
||||||
return CompressZLIBWithSettings(aData);
|
return CompressZLIBWithSettings(aData);
|
||||||
}
|
}
|
||||||
@ -242,6 +294,27 @@ QByteArray Compression::CompressDeflateWithSettings(const QByteArray &aData, int
|
|||||||
return compressed;
|
return compressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray Compression::DecompressLZO(const QByteArray &aCompressedData, quint32 aDestSize) {
|
||||||
|
static bool ok = (lzo_init() == LZO_E_OK);
|
||||||
|
if (!ok)
|
||||||
|
throw std::runtime_error("lzo_init failed");
|
||||||
|
|
||||||
|
QByteArray dst(aDestSize, Qt::Uninitialized);
|
||||||
|
lzo_uint out = aDestSize;
|
||||||
|
|
||||||
|
int rc = lzo1x_decompress_safe(
|
||||||
|
reinterpret_cast<const lzo_bytep>(aCompressedData.constData()),
|
||||||
|
static_cast<lzo_uint>(aCompressedData.size()),
|
||||||
|
reinterpret_cast<lzo_bytep>(dst.data()),
|
||||||
|
&out,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
if (rc != LZO_E_OK || out != aDestSize)
|
||||||
|
throw std::runtime_error("LZO decompression error");
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray Compression::DecompressOodle(const QByteArray &aCompressedData, quint32 aDecompressedSize) {
|
QByteArray Compression::DecompressOodle(const QByteArray &aCompressedData, quint32 aDecompressedSize) {
|
||||||
return pDecompressOodle(aCompressedData, aCompressedData.length(), aDecompressedSize);
|
return pDecompressOodle(aCompressedData, aCompressedData.length(), aDecompressedSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,10 @@ class Compression {
|
|||||||
public:
|
public:
|
||||||
static quint32 CalculateAdler32Checksum(const QByteArray &data);
|
static quint32 CalculateAdler32Checksum(const QByteArray &data);
|
||||||
static QByteArray DecompressZLIB(const QByteArray &aCompressedData);
|
static QByteArray DecompressZLIB(const QByteArray &aCompressedData);
|
||||||
|
static qint64 FindZlibOffset(const QByteArray &bytes);
|
||||||
|
static QByteArray StripHashBlocks(const QByteArray &raw,
|
||||||
|
int dataChunkSize = 0x200000,
|
||||||
|
int hashChunkSize = 0x2000);
|
||||||
static QByteArray CompressZLIB(const QByteArray &aData);
|
static QByteArray CompressZLIB(const QByteArray &aData);
|
||||||
static QByteArray CompressZLIBWithSettings(const QByteArray &aData,
|
static QByteArray CompressZLIBWithSettings(const QByteArray &aData,
|
||||||
int aCompressionLevel = Z_BEST_COMPRESSION,
|
int aCompressionLevel = Z_BEST_COMPRESSION,
|
||||||
@ -64,13 +68,14 @@ public:
|
|||||||
int aStrategy = Z_DEFAULT_STRATEGY,
|
int aStrategy = Z_DEFAULT_STRATEGY,
|
||||||
const QByteArray &aDictionary = {});
|
const QByteArray &aDictionary = {});
|
||||||
|
|
||||||
|
static QByteArray DecompressLZO(const QByteArray &aCompressedData, quint32 aDestSize);
|
||||||
|
|
||||||
static QByteArray DecompressOodle(const QByteArray &aCompressedData, quint32 aDecompressedSize);
|
static QByteArray DecompressOodle(const QByteArray &aCompressedData, quint32 aDecompressedSize);
|
||||||
static QByteArray CompressOodle(const QByteArray &aData);
|
static QByteArray CompressOodle(const QByteArray &aData);
|
||||||
|
|
||||||
|
|
||||||
static QByteArray CompressXMem(const QByteArray &data);
|
static QByteArray CompressXMem(const QByteArray &data);
|
||||||
static QByteArray DecompressXMem(const QByteArray &data);
|
static QByteArray DecompressXMem(const QByteArray &data, int flags = 0, int windowSize = 0x20000, int partSize = 0x80000);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static quint32 pGetOodleCompressedBounds(quint32 aBufferSize);
|
static quint32 pGetOodleCompressedBounds(quint32 aBufferSize);
|
||||||
static QByteArray pCompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize,
|
static QByteArray pCompressOodle(QByteArray aBuffer, quint32 aBufferSize, quint32 aOutputBufferSize,
|
||||||
|
|||||||
@ -1,14 +1,17 @@
|
|||||||
QT += core
|
QT += core
|
||||||
TEMPLATE = lib
|
TEMPLATE = lib
|
||||||
CONFIG += staticlib c++17
|
CONFIG += staticlib c++17
|
||||||
|
DEFINES += MINILZO_USE_STATIC
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
compression.cpp \
|
compression.cpp \
|
||||||
lzokay.cpp \
|
minilzo.c \
|
||||||
|
lzoconf.h \
|
||||||
|
lzodefs.h
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
compression.h \
|
compression.h \
|
||||||
lzokay.h
|
minilzo.h
|
||||||
|
|
||||||
LIBS += \
|
LIBS += \
|
||||||
-L$$PWD/../../third_party/xbox_sdk/lib -lxcompress64 \
|
-L$$PWD/../../third_party/xbox_sdk/lib -lxcompress64 \
|
||||||
|
|||||||
453
libs/compression/lzoconf.h
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
/* lzoconf.h -- configuration of the LZO data compression library
|
||||||
|
|
||||||
|
This file is part of the LZO real-time data compression library.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
The LZO library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The LZO library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with the LZO library; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
http://www.oberhumer.com/opensource/lzo/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __LZOCONF_H_INCLUDED
|
||||||
|
#define __LZOCONF_H_INCLUDED 1
|
||||||
|
|
||||||
|
#define LZO_VERSION 0x20a0 /* 2.10 */
|
||||||
|
#define LZO_VERSION_STRING "2.10"
|
||||||
|
#define LZO_VERSION_DATE "Mar 01 2017"
|
||||||
|
|
||||||
|
/* internal Autoconf configuration file - only used when building LZO */
|
||||||
|
#if defined(LZO_HAVE_CONFIG_H)
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
// LZO requires a conforming <limits.h>
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
|
||||||
|
# error "invalid CHAR_BIT"
|
||||||
|
#endif
|
||||||
|
#if !defined(UCHAR_MAX) || !defined(USHRT_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
|
||||||
|
# error "check your compiler installation"
|
||||||
|
#endif
|
||||||
|
#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
|
||||||
|
# error "your limits.h macros are broken"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get OS and architecture defines */
|
||||||
|
#ifndef __LZODEFS_H_INCLUDED
|
||||||
|
#include <lzo/lzodefs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
// some core defines
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/* memory checkers */
|
||||||
|
#if !defined(__LZO_CHECKER)
|
||||||
|
# if defined(__BOUNDS_CHECKING_ON)
|
||||||
|
# define __LZO_CHECKER 1
|
||||||
|
# elif defined(__CHECKER__)
|
||||||
|
# define __LZO_CHECKER 1
|
||||||
|
# elif defined(__INSURE__)
|
||||||
|
# define __LZO_CHECKER 1
|
||||||
|
# elif defined(__PURIFY__)
|
||||||
|
# define __LZO_CHECKER 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
// integral and pointer types
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/* lzo_uint must match size_t */
|
||||||
|
#if !defined(LZO_UINT_MAX)
|
||||||
|
# if (LZO_ABI_LLP64)
|
||||||
|
# if (LZO_OS_WIN64)
|
||||||
|
typedef unsigned __int64 lzo_uint;
|
||||||
|
typedef __int64 lzo_int;
|
||||||
|
# define LZO_TYPEOF_LZO_INT LZO_TYPEOF___INT64
|
||||||
|
# else
|
||||||
|
typedef lzo_ullong_t lzo_uint;
|
||||||
|
typedef lzo_llong_t lzo_int;
|
||||||
|
# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG_LONG
|
||||||
|
# endif
|
||||||
|
# define LZO_SIZEOF_LZO_INT 8
|
||||||
|
# define LZO_UINT_MAX 0xffffffffffffffffull
|
||||||
|
# define LZO_INT_MAX 9223372036854775807LL
|
||||||
|
# define LZO_INT_MIN (-1LL - LZO_INT_MAX)
|
||||||
|
# elif (LZO_ABI_IP32L64) /* MIPS R5900 */
|
||||||
|
typedef unsigned int lzo_uint;
|
||||||
|
typedef int lzo_int;
|
||||||
|
# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_INT
|
||||||
|
# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_INT
|
||||||
|
# define LZO_UINT_MAX UINT_MAX
|
||||||
|
# define LZO_INT_MAX INT_MAX
|
||||||
|
# define LZO_INT_MIN INT_MIN
|
||||||
|
# elif (ULONG_MAX >= LZO_0xffffffffL)
|
||||||
|
typedef unsigned long lzo_uint;
|
||||||
|
typedef long lzo_int;
|
||||||
|
# define LZO_SIZEOF_LZO_INT LZO_SIZEOF_LONG
|
||||||
|
# define LZO_TYPEOF_LZO_INT LZO_TYPEOF_LONG
|
||||||
|
# define LZO_UINT_MAX ULONG_MAX
|
||||||
|
# define LZO_INT_MAX LONG_MAX
|
||||||
|
# define LZO_INT_MIN LONG_MIN
|
||||||
|
# else
|
||||||
|
# error "lzo_uint"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The larger type of lzo_uint and lzo_uint32_t. */
|
||||||
|
#if (LZO_SIZEOF_LZO_INT >= 4)
|
||||||
|
# define lzo_xint lzo_uint
|
||||||
|
#else
|
||||||
|
# define lzo_xint lzo_uint32_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int lzo_bool;
|
||||||
|
|
||||||
|
/* sanity checks */
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int) == LZO_SIZEOF_LZO_INT)
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == LZO_SIZEOF_LZO_INT)
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint))
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint32_t))
|
||||||
|
|
||||||
|
#ifndef __LZO_MMODEL
|
||||||
|
#define __LZO_MMODEL /*empty*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* no typedef here because of const-pointer issues */
|
||||||
|
#define lzo_bytep unsigned char __LZO_MMODEL *
|
||||||
|
#define lzo_charp char __LZO_MMODEL *
|
||||||
|
#define lzo_voidp void __LZO_MMODEL *
|
||||||
|
#define lzo_shortp short __LZO_MMODEL *
|
||||||
|
#define lzo_ushortp unsigned short __LZO_MMODEL *
|
||||||
|
#define lzo_intp lzo_int __LZO_MMODEL *
|
||||||
|
#define lzo_uintp lzo_uint __LZO_MMODEL *
|
||||||
|
#define lzo_xintp lzo_xint __LZO_MMODEL *
|
||||||
|
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
|
||||||
|
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
|
||||||
|
|
||||||
|
#define lzo_int8_tp lzo_int8_t __LZO_MMODEL *
|
||||||
|
#define lzo_uint8_tp lzo_uint8_t __LZO_MMODEL *
|
||||||
|
#define lzo_int16_tp lzo_int16_t __LZO_MMODEL *
|
||||||
|
#define lzo_uint16_tp lzo_uint16_t __LZO_MMODEL *
|
||||||
|
#define lzo_int32_tp lzo_int32_t __LZO_MMODEL *
|
||||||
|
#define lzo_uint32_tp lzo_uint32_t __LZO_MMODEL *
|
||||||
|
#if defined(lzo_int64_t)
|
||||||
|
#define lzo_int64_tp lzo_int64_t __LZO_MMODEL *
|
||||||
|
#define lzo_uint64_tp lzo_uint64_t __LZO_MMODEL *
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Older LZO versions used to support ancient systems and memory models
|
||||||
|
* such as 16-bit MSDOS with __huge pointers or Cray PVP, but these
|
||||||
|
* obsolete configurations are not supported any longer.
|
||||||
|
*/
|
||||||
|
#if defined(__LZO_MMODEL_HUGE)
|
||||||
|
#error "__LZO_MMODEL_HUGE memory model is unsupported"
|
||||||
|
#endif
|
||||||
|
#if (LZO_MM_PVP)
|
||||||
|
#error "LZO_MM_PVP memory model is unsupported"
|
||||||
|
#endif
|
||||||
|
#if (LZO_SIZEOF_INT < 4)
|
||||||
|
#error "LZO_SIZEOF_INT < 4 is unsupported"
|
||||||
|
#endif
|
||||||
|
#if (__LZO_UINTPTR_T_IS_POINTER)
|
||||||
|
#error "__LZO_UINTPTR_T_IS_POINTER is unsupported"
|
||||||
|
#endif
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) >= 4)
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) >= 4)
|
||||||
|
/* Strange configurations where sizeof(lzo_uint) != sizeof(size_t) should
|
||||||
|
* work but have not received much testing lately, so be strict here.
|
||||||
|
*/
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(size_t))
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(ptrdiff_t))
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(lzo_uintptr_t))
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_uintptr_t))
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_uintptr_t))
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long *) == sizeof(lzo_uintptr_t))
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_voidp))
|
||||||
|
LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_bytep))
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
// function types
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/* name mangling */
|
||||||
|
#if !defined(__LZO_EXTERN_C)
|
||||||
|
# ifdef __cplusplus
|
||||||
|
# define __LZO_EXTERN_C extern "C"
|
||||||
|
# else
|
||||||
|
# define __LZO_EXTERN_C extern
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* calling convention */
|
||||||
|
#if !defined(__LZO_CDECL)
|
||||||
|
# define __LZO_CDECL __lzo_cdecl
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* DLL export information */
|
||||||
|
#if !defined(__LZO_EXPORT1)
|
||||||
|
# define __LZO_EXPORT1 /*empty*/
|
||||||
|
#endif
|
||||||
|
#if !defined(__LZO_EXPORT2)
|
||||||
|
# define __LZO_EXPORT2 /*empty*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* __cdecl calling convention for public C and assembly functions */
|
||||||
|
#if !defined(LZO_PUBLIC)
|
||||||
|
# define LZO_PUBLIC(r) __LZO_EXPORT1 r __LZO_EXPORT2 __LZO_CDECL
|
||||||
|
#endif
|
||||||
|
#if !defined(LZO_EXTERN)
|
||||||
|
# define LZO_EXTERN(r) __LZO_EXTERN_C LZO_PUBLIC(r)
|
||||||
|
#endif
|
||||||
|
#if !defined(LZO_PRIVATE)
|
||||||
|
# define LZO_PRIVATE(r) static r __LZO_CDECL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* function types */
|
||||||
|
typedef int
|
||||||
|
(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len,
|
||||||
|
lzo_bytep dst, lzo_uintp dst_len,
|
||||||
|
lzo_voidp wrkmem );
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len,
|
||||||
|
lzo_bytep dst, lzo_uintp dst_len,
|
||||||
|
lzo_voidp wrkmem );
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len,
|
||||||
|
lzo_bytep dst, lzo_uintp dst_len,
|
||||||
|
lzo_voidp wrkmem );
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len,
|
||||||
|
lzo_bytep dst, lzo_uintp dst_len,
|
||||||
|
lzo_voidp wrkmem,
|
||||||
|
const lzo_bytep dict, lzo_uint dict_len );
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len,
|
||||||
|
lzo_bytep dst, lzo_uintp dst_len,
|
||||||
|
lzo_voidp wrkmem,
|
||||||
|
const lzo_bytep dict, lzo_uint dict_len );
|
||||||
|
|
||||||
|
|
||||||
|
/* Callback interface. Currently only the progress indicator ("nprogress")
|
||||||
|
* is used, but this may change in a future release. */
|
||||||
|
|
||||||
|
struct lzo_callback_t;
|
||||||
|
typedef struct lzo_callback_t lzo_callback_t;
|
||||||
|
#define lzo_callback_p lzo_callback_t __LZO_MMODEL *
|
||||||
|
|
||||||
|
/* malloc & free function types */
|
||||||
|
typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t)
|
||||||
|
(lzo_callback_p self, lzo_uint items, lzo_uint size);
|
||||||
|
typedef void (__LZO_CDECL *lzo_free_func_t)
|
||||||
|
(lzo_callback_p self, lzo_voidp ptr);
|
||||||
|
|
||||||
|
/* a progress indicator callback function */
|
||||||
|
typedef void (__LZO_CDECL *lzo_progress_func_t)
|
||||||
|
(lzo_callback_p, lzo_uint, lzo_uint, int);
|
||||||
|
|
||||||
|
struct lzo_callback_t
|
||||||
|
{
|
||||||
|
/* custom allocators (set to 0 to disable) */
|
||||||
|
lzo_alloc_func_t nalloc; /* [not used right now] */
|
||||||
|
lzo_free_func_t nfree; /* [not used right now] */
|
||||||
|
|
||||||
|
/* a progress indicator callback function (set to 0 to disable) */
|
||||||
|
lzo_progress_func_t nprogress;
|
||||||
|
|
||||||
|
/* INFO: the first parameter "self" of the nalloc/nfree/nprogress
|
||||||
|
* callbacks points back to this struct, so you are free to store
|
||||||
|
* some extra info in the following variables. */
|
||||||
|
lzo_voidp user1;
|
||||||
|
lzo_xint user2;
|
||||||
|
lzo_xint user3;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
// error codes and prototypes
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/* Error codes for the compression/decompression functions. Negative
|
||||||
|
* values are errors, positive values will be used for special but
|
||||||
|
* normal events.
|
||||||
|
*/
|
||||||
|
#define LZO_E_OK 0
|
||||||
|
#define LZO_E_ERROR (-1)
|
||||||
|
#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */
|
||||||
|
#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
|
||||||
|
#define LZO_E_INPUT_OVERRUN (-4)
|
||||||
|
#define LZO_E_OUTPUT_OVERRUN (-5)
|
||||||
|
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
|
||||||
|
#define LZO_E_EOF_NOT_FOUND (-7)
|
||||||
|
#define LZO_E_INPUT_NOT_CONSUMED (-8)
|
||||||
|
#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
|
||||||
|
#define LZO_E_INVALID_ARGUMENT (-10)
|
||||||
|
#define LZO_E_INVALID_ALIGNMENT (-11) /* pointer argument is not properly aligned */
|
||||||
|
#define LZO_E_OUTPUT_NOT_CONSUMED (-12)
|
||||||
|
#define LZO_E_INTERNAL_ERROR (-99)
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef lzo_sizeof_dict_t
|
||||||
|
# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* lzo_init() should be the first function you call.
|
||||||
|
* Check the return code !
|
||||||
|
*
|
||||||
|
* lzo_init() is a macro to allow checking that the library and the
|
||||||
|
* compiler's view of various types are consistent.
|
||||||
|
*/
|
||||||
|
#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
|
||||||
|
(int)sizeof(long),(int)sizeof(lzo_uint32_t),(int)sizeof(lzo_uint),\
|
||||||
|
(int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
|
||||||
|
(int)sizeof(lzo_callback_t))
|
||||||
|
LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int);
|
||||||
|
|
||||||
|
/* version functions (useful for shared libraries) */
|
||||||
|
LZO_EXTERN(unsigned) lzo_version(void);
|
||||||
|
LZO_EXTERN(const char *) lzo_version_string(void);
|
||||||
|
LZO_EXTERN(const char *) lzo_version_date(void);
|
||||||
|
LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
|
||||||
|
LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
|
||||||
|
|
||||||
|
/* string functions */
|
||||||
|
LZO_EXTERN(int)
|
||||||
|
lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len);
|
||||||
|
LZO_EXTERN(lzo_voidp)
|
||||||
|
lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
|
||||||
|
LZO_EXTERN(lzo_voidp)
|
||||||
|
lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
|
||||||
|
LZO_EXTERN(lzo_voidp)
|
||||||
|
lzo_memset(lzo_voidp buf, int c, lzo_uint len);
|
||||||
|
|
||||||
|
/* checksum functions */
|
||||||
|
LZO_EXTERN(lzo_uint32_t)
|
||||||
|
lzo_adler32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len);
|
||||||
|
LZO_EXTERN(lzo_uint32_t)
|
||||||
|
lzo_crc32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len);
|
||||||
|
LZO_EXTERN(const lzo_uint32_tp)
|
||||||
|
lzo_get_crc32_table(void);
|
||||||
|
|
||||||
|
/* misc. */
|
||||||
|
LZO_EXTERN(int) _lzo_config_check(void);
|
||||||
|
typedef union {
|
||||||
|
lzo_voidp a00; lzo_bytep a01; lzo_uint a02; lzo_xint a03; lzo_uintptr_t a04;
|
||||||
|
void *a05; unsigned char *a06; unsigned long a07; size_t a08; ptrdiff_t a09;
|
||||||
|
#if defined(lzo_int64_t)
|
||||||
|
lzo_uint64_t a10;
|
||||||
|
#endif
|
||||||
|
} lzo_align_t;
|
||||||
|
|
||||||
|
/* align a char pointer on a boundary that is a multiple of 'size' */
|
||||||
|
LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
|
||||||
|
#define LZO_PTR_ALIGN_UP(p,size) \
|
||||||
|
((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size)))
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
// deprecated macros - only for backward compatibility
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
|
||||||
|
#define lzo_byte unsigned char
|
||||||
|
/* deprecated type names */
|
||||||
|
#define lzo_int32 lzo_int32_t
|
||||||
|
#define lzo_uint32 lzo_uint32_t
|
||||||
|
#define lzo_int32p lzo_int32_t __LZO_MMODEL *
|
||||||
|
#define lzo_uint32p lzo_uint32_t __LZO_MMODEL *
|
||||||
|
#define LZO_INT32_MAX LZO_INT32_C(2147483647)
|
||||||
|
#define LZO_UINT32_MAX LZO_UINT32_C(4294967295)
|
||||||
|
#if defined(lzo_int64_t)
|
||||||
|
#define lzo_int64 lzo_int64_t
|
||||||
|
#define lzo_uint64 lzo_uint64_t
|
||||||
|
#define lzo_int64p lzo_int64_t __LZO_MMODEL *
|
||||||
|
#define lzo_uint64p lzo_uint64_t __LZO_MMODEL *
|
||||||
|
#define LZO_INT64_MAX LZO_INT64_C(9223372036854775807)
|
||||||
|
#define LZO_UINT64_MAX LZO_UINT64_C(18446744073709551615)
|
||||||
|
#endif
|
||||||
|
/* deprecated types */
|
||||||
|
typedef union { lzo_bytep a; lzo_uint b; } __lzo_pu_u;
|
||||||
|
typedef union { lzo_bytep a; lzo_uint32_t b; } __lzo_pu32_u;
|
||||||
|
/* deprecated defines */
|
||||||
|
#if !defined(LZO_SIZEOF_LZO_UINT)
|
||||||
|
# define LZO_SIZEOF_LZO_UINT LZO_SIZEOF_LZO_INT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LZO_CFG_COMPAT)
|
||||||
|
|
||||||
|
#define __LZOCONF_H 1
|
||||||
|
|
||||||
|
#if defined(LZO_ARCH_I086)
|
||||||
|
# define __LZO_i386 1
|
||||||
|
#elif defined(LZO_ARCH_I386)
|
||||||
|
# define __LZO_i386 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LZO_OS_DOS16)
|
||||||
|
# define __LZO_DOS 1
|
||||||
|
# define __LZO_DOS16 1
|
||||||
|
#elif defined(LZO_OS_DOS32)
|
||||||
|
# define __LZO_DOS 1
|
||||||
|
#elif defined(LZO_OS_WIN16)
|
||||||
|
# define __LZO_WIN 1
|
||||||
|
# define __LZO_WIN16 1
|
||||||
|
#elif defined(LZO_OS_WIN32)
|
||||||
|
# define __LZO_WIN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __LZO_CMODEL /*empty*/
|
||||||
|
#define __LZO_DMODEL /*empty*/
|
||||||
|
#define __LZO_ENTRY __LZO_CDECL
|
||||||
|
#define LZO_EXTERN_CDECL LZO_EXTERN
|
||||||
|
#define LZO_ALIGN LZO_PTR_ALIGN_UP
|
||||||
|
|
||||||
|
#define lzo_compress_asm_t lzo_compress_t
|
||||||
|
#define lzo_decompress_asm_t lzo_decompress_t
|
||||||
|
|
||||||
|
#endif /* LZO_CFG_COMPAT */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
3268
libs/compression/lzodefs.h
Normal file
@ -1,647 +0,0 @@
|
|||||||
#include "lzokay.h"
|
|
||||||
#include <cstring>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Based on documentation from the Linux sources: Documentation/lzo.txt
|
|
||||||
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/lzo.txt
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace lzokay {
|
|
||||||
|
|
||||||
#if _WIN32
|
|
||||||
#define HOST_BIG_ENDIAN 0
|
|
||||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
|
||||||
#define HOST_BIG_ENDIAN 1
|
|
||||||
#else
|
|
||||||
#define HOST_BIG_ENDIAN 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HOST_BIG_ENDIAN
|
|
||||||
static uint16_t get_le16(const uint8_t* p) {
|
|
||||||
uint16_t val = *reinterpret_cast<const uint16_t*>(p);
|
|
||||||
#if __GNUC__
|
|
||||||
return __builtin_bswap16(val);
|
|
||||||
#elif _WIN32
|
|
||||||
return _byteswap_ushort(val);
|
|
||||||
#else
|
|
||||||
return (val = (val << 8) | ((val >> 8) & 0xFF));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static uint16_t get_le16(const uint8_t* p) {
|
|
||||||
return *reinterpret_cast<const uint16_t*>(p);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
constexpr std::size_t Max255Count = std::size_t(~0) / 255 - 2;
|
|
||||||
|
|
||||||
#define NEEDS_IN(count) \
|
|
||||||
if (inp + (count) > inp_end) { \
|
|
||||||
dst_size = outp - dst; \
|
|
||||||
return EResult::InputOverrun; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NEEDS_OUT(count) \
|
|
||||||
if (outp + (count) > outp_end) { \
|
|
||||||
dst_size = outp - dst; \
|
|
||||||
return EResult::OutputOverrun; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CONSUME_ZERO_BYTE_LENGTH \
|
|
||||||
std::size_t offset; \
|
|
||||||
{ \
|
|
||||||
const uint8_t *old_inp = inp; \
|
|
||||||
while (*inp == 0) ++inp; \
|
|
||||||
offset = inp - old_inp; \
|
|
||||||
if (offset > Max255Count) { \
|
|
||||||
dst_size = outp - dst; \
|
|
||||||
return EResult::Error; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define WRITE_ZERO_BYTE_LENGTH(length) \
|
|
||||||
{ \
|
|
||||||
std::size_t l; \
|
|
||||||
for (l = length; l > 255; l -= 255) { *outp++ = 0; } \
|
|
||||||
*outp++ = static_cast<uint8_t>(l); \
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr uint32_t M1MaxOffset = 0x0400;
|
|
||||||
constexpr uint32_t M2MaxOffset = 0x0800;
|
|
||||||
constexpr uint32_t M3MaxOffset = 0x4000;
|
|
||||||
// constexpr uint32_t M4MaxOffset = 0xbfff;
|
|
||||||
|
|
||||||
// constexpr uint32_t M1MinLen = 2;
|
|
||||||
// constexpr uint32_t M1MaxLen = 2;
|
|
||||||
constexpr uint32_t M2MinLen = 3;
|
|
||||||
constexpr uint32_t M2MaxLen = 8;
|
|
||||||
// constexpr uint32_t M3MinLen = 3;
|
|
||||||
constexpr uint32_t M3MaxLen = 33;
|
|
||||||
// constexpr uint32_t M4MinLen = 3;
|
|
||||||
constexpr uint32_t M4MaxLen = 9;
|
|
||||||
|
|
||||||
constexpr uint32_t M1Marker = 0x0;
|
|
||||||
// constexpr uint32_t M2Marker = 0x40;
|
|
||||||
constexpr uint32_t M3Marker = 0x20;
|
|
||||||
constexpr uint32_t M4Marker = 0x10;
|
|
||||||
|
|
||||||
constexpr uint32_t MaxMatchByLengthLen = 34; /* Max M3 len + 1 */
|
|
||||||
|
|
||||||
EResult decompress(const uint8_t* src, std::size_t src_size,
|
|
||||||
uint8_t* dst, std::size_t init_dst_size,
|
|
||||||
std::size_t& dst_size) {
|
|
||||||
dst_size = init_dst_size;
|
|
||||||
|
|
||||||
if (src_size < 3) {
|
|
||||||
dst_size = 0;
|
|
||||||
return EResult::InputOverrun;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t* inp = src;
|
|
||||||
const uint8_t* inp_end = src + src_size;
|
|
||||||
uint8_t* outp = dst;
|
|
||||||
uint8_t* outp_end = dst + dst_size;
|
|
||||||
uint8_t* lbcur;
|
|
||||||
std::size_t lblen;
|
|
||||||
std::size_t state = 0;
|
|
||||||
std::size_t nstate = 0;
|
|
||||||
|
|
||||||
/* First byte encoding */
|
|
||||||
if (*inp >= 22) {
|
|
||||||
/* 22..255 : copy literal string
|
|
||||||
* length = (byte - 17) = 4..238
|
|
||||||
* state = 4 [ don't copy extra literals ]
|
|
||||||
* skip byte
|
|
||||||
*/
|
|
||||||
std::size_t len = *inp++ - uint8_t(17);
|
|
||||||
NEEDS_IN(len)
|
|
||||||
NEEDS_OUT(len)
|
|
||||||
for (std::size_t i = 0; i < len; ++i)
|
|
||||||
*outp++ = *inp++;
|
|
||||||
state = 4;
|
|
||||||
} else if (*inp >= 18) {
|
|
||||||
/* 18..21 : copy 0..3 literals
|
|
||||||
* state = (byte - 17) = 0..3 [ copy <state> literals ]
|
|
||||||
* skip byte
|
|
||||||
*/
|
|
||||||
nstate = *inp++ - uint8_t(17);
|
|
||||||
state = nstate;
|
|
||||||
NEEDS_IN(nstate)
|
|
||||||
NEEDS_OUT(nstate)
|
|
||||||
for (std::size_t i = 0; i < nstate; ++i)
|
|
||||||
*outp++ = *inp++;
|
|
||||||
}
|
|
||||||
/* 0..17 : follow regular instruction encoding, see below. It is worth
|
|
||||||
* noting that codes 16 and 17 will represent a block copy from
|
|
||||||
* the dictionary which is empty, and that they will always be
|
|
||||||
* invalid at this place.
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
NEEDS_IN(1)
|
|
||||||
uint8_t inst = *inp++;
|
|
||||||
if (inst & 0xC0) {
|
|
||||||
/* [M2]
|
|
||||||
* 1 L L D D D S S (128..255)
|
|
||||||
* Copy 5-8 bytes from block within 2kB distance
|
|
||||||
* state = S (copy S literals after this block)
|
|
||||||
* length = 5 + L
|
|
||||||
* Always followed by exactly one byte : H H H H H H H H
|
|
||||||
* distance = (H << 3) + D + 1
|
|
||||||
*
|
|
||||||
* 0 1 L D D D S S (64..127)
|
|
||||||
* Copy 3-4 bytes from block within 2kB distance
|
|
||||||
* state = S (copy S literals after this block)
|
|
||||||
* length = 3 + L
|
|
||||||
* Always followed by exactly one byte : H H H H H H H H
|
|
||||||
* distance = (H << 3) + D + 1
|
|
||||||
*/
|
|
||||||
NEEDS_IN(1)
|
|
||||||
lbcur = outp - ((*inp++ << 3) + ((inst >> 2) & 0x7) + 1);
|
|
||||||
lblen = std::size_t(inst >> 5) + 1;
|
|
||||||
nstate = inst & uint8_t(0x3);
|
|
||||||
} else if (inst & M3Marker) {
|
|
||||||
/* [M3]
|
|
||||||
* 0 0 1 L L L L L (32..63)
|
|
||||||
* Copy of small block within 16kB distance (preferably less than 34B)
|
|
||||||
* length = 2 + (L ?: 31 + (zero_bytes * 255) + non_zero_byte)
|
|
||||||
* Always followed by exactly one LE16 : D D D D D D D D : D D D D D D S S
|
|
||||||
* distance = D + 1
|
|
||||||
* state = S (copy S literals after this block)
|
|
||||||
*/
|
|
||||||
lblen = std::size_t(inst & uint8_t(0x1f)) + 2;
|
|
||||||
if (lblen == 2) {
|
|
||||||
CONSUME_ZERO_BYTE_LENGTH
|
|
||||||
NEEDS_IN(1)
|
|
||||||
lblen += offset * 255 + 31 + *inp++;
|
|
||||||
}
|
|
||||||
NEEDS_IN(2)
|
|
||||||
nstate = get_le16(inp);
|
|
||||||
inp += 2;
|
|
||||||
lbcur = outp - ((nstate >> 2) + 1);
|
|
||||||
nstate &= 0x3;
|
|
||||||
} else if (inst & M4Marker) {
|
|
||||||
/* [M4]
|
|
||||||
* 0 0 0 1 H L L L (16..31)
|
|
||||||
* Copy of a block within 16..48kB distance (preferably less than 10B)
|
|
||||||
* length = 2 + (L ?: 7 + (zero_bytes * 255) + non_zero_byte)
|
|
||||||
* Always followed by exactly one LE16 : D D D D D D D D : D D D D D D S S
|
|
||||||
* distance = 16384 + (H << 14) + D
|
|
||||||
* state = S (copy S literals after this block)
|
|
||||||
* End of stream is reached if distance == 16384
|
|
||||||
*/
|
|
||||||
lblen = std::size_t(inst & uint8_t(0x7)) + 2;
|
|
||||||
if (lblen == 2) {
|
|
||||||
CONSUME_ZERO_BYTE_LENGTH
|
|
||||||
NEEDS_IN(1)
|
|
||||||
lblen += offset * 255 + 7 + *inp++;
|
|
||||||
}
|
|
||||||
NEEDS_IN(2)
|
|
||||||
nstate = get_le16(inp);
|
|
||||||
inp += 2;
|
|
||||||
lbcur = outp - (((inst & 0x8) << 11) + (nstate >> 2));
|
|
||||||
nstate &= 0x3;
|
|
||||||
if (lbcur == outp)
|
|
||||||
break; /* Stream finished */
|
|
||||||
lbcur -= 16384;
|
|
||||||
} else {
|
|
||||||
/* [M1] Depends on the number of literals copied by the last instruction. */
|
|
||||||
if (state == 0) {
|
|
||||||
/* If last instruction did not copy any literal (state == 0), this
|
|
||||||
* encoding will be a copy of 4 or more literal, and must be interpreted
|
|
||||||
* like this :
|
|
||||||
*
|
|
||||||
* 0 0 0 0 L L L L (0..15) : copy long literal string
|
|
||||||
* length = 3 + (L ?: 15 + (zero_bytes * 255) + non_zero_byte)
|
|
||||||
* state = 4 (no extra literals are copied)
|
|
||||||
*/
|
|
||||||
std::size_t len = inst + 3;
|
|
||||||
if (len == 3) {
|
|
||||||
CONSUME_ZERO_BYTE_LENGTH
|
|
||||||
NEEDS_IN(1)
|
|
||||||
len += offset * 255 + 15 + *inp++;
|
|
||||||
}
|
|
||||||
/* copy_literal_run */
|
|
||||||
NEEDS_IN(len)
|
|
||||||
NEEDS_OUT(len)
|
|
||||||
for (std::size_t i = 0; i < len; ++i)
|
|
||||||
*outp++ = *inp++;
|
|
||||||
state = 4;
|
|
||||||
continue;
|
|
||||||
} else if (state != 4) {
|
|
||||||
/* If last instruction used to copy between 1 to 3 literals (encoded in
|
|
||||||
* the instruction's opcode or distance), the instruction is a copy of a
|
|
||||||
* 2-byte block from the dictionary within a 1kB distance. It is worth
|
|
||||||
* noting that this instruction provides little savings since it uses 2
|
|
||||||
* bytes to encode a copy of 2 other bytes but it encodes the number of
|
|
||||||
* following literals for free. It must be interpreted like this :
|
|
||||||
*
|
|
||||||
* 0 0 0 0 D D S S (0..15) : copy 2 bytes from <= 1kB distance
|
|
||||||
* length = 2
|
|
||||||
* state = S (copy S literals after this block)
|
|
||||||
* Always followed by exactly one byte : H H H H H H H H
|
|
||||||
* distance = (H << 2) + D + 1
|
|
||||||
*/
|
|
||||||
NEEDS_IN(1)
|
|
||||||
nstate = inst & uint8_t(0x3);
|
|
||||||
lbcur = outp - ((inst >> 2) + (*inp++ << 2) + 1);
|
|
||||||
lblen = 2;
|
|
||||||
} else {
|
|
||||||
/* If last instruction used to copy 4 or more literals (as detected by
|
|
||||||
* state == 4), the instruction becomes a copy of a 3-byte block from the
|
|
||||||
* dictionary from a 2..3kB distance, and must be interpreted like this :
|
|
||||||
*
|
|
||||||
* 0 0 0 0 D D S S (0..15) : copy 3 bytes from 2..3 kB distance
|
|
||||||
* length = 3
|
|
||||||
* state = S (copy S literals after this block)
|
|
||||||
* Always followed by exactly one byte : H H H H H H H H
|
|
||||||
* distance = (H << 2) + D + 2049
|
|
||||||
*/
|
|
||||||
NEEDS_IN(1)
|
|
||||||
nstate = inst & uint8_t(0x3);
|
|
||||||
lbcur = outp - ((inst >> 2) + (*inp++ << 2) + 2049);
|
|
||||||
lblen = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lbcur < dst) {
|
|
||||||
dst_size = outp - dst;
|
|
||||||
return EResult::LookbehindOverrun;
|
|
||||||
}
|
|
||||||
NEEDS_IN(nstate)
|
|
||||||
NEEDS_OUT(lblen + nstate)
|
|
||||||
/* Copy lookbehind */
|
|
||||||
for (std::size_t i = 0; i < lblen; ++i)
|
|
||||||
*outp++ = *lbcur++;
|
|
||||||
state = nstate;
|
|
||||||
/* Copy literal */
|
|
||||||
for (std::size_t i = 0; i < nstate; ++i)
|
|
||||||
*outp++ = *inp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst_size = outp - dst;
|
|
||||||
if (lblen != 3) /* Ensure terminating M4 was encountered */
|
|
||||||
return EResult::Error;
|
|
||||||
if (inp == inp_end)
|
|
||||||
return EResult::Success;
|
|
||||||
else if (inp < inp_end)
|
|
||||||
return EResult::InputNotConsumed;
|
|
||||||
else
|
|
||||||
return EResult::InputOverrun;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct State {
|
|
||||||
const uint8_t* src;
|
|
||||||
const uint8_t* src_end;
|
|
||||||
const uint8_t* inp;
|
|
||||||
uint32_t wind_sz;
|
|
||||||
uint32_t wind_b;
|
|
||||||
uint32_t wind_e;
|
|
||||||
uint32_t cycle1_countdown;
|
|
||||||
|
|
||||||
const uint8_t* bufp;
|
|
||||||
uint32_t buf_sz;
|
|
||||||
|
|
||||||
/* Access next input byte and advance both ends of circular buffer */
|
|
||||||
void get_byte(uint8_t* buf) {
|
|
||||||
if (inp >= src_end) {
|
|
||||||
if (wind_sz > 0)
|
|
||||||
--wind_sz;
|
|
||||||
buf[wind_e] = 0;
|
|
||||||
if (wind_e < DictBase::MaxMatchLen)
|
|
||||||
buf[DictBase::BufSize + wind_e] = 0;
|
|
||||||
} else {
|
|
||||||
buf[wind_e] = *inp;
|
|
||||||
if (wind_e < DictBase::MaxMatchLen)
|
|
||||||
buf[DictBase::BufSize + wind_e] = *inp;
|
|
||||||
++inp;
|
|
||||||
}
|
|
||||||
if (++wind_e == DictBase::BufSize)
|
|
||||||
wind_e = 0;
|
|
||||||
if (++wind_b == DictBase::BufSize)
|
|
||||||
wind_b = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t pos2off(uint32_t pos) const {
|
|
||||||
return wind_b > pos ? wind_b - pos : DictBase::BufSize - (pos - wind_b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DictImpl : public DictBase {
|
|
||||||
public:
|
|
||||||
struct Match3Impl : DictBase::Match3 {
|
|
||||||
static uint32_t make_key(const uint8_t* data) {
|
|
||||||
return ((0x9f5f * (((uint32_t(data[0]) << 5 ^ uint32_t(data[1])) << 5) ^ data[2])) >> 5) & 0x3fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t get_head(uint32_t key) const {
|
|
||||||
return (chain_sz[key] == 0) ? uint16_t(UINT16_MAX) : head[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
std::fill(std::begin(chain_sz), std::end(chain_sz), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove(uint32_t pos, const uint8_t* b) {
|
|
||||||
--chain_sz[make_key(b + pos)];
|
|
||||||
}
|
|
||||||
|
|
||||||
void advance(State& s, uint32_t& match_pos, uint32_t& match_count, const uint8_t* b) {
|
|
||||||
uint32_t key = make_key(b + s.wind_b);
|
|
||||||
match_pos = chain[s.wind_b] = get_head(key);
|
|
||||||
match_count = chain_sz[key]++;
|
|
||||||
if (match_count > DictBase::MaxMatchLen)
|
|
||||||
match_count = DictBase::MaxMatchLen;
|
|
||||||
head[key] = uint16_t(s.wind_b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void skip_advance(State& s, const uint8_t* b) {
|
|
||||||
uint32_t key = make_key(b + s.wind_b);
|
|
||||||
chain[s.wind_b] = get_head(key);
|
|
||||||
head[key] = uint16_t(s.wind_b);
|
|
||||||
best_len[s.wind_b] = uint16_t(DictBase::MaxMatchLen + 1);
|
|
||||||
chain_sz[key]++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Match2Impl : DictBase::Match2 {
|
|
||||||
static uint32_t make_key(const uint8_t* data) {
|
|
||||||
return uint32_t(data[0]) ^ (uint32_t(data[1]) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void init() {
|
|
||||||
std::fill(std::begin(head), std::end(head), UINT16_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(uint16_t pos, const uint8_t* b) {
|
|
||||||
head[make_key(b + pos)] = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void remove(uint32_t pos, const uint8_t* b) {
|
|
||||||
uint16_t& p = head[make_key(b + pos)];
|
|
||||||
if (p == pos)
|
|
||||||
p = UINT16_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool search(State& s, uint32_t& lb_pos, uint32_t& lb_len,
|
|
||||||
uint32_t best_pos[MaxMatchByLengthLen], const uint8_t* b) const {
|
|
||||||
uint16_t pos = head[make_key(b + s.wind_b)];
|
|
||||||
if (pos == UINT16_MAX)
|
|
||||||
return false;
|
|
||||||
if (best_pos[2] == 0)
|
|
||||||
best_pos[2] = pos + 1;
|
|
||||||
if (lb_len < 2) {
|
|
||||||
lb_len = 2;
|
|
||||||
lb_pos = pos;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void init(State& s, const uint8_t* src, std::size_t src_size) {
|
|
||||||
auto& match3 = static_cast<Match3Impl&>(_storage->match3);
|
|
||||||
auto& match2 = static_cast<Match2Impl&>(_storage->match2);
|
|
||||||
|
|
||||||
s.cycle1_countdown = DictBase::MaxDist;
|
|
||||||
match3.init();
|
|
||||||
match2.init();
|
|
||||||
|
|
||||||
s.src = src;
|
|
||||||
s.src_end = src + src_size;
|
|
||||||
s.inp = src;
|
|
||||||
s.wind_sz = uint32_t(std::min(src_size, std::size_t(MaxMatchLen)));
|
|
||||||
s.wind_b = 0;
|
|
||||||
s.wind_e = s.wind_sz;
|
|
||||||
std::copy_n(s.inp, s.wind_sz, _storage->buffer);
|
|
||||||
s.inp += s.wind_sz;
|
|
||||||
|
|
||||||
if (s.wind_e == DictBase::BufSize)
|
|
||||||
s.wind_e = 0;
|
|
||||||
|
|
||||||
if (s.wind_sz < 3)
|
|
||||||
std::fill_n(_storage->buffer + s.wind_b + s.wind_sz, 3, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_next_input_entry(State& s, Match3Impl& match3, Match2Impl& match2) {
|
|
||||||
/* Remove match from about-to-be-clobbered buffer entry */
|
|
||||||
if (s.cycle1_countdown == 0) {
|
|
||||||
match3.remove(s.wind_e, _storage->buffer);
|
|
||||||
match2.remove(s.wind_e, _storage->buffer);
|
|
||||||
} else {
|
|
||||||
--s.cycle1_countdown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void advance(State& s, uint32_t& lb_off, uint32_t& lb_len,
|
|
||||||
uint32_t best_off[MaxMatchByLengthLen], bool skip) {
|
|
||||||
auto& match3 = static_cast<Match3Impl&>(_storage->match3);
|
|
||||||
auto& match2 = static_cast<Match2Impl&>(_storage->match2);
|
|
||||||
|
|
||||||
if (skip) {
|
|
||||||
for (uint32_t i = 0; i < lb_len - 1; ++i) {
|
|
||||||
reset_next_input_entry(s, match3, match2);
|
|
||||||
match3.skip_advance(s, _storage->buffer);
|
|
||||||
match2.add(uint16_t(s.wind_b), _storage->buffer);
|
|
||||||
s.get_byte(_storage->buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lb_len = 1;
|
|
||||||
lb_off = 0;
|
|
||||||
uint32_t lb_pos;
|
|
||||||
|
|
||||||
uint32_t best_pos[MaxMatchByLengthLen] = {};
|
|
||||||
uint32_t match_pos, match_count;
|
|
||||||
match3.advance(s, match_pos, match_count, _storage->buffer);
|
|
||||||
|
|
||||||
int best_char = _storage->buffer[s.wind_b];
|
|
||||||
uint32_t best_len = lb_len;
|
|
||||||
if (lb_len >= s.wind_sz) {
|
|
||||||
if (s.wind_sz == 0)
|
|
||||||
best_char = -1;
|
|
||||||
lb_off = 0;
|
|
||||||
match3.best_len[s.wind_b] = DictBase::MaxMatchLen + 1;
|
|
||||||
} else {
|
|
||||||
if (match2.search(s, lb_pos, lb_len, best_pos, _storage->buffer) && s.wind_sz >= 3) {
|
|
||||||
for (uint32_t i = 0; i < match_count; ++i, match_pos = match3.chain[match_pos]) {
|
|
||||||
auto ref_ptr = _storage->buffer + s.wind_b;
|
|
||||||
auto match_ptr = _storage->buffer + match_pos;
|
|
||||||
auto mismatch = std::mismatch(ref_ptr, ref_ptr + s.wind_sz, match_ptr);
|
|
||||||
auto match_len = uint32_t(mismatch.first - ref_ptr);
|
|
||||||
if (match_len < 2)
|
|
||||||
continue;
|
|
||||||
if (match_len < MaxMatchByLengthLen && best_pos[match_len] == 0)
|
|
||||||
best_pos[match_len] = match_pos + 1;
|
|
||||||
if (match_len > lb_len) {
|
|
||||||
lb_len = match_len;
|
|
||||||
lb_pos = match_pos;
|
|
||||||
if (match_len == s.wind_sz || match_len > match3.best_len[match_pos])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lb_len > best_len)
|
|
||||||
lb_off = s.pos2off(lb_pos);
|
|
||||||
match3.best_len[s.wind_b] = uint16_t(lb_len);
|
|
||||||
for (auto posit = std::begin(best_pos) + 2, offit = best_off + 2;
|
|
||||||
posit != std::end(best_pos); ++posit, ++offit) {
|
|
||||||
*offit = (*posit > 0) ? s.pos2off(*posit - 1) : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reset_next_input_entry(s, match3, match2);
|
|
||||||
|
|
||||||
match2.add(uint16_t(s.wind_b), _storage->buffer);
|
|
||||||
|
|
||||||
s.get_byte(_storage->buffer);
|
|
||||||
|
|
||||||
if (best_char < 0) {
|
|
||||||
s.buf_sz = 0;
|
|
||||||
lb_len = 0;
|
|
||||||
/* Signal exit */
|
|
||||||
} else {
|
|
||||||
s.buf_sz = s.wind_sz + 1;
|
|
||||||
}
|
|
||||||
s.bufp = s.inp - s.buf_sz;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static void find_better_match(const uint32_t best_off[MaxMatchByLengthLen], uint32_t& lb_len, uint32_t& lb_off) {
|
|
||||||
if (lb_len <= M2MinLen || lb_off <= M2MaxOffset)
|
|
||||||
return;
|
|
||||||
if (lb_off > M2MaxOffset && lb_len >= M2MinLen + 1 && lb_len <= M2MaxLen + 1 &&
|
|
||||||
best_off[lb_len - 1] != 0 && best_off[lb_len - 1] <= M2MaxOffset) {
|
|
||||||
lb_len -= 1;
|
|
||||||
lb_off = best_off[lb_len];
|
|
||||||
} else if (lb_off > M3MaxOffset && lb_len >= M4MaxLen + 1 && lb_len <= M2MaxLen + 2 &&
|
|
||||||
best_off[lb_len - 2] && best_off[lb_len] <= M2MaxOffset) {
|
|
||||||
lb_len -= 2;
|
|
||||||
lb_off = best_off[lb_len];
|
|
||||||
} else if (lb_off > M3MaxOffset && lb_len >= M4MaxLen + 1 && lb_len <= M3MaxLen + 1 &&
|
|
||||||
best_off[lb_len - 1] != 0 && best_off[lb_len - 2] <= M3MaxOffset) {
|
|
||||||
lb_len -= 1;
|
|
||||||
lb_off = best_off[lb_len];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static EResult encode_literal_run(uint8_t*& outp, const uint8_t* outp_end, const uint8_t* dst, std::size_t& dst_size,
|
|
||||||
const uint8_t* lit_ptr, uint32_t lit_len) {
|
|
||||||
if (outp == dst && lit_len <= 238) {
|
|
||||||
NEEDS_OUT(1);
|
|
||||||
*outp++ = uint8_t(17 + lit_len);
|
|
||||||
} else if (lit_len <= 3) {
|
|
||||||
outp[-2] = uint8_t(outp[-2] | lit_len);
|
|
||||||
} else if (lit_len <= 18) {
|
|
||||||
NEEDS_OUT(1);
|
|
||||||
*outp++ = uint8_t(lit_len - 3);
|
|
||||||
} else {
|
|
||||||
NEEDS_OUT((lit_len - 18) / 255 + 2);
|
|
||||||
*outp++ = 0;
|
|
||||||
WRITE_ZERO_BYTE_LENGTH(lit_len - 18);
|
|
||||||
}
|
|
||||||
NEEDS_OUT(lit_len);
|
|
||||||
outp = std::copy_n(lit_ptr, lit_len, outp);
|
|
||||||
return EResult::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
static EResult encode_lookback_match(uint8_t*& outp, const uint8_t* outp_end, const uint8_t* dst, std::size_t& dst_size,
|
|
||||||
uint32_t lb_len, uint32_t lb_off, uint32_t last_lit_len) {
|
|
||||||
if (lb_len == 2) {
|
|
||||||
lb_off -= 1;
|
|
||||||
NEEDS_OUT(2);
|
|
||||||
*outp++ = uint8_t(M1Marker | ((lb_off & 0x3) << 2));
|
|
||||||
*outp++ = uint8_t(lb_off >> 2);
|
|
||||||
} else if (lb_len <= M2MaxLen && lb_off <= M2MaxOffset) {
|
|
||||||
lb_off -= 1;
|
|
||||||
NEEDS_OUT(2);
|
|
||||||
*outp++ = uint8_t((lb_len - 1) << 5 | ((lb_off & 0x7) << 2));
|
|
||||||
*outp++ = uint8_t(lb_off >> 3);
|
|
||||||
} else if (lb_len == M2MinLen && lb_off <= M1MaxOffset + M2MaxOffset && last_lit_len >= 4) {
|
|
||||||
lb_off -= 1 + M2MaxOffset;
|
|
||||||
NEEDS_OUT(2);
|
|
||||||
*outp++ = uint8_t(M1Marker | ((lb_off & 0x3) << 2));
|
|
||||||
*outp++ = uint8_t(lb_off >> 2);
|
|
||||||
} else if (lb_off <= M3MaxOffset) {
|
|
||||||
lb_off -= 1;
|
|
||||||
if (lb_len <= M3MaxLen) {
|
|
||||||
NEEDS_OUT(1);
|
|
||||||
*outp++ = uint8_t(M3Marker | (lb_len - 2));
|
|
||||||
} else {
|
|
||||||
lb_len -= M3MaxLen;
|
|
||||||
NEEDS_OUT(lb_len / 255 + 2);
|
|
||||||
*outp++ = uint8_t(M3Marker);
|
|
||||||
WRITE_ZERO_BYTE_LENGTH(lb_len);
|
|
||||||
}
|
|
||||||
NEEDS_OUT(2);
|
|
||||||
*outp++ = uint8_t(lb_off << 2);
|
|
||||||
*outp++ = uint8_t(lb_off >> 6);
|
|
||||||
} else {
|
|
||||||
lb_off -= 0x4000;
|
|
||||||
if (lb_len <= M4MaxLen) {
|
|
||||||
NEEDS_OUT(1);
|
|
||||||
*outp++ = uint8_t(M4Marker | ((lb_off & 0x4000) >> 11) | (lb_len - 2));
|
|
||||||
} else {
|
|
||||||
lb_len -= M4MaxLen;
|
|
||||||
NEEDS_OUT(lb_len / 255 + 2);
|
|
||||||
*outp++ = uint8_t(M4Marker | ((lb_off & 0x4000) >> 11));
|
|
||||||
WRITE_ZERO_BYTE_LENGTH(lb_len);
|
|
||||||
}
|
|
||||||
NEEDS_OUT(2);
|
|
||||||
*outp++ = uint8_t(lb_off << 2);
|
|
||||||
*outp++ = uint8_t(lb_off >> 6);
|
|
||||||
}
|
|
||||||
return EResult::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
EResult compress(const uint8_t* src, std::size_t src_size,
|
|
||||||
uint8_t* dst, std::size_t init_dst_size,
|
|
||||||
std::size_t& dst_size, DictBase& dict) {
|
|
||||||
EResult err;
|
|
||||||
State s;
|
|
||||||
auto& d = static_cast<DictImpl&>(dict);
|
|
||||||
dst_size = init_dst_size;
|
|
||||||
uint8_t* outp = dst;
|
|
||||||
uint8_t* outp_end = dst + dst_size;
|
|
||||||
uint32_t lit_len = 0;
|
|
||||||
uint32_t lb_off, lb_len;
|
|
||||||
uint32_t best_off[MaxMatchByLengthLen];
|
|
||||||
d.init(s, src, src_size);
|
|
||||||
const uint8_t* lit_ptr = s.inp;
|
|
||||||
d.advance(s, lb_off, lb_len, best_off, false);
|
|
||||||
while (s.buf_sz > 0) {
|
|
||||||
if (lit_len == 0)
|
|
||||||
lit_ptr = s.bufp;
|
|
||||||
if (lb_len < 2 || (lb_len == 2 && (lb_off > M1MaxOffset || lit_len == 0 || lit_len >= 4)) ||
|
|
||||||
(lb_len == 2 && outp == dst) || (outp == dst && lit_len == 0)) {
|
|
||||||
lb_len = 0;
|
|
||||||
} else if (lb_len == M2MinLen && lb_off > M1MaxOffset + M2MaxOffset && lit_len >= 4) {
|
|
||||||
lb_len = 0;
|
|
||||||
}
|
|
||||||
if (lb_len == 0) {
|
|
||||||
++lit_len;
|
|
||||||
d.advance(s, lb_off, lb_len, best_off, false);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
find_better_match(best_off, lb_len, lb_off);
|
|
||||||
if ((err = encode_literal_run(outp, outp_end, dst, dst_size, lit_ptr, lit_len)) < EResult::Success)
|
|
||||||
return err;
|
|
||||||
if ((err = encode_lookback_match(outp, outp_end, dst, dst_size, lb_len, lb_off, lit_len)) < EResult::Success)
|
|
||||||
return err;
|
|
||||||
lit_len = 0;
|
|
||||||
d.advance(s, lb_off, lb_len, best_off, true);
|
|
||||||
}
|
|
||||||
if ((err = encode_literal_run(outp, outp_end, dst, dst_size, lit_ptr, lit_len)) < EResult::Success)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* Terminating M4 */
|
|
||||||
NEEDS_OUT(3);
|
|
||||||
*outp++ = M4Marker | 1;
|
|
||||||
*outp++ = 0;
|
|
||||||
*outp++ = 0;
|
|
||||||
|
|
||||||
dst_size = outp - dst;
|
|
||||||
return EResult::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace lzokay {
|
|
||||||
|
|
||||||
enum class EResult {
|
|
||||||
LookbehindOverrun = -4,
|
|
||||||
OutputOverrun = -3,
|
|
||||||
InputOverrun = -2,
|
|
||||||
Error = -1,
|
|
||||||
Success = 0,
|
|
||||||
InputNotConsumed = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
class DictBase {
|
|
||||||
protected:
|
|
||||||
static constexpr uint32_t HashSize = 0x4000;
|
|
||||||
static constexpr uint32_t MaxDist = 0xbfff;
|
|
||||||
static constexpr uint32_t MaxMatchLen = 0x800;
|
|
||||||
static constexpr uint32_t BufSize = MaxDist + MaxMatchLen;
|
|
||||||
|
|
||||||
/* List encoding of previous 3-byte data matches */
|
|
||||||
struct Match3 {
|
|
||||||
uint16_t head[HashSize]; /* key -> chain-head-pos */
|
|
||||||
uint16_t chain_sz[HashSize]; /* key -> chain-size */
|
|
||||||
uint16_t chain[BufSize]; /* chain-pos -> next-chain-pos */
|
|
||||||
uint16_t best_len[BufSize]; /* chain-pos -> best-match-length */
|
|
||||||
};
|
|
||||||
/* Encoding of 2-byte data matches */
|
|
||||||
struct Match2 {
|
|
||||||
uint16_t head[1 << 16]; /* 2-byte-data -> head-pos */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Data {
|
|
||||||
Match3 match3;
|
|
||||||
Match2 match2;
|
|
||||||
|
|
||||||
/* Circular buffer caching enough data to access the maximum lookback
|
|
||||||
* distance of 48K + maximum match length of 2K. An additional 2K is
|
|
||||||
* allocated so the start of the buffer may be replicated at the end,
|
|
||||||
* therefore providing efficient circular access.
|
|
||||||
*/
|
|
||||||
uint8_t buffer[BufSize + MaxMatchLen];
|
|
||||||
};
|
|
||||||
using storage_type = Data;
|
|
||||||
storage_type* _storage;
|
|
||||||
DictBase() = default;
|
|
||||||
friend struct State;
|
|
||||||
friend EResult compress(const uint8_t* src, std::size_t src_size,
|
|
||||||
uint8_t* dst, std::size_t& dst_size, DictBase& dict);
|
|
||||||
};
|
|
||||||
template <template<typename> class _Alloc = std::allocator>
|
|
||||||
class Dict : public DictBase {
|
|
||||||
_Alloc<DictBase::storage_type> _allocator;
|
|
||||||
public:
|
|
||||||
Dict() { _storage = _allocator.allocate(1); }
|
|
||||||
~Dict() { _allocator.deallocate(_storage, 1); }
|
|
||||||
};
|
|
||||||
|
|
||||||
EResult decompress(const uint8_t* src, std::size_t src_size,
|
|
||||||
uint8_t* dst, std::size_t dst_size,
|
|
||||||
std::size_t& out_size);
|
|
||||||
EResult compress(const uint8_t* src, std::size_t src_size,
|
|
||||||
uint8_t* dst, std::size_t dst_size,
|
|
||||||
std::size_t& out_size, DictBase& dict);
|
|
||||||
inline EResult compress(const uint8_t* src, std::size_t src_size,
|
|
||||||
uint8_t* dst, std::size_t dst_size,
|
|
||||||
std::size_t& out_size) {
|
|
||||||
Dict<> dict;
|
|
||||||
return compress(src, src_size, dst, dst_size, out_size, dict);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr std::size_t compress_worst_size(std::size_t s) {
|
|
||||||
return s + s / 16 + 64 + 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
6365
libs/compression/minilzo.c
Normal file
106
libs/compression/minilzo.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/* minilzo.h -- mini subset of the LZO real-time data compression library
|
||||||
|
|
||||||
|
This file is part of the LZO real-time data compression library.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
The LZO library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The LZO library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with the LZO library; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
http://www.oberhumer.com/opensource/lzo/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE:
|
||||||
|
* the full LZO package can be found at
|
||||||
|
* http://www.oberhumer.com/opensource/lzo/
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __MINILZO_H_INCLUDED
|
||||||
|
#define __MINILZO_H_INCLUDED 1
|
||||||
|
|
||||||
|
#define MINILZO_VERSION 0x20a0 /* 2.10 */
|
||||||
|
|
||||||
|
#if defined(__LZOCONF_H_INCLUDED)
|
||||||
|
# error "you cannot use both LZO and miniLZO"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* internal Autoconf configuration file - only used when building miniLZO */
|
||||||
|
#ifdef MINILZO_HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifndef __LZODEFS_H_INCLUDED
|
||||||
|
#include "lzodefs.h"
|
||||||
|
#endif
|
||||||
|
#undef LZO_HAVE_CONFIG_H
|
||||||
|
#include "lzoconf.h"
|
||||||
|
|
||||||
|
#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION)
|
||||||
|
# error "version mismatch in header files"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
//
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/* Memory required for the wrkmem parameter.
|
||||||
|
* When the required size is 0, you can also pass a NULL pointer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
|
||||||
|
#define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t))
|
||||||
|
#define LZO1X_MEM_DECOMPRESS (0)
|
||||||
|
|
||||||
|
|
||||||
|
/* compression */
|
||||||
|
LZO_EXTERN(int)
|
||||||
|
lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len,
|
||||||
|
lzo_bytep dst, lzo_uintp dst_len,
|
||||||
|
lzo_voidp wrkmem );
|
||||||
|
|
||||||
|
/* decompression */
|
||||||
|
LZO_EXTERN(int)
|
||||||
|
lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len,
|
||||||
|
lzo_bytep dst, lzo_uintp dst_len,
|
||||||
|
lzo_voidp wrkmem /* NOT USED */ );
|
||||||
|
|
||||||
|
/* safe decompression with overrun testing */
|
||||||
|
LZO_EXTERN(int)
|
||||||
|
lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len,
|
||||||
|
lzo_bytep dst, lzo_uintp dst_len,
|
||||||
|
lzo_voidp wrkmem /* NOT USED */ );
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* already included */
|
||||||
|
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@ -3,11 +3,19 @@ TEMPLATE = lib
|
|||||||
CONFIG += staticlib c++17
|
CONFIG += staticlib c++17
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
highlighter_cfg.cpp \
|
||||||
|
highlighter_shock.cpp \
|
||||||
|
highlighter_rumble.cpp \
|
||||||
|
highlighter_gsc.cpp \
|
||||||
logmanager.cpp \
|
logmanager.cpp \
|
||||||
statusbarmanager.cpp
|
statusbarmanager.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
enums.h \
|
enums.h \
|
||||||
|
highlighter_cfg.h \
|
||||||
|
highlighter_shock.h \
|
||||||
|
highlighter_rumble.h \
|
||||||
|
highlighter_gsc.h \
|
||||||
logmanager.h \
|
logmanager.h \
|
||||||
stringutils.h \
|
stringutils.h \
|
||||||
utils.h \
|
utils.h \
|
||||||
|
|||||||
@ -650,25 +650,6 @@ enum MENU_BUTTON {
|
|||||||
APAD_RIGHT = 31
|
APAD_RIGHT = 31
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ASSET_TYPE {
|
|
||||||
ASSET_UNKNOWN = 0,
|
|
||||||
ASSET_ANIMATION = 4, // x_anim PARTIALLY VERIFIED
|
|
||||||
ASSET_MODEL = 5, // xmodel PARTIALLY VERIFIED
|
|
||||||
ASSET_MATERIAL = 6, // material VERIFIED
|
|
||||||
ASSET_BIK_FILE = 7, // .bik file PARTIALLY VERIFIED
|
|
||||||
ASSET_SOUND = 9, // loaded_sound VERIFIED
|
|
||||||
ASSET_COLLISION_MAP = 12, // collision_map PARTIALLY VERIFIED
|
|
||||||
ASSET_SHADER = 13, // shader PARTIALLY VERIFIED
|
|
||||||
ASSET_D3DBSP_DUMP = 17, // d3dbsp dump VERIFIED
|
|
||||||
ASSET_FONT = 20, // font PARTIALLY VERIFIED
|
|
||||||
ASSET_MENU = 21, // menu_file VERIFIED
|
|
||||||
ASSET_LOCAL_STRING = 23, // localized string VERIFIED
|
|
||||||
ASSET_WEAPON = 24, // weapon VERIFIED
|
|
||||||
ASSET_EFFECT = 26, // fx VERIFIED
|
|
||||||
ASSET_RAW_FILE = 32, // raw_file VERIFIED
|
|
||||||
ASSET_STRING_TABLE = 33 // string_table PARTIALLY VERIFIED
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SHADER_TYPE {
|
enum SHADER_TYPE {
|
||||||
SHADER_NONE = 0x00,
|
SHADER_NONE = 0x00,
|
||||||
SHADER_PIXEL = 0x01,
|
SHADER_PIXEL = 0x01,
|
||||||
|
|||||||
111
libs/core/highlighter_cfg.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#include "highlighter_cfg.h"
|
||||||
|
|
||||||
|
Highlighter_CFG::Highlighter_CFG(QTextDocument *parent)
|
||||||
|
: QSyntaxHighlighter(parent) {
|
||||||
|
HighlightingRule rule;
|
||||||
|
|
||||||
|
// Command keywords: set, seta, bind, etc.
|
||||||
|
keywordFormat.setForeground(QColor("#569CD6"));
|
||||||
|
keywordFormat.setFontWeight(QFont::Bold);
|
||||||
|
const QString keywordPatterns[] = {
|
||||||
|
QStringLiteral("\\bset\\b"),
|
||||||
|
QStringLiteral("\\bseta\\b"),
|
||||||
|
QStringLiteral("\\bbind\\b"),
|
||||||
|
QStringLiteral("\\bvstr\\b"),
|
||||||
|
QStringLiteral("\\bsay\\b"),
|
||||||
|
QStringLiteral("\\bwait\\b"),
|
||||||
|
QStringLiteral("\\bexec\\b"),
|
||||||
|
QStringLiteral("\\bunbind\\b"),
|
||||||
|
QStringLiteral("\\bcreatefx\\b"),
|
||||||
|
QStringLiteral("\\bcreatefx_drawdist\\b"),
|
||||||
|
QStringLiteral("\\bcreatefx_scaleid\\b"),
|
||||||
|
QStringLiteral("\\bbindaxis\\b")
|
||||||
|
};
|
||||||
|
for (const QString &pattern : keywordPatterns) {
|
||||||
|
rule.pattern = QRegularExpression(pattern);
|
||||||
|
rule.format = keywordFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Button constants: BUTTON_*, DPAD_*
|
||||||
|
buttonFormat.setForeground(QColor("#4EC9B0"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\b(BUTTON|DPAD)_[A-Z]+\\b"));
|
||||||
|
rule.format = buttonFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Highlight *entire* 'bind var' or 'seta var' as one match, so we can highlight the variable part manually in highlightBlock()
|
||||||
|
// Regex captures the command and the following variable as two groups
|
||||||
|
bindSetVariablePattern = QRegularExpression(QStringLiteral("\\b(bind|bindaxis|set|seta)\\s+(\\w+)"));
|
||||||
|
|
||||||
|
// Quoted strings (highlight first so numbers inside are overridden)
|
||||||
|
quotationFormat.setForeground(QColor("#CE9178"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\".*?\""));
|
||||||
|
rule.format = quotationFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Numbers (normal numbers, no filtering for inside strings, since strings override them)
|
||||||
|
numberFormat.setForeground(QColor("#B5CEA8"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\b-?\\d+(\\.\\d+)?f?\\b"));
|
||||||
|
rule.format = numberFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Comments: single-line comments with //
|
||||||
|
singleLineCommentFormat.setForeground(QColor("#6A9955"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("//[^\n]*"));
|
||||||
|
rule.format = singleLineCommentFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Command chaining symbol: ;
|
||||||
|
operatorFormat.setForeground(QColor("#D4D4D4"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral(";"));
|
||||||
|
rule.format = operatorFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Highlighter_CFG::highlightBlock(const QString &text) {
|
||||||
|
// Apply all standard highlighting rules
|
||||||
|
for (const HighlightingRule &rule : std::as_const(highlightingRules)) {
|
||||||
|
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
|
||||||
|
while (matchIterator.hasNext()) {
|
||||||
|
QRegularExpressionMatch match = matchIterator.next();
|
||||||
|
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Highlight the immediate variable after 'bind', 'bindaxis', 'set', or 'seta'
|
||||||
|
QRegularExpressionMatchIterator iter = bindSetVariablePattern.globalMatch(text);
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
QRegularExpressionMatch match = iter.next();
|
||||||
|
int varStart = match.capturedStart(2); // Group 2 is the variable
|
||||||
|
int varLength = match.capturedLength(2);
|
||||||
|
setFormat(varStart, varLength, variableFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentBlockState(0);
|
||||||
|
|
||||||
|
// Handle multiline comments safely
|
||||||
|
int startIndex = 0;
|
||||||
|
if (previousBlockState() != 1)
|
||||||
|
startIndex = text.indexOf(commentStartExpression);
|
||||||
|
|
||||||
|
while (startIndex >= 0) {
|
||||||
|
QRegularExpressionMatch match = commentEndExpression.match(text, startIndex);
|
||||||
|
int endIndex = match.hasMatch() ? match.capturedStart() : -1;
|
||||||
|
|
||||||
|
int commentLength;
|
||||||
|
if (endIndex == -1) {
|
||||||
|
setCurrentBlockState(1);
|
||||||
|
commentLength = text.length() - startIndex;
|
||||||
|
} else {
|
||||||
|
commentLength = endIndex - startIndex + match.capturedLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safety check to avoid infinite loops
|
||||||
|
if (commentLength <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
||||||
|
startIndex = text.indexOf(commentStartExpression, startIndex + commentLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
45
libs/core/highlighter_cfg.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#ifndef HIGHLIGHTER_CFG_H
|
||||||
|
#define HIGHLIGHTER_CFG_H
|
||||||
|
|
||||||
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
class Highlighter_CFG : public QSyntaxHighlighter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Highlighter_CFG(QTextDocument *parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void highlightBlock(const QString &text) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct HighlightingRule
|
||||||
|
{
|
||||||
|
QRegularExpression pattern;
|
||||||
|
QTextCharFormat format;
|
||||||
|
};
|
||||||
|
QList<HighlightingRule> highlightingRules;
|
||||||
|
|
||||||
|
QRegularExpression commentStartExpression;
|
||||||
|
QRegularExpression commentEndExpression;
|
||||||
|
QRegularExpression bindSetVariablePattern;
|
||||||
|
QTextCharFormat buttonFormat;
|
||||||
|
QTextCharFormat operatorFormat;
|
||||||
|
QTextCharFormat keywordFormat;
|
||||||
|
QTextCharFormat classFormat;
|
||||||
|
QTextCharFormat quotationFormat;
|
||||||
|
QTextCharFormat functionFormat;
|
||||||
|
QTextCharFormat singleLineCommentFormat;
|
||||||
|
QTextCharFormat multiLineCommentFormat;
|
||||||
|
QTextCharFormat preprocessorFormat;
|
||||||
|
QTextCharFormat variableFormat;
|
||||||
|
QTextCharFormat numberFormat;
|
||||||
|
QTextCharFormat devBlockCommentFormat;
|
||||||
|
|
||||||
|
QRegularExpression devCommentStart;
|
||||||
|
QRegularExpression devCommentEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HIGHLIGHTER_CFG_H
|
||||||
138
libs/core/highlighter_gsc.cpp
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#include "highlighter_gsc.h"
|
||||||
|
|
||||||
|
Highlighter_GSC::Highlighter_GSC(QTextDocument *parent)
|
||||||
|
: QSyntaxHighlighter(parent) {
|
||||||
|
HighlightingRule rule;
|
||||||
|
|
||||||
|
// C++ Keywords
|
||||||
|
keywordFormat.setForeground(QColor("#569CD6"));
|
||||||
|
keywordFormat.setFontWeight(QFont::Bold);
|
||||||
|
const QString keywordPatterns[] = {
|
||||||
|
QStringLiteral("\\bchar\\b"), QStringLiteral("\\bclass\\b"), QStringLiteral("\\bconst\\b"),
|
||||||
|
QStringLiteral("\\bdouble\\b"), QStringLiteral("\\benum\\b"), QStringLiteral("\\bexplicit\\b"),
|
||||||
|
QStringLiteral("\\bfriend\\b"), QStringLiteral("\\binline\\b"), QStringLiteral("\\bint\\b"),
|
||||||
|
QStringLiteral("\\blong\\b"), QStringLiteral("\\bnamespace\\b"), QStringLiteral("\\boperator\\b"),
|
||||||
|
QStringLiteral("\\bprivate\\b"), QStringLiteral("\\bprotected\\b"), QStringLiteral("\\bpublic\\b"),
|
||||||
|
QStringLiteral("\\bshort\\b"), QStringLiteral("\\bsignals\\b"), QStringLiteral("\\bsigned\\b"),
|
||||||
|
QStringLiteral("\\bslots\\b"), QStringLiteral("\\bstatic\\b"), QStringLiteral("\\bstruct\\b"),
|
||||||
|
QStringLiteral("\\btemplate\\b"), QStringLiteral("\\btypedef\\b"), QStringLiteral("\\btypename\\b"),
|
||||||
|
QStringLiteral("\\bunion\\b"), QStringLiteral("\\bunsigned\\b"), QStringLiteral("\\bvirtual\\b"),
|
||||||
|
QStringLiteral("\\bvoid\\b"), QStringLiteral("\\bvolatile\\b"), QStringLiteral("\\bbool\\b")
|
||||||
|
};
|
||||||
|
for (const QString &pattern : keywordPatterns) {
|
||||||
|
rule.pattern = QRegularExpression(pattern);
|
||||||
|
rule.format = keywordFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GSC Control Keywords
|
||||||
|
const QString gscKeywords[] = {
|
||||||
|
QStringLiteral("\\bif\\b"), QStringLiteral("\\belse\\b"), QStringLiteral("\\bswitch\\b"),
|
||||||
|
QStringLiteral("\\bcase\\b"), QStringLiteral("\\bbreak\\b"), QStringLiteral("\\bbreakpoint\\b"),
|
||||||
|
QStringLiteral("\\bcontinue\\b"), QStringLiteral("\\bfor\\b"), QStringLiteral("\\bwhile\\b"),
|
||||||
|
QStringLiteral("\\breturn\\b"), QStringLiteral("\\bdefault\\b"), QStringLiteral("\\bwait\\b"),
|
||||||
|
QStringLiteral("\\bwaittill\\b"), QStringLiteral("\\bwaittillframeend\\b"),
|
||||||
|
QStringLiteral("\\bendon\\b"), QStringLiteral("\\bnotify\\b"), QStringLiteral("\\bthread\\b")
|
||||||
|
};
|
||||||
|
for (const QString &pattern : gscKeywords) {
|
||||||
|
rule.pattern = QRegularExpression(pattern);
|
||||||
|
rule.format = keywordFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class format
|
||||||
|
classFormat.setForeground(QColor("#C586C0"));
|
||||||
|
classFormat.setFontWeight(QFont::Bold);
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\bQ[A-Za-z]+\\b"));
|
||||||
|
rule.format = classFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Preprocessor: #include and #using_animtree
|
||||||
|
preprocessorFormat.setForeground(QColor("#D7BA7D"));
|
||||||
|
preprocessorFormat.setFontWeight(QFont::Bold);
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("^\\s*#(?:include|using_animtree)\\b.*"));
|
||||||
|
rule.format = preprocessorFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Hardcoded Variables: self, level, game
|
||||||
|
variableFormat.setForeground(QColor("#4EC9B0"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\b(self|level|game)\\b"));
|
||||||
|
rule.format = variableFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Quoted Strings
|
||||||
|
quotationFormat.setForeground(QColor("#CE9178"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\".*?\""));
|
||||||
|
rule.format = quotationFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Numeric literals (including optional .f)
|
||||||
|
numberFormat.setForeground(QColor("#B5CEA8"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\b-?\\d+(\\.\\d+)?f?\\b"));
|
||||||
|
rule.format = numberFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Boolean literals
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\b(true|false|undefined)\\b"));
|
||||||
|
rule.format = numberFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Function calls
|
||||||
|
functionFormat.setForeground(QColor("#9CDCFE"));
|
||||||
|
functionFormat.setFontItalic(true);
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\b[A-Za-z_][A-Za-z0-9_]*(?=\\s*\\()"));
|
||||||
|
rule.format = functionFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Function pointers ::func
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("::\\b(\\w+)\\b"));
|
||||||
|
rule.format = functionFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Single-line comments
|
||||||
|
singleLineCommentFormat.setForeground(QColor("#6A9955"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("//[^\n]*"));
|
||||||
|
rule.format = singleLineCommentFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Developer block comments /# ... #/
|
||||||
|
devBlockCommentFormat.setForeground(QColor("#6A9955"));
|
||||||
|
devCommentStart = QRegularExpression(QStringLiteral("/#"));
|
||||||
|
devCommentEnd = QRegularExpression(QStringLiteral("#/"));
|
||||||
|
|
||||||
|
// Multi-line comment /* ... */
|
||||||
|
multiLineCommentFormat.setForeground(QColor("#6A9955"));
|
||||||
|
commentStartExpression = QRegularExpression(QStringLiteral("/\\*"));
|
||||||
|
commentEndExpression = QRegularExpression(QStringLiteral("\\*/"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Highlighter_GSC::highlightBlock(const QString &text) {
|
||||||
|
for (const HighlightingRule &rule : std::as_const(highlightingRules)) {
|
||||||
|
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
|
||||||
|
while (matchIterator.hasNext()) {
|
||||||
|
QRegularExpressionMatch match = matchIterator.next();
|
||||||
|
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentBlockState(0);
|
||||||
|
|
||||||
|
int startIndex = 0;
|
||||||
|
if (previousBlockState() != 1)
|
||||||
|
startIndex = text.indexOf(commentStartExpression);
|
||||||
|
|
||||||
|
while (startIndex >= 0) {
|
||||||
|
QRegularExpressionMatch match = commentEndExpression.match(text, startIndex);
|
||||||
|
int endIndex = match.capturedStart();
|
||||||
|
int commentLength = 0;
|
||||||
|
if (endIndex == -1) {
|
||||||
|
setCurrentBlockState(1);
|
||||||
|
commentLength = text.length() - startIndex;
|
||||||
|
} else {
|
||||||
|
commentLength = endIndex - startIndex
|
||||||
|
+ match.capturedLength();
|
||||||
|
}
|
||||||
|
setFormat(startIndex, commentLength, multiLineCommentFormat);
|
||||||
|
startIndex = text.indexOf(commentStartExpression, startIndex + commentLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
42
libs/core/highlighter_gsc.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef HIGHLIGHTER_GSC_H
|
||||||
|
#define HIGHLIGHTER_GSC_H
|
||||||
|
|
||||||
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
class Highlighter_GSC : public QSyntaxHighlighter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Highlighter_GSC(QTextDocument *parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void highlightBlock(const QString &text) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct HighlightingRule
|
||||||
|
{
|
||||||
|
QRegularExpression pattern;
|
||||||
|
QTextCharFormat format;
|
||||||
|
};
|
||||||
|
QList<HighlightingRule> highlightingRules;
|
||||||
|
|
||||||
|
QRegularExpression commentStartExpression;
|
||||||
|
QRegularExpression commentEndExpression;
|
||||||
|
QTextCharFormat keywordFormat;
|
||||||
|
QTextCharFormat classFormat;
|
||||||
|
QTextCharFormat quotationFormat;
|
||||||
|
QTextCharFormat functionFormat;
|
||||||
|
QTextCharFormat singleLineCommentFormat;
|
||||||
|
QTextCharFormat multiLineCommentFormat;
|
||||||
|
QTextCharFormat preprocessorFormat;
|
||||||
|
QTextCharFormat variableFormat;
|
||||||
|
QTextCharFormat numberFormat;
|
||||||
|
QTextCharFormat devBlockCommentFormat;
|
||||||
|
|
||||||
|
QRegularExpression devCommentStart;
|
||||||
|
QRegularExpression devCommentEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HIGHLIGHTER_GSC_H
|
||||||
37
libs/core/highlighter_rumble.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "highlighter_rumble.h"
|
||||||
|
|
||||||
|
Highlighter_Rumble::Highlighter_Rumble(QTextDocument *parent)
|
||||||
|
: QSyntaxHighlighter(parent) {
|
||||||
|
HighlightingRule rule;
|
||||||
|
|
||||||
|
// Format for the "RUMBLEGRAPHFILE" header
|
||||||
|
headerFormat.setForeground(QColor("#569CD6"));
|
||||||
|
headerFormat.setFontWeight(QFont::Bold);
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("^RUMBLEGRAPHFILE\\b"));
|
||||||
|
rule.format = headerFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Format for line count (second line, typically a single integer)
|
||||||
|
countFormat.setForeground(QColor("#C586C0"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("^\\d+$"));
|
||||||
|
rule.format = countFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Format for floating-point number pairs (e.g. 0.0000 0.4701)
|
||||||
|
floatPairFormat.setForeground(QColor("#B5CEA8"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("^\\s*-?\\d+\\.\\d+\\s+-?\\d+\\.\\d+\\s*$"));
|
||||||
|
rule.format = floatPairFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Highlighter_Rumble::highlightBlock(const QString &text) {
|
||||||
|
for (const HighlightingRule &rule : std::as_const(highlightingRules)) {
|
||||||
|
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
|
||||||
|
while (matchIterator.hasNext()) {
|
||||||
|
QRegularExpressionMatch match = matchIterator.next();
|
||||||
|
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentBlockState(0);
|
||||||
|
}
|
||||||
29
libs/core/highlighter_rumble.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef HIGHLIGHTER_RUMBLE_H
|
||||||
|
#define HIGHLIGHTER_RUMBLE_H
|
||||||
|
|
||||||
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
class Highlighter_Rumble : public QSyntaxHighlighter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Highlighter_Rumble(QTextDocument *parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void highlightBlock(const QString &text) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct HighlightingRule {
|
||||||
|
QRegularExpression pattern;
|
||||||
|
QTextCharFormat format;
|
||||||
|
};
|
||||||
|
QVector<HighlightingRule> highlightingRules;
|
||||||
|
|
||||||
|
QTextCharFormat headerFormat;
|
||||||
|
QTextCharFormat countFormat;
|
||||||
|
QTextCharFormat floatPairFormat;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HIGHLIGHTER_RUMBLE_H
|
||||||
43
libs/core/highlighter_shock.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include "highlighter_shock.h"
|
||||||
|
|
||||||
|
Highlighter_Shock::Highlighter_Shock(QTextDocument *parent)
|
||||||
|
: QSyntaxHighlighter(parent) {
|
||||||
|
HighlightingRule rule;
|
||||||
|
|
||||||
|
// Format for bg_shock_* keys
|
||||||
|
keyFormat.setForeground(QColor("#569CD6"));
|
||||||
|
keyFormat.setFontWeight(QFont::Bold);
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\bbg_shock_[\\w]+\\b"));
|
||||||
|
rule.format = keyFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Format for quoted string values
|
||||||
|
stringFormat.setForeground(QColor("#CE9178"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\"[^\"]*\""));
|
||||||
|
rule.format = stringFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Format for numeric values inside quotes (overridden by stringFormat but still useful for raw values)
|
||||||
|
numberFormat.setForeground(QColor("#B5CEA8"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("-?\\d+(\\.\\d+)?"));
|
||||||
|
rule.format = numberFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
|
||||||
|
// Optional: Format for control groups (e.g., bg_shock_volume_*)
|
||||||
|
subgroupFormat.setForeground(QColor("#4EC9B0"));
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\bbg_shock_volume_\\w+\\b"));
|
||||||
|
rule.format = subgroupFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Highlighter_Shock::highlightBlock(const QString &text) {
|
||||||
|
for (const HighlightingRule &rule : std::as_const(highlightingRules)) {
|
||||||
|
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
|
||||||
|
while (matchIterator.hasNext()) {
|
||||||
|
QRegularExpressionMatch match = matchIterator.next();
|
||||||
|
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentBlockState(0);
|
||||||
|
}
|
||||||
30
libs/core/highlighter_shock.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef HIGHLIGHTER_SHOCK_H
|
||||||
|
#define HIGHLIGHTER_SHOCK_H
|
||||||
|
|
||||||
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
class Highlighter_Shock : public QSyntaxHighlighter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Highlighter_Shock(QTextDocument *parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void highlightBlock(const QString &text) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct HighlightingRule {
|
||||||
|
QRegularExpression pattern;
|
||||||
|
QTextCharFormat format;
|
||||||
|
};
|
||||||
|
QVector<HighlightingRule> highlightingRules;
|
||||||
|
|
||||||
|
QTextCharFormat keyFormat;
|
||||||
|
QTextCharFormat stringFormat;
|
||||||
|
QTextCharFormat numberFormat;
|
||||||
|
QTextCharFormat subgroupFormat;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HIGHLIGHTER_SHOCK_H
|
||||||
@ -7,6 +7,8 @@
|
|||||||
#include <QtZlib/zlib.h>
|
#include <QtZlib/zlib.h>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
public:
|
public:
|
||||||
@ -22,6 +24,178 @@ public:
|
|||||||
testFile.close();
|
testFile.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
static quint8 ReverseBits(quint8 b) {
|
||||||
|
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||||
|
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||||
|
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
static QIcon CreateAssetIcon(const QString& name, QColor color = QColor()) {
|
||||||
|
constexpr int iconSize = 32;
|
||||||
|
constexpr int padding = 4;
|
||||||
|
|
||||||
|
QImage result(iconSize, iconSize, QImage::Format_ARGB32);
|
||||||
|
result.fill(Qt::transparent);
|
||||||
|
|
||||||
|
if (!color.isValid()) {
|
||||||
|
color = Utils::StringToColor(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainter painter(&result);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
painter.setRenderHint(QPainter::TextAntialiasing, true);
|
||||||
|
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
|
||||||
|
|
||||||
|
// Draw background
|
||||||
|
QBrush brush(color);
|
||||||
|
brush.setStyle(Qt::SolidPattern);
|
||||||
|
painter.setBrush(color);
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.drawRoundedRect(0, 0, iconSize, iconSize, 4, 4);
|
||||||
|
|
||||||
|
// Set base font
|
||||||
|
QFont font("Heavitas");
|
||||||
|
font.setPixelSize(iconSize); // Start large
|
||||||
|
painter.setFont(font);
|
||||||
|
|
||||||
|
// Adjust font size to fit text width (only reduce, not increase)
|
||||||
|
QFontMetrics fm(font);
|
||||||
|
int textWidth = fm.horizontalAdvance(name);
|
||||||
|
while (textWidth > iconSize - 2 * padding && font.pixelSize() > 1) {
|
||||||
|
font.setPixelSize(font.pixelSize() - 1);
|
||||||
|
painter.setFont(font);
|
||||||
|
fm = QFontMetrics(font);
|
||||||
|
textWidth = fm.horizontalAdvance(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate vertical scaling factor
|
||||||
|
qreal scaleY = 1.2 * iconSize / fm.height();
|
||||||
|
|
||||||
|
// Apply transform: scale vertically, center align
|
||||||
|
painter.save();
|
||||||
|
painter.translate(iconSize / 2.0, iconSize / 2.0);
|
||||||
|
painter.scale(1.0, scaleY);
|
||||||
|
painter.translate(-iconSize / 2.0, -iconSize / 2.0);
|
||||||
|
|
||||||
|
QRect textRect(0, 0, iconSize, iconSize);
|
||||||
|
|
||||||
|
// Draw stroke
|
||||||
|
painter.setPen(Qt::black);
|
||||||
|
for (int dx = 0; dx <= 1; ++dx) {
|
||||||
|
for (int dy = 0; dy <= 1; ++dy) {
|
||||||
|
if (dx || dy)
|
||||||
|
painter.drawText(textRect.translated(dx, dy), Qt::AlignCenter, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw main text
|
||||||
|
painter.setPen(Qt::white);
|
||||||
|
painter.drawText(textRect, Qt::AlignCenter, name);
|
||||||
|
painter.restore();
|
||||||
|
|
||||||
|
// Debug output
|
||||||
|
QDir().mkdir(QDir().absoluteFilePath(".") + "/icons/");
|
||||||
|
result.save(QDir().absoluteFilePath(".") + "/icons/" + name + ".png");
|
||||||
|
|
||||||
|
return QIcon(QPixmap::fromImage(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
static QIcon CreateGameIcon(const int gameNum, QColor color = QColor()) {
|
||||||
|
constexpr int size = 32;
|
||||||
|
constexpr int padding = 4; // pixels of padding on all sides
|
||||||
|
const int contentSize = size - 2 * padding;
|
||||||
|
|
||||||
|
QImage result(size, size, QImage::Format_ARGB32);
|
||||||
|
result.fill(Qt::transparent);
|
||||||
|
|
||||||
|
if (!color.isValid()) {
|
||||||
|
color = Utils::StringToColor(QString("COD%1").arg(gameNum));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainter painter(&result);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
painter.setRenderHint(QPainter::TextAntialiasing, false);
|
||||||
|
painter.setRenderHint(QPainter::SmoothPixmapTransform, false);
|
||||||
|
|
||||||
|
// Draw background
|
||||||
|
painter.setBrush(color);
|
||||||
|
painter.setPen(Qt::NoPen);
|
||||||
|
painter.drawRoundedRect(0, 0, size, size, 4, 4);
|
||||||
|
|
||||||
|
// === Font Setup ===
|
||||||
|
QFont codFont("Heavitas");
|
||||||
|
codFont.setPixelSize(contentSize * 0.40);
|
||||||
|
|
||||||
|
QFont numFont("Heavitas");
|
||||||
|
numFont.setPixelSize(contentSize);
|
||||||
|
|
||||||
|
// === Layout Areas (inside padding) ===
|
||||||
|
const QRect contentRect(padding, padding, contentSize, contentSize);
|
||||||
|
const int col1 = contentRect.left();
|
||||||
|
const int col2 = contentRect.left() + contentRect.width() / 3;
|
||||||
|
|
||||||
|
const int thirdH = contentRect.height() / 3;
|
||||||
|
const QRect codRects[] = {
|
||||||
|
QRect(col1, 2 + contentRect.top(), contentRect.width() / 3, thirdH),
|
||||||
|
QRect(col1, contentRect.top() + thirdH, contentRect.width() / 3, thirdH),
|
||||||
|
QRect(col1, -2 + contentRect.top() + 2 * thirdH, contentRect.width() / 3, thirdH),
|
||||||
|
};
|
||||||
|
|
||||||
|
const QRect numRect(col2, contentRect.top(), contentRect.width() * 2 / 3, contentRect.height());
|
||||||
|
|
||||||
|
const QString codLetters[] = { "C", "O", "D" };
|
||||||
|
const QString numText = QString::number(gameNum);
|
||||||
|
|
||||||
|
// === Stroke pass ===
|
||||||
|
for (int dx = -1; dx <= 2; ++dx) {
|
||||||
|
for (int dy = -1; dy <= 2; ++dy) {
|
||||||
|
if (dx == 0 && dy == 0) continue;
|
||||||
|
|
||||||
|
painter.setPen(Qt::black);
|
||||||
|
painter.setFont(codFont);
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
painter.drawText(codRects[i].translated(dx, dy), Qt::AlignCenter, codLetters[i]);
|
||||||
|
|
||||||
|
painter.setFont(numFont);
|
||||||
|
painter.drawText(numRect.translated(dx, dy), Qt::AlignCenter, numText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Fill pass ===
|
||||||
|
painter.setPen(Qt::white);
|
||||||
|
painter.setFont(codFont);
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
painter.drawText(codRects[i], Qt::AlignCenter, codLetters[i]);
|
||||||
|
|
||||||
|
painter.setFont(numFont);
|
||||||
|
painter.drawText(numRect, Qt::AlignCenter, numText);
|
||||||
|
|
||||||
|
// Save & return icon
|
||||||
|
QDir().mkdir(QDir().absoluteFilePath(".") + "/icons/");
|
||||||
|
result.save(QDir().absoluteFilePath(".") + QString("/icons/COD%1.png").arg(gameNum));
|
||||||
|
|
||||||
|
return QIcon(QPixmap::fromImage(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static QColor StringToColor(const QString& str) {
|
||||||
|
// 1. Hash the string using Qt's built-in hash (MD5, SHA1, or any)
|
||||||
|
QByteArray hash = QCryptographicHash::hash(str.toUtf8(), QCryptographicHash::Md5);
|
||||||
|
|
||||||
|
// 2. Use first 3 bytes of hash for RGB
|
||||||
|
// This guarantees same string = same color every time
|
||||||
|
int r = static_cast<unsigned char>(hash[0]);
|
||||||
|
int g = static_cast<unsigned char>(hash[1]);
|
||||||
|
int b = static_cast<unsigned char>(hash[2]);
|
||||||
|
|
||||||
|
// 3. Optionally adjust brightness or saturation to avoid too dark/light colors
|
||||||
|
QColor color(r, g, b);
|
||||||
|
if (color.value() < 128) { // brighten if too dark
|
||||||
|
color = color.lighter(150);
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
static bool ReadUntilString(QDataStream* stream, const QString& targetString) {
|
static bool ReadUntilString(QDataStream* stream, const QString& targetString) {
|
||||||
if (!stream || targetString.isEmpty()) {
|
if (!stream || targetString.isEmpty()) {
|
||||||
return false; // Invalid input
|
return false; // Invalid input
|
||||||
@ -90,53 +264,6 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
AssetTypeToString()
|
|
||||||
|
|
||||||
Convert asset type string to asset desc string
|
|
||||||
*/
|
|
||||||
static QString AssetTypeToString(const QString aAssetType) {
|
|
||||||
const QString cleanedType = aAssetType.toUpper();
|
|
||||||
if (cleanedType == "17000000") { // localized string PARTIALLY VERIFIED
|
|
||||||
return "LOCAL STRING";
|
|
||||||
} else if (cleanedType == "20000000") { // raw_file PARTIALLY VERIFIED
|
|
||||||
return "RAW FILE";
|
|
||||||
} else if (cleanedType == "1A000000") { // fx PARTIALLY VERIFIED
|
|
||||||
return "EFFECT";
|
|
||||||
} else if (cleanedType == "09000000") { // loaded_sound PARTIALLY VERIFIED
|
|
||||||
return "SOUND";
|
|
||||||
} else if (cleanedType == "04000000") { // x_anim PARTIALLY VERIFIED
|
|
||||||
return "ANIMATION";
|
|
||||||
} else if (cleanedType == "0C000000") { // collision_map PARTIALLY VERIFIED
|
|
||||||
return "COLLISION MAP";
|
|
||||||
} else if (cleanedType == "21000000") { // string_table PARTIALLY VERIFIED
|
|
||||||
return "STRING TABLE";
|
|
||||||
} else if (cleanedType == "15000000") { // menu_file PARTIALLY VERIFIED
|
|
||||||
return "MENU";
|
|
||||||
} else if (cleanedType == "07000000") { // tech set PARTIALLY VERIFIED
|
|
||||||
return "TECH SET";
|
|
||||||
} else if (cleanedType == "18000000") { // weapon PARTIALLY VERIFIED
|
|
||||||
return "WEAPON";
|
|
||||||
} else if (cleanedType == "11000000") { // gfx map PARTIALLY VERIFIED
|
|
||||||
return "GFX MAP";
|
|
||||||
} else if (cleanedType == "12000000") { // light_def PARTIALLY VERIFIED
|
|
||||||
return "LIGHT DEF";
|
|
||||||
} else if (cleanedType == "14000000") { // font PARTIALLY VERIFIED
|
|
||||||
return "FONT";
|
|
||||||
} else if (cleanedType == "05000000") { // xmodel PARTIALLY VERIFIED
|
|
||||||
return "MODEL";
|
|
||||||
} else if (cleanedType == "0D000000") { // d3dbsp PARTIALLY VERIFIED
|
|
||||||
return "D3DBSP";
|
|
||||||
} else if (cleanedType == "06000000") { // image PARTIALLY VERIFIED
|
|
||||||
return "IMAGE";
|
|
||||||
} else if (cleanedType == "0E000000") { // game map sp PARTIALLY VERIFIED
|
|
||||||
return "GAME MAP SP";
|
|
||||||
} else if (cleanedType == "0B000000") { // col map sp PARTIALLY VERIFIED
|
|
||||||
return "COL MAP SP";
|
|
||||||
}
|
|
||||||
return aAssetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
LumpTypeToString()
|
LumpTypeToString()
|
||||||
|
|
||||||
|
|||||||
@ -648,25 +648,6 @@ enum MENU_BUTTON {
|
|||||||
APAD_RIGHT = 31
|
APAD_RIGHT = 31
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ASSET_TYPE {
|
|
||||||
ASSET_UNKNOWN = 0,
|
|
||||||
ASSET_ANIMATION = 4, // x_anim PARTIALLY VERIFIED
|
|
||||||
ASSET_MODEL = 5, // xmodel PARTIALLY VERIFIED
|
|
||||||
ASSET_MATERIAL = 6, // material VERIFIED
|
|
||||||
ASSET_BIK_FILE = 7, // .bik file PARTIALLY VERIFIED
|
|
||||||
ASSET_SOUND = 9, // loaded_sound VERIFIED
|
|
||||||
ASSET_COLLISION_MAP = 12, // collision_map PARTIALLY VERIFIED
|
|
||||||
ASSET_SHADER = 13, // shader PARTIALLY VERIFIED
|
|
||||||
ASSET_D3DBSP_DUMP = 17, // d3dbsp dump VERIFIED
|
|
||||||
ASSET_FONT = 20, // font PARTIALLY VERIFIED
|
|
||||||
ASSET_MENU = 21, // menu_file VERIFIED
|
|
||||||
ASSET_LOCAL_STRING = 23, // localized string VERIFIED
|
|
||||||
ASSET_WEAPON = 24, // weapon VERIFIED
|
|
||||||
ASSET_EFFECT = 26, // fx VERIFIED
|
|
||||||
ASSET_RAW_FILE = 32, // raw_file VERIFIED
|
|
||||||
ASSET_STRING_TABLE = 33 // string_table PARTIALLY VERIFIED
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SHADER_TYPE {
|
enum SHADER_TYPE {
|
||||||
SHADER_NONE = 0x00,
|
SHADER_NONE = 0x00,
|
||||||
SHADER_PIXEL = 0x01,
|
SHADER_PIXEL = 0x01,
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "encryption.h"
|
#include "encryption.h"
|
||||||
#include "QtZlib/zlib.h"
|
#include "QtZlib/zlib.h"
|
||||||
#include "ecrypt-sync.h"
|
#include "ecrypt-sync.h"
|
||||||
|
#include "compression.h"
|
||||||
|
|
||||||
void Encryption::Convert32BitTo8Bit(quint32 value, quint8 *array) {
|
void Encryption::Convert32BitTo8Bit(quint32 value, quint8 *array) {
|
||||||
array[0] = static_cast<quint8>(value >> 0);
|
array[0] = static_cast<quint8>(value >> 0);
|
||||||
@ -350,7 +351,7 @@ void Encryption::generateNewIV(int index, const QByteArray &hash, QByteArray &iv
|
|||||||
ivCounter[index]++;
|
ivCounter[index]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray Encryption::decryptFastFile(const QByteArray &fastFileData)
|
QByteArray Encryption::decryptFastFile_BO2(const QByteArray &fastFileData)
|
||||||
{
|
{
|
||||||
const QByteArray bo2_salsa20_key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE");
|
const QByteArray bo2_salsa20_key = QByteArray::fromHex("641D8A2FE31D3AA63622BBC9CE8587229D42B0F8ED9B924130BF88B65EDC50BE");
|
||||||
|
|
||||||
@ -438,3 +439,68 @@ QByteArray Encryption::decryptFastFile(const QByteArray &fastFileData)
|
|||||||
|
|
||||||
return finalFastFile;
|
return finalFastFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray Encryption::decryptFastFile_BO3(const QByteArray &fastFileData) {
|
||||||
|
const QByteArray salsaKey = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3");
|
||||||
|
|
||||||
|
QByteArray ivTable(0xFB0, 0);
|
||||||
|
fillIVTable(fastFileData, ivTable, 0xFB0 - 1);
|
||||||
|
|
||||||
|
QVector<quint32> ivCounter(4, 1);
|
||||||
|
QDataStream stream(fastFileData);
|
||||||
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
||||||
|
QByteArray finalFastFile;
|
||||||
|
QByteArray sha1Hash(20, 0);
|
||||||
|
QByteArray ivPtr(8, 0);
|
||||||
|
int chunkIndex = 0;
|
||||||
|
|
||||||
|
while (!stream.atEnd()) {
|
||||||
|
if (stream.device()->bytesAvailable() < 4) {
|
||||||
|
qWarning() << "No sufficient data for chunk size at offset:" << stream.device()->pos();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 dataLength;
|
||||||
|
stream >> dataLength;
|
||||||
|
|
||||||
|
if (dataLength == 0 || dataLength > fastFileData.size() - stream.device()->pos()) {
|
||||||
|
qWarning() << "Invalid data length at offset:" << stream.device()->pos();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fillIV(chunkIndex % 4, ivPtr, ivTable, ivCounter);
|
||||||
|
|
||||||
|
ECRYPT_ctx x;
|
||||||
|
ECRYPT_keysetup(&x, reinterpret_cast<const u8*>(salsaKey.constData()), 256, 0);
|
||||||
|
ECRYPT_ivsetup(&x, reinterpret_cast<const u8*>(ivPtr.constData()));
|
||||||
|
|
||||||
|
QByteArray encryptedBlock = fastFileData.mid(stream.device()->pos(), dataLength);
|
||||||
|
QByteArray decryptedBlock(dataLength, Qt::Uninitialized);
|
||||||
|
|
||||||
|
ECRYPT_decrypt_bytes(&x,
|
||||||
|
reinterpret_cast<const u8*>(encryptedBlock.constData()),
|
||||||
|
reinterpret_cast<u8*>(decryptedBlock.data()),
|
||||||
|
dataLength);
|
||||||
|
|
||||||
|
// SHA1 hash update
|
||||||
|
sha1Hash = QCryptographicHash::hash(decryptedBlock, QCryptographicHash::Sha1);
|
||||||
|
|
||||||
|
// Decompress (ZLIB raw DEFLATE)
|
||||||
|
QByteArray decompressedData = Compression::DecompressDeflate(decryptedBlock);
|
||||||
|
if (decompressedData.isEmpty()) {
|
||||||
|
qWarning() << "Failed decompression at chunk index:" << chunkIndex;
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
finalFastFile.append(decompressedData);
|
||||||
|
|
||||||
|
// Update IV table using SHA1
|
||||||
|
generateNewIV(chunkIndex % 4, sha1Hash, ivTable, ivCounter);
|
||||||
|
|
||||||
|
stream.skipRawData(dataLength);
|
||||||
|
chunkIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalFastFile;
|
||||||
|
}
|
||||||
|
|||||||
@ -46,7 +46,8 @@ public:
|
|||||||
|
|
||||||
static void generateNewIV(int index, const QByteArray& hash, QByteArray& ivTable, QVector<quint32>& ivCounter);
|
static void generateNewIV(int index, const QByteArray& hash, QByteArray& ivTable, QVector<quint32>& ivCounter);
|
||||||
|
|
||||||
static QByteArray decryptFastFile(const QByteArray& fastFileData);
|
static QByteArray decryptFastFile_BO2(const QByteArray& fastFileData);
|
||||||
|
static QByteArray decryptFastFile_BO3(const QByteArray& fastFileData);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ENCRYPTION_H
|
#endif // ENCRYPTION_H
|
||||||
|
|||||||
@ -17,4 +17,16 @@ HEADERS += \
|
|||||||
config_win32.h \
|
config_win32.h \
|
||||||
sha1.h
|
sha1.h
|
||||||
|
|
||||||
|
app.depends += \
|
||||||
|
compression
|
||||||
|
|
||||||
|
LIBS += \
|
||||||
|
-L$$OUT_PWD/../ -lcompression
|
||||||
|
|
||||||
|
INCLUDEPATH += \
|
||||||
|
$$PWD/../compression
|
||||||
|
|
||||||
|
DEPENDPATH += \
|
||||||
|
$$PWD/../compression
|
||||||
|
|
||||||
DESTDIR = $$OUT_PWD/../
|
DESTDIR = $$OUT_PWD/../
|
||||||
|
|||||||
115
libs/fastfile/360/fastfile_cod10_360.cpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
#include "fastfile_cod10_360.h"
|
||||||
|
#include "zonefile_cod10_360.h"
|
||||||
|
#include "encryption.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
FastFile_COD10_360::FastFile_COD10_360()
|
||||||
|
: FastFile() {
|
||||||
|
SetCompany(COMPANY_INFINITY_WARD);
|
||||||
|
SetType(FILETYPE_FAST_FILE);
|
||||||
|
SetSignage(SIGNAGE_UNSIGNED);
|
||||||
|
SetMagic(0);
|
||||||
|
SetVersion(0);
|
||||||
|
SetPlatform("360");
|
||||||
|
SetGame("COD10");
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD10_360::FastFile_COD10_360(const QByteArray& aData)
|
||||||
|
: FastFile_COD10_360() {
|
||||||
|
|
||||||
|
if (!aData.isEmpty()) {
|
||||||
|
Load(aData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD10_360::FastFile_COD10_360(const QString aFilePath)
|
||||||
|
: FastFile_COD10_360() {
|
||||||
|
|
||||||
|
if (!aFilePath.isEmpty()) {
|
||||||
|
Load(aFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD10_360::~FastFile_COD10_360() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray FastFile_COD10_360::GetBinaryData() {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FastFile_COD10_360::Load(const QString aFilePath) {
|
||||||
|
if (aFilePath.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check fastfile can be read
|
||||||
|
QFile *file = new QFile(aFilePath);
|
||||||
|
if (!file->open(QIODevice::ReadOnly)) {
|
||||||
|
qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompress fastfile and close
|
||||||
|
const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0);
|
||||||
|
SetStem(fastFileStem);
|
||||||
|
if (!Load(file->readAll())) {
|
||||||
|
qDebug() << "Error: Failed to load fastfile: " << fastFileStem + ".ff";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->close();
|
||||||
|
|
||||||
|
// Open zone file after decompressing ff and writing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FastFile_COD10_360::Load(const QByteArray aData) {
|
||||||
|
QByteArray decompressedData;
|
||||||
|
|
||||||
|
// Create a QDataStream on the input data.
|
||||||
|
QDataStream fastFileStream(aData);
|
||||||
|
fastFileStream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
||||||
|
// For COD7/COD9, use BigEndian.
|
||||||
|
fastFileStream.setByteOrder(QDataStream::BigEndian);
|
||||||
|
|
||||||
|
// Select key based on game.
|
||||||
|
QByteArray key = QByteArray::fromHex("0E50F49F412317096038665622DD091332A209BA0A05A00E1377CEDB0A3CB1D3");
|
||||||
|
|
||||||
|
// Read the 8-byte magic.
|
||||||
|
QByteArray fileMagic(8, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(fileMagic.data(), 8);
|
||||||
|
if (fileMagic != "PHEEBs71") {
|
||||||
|
qWarning() << "Invalid fast file magic!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fastFileStream.skipRawData(4);
|
||||||
|
|
||||||
|
// Read IV table name (32 bytes).
|
||||||
|
QByteArray fileName(32, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(fileName.data(), 32);
|
||||||
|
|
||||||
|
// Skip the RSA signature (256 bytes).
|
||||||
|
QByteArray rsaSignature(256, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(rsaSignature.data(), 256);
|
||||||
|
|
||||||
|
decompressedData = Encryption::decryptFastFile_BO2(aData);
|
||||||
|
|
||||||
|
// For COD9, write out the complete decompressed zone for testing.
|
||||||
|
QFile testFile("exports/" + GetBaseStem() + ".zone");
|
||||||
|
if(testFile.open(QIODevice::WriteOnly)) {
|
||||||
|
testFile.write(decompressedData);
|
||||||
|
testFile.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the zone file with the decompressed data (using an Xbox platform flag).
|
||||||
|
ZoneFile_COD10_360 zoneFile;
|
||||||
|
zoneFile.SetStem(GetBaseStem() + ".zone");
|
||||||
|
zoneFile.Load(decompressedData);
|
||||||
|
SetZoneFile(std::make_shared<ZoneFile_COD10_360>(zoneFile));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
20
libs/fastfile/360/fastfile_cod10_360.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef FASTFILE_COD10_360_H
|
||||||
|
#define FASTFILE_COD10_360_H
|
||||||
|
|
||||||
|
#include "fastfile.h"
|
||||||
|
|
||||||
|
class FastFile_COD10_360 : public FastFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FastFile_COD10_360();
|
||||||
|
FastFile_COD10_360(const QByteArray& aData);
|
||||||
|
FastFile_COD10_360(const QString aFilePath);
|
||||||
|
~FastFile_COD10_360();
|
||||||
|
|
||||||
|
QByteArray GetBinaryData() override;
|
||||||
|
|
||||||
|
bool Load(const QString aFilePath) override;
|
||||||
|
bool Load(const QByteArray aData) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FASTFILE_COD10_360_H
|
||||||
107
libs/fastfile/360/fastfile_cod11_360.cpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include "fastfile_cod11_360.h"
|
||||||
|
#include "zonefile_cod11_360.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "compression.h"
|
||||||
|
#include "encryption.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
FastFile_COD11_360::FastFile_COD11_360()
|
||||||
|
: FastFile() {
|
||||||
|
SetCompany(COMPANY_INFINITY_WARD);
|
||||||
|
SetType(FILETYPE_FAST_FILE);
|
||||||
|
SetSignage(SIGNAGE_UNSIGNED);
|
||||||
|
SetMagic(0);
|
||||||
|
SetVersion(0);
|
||||||
|
SetGame("COD11");
|
||||||
|
SetPlatform("PC");
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD11_360::FastFile_COD11_360(const QByteArray& aData)
|
||||||
|
: FastFile_COD11_360() {
|
||||||
|
|
||||||
|
if (!aData.isEmpty()) {
|
||||||
|
Load(aData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD11_360::FastFile_COD11_360(const QString aFilePath)
|
||||||
|
: FastFile_COD11_360() {
|
||||||
|
if (!aFilePath.isEmpty()) {
|
||||||
|
Load(aFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD11_360::~FastFile_COD11_360() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray FastFile_COD11_360::GetBinaryData() {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FastFile_COD11_360::Load(const QString aFilePath) {
|
||||||
|
if (aFilePath.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check fastfile can be read
|
||||||
|
QFile *file = new QFile(aFilePath);
|
||||||
|
if (!file->open(QIODevice::ReadOnly)) {
|
||||||
|
qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompress fastfile and close
|
||||||
|
const QString fastFileStem = aFilePath.section("/", -1, -1).split('.').first();
|
||||||
|
SetStem(fastFileStem);
|
||||||
|
if (!Load(file->readAll())) {
|
||||||
|
qDebug() << "Error: Failed to load fastfile: " << fastFileStem;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->close();
|
||||||
|
|
||||||
|
// Open zone file after decompressing ff and writing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FastFile_COD11_360::Load(const QByteArray aData) {
|
||||||
|
QByteArray decompressedData;
|
||||||
|
|
||||||
|
// Prepare data stream for parsing
|
||||||
|
QDataStream fastFileStream(aData);
|
||||||
|
fastFileStream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
||||||
|
// Verify magic header
|
||||||
|
QByteArray fileMagic(8, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(fileMagic.data(), 8);
|
||||||
|
if (fileMagic != "TAff0000") {
|
||||||
|
qWarning() << "Invalid fast file magic for COD12!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip: File size (4 bytes), flags/version (4 bytes), unknown (8 bytes), build tag (32 bytes), RSA signature (256 bytes)
|
||||||
|
fastFileStream.skipRawData(4 + 4 + 8 + 32 + 256); // total 304 bytes skipped so far + 8 bytes magic = 312 bytes at correct position.
|
||||||
|
|
||||||
|
// Correctly positioned at 0x138
|
||||||
|
QByteArray encryptedData = aData.mid(0x138);
|
||||||
|
decompressedData = Encryption::decryptFastFile_BO3(encryptedData);
|
||||||
|
|
||||||
|
// Output for verification/testing
|
||||||
|
Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
|
||||||
|
|
||||||
|
// Load the zone file with decompressed data
|
||||||
|
ZoneFile_COD11_360 zoneFile;
|
||||||
|
zoneFile.SetStem(GetBaseStem() + ".zone");
|
||||||
|
if (!zoneFile.Load(decompressedData)) {
|
||||||
|
qWarning() << "Failed to load ZoneFile!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetZoneFile(std::make_shared<ZoneFile_COD11_360>(zoneFile));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
20
libs/fastfile/360/fastfile_cod11_360.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef FASTFILE_COD11_360_H
|
||||||
|
#define FASTFILE_COD11_360_H
|
||||||
|
|
||||||
|
#include "fastfile.h"
|
||||||
|
|
||||||
|
class FastFile_COD11_360 : public FastFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FastFile_COD11_360();
|
||||||
|
FastFile_COD11_360(const QByteArray &aData);
|
||||||
|
FastFile_COD11_360(const QString aFilePath);
|
||||||
|
~FastFile_COD11_360();
|
||||||
|
|
||||||
|
QByteArray GetBinaryData() override;
|
||||||
|
|
||||||
|
bool Load(const QString aFilePath) override;
|
||||||
|
bool Load(const QByteArray aData) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FASTFILE_COD11_360_H
|
||||||
107
libs/fastfile/360/fastfile_cod12_360.cpp
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#include "fastfile_cod12_360.h"
|
||||||
|
#include "zonefile_cod12_360.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "compression.h"
|
||||||
|
#include "encryption.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
FastFile_COD12_360::FastFile_COD12_360()
|
||||||
|
: FastFile() {
|
||||||
|
SetCompany(COMPANY_INFINITY_WARD);
|
||||||
|
SetType(FILETYPE_FAST_FILE);
|
||||||
|
SetSignage(SIGNAGE_UNSIGNED);
|
||||||
|
SetMagic(0);
|
||||||
|
SetVersion(0);
|
||||||
|
SetGame("COD12");
|
||||||
|
SetPlatform("PC");
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD12_360::FastFile_COD12_360(const QByteArray& aData)
|
||||||
|
: FastFile_COD12_360() {
|
||||||
|
|
||||||
|
if (!aData.isEmpty()) {
|
||||||
|
Load(aData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD12_360::FastFile_COD12_360(const QString aFilePath)
|
||||||
|
: FastFile_COD12_360() {
|
||||||
|
if (!aFilePath.isEmpty()) {
|
||||||
|
Load(aFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD12_360::~FastFile_COD12_360() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray FastFile_COD12_360::GetBinaryData() {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FastFile_COD12_360::Load(const QString aFilePath) {
|
||||||
|
if (aFilePath.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check fastfile can be read
|
||||||
|
QFile *file = new QFile(aFilePath);
|
||||||
|
if (!file->open(QIODevice::ReadOnly)) {
|
||||||
|
qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompress fastfile and close
|
||||||
|
const QString fastFileStem = aFilePath.section("/", -1, -1).split('.').first();
|
||||||
|
SetStem(fastFileStem);
|
||||||
|
if (!Load(file->readAll())) {
|
||||||
|
qDebug() << "Error: Failed to load fastfile: " << fastFileStem;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->close();
|
||||||
|
|
||||||
|
// Open zone file after decompressing ff and writing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FastFile_COD12_360::Load(const QByteArray aData) {
|
||||||
|
QByteArray decompressedData;
|
||||||
|
|
||||||
|
// Prepare data stream for parsing
|
||||||
|
QDataStream fastFileStream(aData);
|
||||||
|
fastFileStream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
||||||
|
// Verify magic header
|
||||||
|
QByteArray fileMagic(8, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(fileMagic.data(), 8);
|
||||||
|
if (fileMagic != "TAff0000") {
|
||||||
|
qWarning() << "Invalid fast file magic for COD12!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip: File size (4 bytes), flags/version (4 bytes), unknown (8 bytes), build tag (32 bytes), RSA signature (256 bytes)
|
||||||
|
fastFileStream.skipRawData(4 + 4 + 8 + 32 + 256); // total 304 bytes skipped so far + 8 bytes magic = 312 bytes at correct position.
|
||||||
|
|
||||||
|
// Correctly positioned at 0x138
|
||||||
|
QByteArray encryptedData = aData.mid(0x138);
|
||||||
|
decompressedData = Encryption::decryptFastFile_BO3(encryptedData);
|
||||||
|
|
||||||
|
// Output for verification/testing
|
||||||
|
Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
|
||||||
|
|
||||||
|
// Load the zone file with decompressed data
|
||||||
|
ZoneFile_COD12_360 zoneFile;
|
||||||
|
zoneFile.SetStem(GetBaseStem() + ".zone");
|
||||||
|
if (!zoneFile.Load(decompressedData)) {
|
||||||
|
qWarning() << "Failed to load ZoneFile!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetZoneFile(std::make_shared<ZoneFile_COD12_360>(zoneFile));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
20
libs/fastfile/360/fastfile_cod12_360.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef FASTFILE_COD12_360_H
|
||||||
|
#define FASTFILE_COD12_360_H
|
||||||
|
|
||||||
|
#include "fastfile.h"
|
||||||
|
|
||||||
|
class FastFile_COD12_360 : public FastFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FastFile_COD12_360();
|
||||||
|
FastFile_COD12_360(const QByteArray &aData);
|
||||||
|
FastFile_COD12_360(const QString aFilePath);
|
||||||
|
~FastFile_COD12_360();
|
||||||
|
|
||||||
|
QByteArray GetBinaryData() override;
|
||||||
|
|
||||||
|
bool Load(const QString aFilePath) override;
|
||||||
|
bool Load(const QByteArray aData) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FASTFILE_COD12_360_H
|
||||||
@ -1,25 +1,48 @@
|
|||||||
#include "fastfile_cod2.h"
|
#include "fastfile_cod2_360.h"
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "compression.h"
|
#include "compression.h"
|
||||||
#include "zonefile_cod2.h"
|
#include "zonefile_cod2_360.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
FastFile_COD2::FastFile_COD2() {
|
FastFile_COD2_360::FastFile_COD2_360()
|
||||||
|
: FastFile() {
|
||||||
|
SetCompany(COMPANY_INFINITY_WARD);
|
||||||
|
SetType(FILETYPE_FAST_FILE);
|
||||||
|
SetSignage(SIGNAGE_UNSIGNED);
|
||||||
|
SetMagic(0);
|
||||||
|
SetVersion(0);
|
||||||
|
SetPlatform("360");
|
||||||
|
SetGame("COD2");
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD2_360::FastFile_COD2_360(const QByteArray& aData)
|
||||||
|
: FastFile_COD2_360() {
|
||||||
|
|
||||||
|
if (!aData.isEmpty()) {
|
||||||
|
Load(aData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD2_360::FastFile_COD2_360(const QString aFilePath)
|
||||||
|
: FastFile_COD2_360() {
|
||||||
|
|
||||||
|
if (!aFilePath.isEmpty()) {
|
||||||
|
Load(aFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD2_360::~FastFile_COD2_360() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FastFile_COD2::~FastFile_COD2() {
|
QByteArray FastFile_COD2_360::GetBinaryData() {
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray FastFile_COD2::GetBinaryData() {
|
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FastFile_COD2::Load(const QString aFilePath) {
|
bool FastFile_COD2_360::Load(const QString aFilePath) {
|
||||||
if (aFilePath.isEmpty()) {
|
if (aFilePath.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -32,11 +55,9 @@ bool FastFile_COD2::Load(const QString aFilePath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decompress fastfile and close
|
// Decompress fastfile and close
|
||||||
const QString fastFileStem = aFilePath.section("/", -1, -1).section(".", 0, 0);
|
SetStem(aFilePath.section("/", -1, -1));
|
||||||
qDebug() << "fastFileStem: " << fastFileStem;
|
|
||||||
SetStem(fastFileStem);
|
|
||||||
if (!Load(file->readAll())) {
|
if (!Load(file->readAll())) {
|
||||||
qDebug() << "Error: Failed to load fastfile: " << fastFileStem;
|
qDebug() << "Error: Failed to load fastfile: " << GetStem();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,38 +67,22 @@ bool FastFile_COD2::Load(const QString aFilePath) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FastFile_COD2::Load(const QByteArray aData) {
|
bool FastFile_COD2_360::Load(const QByteArray aData) {
|
||||||
// Create a QDataStream on the input data.
|
// Create a QDataStream on the input data.
|
||||||
QDataStream fastFileStream(aData);
|
QDataStream fastFileStream(aData);
|
||||||
fastFileStream.setByteOrder(QDataStream::LittleEndian);
|
fastFileStream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
||||||
// Parse header values.
|
|
||||||
SetCompany(COMPANY_INFINITY_WARD);
|
|
||||||
SetType(FILETYPE_FAST_FILE);
|
|
||||||
SetSignage(SIGNAGE_UNSIGNED);
|
|
||||||
SetMagic(0);
|
|
||||||
SetVersion(0);
|
|
||||||
SetPlatform("360");
|
|
||||||
SetGame("COD2");
|
|
||||||
|
|
||||||
Utils::ReadUntilHex(&fastFileStream, "78");
|
Utils::ReadUntilHex(&fastFileStream, "78");
|
||||||
QByteArray compressedData = aData.mid(fastFileStream.device()->pos());
|
QByteArray compressedData = aData.mid(fastFileStream.device()->pos());
|
||||||
QByteArray decompressedData = Compression::DecompressZLIB(compressedData);
|
QByteArray decompressedData = Compression::DecompressZLIB(compressedData);
|
||||||
|
|
||||||
QDir exportsDir(QDir::currentPath());
|
Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
|
||||||
exportsDir.mkdir("exports");
|
|
||||||
|
|
||||||
QFile testFile("exports/" + GetStem() + ".zone");
|
|
||||||
if(testFile.open(QIODevice::WriteOnly)) {
|
|
||||||
testFile.write(decompressedData);
|
|
||||||
testFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the zone file with the decompressed data (using an Xbox platform flag).
|
// Load the zone file with the decompressed data (using an Xbox platform flag).
|
||||||
ZoneFile_COD2 zoneFile;
|
ZoneFile_COD2_360 zoneFile;
|
||||||
zoneFile.SetStem(GetStem());
|
zoneFile.SetStem(GetBaseStem() + ".zone");
|
||||||
zoneFile.Load(decompressedData, FF_PLATFORM_XBOX);
|
zoneFile.Load(decompressedData);
|
||||||
SetZoneFile(std::make_shared<ZoneFile_COD2>(zoneFile));
|
SetZoneFile(std::make_shared<ZoneFile_COD2_360>(zoneFile));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
20
libs/fastfile/360/fastfile_cod2_360.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef FASTFILE_COD2_360_H
|
||||||
|
#define FASTFILE_COD2_360_H
|
||||||
|
|
||||||
|
#include "fastfile.h"
|
||||||
|
|
||||||
|
class FastFile_COD2_360 : public FastFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FastFile_COD2_360();
|
||||||
|
FastFile_COD2_360(const QByteArray& aData);
|
||||||
|
FastFile_COD2_360(const QString aFilePath);
|
||||||
|
~FastFile_COD2_360();
|
||||||
|
|
||||||
|
QByteArray GetBinaryData() override;
|
||||||
|
|
||||||
|
bool Load(const QString aFilePath) override;
|
||||||
|
bool Load(const QByteArray aData) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FASTFILE_COD2_360_H
|
||||||
139
libs/fastfile/360/fastfile_cod4_360.cpp
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
#include "fastfile_cod4_360.h"
|
||||||
|
#include "zonefile_cod4_360.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "compression.h"
|
||||||
|
#include "statusbarmanager.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
FastFile_COD4_360::FastFile_COD4_360()
|
||||||
|
: FastFile() {
|
||||||
|
SetCompany(COMPANY_INFINITY_WARD);
|
||||||
|
SetType(FILETYPE_FAST_FILE);
|
||||||
|
SetSignage(SIGNAGE_UNSIGNED);
|
||||||
|
SetMagic(0);
|
||||||
|
SetVersion(0);
|
||||||
|
SetPlatform("360");
|
||||||
|
SetGame("COD4");
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD4_360::FastFile_COD4_360(const QByteArray& aData)
|
||||||
|
: FastFile_COD4_360() {
|
||||||
|
|
||||||
|
if (!aData.isEmpty()) {
|
||||||
|
Load(aData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD4_360::FastFile_COD4_360(const QString aFilePath)
|
||||||
|
: FastFile_COD4_360() {
|
||||||
|
|
||||||
|
if (!aFilePath.isEmpty()) {
|
||||||
|
Load(aFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FastFile_COD4_360::~FastFile_COD4_360() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray FastFile_COD4_360::GetBinaryData() {
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FastFile_COD4_360::Load(const QString aFilePath) {
|
||||||
|
StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/path", 1000);
|
||||||
|
|
||||||
|
if (aFilePath.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check fastfile can be read
|
||||||
|
QFile *file = new QFile(aFilePath);
|
||||||
|
if (!file->open(QIODevice::ReadOnly)) {
|
||||||
|
qDebug() << QString("Error: Failed to open FastFile: %1!").arg(aFilePath);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompress fastfile and close
|
||||||
|
QString fastFileStem = aFilePath.split('/').last().replace(".ff", "");
|
||||||
|
SetStem(fastFileStem);
|
||||||
|
if (!Load(file->readAll())) {
|
||||||
|
qDebug() << "Error: Failed to load fastfile: " << fastFileStem;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->close();
|
||||||
|
|
||||||
|
// Open zone file after decompressing ff and writing
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FastFile_COD4_360::Load(const QByteArray aData) {
|
||||||
|
StatusBarManager::instance().updateStatus("Loading COD5 Fast File w/data", 1000);
|
||||||
|
QByteArray decompressedData;
|
||||||
|
|
||||||
|
const QString header = aData.left(8);
|
||||||
|
if (header == "IWffu100") {
|
||||||
|
// For COD5, simply decompress from offset 12.
|
||||||
|
decompressedData = Compression::DecompressZLIB(aData.mid(12));
|
||||||
|
} else if (header == "IWff0100") {
|
||||||
|
// Create a QDataStream on the input data.
|
||||||
|
QDataStream fastFileStream(aData.mid(12));
|
||||||
|
fastFileStream.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
|
||||||
|
QByteArray magic(8, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(magic.data(), 8);
|
||||||
|
if (magic != "IWffs100") {
|
||||||
|
qDebug() << "Found invalid signed header: " << magic;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fastFileStream.skipRawData(4);
|
||||||
|
|
||||||
|
QByteArray rsaSigChecksum(32, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(rsaSigChecksum.data(), 32);
|
||||||
|
|
||||||
|
QByteArray rsaSig(256, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(rsaSig.data(), 256);
|
||||||
|
|
||||||
|
QByteArray fileName(32, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(fileName.data(), 32);
|
||||||
|
|
||||||
|
fastFileStream.skipRawData(4);
|
||||||
|
|
||||||
|
QByteArray bigSigBlock(7856, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(bigSigBlock.data(), 7856);
|
||||||
|
|
||||||
|
QVector<QByteArray> sigBlocks = QVector<QByteArray>();
|
||||||
|
QByteArray compressedData;
|
||||||
|
|
||||||
|
for (int i = 0; i < (aData.size() / 202000) + 1; i++)
|
||||||
|
{
|
||||||
|
QByteArray newSigBlocks;
|
||||||
|
for (int j = 0; j < 256; j++) {
|
||||||
|
QByteArray newSigBlock(32, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(newSigBlock.data(), 32);
|
||||||
|
sigBlocks.append(newSigBlock);
|
||||||
|
}
|
||||||
|
newSigBlocks.append(newSigBlocks);
|
||||||
|
for (int j = 0; j < 256; j++) {
|
||||||
|
QByteArray compressedChunk(8192, Qt::Uninitialized);
|
||||||
|
fastFileStream.readRawData(compressedChunk.data(), 8192);
|
||||||
|
compressedData.append(compressedChunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
decompressedData = Compression::DecompressZLIB(compressedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Utils::ExportData(GetBaseStem() + ".zone", decompressedData);
|
||||||
|
|
||||||
|
ZoneFile_COD4_360 zoneFile;
|
||||||
|
zoneFile.SetStem(GetBaseStem() + ".zone");
|
||||||
|
zoneFile.Load(decompressedData);
|
||||||
|
SetZoneFile(std::make_shared<ZoneFile_COD4_360>(zoneFile));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
20
libs/fastfile/360/fastfile_cod4_360.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef FASTFILE_COD4_360_H
|
||||||
|
#define FASTFILE_COD4_360_H
|
||||||
|
|
||||||
|
#include "fastfile.h"
|
||||||
|
|
||||||
|
class FastFile_COD4_360 : public FastFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FastFile_COD4_360();
|
||||||
|
FastFile_COD4_360(const QByteArray &aData);
|
||||||
|
FastFile_COD4_360(const QString aFilePath);
|
||||||
|
~FastFile_COD4_360();
|
||||||
|
|
||||||
|
QByteArray GetBinaryData() override;
|
||||||
|
|
||||||
|
bool Load(const QString aFilePath) override;
|
||||||
|
bool Load(const QByteArray aData) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FASTFILE_COD4_360_H
|
||||||