Explicit Asset ID refactor

This commit is contained in:
Jack Andersen 2019-09-30 21:38:03 -10:00
parent c7ffe725ae
commit 16ca0d24c2
113 changed files with 1782 additions and 2057 deletions

View File

@ -1,110 +1,263 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0" is_locked="true"> <profile version="1.0" is_locked="false">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="Annotator" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="ARCIssues" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="AccessorsWereOverridden" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AlwaysNilVariable" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="AmdModulesDependencies" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ArgumentSelectionDefectsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ArrayIssues" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="ArrayIssues" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="AssociatedTypeMismatch" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BadExpressionStatementJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BibtexDuplicateBibliography" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BibtexDuplicateBibliographystyle" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BibtexDuplicateId" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BibtexMissingBibliographystyle" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="BridgeCastIssues" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CallDealloc" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CallerJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CannotResolve" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="CannotResolve" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="CheckDtdRefs" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="CheckImageSize" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckEmptyScriptTag" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="CheckNodeTest" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckTagEmptyBody" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ClangTidyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckValidXmlInScriptTagBody" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="CoffeeScriptArgumentsOutsideFunction" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CheckXmlFileWithXercesValidator" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="CoffeeScriptFunctionSignatures" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ClangTidyInspection" enabled="false" level="WARNING" enabled_by_default="false"> <inspection_tool class="CoffeeScriptInfiniteLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<option name="clangTidyChecks" value="*,-cert-env33-c,-cppcoreguidelines-no-malloc,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-union-access,-google-*,google-default-arguments,google-explicit-constructor,google-runtime-member-string-references,google-runtime-memset,google-runtime-operator,-llvm-*,-readability-simplify-boolean-expr,-readability-braces-around-statements,-readability-identifier-naming,-readability-function-size,-misc-bool-pointer-implicit-conversion,-misc-unused-parameters,-modernize-use-using,-safety-no-assembler,-clang-diagnostic-*,-clang-analyzer-*,-cert-flp30-c,-cppcoreguidelines-pro-type-vararg" /> <inspection_tool class="CoffeeScriptLiteralNotFunction" enabled="false" level="ERROR" enabled_by_default="false" />
</inspection_tool> <inspection_tool class="CoffeeScriptModulesDependencies" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="CommandLineInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="CoffeeScriptSillyAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CoffeeScriptSwitchStatementWithNoDefaultBranch" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CoffeeScriptUnusedLocalSymbols" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CommaExpressionJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConstExpressionRequired" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="ConstExpressionRequired" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="ConstantConditionalExpressionJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConstantIfStatementJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ConstructionIsNotAllowed" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="ConstructionIsNotAllowed" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="ContinueOrBreakFromFinallyBlockJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssFloatPxLength" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="CssInvalidAtRule" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidCharsetRule" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssInvalidElement" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidFunction" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidHtmlTagReference" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssInvalidImport" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssInvalidMediaFeature" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidPropertyValue" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssInvalidPseudoSelector" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssMissingComma" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssNegativeValue" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssNoGenericFontName" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssOverwrittenProperties" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssRedundantUnit" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssReplaceWithShorthandSafely" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="CssReplaceWithShorthandUnsafely" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="CssUnitlessNumber" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssUnknownProperty" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CssUnknownTarget" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssUnresolvedClass" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssUnresolvedCustomProperty" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="CssUnusedSymbol" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DeprecatedAPI" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="DeprecatedAPI" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DeprecatedApi" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DerivedFunctionsReturnTypeMismatch" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="DerivedFunctionsReturnTypeMismatch" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="DuplicateAttribute" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicateCaseLabelJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicateDeclarations" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="DuplicateDeclarations" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="DuplicateSwitchCase" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="DuplicateSwitchCase" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EndlessLoop" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ES6BindWithArrowFunction" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EqualityInConditionalOperator" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ES6CheckImport" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ES6ClassMemberInitializationOrder" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ES6ConvertModuleExportToExport" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ES6ConvertRequireIntoImport" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ES6ConvertToForOf" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ES6ConvertVarToLetConst" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ES6MissingAwait" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ES6ModulesDependencies" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ES6PossiblyAsyncFunction" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ES6ShorthandObjectProperty" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="ES6UnusedImports" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EmptyDeclOrStmtInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EmptyStatementBodyJS" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_reportEmptyBlocks" value="false" />
</inspection_tool>
<inspection_tool class="ExceptionCaughtLocallyJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FallThroughInSwitchStatementJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FieldMustBeInitialized" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="FieldMustBeInitialized" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="FormatSpecifiers" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="FlowJSConfig" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FunctionImplicitDeclarationInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="FlowJSFlagCommentPlacement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FunctionParameterCountMismatch" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="FunctionParameterCountMismatch" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="HidesUpperScope" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="HardwiredNamespacePrefix" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HidingNonVirtualFunction" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="HidesClassScope" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlExtraClosingTag" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="HtmlDeprecatedAttribute" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlMissingClosingTag" enabled="true" level="INFORMATION" enabled_by_default="true" /> <inspection_tool class="HtmlDeprecatedTag" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlUnknownAnchorTarget" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="HtmlFormInputWithoutLabel" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="HtmlRequiredAltAttribute" enabled="false" level="WARNING" enabled_by_default="false" />
<option name="myValues"> <inspection_tool class="HtmlRequiredLangAttribute" enabled="false" level="WARNING" enabled_by_default="false" />
<value> <inspection_tool class="HtmlRequiredTitleElement" enabled="false" level="WARNING" enabled_by_default="false" />
<list size="0" /> <inspection_tool class="ImplementationHasNoInterface" enabled="false" level="WARNING" enabled_by_default="false" />
</value> <inspection_tool class="ImplicitTypeConversion" enabled="false" level="WARNING" enabled_by_default="false" />
</option> <inspection_tool class="IncompatibleMaskJS" enabled="false" level="WARNING" enabled_by_default="false" />
<option name="myCustomValuesEnabled" value="true" />
</inspection_tool>
<inspection_tool class="HtmlUnknownBooleanAttribute" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myValues">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="nobr" />
<item index="1" class="java.lang.String" itemvalue="noembed" />
<item index="2" class="java.lang.String" itemvalue="comment" />
<item index="3" class="java.lang.String" itemvalue="noscript" />
<item index="4" class="java.lang.String" itemvalue="embed" />
<item index="5" class="java.lang.String" itemvalue="script" />
</list>
</value>
</option>
<option name="myCustomValuesEnabled" value="true" />
</inspection_tool>
<inspection_tool class="HtmlUnknownTarget" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ImplicitIntegerAndEnumConversion" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ImplicitPointerAndIntegerConversion" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IncompatibleEnums" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IncompatibleInitializers" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IncompatiblePointers" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IncompatibleTypes" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="IncompatibleTypes" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="InconsistentLineSeparators" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="IndexZeroUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InfiniteRecursion" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="InfiniteLoopJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InfiniteRecursionJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InitializationIssue" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="InitializerIssues" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="InitializerIssues" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="InjectedReferences" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="IntegerTypeRequired" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="IntegerTypeRequired" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="JsonDuplicatePropertyKeys" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="InterfaceHasNoImplementation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JsonStandardCompliance" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="JSAccessibilityCheck" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="KRUnspecifiedParameters" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="JSAnnotator" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="LocalValueEscapesScope" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="JSArrowFunctionBracesCanBeRemoved" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="LongLine" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="JSAssignmentUsedAsCondition" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LossyEncoding" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="JSBitwiseOperatorUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MarkdownUnresolvedFileReference" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="JSCheckFunctionSignatures" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSClosureCompilerSyntax" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSCommentMatchesSignature" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSComparisonWithNaN" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSConsecutiveCommasInArrayLiteral" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSConstructorReturnsPrimitive" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSDeprecatedSymbols" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSDuplicatedDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSEqualityComparisonWithCoercion" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSFileReferences" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSFunctionExpressionToArrowFunction" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="JSIgnoredPromiseFromCall" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSIncompatibleTypesComparison" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSJQueryEfficiency" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSJoinVariableDeclarationAndAssignment" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="JSLastCommaInArrayLiteral" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSLastCommaInObjectLiteral" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSMethodCanBeStatic" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSMismatchedCollectionQueryUpdate" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSMissingSwitchBranches" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="JSMissingSwitchDefault" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="JSNonASCIINames" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSObjectNullOrUndefined" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSPotentiallyInvalidConstructorUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSPotentiallyInvalidTargetOfIndexedPropertyAccess" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSPotentiallyInvalidUsageOfClassThis" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSPotentiallyInvalidUsageOfThis" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSPrimitiveTypeWrapperUsage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSRedeclarationOfBlockScope" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="JSRedundantSwitchStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSReferencingArgumentsOutsideOfFunction" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="JSReferencingMutableVariableFromClosure" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSRemoveUnnecessaryParentheses" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="JSStringConcatenationToES6Template" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="JSSuspiciousNameCombination" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSSwitchVariableDeclarationIssue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSTestFailedLine" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSTypeOfValues" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUndeclaredVariable" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSUndefinedPropertyAssignment" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnfilteredForInLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnnecessarySemicolon" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnreachableSwitchBranches" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnresolvedExtXType" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnresolvedFunction" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnresolvedLibraryURL" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnresolvedVariable" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnusedAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnusedGlobalSymbols" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSUnusedLocalSymbols" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSValidateJSDoc" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JSValidateTypes" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JSXNamespaceValidation" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="Json5StandardCompliance" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="JsonSchemaCompliance" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="JsonSchemaDeprecation" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="JsonSchemaRefReference" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="KeyValueCodingInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LastArgumentMustBeNull" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexAvoidEqnarray" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexCdot" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexCiteBeforePeriod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexCollapseCite" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexCommandAlreadyDefined" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexDiacriticIJ" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexDiscouragedUseOfDef" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexDuplicateDefinition" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexDuplicateLabel" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexEllipsis" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexEnDash" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexEncloseWithLeftRight" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexEquationReference" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexExtremeInequality" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexFigureNotReferenced" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexFileNotFound" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexGatherEquations" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexGroupedSubSupScript" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexInclusionLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexLabelConvention" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexLineBreak" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexMakeatletter" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexMathOperatorEscape" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexMightBreakTexify" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexMissingImport" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexMissingLabel" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexMultipleIncludes" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexNestedIncludes" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexNoExtension" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexNonBreakingSpace" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexNonMatchingEnvironment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexNonMatchingIf" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexOverInsteadOfFrac" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexPrimitiveEquation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexPrimitiveStyle" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexQedHere" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexRedundantEscape" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexRedundantPar" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexSentenceEndWithCapital" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexSpaceAfterAbbreviation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexTooLargeSection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexTrimWhitespace" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexUnicode" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexUnresolvedReference" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LatexXInsteadOfTimes" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LessResolvedByNameOnly" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="LessUnresolvedMixin" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LessUnresolvedVariable" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="LoopStatementThatDoesntLoopJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MemberFunctionCanBeStaticInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="MemberVisibility" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="MemberVisibility" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="MissingReturn" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MethodIsLaterInTheScope" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MissingSwitchCase" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MethodParameterCountMismatch" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="MssqlBuiltinInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MysqlParsingInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NoAttributeForProperty" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NoClassDefinition" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NoDefaultBaseConstructor" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="NoDefaultBaseConstructor" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="NonAsciiCharacters" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NoGetterOrSetter" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NodeModulesDependencies" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="NotAssignable" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="NotAssignable" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="NotImplementedFunctions" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NotImplementedMethods" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NotInitializedVariable" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NotImplementsProtocol" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="NotSuperclass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NotInHierarchyMessage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCDFAInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NotReleasedValue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCGlobalUnused" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NotVisibleClass" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCLoopDoesntUseConditionVariableInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NpmUsedModulesInstalled" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="OCSimplifyInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCLegacyObjCLiteralInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCUnusedGlobalDeclarationInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCNotLocalizedStringInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCUnusedMacroInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCNotReleasedIvarInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCUnusedStructInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCUnusedClassInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCUnusedTemplateParameterInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCUnusedInstanceVariableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCUnusedMethodInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OCUnusedPropertyInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ObsoleteNSLiteral" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OctalIntegerJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OtherCpp" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="OtherObjC" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="OverriddenAttributeMismatch" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="OverriddenTypeMismatch" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PackageJsonMismatchedDependency" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PgSelectFromProcedureInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PointerTypeRequired" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="PointerTypeRequired" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="ProblematicWhitespace" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="PointlessArithmeticExpressionJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyAbstractClassInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="PointlessBooleanExpressionJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyArgumentEqualDefaultInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" /> <inspection_tool class="PrivateCategoryShouldBeNearImplementation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyArgumentListInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PropertyAndIvarTypeMismatch" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyAssignmentToLoopOrWithParameterInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="PyAsyncCallInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyAttributeOutsideInitInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyAugmentAssignmentInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="PyBroadExceptionInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyByteLiteralInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyCallByClassInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyCallingNonCallableInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyChainedComparisonsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyClassHasNoInitInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyClassicStyleClassInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyComparisonWithNoneInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyCompatibilityInspection" enabled="false" level="WARNING" enabled_by_default="false"> <inspection_tool class="PyCompatibilityInspection" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ourVersions"> <option name="ourVersions">
<value> <value>
@ -115,115 +268,109 @@
</value> </value>
</option> </option>
</inspection_tool> </inspection_tool>
<inspection_tool class="PyDecoratorInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PyDataclassInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyDefaultArgumentInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PyProtocolInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyDeprecationInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyDictCreationInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyDictDuplicateKeysInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyDocstringTypesInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyDunderSlotsInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyExceptClausesOrderInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyExceptionInheritInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyFromFutureImportInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyGlobalUndefinedInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyInconsistentIndentationInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyIncorrectDocstringInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyInitNewSignatureInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyInterpreterInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyListCreationInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyMandatoryEncodingInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyMethodFirstArgAssignmentInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyMethodMayBeStaticInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyMethodOverridingInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyMethodParametersInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyMissingConstructorInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyMissingOrEmptyDocstringInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="PyMissingTypeHintsInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="PyNamedTupleInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyNestedDecoratorsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyNonAsciiCharInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyNoneFunctionAssignmentInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyOldStyleClassesInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyOverloadsInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="0" />
</value>
</option>
</inspection_tool>
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyPropertyAccessInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyPropertyDefinitionInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyProtectedMemberInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyRaisingNewStyleClassInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PyRaisingNewStyleClassInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyRedeclarationInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PyStubPackagesAdvertiser" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyRedundantParenthesesInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="PyStubPackagesCompatibilityInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyReturnFromInitInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PyTestParametrizedInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PySetFunctionToLiteralInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PyTypeHintsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyShadowingBuiltinsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="RedundantSuppression" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyShadowingNamesInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="RedundantTypeConversion" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PySimplifyBooleanCheckInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="RegExpUnexpectedAnchor" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PySingleQuotedDocstringInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="ReleasingOfAssignProperties" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyStatementEffectInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ReservedWordUsedAsNameJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyStringExceptionInspection" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="ReturnFromFinallyBlockJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyStringFormatInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SassScssResolvedByNameOnly" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="PySuperArgumentsInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SassScssUnresolvedMixin" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyTrailingSemicolonInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SassScssUnresolvedPlaceholderSelector" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyTupleAssignmentBalanceInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SassScssUnresolvedVariable" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyTupleItemAssignmentInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyTypeCheckerInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyUnboundLocalVariableInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyUnnecessaryBackslashInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyUnreachableCodeInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyUnusedLocalInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoreTupleUnpacking" value="true" />
<option name="ignoreLambdaParameters" value="true" />
<option name="ignoreLoopIterationVariables" value="true" />
</inspection_tool>
<inspection_tool class="RedundantCast" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RegExpAnonymousGroup" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RegExpDuplicateAlternationBranch" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RegExpEmptyAlternationBranch" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RegExpEscapedMetaCharacter" enabled="true" level="INFORMATION" enabled_by_default="true" />
<inspection_tool class="RegExpOctalEscape" enabled="true" level="INFORMATION" enabled_by_default="true" />
<inspection_tool class="RegExpRedundantEscape" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RegExpRepeatedSpace" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RegExpSingleCharAlternation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RequiredAttributes" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myAdditionalRequiredHtmlAttributes" value="" />
</inspection_tool>
<inspection_tool class="ResourceNotFoundInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ScalarTypeRequired" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="ScalarTypeRequired" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="SignednessMismatch" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SetterForReadonlyProperty" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ShiftOutOfRangeJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SillyAssignmentJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false"> <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" /> <option name="processCode" value="true" />
<option name="processLiterals" value="true" /> <option name="processLiterals" value="true" />
<option name="processComments" value="true" /> <option name="processComments" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="SqlAddNotNullColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlAggregatesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlAmbiguousColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlAutoIncrementDuplicateInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlCheckUsingColumnsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlConstantConditionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlDeprecateTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlDerivedTableAliasInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlDialectInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlDropIndexedColumnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlErrorHandlingInspection" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="SqlIdentifierInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlIllegalCursorStateInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlInsertValuesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlJoinWithoutOnInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlNoDataSourceInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlNullComparisonInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlRedundantOrderingDirectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlResolveInspection" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="SqlShouldBeInGroupByInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlSideEffectsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlSignatureInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlStorageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlTriggerTransitionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlTypeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlUnreachableCodeInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlUnusedSubqueryItemInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlUnusedVariableInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SqlWithoutWhereInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StaticnessMismatch" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="StaticnessMismatch" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="SyntaxError" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="StringLocalizationInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SuspiciousTypeOfGuard" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TemplateArgumentsIssues" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="TemplateArgumentsIssues" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="TodoComment" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="ThisExpressionReferencesGlobalObjectJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ThrowFromFinallyBlockJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TrivialConditionalJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TrivialIfJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptAbstractClassConstructorCanBeMadeProtected" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptAccessibilityCheck" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptCheckImport" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="TypeScriptConfig" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptFieldCanBeMadeReadonly" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptLibrary" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="TypeScriptMissingAugmentationImport" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="TypeScriptPreferShortImport" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptSuspiciousConstructorParameterAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptUMDGlobal" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptUnresolvedFunction" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptUnresolvedVariable" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptValidateJSTypes" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="TypeScriptValidateTypes" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="TypescriptExplicitMemberType" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="UnavailableInDeploymentTarget" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryContinueJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryLabelJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryLabelOnBreakStatementJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryLabelOnContinueStatementJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryLocalVariableJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnnecessaryReturnJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnreachableCode" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UnreachableCode" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnresolvedReference" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="UnreachableCodeJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedDefine" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="UnresolvedCollectionMessage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedExpressionResult" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UnresolvedMessage" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedImportStatement" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UnterminatedStatementJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedLocalVariable" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UsingZeroAsNil" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedLocalization" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="WebpackConfigHighlighting" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedParameter" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="WithStatementJS" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="UnusedValue" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="XmlDeprecatedElement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ValueMayNotFitIntoReceiver" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="XsltDeclarations" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlDefaultAttributeValue" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="XsltTemplateInvocation" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlDuplicatedId" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="XsltUnusedDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlHighlighting" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="XsltVariableShadowing" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlInvalidId" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="YAMLDuplicatedKeys" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlPathReference" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="YAMLRecursiveAlias" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="XmlUnboundNsPrefix" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="YAMLSchemaDeprecation" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="XmlUnusedNamespaceDeclaration" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="YAMLSchemaValidation" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="XmlWrongRootElement" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="YAMLUnresolvedAlias" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="YAMLUnusedAnchor" enabled="false" level="WARNING" enabled_by_default="false" />
</profile> </profile>
</component> </component>

View File

@ -13,8 +13,8 @@ bool BuildMasterShader(const hecl::ProjectPath& path) {
return false; return false;
{ {
hecl::blender::PyOutStream os = conn.beginPythonOut(true); hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os << RETRO_MASTER_SHADER; os << std::string_view((char*)RETRO_MASTER_SHADER, RETRO_MASTER_SHADER_SZ);
os << "make_master_shader_library()\n"; os << "make_master_shader_library()\n"sv;
} }
return conn.saveBlend(); return conn.saveBlend();
} }

View File

@ -4,9 +4,56 @@ import bpy
# Root Eevee Nodes # Root Eevee Nodes
# Additive output node
def make_additive_output():
new_grp = bpy.data.node_groups.new('HECLAdditiveOutput', 'ShaderNodeTree')
shader_input = new_grp.inputs.new('NodeSocketShader', 'Surface')
new_grp.use_fake_user = True
# Group inputs
grp_in = new_grp.nodes.new('NodeGroupInput')
grp_in.location = (0, 0)
# Add Shader
emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader')
emissive_add_shader.location = (200, 0)
# Transparent BDSF (Provides alpha)
transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent')
transparent_bdsf.location = (0, 100)
transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0)
# Material Output (Final output)
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial')
mat_out.location = (400, 0)
# Links
new_grp.links.new(grp_in.outputs['Surface'], emissive_add_shader.inputs[1])
new_grp.links.new(transparent_bdsf.outputs[0], emissive_add_shader.inputs[0])
new_grp.links.new(emissive_add_shader.outputs[0], mat_out.inputs['Surface'])
# Blend output node
def make_blend_opaque_output():
for tp in ('HECLBlendOutput', 'HECLOpaqueOutput'):
new_grp = bpy.data.node_groups.new(tp, 'ShaderNodeTree')
shader_input = new_grp.inputs.new('NodeSocketShader', 'Surface')
new_grp.use_fake_user = True
# Group inputs
grp_in = new_grp.nodes.new('NodeGroupInput')
grp_in.location = (0, 0)
# Material Output (Final output)
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial')
mat_out.location = (200, 0)
# Links
new_grp.links.new(grp_in.outputs['Surface'], mat_out.inputs['Surface'])
#0 - RetroShader #0 - RetroShader
def make_retro_shader(): def make_retro_shader():
new_grp = bpy.data.node_groups.new('RetroShader', 'ShaderNodeTree') new_grp = bpy.data.node_groups.new('RetroShader', 'ShaderNodeTree')
surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface')
lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap')
lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0)
diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse')
@ -112,8 +159,8 @@ def make_retro_shader():
alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') alpha_mix = new_grp.nodes.new('ShaderNodeMixShader')
alpha_mix.location = (-40, -112) alpha_mix.location = (-40, -112)
# Material Output (Final output) # Group outputs (Final output)
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial') mat_out = new_grp.nodes.new('NodeGroupOutput')
mat_out.location = (150, -88) mat_out.location = (150, -88)
# Links # Links
@ -150,6 +197,7 @@ def make_retro_shader():
def make_retro_dynamic_shader(): def make_retro_dynamic_shader():
new_grp = bpy.data.node_groups.new('RetroDynamicShader', 'ShaderNodeTree') new_grp = bpy.data.node_groups.new('RetroDynamicShader', 'ShaderNodeTree')
surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface')
lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap')
lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0)
diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse')
@ -275,8 +323,8 @@ def make_retro_dynamic_shader():
alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') alpha_mix = new_grp.nodes.new('ShaderNodeMixShader')
alpha_mix.location = (-40, -112) alpha_mix.location = (-40, -112)
# Material Output (Final output) # Group outputs (Final output)
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial') mat_out = new_grp.nodes.new('NodeGroupOutput')
mat_out.location = (150, -88) mat_out.location = (150, -88)
# Links # Links
@ -319,6 +367,7 @@ def make_retro_dynamic_shader():
def make_retro_dynamic_alpha_shader(): def make_retro_dynamic_alpha_shader():
new_grp = bpy.data.node_groups.new('RetroDynamicAlphaShader', 'ShaderNodeTree') new_grp = bpy.data.node_groups.new('RetroDynamicAlphaShader', 'ShaderNodeTree')
surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface')
lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap')
lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0)
diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse')
@ -454,7 +503,7 @@ def make_retro_dynamic_alpha_shader():
alpha_mix.location = (-40, -112) alpha_mix.location = (-40, -112)
# Material Output (Final output) # Material Output (Final output)
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial') mat_out = new_grp.nodes.new('NodeGroupOutput')
mat_out.location = (150, -88) mat_out.location = (150, -88)
# Links # Links
@ -499,6 +548,7 @@ def make_retro_dynamic_alpha_shader():
def make_retro_dynamic_character_shader(): def make_retro_dynamic_character_shader():
new_grp = bpy.data.node_groups.new('RetroDynamicCharacterShader', 'ShaderNodeTree') new_grp = bpy.data.node_groups.new('RetroDynamicCharacterShader', 'ShaderNodeTree')
surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface')
lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap')
lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0)
diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse')
@ -613,7 +663,7 @@ def make_retro_dynamic_character_shader():
alpha_mix.location = (-40, -112) alpha_mix.location = (-40, -112)
# Material Output (Final output) # Material Output (Final output)
mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial') mat_out = new_grp.nodes.new('NodeGroupOutput')
mat_out.location = (150, -88) mat_out.location = (150, -88)
# Links # Links
@ -1537,6 +1587,8 @@ MP3_PASS_GROUPS = (
) )
def make_master_shader_library(): def make_master_shader_library():
make_additive_output()
make_blend_opaque_output()
for shad in ROOT_SHADER_GROUPS: for shad in ROOT_SHADER_GROUPS:
shad() shad()
for uva in UV_ANIMATION_GROUPS: for uva in UV_ANIMATION_GROUPS:

View File

@ -23,8 +23,7 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
ancs.getCharacterResInfo(chResInfo); ancs.getCharacterResInfo(chResInfo);
for (const auto& info : chResInfo) { for (const auto& info : chResInfo) {
const nod::Node* node; const nod::Node* node;
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node, true, false); if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node, true, false)) {
if (cmdlE) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
if (force || cmdlPath.isNone()) { if (force || cmdlPath.isNone()) {
cmdlPath.makeDirChain(false); cmdlPath.makeDirChain(false);
@ -39,8 +38,9 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
pakRouter.lookupAndReadDNA(info.cskr, cskr); pakRouter.lookupAndReadDNA(info.cskr, cskr);
typename ANCSDNA::CINFType cinf; typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(info.cinf, cinf); pakRouter.lookupAndReadDNA(info.cinf, cinf);
using RigPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>; using RigPair = std::pair<std::pair<typename PAKRouter::IDType, typename ANCSDNA::CSKRType*>,
RigPair rigPair(&cskr, &cinf); std::pair<typename PAKRouter::IDType, typename ANCSDNA::CINFType*>>;
RigPair rigPair({info.cskr, &cskr}, {info.cinf, &cinf});
PAKEntryReadStream rs = cmdlE->beginReadStream(*node); PAKEntryReadStream rs = cmdlE->beginReadStream(*node);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>( DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>(
@ -54,11 +54,10 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
/* Extract attachment CMDL/CSKRs first */ /* Extract attachment CMDL/CSKRs first */
auto attRange = pakRouter.lookupCharacterAttachmentRigs(entry.id); auto attRange = pakRouter.lookupCharacterAttachmentRigs(entry.id);
for (auto it = attRange.first; it != attRange.second; ++it) { for (auto it = attRange.first; it != attRange.second; ++it) {
auto cmdlid = it->second.first.second; auto cmdlid = it->second.first.cmdl;
const nod::Node* node; const nod::Node* node;
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, &node, true, false); if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, &node, true, false)) {
if (cmdlE) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
if (force || cmdlPath.isNone()) { if (force || cmdlPath.isNone()) {
cmdlPath.makeDirChain(false); cmdlPath.makeDirChain(false);
@ -71,11 +70,12 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
const auto* rp = pakRouter.lookupCMDLRigPair(cmdlid); const auto* rp = pakRouter.lookupCMDLRigPair(cmdlid);
typename ANCSDNA::CSKRType cskr; typename ANCSDNA::CSKRType cskr;
pakRouter.lookupAndReadDNA(rp->first, cskr); pakRouter.lookupAndReadDNA(rp->cskr, cskr);
typename ANCSDNA::CINFType cinf; typename ANCSDNA::CINFType cinf;
pakRouter.lookupAndReadDNA(rp->second, cinf); pakRouter.lookupAndReadDNA(rp->cinf, cinf);
using RigPair = std::pair<typename ANCSDNA::CSKRType*, typename ANCSDNA::CINFType*>; using RigPair = std::pair<std::pair<typename PAKRouter::IDType, typename ANCSDNA::CSKRType*>,
RigPair rigPair(&cskr, &cinf); std::pair<typename PAKRouter::IDType, typename ANCSDNA::CINFType*>>;
RigPair rigPair({rp->cskr, &cskr}, {rp->cinf, &cinf});
PAKEntryReadStream rs = cmdlE->beginReadStream(*node); PAKEntryReadStream rs = cmdlE->beginReadStream(*node);
DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>( DNACMDL::ReadCMDLToBlender<PAKRouter, MaterialSet, RigPair, SurfaceHeader, CMDLVersion>(
@ -123,23 +123,25 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
/* Build CINF if needed */ /* Build CINF if needed */
if (cinfsDone.find(info.cinf) == cinfsDone.end()) { if (cinfsDone.find(info.cinf) == cinfsDone.end()) {
typename ANCSDNA::CINFType cinf; if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(info.cinf, nullptr, true, false)) {
pakRouter.lookupAndReadDNA(info.cinf, cinf); hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE);
cinf.sendCINFToBlender(os, info.cinf); os.linkArmature(cinfPath.getAbsolutePathUTF8(), fmt::format(fmt("CINF_{}"), info.cinf));
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.collection.objects.link(obj)\n";
}
if (cinfsDone.empty()) { if (cinfsDone.empty()) {
firstName = ANCSDNA::CINFType::GetCINFArmatureName(info.cinf); firstName = ANCSDNA::CINFType::GetCINFArmatureName(info.cinf);
firstCinf = cinf; pakRouter.lookupAndReadDNA(info.cinf, firstCinf);
} }
cinfsDone.insert(info.cinf); cinfsDone.insert(info.cinf);
} else }
os.format(fmt("arm_obj = bpy.data.objects['CINF_{}']\n"), info.cinf); os.format(fmt("arm_obj = bpy.data.objects['CINF_{}']\n"), info.cinf);
os << "actor_subtype.linked_armature = arm_obj.name\n"; os << "actor_subtype.linked_armature = arm_obj.name\n";
/* Link CMDL */ /* Link CMDL */
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, nullptr, true, false); if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, nullptr, true, false)) {
if (cmdlE) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).data(), true); os.linkMesh(cmdlPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE));
/* Attach CMDL to CINF */ /* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n" os << "if obj.name not in bpy.context.scene.objects:\n"
@ -155,10 +157,10 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
os.format(fmt("overlay.name = '{}'\n"), overlay.first); os.format(fmt("overlay.name = '{}'\n"), overlay.first);
/* Link CMDL */ /* Link CMDL */
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(overlay.second.first, nullptr, true, false); if (const typename PAKRouter::EntryType* cmdlE =
if (cmdlE) { pakRouter.lookupEntry(overlay.second.first, nullptr, true, false)) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).data(), true); os.linkMesh(cmdlPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE));
/* Attach CMDL to CINF */ /* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n" os << "if obj.name not in bpy.context.scene.objects:\n"
@ -175,30 +177,32 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
os << "attachment = actor_data.attachments.add()\n"; os << "attachment = actor_data.attachments.add()\n";
os.format(fmt("attachment.name = '{}'\n"), it->second.second); os.format(fmt("attachment.name = '{}'\n"), it->second.second);
auto cinfid = it->second.first.first; auto cinfid = it->second.first.cinf;
auto cmdlid = it->second.first.second; auto cmdlid = it->second.first.cmdl;
if (cinfid.isValid()) { if (cinfid.isValid()) {
/* Build CINF if needed */ /* Build CINF if needed */
if (cinfsDone.find(cinfid) == cinfsDone.end()) { if (cinfsDone.find(cinfid) == cinfsDone.end()) {
typename ANCSDNA::CINFType cinf; if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(cinfid, nullptr, true, false)) {
pakRouter.lookupAndReadDNA(cinfid, cinf); hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE);
cinf.sendCINFToBlender(os, cinfid); os.linkArmature(cinfPath.getAbsolutePathUTF8(), fmt::format(fmt("CINF_{}"), cinfid));
os << "if obj.name not in bpy.context.scene.objects:\n"
" bpy.context.scene.collection.objects.link(obj)\n";
}
if (cinfsDone.empty()) { if (cinfsDone.empty()) {
firstName = ANCSDNA::CINFType::GetCINFArmatureName(cinfid); firstName = ANCSDNA::CINFType::GetCINFArmatureName(cinfid);
firstCinf = cinf; pakRouter.lookupAndReadDNA(cinfid, firstCinf);
} }
cinfsDone.insert(cinfid); cinfsDone.insert(cinfid);
} else }
os.format(fmt("arm_obj = bpy.data.objects['CINF_{}']\n"), cinfid); os.format(fmt("arm_obj = bpy.data.objects['CINF_{}']\n"), cinfid);
os << "attachment.linked_armature = arm_obj.name\n"; os << "attachment.linked_armature = arm_obj.name\n";
} }
/* Link CMDL */ /* Link CMDL */
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, nullptr, true, false); if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, nullptr, true, false)) {
if (cmdlE) {
hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE);
os.linkBlend(cmdlPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).data(), true); os.linkMesh(cmdlPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE));
/* Attach CMDL to CINF */ /* Attach CMDL to CINF */
os << "if obj.name not in bpy.context.scene.objects:\n" os << "if obj.name not in bpy.context.scene.objects:\n"
@ -228,8 +232,9 @@ bool ReadANCSToBlender(hecl::blender::Connection& conn, const ANCSDNA& ancs, con
if (pakRouter.lookupAndReadDNA(id.second.animId, anim, true)) { if (pakRouter.lookupAndReadDNA(id.second.animId, anim, true)) {
os.format(fmt( os.format(fmt(
"act = bpy.data.actions.new('{}')\n" "act = bpy.data.actions.new('{}')\n"
"act.use_fake_user = True\n"), "act.use_fake_user = True\n"
id.second.name); "act.anim_id = '{}'\n"),
id.second.name, id.second.animId);
anim.sendANIMToBlender(os, inverter, id.second.additive); anim.sendANIMToBlender(os, inverter, id.second.additive);
} }

View File

@ -5,9 +5,9 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <athena/Types.hpp> #include "athena/Types.hpp"
#include <hecl/Blender/Connection.hpp> #include "hecl/Blender/Connection.hpp"
#include <hecl/SystemChar.hpp> #include "hecl/SystemChar.hpp"
namespace DataSpec { namespace DataSpec {
struct SpecBase; struct SpecBase;
@ -20,7 +20,7 @@ class ProjectPath;
namespace DataSpec::DNAANCS { namespace DataSpec::DNAANCS {
using Actor = hecl::blender::Actor; using Actor = hecl::blender::Actor;
using Armature = hecl::blender::Armature; using Armature = Actor::ActorArmature;
using Action = hecl::blender::Action; using Action = hecl::blender::Action;
template <typename IDTYPE> template <typename IDTYPE>

View File

@ -24,7 +24,7 @@ bool ATBL::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
uint16_t idx = rs.readUint16Big(); uint16_t idx = rs.readUint16Big();
if (idx == 0xffff) if (idx == 0xffff)
continue; continue;
w.writeUint16(fmt::format(fmt("0x{:04X}"), i).c_str(), idx); w.writeUint16(fmt::format(fmt("0x{:04X}"), i), idx);
} }
athena::io::FileWriter fw(outPath.getAbsolutePath()); athena::io::FileWriter fw(outPath.getAbsolutePath());

View File

@ -153,7 +153,7 @@ public:
"orig_vert = bm.verts[{}]\n" "orig_vert = bm.verts[{}]\n"
"vert = bm.verts.new(orig_vert.co)\n"), "vert = bm.verts.new(orig_vert.co)\n"),
ev.first + baseVert); ev.first + baseVert);
rp.first->weightVertex(os, *rp.second, se.first); rp.first.second->weightVertex(os, *rp.second.second, se.first);
++nextVert; ++nextVert;
++addedVerts; ++addedVerts;
} }
@ -585,7 +585,7 @@ atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::I
"\n" "\n"
"lightmap_tri_tracker = {}\n"; "lightmap_tri_tracker = {}\n";
if (rp.first) if (rp.first.second)
os << "dvert_lay = bm.verts.layers.deform.verify()\n"; os << "dvert_lay = bm.verts.layers.deform.verify()\n";
/* Pre-read pass to determine maximum used vert indices */ /* Pre-read pass to determine maximum used vert indices */
@ -611,7 +611,7 @@ atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::I
switch (s - matSecCount) { switch (s - matSecCount) {
case 0: { case 0: {
/* Positions */ /* Positions */
if (SurfaceHeader::UseMatrixSkinning() && rp.first) if (SurfaceHeader::UseMatrixSkinning() && rp.first.second)
skinIndices.assign(secSizes[s] / 12, -1); skinIndices.assign(secSizes[s] / 12, -1);
break; break;
} }
@ -655,13 +655,13 @@ atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::I
SurfaceHeader sHead; SurfaceHeader sHead;
sHead.read(reader); sHead.read(reader);
const atInt16* bankIn = nullptr; const atInt16* bankIn = nullptr;
if (SurfaceHeader::UseMatrixSkinning() && rp.first) if (SurfaceHeader::UseMatrixSkinning() && rp.first.second)
bankIn = rp.first->getMatrixBank(sHead.skinMatrixBankIdx()); bankIn = rp.first.second->getMatrixBank(sHead.skinMatrixBankIdx());
/* Do max index pre-read */ /* Do max index pre-read */
atUint32 realDlSize = secSizes[s] - (reader.position() - secStart); atUint32 realDlSize = secSizes[s] - (reader.position() - secStart);
DLReader dl(vertAttribs[sHead.matIdx], reader.readUBytes(realDlSize), realDlSize, extraTracker, bankIn); DLReader dl(vertAttribs[sHead.matIdx], reader.readUBytes(realDlSize), realDlSize, extraTracker, bankIn);
if (SurfaceHeader::UseMatrixSkinning() && rp.first) if (SurfaceHeader::UseMatrixSkinning() && rp.first.second)
dl.preReadMaxIdxs(maxIdxs, skinIndices); dl.preReadMaxIdxs(maxIdxs, skinIndices);
else else
dl.preReadMaxIdxs(maxIdxs); dl.preReadMaxIdxs(maxIdxs);
@ -698,27 +698,27 @@ atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::I
positions.push_back(reader.readVec3fBig()); positions.push_back(reader.readVec3fBig());
const atVec3f& pos = positions.back(); const atVec3f& pos = positions.back();
os.format(fmt("vert = bm.verts.new(({},{},{}))\n"), pos.simd[0], pos.simd[1], pos.simd[2]); os.format(fmt("vert = bm.verts.new(({},{},{}))\n"), pos.simd[0], pos.simd[1], pos.simd[2]);
if (rp.first) { if (rp.first.second) {
if (SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) if (SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty())
rp.first->weightVertex(os, *rp.second, skinIndices[i]); rp.first.second->weightVertex(os, *rp.second.second, skinIndices[i]);
else if (!SurfaceHeader::UseMatrixSkinning()) else if (!SurfaceHeader::UseMatrixSkinning())
rp.first->weightVertex(os, *rp.second, i); rp.first.second->weightVertex(os, *rp.second.second, i);
} }
} }
if (rp.first && SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) if (rp.first.second && SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty())
vertCount += extraTracker.sendAdditionalVertsToBlender(os, rp, 0); vertCount += extraTracker.sendAdditionalVertsToBlender(os, rp, 0);
os.format(fmt("two_face_vert = {}\n"), vertCount); os.format(fmt("two_face_vert = {}\n"), vertCount);
for (size_t i = 0; i <= maxIdxs.pos; ++i) { for (size_t i = 0; i <= maxIdxs.pos; ++i) {
const atVec3f& pos = positions[i]; const atVec3f& pos = positions[i];
os.format(fmt("vert = bm.verts.new(({},{},{}))\n"), pos.simd[0], pos.simd[1], pos.simd[2]); os.format(fmt("vert = bm.verts.new(({},{},{}))\n"), pos.simd[0], pos.simd[1], pos.simd[2]);
if (rp.first) { if (rp.first.second) {
if (SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) if (SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty())
rp.first->weightVertex(os, *rp.second, skinIndices[i]); rp.first.second->weightVertex(os, *rp.second.second, skinIndices[i]);
else if (!SurfaceHeader::UseMatrixSkinning()) else if (!SurfaceHeader::UseMatrixSkinning())
rp.first->weightVertex(os, *rp.second, i); rp.first.second->weightVertex(os, *rp.second.second, i);
} }
} }
if (rp.first && SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) if (rp.first.second && SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty())
extraTracker.sendAdditionalVertsToBlender(os, rp, vertCount); extraTracker.sendAdditionalVertsToBlender(os, rp, vertCount);
break; break;
} }
@ -792,8 +792,8 @@ atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::I
unsigned matUVCount = curVA.uvCount; unsigned matUVCount = curVA.uvCount;
bool matShortUVs = curVA.shortUVs; bool matShortUVs = curVA.shortUVs;
const atInt16* bankIn = nullptr; const atInt16* bankIn = nullptr;
if (SurfaceHeader::UseMatrixSkinning() && rp.first) if (SurfaceHeader::UseMatrixSkinning() && rp.first.second)
bankIn = rp.first->getMatrixBank(sHead.skinMatrixBankIdx()); bankIn = rp.first.second->getMatrixBank(sHead.skinMatrixBankIdx());
os.format(fmt("materials[{}].pass_index = {}\n"), sHead.matIdx, surfIdx++); os.format(fmt("materials[{}].pass_index = {}\n"), sHead.matIdx, surfIdx++);
if (matUVCount > createdUVLayers) { if (matUVCount > createdUVLayers) {
@ -996,8 +996,10 @@ atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::I
/* Finish Mesh */ /* Finish Mesh */
FinishBlenderMesh(os, matSetCount, meshIdx); FinishBlenderMesh(os, matSetCount, meshIdx);
if (rp.first) if (rp.first.second) {
rp.second->sendVertexGroupsToBlender(os); os.format(fmt("mesh.cskr_id = '{}'\n"), rp.first.first);
rp.second.second->sendVertexGroupsToBlender(os);
}
return lastDlSec; return lastDlSec;
} }
@ -1043,28 +1045,28 @@ bool ReadCMDLToBlender(hecl::blender::Connection& conn, athena::io::IStreamReade
} }
template bool ReadCMDLToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::MaterialSet, template bool ReadCMDLToBlender<PAKRouter<DNAMP1::PAKBridge>, DNAMP1::MaterialSet,
std::pair<DNAMP1::CSKR*, DNAMP1::CINF*>, DNACMDL::SurfaceHeader_1, 2>( std::pair<std::pair<UniqueID32, DNAMP1::CSKR*>, std::pair<UniqueID32, DNAMP1::CINF*>>, DNACMDL::SurfaceHeader_1, 2>(
hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter<DNAMP1::PAKBridge>& pakRouter, hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter<DNAMP1::PAKBridge>& pakRouter,
const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry, const SpecBase& dataspec, const PAKRouter<DNAMP1::PAKBridge>::EntryType& entry, const SpecBase& dataspec,
const std::pair<DNAMP1::CSKR*, DNAMP1::CINF*>& rp); const std::pair<std::pair<UniqueID32, DNAMP1::CSKR*>, std::pair<UniqueID32, DNAMP1::CINF*>>& rp);
template bool ReadCMDLToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::MaterialSet, template bool ReadCMDLToBlender<PAKRouter<DNAMP2::PAKBridge>, DNAMP2::MaterialSet,
std::pair<DNAMP2::CSKR*, DNAMP2::CINF*>, DNACMDL::SurfaceHeader_2, 4>( std::pair<std::pair<UniqueID32, DNAMP2::CSKR*>, std::pair<UniqueID32, DNAMP2::CINF*>>, DNACMDL::SurfaceHeader_2, 4>(
hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter<DNAMP2::PAKBridge>& pakRouter, hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter<DNAMP2::PAKBridge>& pakRouter,
const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry, const SpecBase& dataspec, const PAKRouter<DNAMP2::PAKBridge>::EntryType& entry, const SpecBase& dataspec,
const std::pair<DNAMP2::CSKR*, DNAMP2::CINF*>& rp); const std::pair<std::pair<UniqueID32, DNAMP2::CSKR*>, std::pair<UniqueID32, DNAMP2::CINF*>>& rp);
template bool ReadCMDLToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::MaterialSet, template bool ReadCMDLToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::MaterialSet,
std::pair<DNAMP3::CSKR*, DNAMP3::CINF*>, DNACMDL::SurfaceHeader_3, 4>( std::pair<std::pair<UniqueID64, DNAMP3::CSKR*>, std::pair<UniqueID64, DNAMP3::CINF*>>, DNACMDL::SurfaceHeader_3, 4>(
hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter<DNAMP3::PAKBridge>& pakRouter, hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter<DNAMP3::PAKBridge>& pakRouter,
const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry, const SpecBase& dataspec, const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry, const SpecBase& dataspec,
const std::pair<DNAMP3::CSKR*, DNAMP3::CINF*>& rp); const std::pair<std::pair<UniqueID64, DNAMP3::CSKR*>, std::pair<UniqueID64, DNAMP3::CINF*>>& rp);
template bool ReadCMDLToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::MaterialSet, template bool ReadCMDLToBlender<PAKRouter<DNAMP3::PAKBridge>, DNAMP3::MaterialSet,
std::pair<DNAMP3::CSKR*, DNAMP3::CINF*>, DNACMDL::SurfaceHeader_3, 5>( std::pair<std::pair<UniqueID64, DNAMP3::CSKR*>, std::pair<UniqueID64, DNAMP3::CINF*>>, DNACMDL::SurfaceHeader_3, 5>(
hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter<DNAMP3::PAKBridge>& pakRouter, hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter<DNAMP3::PAKBridge>& pakRouter,
const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry, const SpecBase& dataspec, const PAKRouter<DNAMP3::PAKBridge>::EntryType& entry, const SpecBase& dataspec,
const std::pair<DNAMP3::CSKR*, DNAMP3::CINF*>& rp); const std::pair<std::pair<UniqueID64, DNAMP3::CSKR*>, std::pair<UniqueID64, DNAMP3::CINF*>>& rp);
template <class PAKRouter, class MaterialSet> template <class PAKRouter, class MaterialSet>
void NameCMDL(athena::io::IStreamReader& reader, PAKRouter& pakRouter, typename PAKRouter::EntryType& entry, void NameCMDL(athena::io::IStreamReader& reader, PAKRouter& pakRouter, typename PAKRouter::EntryType& entry,

View File

@ -42,13 +42,13 @@ static const std::vector<FourCC> DecalTypes = {SBIG('NCDL'), SBIG('DDCL'), SBIG(
SBIG('3LAV'), SBIG('3SAN'), SBIG('CHDL'), SBIG('ENDL')}; SBIG('3LAV'), SBIG('3SAN'), SBIG('CHDL'), SBIG('ENDL')};
template <> template <>
const char* CRSM<UniqueID32>::DNAType() { std::string_view CRSM<UniqueID32>::DNAType() {
return "CRSM<UniqueID32>"; return "CRSM<UniqueID32>"sv;
} }
template <> template <>
const char* CRSM<UniqueID64>::DNAType() { std::string_view CRSM<UniqueID64>::DNAType() {
return "CRSM<UniqueID64>"; return "CRSM<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>
@ -62,29 +62,29 @@ void CRSM<IDType>::_read(athena::io::YAMLDocReader& r) {
if (auto rec = r.enterSubRecord(elem.first.c_str())) { if (auto rec = r.enterSubRecord(elem.first.c_str())) {
FourCC clsId(elem.first.c_str()); FourCC clsId(elem.first.c_str());
auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(), auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; }); [&clsId](const FourCC& other) { return clsId == other; });
if (gen != GeneratorTypes.end()) { if (gen != GeneratorTypes.end()) {
x0_generators[clsId].read(r); x0_generators[clsId].read(r);
continue; continue;
} }
auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(), auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; }); [&clsId](const FourCC& other) { return clsId == other; });
if (sfx != SFXTypes.end()) { if (sfx != SFXTypes.end()) {
x10_sfx[clsId] = r.readInt32(clsId.toString().c_str()); x10_sfx[clsId] = r.readInt32(clsId.toString());
continue; continue;
} }
auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; }); [&clsId](const FourCC& other) { return clsId == other; });
if (decal != DecalTypes.end()) { if (decal != DecalTypes.end()) {
x20_decals[clsId].read(r); x20_decals[clsId].read(r);
continue; continue;
} }
if (clsId == SBIG('RNGE')) if (clsId == SBIG('RNGE'))
x30_RNGE = r.readFloat(nullptr); x30_RNGE = r.readFloat();
else if (clsId == SBIG('FOFF')) else if (clsId == SBIG('FOFF'))
x34_FOFF = r.readFloat(nullptr); x34_FOFF = r.readFloat();
} }
} }
} }
@ -93,16 +93,16 @@ template <class IDType>
void CRSM<IDType>::_write(athena::io::YAMLDocWriter& w) const { void CRSM<IDType>::_write(athena::io::YAMLDocWriter& w) const {
for (const auto& pair : x0_generators) for (const auto& pair : x0_generators)
if (pair.second) if (pair.second)
if (auto rec = w.enterSubRecord(pair.first.toString().c_str())) if (auto rec = w.enterSubRecord(pair.first.toString()))
pair.second.write(w); pair.second.write(w);
for (const auto& pair : x10_sfx) for (const auto& pair : x10_sfx)
if (pair.second != UINT32_MAX) if (pair.second != UINT32_MAX)
w.writeUint32(pair.first.toString().c_str(), pair.second); w.writeUint32(pair.first.toString(), pair.second);
for (const auto& pair : x20_decals) for (const auto& pair : x20_decals)
if (pair.second) if (pair.second)
if (auto rec = w.enterSubRecord(pair.first.toString().c_str())) if (auto rec = w.enterSubRecord(pair.first.toString()))
pair.second.write(w); pair.second.write(w);
if (x30_RNGE != 50.f) if (x30_RNGE != 50.f)
@ -150,14 +150,14 @@ void CRSM<IDType>::_read(athena::io::IStreamReader& r) {
while (clsId != SBIG('_END')) { while (clsId != SBIG('_END')) {
clsId.read(r); clsId.read(r);
auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(), auto gen = std::find_if(GeneratorTypes.begin(), GeneratorTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; }); [&clsId](const FourCC& other) { return clsId == other; });
if (gen != GeneratorTypes.end()) { if (gen != GeneratorTypes.end()) {
x0_generators[clsId].read(r); x0_generators[clsId].read(r);
continue; continue;
} }
auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(), auto sfx = std::find_if(SFXTypes.begin(), SFXTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; }); [&clsId](const FourCC& other) { return clsId == other; });
if (sfx != SFXTypes.end()) { if (sfx != SFXTypes.end()) {
DNAFourCC fcc; DNAFourCC fcc;
fcc.read(r); fcc.read(r);
@ -169,7 +169,7 @@ void CRSM<IDType>::_read(athena::io::IStreamReader& r) {
} }
auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(), auto decal = std::find_if(DecalTypes.begin(), DecalTypes.end(),
[&clsId](const FourCC& other) -> bool { return clsId == other; }); [&clsId](const FourCC& other) { return clsId == other; });
if (decal != DecalTypes.end()) { if (decal != DecalTypes.end()) {
x20_decals[clsId].read(r); x20_decals[clsId].read(r);
continue; continue;

View File

@ -9,9 +9,6 @@ ThreadLocalPtr<SpecBase> g_curSpec;
ThreadLocalPtr<PAKRouterBase> g_PakRouter; ThreadLocalPtr<PAKRouterBase> g_PakRouter;
ThreadLocalPtr<hecl::blender::Token> g_ThreadBlenderToken; ThreadLocalPtr<hecl::blender::Token> g_ThreadBlenderToken;
ThreadLocalPtr<hecl::Database::Project> UniqueIDBridge::s_Project; ThreadLocalPtr<hecl::Database::Project> UniqueIDBridge::s_Project;
ThreadLocalPtr<IDRestorer<UniqueID32>> UniqueIDBridge::s_restorer32;
ThreadLocalPtr<IDRestorer<UniqueID64>> UniqueIDBridge::s_restorer64;
ThreadLocalPtr<IDRestorer<UniqueID128>> UniqueIDBridge::s_restorer128;
UniqueID32 UniqueID32::kInvalidId; UniqueID32 UniqueID32::kInvalidId;
template <class IDType> template <class IDType>
@ -40,12 +37,6 @@ hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool si
const hecl::ProjectPath* search = project->lookupBridgePath(id.toUint64()); const hecl::ProjectPath* search = project->lookupBridgePath(id.toUint64());
if (!search) { if (!search) {
if (IDRestorer<IDType>* restorer = GetIDRestorer<IDType>()) {
IDType newId = restorer->originalToNew(id);
if (newId.isValid())
if (const hecl::ProjectPath* newSearch = project->lookupBridgePath(newId.toUint64()))
return *newSearch;
}
if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id.isValid()) if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id.isValid())
LogDNACommon.report(logvisor::Warning, fmt("unable to translate {} to path"), id); LogDNACommon.report(logvisor::Warning, fmt("unable to translate {} to path"), id);
return {}; return {};
@ -70,26 +61,9 @@ hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str) {
template hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID32>(std::string_view str); template hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID32>(std::string_view str);
template hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID64>(std::string_view str); template hecl::ProjectPath UniqueIDBridge::MakePathFromString<UniqueID64>(std::string_view str);
template <class IDType>
void UniqueIDBridge::TransformOldHashToNewHash(IDType& id) {
id = TranslatePakIdToPath(id);
}
template void UniqueIDBridge::TransformOldHashToNewHash(UniqueID32& id);
template void UniqueIDBridge::TransformOldHashToNewHash(UniqueID64& id);
void UniqueIDBridge::SetThreadProject(hecl::Database::Project& project) { s_Project.reset(&project); } void UniqueIDBridge::SetThreadProject(hecl::Database::Project& project) { s_Project.reset(&project); }
/** PAK 32-bit Unique ID */ /** PAK 32-bit Unique ID */
void UniqueID32::assign(uint32_t id, bool noOriginal) {
m_id = id ? id : 0xffffffff;
if (!noOriginal)
if (IDRestorer<UniqueID32>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID32>()) {
UniqueID32 origId = restorer->newToOriginal(*this);
if (origId.isValid())
*this = origId;
}
}
template <> template <>
void UniqueID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) { void UniqueID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
assign(reader.readUint32Big()); assign(reader.readUint32Big());
@ -100,7 +74,7 @@ void UniqueID32::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
} }
template <> template <>
void UniqueID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) { void UniqueID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
*this = UniqueIDBridge::MakePathFromString<UniqueID32>(reader.readString(nullptr)); *this = UniqueIDBridge::MakePathFromString<UniqueID32>(reader.readString());
} }
template <> template <>
void UniqueID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) { void UniqueID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
@ -109,9 +83,7 @@ void UniqueID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& write
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path) if (!path)
return; return;
writer.writeString(nullptr, path.getAuxInfo().size() writer.writeString(path.getEncodableStringUTF8());
? (std::string(path.getRelativePathUTF8()) + '|' + path.getAuxInfoUTF8().data())
: path.getRelativePathUTF8());
} }
template <> template <>
void UniqueID32::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) { void UniqueID32::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
@ -143,62 +115,7 @@ void UniqueID32Zero::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT&
UniqueID32::Enumerate<BigDNA::BinarySize>(s); UniqueID32::Enumerate<BigDNA::BinarySize>(s);
} }
AuxiliaryID32& AuxiliaryID32::operator=(const hecl::ProjectPath& path) {
assign(path.ensureAuxInfo(m_auxStr).hash().val32());
return *this;
}
AuxiliaryID32& AuxiliaryID32::operator=(const UniqueID32& id) {
m_baseId = id;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
if (path) {
if (m_addExtension)
path = path.getWithExtension(m_addExtension);
*this = path;
}
return *this;
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
assign(reader.readUint32Big());
m_baseId = *this;
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
writer.writeUint32Big(m_id);
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
hecl::ProjectPath readPath = UniqueIDBridge::MakePathFromString<UniqueID32>(reader.readString(nullptr));
*this = readPath.ensureAuxInfo(m_auxStr);
}
template <>
void AuxiliaryID32::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
if (!isValid())
return;
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath<UniqueID32>(*this, true);
if (!path)
path = UniqueIDBridge::TranslatePakIdToPath(m_baseId);
if (!path)
return;
if (m_addExtension)
path = path.getWithExtension(m_addExtension);
hecl::SystemUTF8Conv ufx8AuxStr(m_auxStr);
writer.writeString(nullptr, std::string(path.getRelativePathUTF8()) + '|' + ufx8AuxStr);
}
/** PAK 64-bit Unique ID */ /** PAK 64-bit Unique ID */
void UniqueID64::assign(uint64_t id, bool noOriginal) {
m_id = id ? id : 0xffffffffffffffff;
if (!noOriginal)
if (IDRestorer<UniqueID64>* restorer = UniqueIDBridge::GetIDRestorer<UniqueID64>()) {
UniqueID64 origId = restorer->newToOriginal(*this);
if (origId.isValid())
*this = origId;
}
}
template <> template <>
void UniqueID64::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) { void UniqueID64::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
assign(reader.readUint64Big()); assign(reader.readUint64Big());
@ -209,7 +126,7 @@ void UniqueID64::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
} }
template <> template <>
void UniqueID64::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) { void UniqueID64::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
*this = UniqueIDBridge::MakePathFromString<UniqueID64>(reader.readString(nullptr)); *this = UniqueIDBridge::MakePathFromString<UniqueID64>(reader.readString());
} }
template <> template <>
void UniqueID64::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) { void UniqueID64::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
@ -218,9 +135,7 @@ void UniqueID64::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& write
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path) if (!path)
return; return;
writer.writeString(nullptr, path.getAuxInfo().size() writer.writeString(path.getEncodableStringUTF8());
? (std::string(path.getRelativePathUTF8()) + '|' + path.getAuxInfoUTF8().data())
: path.getRelativePathUTF8());
} }
template <> template <>
void UniqueID64::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) { void UniqueID64::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
@ -244,7 +159,7 @@ void UniqueID128::Enumerate<BigDNA::Write>(typename Write::StreamT& writer) {
} }
template <> template <>
void UniqueID128::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) { void UniqueID128::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
*this = UniqueIDBridge::MakePathFromString<UniqueID128>(reader.readString(nullptr)); *this = UniqueIDBridge::MakePathFromString<UniqueID128>(reader.readString());
} }
template <> template <>
void UniqueID128::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) { void UniqueID128::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
@ -253,9 +168,7 @@ void UniqueID128::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writ
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this);
if (!path) if (!path)
return; return;
writer.writeString(nullptr, path.getAuxInfo().size() writer.writeString(path.getEncodableStringUTF8());
? (std::string(path.getRelativePathUTF8()) + '|' + path.getAuxInfoUTF8().data())
: path.getRelativePathUTF8());
} }
template <> template <>
void UniqueID128::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) { void UniqueID128::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
@ -281,4 +194,12 @@ void WordBitmap::write(athena::io::IStreamWriter& writer) const {
} }
void WordBitmap::binarySize(size_t& __isz) const { __isz += m_words.size() * 4; } void WordBitmap::binarySize(size_t& __isz) const { __isz += m_words.size() * 4; }
hecl::ProjectPath GetPathBeginsWith(const hecl::DirectoryEnumerator& dEnum, const hecl::ProjectPath& parentPath,
hecl::SystemStringView test) {
for (const auto& ent : dEnum)
if (hecl::StringUtils::BeginsWith(ent.m_name, test))
return hecl::ProjectPath(parentPath, ent.m_name);
return {};
}
} // namespace DataSpec } // namespace DataSpec

View File

@ -41,23 +41,23 @@ inline void DNAColor::Enumerate<BigDNA::Write>(typename Write::StreamT& _w) {
template <> template <>
inline void DNAColor::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& _r) { inline void DNAColor::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& _r) {
size_t count; size_t count;
if (auto v = _r.enterSubVector(nullptr, count)) { if (auto v = _r.enterSubVector(count)) {
zeus::simd_floats f; zeus::simd_floats f;
f[0] = (count >= 1) ? _r.readFloat(nullptr) : 0.f; f[0] = (count >= 1) ? _r.readFloat() : 0.f;
f[1] = (count >= 2) ? _r.readFloat(nullptr) : 0.f; f[1] = (count >= 2) ? _r.readFloat() : 0.f;
f[2] = (count >= 3) ? _r.readFloat(nullptr) : 0.f; f[2] = (count >= 3) ? _r.readFloat() : 0.f;
f[3] = (count >= 4) ? _r.readFloat(nullptr) : 0.f; f[3] = (count >= 4) ? _r.readFloat() : 0.f;
mSimd.copy_from(f); mSimd.copy_from(f);
} }
} }
template <> template <>
inline void DNAColor::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& _w) { inline void DNAColor::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& _w) {
if (auto v = _w.enterSubVector(nullptr)) { if (auto v = _w.enterSubVector()) {
zeus::simd_floats f(mSimd); zeus::simd_floats f(mSimd);
_w.writeFloat(nullptr, f[0]); _w.writeFloat(f[0]);
_w.writeFloat(nullptr, f[1]); _w.writeFloat(f[1]);
_w.writeFloat(nullptr, f[2]); _w.writeFloat(f[2]);
_w.writeFloat(nullptr, f[3]); _w.writeFloat(f[3]);
} }
} }
template <> template <>
@ -99,56 +99,16 @@ class UniqueIDBridge {
friend class UniqueID64; friend class UniqueID64;
static ThreadLocalPtr<hecl::Database::Project> s_Project; static ThreadLocalPtr<hecl::Database::Project> s_Project;
static ThreadLocalPtr<IDRestorer<UniqueID32>> s_restorer32;
static ThreadLocalPtr<IDRestorer<UniqueID64>> s_restorer64;
static ThreadLocalPtr<IDRestorer<UniqueID128>> s_restorer128;
public: public:
template <class IDType> template <class IDType>
static hecl::ProjectPath TranslatePakIdToPath(const IDType& id, bool silenceWarnings = false); static hecl::ProjectPath TranslatePakIdToPath(const IDType& id, bool silenceWarnings = false);
template <class IDType> template <class IDType>
static hecl::ProjectPath MakePathFromString(std::string_view str); static hecl::ProjectPath MakePathFromString(std::string_view str);
template <class IDType>
static void TransformOldHashToNewHash(IDType& id);
static void SetThreadProject(hecl::Database::Project& project); static void SetThreadProject(hecl::Database::Project& project);
template <class IDType>
static IDRestorer<IDType>* GetIDRestorer();
template <class IDType>
static void SetIDRestorer(IDRestorer<IDType>* restorer);
}; };
template <>
inline IDRestorer<UniqueID32>* UniqueIDBridge::GetIDRestorer<UniqueID32>() {
return s_restorer32.get();
}
template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID32>(IDRestorer<UniqueID32>* restorer) {
s_restorer32.reset(restorer);
}
template <>
inline IDRestorer<UniqueID64>* UniqueIDBridge::GetIDRestorer<UniqueID64>() {
return s_restorer64.get();
}
template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID64>(IDRestorer<UniqueID64>* restorer) {
s_restorer64.reset(restorer);
}
template <>
inline IDRestorer<UniqueID128>* UniqueIDBridge::GetIDRestorer<UniqueID128>() {
return s_restorer128.get();
}
template <>
inline void UniqueIDBridge::SetIDRestorer<UniqueID128>(IDRestorer<UniqueID128>* restorer) {
s_restorer128.reset(restorer);
}
/** PAK 32-bit Unique ID */ /** PAK 32-bit Unique ID */
class UniqueID32 : public BigDNA { class UniqueID32 : public BigDNA {
protected: protected:
@ -159,10 +119,10 @@ public:
static UniqueID32 kInvalidId; static UniqueID32 kInvalidId;
AT_DECL_EXPLICIT_DNA_YAML AT_DECL_EXPLICIT_DNA_YAML
bool isValid() const { return m_id != 0xffffffff && m_id != 0; } bool isValid() const { return m_id != 0xffffffff && m_id != 0; }
void assign(uint32_t id, bool noOriginal = false); void assign(uint32_t id) { m_id = id ? id : 0xffffffff; }
UniqueID32& operator=(const hecl::ProjectPath& path) { UniqueID32& operator=(const hecl::ProjectPath& path) {
assign(path.hash().val32()); assign(path.parsedHash32());
return *this; return *this;
} }
@ -175,7 +135,7 @@ public:
void clear() { m_id = 0xffffffff; } void clear() { m_id = 0xffffffff; }
UniqueID32() = default; UniqueID32() = default;
UniqueID32(uint32_t idin, bool noOriginal = false) { assign(idin, noOriginal); } UniqueID32(uint32_t idin) { assign(idin); }
UniqueID32(athena::io::IStreamReader& reader) { read(reader); } UniqueID32(athena::io::IStreamReader& reader) { read(reader); }
UniqueID32(const hecl::ProjectPath& path) { *this = path; } UniqueID32(const hecl::ProjectPath& path) { *this = path; }
UniqueID32(const char* hexStr) { UniqueID32(const char* hexStr) {
@ -202,22 +162,6 @@ public:
using UniqueID32::UniqueID32; using UniqueID32::UniqueID32;
}; };
class AuxiliaryID32 : public UniqueID32 {
const hecl::SystemChar* m_auxStr;
const hecl::SystemChar* m_addExtension;
UniqueID32 m_baseId;
public:
AT_DECL_DNA
Delete __d2;
AuxiliaryID32(const hecl::SystemChar* auxStr, const hecl::SystemChar* addExtension = nullptr)
: m_auxStr(auxStr), m_addExtension(addExtension) {}
AuxiliaryID32& operator=(const hecl::ProjectPath& path);
AuxiliaryID32& operator=(const UniqueID32& id);
const UniqueID32& getBaseId() const { return m_baseId; }
};
/** PAK 64-bit Unique ID */ /** PAK 64-bit Unique ID */
class UniqueID64 : public BigDNA { class UniqueID64 : public BigDNA {
uint64_t m_id = 0xffffffffffffffff; uint64_t m_id = 0xffffffffffffffff;
@ -226,7 +170,7 @@ public:
using value_type = uint64_t; using value_type = uint64_t;
AT_DECL_EXPLICIT_DNA_YAML AT_DECL_EXPLICIT_DNA_YAML
bool isValid() const { return m_id != 0xffffffffffffffff && m_id != 0; } bool isValid() const { return m_id != 0xffffffffffffffff && m_id != 0; }
void assign(uint64_t id, bool noOriginal = false); void assign(uint64_t id) { m_id = id ? id : 0xffffffffffffffff; }
UniqueID64& operator=(const hecl::ProjectPath& path) { UniqueID64& operator=(const hecl::ProjectPath& path) {
assign(path.hash().val64()); assign(path.hash().val64());
@ -241,7 +185,7 @@ public:
void clear() { m_id = 0xffffffffffffffff; } void clear() { m_id = 0xffffffffffffffff; }
UniqueID64() = default; UniqueID64() = default;
UniqueID64(uint64_t idin, bool noOriginal = false) { assign(idin, noOriginal); } UniqueID64(uint64_t idin) { assign(idin); }
UniqueID64(athena::io::IStreamReader& reader) { read(reader); } UniqueID64(athena::io::IStreamReader& reader) { read(reader); }
UniqueID64(const hecl::ProjectPath& path) { *this = path; } UniqueID64(const hecl::ProjectPath& path) { *this = path; }
UniqueID64(const char* hexStr) { UniqueID64(const char* hexStr) {
@ -280,7 +224,7 @@ public:
m_id.id[0] = 0xffffffffffffffff; m_id.id[0] = 0xffffffffffffffff;
m_id.id[1] = 0xffffffffffffffff; m_id.id[1] = 0xffffffffffffffff;
} }
UniqueID128(uint64_t idin, bool noOriginal = false) { UniqueID128(uint64_t idin) {
m_id.id[0] = idin; m_id.id[0] = idin;
m_id.id[1] = 0; m_id.id[1] = 0;
} }
@ -401,25 +345,32 @@ typedef std::function<bool(const hecl::ProjectPath&, const hecl::ProjectPath&)>
/** Mappings of resources involved in extracting characters */ /** Mappings of resources involved in extracting characters */
template <class IDType> template <class IDType>
struct CharacterAssociations { struct CharacterAssociations {
using RigPair = std::pair<IDType, IDType>; struct RigPair { IDType cskr, cinf; };
struct ModelRigPair { IDType cinf, cmdl; };
/* CMDL -> (CSKR, CINF) */ /* CMDL -> (CSKR, CINF) */
std::unordered_map<IDType, RigPair> m_cmdlRigs; std::unordered_map<IDType, RigPair> m_cmdlRigs;
/* (CSKR, CINF) -> ANCS */ /* CSKR -> ANCS */
std::unordered_map<IDType, std::pair<IDType, std::string>> m_cskrCinfToCharacter; std::unordered_map<IDType, std::pair<IDType, std::string>> m_cskrToCharacter;
/* ANCS -> (CINF, CMDL) */ /* ANCS -> (CINF, CMDL) */
std::unordered_multimap<IDType, std::pair<RigPair, std::string>> m_characterToAttachmentRigs; std::unordered_multimap<IDType, std::pair<ModelRigPair, std::string>> m_characterToAttachmentRigs;
using MultimapIteratorPair = using MultimapIteratorPair =
std::pair<typename std::unordered_multimap<IDType, std::pair<RigPair, std::string>>::const_iterator, std::pair<typename std::unordered_multimap<IDType, std::pair<ModelRigPair, std::string>>::const_iterator,
typename std::unordered_multimap<IDType, std::pair<RigPair, std::string>>::const_iterator>; typename std::unordered_multimap<IDType, std::pair<ModelRigPair, std::string>>::const_iterator>;
void addAttachmentRig(IDType character, IDType cinf, IDType cmdl, const char* name) { void addAttachmentRig(IDType character, IDType cinf, IDType cmdl, const char* name) {
auto range = m_characterToAttachmentRigs.equal_range(character); auto range = m_characterToAttachmentRigs.equal_range(character);
for (auto it = range.first; it != range.second; ++it) for (auto it = range.first; it != range.second; ++it)
if (it->second.second == name) if (it->second.second == name)
return; return;
m_characterToAttachmentRigs.insert(std::make_pair(character, std::make_pair(std::make_pair(cinf, cmdl), name))); m_characterToAttachmentRigs.insert(std::make_pair(character, std::make_pair(ModelRigPair{cinf, cmdl}, name)));
} }
}; };
hecl::ProjectPath GetPathBeginsWith(const hecl::DirectoryEnumerator& dEnum, const hecl::ProjectPath& parentPath,
hecl::SystemStringView test);
inline hecl::ProjectPath GetPathBeginsWith(const hecl::ProjectPath& parentPath, hecl::SystemStringView test) {
return GetPathBeginsWith(hecl::DirectoryEnumerator(parentPath.getAbsolutePath()), parentPath, test);
}
} // namespace DataSpec } // namespace DataSpec
/* Hash template-specializations for UniqueID types */ /* Hash template-specializations for UniqueID types */
@ -446,5 +397,6 @@ struct hash<DataSpec::UniqueID128> {
} // namespace std } // namespace std
FMT_CUSTOM_FORMATTER(DataSpec::UniqueID32, "{:08X}", obj.toUint32()) FMT_CUSTOM_FORMATTER(DataSpec::UniqueID32, "{:08X}", obj.toUint32())
FMT_CUSTOM_FORMATTER(DataSpec::UniqueID32Zero, "{:08X}", obj.toUint32())
FMT_CUSTOM_FORMATTER(DataSpec::UniqueID64, "{:016X}", obj.toUint64()) FMT_CUSTOM_FORMATTER(DataSpec::UniqueID64, "{:016X}", obj.toUint64())
FMT_CUSTOM_FORMATTER(DataSpec::UniqueID128, "{:016X}{:016X}", obj.toHighUint64(), obj.toLowUint64()) FMT_CUSTOM_FORMATTER(DataSpec::UniqueID128, "{:016X}{:016X}", obj.toHighUint64(), obj.toLowUint64())

View File

@ -8,13 +8,13 @@
namespace DataSpec::DNAParticle { namespace DataSpec::DNAParticle {
template <> template <>
const char* DPSM<UniqueID32>::DNAType() { std::string_view DPSM<UniqueID32>::DNAType() {
return "DPSM<UniqueID32>"; return "DPSM<UniqueID32>"sv;
} }
template <> template <>
const char* DPSM<UniqueID64>::DNAType() { std::string_view DPSM<UniqueID64>::DNAType() {
return "DPSM<UniqueID64>"; return "DPSM<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>
@ -69,10 +69,10 @@ void DPSM<IDType>::_read(athena::io::YAMLDocReader& r) {
x58_DMCL.read(r); x58_DMCL.read(r);
break; break;
case SBIG('DMAB'): case SBIG('DMAB'):
x5c_24_DMAB = r.readBool(nullptr); x5c_24_DMAB = r.readBool();
break; break;
case SBIG('DMOO'): case SBIG('DMOO'):
x5c_25_DMOO = r.readBool(nullptr); x5c_25_DMOO = r.readBool();
break; break;
} }
} }

View File

@ -400,13 +400,13 @@ AT_SUBSPECIALIZE_DNA_YAML(ELSM<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(ELSM<UniqueID64>) AT_SUBSPECIALIZE_DNA_YAML(ELSM<UniqueID64>)
template <> template <>
const char* ELSM<UniqueID32>::DNAType() { std::string_view ELSM<UniqueID32>::DNAType() {
return "urde::ELSM<UniqueID32>"; return "urde::ELSM<UniqueID32>"sv;
} }
template <> template <>
const char* ELSM<UniqueID64>::DNAType() { std::string_view ELSM<UniqueID64>::DNAType() {
return "urde::ELSM<UniqueID64>"; return "urde::ELSM<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>

View File

@ -132,7 +132,7 @@ void FONT<IDType>::_read(athena::io::YAMLDocReader& __dna_docin) {
else else
glyphs.emplace_back(new GlyphMP2); glyphs.emplace_back(new GlyphMP2);
if (auto rec = __dna_docin.enterSubRecord(nullptr)) if (auto rec = __dna_docin.enterSubRecord())
glyphs.back()->read(__dna_docin); glyphs.back()->read(__dna_docin);
} }
} }
@ -171,7 +171,7 @@ void FONT<IDType>::_write(athena::io::YAMLDocWriter& __dna_docout) const {
/* glyphs */ /* glyphs */
if (auto v = __dna_docout.enterSubVector("glyphs")) if (auto v = __dna_docout.enterSubVector("glyphs"))
for (const std::unique_ptr<IGlyph>& glyph : glyphs) for (const std::unique_ptr<IGlyph>& glyph : glyphs)
if (auto rec = __dna_docout.enterSubRecord(nullptr)) if (auto rec = __dna_docout.enterSubRecord())
glyph->write(__dna_docout); glyph->write(__dna_docout);
/* kerningInfoCount squelched */ /* kerningInfoCount squelched */
/* kerningInfo */ /* kerningInfo */
@ -179,13 +179,13 @@ void FONT<IDType>::_write(athena::io::YAMLDocWriter& __dna_docout) const {
} }
template <> template <>
const char* FONT<UniqueID32>::DNAType() { std::string_view FONT<UniqueID32>::DNAType() {
return "FONT<UniqueID32>"; return "FONT<UniqueID32>"sv;
} }
template <> template <>
const char* FONT<UniqueID64>::DNAType() { std::string_view FONT<UniqueID64>::DNAType() {
return "FONT<UniqueID64>"; return "FONT<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>

View File

@ -38,13 +38,13 @@ AT_SPECIALIZE_DNA(FSM2<UniqueID32>)
AT_SPECIALIZE_DNA(FSM2<UniqueID64>) AT_SPECIALIZE_DNA(FSM2<UniqueID64>)
template <> template <>
const char* FSM2<UniqueID32>::DNAType() { std::string_view FSM2<UniqueID32>::DNAType() {
return "urde::FSM2<UniqueID32>"; return "urde::FSM2<UniqueID32>"sv;
} }
template <> template <>
const char* FSM2<UniqueID64>::DNAType() { std::string_view FSM2<UniqueID64>::DNAType() {
return "urde::FSM2<UniqueID64>"; return "urde::FSM2<UniqueID64>"sv;
} }
template struct FSM2<UniqueID32>; template struct FSM2<UniqueID32>;

View File

@ -288,9 +288,15 @@ bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const
mtx[2][2], mtx[3][2]); mtx[2][2], mtx[3][2]);
/* World background */ /* World background */
hecl::ProjectPath worldBlend(outPath.getParentPath().getParentPath(), "!world.blend"); hecl::ProjectPath worldDir = outPath.getParentPath().getParentPath();
if (worldBlend.isFile()) for (const auto& ent : hecl::DirectoryEnumerator(worldDir.getAbsolutePath())) {
os.linkBackground("//../!world.blend", "World"); if (hecl::StringUtils::BeginsWith(ent.m_name, _SYS_STR("!world_")) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".blend"))) {
hecl::SystemUTF8Conv conv(ent.m_name);
os.linkBackground(fmt::format(fmt("//../{}"), conv), "World"sv);
break;
}
}
os.centerView(); os.centerView();
os.close(); os.close();
@ -335,7 +341,7 @@ bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out) {
mapa.header = std::make_unique<typename MAPAType::Header>(); mapa.header = std::make_unique<typename MAPAType::Header>();
typename MAPAType::Header& header = static_cast<typename MAPAType::Header&>(*mapa.header); typename MAPAType::Header& header = static_cast<typename MAPAType::Header&>(*mapa.header);
header.unknown1 = 0; header.unknown1 = 0;
header.mapVisMode = mapaIn.visType.val; header.mapVisMode = mapaIn.visType;
header.boundingBox[0] = aabb.min; header.boundingBox[0] = aabb.min;
header.boundingBox[1] = aabb.max; header.boundingBox[1] = aabb.max;
header.moCount = mapaIn.pois.size(); header.moCount = mapaIn.pois.size();
@ -379,22 +385,22 @@ bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out) {
prim.type = GX::TRIANGLESTRIP; prim.type = GX::TRIANGLESTRIP;
prim.indexCount = surfIn.count; prim.indexCount = surfIn.count;
prim.indices.reserve(surfIn.count); prim.indices.reserve(surfIn.count);
auto itBegin = mapaIn.indices.begin() + surfIn.start.val; auto itBegin = mapaIn.indices.begin() + surfIn.start;
auto itEnd = itBegin + surfIn.count; auto itEnd = itBegin + surfIn.count;
for (auto it = itBegin; it != itEnd; ++it) for (auto it = itBegin; it != itEnd; ++it)
prim.indices.push_back(it->val); prim.indices.push_back(*it);
surf.borderCount = surfIn.borders.size(); surf.borderCount = surfIn.borders.size();
surf.borders.reserve(surfIn.borders.size()); surf.borders.reserve(surfIn.borders.size());
for (const auto& borderIn : surfIn.borders) { for (const auto& borderIn : surfIn.borders) {
surf.borders.emplace_back(); surf.borders.emplace_back();
DNAMAPA::MAPA::Surface::Border& border = surf.borders.back(); DNAMAPA::MAPA::Surface::Border& border = surf.borders.back();
border.indexCount = borderIn.second.val; border.indexCount = borderIn.second;
border.indices.reserve(borderIn.second.val); border.indices.reserve(borderIn.second);
auto it2Begin = mapaIn.indices.begin() + borderIn.first.val; auto it2Begin = mapaIn.indices.begin() + borderIn.first;
auto it2End = it2Begin + borderIn.second.val; auto it2End = it2Begin + borderIn.second;
for (auto it = it2Begin; it != it2End; ++it) for (auto it = it2Begin; it != it2End; ++it)
border.indices.push_back(it->val); border.indices.push_back(*it);
} }
surfHead.normal = surfIn.normal.val; surfHead.normal = surfIn.normal.val;

View File

@ -33,7 +33,7 @@ bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const
"\n"; "\n";
hecl::ProjectPath hexPath = pakRouter.getWorking(mapu.hexMapa); hecl::ProjectPath hexPath = pakRouter.getWorking(mapu.hexMapa);
os.linkBlend(hexPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(mapu.hexMapa).data()); os.linkMesh(hexPath.getAbsolutePathUTF8(), "MAP");
os << "hexMesh = bpy.data.objects['MAP'].data\n"; os << "hexMesh = bpy.data.objects['MAP'].data\n";
for (const MAPU::World& wld : mapu.worlds) { for (const MAPU::World& wld : mapu.worlds) {
@ -114,7 +114,13 @@ bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPat
mapu.worlds.emplace_back(); mapu.worlds.emplace_back();
MAPU::World& wldOut = mapu.worlds.back(); MAPU::World& wldOut = mapu.worlds.back();
wldOut.name = wld.name; wldOut.name = wld.name;
wldOut.mlvl = hecl::ProjectPath(wld.worldPath, _SYS_STR("!world.*")); for (const auto& ent : wld.worldPath.enumerateDir()) {
if (hecl::StringUtils::BeginsWith(ent.m_name, _SYS_STR("!world_")) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".blend"))) {
wldOut.mlvl = hecl::ProjectPath(wld.worldPath, ent.m_name);
break;
}
}
wldOut.transform.xf[0] = wld.xf.val[0]; wldOut.transform.xf[0] = wld.xf.val[0];
wldOut.transform.xf[1] = wld.xf.val[1]; wldOut.transform.xf[1] = wld.xf.val[1];
wldOut.transform.xf[2] = wld.xf.val[2]; wldOut.transform.xf[2] = wld.xf.val[2];

View File

@ -11,24 +11,24 @@ void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRID
UniqueResult::Type resultType = UniqueResult::Type::NotFound; UniqueResult::Type resultType = UniqueResult::Type::NotFound;
bool foundOneLayer = false; bool foundOneLayer = false;
const hecl::SystemString* levelName = nullptr; const hecl::SystemString* levelName = nullptr;
typename PAKBRIDGE::PAKType::IDType levelId; typename PAKBRIDGE::PAKType::IDType useLevelId;
typename PAKBRIDGE::PAKType::IDType areaId; typename PAKBRIDGE::PAKType::IDType useAreaId;
unsigned layerIdx; unsigned layerIdx = 0;
for (const auto& lpair : pakBridge.m_levelDeps) { for (const auto& [levelId, level] : pakBridge.m_levelDeps) {
if (entry.id == lpair.first) { if (entry.id == levelId || level.resources.find(entry.id) != level.resources.end()) {
levelName = &lpair.second.name; levelName = &level.name;
resultType = UniqueResult::Type::Level; resultType = UniqueResult::Type::Level;
break; break;
} }
for (const auto& pair : lpair.second.areas) { for (const auto& [areaId, area] : level.areas) {
unsigned l = 0; unsigned l = 0;
for (const auto& layer : pair.second.layers) { for (const auto& layer : area.layers) {
if (layer.resources.find(entry.id) != layer.resources.end()) { if (layer.resources.find(entry.id) != layer.resources.end()) {
if (foundOneLayer) { if (foundOneLayer) {
if (areaId == pair.first) { if (useAreaId == areaId) {
resultType = UniqueResult::Type::Area; resultType = UniqueResult::Type::Area;
} else if (levelId == lpair.first) { } else if (useLevelId == levelId) {
resultType = UniqueResult::Type::Level; resultType = UniqueResult::Type::Level;
break; break;
} else { } else {
@ -38,19 +38,19 @@ void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRID
continue; continue;
} else } else
resultType = UniqueResult::Type::Layer; resultType = UniqueResult::Type::Layer;
levelName = &lpair.second.name; levelName = &level.name;
levelId = lpair.first; useLevelId = levelId;
areaId = pair.first; useAreaId = areaId;
layerIdx = l; layerIdx = l;
foundOneLayer = true; foundOneLayer = true;
} }
++l; ++l;
} }
if (pair.second.resources.find(entry.id) != pair.second.resources.end()) { if (area.resources.find(entry.id) != area.resources.end()) {
if (foundOneLayer) { if (foundOneLayer) {
if (areaId == pair.first) { if (useAreaId == areaId) {
resultType = UniqueResult::Type::Area; resultType = UniqueResult::Type::Area;
} else if (levelId == lpair.first) { } else if (useLevelId == levelId) {
resultType = UniqueResult::Type::Level; resultType = UniqueResult::Type::Level;
break; break;
} else { } else {
@ -60,9 +60,9 @@ void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRID
continue; continue;
} else } else
resultType = UniqueResult::Type::Area; resultType = UniqueResult::Type::Area;
levelName = &lpair.second.name; levelName = &level.name;
levelId = lpair.first; useLevelId = levelId;
areaId = pair.first; useAreaId = areaId;
foundOneLayer = true; foundOneLayer = true;
} }
} }
@ -70,7 +70,7 @@ void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRID
m_type = resultType; m_type = resultType;
m_levelName = levelName; m_levelName = levelName;
if (resultType == UniqueResult::Type::Layer || resultType == UniqueResult::Type::Area) { if (resultType == UniqueResult::Type::Layer || resultType == UniqueResult::Type::Area) {
const typename PAKBRIDGE::Level::Area& area = pakBridge.m_levelDeps.at(levelId).areas.at(areaId); const typename PAKBRIDGE::Level::Area& area = pakBridge.m_levelDeps.at(useLevelId).areas.at(useAreaId);
m_areaName = &area.name; m_areaName = &area.name;
if (resultType == UniqueResult::Type::Layer) { if (resultType == UniqueResult::Type::Layer) {
const typename PAKBRIDGE::Level::Area::Layer& layer = area.layers[layerIdx]; const typename PAKBRIDGE::Level::Area::Layer& layer = area.layers[layerIdx];
@ -160,7 +160,7 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
/* Add named resources to catalog YAML files */ /* Add named resources to catalog YAML files */
for (BRIDGETYPE& bridge : bridges) { for (BRIDGETYPE& bridge : bridges) {
athena::io::YAMLDocWriter catalogWriter(nullptr); athena::io::YAMLDocWriter catalogWriter;
enterPAKBridge(bridge); enterPAKBridge(bridge);
@ -171,15 +171,15 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
for (const auto& namedEntry : pak.m_nameEntries) { for (const auto& namedEntry : pak.m_nameEntries) {
if (namedEntry.name == "holo_cinf") if (namedEntry.name == "holo_cinf")
continue; /* Problematic corner case */ continue; /* Problematic corner case */
if (auto rec = catalogWriter.enterSubRecord(namedEntry.name.c_str())) { if (auto rec = catalogWriter.enterSubRecord(namedEntry.name)) {
hecl::ProjectPath working = getWorking(namedEntry.id); hecl::ProjectPath working = getWorking(namedEntry.id);
if (working.getAuxInfoUTF8().size()) { if (working.getAuxInfoUTF8().size()) {
if (auto v = catalogWriter.enterSubVector(nullptr)) { if (auto v = catalogWriter.enterSubVector()) {
catalogWriter.writeString(nullptr, working.getRelativePathUTF8()); catalogWriter.writeString(working.getRelativePathUTF8());
catalogWriter.writeString(nullptr, working.getAuxInfoUTF8()); catalogWriter.writeString(working.getAuxInfoUTF8());
} }
} else } else
catalogWriter.writeString(nullptr, working.getRelativePathUTF8()); catalogWriter.writeString(working.getRelativePathUTF8());
} }
} }
@ -212,8 +212,8 @@ void PAKRouter<BRIDGETYPE>::enterPAKBridge(const BRIDGETYPE& pakBridge) {
template <class BRIDGETYPE> template <class BRIDGETYPE>
hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCharacterWorking(const EntryType* entry) const { hecl::ProjectPath PAKRouter<BRIDGETYPE>::getCharacterWorking(const EntryType* entry) const {
auto characterSearch = m_charAssoc.m_cskrCinfToCharacter.find(entry->id); auto characterSearch = m_charAssoc.m_cskrToCharacter.find(entry->id);
if (characterSearch != m_charAssoc.m_cskrCinfToCharacter.cend()) { if (characterSearch != m_charAssoc.m_cskrToCharacter.cend()) {
hecl::ProjectPath characterPath = getWorking(characterSearch->second.first); hecl::ProjectPath characterPath = getWorking(characterSearch->second.first);
if (entry->type == FOURCC('EVNT')) { if (entry->type == FOURCC('EVNT')) {
hecl::SystemStringConv wideStr(characterSearch->second.second); hecl::SystemStringConv wideStr(characterSearch->second.second);
@ -240,11 +240,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
const EntryType* singleSearch = pak->lookupEntry(entry->id); const EntryType* singleSearch = pak->lookupEntry(entry->id);
if (singleSearch) { if (singleSearch) {
const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first;
#if HECL_UCS2 hecl::SystemString entName = hecl::UTF8StringToSysString(getBestEntryName(*entry));
hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry));
#else
hecl::SystemString entName = getBestEntryName(*entry);
#endif
hecl::SystemString auxInfo; hecl::SystemString auxInfo;
if (extractor.fileExts[0] && !extractor.fileExts[1]) if (extractor.fileExts[0] && !extractor.fileExts[1])
entName += extractor.fileExts[0]; entName += extractor.fileExts[0];
@ -260,11 +256,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
if (uniqueSearch != m_uniqueEntries.end()) { if (uniqueSearch != m_uniqueEntries.end()) {
const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first); const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first);
const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].first; const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].first;
#if HECL_UCS2 hecl::SystemString entName = hecl::UTF8StringToSysString(getBestEntryName(*entry));
hecl::SystemString entName = hecl::UTF8ToWide(getBestEntryName(*entry));
#else
hecl::SystemString entName = getBestEntryName(*entry);
#endif
hecl::SystemString auxInfo; hecl::SystemString auxInfo;
if (extractor.fileExts[0] && !extractor.fileExts[1]) if (extractor.fileExts[0] && !extractor.fileExts[1])
entName += extractor.fileExts[0]; entName += extractor.fileExts[0];
@ -282,11 +274,7 @@ hecl::ProjectPath PAKRouter<BRIDGETYPE>::getWorking(const EntryType* entry,
auto sharedSearch = m_sharedEntries.find(entry->id); auto sharedSearch = m_sharedEntries.find(entry->id);
if (sharedSearch != m_sharedEntries.end()) { if (sharedSearch != m_sharedEntries.end()) {
#if HECL_UCS2 hecl::SystemString entBase = hecl::UTF8StringToSysString(getBestEntryName(*entry));
hecl::SystemString entBase = hecl::UTF8ToWide(getBestEntryName(*entry));
#else
hecl::SystemString entBase = getBestEntryName(*entry);
#endif
hecl::SystemString auxInfo; hecl::SystemString auxInfo;
hecl::SystemString entName = entBase; hecl::SystemString entName = entBase;
if (extractor.fileExts[0] && !extractor.fileExts[1]) if (extractor.fileExts[0] && !extractor.fileExts[1])
@ -389,18 +377,22 @@ std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const EntryType& entry, bool
if (stdOverride && !pak.m_noShare) { if (stdOverride && !pak.m_noShare) {
if (entry.type == FOURCC('MLVL')) if (entry.type == FOURCC('MLVL'))
return "!world"; return fmt::format(fmt("!world_{}"), entry.id);
else if (entry.type == FOURCC('MREA')) else if (entry.type == FOURCC('MREA'))
return "!area"; return fmt::format(fmt("!area_{}"), entry.id);
else if (entry.type == FOURCC('MAPA')) else if (entry.type == FOURCC('MAPA'))
return "!map"; return fmt::format(fmt("!map_{}"), entry.id);
else if (entry.type == FOURCC('PATH')) else if (entry.type == FOURCC('PATH'))
return "!path"; return fmt::format(fmt("!path_{}"), entry.id);
else if (entry.type == FOURCC('MAPW'))
return fmt::format(fmt("!mapw_{}"), entry.id);
else if (entry.type == FOURCC('SAVW'))
return fmt::format(fmt("!savw_{}"), entry.id);
} }
bool named; std::string catalogueName;
name = pak.bestEntryName(bridge.getNode(), entry, named); name = pak.bestEntryName(bridge.getNode(), entry, catalogueName);
if (named) if (!catalogueName.empty())
return name; return name;
} }
return name; return name;
@ -417,18 +409,22 @@ std::string PAKRouter<BRIDGETYPE>::getBestEntryName(const IDType& entry, bool st
if (stdOverride && !pak.m_noShare) { if (stdOverride && !pak.m_noShare) {
if (e->type == FOURCC('MLVL')) if (e->type == FOURCC('MLVL'))
return "!world"; return fmt::format(fmt("!world_{}"), e->id);
else if (e->type == FOURCC('MREA')) else if (e->type == FOURCC('MREA'))
return "!area"; return fmt::format(fmt("!area_{}"), e->id);
else if (e->type == FOURCC('MAPA')) else if (e->type == FOURCC('MAPA'))
return "!map"; return fmt::format(fmt("!map_{}"), e->id);
else if (e->type == FOURCC('PATH')) else if (e->type == FOURCC('PATH'))
return "!path"; return fmt::format(fmt("!path_{}"), e->id);
else if (e->type == FOURCC('MAPW'))
return fmt::format(fmt("!mapw_{}"), e->id);
else if (e->type == FOURCC('SAVW'))
return fmt::format(fmt("!savw_{}"), e->id);
} }
bool named; std::string catalogueName;
name = pak.bestEntryName(bridge.getNode(), *e, named); name = pak.bestEntryName(bridge.getNode(), *e, catalogueName);
if (named) if (!catalogueName.empty())
return name; return name;
} }
return name; return name;

View File

@ -137,6 +137,7 @@ struct Level {
std::unordered_set<IDType> resources; std::unordered_set<IDType> resources;
}; };
std::unordered_map<IDType, Area> areas; std::unordered_map<IDType, Area> areas;
std::unordered_set<IDType> resources;
}; };
/** PAKRouter (for detecting shared entry locations) */ /** PAKRouter (for detecting shared entry locations) */
@ -176,6 +177,7 @@ public:
void build(std::vector<BRIDGETYPE>& bridges, std::function<void(float)> progress); void build(std::vector<BRIDGETYPE>& bridges, std::function<void(float)> progress);
void enterPAKBridge(const BRIDGETYPE& pakBridge); void enterPAKBridge(const BRIDGETYPE& pakBridge);
const BRIDGETYPE& getCurrentBridge() const { return (*m_bridges)[reinterpret_cast<intptr_t>(m_curBridgeIdx.get())]; }
using PAKRouterBase::getWorking; using PAKRouterBase::getWorking;
hecl::ProjectPath getWorking(const EntryType* entry, const ResExtractor<BRIDGETYPE>& extractor) const; hecl::ProjectPath getWorking(const EntryType* entry, const ResExtractor<BRIDGETYPE>& extractor) const;

View File

@ -5,13 +5,13 @@
namespace DataSpec::DNAParticle { namespace DataSpec::DNAParticle {
template <> template <>
const char* GPSM<UniqueID32>::DNAType() { std::string_view GPSM<UniqueID32>::DNAType() {
return "GPSM<UniqueID32>"; return "GPSM<UniqueID32>"sv;
} }
template <> template <>
const char* GPSM<UniqueID64>::DNAType() { std::string_view GPSM<UniqueID64>::DNAType() {
return "GPSM<UniqueID64>"; return "GPSM<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>
@ -40,10 +40,10 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r) {
x30_COLR.read(r); x30_COLR.read(r);
break; break;
case SBIG('CIND'): case SBIG('CIND'):
x45_30_CIND = r.readBool(nullptr); x45_30_CIND = r.readBool();
break; break;
case SBIG('AAPH'): case SBIG('AAPH'):
x44_26_AAPH = r.readBool(nullptr); x44_26_AAPH = r.readBool();
break; break;
case SBIG('CSSD'): case SBIG('CSSD'):
xa0_CSSD.read(r); xa0_CSSD.read(r);
@ -52,7 +52,7 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r) {
x2c_GRTE.read(r); x2c_GRTE.read(r);
break; break;
case SBIG('FXLL'): case SBIG('FXLL'):
x44_25_FXLL = r.readBool(nullptr); x44_25_FXLL = r.readBool();
break; break;
case SBIG('ICTS'): case SBIG('ICTS'):
x8c_ICTS.read(r); x8c_ICTS.read(r);
@ -88,13 +88,13 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r) {
x108_LINT.read(r); x108_LINT.read(r);
break; break;
case SBIG('LINE'): case SBIG('LINE'):
x44_24_LINE = r.readBool(nullptr); x44_24_LINE = r.readBool();
break; break;
case SBIG('LFOT'): case SBIG('LFOT'):
x114_LFOT.read(r); x114_LFOT.read(r);
break; break;
case SBIG('LIT_'): case SBIG('LIT_'):
x44_29_LIT_ = r.readBool(nullptr); x44_29_LIT_ = r.readBool();
break; break;
case SBIG('LTME'): case SBIG('LTME'):
x34_LTME.read(r); x34_LTME.read(r);
@ -112,7 +112,7 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r) {
x48_MBSP.read(r); x48_MBSP.read(r);
break; break;
case SBIG('MBLR'): case SBIG('MBLR'):
x44_30_MBLR = r.readBool(nullptr); x44_30_MBLR = r.readBool();
break; break;
case SBIG('NCSY'): case SBIG('NCSY'):
x9c_NCSY.read(r); x9c_NCSY.read(r);
@ -121,10 +121,10 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r) {
xc8_PISY.read(r); xc8_PISY.read(r);
break; break;
case SBIG('OPTS'): case SBIG('OPTS'):
x45_31_OPTS = r.readBool(nullptr); x45_31_OPTS = r.readBool();
break; break;
case SBIG('PMAB'): case SBIG('PMAB'):
x44_31_PMAB = r.readBool(nullptr); x44_31_PMAB = r.readBool();
break; break;
case SBIG('SESD'): case SBIG('SESD'):
xf8_SESD.read(r); xf8_SESD.read(r);
@ -151,7 +151,7 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r) {
x18_POFS.read(r); x18_POFS.read(r);
break; break;
case SBIG('PMUS'): case SBIG('PMUS'):
x45_24_PMUS = r.readBool(nullptr); x45_24_PMUS = r.readBool();
break; break;
case SBIG('PSIV'): case SBIG('PSIV'):
x0_PSIV.read(r); x0_PSIV.read(r);
@ -178,13 +178,13 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r) {
x1c_SEED.read(r); x1c_SEED.read(r);
break; break;
case SBIG('PMOO'): case SBIG('PMOO'):
x45_25_PMOO = r.readBool(nullptr); x45_25_PMOO = r.readBool();
break; break;
case SBIG('SSSD'): case SBIG('SSSD'):
xe4_SSSD.read(r); xe4_SSSD.read(r);
break; break;
case SBIG('SORT'): case SBIG('SORT'):
x44_28_SORT = r.readBool(nullptr); x44_28_SORT = r.readBool();
break; break;
case SBIG('SIZE'): case SBIG('SIZE'):
x4c_SIZE.read(r); x4c_SIZE.read(r);
@ -205,16 +205,16 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r) {
x58_TIND.read(r); x58_TIND.read(r);
break; break;
case SBIG('VMD4'): case SBIG('VMD4'):
x45_29_VMD4 = r.readBool(nullptr); x45_29_VMD4 = r.readBool();
break; break;
case SBIG('VMD3'): case SBIG('VMD3'):
x45_28_VMD3 = r.readBool(nullptr); x45_28_VMD3 = r.readBool();
break; break;
case SBIG('VMD2'): case SBIG('VMD2'):
x45_27_VMD2 = r.readBool(nullptr); x45_27_VMD2 = r.readBool();
break; break;
case SBIG('VMD1'): case SBIG('VMD1'):
x45_26_VMD1 = r.readBool(nullptr); x45_26_VMD1 = r.readBool();
break; break;
case SBIG('VEL4'): case SBIG('VEL4'):
x88_VEL4.read(r); x88_VEL4.read(r);
@ -229,16 +229,16 @@ void GPSM<IDType>::_read(typename ReadYaml::StreamT& r) {
x7c_VEL1.read(r); x7c_VEL1.read(r);
break; break;
case SBIG('ZBUF'): case SBIG('ZBUF'):
x44_27_ZBUF = r.readBool(nullptr); x44_27_ZBUF = r.readBool();
break; break;
case SBIG('WIDT'): case SBIG('WIDT'):
x24_WIDT.read(r); x24_WIDT.read(r);
break; break;
case SBIG('ORNT'): case SBIG('ORNT'):
x30_30_ORNT = r.readBool(nullptr); x30_30_ORNT = r.readBool();
break; break;
case SBIG('RSOP'): case SBIG('RSOP'):
x30_31_RSOP = r.readBool(nullptr); x30_31_RSOP = r.readBool();
break; break;
case SBIG('ADV1'): case SBIG('ADV1'):
x10c_ADV1.read(r); x10c_ADV1.read(r);

View File

@ -5,11 +5,11 @@ logvisor::Module LogModule("urde::DNAParticle");
template <> template <>
void REConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) { void REConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
val = r.readFloat(nullptr); val = r.readFloat();
} }
template <> template <>
void REConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) { void REConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) {
w.writeFloat(nullptr, val); w.writeFloat(val);
} }
template <> template <>
void REConstant::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) { void REConstant::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
@ -26,11 +26,11 @@ void REConstant::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
template <> template <>
void IEConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) { void IEConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
val = r.readUint32(nullptr); val = r.readUint32();
} }
template <> template <>
void IEConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) { void IEConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) {
w.writeUint32(nullptr, val); w.writeUint32(val);
} }
template <> template <>
void IEConstant::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) { void IEConstant::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
@ -48,18 +48,18 @@ void IEConstant::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
template <> template <>
void VEConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) { void VEConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
size_t elemCount; size_t elemCount;
if (auto v = r.enterSubVector(nullptr, elemCount)) { if (auto v = r.enterSubVector(elemCount)) {
for (size_t i = 0; i < 3 && i < elemCount; ++i) { for (size_t i = 0; i < 3 && i < elemCount; ++i) {
if (auto rec = r.enterSubRecord(nullptr)) if (auto rec = r.enterSubRecord())
comps[i].read(r); comps[i].read(r);
} }
} }
} }
template <> template <>
void VEConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) { void VEConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) {
if (auto v = w.enterSubVector(nullptr)) if (auto v = w.enterSubVector())
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
if (auto rec = w.enterSubRecord(nullptr)) if (auto rec = w.enterSubRecord())
comps[i].write(w); comps[i].write(w);
} }
template <> template <>
@ -84,14 +84,14 @@ void VEConstant::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
template <> template <>
void CEConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) { void CEConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
if (auto rec = r.enterSubRecord(nullptr)) if (auto rec = r.enterSubRecord())
comps[i].read(r); comps[i].read(r);
} }
template <> template <>
void CEConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) { void CEConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) {
if (auto v = w.enterSubVector(nullptr)) if (auto v = w.enterSubVector())
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
if (auto rec = w.enterSubRecord(nullptr)) if (auto rec = w.enterSubRecord())
comps[i].write(w); comps[i].write(w);
} }
template <> template <>
@ -119,14 +119,14 @@ void CEConstant::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
template <> template <>
void MVEConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) { void MVEConstant::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
if (auto rec = r.enterSubRecord(nullptr)) if (auto rec = r.enterSubRecord())
comps[i].read(r); comps[i].read(r);
} }
template <> template <>
void MVEConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) { void MVEConstant::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) {
if (auto v = w.enterSubVector(nullptr)) if (auto v = w.enterSubVector())
for (int i = 0; i < 3; ++i) for (int i = 0; i < 3; ++i)
if (auto rec = w.enterSubRecord(nullptr)) if (auto rec = w.enterSubRecord())
comps[i].write(w); comps[i].write(w);
} }
template <> template <>
@ -402,7 +402,7 @@ void RealElementFactory::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {
template <> template <>
void RealElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) { void RealElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
if (m_elem) { if (m_elem) {
w.writeBytes((atInt8*)m_elem->ClassID(), 4); w.writeBytes((atInt8*)m_elem->ClassID().data(), 4);
m_elem->write(w); m_elem->write(w);
} else } else
w.writeBytes((atInt8*)"NONE", 4); w.writeBytes((atInt8*)"NONE", 4);
@ -566,7 +566,7 @@ void IntElementFactory::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {
template <> template <>
void IntElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) { void IntElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
if (m_elem) { if (m_elem) {
w.writeBytes((atInt8*)m_elem->ClassID(), 4); w.writeBytes((atInt8*)m_elem->ClassID().data(), 4);
m_elem->write(w); m_elem->write(w);
} else } else
w.writeBytes((atInt8*)"NONE", 4); w.writeBytes((atInt8*)"NONE", 4);
@ -730,7 +730,7 @@ void VectorElementFactory::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {
template <> template <>
void VectorElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) { void VectorElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
if (m_elem) { if (m_elem) {
w.writeBytes((atInt8*)m_elem->ClassID(), 4); w.writeBytes((atInt8*)m_elem->ClassID().data(), 4);
m_elem->write(w); m_elem->write(w);
} else } else
w.writeBytes((atInt8*)"NONE", 4); w.writeBytes((atInt8*)"NONE", 4);
@ -828,7 +828,7 @@ void ColorElementFactory::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {
template <> template <>
void ColorElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) { void ColorElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
if (m_elem) { if (m_elem) {
w.writeBytes((atInt8*)m_elem->ClassID(), 4); w.writeBytes((atInt8*)m_elem->ClassID().data(), 4);
m_elem->write(w); m_elem->write(w);
} else } else
w.writeBytes((atInt8*)"NONE", 4); w.writeBytes((atInt8*)"NONE", 4);
@ -960,7 +960,7 @@ void ModVectorElementFactory::Enumerate<BigDNA::Read>(typename Read::StreamT& r)
template <> template <>
void ModVectorElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) { void ModVectorElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
if (m_elem) { if (m_elem) {
w.writeBytes((atInt8*)m_elem->ClassID(), 4); w.writeBytes((atInt8*)m_elem->ClassID().data(), 4);
m_elem->write(w); m_elem->write(w);
} else } else
w.writeBytes((atInt8*)"NONE", 4); w.writeBytes((atInt8*)"NONE", 4);
@ -1044,7 +1044,7 @@ void EmitterElementFactory::Enumerate<BigDNA::Read>(typename Read::StreamT& r) {
template <> template <>
void EmitterElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) { void EmitterElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
if (m_elem) { if (m_elem) {
w.writeBytes((atInt8*)m_elem->ClassID(), 4); w.writeBytes((atInt8*)m_elem->ClassID().data(), 4);
m_elem->write(w); m_elem->write(w);
} else } else
w.writeBytes((atInt8*)"NONE", 4); w.writeBytes((atInt8*)"NONE", 4);
@ -1052,11 +1052,11 @@ void EmitterElementFactory::Enumerate<BigDNA::Write>(typename Write::StreamT& w)
template <> template <>
void BoolHelper::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) { void BoolHelper::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& r) {
value = r.readBool(nullptr); value = r.readBool();
} }
template <> template <>
void BoolHelper::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) { void BoolHelper::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w) {
w.writeBool(nullptr, value); w.writeBool(value);
} }
template <> template <>
void BoolHelper::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) { void BoolHelper::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
@ -1121,12 +1121,12 @@ void EESimpleEmitterTR::Enumerate<BigDNA::Write>(typename Write::StreamT& w) {
} }
template <> template <>
const char* UVEConstant<UniqueID32>::DNAType() { std::string_view UVEConstant<UniqueID32>::DNAType() {
return "UVEConstant<UniqueID32>"; return "UVEConstant<UniqueID32>"sv;
} }
template <> template <>
const char* UVEConstant<UniqueID64>::DNAType() { std::string_view UVEConstant<UniqueID64>::DNAType() {
return "UVEConstant<UniqueID64>"; return "UVEConstant<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>
@ -1166,12 +1166,12 @@ template struct UVEConstant<UniqueID32>;
template struct UVEConstant<UniqueID64>; template struct UVEConstant<UniqueID64>;
template <> template <>
const char* UVEAnimTexture<UniqueID32>::DNAType() { std::string_view UVEAnimTexture<UniqueID32>::DNAType() {
return "UVEAnimTexture<UniqueID32>"; return "UVEAnimTexture<UniqueID32>"sv;
} }
template <> template <>
const char* UVEAnimTexture<UniqueID64>::DNAType() { std::string_view UVEAnimTexture<UniqueID64>::DNAType() {
return "UVEAnimTexture<UniqueID64>"; return "UVEAnimTexture<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>
@ -1190,7 +1190,7 @@ void UVEAnimTexture<IDType>::_read(typename ReadYaml::StreamT& r) {
if (auto rec = r.enterSubRecord("cycleFrames")) if (auto rec = r.enterSubRecord("cycleFrames"))
cycleFrames.read(r); cycleFrames.read(r);
if (auto rec = r.enterSubRecord("loop")) if (auto rec = r.enterSubRecord("loop"))
loop = r.readBool(nullptr); loop = r.readBool();
} }
template <class IDType> template <class IDType>
void UVEAnimTexture<IDType>::_write(typename WriteYaml::StreamT& w) const { void UVEAnimTexture<IDType>::_write(typename WriteYaml::StreamT& w) const {
@ -1254,12 +1254,12 @@ template struct UVEAnimTexture<UniqueID32>;
template struct UVEAnimTexture<UniqueID64>; template struct UVEAnimTexture<UniqueID64>;
template <> template <>
const char* UVElementFactory<UniqueID32>::DNAType() { std::string_view UVElementFactory<UniqueID32>::DNAType() {
return "UVElementFactory<UniqueID32>"; return "UVElementFactory<UniqueID32>"sv;
} }
template <> template <>
const char* UVElementFactory<UniqueID64>::DNAType() { std::string_view UVElementFactory<UniqueID64>::DNAType() {
return "UVElementFactory<UniqueID64>"; return "UVElementFactory<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>
@ -1282,7 +1282,7 @@ void UVElementFactory<IDType>::_read(typename Read::StreamT& r) {
template <class IDType> template <class IDType>
void UVElementFactory<IDType>::_write(typename Write::StreamT& w) const { void UVElementFactory<IDType>::_write(typename Write::StreamT& w) const {
if (m_elem) { if (m_elem) {
w.writeBytes((atInt8*)m_elem->ClassID(), 4); w.writeBytes((atInt8*)m_elem->ClassID().data(), 4);
m_elem->write(w); m_elem->write(w);
} else } else
w.writeBytes((atInt8*)"NONE", 4); w.writeBytes((atInt8*)"NONE", 4);
@ -1318,12 +1318,12 @@ template struct UVElementFactory<UniqueID32>;
template struct UVElementFactory<UniqueID64>; template struct UVElementFactory<UniqueID64>;
template <> template <>
const char* SpawnSystemKeyframeData<UniqueID32>::SpawnSystemKeyframeInfo::DNAType() { std::string_view SpawnSystemKeyframeData<UniqueID32>::SpawnSystemKeyframeInfo::DNAType() {
return "SpawnSystemKeyframeData<UniqueID32>::SpawnSystemKeyframeInfo"; return "SpawnSystemKeyframeData<UniqueID32>::SpawnSystemKeyframeInfo"sv;
} }
template <> template <>
const char* SpawnSystemKeyframeData<UniqueID64>::SpawnSystemKeyframeInfo::DNAType() { std::string_view SpawnSystemKeyframeData<UniqueID64>::SpawnSystemKeyframeInfo::DNAType() {
return "SpawnSystemKeyframeData<UniqueID64>::SpawnSystemKeyframeInfo"; return "SpawnSystemKeyframeData<UniqueID64>::SpawnSystemKeyframeInfo"sv;
} }
template <class IDType> template <class IDType>
@ -1336,31 +1336,31 @@ void SpawnSystemKeyframeData<IDType>::SpawnSystemKeyframeInfo::Enumerate(typenam
} }
template <> template <>
const char* SpawnSystemKeyframeData<UniqueID32>::DNAType() { std::string_view SpawnSystemKeyframeData<UniqueID32>::DNAType() {
return "SpawnSystemKeyframeData<UniqueID32>"; return "SpawnSystemKeyframeData<UniqueID32>"sv;
} }
template <> template <>
const char* SpawnSystemKeyframeData<UniqueID64>::DNAType() { std::string_view SpawnSystemKeyframeData<UniqueID64>::DNAType() {
return "SpawnSystemKeyframeData<UniqueID64>"; return "SpawnSystemKeyframeData<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>
void SpawnSystemKeyframeData<IDType>::_read(typename ReadYaml::StreamT& r) { void SpawnSystemKeyframeData<IDType>::_read(typename ReadYaml::StreamT& r) {
if (auto rec = r.enterSubRecord("a")) if (auto rec = r.enterSubRecord("a"))
a = r.readUint32(nullptr); a = r.readUint32();
if (auto rec = r.enterSubRecord("b")) if (auto rec = r.enterSubRecord("b"))
b = r.readUint32(nullptr); b = r.readUint32();
if (auto rec = r.enterSubRecord("endFrame")) if (auto rec = r.enterSubRecord("endFrame"))
endFrame = r.readUint32(nullptr); endFrame = r.readUint32();
if (auto rec = r.enterSubRecord("d")) if (auto rec = r.enterSubRecord("d"))
d = r.readUint32(nullptr); d = r.readUint32();
spawns.clear(); spawns.clear();
size_t spawnCount; size_t spawnCount;
if (auto v = r.enterSubVector("spawns", spawnCount)) { if (auto v = r.enterSubVector("spawns", spawnCount)) {
spawns.reserve(spawnCount); spawns.reserve(spawnCount);
for (const auto& child : r.getCurNode()->m_seqChildren) { for (const auto& child : r.getCurNode()->m_seqChildren) {
(void)child; (void)child;
if (auto rec = r.enterSubRecord(nullptr)) { if (auto rec = r.enterSubRecord()) {
spawns.emplace_back(); spawns.emplace_back();
spawns.back().first = r.readUint32("startFrame"); spawns.back().first = r.readUint32("startFrame");
size_t systemCount; size_t systemCount;
@ -1370,7 +1370,7 @@ void SpawnSystemKeyframeData<IDType>::_read(typename ReadYaml::StreamT& r) {
(void)in; (void)in;
spawns.back().second.emplace_back(); spawns.back().second.emplace_back();
SpawnSystemKeyframeInfo& info = spawns.back().second.back(); SpawnSystemKeyframeInfo& info = spawns.back().second.back();
if (auto rec = r.enterSubRecord(nullptr)) if (auto rec = r.enterSubRecord())
info.read(r); info.read(r);
} }
} }
@ -1389,11 +1389,11 @@ void SpawnSystemKeyframeData<IDType>::_write(typename WriteYaml::StreamT& w) con
w.writeUint32("d", d); w.writeUint32("d", d);
if (auto v = w.enterSubVector("spawns")) { if (auto v = w.enterSubVector("spawns")) {
for (const auto& spawn : spawns) { for (const auto& spawn : spawns) {
if (auto rec = w.enterSubRecord(nullptr)) { if (auto rec = w.enterSubRecord()) {
w.writeUint32("startFrame", spawn.first); w.writeUint32("startFrame", spawn.first);
if (auto v = w.enterSubVector("systems")) if (auto v = w.enterSubVector("systems"))
for (const auto& info : spawn.second) for (const auto& info : spawn.second)
if (auto rec = w.enterSubRecord(nullptr)) if (auto rec = w.enterSubRecord())
info.write(w); info.write(w);
} }
} }
@ -1463,12 +1463,12 @@ template struct SpawnSystemKeyframeData<UniqueID32>;
template struct SpawnSystemKeyframeData<UniqueID64>; template struct SpawnSystemKeyframeData<UniqueID64>;
template <> template <>
const char* ChildResourceFactory<UniqueID32>::DNAType() { std::string_view ChildResourceFactory<UniqueID32>::DNAType() {
return "ChildResourceFactory<UniqueID32>"; return "ChildResourceFactory<UniqueID32>"sv;
} }
template <> template <>
const char* ChildResourceFactory<UniqueID64>::DNAType() { std::string_view ChildResourceFactory<UniqueID64>::DNAType() {
return "ChildResourceFactory<UniqueID64>"; return "ChildResourceFactory<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>

View File

@ -13,8 +13,8 @@ extern logvisor::Module LogModule;
struct IElement : BigDNAVYaml { struct IElement : BigDNAVYaml {
Delete _d; Delete _d;
~IElement() override = default; ~IElement() override = default;
virtual const char* ClassID() const = 0; virtual std::string_view ClassID() const = 0;
const char* DNATypeV() const override { return ClassID(); } std::string_view DNATypeV() const override { return ClassID(); }
}; };
struct IRealElement : IElement { struct IRealElement : IElement {
@ -84,20 +84,20 @@ struct BoolHelper : IElement {
value = val; value = val;
return *this; return *this;
} }
const char* ClassID() const override { return "BoolHelper"; } std::string_view ClassID() const override { return "BoolHelper"sv; }
}; };
struct RELifetimeTween : IRealElement { struct RELifetimeTween : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory a; RealElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "LFTW"; } std::string_view ClassID() const override { return "LFTW"sv; }
}; };
struct REConstant : IRealElement { struct REConstant : IRealElement {
AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE
Value<float> val; Value<float> val;
const char* ClassID() const override { return "CNST"; } std::string_view ClassID() const override { return "CNST"sv; }
}; };
struct RETimeChain : IRealElement { struct RETimeChain : IRealElement {
@ -105,14 +105,14 @@ struct RETimeChain : IRealElement {
RealElementFactory a; RealElementFactory a;
RealElementFactory b; RealElementFactory b;
IntElementFactory thresholdFrame; IntElementFactory thresholdFrame;
const char* ClassID() const override { return "CHAN"; } std::string_view ClassID() const override { return "CHAN"sv; }
}; };
struct REAdd : IRealElement { struct REAdd : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory a; RealElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "ADD_"; } std::string_view ClassID() const override { return "ADD_"sv; }
}; };
struct REClamp : IRealElement { struct REClamp : IRealElement {
@ -120,7 +120,7 @@ struct REClamp : IRealElement {
RealElementFactory min; RealElementFactory min;
RealElementFactory max; RealElementFactory max;
RealElementFactory val; RealElementFactory val;
const char* ClassID() const override { return "CLMP"; } std::string_view ClassID() const override { return "CLMP"sv; }
}; };
struct REKeyframeEmitter : IRealElement { struct REKeyframeEmitter : IRealElement {
@ -133,28 +133,28 @@ struct REKeyframeEmitter : IRealElement {
Value<atUint32> loopStart; Value<atUint32> loopStart;
Value<atUint32> count; Value<atUint32> count;
Vector<float, AT_DNA_COUNT(count)> keys; Vector<float, AT_DNA_COUNT(count)> keys;
const char* ClassID() const override { return percentageTween ? "KEYP" : "KEYE"; } std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; }
}; };
struct REInitialRandom : IRealElement { struct REInitialRandom : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory a; RealElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "IRND"; } std::string_view ClassID() const override { return "IRND"sv; }
}; };
struct RERandom : IRealElement { struct RERandom : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory a; RealElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "RAND"; } std::string_view ClassID() const override { return "RAND"sv; }
}; };
struct REMultiply : IRealElement { struct REMultiply : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory a; RealElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "MULT"; } std::string_view ClassID() const override { return "MULT"sv; }
}; };
struct REPulse : IRealElement { struct REPulse : IRealElement {
@ -163,19 +163,19 @@ struct REPulse : IRealElement {
IntElementFactory bDuration; IntElementFactory bDuration;
RealElementFactory a; RealElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "PULS"; } std::string_view ClassID() const override { return "PULS"sv; }
}; };
struct RETimeScale : IRealElement { struct RETimeScale : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory dv; RealElementFactory dv;
const char* ClassID() const override { return "SCAL"; } std::string_view ClassID() const override { return "SCAL"sv; }
}; };
struct RELifetimePercent : IRealElement { struct RELifetimePercent : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory percent; RealElementFactory percent;
const char* ClassID() const override { return "RLPT"; } std::string_view ClassID() const override { return "RLPT"sv; }
}; };
struct RESineWave : IRealElement { struct RESineWave : IRealElement {
@ -183,14 +183,14 @@ struct RESineWave : IRealElement {
RealElementFactory frequency; RealElementFactory frequency;
RealElementFactory amplitude; RealElementFactory amplitude;
RealElementFactory phase; RealElementFactory phase;
const char* ClassID() const override { return "SINE"; } std::string_view ClassID() const override { return "SINE"sv; }
}; };
struct REInitialSwitch : IRealElement { struct REInitialSwitch : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory a; RealElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "ISWT"; } std::string_view ClassID() const override { return "ISWT"sv; }
}; };
struct RECompareLessThan : IRealElement { struct RECompareLessThan : IRealElement {
@ -199,7 +199,7 @@ struct RECompareLessThan : IRealElement {
RealElementFactory cb; RealElementFactory cb;
RealElementFactory pass; RealElementFactory pass;
RealElementFactory fail; RealElementFactory fail;
const char* ClassID() const override { return "CLTN"; } std::string_view ClassID() const override { return "CLTN"sv; }
}; };
struct RECompareEquals : IRealElement { struct RECompareEquals : IRealElement {
@ -208,101 +208,101 @@ struct RECompareEquals : IRealElement {
RealElementFactory cb; RealElementFactory cb;
RealElementFactory pass; RealElementFactory pass;
RealElementFactory fail; RealElementFactory fail;
const char* ClassID() const override { return "CEQL"; } std::string_view ClassID() const override { return "CEQL"sv; }
}; };
struct REParticleAdvanceParam1 : IRealElement { struct REParticleAdvanceParam1 : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PAP1"; } std::string_view ClassID() const override { return "PAP1"sv; }
}; };
struct REParticleAdvanceParam2 : IRealElement { struct REParticleAdvanceParam2 : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PAP2"; } std::string_view ClassID() const override { return "PAP2"sv; }
}; };
struct REParticleAdvanceParam3 : IRealElement { struct REParticleAdvanceParam3 : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PAP3"; } std::string_view ClassID() const override { return "PAP3"sv; }
}; };
struct REParticleAdvanceParam4 : IRealElement { struct REParticleAdvanceParam4 : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PAP4"; } std::string_view ClassID() const override { return "PAP4"sv; }
}; };
struct REParticleAdvanceParam5 : IRealElement { struct REParticleAdvanceParam5 : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PAP5"; } std::string_view ClassID() const override { return "PAP5"sv; }
}; };
struct REParticleAdvanceParam6 : IRealElement { struct REParticleAdvanceParam6 : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PAP6"; } std::string_view ClassID() const override { return "PAP6"sv; }
}; };
struct REParticleAdvanceParam7 : IRealElement { struct REParticleAdvanceParam7 : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PAP7"; } std::string_view ClassID() const override { return "PAP7"sv; }
}; };
struct REParticleAdvanceParam8 : IRealElement { struct REParticleAdvanceParam8 : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PAP8"; } std::string_view ClassID() const override { return "PAP8"sv; }
}; };
struct REParticleSizeOrLineLength : IRealElement { struct REParticleSizeOrLineLength : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PSLL"; } std::string_view ClassID() const override { return "PSLL"sv; }
}; };
struct REParticleRotationOrLineWidth : IRealElement { struct REParticleRotationOrLineWidth : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PRLW"; } std::string_view ClassID() const override { return "PRLW"sv; }
}; };
struct RESubtract : IRealElement { struct RESubtract : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory a; RealElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "SUB_"; } std::string_view ClassID() const override { return "SUB_"sv; }
}; };
struct REVectorMagnitude : IRealElement { struct REVectorMagnitude : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory vec; VectorElementFactory vec;
const char* ClassID() const override { return "VMAG"; } std::string_view ClassID() const override { return "VMAG"sv; }
}; };
struct REVectorXToReal : IRealElement { struct REVectorXToReal : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory vec; VectorElementFactory vec;
const char* ClassID() const override { return "VXTR"; } std::string_view ClassID() const override { return "VXTR"sv; }
}; };
struct REVectorYToReal : IRealElement { struct REVectorYToReal : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory vec; VectorElementFactory vec;
const char* ClassID() const override { return "VYTR"; } std::string_view ClassID() const override { return "VYTR"sv; }
}; };
struct REVectorZToReal : IRealElement { struct REVectorZToReal : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory vec; VectorElementFactory vec;
const char* ClassID() const override { return "VZTR"; } std::string_view ClassID() const override { return "VZTR"sv; }
}; };
struct RECEXT : IRealElement { struct RECEXT : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory index; IntElementFactory index;
const char* ClassID() const override { return "CEXT"; } std::string_view ClassID() const override { return "CEXT"sv; }
}; };
struct REIntTimesReal : IRealElement { struct REIntTimesReal : IRealElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory a; IntElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "ITRL"; } std::string_view ClassID() const override { return "ITRL"sv; }
}; };
struct IEKeyframeEmitter : IIntElement { struct IEKeyframeEmitter : IIntElement {
@ -315,14 +315,14 @@ struct IEKeyframeEmitter : IIntElement {
Value<atUint32> loopStart; Value<atUint32> loopStart;
Value<atUint32> count; Value<atUint32> count;
Vector<atUint32, AT_DNA_COUNT(count)> keys; Vector<atUint32, AT_DNA_COUNT(count)> keys;
const char* ClassID() const override { return percentageTween ? "KEYP" : "KEYE"; } std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; }
}; };
struct IEDeath : IIntElement { struct IEDeath : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory passthrough; IntElementFactory passthrough;
IntElementFactory thresholdFrame; IntElementFactory thresholdFrame;
const char* ClassID() const override { return "DETH"; } std::string_view ClassID() const override { return "DETH"sv; }
}; };
struct IEClamp : IIntElement { struct IEClamp : IIntElement {
@ -330,7 +330,7 @@ struct IEClamp : IIntElement {
IntElementFactory min; IntElementFactory min;
IntElementFactory max; IntElementFactory max;
IntElementFactory val; IntElementFactory val;
const char* ClassID() const override { return "CLMP"; } std::string_view ClassID() const override { return "CLMP"sv; }
}; };
struct IETimeChain : IIntElement { struct IETimeChain : IIntElement {
@ -338,39 +338,39 @@ struct IETimeChain : IIntElement {
IntElementFactory a; IntElementFactory a;
IntElementFactory b; IntElementFactory b;
IntElementFactory thresholdFrame; IntElementFactory thresholdFrame;
const char* ClassID() const override { return "CHAN"; } std::string_view ClassID() const override { return "CHAN"sv; }
}; };
struct IEAdd : IIntElement { struct IEAdd : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory a; IntElementFactory a;
IntElementFactory b; IntElementFactory b;
const char* ClassID() const override { return "ADD_"; } std::string_view ClassID() const override { return "ADD_"sv; }
}; };
struct IEConstant : IIntElement { struct IEConstant : IIntElement {
AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE
Value<atUint32> val; Value<atUint32> val;
const char* ClassID() const override { return "CNST"; } std::string_view ClassID() const override { return "CNST"sv; }
}; };
struct IEImpulse : IIntElement { struct IEImpulse : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory val; IntElementFactory val;
const char* ClassID() const override { return "IMPL"; } std::string_view ClassID() const override { return "IMPL"sv; }
}; };
struct IELifetimePercent : IIntElement { struct IELifetimePercent : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory percent; IntElementFactory percent;
const char* ClassID() const override { return "ILPT"; } std::string_view ClassID() const override { return "ILPT"sv; }
}; };
struct IEInitialRandom : IIntElement { struct IEInitialRandom : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory a; IntElementFactory a;
IntElementFactory b; IntElementFactory b;
const char* ClassID() const override { return "IRND"; } std::string_view ClassID() const override { return "IRND"sv; }
}; };
struct IEPulse : IIntElement { struct IEPulse : IIntElement {
@ -379,14 +379,14 @@ struct IEPulse : IIntElement {
IntElementFactory bDuration; IntElementFactory bDuration;
IntElementFactory a; IntElementFactory a;
IntElementFactory b; IntElementFactory b;
const char* ClassID() const override { return "PULS"; } std::string_view ClassID() const override { return "PULS"sv; }
}; };
struct IEMultiply : IIntElement { struct IEMultiply : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory a; IntElementFactory a;
IntElementFactory b; IntElementFactory b;
const char* ClassID() const override { return "MULT"; } std::string_view ClassID() const override { return "MULT"sv; }
}; };
struct IESampleAndHold : IIntElement { struct IESampleAndHold : IIntElement {
@ -394,46 +394,46 @@ struct IESampleAndHold : IIntElement {
IntElementFactory val; IntElementFactory val;
IntElementFactory waitMin; IntElementFactory waitMin;
IntElementFactory waitMax; IntElementFactory waitMax;
const char* ClassID() const override { return "SPAH"; } std::string_view ClassID() const override { return "SPAH"sv; }
}; };
struct IERandom : IIntElement { struct IERandom : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory a; IntElementFactory a;
IntElementFactory b; IntElementFactory b;
const char* ClassID() const override { return "RAND"; } std::string_view ClassID() const override { return "RAND"sv; }
}; };
struct IETimeScale : IIntElement { struct IETimeScale : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory dv; RealElementFactory dv;
const char* ClassID() const override { return "TSCL"; } std::string_view ClassID() const override { return "TSCL"sv; }
}; };
struct IEGTCP : IIntElement { struct IEGTCP : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "GTCP"; } std::string_view ClassID() const override { return "GTCP"sv; }
}; };
struct IEModulo : IIntElement { struct IEModulo : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory a; IntElementFactory a;
IntElementFactory b; IntElementFactory b;
const char* ClassID() const override { return "MODU"; } std::string_view ClassID() const override { return "MODU"sv; }
}; };
struct IESubtract : IIntElement { struct IESubtract : IIntElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
IntElementFactory direction; IntElementFactory direction;
IntElementFactory baseRadius; IntElementFactory baseRadius;
const char* ClassID() const override { return "SUB_"; } std::string_view ClassID() const override { return "SUB_"sv; }
}; };
struct VECone : IVectorElement { struct VECone : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory a; VectorElementFactory a;
RealElementFactory b; RealElementFactory b;
const char* ClassID() const override { return "CONE"; } std::string_view ClassID() const override { return "CONE"sv; }
}; };
struct VETimeChain : IVectorElement { struct VETimeChain : IVectorElement {
@ -441,7 +441,7 @@ struct VETimeChain : IVectorElement {
VectorElementFactory a; VectorElementFactory a;
VectorElementFactory b; VectorElementFactory b;
IntElementFactory thresholdFrame; IntElementFactory thresholdFrame;
const char* ClassID() const override { return "CHAN"; } std::string_view ClassID() const override { return "CHAN"sv; }
}; };
struct VEAngleCone : IVectorElement { struct VEAngleCone : IVectorElement {
@ -451,14 +451,14 @@ struct VEAngleCone : IVectorElement {
RealElementFactory angleXRange; RealElementFactory angleXRange;
RealElementFactory angleYRange; RealElementFactory angleYRange;
RealElementFactory magnitude; RealElementFactory magnitude;
const char* ClassID() const override { return "ANGC"; } std::string_view ClassID() const override { return "ANGC"sv; }
}; };
struct VEAdd : IVectorElement { struct VEAdd : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory a; VectorElementFactory a;
VectorElementFactory b; VectorElementFactory b;
const char* ClassID() const override { return "ADD_"; } std::string_view ClassID() const override { return "ADD_"sv; }
}; };
struct VECircleCluster : IVectorElement { struct VECircleCluster : IVectorElement {
@ -467,13 +467,13 @@ struct VECircleCluster : IVectorElement {
VectorElementFactory circleNormal; VectorElementFactory circleNormal;
IntElementFactory cycleFrames; IntElementFactory cycleFrames;
RealElementFactory randomFactor; RealElementFactory randomFactor;
const char* ClassID() const override { return "CCLU"; } std::string_view ClassID() const override { return "CCLU"sv; }
}; };
struct VEConstant : IVectorElement { struct VEConstant : IVectorElement {
AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE
RealElementFactory comps[3]; RealElementFactory comps[3];
const char* ClassID() const override { return "CNST"; } std::string_view ClassID() const override { return "CNST"sv; }
}; };
struct VECircle : IVectorElement { struct VECircle : IVectorElement {
@ -483,7 +483,7 @@ struct VECircle : IVectorElement {
RealElementFactory angleConstant; RealElementFactory angleConstant;
RealElementFactory angleLinear; RealElementFactory angleLinear;
RealElementFactory circleRadius; RealElementFactory circleRadius;
const char* ClassID() const override { return "CIRC"; } std::string_view ClassID() const override { return "CIRC"sv; }
}; };
struct VEKeyframeEmitter : IVectorElement { struct VEKeyframeEmitter : IVectorElement {
@ -496,20 +496,20 @@ struct VEKeyframeEmitter : IVectorElement {
Value<atUint32> loopStart; Value<atUint32> loopStart;
Value<atUint32> count; Value<atUint32> count;
Vector<atVec3f, AT_DNA_COUNT(count)> keys; Vector<atVec3f, AT_DNA_COUNT(count)> keys;
const char* ClassID() const override { return percentageTween ? "KEYP" : "KEYE"; } std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; }
}; };
struct VEMultiply : IVectorElement { struct VEMultiply : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory a; VectorElementFactory a;
VectorElementFactory b; VectorElementFactory b;
const char* ClassID() const override { return "MULT"; } std::string_view ClassID() const override { return "MULT"sv; }
}; };
struct VERealToVector : IVectorElement { struct VERealToVector : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory a; RealElementFactory a;
const char* ClassID() const override { return "RTOV"; } std::string_view ClassID() const override { return "RTOV"sv; }
}; };
struct VEPulse : IVectorElement { struct VEPulse : IVectorElement {
@ -518,38 +518,38 @@ struct VEPulse : IVectorElement {
IntElementFactory bDuration; IntElementFactory bDuration;
VectorElementFactory a; VectorElementFactory a;
VectorElementFactory b; VectorElementFactory b;
const char* ClassID() const override { return "PULS"; } std::string_view ClassID() const override { return "PULS"sv; }
}; };
struct VEParticleVelocity : IVectorElement { struct VEParticleVelocity : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PVEL"; } std::string_view ClassID() const override { return "PVEL"sv; }
}; };
struct VESPOS : IVectorElement { struct VESPOS : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory a; VectorElementFactory a;
const char* ClassID() const override { return "SPOS"; } std::string_view ClassID() const override { return "SPOS"sv; }
}; };
struct VEPLCO : IVectorElement { struct VEPLCO : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PLCO"; } std::string_view ClassID() const override { return "PLCO"sv; }
}; };
struct VEPLOC : IVectorElement { struct VEPLOC : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PLOC"; } std::string_view ClassID() const override { return "PLOC"sv; }
}; };
struct VEPSOR : IVectorElement { struct VEPSOR : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PSOR"; } std::string_view ClassID() const override { return "PSOR"sv; }
}; };
struct VEPSOF : IVectorElement { struct VEPSOF : IVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "PSOF"; } std::string_view ClassID() const override { return "PSOF"sv; }
}; };
struct CEKeyframeEmitter : IColorElement { struct CEKeyframeEmitter : IColorElement {
@ -562,13 +562,13 @@ struct CEKeyframeEmitter : IColorElement {
Value<atUint32> loopStart; Value<atUint32> loopStart;
Value<atUint32> count; Value<atUint32> count;
Vector<atVec4f, AT_DNA_COUNT(count)> keys; Vector<atVec4f, AT_DNA_COUNT(count)> keys;
const char* ClassID() const override { return percentageTween ? "KEYP" : "KEYE"; } std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; }
}; };
struct CEConstant : IColorElement { struct CEConstant : IColorElement {
AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE
RealElementFactory comps[4]; RealElementFactory comps[4];
const char* ClassID() const override { return "CNST"; } std::string_view ClassID() const override { return "CNST"sv; }
}; };
struct CETimeChain : IColorElement { struct CETimeChain : IColorElement {
@ -576,7 +576,7 @@ struct CETimeChain : IColorElement {
ColorElementFactory a; ColorElementFactory a;
ColorElementFactory b; ColorElementFactory b;
IntElementFactory thresholdFrame; IntElementFactory thresholdFrame;
const char* ClassID() const override { return "CHAN"; } std::string_view ClassID() const override { return "CHAN"sv; }
}; };
struct CEFadeEnd : IColorElement { struct CEFadeEnd : IColorElement {
@ -585,7 +585,7 @@ struct CEFadeEnd : IColorElement {
ColorElementFactory b; ColorElementFactory b;
RealElementFactory startFrame; RealElementFactory startFrame;
RealElementFactory endFrame; RealElementFactory endFrame;
const char* ClassID() const override { return "CFDE"; } std::string_view ClassID() const override { return "CFDE"sv; }
}; };
struct CEFade : IColorElement { struct CEFade : IColorElement {
@ -593,7 +593,7 @@ struct CEFade : IColorElement {
ColorElementFactory a; ColorElementFactory a;
ColorElementFactory b; ColorElementFactory b;
RealElementFactory endFrame; RealElementFactory endFrame;
const char* ClassID() const override { return "FADE"; } std::string_view ClassID() const override { return "FADE"sv; }
}; };
struct CEPulse : IColorElement { struct CEPulse : IColorElement {
@ -602,7 +602,7 @@ struct CEPulse : IColorElement {
IntElementFactory bDuration; IntElementFactory bDuration;
ColorElementFactory a; ColorElementFactory a;
ColorElementFactory b; ColorElementFactory b;
const char* ClassID() const override { return "PULS"; } std::string_view ClassID() const override { return "PULS"sv; }
}; };
struct MVEImplosion : IModVectorElement { struct MVEImplosion : IModVectorElement {
@ -612,7 +612,7 @@ struct MVEImplosion : IModVectorElement {
RealElementFactory maxRadius; RealElementFactory maxRadius;
RealElementFactory minRadius; RealElementFactory minRadius;
BoolHelper enableMinRadius; BoolHelper enableMinRadius;
const char* ClassID() const override { return "IMPL"; } std::string_view ClassID() const override { return "IMPL"sv; }
}; };
struct MVEExponentialImplosion : IModVectorElement { struct MVEExponentialImplosion : IModVectorElement {
@ -622,7 +622,7 @@ struct MVEExponentialImplosion : IModVectorElement {
RealElementFactory maxRadius; RealElementFactory maxRadius;
RealElementFactory minRadius; RealElementFactory minRadius;
BoolHelper enableMinRadius; BoolHelper enableMinRadius;
const char* ClassID() const override { return "EMPL"; } std::string_view ClassID() const override { return "EMPL"sv; }
}; };
struct MVETimeChain : IModVectorElement { struct MVETimeChain : IModVectorElement {
@ -630,7 +630,7 @@ struct MVETimeChain : IModVectorElement {
ModVectorElementFactory a; ModVectorElementFactory a;
ModVectorElementFactory b; ModVectorElementFactory b;
IntElementFactory thresholdFrame; IntElementFactory thresholdFrame;
const char* ClassID() const override { return "CHAN"; } std::string_view ClassID() const override { return "CHAN"sv; }
}; };
struct MVEBounce : IModVectorElement { struct MVEBounce : IModVectorElement {
@ -640,32 +640,32 @@ struct MVEBounce : IModVectorElement {
RealElementFactory friction; RealElementFactory friction;
RealElementFactory restitution; RealElementFactory restitution;
BoolHelper dieOnPenetrate; BoolHelper dieOnPenetrate;
const char* ClassID() const override { return "BNCE"; } std::string_view ClassID() const override { return "BNCE"sv; }
}; };
struct MVEConstant : IModVectorElement { struct MVEConstant : IModVectorElement {
AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE
RealElementFactory comps[3]; RealElementFactory comps[3];
const char* ClassID() const override { return "CNST"; } std::string_view ClassID() const override { return "CNST"sv; }
}; };
struct MVEGravity : IModVectorElement { struct MVEGravity : IModVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory acceleration; VectorElementFactory acceleration;
const char* ClassID() const override { return "GRAV"; } std::string_view ClassID() const override { return "GRAV"sv; }
}; };
struct MVEExplode : IModVectorElement { struct MVEExplode : IModVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
RealElementFactory impulseMagnitude; RealElementFactory impulseMagnitude;
RealElementFactory falloffFactor; RealElementFactory falloffFactor;
const char* ClassID() const override { return "EXPL"; } std::string_view ClassID() const override { return "EXPL"sv; }
}; };
struct MVESetPosition : IModVectorElement { struct MVESetPosition : IModVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory position; VectorElementFactory position;
const char* ClassID() const override { return "SPOS"; } std::string_view ClassID() const override { return "SPOS"sv; }
}; };
struct MVELinearImplosion : IModVectorElement { struct MVELinearImplosion : IModVectorElement {
@ -675,7 +675,7 @@ struct MVELinearImplosion : IModVectorElement {
RealElementFactory maxRadius; RealElementFactory maxRadius;
RealElementFactory minRadius; RealElementFactory minRadius;
BoolHelper enableMinRadius; BoolHelper enableMinRadius;
const char* ClassID() const override { return "LMPL"; } std::string_view ClassID() const override { return "LMPL"sv; }
}; };
struct MVEPulse : IModVectorElement { struct MVEPulse : IModVectorElement {
@ -684,14 +684,14 @@ struct MVEPulse : IModVectorElement {
IntElementFactory bDuration; IntElementFactory bDuration;
ModVectorElementFactory a; ModVectorElementFactory a;
ModVectorElementFactory b; ModVectorElementFactory b;
const char* ClassID() const override { return "PULS"; } std::string_view ClassID() const override { return "PULS"sv; }
}; };
struct MVEWind : IModVectorElement { struct MVEWind : IModVectorElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory windVelocity; VectorElementFactory windVelocity;
RealElementFactory factor; RealElementFactory factor;
const char* ClassID() const override { return "WIND"; } std::string_view ClassID() const override { return "WIND"sv; }
}; };
struct MVESwirl : IModVectorElement { struct MVESwirl : IModVectorElement {
@ -700,14 +700,14 @@ struct MVESwirl : IModVectorElement {
VectorElementFactory curveBinormal; VectorElementFactory curveBinormal;
RealElementFactory filterGain; RealElementFactory filterGain;
RealElementFactory tangentialVelocity; RealElementFactory tangentialVelocity;
const char* ClassID() const override { return "SWRL"; } std::string_view ClassID() const override { return "SWRL"sv; }
}; };
struct EESimpleEmitter : IEmitterElement { struct EESimpleEmitter : IEmitterElement {
AT_DECL_DNA_YAMLV_NO_TYPE AT_DECL_DNA_YAMLV_NO_TYPE
VectorElementFactory position; VectorElementFactory position;
VectorElementFactory velocity; VectorElementFactory velocity;
const char* ClassID() const override { return "SEMR"; } std::string_view ClassID() const override { return "SEMR"sv; }
}; };
struct VESphere : IEmitterElement { struct VESphere : IEmitterElement {
@ -715,7 +715,7 @@ struct VESphere : IEmitterElement {
VectorElementFactory sphereOrigin; VectorElementFactory sphereOrigin;
RealElementFactory sphereRadius; RealElementFactory sphereRadius;
RealElementFactory magnitude; RealElementFactory magnitude;
const char* ClassID() const override { return "SPHE"; } std::string_view ClassID() const override { return "SPHE"sv; }
}; };
struct VEAngleSphere : IEmitterElement { struct VEAngleSphere : IEmitterElement {
@ -727,12 +727,12 @@ struct VEAngleSphere : IEmitterElement {
RealElementFactory angleYBias; RealElementFactory angleYBias;
RealElementFactory angleXRange; RealElementFactory angleXRange;
RealElementFactory angleYRange; RealElementFactory angleYRange;
const char* ClassID() const override { return "ASPH"; } std::string_view ClassID() const override { return "ASPH"sv; }
}; };
struct EESimpleEmitterTR : EESimpleEmitter { struct EESimpleEmitterTR : EESimpleEmitter {
AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE
const char* ClassID() const override { return "SETR"; } std::string_view ClassID() const override { return "SETR"sv; }
}; };
template <class IDType> template <class IDType>
@ -740,7 +740,7 @@ struct UVEConstant : IUVElement {
AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE
AT_SUBDECL_DNA AT_SUBDECL_DNA
CastIDToZero<IDType> tex; CastIDToZero<IDType> tex;
const char* ClassID() const override { return "CNST"; } std::string_view ClassID() const override { return "CNST"sv; }
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const override { void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const override {
g_curSpec->flattenDependencies(tex, pathsOut); g_curSpec->flattenDependencies(tex, pathsOut);
@ -758,7 +758,7 @@ struct UVEAnimTexture : IUVElement {
IntElementFactory strideH; IntElementFactory strideH;
IntElementFactory cycleFrames; IntElementFactory cycleFrames;
Value<bool> loop = false; Value<bool> loop = false;
const char* ClassID() const override { return "ATEX"; } std::string_view ClassID() const override { return "ATEX"sv; }
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const override { void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const override {
g_curSpec->flattenDependencies(tex, pathsOut); g_curSpec->flattenDependencies(tex, pathsOut);

View File

@ -52,7 +52,7 @@ RigInverter<CINFType>::Bone::Bone(const CINFType& cinf, const typename CINFType:
m_tail = naturalTail; m_tail = naturalTail;
else if (isLCTR) else if (isLCTR)
m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * (m_tail - boneOrigin).magnitude(); m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * (m_tail - boneOrigin).magnitude();
} else if (parentIdx != UINT32_MAX) { } else {
/* Extrapolate by delta with parent */ /* Extrapolate by delta with parent */
m_tail = boneOrigin + m_parentDelta; m_tail = boneOrigin + m_parentDelta;
float deltaMag = m_parentDelta.magnitude(); float deltaMag = m_parentDelta.magnitude();
@ -67,9 +67,6 @@ RigInverter<CINFType>::Bone::Bone(const CINFType& cinf, const typename CINFType:
if (isLCTR) if (isLCTR)
m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * deltaMag; m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * deltaMag;
} else {
/* Fallback to +Y tail */
m_tail = naturalTail;
} }
} }

View File

@ -7,13 +7,13 @@
namespace DataSpec::DNAParticle { namespace DataSpec::DNAParticle {
template <> template <>
const char* SWSH<UniqueID32>::DNAType() { std::string_view SWSH<UniqueID32>::DNAType() {
return "SWSH<UniqueID32>"; return "SWSH<UniqueID32>"sv;
} }
template <> template <>
const char* SWSH<UniqueID64>::DNAType() { std::string_view SWSH<UniqueID64>::DNAType() {
return "SWSH<UniqueID64>"; return "SWSH<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>
@ -78,37 +78,37 @@ void SWSH<IDType>::_read(typename BigDNA::ReadYaml::StreamT& r) {
x40_TSPN.read(r); x40_TSPN.read(r);
break; break;
case SBIG('LLRD'): case SBIG('LLRD'):
x44_24_LLRD = r.readBool(nullptr); x44_24_LLRD = r.readBool();
break; break;
case SBIG('CROS'): case SBIG('CROS'):
x44_25_CROS = r.readBool(nullptr); x44_25_CROS = r.readBool();
break; break;
case SBIG('VLS1'): case SBIG('VLS1'):
x44_26_VLS1 = r.readBool(nullptr); x44_26_VLS1 = r.readBool();
break; break;
case SBIG('VLS2'): case SBIG('VLS2'):
x44_27_VLS2 = r.readBool(nullptr); x44_27_VLS2 = r.readBool();
break; break;
case SBIG('SROT'): case SBIG('SROT'):
x44_28_SROT = r.readBool(nullptr); x44_28_SROT = r.readBool();
break; break;
case SBIG('WIRE'): case SBIG('WIRE'):
x44_29_WIRE = r.readBool(nullptr); x44_29_WIRE = r.readBool();
break; break;
case SBIG('TEXW'): case SBIG('TEXW'):
x44_30_TEXW = r.readBool(nullptr); x44_30_TEXW = r.readBool();
break; break;
case SBIG('AALP'): case SBIG('AALP'):
x44_31_AALP = r.readBool(nullptr); x44_31_AALP = r.readBool();
break; break;
case SBIG('ZBUF'): case SBIG('ZBUF'):
x45_24_ZBUF = r.readBool(nullptr); x45_24_ZBUF = r.readBool();
break; break;
case SBIG('ORNT'): case SBIG('ORNT'):
x45_25_ORNT = r.readBool(nullptr); x45_25_ORNT = r.readBool();
break; break;
case SBIG('CRND'): case SBIG('CRND'):
x45_26_CRND = r.readBool(nullptr); x45_26_CRND = r.readBool();
break; break;
default: default:
break; break;

View File

@ -1594,8 +1594,8 @@ void DataSpec::TXTR::PaletteMeta::Enumerate(typename Op::StreamT& s) {
AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::PaletteMeta) AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::PaletteMeta)
const char* DataSpec::TXTR::PaletteMeta::DNAType() { std::string_view DataSpec::TXTR::PaletteMeta::DNAType() {
return "DataSpec::TXTR::PaletteMeta"; return "DataSpec::TXTR::PaletteMeta"sv;
} }
template <class Op> template <class Op>
@ -1612,8 +1612,8 @@ void DataSpec::TXTR::Meta::Enumerate(typename Op::StreamT& s) {
AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::Meta) AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::Meta)
const char* DataSpec::TXTR::Meta::DNAType() { std::string_view DataSpec::TXTR::Meta::DNAType() {
return "DataSpec::TXTR::Meta"; return "DataSpec::TXTR::Meta"sv;
} }
static const atInt32 RetroToDol[11] { static const atInt32 RetroToDol[11] {

View File

@ -101,7 +101,7 @@ void WPSM<IDType>::_read(athena::io::YAMLDocReader& r) {
xa6_SWTR.read(r); xa6_SWTR.read(r);
break; break;
case SBIG('PJFX'): case SBIG('PJFX'):
xa8_PJFX = r.readUint32(nullptr); xa8_PJFX = r.readUint32();
break; break;
case SBIG('RNGE'): case SBIG('RNGE'):
xac_RNGE.read(r); xac_RNGE.read(r);
@ -642,13 +642,13 @@ AT_SUBSPECIALIZE_DNA_YAML(WPSM<UniqueID32>)
AT_SUBSPECIALIZE_DNA_YAML(WPSM<UniqueID64>) AT_SUBSPECIALIZE_DNA_YAML(WPSM<UniqueID64>)
template <> template <>
const char* WPSM<UniqueID32>::DNAType() { std::string_view WPSM<UniqueID32>::DNAType() {
return "WPSM<UniqueID32>"; return "WPSM<UniqueID32>"sv;
} }
template <> template <>
const char* WPSM<UniqueID64>::DNAType() { std::string_view WPSM<UniqueID64>::DNAType() {
return "WPSM<UniqueID64>"; return "WPSM<UniqueID64>"sv;
} }
template <class IDType> template <class IDType>

View File

@ -43,7 +43,7 @@ void AFSM::State::Transition::Enumerate<BigDNA::BinarySize>(typename BinarySize:
trig.binarySize(s); trig.binarySize(s);
} }
const char* AFSM::State::Transition::DNAType() { return "urde::DNAMP1::AFSM::Transition"; } std::string_view AFSM::State::Transition::DNAType() { return "urde::DNAMP1::AFSM::Transition"sv; }
template <> template <>
void AFSM::State::Transition::Trigger::Enumerate<BigDNA::Read>(athena::io::IStreamReader& __dna_reader) { void AFSM::State::Transition::Trigger::Enumerate<BigDNA::Read>(athena::io::IStreamReader& __dna_reader) {
@ -99,6 +99,8 @@ void AFSM::State::Transition::Trigger::Enumerate<BigDNA::BinarySize>(size_t& __i
__isz += (first ? 8 : 4); __isz += (first ? 8 : 4);
} }
const char* AFSM::State::Transition::Trigger::DNAType() { return "urde::DNAMP1::AFSM::State::Transition::Trigger"; } std::string_view AFSM::State::Transition::Trigger::DNAType() {
return "urde::DNAMP1::AFSM::State::Transition::Trigger"sv;
}
} // namespace DataSpec::DNAMP1 } // namespace DataSpec::DNAMP1

View File

@ -87,21 +87,21 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumer
if (auto v = reader.enterSubVector("range", parmValCount)) { if (auto v = reader.enterSubVector("range", parmValCount)) {
switch (DataType(parmType)) { switch (DataType(parmType)) {
case DataType::Int32: case DataType::Int32:
range[0].int32 = reader.readInt32(nullptr); range[0].int32 = reader.readInt32();
range[1].int32 = reader.readInt32(nullptr); range[1].int32 = reader.readInt32();
break; break;
case DataType::UInt32: case DataType::UInt32:
case DataType::Enum: case DataType::Enum:
range[0].uint32 = reader.readUint32(nullptr); range[0].uint32 = reader.readUint32();
range[1].uint32 = reader.readUint32(nullptr); range[1].uint32 = reader.readUint32();
break; break;
case DataType::Float: case DataType::Float:
range[0].float32 = reader.readFloat(nullptr); range[0].float32 = reader.readFloat();
range[1].float32 = reader.readFloat(nullptr); range[1].float32 = reader.readFloat();
break; break;
case DataType::Bool: case DataType::Bool:
range[0].bool1 = reader.readBool(nullptr); range[0].bool1 = reader.readBool();
range[1].bool1 = reader.readBool(nullptr); range[1].bool1 = reader.readBool();
break; break;
default: default:
break; break;
@ -118,28 +118,28 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumer
if (auto v = writer.enterSubVector("range")) { if (auto v = writer.enterSubVector("range")) {
switch (DataType(parmType)) { switch (DataType(parmType)) {
case DataType::Int32: case DataType::Int32:
writer.writeInt32(nullptr, range[0].int32); writer.writeInt32(range[0].int32);
writer.writeInt32(nullptr, range[1].int32); writer.writeInt32(range[1].int32);
break; break;
case DataType::UInt32: case DataType::UInt32:
case DataType::Enum: case DataType::Enum:
writer.writeUint32(nullptr, range[0].uint32); writer.writeUint32(range[0].uint32);
writer.writeUint32(nullptr, range[1].uint32); writer.writeUint32(range[1].uint32);
break; break;
case DataType::Float: case DataType::Float:
writer.writeFloat(nullptr, range[0].float32); writer.writeFloat(range[0].float32);
writer.writeFloat(nullptr, range[1].float32); writer.writeFloat(range[1].float32);
break; break;
case DataType::Bool: case DataType::Bool:
writer.writeBool(nullptr, range[0].bool1); writer.writeBool(range[0].bool1);
writer.writeBool(nullptr, range[1].bool1); writer.writeBool(range[1].bool1);
break; break;
} }
} }
} }
const char* ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::DNAType() { std::string_view ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::DNAType() {
return "urde::DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo"; return "urde::DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo"sv;
} }
template <> template <>
@ -257,17 +257,17 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate<BigDNA
for (const ParmInfo& pi : parmInfos) { for (const ParmInfo& pi : parmInfos) {
switch (ParmInfo::DataType(pi.parmType)) { switch (ParmInfo::DataType(pi.parmType)) {
case ParmInfo::DataType::Int32: case ParmInfo::DataType::Int32:
ai.parmVals.emplace_back(reader.readInt32(nullptr)); ai.parmVals.emplace_back(reader.readInt32());
break; break;
case ParmInfo::DataType::UInt32: case ParmInfo::DataType::UInt32:
case ParmInfo::DataType::Enum: case ParmInfo::DataType::Enum:
ai.parmVals.emplace_back(reader.readUint32(nullptr)); ai.parmVals.emplace_back(reader.readUint32());
break; break;
case ParmInfo::DataType::Float: case ParmInfo::DataType::Float:
ai.parmVals.emplace_back(reader.readFloat(nullptr)); ai.parmVals.emplace_back(reader.readFloat());
break; break;
case ParmInfo::DataType::Bool: case ParmInfo::DataType::Bool:
ai.parmVals.emplace_back(reader.readBool(nullptr)); ai.parmVals.emplace_back(reader.readBool());
break; break;
default: default:
break; break;
@ -294,17 +294,17 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate<BigDNA
pVal = *it++; pVal = *it++;
switch (ParmInfo::DataType(pi.parmType)) { switch (ParmInfo::DataType(pi.parmType)) {
case ParmInfo::DataType::Int32: case ParmInfo::DataType::Int32:
writer.writeInt32(nullptr, pVal.int32); writer.writeInt32(pVal.int32);
break; break;
case ParmInfo::DataType::UInt32: case ParmInfo::DataType::UInt32:
case ParmInfo::DataType::Enum: case ParmInfo::DataType::Enum:
writer.writeUint32(nullptr, pVal.uint32); writer.writeUint32(pVal.uint32);
break; break;
case ParmInfo::DataType::Float: case ParmInfo::DataType::Float:
writer.writeFloat(nullptr, pVal.float32); writer.writeFloat(pVal.float32);
break; break;
case ParmInfo::DataType::Bool: case ParmInfo::DataType::Bool:
writer.writeBool(nullptr, pVal.bool1); writer.writeBool(pVal.bool1);
break; break;
default: default:
break; break;
@ -314,8 +314,8 @@ void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate<BigDNA
}); });
} }
const char* ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::DNAType() { std::string_view ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::DNAType() {
return "urde::DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState"; return "urde::DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState"sv;
} }
template <> template <>
@ -605,7 +605,9 @@ void ANCS::CharacterSet::CharacterInfo::Enumerate<BigDNA::WriteYaml>(athena::io:
} }
} }
const char* ANCS::CharacterSet::CharacterInfo::DNAType() { return "urde::DNAMP1::ANCS::CharacterSet::CharacterInfo"; } std::string_view ANCS::CharacterSet::CharacterInfo::DNAType() {
return "urde::DNAMP1::ANCS::CharacterSet::CharacterInfo"sv;
}
template <> template <>
void ANCS::AnimationSet::MetaAnimFactory::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) { void ANCS::AnimationSet::MetaAnimFactory::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
@ -657,19 +659,19 @@ template <>
void ANCS::AnimationSet::MetaAnimFactory::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) { void ANCS::AnimationSet::MetaAnimFactory::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
std::string type = reader.readString("type"); std::string type = reader.readString("type");
std::transform(type.begin(), type.end(), type.begin(), tolower); std::transform(type.begin(), type.end(), type.begin(), tolower);
if (!type.compare("primitive")) { if (type == "primitive") {
m_anim.reset(new struct MetaAnimPrimitive); m_anim.reset(new struct MetaAnimPrimitive);
m_anim->read(reader); m_anim->read(reader);
} else if (!type.compare("blend")) { } else if (type == "blend") {
m_anim.reset(new struct MetaAnimBlend); m_anim.reset(new struct MetaAnimBlend);
m_anim->read(reader); m_anim->read(reader);
} else if (!type.compare("phaseblend")) { } else if (type == "phaseblend") {
m_anim.reset(new struct MetaAnimPhaseBlend); m_anim.reset(new struct MetaAnimPhaseBlend);
m_anim->read(reader); m_anim->read(reader);
} else if (!type.compare("random")) { } else if (type == "random") {
m_anim.reset(new struct MetaAnimRandom); m_anim.reset(new struct MetaAnimRandom);
m_anim->read(reader); m_anim->read(reader);
} else if (!type.compare("sequence")) { } else if (type == "sequence") {
m_anim.reset(new struct MetaAnimSequence); m_anim.reset(new struct MetaAnimSequence);
m_anim->read(reader); m_anim->read(reader);
} else { } else {
@ -685,8 +687,8 @@ void ANCS::AnimationSet::MetaAnimFactory::Enumerate<BigDNA::WriteYaml>(athena::i
m_anim->write(writer); m_anim->write(writer);
} }
const char* ANCS::AnimationSet::MetaAnimFactory::DNAType() { std::string_view ANCS::AnimationSet::MetaAnimFactory::DNAType() {
return "urde::DNAMP1::ANCS::AnimationSet::MetaAnimFactory"; return "urde::DNAMP1::ANCS::AnimationSet::MetaAnimFactory"sv;
} }
template <> template <>
@ -734,13 +736,13 @@ template <>
void ANCS::AnimationSet::MetaTransFactory::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) { void ANCS::AnimationSet::MetaTransFactory::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
std::string type = reader.readString("type"); std::string type = reader.readString("type");
std::transform(type.begin(), type.end(), type.begin(), tolower); std::transform(type.begin(), type.end(), type.begin(), tolower);
if (!type.compare("metaanim")) { if (type == "metaanim") {
m_trans.reset(new struct MetaTransMetaAnim); m_trans.reset(new struct MetaTransMetaAnim);
m_trans->read(reader); m_trans->read(reader);
} else if (!type.compare("trans")) { } else if (type == "trans") {
m_trans.reset(new struct MetaTransTrans); m_trans.reset(new struct MetaTransTrans);
m_trans->read(reader); m_trans->read(reader);
} else if (!type.compare("phasetrans")) { } else if (type == "phasetrans") {
m_trans.reset(new struct MetaTransPhaseTrans); m_trans.reset(new struct MetaTransPhaseTrans);
m_trans->read(reader); m_trans->read(reader);
} else { } else {
@ -758,8 +760,8 @@ void ANCS::AnimationSet::MetaTransFactory::Enumerate<BigDNA::WriteYaml>(athena::
m_trans->write(writer); m_trans->write(writer);
} }
const char* ANCS::AnimationSet::MetaTransFactory::DNAType() { std::string_view ANCS::AnimationSet::MetaTransFactory::DNAType() {
return "urde::DNAMP1::ANCS::AnimationSet::MetaTransFactory"; return "urde::DNAMP1::ANCS::AnimationSet::MetaTransFactory"sv;
} }
template <> template <>
@ -953,7 +955,7 @@ void ANCS::AnimationSet::MetaAnimPrimitive::gatherPrimitives(
out[animIdx] = {animName, animId, ANIM::GetEVNTId(rs), false}; out[animIdx] = {animName, animId, ANIM::GetEVNTId(rs), false};
} }
const char* ANCS::AnimationSet::DNAType() { return "urde::DNAMP1::ANCS::AnimationSet"; } std::string_view ANCS::AnimationSet::DNAType() { return "urde::DNAMP1::ANCS::AnimationSet"sv; }
bool ANCS::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, bool ANCS::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
@ -1011,13 +1013,13 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
ch.cmdlIce = UniqueID32Zero{}; ch.cmdlIce = UniqueID32Zero{};
ch.cskrIce = UniqueID32Zero{}; ch.cskrIce = UniqueID32Zero{};
hecl::SystemStringConv chSysName(ch.name);
ch.cskr = inPath.ensureAuxInfo(hecl::SystemString(chSysName.sys_str()) + _SYS_STR(".CSKR"));
int subtypeIdx = 0; int subtypeIdx = 0;
ch.animAABBs.clear(); ch.animAABBs.clear();
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) { for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) {
if (!sub.name.compare(ch.name)) { if (sub.name == ch.name) {
hecl::SystemStringConv chSysName(ch.name);
ch.cskr = inPath.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.CSKR")), chSysName, sub.cskrId));
/* Add subtype AABBs */ /* Add subtype AABBs */
ch.animAABBs.reserve(actor.actions.size()); ch.animAABBs.reserve(actor.actions.size());
for (const DNAANCS::Action& act : actor.actions) { for (const DNAANCS::Action& act : actor.actions) {
@ -1031,16 +1033,15 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
if (sub.armature >= 0) { if (sub.armature >= 0) {
const DNAANCS::Armature& arm = actor.armatures[sub.armature]; const DNAANCS::Armature& arm = actor.armatures[sub.armature];
hecl::SystemStringConv armSysName(arm.name); ch.cinf = arm.path;
ch.cinf = inPath.ensureAuxInfo(hecl::SystemString(armSysName.sys_str()) + _SYS_STR(".CINF"));
ch.cmdl = sub.mesh; ch.cmdl = sub.mesh;
auto search = std::find_if(sub.overlayMeshes.cbegin(), sub.overlayMeshes.cend(), auto search = std::find_if(sub.overlayMeshes.cbegin(), sub.overlayMeshes.cend(),
[](const auto& p) { return p.first == "ICE"; }); [](const auto& p) { return p.name == "ICE"; });
if (search != sub.overlayMeshes.cend()) { if (search != sub.overlayMeshes.cend()) {
hecl::SystemStringConv overlaySys(search->first); hecl::SystemStringConv overlaySys(search->name);
ch.cmdlIce = search->second; ch.cmdlIce = search->mesh;
ch.cskrIce = inPath.ensureAuxInfo(hecl::SystemString(chSysName.sys_str()) + _SYS_STR('.') + ch.cskrIce = inPath.ensureAuxInfo(
overlaySys.c_str() + _SYS_STR(".CSKR")); fmt::format(fmt(_SYS_STR("{}.{}_{}.CSKR")), chSysName, overlaySys, search->cskrId));
} }
} }
@ -1055,28 +1056,43 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
} }
/* Set Animation Resource IDs */ /* Set Animation Resource IDs */
ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) -> bool { ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) {
hecl::SystemStringConv sysStr(prim.animName); hecl::SystemStringConv sysStr(prim.animName);
hecl::ProjectPath pathOut = inPath.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".ANIM")); for (const DNAANCS::Action& act : actor.actions) {
prim.animId = pathOut; if (act.name == prim.animName) {
hecl::ProjectPath pathOut = inPath.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.ANIM")), sysStr, act.animId));
prim.animId = pathOut;
break;
}
}
return true; return true;
}); });
/* Gather ANIM resources */ /* Gather ANIM resources */
hecl::DirectoryEnumerator dEnum(inPath.getParentPath().getAbsolutePath());
ancs.animationSet.animResources.reserve(actor.actions.size()); ancs.animationSet.animResources.reserve(actor.actions.size());
for (const DNAANCS::Action& act : actor.actions) { for (const DNAANCS::Action& act : actor.actions) {
hecl::SystemStringConv sysStr(act.name); hecl::SystemStringConv sysStr(act.name);
hecl::ProjectPath pathOut = inPath.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".ANIM")); hecl::ProjectPath pathOut = inPath.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.ANIM")), sysStr, act.animId));
ancs.animationSet.animResources.emplace_back(); ancs.animationSet.animResources.emplace_back();
ancs.animationSet.animResources.back().animId = pathOut; ancs.animationSet.animResources.back().animId = pathOut;
/* Check for associated EVNT YAML */ /* Check for associated EVNT YAML */
hecl::ProjectPath evntYamlPath = inPath.getWithExtension( hecl::SystemString testPrefix(inPath.getWithExtension(
(hecl::SystemString(_SYS_STR(".")) + sysStr.c_str() + _SYS_STR(".evnt.yaml")).c_str(), true); fmt::format(fmt(_SYS_STR(".{}_")), sysStr).c_str(), true).getLastComponent());
evntYamlPath = evntYamlPath.ensureAuxInfo(_SYS_STR("")); hecl::ProjectPath evntYamlPath;
if (evntYamlPath.isFile()) for (const auto& ent : dEnum) {
if (hecl::StringUtils::BeginsWith(ent.m_name, testPrefix.c_str()) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".evnt.yaml"))) {
evntYamlPath = hecl::ProjectPath(inPath.getParentPath(), ent.m_name);
break;
}
}
if (evntYamlPath.isFile()) {
evntYamlPath = evntYamlPath.ensureAuxInfo(_SYS_STR(""));
ancs.animationSet.animResources.back().evntId = evntYamlPath; ancs.animationSet.animResources.back().evntId = evntYamlPath;
}
} }
/* Write out ANCS */ /* Write out ANCS */
@ -1086,28 +1102,20 @@ bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
return true; return true;
} }
bool ANCS::CookCINF(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor) { static const hecl::SystemRegex regCskrNameId(_SYS_STR(R"((.*)_[0-9a-fA-F]{8}\.CSKR)"),
hecl::SystemString armName(inPath.getAuxInfo().begin(), inPath.getAuxInfo().end() - 5); std::regex::ECMAScript | std::regex::optimize);
static const hecl::SystemRegex regCskrName(_SYS_STR(R"((.*)\.CSKR)"),
for (const DNAANCS::Armature& arm : actor.armatures) { std::regex::ECMAScript | std::regex::optimize);
hecl::SystemStringConv sysStr(arm.name);
if (sysStr.sys_str() == armName) {
std::unordered_map<std::string, atInt32> boneIdMap;
CINF cinf(arm, boneIdMap);
/* Write out CINF resource */
athena::io::TransactionalFileWriter w(outPath.getAbsolutePath());
cinf.write(w);
return true;
}
}
return false;
}
bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc) { const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc) {
hecl::SystemString subName(inPath.getAuxInfo().begin(), inPath.getAuxInfo().end() - 5); auto auxInfo = inPath.getAuxInfo();
hecl::SystemViewRegexMatch match;
if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrNameId) &&
!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrName))
return false;
hecl::SystemString subName = match[1].str();
hecl::SystemString overName; hecl::SystemString overName;
auto dotPos = subName.rfind(_SYS_STR('.')); auto dotPos = subName.rfind(_SYS_STR('.'));
if (dotPos != hecl::SystemString::npos) { if (dotPos != hecl::SystemString::npos) {
@ -1120,13 +1128,13 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
/* Build bone ID map */ /* Build bone ID map */
std::unordered_map<std::string, atInt32> boneIdMap; std::unordered_map<std::string, atInt32> boneIdMap;
for (const DNAANCS::Armature& arm : actor.armatures) { for (const DNAANCS::Armature& arm : actor.armatures) {
CINF cinf(arm, boneIdMap); CINF cinf(*arm.armature, boneIdMap);
} }
const DNAANCS::Actor::Subtype* subtype = nullptr; const DNAANCS::Actor::Subtype* subtype = nullptr;
if (subName != _SYS_STR("ATTACH")) { if (subName != _SYS_STR("ATTACH")) {
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) { for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) {
if (!sub.name.compare(subNameView.str())) { if (sub.name == subNameView.str()) {
subtype = &sub; subtype = &sub;
break; break;
} }
@ -1139,7 +1147,7 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
if (subName == _SYS_STR("ATTACH")) { if (subName == _SYS_STR("ATTACH")) {
const DNAANCS::Actor::Attachment* attachment = nullptr; const DNAANCS::Actor::Attachment* attachment = nullptr;
for (const DNAANCS::Actor::Attachment& att : actor.attachments) { for (const DNAANCS::Actor::Attachment& att : actor.attachments) {
if (!att.name.compare(overNameView.str())) { if (att.name == overNameView.str()) {
attachment = &att; attachment = &att;
break; break;
} }
@ -1151,8 +1159,8 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
modelPath = &subtype->mesh; modelPath = &subtype->mesh;
} else { } else {
for (const auto& overlay : subtype->overlayMeshes) for (const auto& overlay : subtype->overlayMeshes)
if (!overlay.first.compare(overNameView.str())) { if (overlay.name == overNameView.str()) {
modelPath = &overlay.second; modelPath = &overlay.mesh;
break; break;
} }
} }
@ -1225,7 +1233,13 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc) { const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc) {
hecl::SystemString subName(inPath.getAuxInfo().begin(), inPath.getAuxInfo().end() - 5); auto auxInfo = inPath.getAuxInfo();
hecl::SystemViewRegexMatch match;
if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrNameId) &&
!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrName))
return false;
hecl::SystemString subName = match[1].str();
hecl::SystemString overName; hecl::SystemString overName;
auto dotPos = subName.rfind(_SYS_STR('.')); auto dotPos = subName.rfind(_SYS_STR('.'));
if (dotPos != hecl::SystemString::npos) { if (dotPos != hecl::SystemString::npos) {
@ -1238,13 +1252,13 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath&
/* Build bone ID map */ /* Build bone ID map */
std::unordered_map<std::string, atInt32> boneIdMap; std::unordered_map<std::string, atInt32> boneIdMap;
for (const DNAANCS::Armature& arm : actor.armatures) { for (const DNAANCS::Armature& arm : actor.armatures) {
CINF cinf(arm, boneIdMap); CINF cinf(*arm.armature, boneIdMap);
} }
const DNAANCS::Actor::Subtype* subtype = nullptr; const DNAANCS::Actor::Subtype* subtype = nullptr;
if (subName != _SYS_STR("ATTACH")) { if (subName != _SYS_STR("ATTACH")) {
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) { for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) {
if (!sub.name.compare(subNameView.str())) { if (sub.name == subNameView.str()) {
subtype = &sub; subtype = &sub;
break; break;
} }
@ -1257,7 +1271,7 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath&
if (subName == _SYS_STR("ATTACH")) { if (subName == _SYS_STR("ATTACH")) {
const DNAANCS::Actor::Attachment* attachment = nullptr; const DNAANCS::Actor::Attachment* attachment = nullptr;
for (const DNAANCS::Actor::Attachment& att : actor.attachments) { for (const DNAANCS::Actor::Attachment& att : actor.attachments) {
if (!att.name.compare(overNameView.str())) { if (att.name == overNameView.str()) {
attachment = &att; attachment = &att;
break; break;
} }
@ -1269,8 +1283,8 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath&
modelPath = &subtype->mesh; modelPath = &subtype->mesh;
} else { } else {
for (const auto& overlay : subtype->overlayMeshes) for (const auto& overlay : subtype->overlayMeshes)
if (!overlay.first.compare(overNameView.str())) { if (overlay.name == overNameView.str()) {
modelPath = &overlay.second; modelPath = &overlay.mesh;
break; break;
} }
} }
@ -1365,9 +1379,20 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath&
return true; return true;
} }
static const hecl::SystemRegex regAnimNameId(_SYS_STR(R"((.*)_[0-9a-fA-F]{8}\.ANIM)"),
std::regex::ECMAScript | std::regex::optimize);
static const hecl::SystemRegex regAnimName(_SYS_STR(R"((.*)\.ANIM)"),
std::regex::ECMAScript | std::regex::optimize);
bool ANCS::CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, bool ANCS::CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
hecl::blender::DataStream& ds, bool pc) { hecl::blender::DataStream& ds, bool pc) {
hecl::SystemString actName(inPath.getAuxInfo().begin(), inPath.getAuxInfo().end() - 5); auto auxInfo = inPath.getAuxInfo();
hecl::SystemViewRegexMatch match;
if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regAnimNameId) &&
!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regAnimName))
return false;
hecl::SystemString actName = match[1].str();
hecl::SystemUTF8Conv actNameView(actName); hecl::SystemUTF8Conv actNameView(actName);
DNAANCS::Action action = ds.compileActionChannelsOnly(actNameView.str()); DNAANCS::Action action = ds.compileActionChannelsOnly(actNameView.str());
@ -1380,22 +1405,31 @@ bool ANCS::CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& i
std::optional<DNAANIM::RigInverter<CINF>> rigInv; std::optional<DNAANIM::RigInverter<CINF>> rigInv;
for (const DNAANCS::Armature& arm : actor.armatures) { for (const DNAANCS::Armature& arm : actor.armatures) {
if (!rigInv) { if (!rigInv) {
rigCinf.emplace(arm, boneIdMap); rigCinf.emplace(*arm.armature, boneIdMap);
auto matrices = ds.getBoneMatrices(arm.name); auto matrices = ds.getBoneMatrices(arm.name);
rigInv.emplace(*rigCinf, matrices); rigInv.emplace(*rigCinf, matrices);
} else { } else {
CINF cinf(arm, boneIdMap); CINF cinf(*arm.armature, boneIdMap);
} }
} }
ANIM anim(action, boneIdMap, *rigInv, pc); ANIM anim(action, boneIdMap, *rigInv, pc);
/* Check for associated EVNT YAML */ /* Check for associated EVNT YAML */
hecl::ProjectPath evntYamlPath = hecl::SystemString testPrefix(inPath.getWithExtension(
inPath.getWithExtension((hecl::SystemString(_SYS_STR(".")) + actName + _SYS_STR(".evnt.yaml")).c_str(), true); fmt::format(fmt(_SYS_STR(".{}_")), actName).c_str(), true).getLastComponent());
evntYamlPath = evntYamlPath.ensureAuxInfo(_SYS_STR("")); hecl::ProjectPath evntYamlPath;
if (evntYamlPath.isFile()) for (const auto& ent : hecl::DirectoryEnumerator(inPath.getParentPath().getAbsolutePath())) {
if (hecl::StringUtils::BeginsWith(ent.m_name, testPrefix.c_str()) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".evnt.yaml"))) {
evntYamlPath = hecl::ProjectPath(inPath.getParentPath(), ent.m_name);
break;
}
}
if (evntYamlPath.isFile()) {
evntYamlPath = evntYamlPath.ensureAuxInfo(_SYS_STR(""));
anim.m_anim->evnt = evntYamlPath; anim.m_anim->evnt = evntYamlPath;
}
/* Write out ANIM resource */ /* Write out ANIM resource */
athena::io::TransactionalFileWriter w(outPath.getAbsolutePath()); athena::io::TransactionalFileWriter w(outPath.getAbsolutePath());

View File

@ -408,8 +408,6 @@ struct ANCS : BigDNA {
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor); static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor);
static bool CookCINF(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor);
static bool CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, static bool CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc); const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc);
static bool CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, static bool CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor,

View File

@ -151,7 +151,7 @@ void ANIM::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
m_anim->binarySize(s); m_anim->binarySize(s);
} }
const char* ANIM::ANIM0::DNAType() { return "ANIM0"; } std::string_view ANIM::ANIM0::DNAType() { return "ANIM0"sv; }
template <> template <>
void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) { void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
@ -309,7 +309,7 @@ void ANIM::ANIM0::Enumerate<BigDNA::BinarySize>(size_t& __isz) {
__isz += 4; __isz += 4;
} }
const char* ANIM::ANIM2::DNAType() { return "ANIM2"; } std::string_view ANIM::ANIM2::DNAType() { return "ANIM2"sv; }
template <> template <>
void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) { void ANIM::ANIM2::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {

View File

@ -192,7 +192,7 @@ struct ANIM : BigDNA {
if (m_anim->evnt.isValid()) { if (m_anim->evnt.isValid()) {
hecl::SystemStringConv sysStr(animInfo.name); hecl::SystemStringConv sysStr(animInfo.name);
hecl::ProjectPath evntYamlPath = outPath.getWithExtension( hecl::ProjectPath evntYamlPath = outPath.getWithExtension(
(hecl::SystemString(_SYS_STR(".")) + sysStr.c_str() + _SYS_STR(".evnt.yaml")).c_str(), true); fmt::format(fmt(_SYS_STR(".{}_{}.evnt.yaml")), sysStr, m_anim->evnt).c_str(), true);
hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType(); hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType();
if (force || evntYamlType == hecl::ProjectPath::Type::None) { if (force || evntYamlType == hecl::ProjectPath::Type::None) {

View File

@ -156,4 +156,44 @@ CINF::CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& i
boneIds.push_back(it->id); boneIds.push_back(it->id);
} }
bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) {
if (!force && outPath.isFile())
return true;
auto& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::blender::BlendType::Armature))
return false;
auto os = conn.beginPythonOut(true);
os.format(fmt("import bpy\n"
"from mathutils import Vector\n"
"bpy.context.scene.name = 'CINF_{}'\n"
"bpy.context.scene.hecl_arm_obj = bpy.context.scene.name\n"
"\n"
"# Clear Scene\n"
"if len(bpy.data.collections):\n"
" bpy.data.collections.remove(bpy.data.collections[0])\n"
"\n"), entry.id);
CINF cinf;
cinf.read(rs);
cinf.sendCINFToBlender(os, entry.id);
os.centerView();
os.close();
return conn.saveBlend();
}
bool CINF::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
const hecl::blender::Armature& armature) {
std::unordered_map<std::string, atInt32> boneIdMap;
CINF cinf(armature, boneIdMap);
/* Write out CINF resource */
athena::io::TransactionalFileWriter w(outPath.getAbsolutePath());
cinf.write(w);
return true;
}
} // namespace DataSpec::DNAMP1 } // namespace DataSpec::DNAMP1

View File

@ -2,6 +2,7 @@
#include "DataSpec/DNACommon/DNACommon.hpp" #include "DataSpec/DNACommon/DNACommon.hpp"
#include "DataSpec/DNACommon/RigInverter.hpp" #include "DataSpec/DNACommon/RigInverter.hpp"
#include "DNAMP1.hpp"
namespace DataSpec::DNAMP1 { namespace DataSpec::DNAMP1 {
@ -44,6 +45,13 @@ struct CINF : BigDNA {
std::unordered_map<std::string, atInt32>& idMap, std::map<std::string, int>& nameMap); std::unordered_map<std::string, atInt32>& idMap, std::map<std::string, int>& nameMap);
CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& idMap); CINF(const Armature& armature, std::unordered_map<std::string, atInt32>& idMap);
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
const hecl::blender::Armature& armature);
}; };
} // namespace DataSpec::DNAMP1 } // namespace DataSpec::DNAMP1

View File

@ -7,40 +7,40 @@ bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) { std::function<void(const hecl::SystemChar*)> fileChanged) {
/* Check for RigPair */ /* Check for RigPair */
const typename CharacterAssociations<UniqueID32>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
CINF cinf; CINF cinf;
CSKR cskr; CSKR cskr;
std::pair<CSKR*, CINF*> loadRp(nullptr, nullptr); using RigPair = std::pair<std::pair<UniqueID32, CSKR*>, std::pair<UniqueID32, CINF*>>;
if (rp) { RigPair loadRp = {};
pakRouter.lookupAndReadDNA(rp->first, cskr); if (const typename CharacterAssociations<UniqueID32>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id)) {
pakRouter.lookupAndReadDNA(rp->second, cinf); pakRouter.lookupAndReadDNA(rp->cskr, cskr);
loadRp.first = &cskr; pakRouter.lookupAndReadDNA(rp->cinf, cinf);
loadRp.second = &cinf; loadRp.first = {rp->cskr, &cskr};
loadRp.second = {rp->cinf, &cinf};
} }
/* Do extract */ /* Do extract */
hecl::blender::Connection& conn = btok.getBlenderConnection(); hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*, CINF*>, DNACMDL::SurfaceHeader_1, 2>( DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, RigPair, DNACMDL::SurfaceHeader_1, 2>(
conn, rs, pakRouter, entry, dataSpec, loadRp); conn, rs, pakRouter, entry, dataSpec, loadRp);
conn.saveBlend(); conn.saveBlend();
#if 0 #if 0
/* Cook and re-extract test */ /* Cook and re-extract test */
hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true); hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true);
hecl::blender::Connection::DataStream ds = conn.beginData(); hecl::blender::Connection::DataStream ds = conn.beginData();
DNACMDL::Mesh mesh = ds.compileMesh(hecl::TopologyTriStrips, -1); DNACMDL::Mesh mesh = ds.compileMesh(hecl::TopologyTriStrips, -1);
ds.close(); ds.close();
DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1_2, 2>(tempOut, outPath, mesh); DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1_2, 2>(tempOut, outPath, mesh);
athena::io::FileReader reader(tempOut.getAbsolutePath()); athena::io::FileReader reader(tempOut.getAbsolutePath());
hecl::ProjectPath tempBlend = outPath.getWithExtension(_SYS_STR(".recook.blend"), true); hecl::ProjectPath tempBlend = outPath.getWithExtension(_SYS_STR(".recook.blend"), true);
if (!conn.createBlend(tempBlend, hecl::blender::Connection::TypeMesh)) if (!conn.createBlend(tempBlend, hecl::blender::Connection::TypeMesh))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_1_2, 2> DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_1_2, 2>
(conn, reader, pakRouter, entry, dataSpec, loadRp); (conn, reader, pakRouter, entry, dataSpec, loadRp);
return conn.saveBlend(); return conn.saveBlend();
#elif 0 #elif 0
/* HMDL cook test */ /* HMDL cook test */
hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true); hecl::ProjectPath tempOut = outPath.getWithExtension(_SYS_STR(".recook"), true);

View File

@ -438,7 +438,8 @@ static void _GenerateRootShader(Stream& out, const char* type, Targs... args) {
out << "node = new_nodetree.nodes.new('ShaderNodeGroup')\n" out << "node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
"node.name = 'Output'\n" "node.name = 'Output'\n"
"node.node_tree = bpy.data.node_groups['" << type << "']\n" "node.node_tree = bpy.data.node_groups['" << type << "']\n"
"gridder.place_node(node, 1)\n"; "gridder.place_node(node, 1)\n"
"new_nodetree.links.new(node.outputs['Surface'], blend_node.inputs['Surface'])\n";
_GenerateRootShader(out, 0, args...); _GenerateRootShader(out, 0, args...);
} }
@ -455,6 +456,7 @@ static void _ConstructMaterial(Stream& out, const MAT& material, unsigned groupI
out << "new_material.use_fake_user = True\n" out << "new_material.use_fake_user = True\n"
"new_material.use_nodes = True\n" "new_material.use_nodes = True\n"
"new_material.use_backface_culling = True\n" "new_material.use_backface_culling = True\n"
"new_material.blend_method = 'BLEND'\n"
"new_nodetree = new_material.node_tree\n" "new_nodetree = new_material.node_tree\n"
"for n in new_nodetree.nodes:\n" "for n in new_nodetree.nodes:\n"
" new_nodetree.nodes.remove(n)\n" " new_nodetree.nodes.remove(n)\n"
@ -498,12 +500,18 @@ static void _ConstructMaterial(Stream& out, const MAT& material, unsigned groupI
} }
/* Blend factors */ /* Blend factors */
out << "blend_node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
"blend_node.name = 'Blend'\n"
"gridder.place_node(blend_node, 2)\n";
using BlendFactor = Material::BlendFactor; using BlendFactor = Material::BlendFactor;
if (material.blendDstFac != BlendFactor::BL_ZERO) { if (material.blendDstFac != BlendFactor::BL_ZERO) {
if (material.blendDstFac == BlendFactor::BL_ONE) if (material.blendDstFac == BlendFactor::BL_ONE)
out << "new_material.blend_method = 'ADD'\n"; out << "blend_node.node_tree = bpy.data.node_groups['HECLAdditiveOutput']\n";
else else
out << "new_material.blend_method = 'BLEND'\n"; out << "blend_node.node_tree = bpy.data.node_groups['HECLBlendOutput']\n";
} else {
out << "blend_node.node_tree = bpy.data.node_groups['HECLOpaqueOutput']\n"
"new_material.blend_method = 'OPAQUE'\n";
} }
/* Add texture maps/tcgs */ /* Add texture maps/tcgs */
@ -994,11 +1002,11 @@ HMDLMaterialSet::Material::Material(const hecl::blender::Material& mat) {
} }
MaterialSet::Material::UVAnimation::UVAnimation(const std::string& gameFunction, const std::vector<atVec4f>& gameArgs) { MaterialSet::Material::UVAnimation::UVAnimation(const std::string& gameFunction, const std::vector<atVec4f>& gameArgs) {
if (!gameFunction.compare("RetroUVMode0NodeN")) if (gameFunction == "RetroUVMode0NodeN")
mode = Mode::MvInvNoTranslation; mode = Mode::MvInvNoTranslation;
else if (!gameFunction.compare("RetroUVMode1NodeN")) else if (gameFunction == "RetroUVMode1NodeN")
mode = Mode::MvInv; mode = Mode::MvInv;
else if (!gameFunction.compare("RetroUVMode2Node")) { else if (gameFunction == "RetroUVMode2Node") {
mode = Mode::Scroll; mode = Mode::Scroll;
if (gameArgs.size() < 2) if (gameArgs.size() < 2)
Log.report(logvisor::Fatal, fmt("Mode2 UV anim requires 2 vector arguments")); Log.report(logvisor::Fatal, fmt("Mode2 UV anim requires 2 vector arguments"));
@ -1006,13 +1014,13 @@ MaterialSet::Material::UVAnimation::UVAnimation(const std::string& gameFunction,
vals[1] = gameArgs[0].simd[1]; vals[1] = gameArgs[0].simd[1];
vals[2] = gameArgs[1].simd[0]; vals[2] = gameArgs[1].simd[0];
vals[3] = gameArgs[1].simd[1]; vals[3] = gameArgs[1].simd[1];
} else if (!gameFunction.compare("RetroUVMode3Node")) { } else if (gameFunction == "RetroUVMode3Node") {
mode = Mode::Rotation; mode = Mode::Rotation;
if (gameArgs.size() < 2) if (gameArgs.size() < 2)
Log.report(logvisor::Fatal, fmt("Mode3 UV anim requires 2 arguments")); Log.report(logvisor::Fatal, fmt("Mode3 UV anim requires 2 arguments"));
vals[0] = gameArgs[0].simd[0]; vals[0] = gameArgs[0].simd[0];
vals[1] = gameArgs[1].simd[0]; vals[1] = gameArgs[1].simd[0];
} else if (!gameFunction.compare("RetroUVMode4Node")) { } else if (gameFunction == "RetroUVMode4Node") {
mode = Mode::HStrip; mode = Mode::HStrip;
if (gameArgs.size() < 4) if (gameArgs.size() < 4)
Log.report(logvisor::Fatal, fmt("Mode4 UV anim requires 4 arguments")); Log.report(logvisor::Fatal, fmt("Mode4 UV anim requires 4 arguments"));
@ -1020,7 +1028,7 @@ MaterialSet::Material::UVAnimation::UVAnimation(const std::string& gameFunction,
vals[1] = gameArgs[1].simd[0]; vals[1] = gameArgs[1].simd[0];
vals[2] = gameArgs[2].simd[0]; vals[2] = gameArgs[2].simd[0];
vals[3] = gameArgs[3].simd[0]; vals[3] = gameArgs[3].simd[0];
} else if (!gameFunction.compare("RetroUVMode5Node")) { } else if (gameFunction == "RetroUVMode5Node") {
mode = Mode::VStrip; mode = Mode::VStrip;
if (gameArgs.size() < 4) if (gameArgs.size() < 4)
Log.report(logvisor::Fatal, fmt("Mode5 UV anim requires 4 arguments")); Log.report(logvisor::Fatal, fmt("Mode5 UV anim requires 4 arguments"));
@ -1028,9 +1036,9 @@ MaterialSet::Material::UVAnimation::UVAnimation(const std::string& gameFunction,
vals[1] = gameArgs[1].simd[0]; vals[1] = gameArgs[1].simd[0];
vals[2] = gameArgs[2].simd[0]; vals[2] = gameArgs[2].simd[0];
vals[3] = gameArgs[3].simd[0]; vals[3] = gameArgs[3].simd[0];
} else if (!gameFunction.compare("RetroUVMode6NodeN")) } else if (gameFunction == "RetroUVMode6NodeN")
mode = Mode::Model; mode = Mode::Model;
else if (!gameFunction.compare("RetroUVMode7NodeN")) { else if (gameFunction == "RetroUVMode7NodeN") {
mode = Mode::CylinderEnvironment; mode = Mode::CylinderEnvironment;
if (gameArgs.size() < 2) if (gameArgs.size() < 2)
Log.report(logvisor::Fatal, fmt("Mode7 UV anim requires 2 arguments")); Log.report(logvisor::Fatal, fmt("Mode7 UV anim requires 2 arguments"));
@ -1083,8 +1091,8 @@ void HMDLMaterialSet::Material::PASS::Enumerate(typename Op::StreamT& s) {
AT_SPECIALIZE_DNA(HMDLMaterialSet::Material::PASS) AT_SPECIALIZE_DNA(HMDLMaterialSet::Material::PASS)
const char* HMDLMaterialSet::Material::PASS::DNAType() { std::string_view HMDLMaterialSet::Material::PASS::DNAType() {
return "DataSpec::DNAMP1::HMDLMaterialSet::Material::PASS"; return "DataSpec::DNAMP1::HMDLMaterialSet::Material::PASS"sv;
} }
} // namespace DataSpec::DNAMP1 } // namespace DataSpec::DNAMP1

View File

@ -44,7 +44,7 @@ bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
r.emplace(songsPath.getAbsolutePath()); r.emplace(songsPath.getAbsolutePath());
athena::io::YAMLDocWriter ydw("amuse::Songs", r ? &*r : nullptr); athena::io::YAMLDocWriter ydw("amuse::Songs", r ? &*r : nullptr);
r = std::nullopt; r = std::nullopt;
ydw.writeString(fmt::format(fmt("{:04X}"), head.midiSetupId).c_str(), ydw.writeString(fmt::format(fmt("{:04X}"), head.midiSetupId),
fmt::format(fmt("../MidiData/{}"), midPath.getLastComponentUTF8())); fmt::format(fmt("../MidiData/{}"), midPath.getLastComponentUTF8()));
athena::io::FileWriter w(songsPath.getAbsolutePath()); athena::io::FileWriter w(songsPath.getAbsolutePath());
ydw.finish(&w); ydw.finish(&w);

View File

@ -64,9 +64,9 @@ PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
m_pak.read(rs); m_pak.read(rs);
/* Append Level String */ /* Append Level String */
for (auto& ent : m_pak.m_entries) { for (auto& [id, entry] : m_pak.m_entries) {
PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL')) { if (entry.type == FOURCC('MLVL')) {
m_levelId = entry.id;
PAKEntryReadStream rs = entry.beginReadStream(m_node); PAKEntryReadStream rs = entry.beginReadStream(m_node);
MLVL mlvl; MLVL mlvl;
mlvl.read(rs); mlvl.read(rs);
@ -94,8 +94,7 @@ static hecl::SystemString LayerName(std::string_view name) {
void PAKBridge::build() { void PAKBridge::build() {
/* First pass: build per-area/per-layer dependency map */ /* First pass: build per-area/per-layer dependency map */
for (const auto& ent : m_pak.m_entries) { for (const auto& [id, entry] : m_pak.m_entries) {
const PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL')) { if (entry.type == FOURCC('MLVL')) {
Level& level = m_levelDeps[entry.id]; Level& level = m_levelDeps[entry.id];
@ -104,8 +103,8 @@ void PAKBridge::build() {
PAKEntryReadStream rs = entry.beginReadStream(m_node); PAKEntryReadStream rs = entry.beginReadStream(m_node);
mlvl.read(rs); mlvl.read(rs);
} }
bool named; std::string catalogueName;
std::string bestName = m_pak.bestEntryName(m_node, entry, named); std::string bestName = m_pak.bestEntryName(m_node, entry, catalogueName);
level.name = hecl::SystemStringConv(bestName).sys_str(); level.name = hecl::SystemStringConv(bestName).sys_str();
level.areas.reserve(mlvl.areaCount); level.areas.reserve(mlvl.areaCount);
unsigned layerIdx = 0; unsigned layerIdx = 0;
@ -121,15 +120,20 @@ void PAKBridge::build() {
mapw.reserve(areaCount); mapw.reserve(areaCount);
for (atUint32 i = 0; i < areaCount; ++i) for (atUint32 i = 0; i < areaCount; ++i)
mapw.emplace_back(rs); mapw.emplace_back(rs);
level.resources.insert(mlvl.worldMap);
} }
PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId); PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId);
if (savwEnt) if (savwEnt) {
savwEnt->name = entry.name + "_savw"; savwEnt->name = entry.name + "_savw";
level.resources.insert(mlvl.saveWorldId);
}
PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId); PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId);
if (skyEnt) if (skyEnt) {
skyEnt->name = entry.name + "_skybox"; skyEnt->name = entry.name + "_skybox";
level.resources.insert(mlvl.worldSkyboxId);
}
/* Index areas */ /* Index areas */
unsigned ai = 0; unsigned ai = 0;
@ -193,55 +197,52 @@ void PAKBridge::build() {
} }
/* Second pass: cross-compare uniqueness */ /* Second pass: cross-compare uniqueness */
for (auto& entry : m_pak.m_entries) { for (auto& [id, entry] : m_pak.m_entries)
entry.second.unique.checkEntry(*this, entry.second); entry.unique.checkEntry(*this, entry);
}
} }
void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const { void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) { for (const auto& [id, entry] : m_pak.m_entries) {
if (entry.second.type == FOURCC('ANCS')) { if (entry.type == FOURCC('ANCS')) {
PAKEntryReadStream rs = entry.second.beginReadStream(m_node); PAKEntryReadStream rs = entry.beginReadStream(m_node);
ANCS ancs; ANCS ancs;
ancs.read(rs); ancs.read(rs);
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) { for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) {
charAssoc.m_cmdlRigs[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf); charAssoc.m_cmdlRigs[ci.cmdl] = {ci.cskr, ci.cinf};
charAssoc.m_cskrCinfToCharacter[ci.cskr] = charAssoc.m_cskrToCharacter[ci.cskr] =
std::make_pair(entry.second.id, fmt::format(fmt("{}.CSKR"), ci.name)); std::make_pair(entry.id, fmt::format(fmt("{}_{}.CSKR"), ci.name, ci.cskr));
charAssoc.m_cskrCinfToCharacter[ci.cinf] =
std::make_pair(entry.second.id, fmt::format(fmt("CINF_{}.CINF"), ci.cinf));
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl); PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl);
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr); PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr);
PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf); PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf);
cmdlEnt->name = fmt::format(fmt("ANCS_{}_{}_model"), entry.first, ci.name); cmdlEnt->name = fmt::format(fmt("ANCS_{}_{}_model"), id, ci.name);
cskrEnt->name = fmt::format(fmt("ANCS_{}_{}_skin"), entry.first, ci.name); cskrEnt->name = fmt::format(fmt("ANCS_{}_{}_skin"), id, ci.name);
cinfEnt->name = fmt::format(fmt("ANCS_{}_{}_skel"), entry.first, ci.name); cinfEnt->name = fmt::format(fmt("ANCS_{}_{}_skel"), id, ci.name);
if (ci.cmdlIce.isValid() && ci.cskrIce.isValid()) { if (ci.cmdlIce.isValid() && ci.cskrIce.isValid()) {
charAssoc.m_cmdlRigs[ci.cmdlIce] = std::make_pair(ci.cskrIce, ci.cinf); charAssoc.m_cmdlRigs[ci.cmdlIce] = {ci.cskrIce, ci.cinf};
charAssoc.m_cskrCinfToCharacter[ci.cskrIce] = charAssoc.m_cskrToCharacter[ci.cskrIce] =
std::make_pair(entry.second.id, fmt::format(fmt("{}.ICE.CSKR"), ci.name)); std::make_pair(entry.id, fmt::format(fmt("{}.ICE_{}.CSKR"), ci.name, ci.cskrIce));
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlIce); PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlIce);
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrIce); PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrIce);
cmdlEnt->name = fmt::format(fmt("ANCS_{}_{}_icemodel"), entry.first, ci.name); cmdlEnt->name = fmt::format(fmt("ANCS_{}_{}_icemodel"), id, ci.name);
cskrEnt->name = fmt::format(fmt("ANCS_{}_{}_iceskin"), entry.first, ci.name); cskrEnt->name = fmt::format(fmt("ANCS_{}_{}_iceskin"), id, ci.name);
} }
} }
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animInfo; std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animInfo;
ancs.getAnimationResInfo(&pakRouter, animInfo); ancs.getAnimationResInfo(&pakRouter, animInfo);
for (auto& ae : animInfo) { for (auto& [animIdx, animResInfo] : animInfo) {
PAK::Entry* animEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.animId); PAK::Entry* animEnt = (PAK::Entry*)m_pak.lookupEntry(animResInfo.animId);
animEnt->name = fmt::format(fmt("ANCS_{}_{}"), entry.first, ae.second.name); animEnt->name = fmt::format(fmt("ANCS_{}_{}"), id, animResInfo.name);
charAssoc.m_cskrCinfToCharacter[ae.second.animId] = charAssoc.m_cskrToCharacter[animResInfo.animId] =
std::make_pair(entry.second.id, fmt::format(fmt("{}.ANIM"), ae.second.name)); std::make_pair(entry.id, fmt::format(fmt("{}_{}.ANIM"), animResInfo.name, animResInfo.animId));
if (ae.second.evntId.isValid()) { if (animResInfo.evntId.isValid()) {
PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.evntId); PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(animResInfo.evntId);
evntEnt->name = fmt::format(fmt("ANCS_{}_{}_evnt"), entry.first, ae.second.name); evntEnt->name = fmt::format(fmt("ANCS_{}_{}_evnt"), id, animResInfo.name);
charAssoc.m_cskrCinfToCharacter[ae.second.evntId] = charAssoc.m_cskrToCharacter[animResInfo.evntId] =
std::make_pair(entry.second.id, fmt::format(fmt("{}.evnt.yaml"), ae.second.name)); std::make_pair(entry.id, fmt::format(fmt("{}_{}.evnt.yaml"), animResInfo.name, animResInfo.evntId));
} }
} }
} else if (entry.second.type == FOURCC('MREA')) { } else if (entry.type == FOURCC('MREA')) {
PAKEntryReadStream rs = entry.second.beginReadStream(m_node); PAKEntryReadStream rs = entry.beginReadStream(m_node);
MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc); MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc);
} }
} }
@ -249,12 +250,12 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssoci
void PAKBridge::addPATHToMREA(PAKRouter<PAKBridge>& pakRouter, void PAKBridge::addPATHToMREA(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const { std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const {
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) { for (const auto& [id, entry] : m_pak.m_entries) {
if (entry.second.type == FOURCC('MREA')) { if (entry.type == FOURCC('MREA')) {
PAKEntryReadStream rs = entry.second.beginReadStream(m_node); PAKEntryReadStream rs = entry.beginReadStream(m_node);
UniqueID32 pathID = MREA::GetPATHId(rs); UniqueID32 pathID = MREA::GetPATHId(rs);
if (pathID.isValid()) if (pathID.isValid())
pathToMrea[pathID] = entry.first; pathToMrea[pathID] = id;
} }
} }
} }
@ -264,17 +265,18 @@ static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}};
void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter, void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo, std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const { std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const {
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) { for (const auto& [id, entry] : m_pak.m_entries) {
if (entry.second.type == FOURCC('MLVL')) { if (entry.type == FOURCC('MLVL')) {
MLVL mlvl; MLVL mlvl;
{ {
PAKEntryReadStream rs = entry.second.beginReadStream(m_node); PAKEntryReadStream rs = entry.beginReadStream(m_node);
mlvl.read(rs); mlvl.read(rs);
} }
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath(); hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry).getParentPath();
if (mlvl.worldNameId.isValid()) if (mlvl.worldNameId.isValid())
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _SYS_STR("!name.yaml")); pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath,
fmt::format(fmt(_SYS_STR("!name_{}.yaml")), mlvl.worldNameId));
for (const MLVL::Area& area : mlvl.areas) { for (const MLVL::Area& area : mlvl.areas) {
{ {
@ -290,7 +292,8 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
if (area.areaNameId.isValid()) if (area.areaNameId.isValid())
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _SYS_STR("!name.yaml")); pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath,
fmt::format(fmt(_SYS_STR("!name_{}.yaml")), area.areaNameId));
} }
if (mlvl.worldMap.isValid()) { if (mlvl.worldMap.isValid()) {
@ -331,6 +334,8 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
return {AFSM::Extract, {_SYS_STR(".yaml")}}; return {AFSM::Extract, {_SYS_STR(".yaml")}};
case SBIG('FRME'): case SBIG('FRME'):
return {FRME::Extract, {_SYS_STR(".blend")}, 2}; return {FRME::Extract, {_SYS_STR(".blend")}, 2};
case SBIG('CINF'):
return {CINF::Extract, {_SYS_STR(".blend")}, 1};
case SBIG('CMDL'): case SBIG('CMDL'):
return {CMDL::Extract, {_SYS_STR(".blend")}, 1, CMDL::Name}; return {CMDL::Extract, {_SYS_STR(".blend")}, 1, CMDL::Name};
case SBIG('DCLN'): case SBIG('DCLN'):
@ -339,10 +344,14 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
return {ANCS::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 2}; return {ANCS::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 2};
case SBIG('MLVL'): case SBIG('MLVL'):
return {MLVL::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 3}; return {MLVL::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 3};
case SBIG('SAVW'):
return {MLVL::ExtractSAVW, {_SYS_STR(".yaml")}, 3};
case SBIG('MREA'): case SBIG('MREA'):
return {MREA::Extract, {_SYS_STR(".blend")}, 4, MREA::Name}; return {MREA::Extract, {_SYS_STR(".blend")}, 4, MREA::Name};
case SBIG('MAPA'): case SBIG('MAPA'):
return {MAPA::Extract, {_SYS_STR(".blend")}, 4}; return {MAPA::Extract, {_SYS_STR(".blend")}, 4};
case SBIG('MAPW'):
return {MLVL::ExtractMAPW, {_SYS_STR(".yaml")}, 4};
case SBIG('MAPU'): case SBIG('MAPU'):
return {MAPU::Extract, {_SYS_STR(".blend")}, 5}; return {MAPU::Extract, {_SYS_STR(".blend")}, 5};
case SBIG('PATH'): case SBIG('PATH'):
@ -371,40 +380,40 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
return {DNAAudio::ATBL::Extract, {_SYS_STR(".yaml")}}; return {DNAAudio::ATBL::Extract, {_SYS_STR(".yaml")}};
case SBIG('CTWK'): case SBIG('CTWK'):
case SBIG('DUMB'): { case SBIG('DUMB'): {
bool named; std::string catalogueName;
std::string name = pak.bestEntryName(pakNode, entry, named); std::string name = pak.bestEntryName(pakNode, entry, catalogueName);
if (named) { if (!catalogueName.empty()) {
if (!name.compare("PlayerRes")) if (catalogueName == "PlayerRes"sv)
return {ExtractTweak<CTweakPlayerRes>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakPlayerRes>, {_SYS_STR(".yaml")}};
if (!name.compare("GunRes")) if (catalogueName == "GunRes"sv)
return {ExtractTweak<CTweakGunRes>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakGunRes>, {_SYS_STR(".yaml")}};
if (!name.compare("Player")) if (catalogueName == "Player"sv)
return {ExtractTweak<CTweakPlayer>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakPlayer>, {_SYS_STR(".yaml")}};
if (!name.compare("CameraBob")) if (catalogueName == "CameraBob"sv)
return {ExtractTweak<CTweakCameraBob>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakCameraBob>, {_SYS_STR(".yaml")}};
if (!name.compare("SlideShow")) if (catalogueName == "SlideShow"sv)
return {ExtractTweak<CTweakSlideShow>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakSlideShow>, {_SYS_STR(".yaml")}};
if (!name.compare("Game")) if (catalogueName == "Game"sv)
return {ExtractTweak<CTweakGame>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakGame>, {_SYS_STR(".yaml")}};
if (!name.compare("Targeting")) if (catalogueName == "Targeting"sv)
return {ExtractTweak<CTweakTargeting>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakTargeting>, {_SYS_STR(".yaml")}};
if (!name.compare("Gui")) if (catalogueName == "Gui"sv)
return {ExtractTweak<CTweakGui>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakGui>, {_SYS_STR(".yaml")}};
if (!name.compare("AutoMapper")) if (catalogueName == "AutoMapper"sv)
return {ExtractTweak<CTweakAutoMapper>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakAutoMapper>, {_SYS_STR(".yaml")}};
if (!name.compare("PlayerControls") || !name.compare("PlayerControls2")) if (catalogueName == "PlayerControls"sv || catalogueName == "PlayerControls2"sv)
return {ExtractTweak<CTweakPlayerControl>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakPlayerControl>, {_SYS_STR(".yaml")}};
if (!name.compare("Ball")) if (catalogueName == "Ball"sv)
return {ExtractTweak<CTweakBall>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakBall>, {_SYS_STR(".yaml")}};
if (!name.compare("Particle")) if (catalogueName == "Particle"sv)
return {ExtractTweak<CTweakParticle>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakParticle>, {_SYS_STR(".yaml")}};
if (!name.compare("GuiColors")) if (catalogueName == "GuiColors"sv)
return {ExtractTweak<CTweakGuiColors>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakGuiColors>, {_SYS_STR(".yaml")}};
if (!name.compare("PlayerGun")) if (catalogueName == "PlayerGun"sv)
return {ExtractTweak<CTweakPlayerGun>, {_SYS_STR(".yaml")}}; return {ExtractTweak<CTweakPlayerGun>, {_SYS_STR(".yaml")}};
if (!name.compare("DUMB_MazeSeeds")) if (catalogueName == "DUMB_MazeSeeds"sv)
return {ExtractTweak<MazeSeeds>, {_SYS_STR(".yaml")}}; return {ExtractTweak<MazeSeeds>, {_SYS_STR(".yaml")}};
if (!name.compare("DUMB_SnowForces")) if (catalogueName == "DUMB_SnowForces"sv)
return {ExtractTweak<SnowForces>, {_SYS_STR(".yaml")}}; return {ExtractTweak<SnowForces>, {_SYS_STR(".yaml")}};
} }
break; break;

View File

@ -17,12 +17,14 @@ public:
bool m_doExtract; bool m_doExtract;
using Level = DataSpec::Level<UniqueID32>; using Level = DataSpec::Level<UniqueID32>;
std::unordered_map<UniqueID32, Level> m_levelDeps; std::unordered_map<UniqueID32, Level> m_levelDeps;
UniqueID32 m_levelId;
hecl::SystemString m_levelString; hecl::SystemString m_levelString;
PAKBridge(const nod::Node& node, bool doExtract = true); PAKBridge(const nod::Node& node, bool doExtract = true);
void build(); void build();
static ResExtractor<PAKBridge> LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry); static ResExtractor<PAKBridge> LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry);
std::string_view getName() const { return m_node.getName(); } std::string_view getName() const { return m_node.getName(); }
UniqueID32 getLevelId() const { return m_levelId; }
hecl::SystemStringView getLevelString() const { return m_levelString; } hecl::SystemStringView getLevelString() const { return m_levelString; }
using PAKType = PAK; using PAKType = PAK;
const PAKType& getPAK() const { return m_pak; } const PAKType& getPAK() const { return m_pak; }

View File

@ -23,6 +23,6 @@ void EVNT::Enumerate(typename Op::StreamT& s) {
AT_SPECIALIZE_DNA_YAML(EVNT) AT_SPECIALIZE_DNA_YAML(EVNT)
const char* EVNT::DNAType() { return "urde::DNAMP1::EVNT"; } std::string_view EVNT::DNAType() { return "urde::DNAMP1::EVNT"sv; }
} // namespace DataSpec::DNAMP1 } // namespace DataSpec::DNAMP1

View File

@ -274,16 +274,13 @@ AT_SPECIALIZE_DNA(FRME::Widget::TXPNInfo)
bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) { std::function<void(const hecl::SystemChar*)> fileChanged) {
if (!force && outPath.isFile())
return true;
FRME frme; FRME frme;
frme.read(rs); frme.read(rs);
hecl::blender::Connection& conn = btok.getBlenderConnection(); hecl::blender::Connection& conn = btok.getBlenderConnection();
#if 0
if (!force && outPath.isFile())
return true;
#endif
if (!conn.createBlend(outPath, hecl::blender::BlendType::Frame)) if (!conn.createBlend(outPath, hecl::blender::BlendType::Frame))
return false; return false;
@ -501,7 +498,7 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
hecl::ProjectPath modelPath = pakRouter.getWorking(info->model); hecl::ProjectPath modelPath = pakRouter.getWorking(info->model);
const PAKRouter<PAKBridge>::EntryType* cmdlE = pakRouter.lookupEntry(info->model, nullptr, true, true); const PAKRouter<PAKBridge>::EntryType* cmdlE = pakRouter.lookupEntry(info->model, nullptr, true, true);
os.linkBlend(modelPath.getAbsolutePathUTF8().data(), pakRouter.getBestEntryName(*cmdlE).c_str(), true); os.linkMesh(modelPath.getAbsolutePathUTF8(), pakRouter.getBestEntryName(*cmdlE));
os.format(fmt("frme_obj.retro_model_light_mask = {}\n"), info->lightMask); os.format(fmt("frme_obj.retro_model_light_mask = {}\n"), info->lightMask);
os << "print(obj.name)\n" os << "print(obj.name)\n"

View File

@ -46,19 +46,19 @@ struct FRME : BigDNA {
struct BWIGInfo : IWidgetInfo { struct BWIGInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::BWIG"; } std::string_view DNATypeV() const override { return "FRME::BWIG"sv; }
FourCC fourcc() const override { return FOURCC('BWIG'); } FourCC fourcc() const override { return FOURCC('BWIG'); }
}; };
struct HWIGInfo : IWidgetInfo { struct HWIGInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::HWIG"; } std::string_view DNATypeV() const override { return "FRME::HWIG"sv; }
FourCC fourcc() const override { return FOURCC('HWIG'); } FourCC fourcc() const override { return FOURCC('HWIG'); }
}; };
struct CAMRInfo : IWidgetInfo { struct CAMRInfo : IWidgetInfo {
AT_DECL_EXPLICIT_DNAV_NO_TYPE AT_DECL_EXPLICIT_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::CAMR"; } std::string_view DNATypeV() const override { return "FRME::CAMR"sv; }
enum class ProjectionType { Perspective, Orthographic }; enum class ProjectionType { Perspective, Orthographic };
Value<ProjectionType> projectionType; Value<ProjectionType> projectionType;
@ -94,7 +94,7 @@ struct FRME : BigDNA {
struct MODLInfo : IWidgetInfo { struct MODLInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::MODL"; } std::string_view DNATypeV() const override { return "FRME::MODL"sv; }
UniqueID32 model; UniqueID32 model;
enum class BlendMode { Unknown0, Unknown1, Unknown2, Additive }; enum class BlendMode { Unknown0, Unknown1, Unknown2, Additive };
@ -106,7 +106,7 @@ struct FRME : BigDNA {
struct LITEInfo : IWidgetInfo { struct LITEInfo : IWidgetInfo {
AT_DECL_EXPLICIT_DNAV_NO_TYPE AT_DECL_EXPLICIT_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::LITE"; } std::string_view DNATypeV() const override { return "FRME::LITE"sv; }
enum class ELightType : atUint32 { enum class ELightType : atUint32 {
Spot = 0, Spot = 0,
Point = 1, Point = 1,
@ -130,7 +130,7 @@ struct FRME : BigDNA {
struct ENRGInfo : IWidgetInfo { struct ENRGInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::ENRG"; } std::string_view DNATypeV() const override { return "FRME::ENRG"sv; }
UniqueID32 texture; UniqueID32 texture;
FourCC fourcc() const override { return FOURCC('ENRG'); } FourCC fourcc() const override { return FOURCC('ENRG'); }
@ -138,7 +138,7 @@ struct FRME : BigDNA {
struct METRInfo : IWidgetInfo { struct METRInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::METR"; } std::string_view DNATypeV() const override { return "FRME::METR"sv; }
Value<bool> unk1; Value<bool> unk1;
Value<bool> noRoundUp; Value<bool> noRoundUp;
Value<atUint32> maxCapacity; Value<atUint32> maxCapacity;
@ -149,7 +149,7 @@ struct FRME : BigDNA {
struct GRUPInfo : IWidgetInfo { struct GRUPInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::GRUP"; } std::string_view DNATypeV() const override { return "FRME::GRUP"sv; }
Value<atInt16> defaultWorker; Value<atInt16> defaultWorker;
Value<bool> unk3; Value<bool> unk3;
@ -158,7 +158,7 @@ struct FRME : BigDNA {
struct TBGPInfo : IWidgetInfo { struct TBGPInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::TBGP"; } std::string_view DNATypeV() const override { return "FRME::TBGP"sv; }
Value<atUint16> elementCount; Value<atUint16> elementCount;
Value<atUint16> unk2; Value<atUint16> unk2;
Value<atUint32> unkEnum; Value<atUint32> unkEnum;
@ -180,7 +180,7 @@ struct FRME : BigDNA {
struct SLGPInfo : IWidgetInfo { struct SLGPInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::SLGP"; } std::string_view DNATypeV() const override { return "FRME::SLGP"sv; }
Value<float> min; Value<float> min;
Value<float> max; Value<float> max;
Value<float> cur; Value<float> cur;
@ -191,7 +191,7 @@ struct FRME : BigDNA {
struct PANEInfo : IWidgetInfo { struct PANEInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::PANE"; } std::string_view DNATypeV() const override { return "FRME::PANE"sv; }
Value<float> xDim; Value<float> xDim;
Value<float> zDim; Value<float> zDim;
Value<atVec3f> scaleCenter; Value<atVec3f> scaleCenter;
@ -200,7 +200,7 @@ struct FRME : BigDNA {
}; };
struct TXPNInfo : IWidgetInfo { struct TXPNInfo : IWidgetInfo {
const char* DNATypeV() const override { return "FRME::TXPN"; } std::string_view DNATypeV() const override { return "FRME::TXPN"sv; }
enum class Justification : atUint32 { enum class Justification : atUint32 {
Left = 0, Left = 0,
Center, Center,
@ -252,7 +252,7 @@ struct FRME : BigDNA {
struct IMGPInfo : IWidgetInfo { struct IMGPInfo : IWidgetInfo {
AT_DECL_DNAV_NO_TYPE AT_DECL_DNAV_NO_TYPE
const char* DNATypeV() const override { return "FRME::IMGP"; } std::string_view DNATypeV() const override { return "FRME::IMGP"sv; }
UniqueID32 texture; UniqueID32 texture;
Value<atUint32> unk1; Value<atUint32> unk1;
Value<atUint32> unk2; Value<atUint32> unk2;

View File

@ -9,7 +9,10 @@
#include "Runtime/World/ScriptObjectSupport.hpp" #include "Runtime/World/ScriptObjectSupport.hpp"
#include "hecl/Blender/Connection.hpp" #include "hecl/Blender/Connection.hpp"
namespace DataSpec::DNAMP1 { namespace DataSpec {
extern hecl::Database::DataSpecEntry SpecEntMP1;
namespace DNAMP1 {
bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
@ -29,13 +32,13 @@ bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
hecl::ProjectPath areaDir = pakRouter.getWorking(area.areaMREAId).getParentPath(); hecl::ProjectPath areaDir = pakRouter.getWorking(area.areaMREAId).getParentPath();
{ {
athena::io::FileWriter fw(hecl::ProjectPath(areaDir, _SYS_STR("!memoryid.yaml")).getAbsolutePath()); athena::io::FileWriter fw(hecl::ProjectPath(areaDir, _SYS_STR("!memoryid.yaml")).getAbsolutePath());
athena::io::YAMLDocWriter w(nullptr); athena::io::YAMLDocWriter w;
w.writeUint32("memoryid", area.areaId); w.writeUint32("memoryid", area.areaId);
w.finish(&fw); w.finish(&fw);
} }
{ {
athena::io::FileWriter fw(hecl::ProjectPath(areaDir, _SYS_STR("!memoryrelays.yaml")).getAbsolutePath()); athena::io::FileWriter fw(hecl::ProjectPath(areaDir, _SYS_STR("!memoryrelays.yaml")).getAbsolutePath());
athena::io::YAMLDocWriter w(nullptr); athena::io::YAMLDocWriter w;
std::vector<atUint32> relayIds; std::vector<atUint32> relayIds;
for (const atUint32& relay : savw.relays) { for (const atUint32& relay : savw.relays) {
@ -59,6 +62,20 @@ bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged);
} }
bool MLVL::ExtractMAPW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
/* Empty placeholder file for dependency management */
athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::YAMLDocWriter dw("DataSpec::DNAMP1::MAPW");
return dw.finish(&writer);
}
bool MLVL::ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) {
/* Empty placeholder file for dependency management */
athena::io::FileWriter writer(outPath.getAbsolutePath());
athena::io::YAMLDocWriter dw("DataSpec::DNAMP1::SAVW");
return dw.finish(&writer);
}
struct LayerResources { struct LayerResources {
std::unordered_set<hecl::Hash> addedPaths; std::unordered_set<hecl::Hash> addedPaths;
std::vector<std::vector<std::pair<hecl::ProjectPath, bool>>> layerPaths; std::vector<std::vector<std::pair<hecl::ProjectPath, bool>>> layerPaths;
@ -90,16 +107,24 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
athena::io::FileReader reader(inPath.getWithExtension(_SYS_STR(".yaml"), true).getAbsolutePath()); athena::io::FileReader reader(inPath.getWithExtension(_SYS_STR(".yaml"), true).getAbsolutePath());
athena::io::FromYAMLStream(mlvl, reader, &MLVL::readMeta); athena::io::FromYAMLStream(mlvl, reader, &MLVL::readMeta);
const hecl::ProjectPath parentPath = inPath.getParentPath();
const hecl::DirectoryEnumerator dEnum(parentPath.getAbsolutePath());
mlvl.magic = 0xDEAFBABE; mlvl.magic = 0xDEAFBABE;
mlvl.version = 0x11; mlvl.version = 0x11;
hecl::ProjectPath namePath(inPath.getParentPath(), _SYS_STR("!name.yaml")); hecl::ProjectPath namePath = GetPathBeginsWith(dEnum, parentPath, _SYS_STR("!name_"));
if (namePath.isFile()) if (namePath.isFile())
mlvl.worldNameId = namePath; mlvl.worldNameId = namePath;
hecl::ProjectPath globPath = inPath.getWithExtension(_SYS_STR(".*"), true); hecl::ProjectPath savwPath = GetPathBeginsWith(dEnum, parentPath, _SYS_STR("!savw_"));
hecl::ProjectPath savwPath = globPath.ensureAuxInfo(_SYS_STR("SAVW")); if (savwPath.isFile()) {
mlvl.saveWorldId = savwPath; CookSAVW(savwPath.getCookedPath(SpecEntMP1), wld);
hecl::ProjectPath mapwPath = globPath.ensureAuxInfo(_SYS_STR("MAPW")); mlvl.saveWorldId = savwPath;
mlvl.worldMap = mapwPath; }
hecl::ProjectPath mapwPath = GetPathBeginsWith(dEnum, parentPath, _SYS_STR("!mapw_"));
if (mapwPath.isFile()) {
CookMAPW(mapwPath.getCookedPath(SpecEntMP1), wld);
mlvl.worldMap = mapwPath;
}
size_t areaIdx = 0; size_t areaIdx = 0;
size_t nameOffset = 0; size_t nameOffset = 0;
@ -107,7 +132,8 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
if (area.path.getPathType() != hecl::ProjectPath::Type::Directory) if (area.path.getPathType() != hecl::ProjectPath::Type::Directory)
continue; continue;
hecl::ProjectPath areaPath(area.path, _SYS_STR("!area.blend")); const hecl::DirectoryEnumerator areaDEnum(area.path.getAbsolutePath());
const hecl::ProjectPath areaPath = GetPathBeginsWith(areaDEnum, area.path, _SYS_STR("!area_"));
if (!areaPath.isFile()) if (!areaPath.isFile())
continue; continue;
@ -128,12 +154,11 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
/* Bare minimum we'll need exactly the same number of links as relays */ /* Bare minimum we'll need exactly the same number of links as relays */
memRelayLinks.reserve(memRelays.size()); memRelayLinks.reserve(memRelays.size());
hecl::DirectoryEnumerator dEnum(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted);
bool areaInit = false; bool areaInit = false;
size_t layerIdx = 0; size_t layerIdx = 0;
LayerResources layerResources; LayerResources layerResources;
for (const hecl::DirectoryEnumerator::Entry& e : dEnum) { for (const hecl::DirectoryEnumerator::Entry& e :
hecl::DirectoryEnumerator(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted)) {
hecl::SystemString layerName; hecl::SystemString layerName;
hecl::SystemChar* endCh = nullptr; hecl::SystemChar* endCh = nullptr;
hecl::StrToUl(e.m_name.c_str(), &endCh, 0); hecl::StrToUl(e.m_name.c_str(), &endCh, 0);
@ -175,7 +200,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
mlvl.areas.emplace_back(); mlvl.areas.emplace_back();
MLVL::Area& areaOut = mlvl.areas.back(); MLVL::Area& areaOut = mlvl.areas.back();
hecl::ProjectPath namePath(area.path, _SYS_STR("!name.yaml")); hecl::ProjectPath namePath = GetPathBeginsWith(areaDEnum, area.path, _SYS_STR("!name_"));
if (namePath.isFile()) if (namePath.isFile())
areaOut.areaNameId = namePath; areaOut.areaNameId = namePath;
@ -258,7 +283,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
memRelayLinks.push_back(linkOut); memRelayLinks.push_back(linkOut);
memRelays.push_back(memRelay.id); memRelays.push_back(memRelay.id);
} else { } else {
memRelayLinks.push_back(linkOut); memRelayLinks.push_back(linkOut);
} }
} }
} }
@ -333,7 +358,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
} }
} }
hecl::ProjectPath pathPath(areaPath.getParentPath(), _SYS_STR("!path.blend")); hecl::ProjectPath pathPath = GetPathBeginsWith(areaDEnum, area.path, _SYS_STR("!path_"));
urde::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath); urde::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath);
if (pathTag.id.IsValid()) { if (pathTag.id.IsValid()) {
areaOut.deps.emplace_back(pathTag.id.Value(), pathTag.type); areaOut.deps.emplace_back(pathTag.id.Value(), pathTag.type);
@ -375,7 +400,7 @@ bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld) {
continue; continue;
/* Area map */ /* Area map */
hecl::ProjectPath mapPath(area.path, _SYS_STR("/!map.blend")); hecl::ProjectPath mapPath = GetPathBeginsWith(area.path, _SYS_STR("!map_"));
if (mapPath.isFile()) if (mapPath.isFile())
mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath)); mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath));
} }
@ -407,7 +432,7 @@ bool MLVL::CookSAVW(const hecl::ProjectPath& outPath, const World& wld) {
if (area.path.getPathType() != hecl::ProjectPath::Type::Directory) if (area.path.getPathType() != hecl::ProjectPath::Type::Directory)
continue; continue;
hecl::ProjectPath areaPath(area.path, _SYS_STR("/!area.blend")); hecl::ProjectPath areaPath = GetPathBeginsWith(area.path, _SYS_STR("!area_"));
if (!areaPath.isFile()) if (!areaPath.isFile())
continue; continue;
@ -421,9 +446,8 @@ bool MLVL::CookSAVW(const hecl::ProjectPath& outPath, const World& wld) {
} }
savw.relays.insert(savw.relays.end(), memRelays.begin(), memRelays.end()); savw.relays.insert(savw.relays.end(), memRelays.begin(), memRelays.end());
hecl::DirectoryEnumerator dEnum(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted); for (const hecl::DirectoryEnumerator::Entry& e :
hecl::DirectoryEnumerator(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted)) {
for (const hecl::DirectoryEnumerator::Entry& e : dEnum) {
hecl::SystemString layerName; hecl::SystemString layerName;
hecl::SystemChar* endCh = nullptr; hecl::SystemChar* endCh = nullptr;
hecl::StrToUl(e.m_name.c_str(), &endCh, 0); hecl::StrToUl(e.m_name.c_str(), &endCh, 0);
@ -518,4 +542,5 @@ bool MLVL::CookSAVW(const hecl::ProjectPath& outPath, const World& wld) {
return true; return true;
} }
} // namespace DataSpec::DNAMP1 } // namespace DNAMP1
} // namespace DataSpec

View File

@ -131,6 +131,10 @@ struct MLVL : BigDNA {
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)> fileChanged); std::function<void(const hecl::SystemChar*)> fileChanged);
static bool ExtractMAPW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
using World = hecl::blender::World; using World = hecl::blender::World;
static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld, static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld,

View File

@ -180,8 +180,8 @@ static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::IStream
bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>) { std::function<void(const hecl::SystemChar*)>) {
using RigPair = std::pair<CSKR*, CINF*>; using RigPair = std::pair<std::pair<UniqueID32, CSKR*>, std::pair<UniqueID32, CINF*>>;
RigPair dummy(nullptr, nullptr); RigPair dummy = {};
if (!force && outPath.isFile()) if (!force && outPath.isFile())
return true; return true;
@ -298,7 +298,7 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
rs.seek(8, athena::Current); rs.seek(8, athena::Current);
for (uint32_t i = 0; i < entityCount; ++i) { for (uint32_t i = 0; i < entityCount; ++i) {
uint32_t entityId = rs.readUint32Big(); uint32_t entityId = rs.readUint32Big();
visiWriter.writeUint32(nullptr, entityId); visiWriter.writeUint32(entityId);
} }
} }
hecl::ProjectPath visiMetadataPath(outPath.getParentPath(), _SYS_STR("!visi.yaml")); hecl::ProjectPath visiMetadataPath(outPath.getParentPath(), _SYS_STR("!visi.yaml"));
@ -314,7 +314,8 @@ bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
"bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n"; "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n";
/* Link MLVL scene as background */ /* Link MLVL scene as background */
os.linkBackground("//../!world.blend", "World"); os.linkBackground(fmt::format(fmt("//../!world_{}.blend"),
pakRouter.getCurrentBridge().getLevelId()), "World"sv);
os.centerView(); os.centerView();
os.close(); os.close();
@ -357,21 +358,21 @@ void MREA::Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter<PAKB
void MREA::MeshHeader::VisorFlags::setFromBlenderProps(const std::unordered_map<std::string, std::string>& props) { void MREA::MeshHeader::VisorFlags::setFromBlenderProps(const std::unordered_map<std::string, std::string>& props) {
auto search = props.find("retro_disable_enviro_visor"); auto search = props.find("retro_disable_enviro_visor");
if (search != props.cend() && !search->second.compare("True")) if (search != props.cend() && search->second == "True")
setDisableEnviro(true); setDisableEnviro(true);
search = props.find("retro_disable_thermal_visor"); search = props.find("retro_disable_thermal_visor");
if (search != props.cend() && !search->second.compare("True")) if (search != props.cend() && search->second == "True")
setDisableThermal(true); setDisableThermal(true);
search = props.find("retro_disable_xray_visor"); search = props.find("retro_disable_xray_visor");
if (search != props.cend() && !search->second.compare("True")) if (search != props.cend() && search->second == "True")
setDisableXray(true); setDisableXray(true);
search = props.find("retro_thermal_level"); search = props.find("retro_thermal_level");
if (search != props.cend()) { if (search != props.cend()) {
if (!search->second.compare("COOL")) if (search->second == "COOL")
setThermalLevel(ThermalLevel::Cool); setThermalLevel(ThermalLevel::Cool);
else if (!search->second.compare("HOT")) else if (search->second == "HOT")
setThermalLevel(ThermalLevel::Hot); setThermalLevel(ThermalLevel::Hot);
else if (!search->second.compare("WARM")) else if (search->second == "WARM")
setThermalLevel(ThermalLevel::Warm); setThermalLevel(ThermalLevel::Warm);
} }
} }
@ -614,7 +615,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
if (auto __vec = r.enterSubVector("entities", entityCount)) { if (auto __vec = r.enterSubVector("entities", entityCount)) {
entities.reserve(entityCount); entities.reserve(entityCount);
for (size_t i = 0; i < entityCount; ++i) { for (size_t i = 0; i < entityCount; ++i) {
uint32_t entityId = r.readUint32(nullptr); uint32_t entityId = r.readUint32();
for (const SCLY::ScriptLayer& layer : sclyData.layers) { for (const SCLY::ScriptLayer& layer : sclyData.layers) {
for (const std::unique_ptr<IScriptObject>& obj : layer.objects) { for (const std::unique_ptr<IScriptObject>& obj : layer.objects) {
if ((obj->id & ~0x03FF0000) == entityId) { if ((obj->id & ~0x03FF0000) == entityId) {
@ -730,8 +731,10 @@ bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
/* PATH */ /* PATH */
{ {
hecl::ProjectPath pathPath(inPath.getParentPath(), _SYS_STR("!path.blend")); const hecl::ProjectPath pathPath = GetPathBeginsWith(inPath.getParentPath(), _SYS_STR("!path_"));
UniqueID32 pathId = pathPath; UniqueID32 pathId;
if (pathPath.isFile())
pathId = pathPath;
secs.emplace_back(4, 0); secs.emplace_back(4, 0);
athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); athena::io::MemoryWriter w(secs.back().data(), secs.back().size());
pathId.write(w); pathId.write(w);

View File

@ -156,27 +156,27 @@ const PAK::Entry* PAK::lookupEntry(std::string_view name) const {
return nullptr; return nullptr;
} }
std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, bool& named) const { std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const {
std::unordered_map<UniqueID32, Entry>::const_iterator search; std::unordered_map<UniqueID32, Entry>::const_iterator search;
if (entry.type == FOURCC('AGSC') && (search = m_entries.find(entry.id)) != m_entries.cend()) { if (entry.type == FOURCC('AGSC') && (search = m_entries.find(entry.id)) != m_entries.cend()) {
/* Use internal AGSC name for entry */ /* Use internal AGSC name for entry */
auto rs = search->second.beginReadStream(pakNode); auto rs = search->second.beginReadStream(pakNode);
AGSC::Header header; AGSC::Header header;
header.read(rs); header.read(rs);
named = true; catalogueName = header.groupName;
return header.groupName; return fmt::format(fmt("{}_{}"), header.groupName, entry.id);
} }
/* Prefer named entries first */ /* Prefer named entries first */
for (const NameEntry& nentry : m_nameEntries) for (const NameEntry& nentry : m_nameEntries) {
if (nentry.id == entry.id) { if (nentry.id == entry.id) {
named = true; catalogueName = nentry.name;
return nentry.name; return fmt::format(fmt("{}_{}"), nentry.name, entry.id);
} }
}
/* Otherwise return ID format string */ /* Otherwise return ID format string */
named = false; return fmt::format(fmt("{}_{}"), entry.type, entry.id);
return entry.type.toString() + '_' + entry.id.toString();
} }
} // namespace DataSpec::DNAMP1 } // namespace DataSpec::DNAMP1

View File

@ -47,7 +47,7 @@ struct PAK : BigDNA {
const Entry* lookupEntry(const UniqueID32& id) const; const Entry* lookupEntry(const UniqueID32& id) const;
const Entry* lookupEntry(std::string_view name) const; const Entry* lookupEntry(std::string_view name) const;
std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, bool& named) const; std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const;
bool mreaHasDupeResources(const UniqueID32& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); } bool mreaHasDupeResources(const UniqueID32& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); }

View File

@ -24,7 +24,8 @@ static void OutputOctreeNode(hecl::blender::PyOutStream& os, int idx, const zeus
} }
#endif #endif
void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName, const zeus::CMatrix4f* xf) { void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName, const zeus::CMatrix4f* xf,
const std::string& areaPath) {
/* Open Py Stream and read sections */ /* Open Py Stream and read sections */
hecl::blender::PyOutStream os = conn.beginPythonOut(true); hecl::blender::PyOutStream os = conn.beginPythonOut(true);
os << os <<
@ -173,7 +174,7 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
} }
#endif #endif
os.linkBackground("//!area.blend"); os.linkBackground(fmt::format(fmt("//{}"), areaPath));
os.centerView(); os.centerView();
os.close(); os.close();
} }
@ -187,8 +188,16 @@ bool PATH::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
if (!conn.createBlend(outPath, hecl::blender::BlendType::PathMesh)) if (!conn.createBlend(outPath, hecl::blender::BlendType::PathMesh))
return false; return false;
std::string areaPath;
for (const auto& ent : hecl::DirectoryEnumerator(outPath.getParentPath().getAbsolutePath())) {
if (hecl::StringUtils::BeginsWith(ent.m_name, _SYS_STR("!area_"))) {
areaPath = hecl::SystemUTF8Conv(ent.m_name).str();
break;
}
}
const zeus::CMatrix4f* xf = pakRouter.lookupMAPATransform(entry.id); const zeus::CMatrix4f* xf = pakRouter.lookupMAPATransform(entry.id);
path.sendToBlender(conn, pakRouter.getBestEntryName(entry, false), xf); path.sendToBlender(conn, pakRouter.getBestEntryName(entry, false), xf, areaPath);
return conn.saveBlend(); return conn.saveBlend();
} }

View File

@ -66,7 +66,8 @@ struct PATH : BigDNA {
Value<atUint32> octreeNodeCount; Value<atUint32> octreeNodeCount;
Vector<OctreeNode, AT_DNA_COUNT(octreeNodeCount)> octree; Vector<OctreeNode, AT_DNA_COUNT(octreeNodeCount)> octree;
void sendToBlender(hecl::blender::Connection& conn, std::string_view entryName, const zeus::CMatrix4f* xf); void sendToBlender(hecl::blender::Connection& conn, std::string_view entryName, const zeus::CMatrix4f* xf,
const std::string& areaPath);
static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,

View File

@ -62,7 +62,7 @@ void SCAN::Texture::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& w)
w.writeFloat("fadeDuration", fadeDuration); w.writeFloat("fadeDuration", fadeDuration);
} }
const char* SCAN::Texture::DNAType() { return "urde::DNAMP1::SCAN::Texture"; } std::string_view SCAN::Texture::DNAType() { return "urde::DNAMP1::SCAN::Texture"sv; }
template <> template <>
void SCAN::Texture::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) { void SCAN::Texture::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {

View File

@ -91,7 +91,7 @@ void SCLY::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& docout) {
docout.enumerate("layers", layers); docout.enumerate("layers", layers);
} }
const char* SCLY::DNAType() { return "urde::DNAMP1::SCLY"; } std::string_view SCLY::DNAType() { return "urde::DNAMP1::SCLY"sv; }
template <> template <>
void SCLY::ScriptLayer::Enumerate<BigDNA::Read>(athena::io::IStreamReader& rs) { void SCLY::ScriptLayer::Enumerate<BigDNA::Read>(athena::io::IStreamReader& rs) {
@ -133,7 +133,7 @@ void SCLY::ScriptLayer::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& r
objectCount = objCount; objectCount = objCount;
objects.reserve(objCount); objects.reserve(objCount);
for (atUint32 i = 0; i < objectCount; i++) { for (atUint32 i = 0; i < objectCount; i++) {
if (auto rec = rs.enterSubRecord(nullptr)) { if (auto rec = rs.enterSubRecord()) {
atUint8 type = rs.readUByte("type"); atUint8 type = rs.readUByte("type");
auto iter = std::find_if(SCRIPT_OBJECT_DB.begin(), SCRIPT_OBJECT_DB.end(), auto iter = std::find_if(SCRIPT_OBJECT_DB.begin(), SCRIPT_OBJECT_DB.end(),
[&type](const ScriptObjectSpec* obj) -> bool { return obj->type == type; }); [&type](const ScriptObjectSpec* obj) -> bool { return obj->type == type; });
@ -182,7 +182,7 @@ void SCLY::ScriptLayer::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter&
ws.writeUByte("unknown", unknown); ws.writeUByte("unknown", unknown);
if (auto v = ws.enterSubVector("objects")) { if (auto v = ws.enterSubVector("objects")) {
for (const std::unique_ptr<IScriptObject>& obj : objects) { for (const std::unique_ptr<IScriptObject>& obj : objects) {
if (auto rec = ws.enterSubRecord(nullptr)) { if (auto rec = ws.enterSubRecord()) {
ws.writeUByte("type", obj->type); ws.writeUByte("type", obj->type);
obj->write(ws); obj->write(ws);
} }
@ -190,6 +190,6 @@ void SCLY::ScriptLayer::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter&
} }
} }
const char* SCLY::ScriptLayer::DNAType() { return "urde::DNAMP1::SCLY::ScriptLayer"; } std::string_view SCLY::ScriptLayer::DNAType() { return "urde::DNAMP1::SCLY::ScriptLayer"sv; }
} // namespace DataSpec::DNAMP1 } // namespace DataSpec::DNAMP1

View File

@ -448,11 +448,11 @@ void STRG::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader) {
template <> template <>
void STRG::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) { void STRG::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer) {
for (const auto& lang : langs) { for (const auto& lang : langs) {
if (auto v = writer.enterSubVector(lang.first.toString().c_str())) if (auto v = writer.enterSubVector(lang.first.toString()))
for (const std::u16string& str : lang.second) for (const std::u16string& str : lang.second)
writer.writeU16String(nullptr, str); writer.writeU16String(str);
} }
} }
const char* STRG::DNAType() { return "urde::DNAMP1::STRG"; } std::string_view STRG::DNAType() { return "urde::DNAMP1::STRG"sv; }
} // namespace DataSpec::DNAMP1 } // namespace DataSpec::DNAMP1

View File

@ -46,9 +46,10 @@ struct Babygoth : IScriptObject {
actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters);
if (noShellModel.isValid() && noShellSkin.isValid()) { if (noShellModel.isValid() && noShellSkin.isValid()) {
charAssoc.m_cmdlRigs[noShellModel] = std::make_pair(noShellSkin, cinf); charAssoc.m_cmdlRigs[noShellModel] = {noShellSkin, cinf};
charAssoc.m_cskrCinfToCharacter[noShellSkin] = charAssoc.m_cskrToCharacter[noShellSkin] =
std::make_pair(patternedInfo.animationParameters.animationCharacterSet, "ATTACH.SHELLESS.CSKR"); std::make_pair(patternedInfo.animationParameters.animationCharacterSet,
fmt::format(fmt("ATTACH.SHELLESS_{}.CSKR"), noShellSkin));
charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, {}, noShellModel, "SHELLESS"); charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, {}, noShellModel, "SHELLESS");
} }
} }

View File

@ -44,9 +44,10 @@ struct Magdolite : IScriptObject {
actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters);
if (cmdlHeadless.isValid() && cskrHeadless.isValid()) { if (cmdlHeadless.isValid() && cskrHeadless.isValid()) {
charAssoc.m_cmdlRigs[cmdlHeadless] = std::make_pair(cskrHeadless, cinf); charAssoc.m_cmdlRigs[cmdlHeadless] = {cskrHeadless, cinf};
charAssoc.m_cskrCinfToCharacter[cskrHeadless] = charAssoc.m_cskrToCharacter[cskrHeadless] =
std::make_pair(patternedInfo.animationParameters.animationCharacterSet, "ATTACH.HEADLESS.CSKR"); std::make_pair(patternedInfo.animationParameters.animationCharacterSet,
fmt::format(fmt("ATTACH.HEADLESS_{}.CSKR"), cskrHeadless));
charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, {}, cmdlHeadless, "HEADLESS"); charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, {}, cmdlHeadless, "HEADLESS");
} }
} }

View File

@ -26,7 +26,7 @@ void Oculus::Enumerate(typename Op::StreamT& s) {
unknown8 = 0.f; unknown8 = 0.f;
} }
const char* Oculus::DNAType() { return "urde::DNAMP1::Oculus"; } std::string_view Oculus::DNAType() { return "urde::DNAMP1::Oculus"sv; }
AT_SPECIALIZE_DNA_YAML(Oculus) AT_SPECIALIZE_DNA_YAML(Oculus)

View File

@ -57,12 +57,10 @@ struct OmegaPirate : IScriptObject {
actorParameters1.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); actorParameters1.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters);
actorParameters2.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); actorParameters2.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters);
if (cmdlPhazonVeins.isValid() && cskrPhazonVeins.isValid() && cinfPhazonVeins.isValid()) { if (cmdlPhazonVeins.isValid() && cskrPhazonVeins.isValid() && cinfPhazonVeins.isValid()) {
charAssoc.m_cmdlRigs[cmdlPhazonVeins] = std::make_pair(cskrPhazonVeins, cinfPhazonVeins); charAssoc.m_cmdlRigs[cmdlPhazonVeins] = {cskrPhazonVeins, cinfPhazonVeins};
charAssoc.m_cskrCinfToCharacter[cskrPhazonVeins] = charAssoc.m_cskrToCharacter[cskrPhazonVeins] =
std::make_pair(patternedInfo.animationParameters.animationCharacterSet, "ATTACH.VEINS.CSKR");
charAssoc.m_cskrCinfToCharacter[cinfPhazonVeins] =
std::make_pair(patternedInfo.animationParameters.animationCharacterSet, std::make_pair(patternedInfo.animationParameters.animationCharacterSet,
fmt::format(fmt("CINF_{}.CINF"), cinfPhazonVeins)); fmt::format(fmt("ATTACH.VEINS_{}.CSKR"), cskrPhazonVeins));
charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, cinfPhazonVeins, charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, cinfPhazonVeins,
cmdlPhazonVeins, "VEINS"); cmdlPhazonVeins, "VEINS");
} }

View File

@ -378,14 +378,15 @@ struct ActorParameters : BigDNA {
const AnimationParameters& animParms) const { const AnimationParameters& animParms) const {
auto cinf = animParms.getCINF(pakRouter); auto cinf = animParms.getCINF(pakRouter);
if (cmdlXray.isValid() && cskrXray.isValid()) { if (cmdlXray.isValid() && cskrXray.isValid()) {
charAssoc.m_cmdlRigs[cmdlXray] = std::make_pair(cskrXray, cinf); charAssoc.m_cmdlRigs[cmdlXray] = {cskrXray, cinf};
charAssoc.m_cskrCinfToCharacter[cskrXray] = std::make_pair(animParms.animationCharacterSet, "ATTACH.XRAY.CSKR"); charAssoc.m_cskrToCharacter[cskrXray] = std::make_pair(animParms.animationCharacterSet,
fmt::format(fmt("ATTACH.XRAY_{}.CSKR"), cskrXray));
charAssoc.addAttachmentRig(animParms.animationCharacterSet, {}, cmdlXray, "XRAY"); charAssoc.addAttachmentRig(animParms.animationCharacterSet, {}, cmdlXray, "XRAY");
} }
if (cmdlThermal.isValid() && cskrThermal.isValid()) { if (cmdlThermal.isValid() && cskrThermal.isValid()) {
charAssoc.m_cmdlRigs[cmdlThermal] = std::make_pair(cskrThermal, cinf); charAssoc.m_cmdlRigs[cmdlThermal] = {cskrThermal, cinf};
charAssoc.m_cskrCinfToCharacter[cskrThermal] = charAssoc.m_cskrToCharacter[cskrThermal] =
std::make_pair(animParms.animationCharacterSet, "ATTACH.THERMAL.CSKR"); std::make_pair(animParms.animationCharacterSet, fmt::format(fmt("ATTACH.THERMAL_{}.CSKR"), cskrThermal));
charAssoc.addAttachmentRig(animParms.animationCharacterSet, {}, cmdlThermal, "THERMAL"); charAssoc.addAttachmentRig(animParms.animationCharacterSet, {}, cmdlThermal, "THERMAL");
} }
} }

View File

@ -61,7 +61,7 @@ void Ridley::Enumerate(typename Op::StreamT& s) {
Do<Op>(athena::io::PropId{"damageInfo9"}, damageInfo9, s); Do<Op>(athena::io::PropId{"damageInfo9"}, damageInfo9, s);
} }
const char* Ridley::DNAType() { return "urde::DNAMP1::Ridley"; } std::string_view Ridley::DNAType() { return "urde::DNAMP1::Ridley"sv; }
AT_SPECIALIZE_DNA_YAML(Ridley) AT_SPECIALIZE_DNA_YAML(Ridley)

View File

@ -41,7 +41,7 @@ void WorldTeleporter::Enumerate(typename Op::StreamT& s) {
} }
} }
const char* WorldTeleporter::DNAType() { return "urde::DNAMP1::WorldTeleporter"; } std::string_view WorldTeleporter::DNAType() { return "urde::DNAMP1::WorldTeleporter"sv; }
AT_SPECIALIZE_DNA_YAML(WorldTeleporter) AT_SPECIALIZE_DNA_YAML(WorldTeleporter)

View File

@ -910,7 +910,7 @@ void CTweakBall::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& __dna
__dna_docout.writeFloat("x234_boostBallIncrementalSpeed2", x234_boostBallIncrementalSpeed2); __dna_docout.writeFloat("x234_boostBallIncrementalSpeed2", x234_boostBallIncrementalSpeed2);
} }
const char* CTweakBall::DNAType() { return "DataSpec::DNAMP1::CTweakBall"; } std::string_view CTweakBall::DNAType() { return "DataSpec::DNAMP1::CTweakBall"sv; }
template <> template <>
void CTweakBall::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) { void CTweakBall::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {

View File

@ -1899,7 +1899,7 @@ void CTweakPlayer::FixupValues() {
x29c_fallCameraPitchDownAngle = zeus::degToRad(x29c_fallCameraPitchDownAngle); x29c_fallCameraPitchDownAngle = zeus::degToRad(x29c_fallCameraPitchDownAngle);
} }
const char* CTweakPlayer::DNAType() { return "DataSpec::DNAMP1::CTweakPlayer"; } std::string_view CTweakPlayer::DNAType() { return "DataSpec::DNAMP1::CTweakPlayer"sv; }
template <> template <>
void CTweakPlayer::Enumerate<BigDNA::BinarySize>(size_t& __isz) { void CTweakPlayer::Enumerate<BigDNA::BinarySize>(size_t& __isz) {

View File

@ -346,7 +346,9 @@ void ANCS::CharacterSet::CharacterInfo::Enumerate<BigDNA::WriteYaml>(typename Wr
} }
} }
const char* ANCS::CharacterSet::CharacterInfo::DNAType() { return "urde::DNAMP2::ANCS::CharacterSet::CharacterInfo"; } std::string_view ANCS::CharacterSet::CharacterInfo::DNAType() {
return "urde::DNAMP2::ANCS::CharacterSet::CharacterInfo"sv;
}
template <> template <>
void ANCS::AnimationSet::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) { void ANCS::AnimationSet::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
@ -521,7 +523,7 @@ void ANCS::AnimationSet::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::Stream
} }
} }
const char* ANCS::AnimationSet::DNAType() { return "urde::DNAMP2::ANCS::AnimationSet"; } std::string_view ANCS::AnimationSet::DNAType() { return "urde::DNAMP2::ANCS::AnimationSet"sv; }
template <class Op> template <class Op>
void ANCS::AnimationSet::EVNT::Enumerate(typename Op::StreamT& s) { void ANCS::AnimationSet::EVNT::Enumerate(typename Op::StreamT& s) {
@ -540,6 +542,6 @@ void ANCS::AnimationSet::EVNT::Enumerate(typename Op::StreamT& s) {
AT_SPECIALIZE_DNA(ANCS::AnimationSet::EVNT) AT_SPECIALIZE_DNA(ANCS::AnimationSet::EVNT)
const char* ANCS::AnimationSet::EVNT::DNAType() { return "urde::DNAMP2::ANCS::AnimationSet::EVNT"; } std::string_view ANCS::AnimationSet::EVNT::DNAType() { return "urde::DNAMP2::ANCS::AnimationSet::EVNT"sv; }
} // namespace DataSpec::DNAMP2 } // namespace DataSpec::DNAMP2

View File

@ -151,7 +151,7 @@ void ANIM::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
m_anim->binarySize(s); m_anim->binarySize(s);
} }
const char* ANIM::ANIM0::DNAType() { return "ANIM0"; } std::string_view ANIM::ANIM0::DNAType() { return "ANIM0"sv; }
template <> template <>
void ANIM::ANIM0::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) { void ANIM::ANIM0::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {
@ -398,7 +398,7 @@ void ANIM::ANIM0::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
} }
} }
const char* ANIM::ANIM2::DNAType() { return "ANIM2"; } std::string_view ANIM::ANIM2::DNAType() { return "ANIM2"sv; }
template <> template <>
void ANIM::ANIM2::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) { void ANIM::ANIM2::Enumerate<BigDNA::Read>(typename Read::StreamT& reader) {

View File

@ -7,22 +7,22 @@ bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>) { std::function<void(const hecl::SystemChar*)>) {
/* Check for RigPair */ /* Check for RigPair */
const typename CharacterAssociations<UniqueID32>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
CINF cinf; CINF cinf;
CSKR cskr; CSKR cskr;
std::pair<CSKR*, CINF*> loadRp(nullptr, nullptr); using RigPair = std::pair<std::pair<UniqueID32, CSKR*>, std::pair<UniqueID32, CINF*>>;
if (rp) { RigPair loadRp = {};
pakRouter.lookupAndReadDNA(rp->first, cskr); if (const typename CharacterAssociations<UniqueID32>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id)) {
pakRouter.lookupAndReadDNA(rp->second, cinf); pakRouter.lookupAndReadDNA(rp->cskr, cskr);
loadRp.first = &cskr; pakRouter.lookupAndReadDNA(rp->cinf, cinf);
loadRp.second = &cinf; loadRp.first = {rp->cskr, &cskr};
loadRp.second = {rp->cinf, &cinf};
} }
/* Do extract */ /* Do extract */
hecl::blender::Connection& conn = btok.getBlenderConnection(); hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*, CINF*>, DNACMDL::SurfaceHeader_2, 4>( DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, RigPair, DNACMDL::SurfaceHeader_2, 4>(
conn, rs, pakRouter, entry, dataSpec, loadRp); conn, rs, pakRouter, entry, dataSpec, loadRp);
return conn.saveBlend(); return conn.saveBlend();
} }

View File

@ -75,8 +75,8 @@ void PAKBridge::build() {
PAKEntryReadStream rs = e.beginReadStream(m_node); PAKEntryReadStream rs = e.beginReadStream(m_node);
mlvl.read(rs); mlvl.read(rs);
} }
bool named; std::string catalogueName;
std::string bestName = m_pak.bestEntryName(m_node, e, named); std::string bestName = m_pak.bestEntryName(m_node, e, catalogueName);
level.name = hecl::SystemStringConv(bestName).sys_str(); level.name = hecl::SystemStringConv(bestName).sys_str();
level.areas.reserve(mlvl.areaCount); level.areas.reserve(mlvl.areaCount);
unsigned layerIdx = 0; unsigned layerIdx = 0;
@ -157,15 +157,13 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssoci
ANCS ancs; ANCS ancs;
ancs.read(rs); ancs.read(rs);
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) { for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) {
charAssoc.m_cmdlRigs[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf); charAssoc.m_cmdlRigs[ci.cmdl] = {ci.cskr, ci.cinf};
charAssoc.m_cskrCinfToCharacter[ci.cskr] = charAssoc.m_cskrToCharacter[ci.cskr] =
std::make_pair(entry.second.id, fmt::format(fmt("{}.CSKR"), ci.name)); std::make_pair(entry.second.id, fmt::format(fmt("{}_{}.CSKR"), ci.name, ci.cskr));
charAssoc.m_cskrCinfToCharacter[ci.cinf] =
std::make_pair(entry.second.id, fmt::format(fmt("CINF_{}.CINF"), ci.cinf));
if (ci.cmdlIce.isValid()) { if (ci.cmdlIce.isValid()) {
charAssoc.m_cmdlRigs[ci.cmdlIce] = std::make_pair(ci.cskrIce, ci.cinf); charAssoc.m_cmdlRigs[ci.cmdlIce] = {ci.cskrIce, ci.cinf};
charAssoc.m_cskrCinfToCharacter[ci.cskrIce] = charAssoc.m_cskrToCharacter[ci.cskrIce] =
std::make_pair(entry.second.id, fmt::format(fmt("{}.ICE.CSKR"), ci.name)); std::make_pair(entry.second.id, fmt::format(fmt("{}.ICE_{}.CSKR"), ci.name, ci.cskrIce));
} }
} }
} }
@ -187,12 +185,14 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath(); hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
if (mlvl.worldNameId.isValid()) if (mlvl.worldNameId.isValid())
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _SYS_STR("!name.yaml")); pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath,
fmt::format(fmt(_SYS_STR("!name_{}.yaml")), mlvl.worldNameId));
for (const MLVL::Area& area : mlvl.areas) { for (const MLVL::Area& area : mlvl.areas) {
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
if (area.areaNameId.isValid()) if (area.areaNameId.isValid())
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _SYS_STR("!name.yaml")); pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath,
fmt::format(fmt(_SYS_STR("!name_{}.yaml")), area.areaNameId));
} }
if (mlvl.worldMap.isValid()) { if (mlvl.worldMap.isValid()) {

View File

@ -145,8 +145,8 @@ void MREA::StreamReader::writeDecompInfos(athena::io::IStreamWriter& writer) con
bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, PAKRouter<PAKBridge>& pakRouter, const DNAMP2::PAK::Entry& entry, bool force,
hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)>) { hecl::blender::Token& btok, std::function<void(const hecl::SystemChar*)>) {
using RigPair = std::pair<CSKR*, CINF*>; using RigPair = std::pair<std::pair<UniqueID32, CSKR*>, std::pair<UniqueID32, CINF*>>;
RigPair dummy(nullptr, nullptr); RigPair dummy = {};
if (!force && outPath.isFile()) if (!force && outPath.isFile())
return true; return true;

View File

@ -3,18 +3,18 @@
namespace DataSpec::DNAMP2 { namespace DataSpec::DNAMP2 {
std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, bool& named) const { std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const {
std::unordered_map<UniqueID32, Entry>::const_iterator search; std::unordered_map<UniqueID32, Entry>::const_iterator search;
if (entry.type == FOURCC('AGSC') && (search = m_entries.find(entry.id)) != m_entries.cend()) { if (entry.type == FOURCC('AGSC') && (search = m_entries.find(entry.id)) != m_entries.cend()) {
/* Use internal AGSC name for entry */ /* Use internal AGSC name for entry */
auto rs = search->second.beginReadStream(pakNode); auto rs = search->second.beginReadStream(pakNode);
AGSC::Header header; AGSC::Header header;
header.read(rs); header.read(rs);
named = true; catalogueName = header.groupName;
return header.groupName; return fmt::format(fmt("{}_{}"), header.groupName, entry.id);
} }
return DNAMP1::PAK::bestEntryName(pakNode, entry, named); return DNAMP1::PAK::bestEntryName(pakNode, entry, catalogueName);
} }
} // namespace DataSpec::DNAMP2 } // namespace DataSpec::DNAMP2

View File

@ -7,7 +7,7 @@ namespace DataSpec::DNAMP2 {
/* Same PAK format as MP1 */ /* Same PAK format as MP1 */
struct PAK : DNAMP1::PAK { struct PAK : DNAMP1::PAK {
using DNAMP1::PAK::PAK; using DNAMP1::PAK::PAK;
std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, bool& named) const; std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const;
}; };
} // namespace DataSpec::DNAMP2 } // namespace DataSpec::DNAMP2

View File

@ -152,7 +152,7 @@ void STRG::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
/* Validate Pass */ /* Validate Pass */
if (root->m_type == YAML_MAPPING_NODE) { if (root->m_type == YAML_MAPPING_NODE) {
for (const auto& lang : root->m_mapChildren) { for (const auto& lang : root->m_mapChildren) {
if (!lang.first.compare("names")) if (lang.first == "names")
continue; continue;
if (lang.first.size() != 4) { if (lang.first.size() != 4) {
Log.report(logvisor::Warning, fmt("STRG language string '{}' must be exactly 4 characters; skipping"), lang.first); Log.report(logvisor::Warning, fmt("STRG language string '{}' must be exactly 4 characters; skipping"), lang.first);
@ -198,18 +198,18 @@ void STRG::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
template <> template <>
void STRG::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) { void STRG::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
for (const auto& lang : langs) { for (const auto& lang : langs) {
if (auto v = writer.enterSubVector(lang.first.toString().c_str())) if (auto v = writer.enterSubVector(lang.first.toString()))
for (const std::u16string& str : lang.second) for (const std::u16string& str : lang.second)
writer.writeU16String(nullptr, str); writer.writeU16String(str);
} }
if (names.size()) { if (names.size()) {
if (auto rec = writer.enterSubRecord("names")) if (auto rec = writer.enterSubRecord("names"))
for (const auto& name : names) for (const auto& name : names)
if (auto rec = writer.enterSubRecord(name.first.c_str())) if (auto rec = writer.enterSubRecord(name.first))
writer.writeInt32(nullptr, name.second); writer.writeInt32(name.second);
} }
} }
const char* STRG::DNAType() { return "urde::DNAMP2::STRG"; } std::string_view STRG::DNAType() { return "urde::DNAMP2::STRG"sv; }
} // namespace DataSpec::DNAMP2 } // namespace DataSpec::DNAMP2

View File

@ -155,7 +155,7 @@ void ANIM::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s) {
m_anim->binarySize(s); m_anim->binarySize(s);
} }
const char* ANIM::ANIM0::DNAType() { return "ANIM0"; } std::string_view ANIM::ANIM0::DNAType() { return "ANIM0"sv; }
template <> template <>
void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) { void ANIM::ANIM0::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
@ -435,7 +435,7 @@ static float ComputeFrames(const std::vector<float>& keyTimes, std::vector<atUin
return mainInterval; return mainInterval;
} }
const char* ANIM::ANIM1::DNAType() { return "ANIM1"; } std::string_view ANIM::ANIM1::DNAType() { return "ANIM1"sv; }
template <> template <>
void ANIM::ANIM1::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) { void ANIM::ANIM1::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {

View File

@ -68,8 +68,8 @@ void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate<BigDNA::WriteYaml>(athena::i
writer.writeFloat("extraFloat", extraFloat); writer.writeFloat("extraFloat", extraFloat);
} }
const char* CHAR::AnimationInfo::EVNT::SFXEvent::DNAType() { std::string_view CHAR::AnimationInfo::EVNT::SFXEvent::DNAType() {
return "urde::DNAMP3::CHAR::AnimationInfo::EVNT::SFXEvent"; return "urde::DNAMP3::CHAR::AnimationInfo::EVNT::SFXEvent"sv;
} }
template <> template <>
@ -122,19 +122,19 @@ template <>
void CHAR::AnimationInfo::MetaAnimFactory::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) { void CHAR::AnimationInfo::MetaAnimFactory::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
std::string type = reader.readString("type"); std::string type = reader.readString("type");
std::transform(type.begin(), type.end(), type.begin(), tolower); std::transform(type.begin(), type.end(), type.begin(), tolower);
if (!type.compare("primitive")) { if (type == "primitive") {
m_anim.reset(new struct MetaAnimPrimitive); m_anim.reset(new struct MetaAnimPrimitive);
m_anim->read(reader); m_anim->read(reader);
} else if (!type.compare("blend")) { } else if (type == "blend") {
m_anim.reset(new struct MetaAnimBlend); m_anim.reset(new struct MetaAnimBlend);
m_anim->read(reader); m_anim->read(reader);
} else if (!type.compare("phaseblend")) { } else if (type == "phaseblend") {
m_anim.reset(new struct MetaAnimPhaseBlend); m_anim.reset(new struct MetaAnimPhaseBlend);
m_anim->read(reader); m_anim->read(reader);
} else if (!type.compare("random")) { } else if (type == "random") {
m_anim.reset(new struct MetaAnimRandom); m_anim.reset(new struct MetaAnimRandom);
m_anim->read(reader); m_anim->read(reader);
} else if (!type.compare("sequence")) { } else if (type == "sequence") {
m_anim.reset(new struct MetaAnimSequence); m_anim.reset(new struct MetaAnimSequence);
m_anim->read(reader); m_anim->read(reader);
} else { } else {
@ -150,8 +150,8 @@ void CHAR::AnimationInfo::MetaAnimFactory::Enumerate<BigDNA::WriteYaml>(athena::
m_anim->write(writer); m_anim->write(writer);
} }
const char* CHAR::AnimationInfo::MetaAnimFactory::DNAType() { std::string_view CHAR::AnimationInfo::MetaAnimFactory::DNAType() {
return "urde::DNAMP3::CHAR::AnimationInfo::MetaAnimFactory"; return "urde::DNAMP3::CHAR::AnimationInfo::MetaAnimFactory"sv;
} }
} // namespace DataSpec::DNAMP3 } // namespace DataSpec::DNAMP3

View File

@ -7,22 +7,22 @@ bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>) { std::function<void(const hecl::SystemChar*)>) {
/* Check for RigPair */ /* Check for RigPair */
const typename CharacterAssociations<UniqueID64>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
CINF cinf; CINF cinf;
CSKR cskr; CSKR cskr;
std::pair<CSKR*, CINF*> loadRp(nullptr, nullptr); using RigPair = std::pair<std::pair<UniqueID64, CSKR*>, std::pair<UniqueID64, CINF*>>;
if (rp) { RigPair loadRp = {};
pakRouter.lookupAndReadDNA(rp->first, cskr); if (const typename CharacterAssociations<UniqueID64>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id)) {
pakRouter.lookupAndReadDNA(rp->second, cinf); pakRouter.lookupAndReadDNA(rp->cskr, cskr);
loadRp.first = &cskr; pakRouter.lookupAndReadDNA(rp->cinf, cinf);
loadRp.second = &cinf; loadRp.first = {rp->cskr, &cskr};
loadRp.second = {rp->cinf, &cinf};
} }
/* Do extract */ /* Do extract */
hecl::blender::Connection& conn = btok.getBlenderConnection(); hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh))
return false; return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*, CINF*>, DNACMDL::SurfaceHeader_3, 5>( DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, RigPair, DNACMDL::SurfaceHeader_3, 5>(
conn, rs, pakRouter, entry, dataSpec, loadRp); conn, rs, pakRouter, entry, dataSpec, loadRp);
return conn.saveBlend(); return conn.saveBlend();
} }

View File

@ -88,6 +88,7 @@ void MaterialSet::ConstructMaterial(Stream& out, const PAKRouter<PAKBridge>& pak
"new_material.use_transparent_shadows = True\n" "new_material.use_transparent_shadows = True\n"
"new_material.diffuse_color = (1.0,1.0,1.0)\n" "new_material.diffuse_color = (1.0,1.0,1.0)\n"
"new_material.use_nodes = True\n" "new_material.use_nodes = True\n"
"new_material.blend_method = 'BLEND'\n"
"new_nodetree = new_material.node_tree\n" "new_nodetree = new_material.node_tree\n"
"material_node = new_nodetree.nodes['Material']\n" "material_node = new_nodetree.nodes['Material']\n"
"final_node = new_nodetree.nodes['Output']\n" "final_node = new_nodetree.nodes['Output']\n"
@ -116,10 +117,17 @@ void MaterialSet::ConstructMaterial(Stream& out, const PAKRouter<PAKBridge>& pak
material.header.flags.shadowOccluderMesh() ? "0" : "1"); material.header.flags.shadowOccluderMesh() ? "0" : "1");
/* Blend factors */ /* Blend factors */
out << "blend_node = new_nodetree.nodes.new('ShaderNodeGroup')\n"
"blend_node.name = 'Blend'\n"
"gridder.place_node(blend_node, 2)\n";
if (material.header.flags.alphaBlending()) if (material.header.flags.alphaBlending())
out << "new_material.blend_method = 'BLEND'\n"; out << "blend_node.node_tree = bpy.data.node_groups['HECLBlendOutput']\n";
else if (material.header.flags.additiveBlending()) else if (material.header.flags.additiveBlending())
out << "new_material.blend_method = 'ADD'\n"; out << "blend_node.node_tree = bpy.data.node_groups['HECLAdditiveOutput']\n";
else {
out << "blend_node.node_tree = bpy.data.node_groups['HECLOpaqueOutput']\n"
"new_material.blend_method = 'OPAQUE'\n";
}
/* Texmap list */ /* Texmap list */
out << "tex_maps = []\n" out << "tex_maps = []\n"

View File

@ -79,8 +79,8 @@ void PAKBridge::build() {
PAKEntryReadStream rs = entry.beginReadStream(m_node); PAKEntryReadStream rs = entry.beginReadStream(m_node);
mlvl.read(rs); mlvl.read(rs);
} }
bool named; std::string catalogueName;
std::string bestName = m_pak.bestEntryName(m_node, entry, named); std::string bestName = m_pak.bestEntryName(m_node, entry, catalogueName);
level.name = hecl::SystemStringConv(bestName).sys_str(); level.name = hecl::SystemStringConv(bestName).sys_str();
level.areas.reserve(mlvl.areaCount); level.areas.reserve(mlvl.areaCount);
unsigned layerIdx = 0; unsigned layerIdx = 0;
@ -163,15 +163,13 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssoci
CHAR aChar; CHAR aChar;
aChar.read(rs); aChar.read(rs);
const CHAR::CharacterInfo& ci = aChar.characterInfo; const CHAR::CharacterInfo& ci = aChar.characterInfo;
charAssoc.m_cmdlRigs[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf); charAssoc.m_cmdlRigs[ci.cmdl] = {ci.cskr, ci.cinf};
charAssoc.m_cskrCinfToCharacter[ci.cskr] = charAssoc.m_cskrToCharacter[ci.cskr] =
std::make_pair(entry.second.id, fmt::format(fmt("{}.CSKR"), ci.name)); std::make_pair(entry.second.id, fmt::format(fmt("{}_{}.CSKR"), ci.name, ci.cskr));
charAssoc.m_cskrCinfToCharacter[ci.cinf] =
std::make_pair(entry.second.id, fmt::format(fmt("CINF_{}.CINF"), ci.cinf));
for (const CHAR::CharacterInfo::Overlay& overlay : ci.overlays) { for (const CHAR::CharacterInfo::Overlay& overlay : ci.overlays) {
charAssoc.m_cmdlRigs[overlay.cmdl] = std::make_pair(overlay.cskr, ci.cinf); charAssoc.m_cmdlRigs[overlay.cmdl] = {overlay.cskr, ci.cinf};
charAssoc.m_cskrCinfToCharacter[overlay.cskr] = charAssoc.m_cskrToCharacter[overlay.cskr] =
std::make_pair(entry.second.id, fmt::format(fmt("{}.{}.CSKR"), ci.name, overlay.type)); std::make_pair(entry.second.id, fmt::format(fmt("{}.{}_{}.CSKR"), ci.name, overlay.type, overlay.cskr));
} }
} }
} }
@ -192,12 +190,14 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath(); hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
if (mlvl.worldNameId.isValid()) if (mlvl.worldNameId.isValid())
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _SYS_STR("!name.yaml")); pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath,
fmt::format(fmt(_SYS_STR("!name_{}.yaml")), mlvl.worldNameId));
for (const MLVL::Area& area : mlvl.areas) { for (const MLVL::Area& area : mlvl.areas) {
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
if (area.areaNameId.isValid()) if (area.areaNameId.isValid())
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _SYS_STR("!name.yaml")); pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath,
fmt::format(fmt(_SYS_STR("!name_{}.yaml")), area.areaNameId));
} }
if (mlvl.worldMap.isValid()) { if (mlvl.worldMap.isValid()) {

View File

@ -59,8 +59,8 @@ void MREA::ReadBabeDeadToBlender_3(hecl::blender::PyOutStream& os, athena::io::I
bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok,
std::function<void(const hecl::SystemChar*)>) { std::function<void(const hecl::SystemChar*)>) {
using RigPair = std::pair<CSKR*, CINF*>; using RigPair = std::pair<std::pair<UniqueID64, CSKR*>, std::pair<UniqueID64, CINF*>>;
RigPair dummy(nullptr, nullptr); RigPair dummy = {};
if (!force && outPath.isFile()) if (!force && outPath.isFile())
return true; return true;

View File

@ -215,17 +215,16 @@ const PAK::Entry* PAK::lookupEntry(std::string_view name) const {
return nullptr; return nullptr;
} }
std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, bool& named) const { std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const {
/* Prefer named entries first */ /* Prefer named entries first */
for (const NameEntry& nentry : m_nameEntries) for (const NameEntry& nentry : m_nameEntries)
if (nentry.id == entry.id) { if (nentry.id == entry.id) {
named = true; catalogueName = nentry.name;
return nentry.name; return fmt::format(fmt("{}_{}"), nentry.name, entry.id);
} }
/* Otherwise return ID format string */ /* Otherwise return ID format string */
named = false; return fmt::format(fmt("{}_{}"), entry.type, entry.id);
return entry.type.toString() + '_' + entry.id.toString();
} }
} // namespace DataSpec::DNAMP3 } // namespace DataSpec::DNAMP3

View File

@ -57,7 +57,7 @@ struct PAK : BigDNA {
const Entry* lookupEntry(const UniqueID64& id) const; const Entry* lookupEntry(const UniqueID64& id) const;
const Entry* lookupEntry(std::string_view name) const; const Entry* lookupEntry(std::string_view name) const;
std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, bool& named) const; std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const;
bool mreaHasDupeResources(const UniqueID64& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); } bool mreaHasDupeResources(const UniqueID64& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); }

View File

@ -79,7 +79,7 @@ void STRG::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
/* Validate Pass */ /* Validate Pass */
if (root->m_type == YAML_MAPPING_NODE) { if (root->m_type == YAML_MAPPING_NODE) {
for (const auto& lang : root->m_mapChildren) { for (const auto& lang : root->m_mapChildren) {
if (!lang.first.compare("names")) if (lang.first == "names")
continue; continue;
if (lang.first.size() != 4) { if (lang.first.size() != 4) {
Log.report(logvisor::Warning, fmt("STRG language string '{}' must be exactly 4 characters; skipping"), lang.first); Log.report(logvisor::Warning, fmt("STRG language string '{}' must be exactly 4 characters; skipping"), lang.first);
@ -111,7 +111,7 @@ void STRG::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
langs.clear(); langs.clear();
langs.reserve(root->m_mapChildren.size()); langs.reserve(root->m_mapChildren.size());
for (const auto& item : root->m_mapChildren) { for (const auto& item : root->m_mapChildren) {
if (!item.first.compare("names") || item.first.size() != 4 || item.second->m_type != YAML_SEQUENCE_NODE) if (item.first == "names" || item.first.size() != 4 || item.second->m_type != YAML_SEQUENCE_NODE)
continue; continue;
std::vector<std::string> strs; std::vector<std::string> strs;
@ -207,19 +207,19 @@ void STRG::Enumerate<BigDNA::BinarySize>(size_t& __isz) {
template <> template <>
void STRG::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) { void STRG::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
for (const auto& item : langs) { for (const auto& item : langs) {
if (auto v = writer.enterSubVector(item.first.toString().c_str())) if (auto v = writer.enterSubVector(item.first.toString()))
for (const std::string& str : item.second) for (const std::string& str : item.second)
writer.writeString(nullptr, str); writer.writeString(str);
} }
if (names.size()) { if (names.size()) {
if (auto rec = writer.enterSubRecord("names")) if (auto rec = writer.enterSubRecord("names"))
for (const auto& item : names) for (const auto& item : names)
if (auto rec = writer.enterSubRecord(item.first.c_str())) if (auto rec = writer.enterSubRecord(item.first))
writer.writeInt32(nullptr, item.second); writer.writeInt32(item.second);
} }
} }
const char* STRG::DNAType() { return "urde::DNAMP3::STRG"; } std::string_view STRG::DNAType() { return "urde::DNAMP3::STRG"sv; }
} // namespace DataSpec::DNAMP3 } // namespace DataSpec::DNAMP3

View File

@ -56,66 +56,6 @@ static const hecl::SystemString regP = _SYS_STR("PAL");
void SpecBase::setThreadProject() { UniqueIDBridge::SetThreadProject(m_project); } void SpecBase::setThreadProject() { UniqueIDBridge::SetThreadProject(m_project); }
template <typename IDType>
IDRestorer<IDType>::IDRestorer(const hecl::ProjectPath& yamlPath, const hecl::Database::Project& project) {
using ValType = typename IDType::value_type;
if (!yamlPath.isFile())
return;
athena::io::YAMLDocReader r;
athena::io::FileReader fr(yamlPath.getAbsolutePath());
if (!fr.isOpen() || !r.parse(&fr))
return;
m_newToOrig.reserve(r.getRootNode()->m_mapChildren.size());
m_origToNew.reserve(r.getRootNode()->m_mapChildren.size());
for (const auto& node : r.getRootNode()->m_mapChildren) {
char* end = const_cast<char*>(node.first.c_str());
ValType id = strtoull(end, &end, 16);
if (end != node.first.c_str() + sizeof(ValType) * 2)
continue;
hecl::ProjectPath path(project.getProjectWorkingPath(), node.second->m_scalarString.c_str());
m_newToOrig.push_back(std::make_pair(IDType{path.hash().valT<ValType>(), true}, IDType{id, true}));
m_origToNew.push_back(std::make_pair(IDType{id, true}, IDType{path.hash().valT<ValType>(), true}));
}
std::sort(m_newToOrig.begin(), m_newToOrig.end(),
[](const std::pair<IDType, IDType>& a, const std::pair<IDType, IDType>& b)
{ return a.first.toUint64() < b.first.toUint64(); });
std::sort(m_origToNew.begin(), m_origToNew.end(),
[](const std::pair<IDType, IDType>& a, const std::pair<IDType, IDType>& b)
{ return a.first.toUint64() < b.first.toUint64(); });
Log.report(logvisor::Info, fmt(_SYS_STR("Loaded Original IDs '{}'")), yamlPath.getRelativePath());
}
template <typename IDType>
IDType IDRestorer<IDType>::newToOriginal(IDType id) const {
if (!id.isValid())
return {};
auto search =
rstl::binary_find(m_newToOrig.cbegin(), m_newToOrig.cend(), id, [](const auto& id) { return id.first; });
if (search == m_newToOrig.cend())
return {};
return search->second;
}
template <typename IDType>
IDType IDRestorer<IDType>::originalToNew(IDType id) const {
if (!id.isValid())
return {};
auto search =
rstl::binary_find(m_origToNew.cbegin(), m_origToNew.cend(), id, [](const auto& id) { return id.first; });
if (search == m_origToNew.cend())
return {};
return search->second;
}
template class IDRestorer<UniqueID32>;
template class IDRestorer<UniqueID64>;
template class IDRestorer<UniqueID128>;
bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps) { bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps) {
m_disc = nod::OpenDiscFromImage(info.srcpath, m_isWii); m_disc = nod::OpenDiscFromImage(info.srcpath, m_isWii);
if (!m_disc) if (!m_disc)
@ -186,12 +126,11 @@ bool IsPathAudioGroup(const hecl::ProjectPath& path) {
} }
static bool IsPathSong(const hecl::ProjectPath& path) { static bool IsPathSong(const hecl::ProjectPath& path) {
if (path.getPathType() != hecl::ProjectPath::Type::Glob || !path.getWithExtension(_SYS_STR(".mid"), true).isFile() || if (path.getPathType() != hecl::ProjectPath::Type::Glob ||
!path.getWithExtension(_SYS_STR(".mid"), true).isFile() ||
!path.getWithExtension(_SYS_STR(".yaml"), true).isFile()) { !path.getWithExtension(_SYS_STR(".yaml"), true).isFile()) {
if (path.isFile() && !hecl::StrCmp(_SYS_STR("mid"), path.getLastComponentExt().data()) && return path.isFile() && path.getLastComponentExt() == _SYS_STR("mid") &&
path.getWithExtension(_SYS_STR(".yaml"), true).isFile()) path.getWithExtension(_SYS_STR(".yaml"), true).isFile();
return true;
return false;
} }
return true; return true;
} }
@ -280,6 +219,11 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co
cookColMesh(cookedPath, path, ds, fast, btok, progress); cookColMesh(cookedPath, path, ds, fast, btok, progress);
break; break;
} }
case hecl::blender::BlendType::Armature: {
hecl::blender::DataStream ds = conn.beginData();
cookArmature(cookedPath, path, ds, fast, btok, progress);
break;
}
case hecl::blender::BlendType::PathMesh: { case hecl::blender::BlendType::PathMesh: {
hecl::blender::DataStream ds = conn.beginData(); hecl::blender::DataStream ds = conn.beginData();
cookPathMesh(cookedPath, path, ds, fast, btok, progress); cookPathMesh(cookedPath, path, ds, fast, btok, progress);
@ -325,7 +269,7 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co
TXTR::Cook(path, cookedPath); TXTR::Cook(path, cookedPath);
} else if (hecl::IsPathYAML(path)) { } else if (hecl::IsPathYAML(path)) {
athena::io::FileReader reader(path.getAbsolutePath()); athena::io::FileReader reader(path.getAbsolutePath());
cookYAML(cookedPath, path, reader, progress); cookYAML(cookedPath, path, reader, btok, progress);
} else if (IsPathAudioGroup(path)) { } else if (IsPathAudioGroup(path)) {
cookAudioGroup(cookedPath, path, progress); cookAudioGroup(cookedPath, path, progress);
} else if (IsPathSong(path)) { } else if (IsPathSong(path)) {
@ -348,6 +292,8 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
} }
case hecl::blender::BlendType::Actor: { case hecl::blender::BlendType::Actor: {
hecl::ProjectPath asGlob = in.getWithExtension(_SYS_STR(".*"), true); hecl::ProjectPath asGlob = in.getWithExtension(_SYS_STR(".*"), true);
hecl::ProjectPath parentPath = asGlob.getParentPath();
hecl::DirectoryEnumerator dEnum(parentPath.getAbsolutePath());
hecl::blender::DataStream ds = conn.beginData(); hecl::blender::DataStream ds = conn.beginData();
hecl::blender::Actor actor = ds.compileActorCharacterOnly(); hecl::blender::Actor actor = ds.compileActorCharacterOnly();
auto actNames = ds.getActionNames(); auto actNames = ds.getActionNames();
@ -361,19 +307,20 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
} }
hecl::SystemStringConv chSysName(sub.name); hecl::SystemStringConv chSysName(sub.name);
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(chSysName.sys_str()) + _SYS_STR(".CSKR"))); pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.CSKR")), chSysName, sub.cskrId)));
const auto& arm = actor.armatures[sub.armature]; const auto& arm = actor.armatures[sub.armature];
hecl::SystemStringConv armSysName(arm.name); if (hecl::IsPathBlend(arm.path))
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(armSysName.sys_str()) + _SYS_STR(".CINF"))); pathsOut.push_back(arm.path);
for (const auto& overlay : sub.overlayMeshes) { for (const auto& overlay : sub.overlayMeshes) {
hecl::SystemStringConv ovelaySys(overlay.first); hecl::SystemStringConv overlaySys(overlay.name);
if (hecl::IsPathBlend(overlay.second)) { if (hecl::IsPathBlend(overlay.mesh)) {
flattenDependenciesBlend(overlay.second, pathsOut, btok); flattenDependenciesBlend(overlay.mesh, pathsOut, btok);
pathsOut.push_back(overlay.second); pathsOut.push_back(overlay.mesh);
} }
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(chSysName.sys_str()) + _SYS_STR('.') + pathsOut.push_back(asGlob.ensureAuxInfo(
ovelaySys.c_str() + _SYS_STR(".CSKR"))); fmt::format(fmt(_SYS_STR("{}.{}_{}.CSKR")), chSysName, overlaySys, overlay.cskrId)));
} }
} }
}; };
@ -391,21 +338,29 @@ void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector
hecl::SystemStringConv chSysName(att.name); hecl::SystemStringConv chSysName(att.name);
pathsOut.push_back( pathsOut.push_back(
asGlob.ensureAuxInfo(hecl::SystemString(_SYS_STR("ATTACH.")) + chSysName.c_str() + _SYS_STR(".CSKR"))); asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("ATTACH.{}_{}.CSKR")), chSysName, att.cskrId)));
if (att.armature >= 0) { if (att.armature >= 0) {
const auto& arm = actor.armatures[att.armature]; const auto& arm = actor.armatures[att.armature];
hecl::SystemStringConv armSysName(arm.name); if (hecl::IsPathBlend(arm.path))
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(armSysName.sys_str()) + _SYS_STR(".CINF"))); pathsOut.push_back(arm.path);
} }
} }
for (const auto& act : actNames) { for (const auto& act : actNames) {
hecl::SystemStringConv actSysName(act); hecl::SystemStringConv actSysName(act.first);
pathsOut.push_back(asGlob.ensureAuxInfo(hecl::SystemString(actSysName.sys_str()) + _SYS_STR(".ANIM"))); hecl::SystemStringConv actAnimId(act.second);
hecl::ProjectPath evntPath = pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.ANIM")), actSysName, actAnimId)));
asGlob.ensureAuxInfo(hecl::SystemStringView{}) hecl::SystemString searchPrefix(asGlob.getWithExtension(
.getWithExtension(fmt::format(fmt(_SYS_STR(".{}.evnt.yaml")), actSysName).c_str(), true); fmt::format(fmt(_SYS_STR(".{}_")), actSysName).c_str(), true).getLastComponent());
hecl::ProjectPath evntPath;
for (const auto& ent : dEnum) {
if (hecl::StringUtils::BeginsWith(ent.m_name, searchPrefix.c_str()) &&
hecl::StringUtils::EndsWith(ent.m_name, _SYS_STR(".evnt.yaml"))) {
evntPath = hecl::ProjectPath(parentPath, ent.m_name);
break;
}
}
if (evntPath.isFile()) if (evntPath.isFile())
pathsOut.push_back(evntPath); pathsOut.push_back(evntPath);
} }
@ -518,19 +473,18 @@ void SpecBase::copyBuildListData(std::vector<std::tuple<size_t, size_t, bool>>&
hecl::SystemString str = fmt::format(fmt(_SYS_STR("Copying {}")), tag); hecl::SystemString str = fmt::format(fmt(_SYS_STR("Copying {}")), tag);
progress.print(str.c_str(), nullptr, ++loadIdx / float(buildList.size())); progress.print(str.c_str(), nullptr, ++loadIdx / float(buildList.size()));
fileIndex.emplace_back(); auto& [positionOut, sizeOut, compressedOut] = fileIndex.emplace_back();
auto& thisIdx = fileIndex.back();
if (tag.type == FOURCC('MLVL')) { if (tag.type == FOURCC('MLVL')) {
auto search = mlvlData.find(tag.id); auto search = mlvlData.find(tag.id);
if (search == mlvlData.end()) if (search == mlvlData.end())
Log.report(logvisor::Fatal, fmt(_SYS_STR("Unable to find MLVL {}")), tag.id); Log.report(logvisor::Fatal, fmt(_SYS_STR("Unable to find MLVL {}")), tag.id);
std::get<0>(thisIdx) = pakOut.position(); positionOut = pakOut.position();
std::get<1>(thisIdx) = ROUND_UP_32(search->second.size()); sizeOut = ROUND_UP_32(search->second.size());
std::get<2>(thisIdx) = false; compressedOut = false;
pakOut.writeUBytes(search->second.data(), search->second.size()); pakOut.writeUBytes(search->second.data(), search->second.size());
for (atUint64 i = search->second.size(); i < std::get<1>(thisIdx); ++i) for (atUint64 i = search->second.size(); i < sizeOut; ++i)
pakOut.writeUByte(0xff); pakOut.writeUByte(0xff);
continue; continue;
@ -545,25 +499,34 @@ void SpecBase::copyBuildListData(std::vector<std::tuple<size_t, size_t, bool>>&
auto data = r.readUBytes(size); auto data = r.readUBytes(size);
auto compData = compressPakData(tag, data.get(), size); auto compData = compressPakData(tag, data.get(), size);
if (compData.first) { if (compData.first) {
std::get<0>(thisIdx) = pakOut.position(); positionOut = pakOut.position();
std::get<1>(thisIdx) = ROUND_UP_32(compData.second + 4); sizeOut = ROUND_UP_32(compData.second + 4);
std::get<2>(thisIdx) = true; compressedOut = true;
pakOut.writeUint32Big(atUint32(size)); pakOut.writeUint32Big(atUint32(size));
pakOut.writeUBytes(compData.first.get(), compData.second); pakOut.writeUBytes(compData.first.get(), compData.second);
for (atUint64 i = compData.second + 4; i < std::get<1>(thisIdx); ++i) for (atUint64 i = compData.second + 4; i < sizeOut; ++i)
pakOut.writeUByte(0xff); pakOut.writeUByte(0xff);
} else { } else {
std::get<0>(thisIdx) = pakOut.position(); positionOut = pakOut.position();
std::get<1>(thisIdx) = ROUND_UP_32(size); sizeOut = ROUND_UP_32(size);
std::get<2>(thisIdx) = false; compressedOut = false;
pakOut.writeUBytes(data.get(), size); pakOut.writeUBytes(data.get(), size);
for (atUint64 i = size; i < std::get<1>(thisIdx); ++i) for (atUint64 i = size; i < sizeOut; ++i)
pakOut.writeUByte(0xff); pakOut.writeUByte(0xff);
} }
} }
progress.startNewLine(); progress.startNewLine();
} }
static bool IsWorldBlend(const hecl::ProjectPath& path) {
if (path.isFile()) {
auto lastComp = path.getLastComponent();
return hecl::StringUtils::BeginsWith(lastComp, _SYS_STR("!world_")) &&
hecl::StringUtils::EndsWith(lastComp, _SYS_STR(".blend"));
}
return false;
}
void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry, bool fast, void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry, bool fast,
hecl::blender::Token& btok, const hecl::MultiProgressPrinter& progress, hecl::blender::Token& btok, const hecl::MultiProgressPrinter& progress,
hecl::ClientProcess* cp) { hecl::ClientProcess* cp) {
@ -590,8 +553,7 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
atUint64 resTableOffset = 0; atUint64 resTableOffset = 0;
std::unordered_map<urde::CAssetId, std::vector<uint8_t>> mlvlData; std::unordered_map<urde::CAssetId, std::vector<uint8_t>> mlvlData;
if (path.getPathType() == hecl::ProjectPath::Type::File && if (IsWorldBlend(path)) /* World PAK */
!hecl::StrCmp(path.getLastComponent().data(), _SYS_STR("!world.blend"))) /* World PAK */
{ {
/* Force-cook MLVL and write resource list structure */ /* Force-cook MLVL and write resource list structure */
m_project.cookPath(path, progress, false, true, fast, entry, cp); m_project.cookPath(path, progress, false, true, fast, entry, cp);
@ -700,6 +662,25 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
void SpecBase::interruptCook() { cancelBackgroundIndex(); } void SpecBase::interruptCook() { cancelBackgroundIndex(); }
std::optional<hecl::blender::World> SpecBase::compileWorldFromDir(const hecl::ProjectPath& dir,
hecl::blender::Token& btok) const {
hecl::ProjectPath asBlend;
for (const auto& ent : hecl::DirectoryEnumerator(dir.getAbsolutePath())) {
if (hecl::StringUtils::BeginsWith(ent.m_name, _SYS_STR("!world_"))) {
asBlend = hecl::ProjectPath(dir, ent.m_name).getWithExtension(_SYS_STR(".blend"), true);
break;
}
}
if (hecl::IsPathBlend(asBlend)) {
hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.openBlend(asBlend))
return {};
hecl::blender::DataStream ds = conn.beginData();
return {ds.compileWorld()};
}
return {};
}
hecl::ProjectPath SpecBase::getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const { hecl::ProjectPath SpecBase::getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const {
const hecl::Database::DataSpecEntry* spec = &getOriginalSpec(); const hecl::Database::DataSpecEntry* spec = &getOriginalSpec();
if (pcTarget) if (pcTarget)
@ -872,11 +853,12 @@ void SpecBase::enumerateNamedResources(
static void WriteTag(athena::io::YAMLDocWriter& cacheWriter, const urde::SObjectTag& pathTag, static void WriteTag(athena::io::YAMLDocWriter& cacheWriter, const urde::SObjectTag& pathTag,
const hecl::ProjectPath& path) { const hecl::ProjectPath& path) {
if (auto v = cacheWriter.enterSubVector(fmt::format(fmt("{}"), pathTag.id).c_str())) { auto key = fmt::format(fmt("{}"), pathTag.id);
cacheWriter.writeString(nullptr, pathTag.type.toString().c_str()); if (auto* existing = cacheWriter.getCurNode()->findMapChild(key)) {
cacheWriter.writeString(nullptr, path.getAuxInfo().size() ? (std::string(path.getRelativePathUTF8()) + '|' + existing->m_seqChildren.emplace_back(athena::io::ValToNode(path.getEncodableStringUTF8()));
path.getAuxInfoUTF8().data()) } else if (auto v = cacheWriter.enterSubVector(key)) {
: path.getRelativePathUTF8()); cacheWriter.writeString(pathTag.type.toString());
cacheWriter.writeString(path.getEncodableStringUTF8());
} }
} }
@ -947,7 +929,7 @@ void SpecBase::backgroundIndexRecursiveCatalogs(const hecl::ProjectPath& dir, at
continue; continue;
/* Read catalog.yaml for .pak directory if exists */ /* Read catalog.yaml for .pak directory if exists */
if (level == 1 && !ent.m_name.compare(_SYS_STR("!catalog.yaml"))) { if (level == 1 && ent.m_name == _SYS_STR("!catalog.yaml")) {
readCatalog(path, nameWriter); readCatalog(path, nameWriter);
continue; continue;
} }
@ -959,11 +941,27 @@ void SpecBase::backgroundIndexRecursiveCatalogs(const hecl::ProjectPath& dir, at
} }
} }
#if DUMP_CACHE_FILL void SpecBase::insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const urde::SObjectTag& tag,
static void DumpCacheAdd(const urde::SObjectTag& pathTag, const hecl::ProjectPath& path) { const hecl::ProjectPath& path, bool dump) {
fmt::print(stderr, fmt("{} {}\n"), pathTag, path.getRelativePathUTF8()); #if 0
} auto search = m_tagToPath.find(tag);
/* ANCS subresources are allowed to be weak-linked */
if (search != m_tagToPath.end() && search->second != path &&
tag.type != FOURCC('CINF') && tag.type != FOURCC('CSKR') &&
tag.type != FOURCC('ANIM') && tag.type != FOURCC('EVNT')) {
Log.report(logvisor::Fatal, fmt(_SYS_STR("'{}|{}' already exists for tag {} as '{}|{}'")),
path.getRelativePath(), path.getAuxInfo(), tag,
search->second.getRelativePath(), search->second.getAuxInfo());
}
#endif #endif
m_tagToPath.insert(std::make_pair(tag, path));
m_pathToTag[path.hash()] = tag;
WriteTag(cacheWriter, tag, path);
#if DUMP_CACHE_FILL
if (dump)
fmt::print(stderr, fmt("{} {}\n"), tag, path.getRelativePathUTF8());
#endif
}
bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter) { bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter) {
/* Avoid redundant filesystem access for re-caches */ /* Avoid redundant filesystem access for re-caches */
@ -988,109 +986,49 @@ bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDoc
return false; return false;
/* Transform tag to glob */ /* Transform tag to glob */
pathTag = {SBIG('ANCS'), asGlob.hash().val32()}; pathTag = {SBIG('ANCS'), asGlob.parsedHash32()};
useGlob = true; useGlob = true;
hecl::blender::DataStream ds = conn.beginData(); hecl::blender::DataStream ds = conn.beginData();
std::vector<std::string> armatureNames = ds.getArmatureNames(); std::vector<std::pair<std::string, std::string>> subtypeNames = ds.getSubtypeNames();
std::vector<std::string> subtypeNames = ds.getSubtypeNames(); std::vector<std::pair<std::string, std::string>> actionNames = ds.getActionNames();
std::vector<std::string> actionNames = ds.getActionNames();
for (const std::string& arm : armatureNames) { for (const auto& sub : subtypeNames) {
hecl::SystemStringConv sysStr(arm); hecl::SystemStringConv subName(sub.first);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".CINF")); hecl::SystemStringConv cskrId(sub.second);
urde::SObjectTag pathTag = buildTagFromPath(subPath); hecl::ProjectPath subPath = asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.CSKR")), subName, cskrId));
m_tagToPath[pathTag] = subPath; insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
}
for (const std::string& sub : subtypeNames) { std::vector<std::pair<std::string, std::string>> overlayNames = ds.getSubtypeOverlayNames(sub.first);
hecl::SystemStringConv sysStr(sub);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".CSKR"));
urde::SObjectTag pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
std::vector<std::string> overlayNames = ds.getSubtypeOverlayNames(sub);
for (const auto& overlay : overlayNames) { for (const auto& overlay : overlayNames) {
hecl::SystemStringConv overlaySys(overlay); hecl::SystemStringConv overlaySys(overlay.first);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR('.') + hecl::SystemStringConv overlayCskrId(overlay.second);
overlaySys.c_str() + _SYS_STR(".CSKR")); hecl::ProjectPath subPath = asGlob.ensureAuxInfo(
urde::SObjectTag pathTag = buildTagFromPath(subPath); fmt::format(fmt(_SYS_STR("{}.{}_{}.CSKR")), subName, overlaySys, overlayCskrId));
m_tagToPath[pathTag] = subPath; insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
} }
} }
std::vector<std::string> attachmentNames = ds.getAttachmentNames(); std::vector<std::pair<std::string, std::string>> attachmentNames = ds.getAttachmentNames();
for (const auto& attachment : attachmentNames) { for (const auto& attachment : attachmentNames) {
hecl::SystemStringConv attachmentSys(attachment); hecl::SystemStringConv attachmentSys(attachment.first);
hecl::SystemStringConv attachmentCskrId(attachment.second);
hecl::ProjectPath subPath = hecl::ProjectPath subPath =
asGlob.ensureAuxInfo(hecl::SystemString(_SYS_STR("ATTACH.")) + attachmentSys.c_str() + _SYS_STR(".CSKR")); asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("ATTACH.{}_{}.CSKR")), attachmentSys, attachmentCskrId));
urde::SObjectTag pathTag = buildTagFromPath(subPath); insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
} }
for (const std::string& act : actionNames) { for (const auto& act : actionNames) {
hecl::SystemStringConv sysStr(act); hecl::SystemStringConv sysStr(act.first);
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(hecl::SystemString(sysStr.sys_str()) + _SYS_STR(".ANIM")); hecl::SystemStringConv animId(act.second);
urde::SObjectTag pathTag = buildTagFromPath(subPath); hecl::ProjectPath subPath = asGlob.ensureAuxInfo(fmt::format(fmt(_SYS_STR("{}_{}.ANIM")), sysStr, animId));
m_tagToPath[pathTag] = subPath; insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath);
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
} }
} else if (pathTag.type == SBIG('MLVL')) {
/* Transform tag to glob */
pathTag = {SBIG('MLVL'), asGlob.hash().val32()};
useGlob = true;
hecl::ProjectPath subPath = asGlob.ensureAuxInfo(_SYS_STR("MAPW"));
urde::SObjectTag pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
subPath = asGlob.ensureAuxInfo(_SYS_STR("SAVW"));
pathTag = buildTagFromPath(subPath);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
} }
/* Cache in-memory */ /* Cache in-memory */
const hecl::ProjectPath& usePath = useGlob ? asGlob : path; const hecl::ProjectPath& usePath = useGlob ? asGlob : path;
m_tagToPath[pathTag] = usePath; insertPathTag(cacheWriter, pathTag, usePath);
m_pathToTag[usePath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, usePath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, usePath);
#endif
} }
return true; return true;
@ -1111,10 +1049,11 @@ void SpecBase::backgroundIndexRecursiveProc(const hecl::ProjectPath& dir, athena
if (ent.m_isDir) { if (ent.m_isDir) {
/* Index AGSC here */ /* Index AGSC here */
if (hecl::ProjectPath(path, "!project.yaml").isFile() && hecl::ProjectPath(path, "!pool.yaml").isFile()) { if (hecl::ProjectPath(path, "!project.yaml").isFile() && hecl::ProjectPath(path, "!pool.yaml").isFile()) {
urde::SObjectTag pathTag(SBIG('AGSC'), path.hash().val32()); /* Avoid redundant filesystem access for re-caches */
m_tagToPath[pathTag] = path; if (m_pathToTag.find(path.hash()) == m_pathToTag.cend()) {
m_pathToTag[path.hash()] = pathTag; urde::SObjectTag pathTag(SBIG('AGSC'), path.parsedHash32());
WriteTag(cacheWriter, pathTag, path); insertPathTag(cacheWriter, pathTag, path);
}
} else { } else {
backgroundIndexRecursiveProc(path, cacheWriter, nameWriter, level + 1); backgroundIndexRecursiveProc(path, cacheWriter, nameWriter, level + 1);
} }
@ -1123,7 +1062,7 @@ void SpecBase::backgroundIndexRecursiveProc(const hecl::ProjectPath& dir, athena
continue; continue;
/* Read catalog.yaml for .pak directory if exists */ /* Read catalog.yaml for .pak directory if exists */
if (level == 1 && !ent.m_name.compare(_SYS_STR("!catalog.yaml"))) { if (level == 1 && ent.m_name == _SYS_STR("!catalog.yaml")) {
readCatalog(path, nameWriter); readCatalog(path, nameWriter);
continue; continue;
} }
@ -1142,8 +1081,8 @@ void SpecBase::backgroundIndexProc() {
hecl::ProjectPath specRoot(m_project.getProjectWorkingPath(), getOriginalSpec().m_name); hecl::ProjectPath specRoot(m_project.getProjectWorkingPath(), getOriginalSpec().m_name);
/* Cache will be overwritten with validated entries afterwards */ /* Cache will be overwritten with validated entries afterwards */
athena::io::YAMLDocWriter cacheWriter(nullptr); athena::io::YAMLDocWriter cacheWriter;
athena::io::YAMLDocWriter nameWriter(nullptr); athena::io::YAMLDocWriter nameWriter;
/* Read in tag cache */ /* Read in tag cache */
if (tagCachePath.isFile()) { if (tagCachePath.isFile()) {
@ -1162,15 +1101,15 @@ void SpecBase::backgroundIndexProc() {
return; return;
const athena::io::YAMLNode& node = *child.second; const athena::io::YAMLNode& node = *child.second;
unsigned long id = strtoul(child.first.c_str(), nullptr, 16); if (node.m_seqChildren.size() >= 2) {
hecl::FourCC type(node.m_seqChildren.at(0)->m_scalarString.c_str()); unsigned long id = strtoul(child.first.c_str(), nullptr, 16);
hecl::ProjectPath path(m_project.getProjectWorkingPath(), node.m_seqChildren.at(1)->m_scalarString); hecl::FourCC type(node.m_seqChildren[0]->m_scalarString.c_str());
if (path.isFileOrGlob()) {
urde::SObjectTag pathTag(type, id); urde::SObjectTag pathTag(type, id);
m_tagToPath[pathTag] = path; for (auto I = node.m_seqChildren.begin() + 1, E = node.m_seqChildren.end(); I != E; ++I) {
m_pathToTag[path.hash()] = pathTag; hecl::ProjectPath path(m_project.getProjectWorkingPath(), (*I)->m_scalarString);
WriteTag(cacheWriter, pathTag, path); if (!path.isNone())
insertPathTag(cacheWriter, pathTag, path, false);
}
} }
++loadIdx; ++loadIdx;
@ -1209,14 +1148,6 @@ void SpecBase::backgroundIndexProc() {
} }
} }
/* Add special original IDs resource if exists (not name-cached to disk) */
hecl::ProjectPath oidsPath(specRoot, "!original_ids.yaml");
urde::SObjectTag oidsTag = buildTagFromPath(oidsPath);
if (oidsTag) {
m_catalogNameToTag["mp1originalids"] = oidsTag;
m_catalogTagToNames[oidsTag].insert("MP1OriginalIDs");
}
Log.report(logvisor::Info, fmt(_SYS_STR("Background index of '{}' started")), getOriginalSpec().m_name); Log.report(logvisor::Info, fmt(_SYS_STR("Background index of '{}' started")), getOriginalSpec().m_name);
backgroundIndexRecursiveProc(specRoot, cacheWriter, nameWriter, 0); backgroundIndexRecursiveProc(specRoot, cacheWriter, nameWriter, 0);

View File

@ -19,34 +19,24 @@ class YAMLDocWriter;
namespace DataSpec { namespace DataSpec {
template <typename IDType>
class IDRestorer {
std::vector<std::pair<IDType, IDType>> m_newToOrig;
std::vector<std::pair<IDType, IDType>> m_origToNew;
public:
IDRestorer(const hecl::ProjectPath& yamlPath, const hecl::Database::Project& project);
IDType newToOriginal(IDType id) const;
IDType originalToNew(IDType id) const;
};
struct SpecBase : hecl::Database::IDataSpec { struct SpecBase : hecl::Database::IDataSpec {
/* HECL Adaptors */ /* HECL Adaptors */
void setThreadProject(); void setThreadProject() override;
bool canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps); bool canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps) override;
void doExtract(const ExtractPassInfo& info, const hecl::MultiProgressPrinter& progress); void doExtract(const ExtractPassInfo& info, const hecl::MultiProgressPrinter& progress) override;
bool canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok); bool canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok) override;
const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path,
const hecl::Database::DataSpecEntry* oldEntry) const; const hecl::Database::DataSpecEntry* oldEntry) const override;
void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, hecl::blender::Token& btok, void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, hecl::blender::Token& btok,
FCookProgress progress); FCookProgress progress) override;
bool canPackage(const hecl::ProjectPath& path); bool canPackage(const hecl::ProjectPath& path) override;
void doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry, bool fast, void doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry, bool fast,
hecl::blender::Token& btok, const hecl::MultiProgressPrinter& progress, hecl::ClientProcess* cp); hecl::blender::Token& btok, const hecl::MultiProgressPrinter& progress,
hecl::ClientProcess* cp) override;
void interruptCook(); void interruptCook() override;
/* Extract handlers */ /* Extract handlers */
virtual bool checkStandaloneID(const char* id) const = 0; virtual bool checkStandaloneID(const char* id) const = 0;
@ -72,9 +62,13 @@ struct SpecBase : hecl::Database::IDataSpec {
/* Pre-cook handlers */ /* Pre-cook handlers */
virtual bool validateYAMLDNAType(athena::io::IStreamReader& fp) const = 0; virtual bool validateYAMLDNAType(athena::io::IStreamReader& fp) const = 0;
std::optional<hecl::blender::World> compileWorldFromDir(const hecl::ProjectPath& dir,
hecl::blender::Token& btok) const;
/* Cook handlers */ /* Cook handlers */
using BlendStream = hecl::blender::DataStream; using BlendStream = hecl::blender::DataStream;
using Mesh = hecl::blender::Mesh; using Mesh = hecl::blender::Mesh;
using Armature = hecl::blender::Armature;
using ColMesh = hecl::blender::ColMesh; using ColMesh = hecl::blender::ColMesh;
using PathMesh = hecl::blender::PathMesh; using PathMesh = hecl::blender::PathMesh;
using Light = hecl::blender::Light; using Light = hecl::blender::Light;
@ -84,6 +78,8 @@ struct SpecBase : hecl::Database::IDataSpec {
hecl::blender::Token& btok, FCookProgress progress) = 0; hecl::blender::Token& btok, FCookProgress progress) = 0;
virtual void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, virtual void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) = 0; hecl::blender::Token& btok, FCookProgress progress) = 0;
virtual void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) = 0;
virtual void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, virtual void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) = 0; hecl::blender::Token& btok, FCookProgress progress) = 0;
virtual void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, virtual void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
@ -95,7 +91,7 @@ struct SpecBase : hecl::Database::IDataSpec {
virtual void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, virtual void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
hecl::blender::Token& btok, FCookProgress progress) = 0; hecl::blender::Token& btok, FCookProgress progress) = 0;
virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin,
FCookProgress progress) = 0; hecl::blender::Token& btok, FCookProgress progress) = 0;
virtual void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) = 0; virtual void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) = 0;
virtual void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) = 0; virtual void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) = 0;
virtual void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, virtual void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
@ -166,7 +162,7 @@ protected:
bool m_pc; bool m_pc;
hecl::ProjectPath m_masterShader; hecl::ProjectPath m_masterShader;
std::unordered_map<urde::SObjectTag, hecl::ProjectPath> m_tagToPath; std::unordered_multimap<urde::SObjectTag, hecl::ProjectPath> m_tagToPath;
std::unordered_map<hecl::Hash, urde::SObjectTag> m_pathToTag; std::unordered_map<hecl::Hash, urde::SObjectTag> m_pathToTag;
std::unordered_map<std::string, urde::SObjectTag> m_catalogNameToTag; std::unordered_map<std::string, urde::SObjectTag> m_catalogNameToTag;
std::unordered_map<urde::SObjectTag, std::unordered_set<std::string>> m_catalogTagToNames; std::unordered_map<urde::SObjectTag, std::unordered_set<std::string>> m_catalogTagToNames;
@ -178,6 +174,8 @@ protected:
bool m_backgroundRunning = false; bool m_backgroundRunning = false;
void readCatalog(const hecl::ProjectPath& catalogPath, athena::io::YAMLDocWriter& nameWriter); void readCatalog(const hecl::ProjectPath& catalogPath, athena::io::YAMLDocWriter& nameWriter);
void insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const urde::SObjectTag& tag,
const hecl::ProjectPath& path, bool dump = true);
bool addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter); bool addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter);
void backgroundIndexRecursiveProc(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter, void backgroundIndexRecursiveProc(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter,
athena::io::YAMLDocWriter& nameWriter, int level); athena::io::YAMLDocWriter& nameWriter, int level);

View File

@ -62,82 +62,6 @@ extern hecl::Database::DataSpecEntry SpecEntMP1;
extern hecl::Database::DataSpecEntry SpecEntMP1PC; extern hecl::Database::DataSpecEntry SpecEntMP1PC;
extern hecl::Database::DataSpecEntry SpecEntMP1ORIG; extern hecl::Database::DataSpecEntry SpecEntMP1ORIG;
static const std::unordered_set<uint32_t> IndividualOrigIDs = {
0xB7BBD0B4, 0x1F9DA858, 0x2A13C23E, 0xF13452F8, 0xA91A7703, 0xC042EC91, 0x12A12131, 0x5F556002, 0xA9798329,
0xB306E26F, 0xCD7B1ACA, 0x8ADA8184, 0x1A29C0E6, 0x5D9F9796, 0x951546A8, 0x7946C4C5, 0x409AA72E,
};
struct OriginalIDs {
static void Generate(PAKRouter<DNAMP1::PAKBridge>& pakRouter, hecl::Database::Project& project) {
Log.report(logvisor::Level::Info, fmt("Generating Original ID mappings..."));
std::unordered_set<UniqueID32> addedIDs;
std::vector<UniqueID32> originalIDs;
pakRouter.enumerateResources([&](const DNAMP1::PAK::Entry* ent) {
if (ent->type == FOURCC('MLVL') || ent->type == FOURCC('SCAN') || ent->type == FOURCC('MREA') ||
IndividualOrigIDs.find(ent->id.toUint32()) != IndividualOrigIDs.end()) {
if (addedIDs.find(ent->id) == addedIDs.cend()) {
addedIDs.insert(ent->id);
originalIDs.push_back(ent->id);
}
}
return true;
});
std::sort(originalIDs.begin(), originalIDs.end());
athena::io::YAMLDocWriter yamlW("MP1OriginalIDs");
for (const UniqueID32& id : originalIDs) {
hecl::ProjectPath path = pakRouter.getWorking(id);
yamlW.writeString(id.toString().c_str(), path.getRelativePathUTF8());
}
hecl::ProjectPath path(project.getProjectWorkingPath(), "MP1/!original_ids.yaml");
path.makeDirChain(false);
athena::io::FileWriter fileW(path.getAbsolutePath());
yamlW.finish(&fileW);
Log.report(logvisor::Level::Info, fmt("Done"));
}
static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
hecl::Database::Project& project = inPath.getProject();
athena::io::YAMLDocReader r;
athena::io::FileReader fr(inPath.getAbsolutePath());
if (!fr.isOpen() || !r.parse(&fr))
return;
std::vector<std::pair<UniqueID32, UniqueID32>> originalIDs;
originalIDs.reserve(r.getRootNode()->m_mapChildren.size());
for (const auto& node : r.getRootNode()->m_mapChildren) {
char* end = const_cast<char*>(node.first.c_str());
u32 id = strtoul(end, &end, 16);
if (end != node.first.c_str() + 8)
continue;
hecl::ProjectPath path(project.getProjectWorkingPath(), node.second->m_scalarString.c_str());
originalIDs.push_back(std::make_pair(id, path.hash().val32()));
}
std::sort(originalIDs.begin(), originalIDs.end(),
[](const std::pair<UniqueID32, UniqueID32>& a, const std::pair<UniqueID32, UniqueID32>& b) {
return a.first < b.first;
});
athena::io::FileWriter w(outPath.getAbsolutePath());
w.writeUint32Big(originalIDs.size());
for (const auto& idPair : originalIDs) {
idPair.first.write(w);
idPair.second.write(w);
}
std::sort(originalIDs.begin(), originalIDs.end(),
[](const std::pair<UniqueID32, UniqueID32>& a, const std::pair<UniqueID32, UniqueID32>& b) {
return a.second < b.second;
});
for (const auto& idPair : originalIDs) {
idPair.second.write(w);
idPair.first.write(w);
}
}
};
struct TextureCache { struct TextureCache {
static void Generate(PAKRouter<DNAMP1::PAKBridge>& pakRouter, hecl::Database::Project& project) { static void Generate(PAKRouter<DNAMP1::PAKBridge>& pakRouter, hecl::Database::Project& project) {
Log.report(logvisor::Level::Info, fmt("Gathering Texture metadata (this can take up to 10 seconds)...")); Log.report(logvisor::Level::Info, fmt("Gathering Texture metadata (this can take up to 10 seconds)..."));
@ -154,7 +78,7 @@ struct TextureCache {
athena::io::YAMLDocWriter yamlW("MP1TextureCache"); athena::io::YAMLDocWriter yamlW("MP1TextureCache");
for (const auto& pair : metaMap) { for (const auto& pair : metaMap) {
hecl::ProjectPath path = pakRouter.getWorking(pair.first); hecl::ProjectPath path = pakRouter.getWorking(pair.first);
auto rec = yamlW.enterSubRecord(path.getRelativePathUTF8().data()); auto rec = yamlW.enterSubRecord(path.getRelativePathUTF8());
pair.second.write(yamlW); pair.second.write(yamlW);
} }
@ -179,7 +103,7 @@ struct TextureCache {
auto rec = r.enterSubRecord(node.first.c_str()); auto rec = r.enterSubRecord(node.first.c_str());
TXTR::Meta meta; TXTR::Meta meta;
meta.read(r); meta.read(r);
metaPairs.push_back(std::make_pair(projectPath.hash().val32(), meta)); metaPairs.push_back(std::make_pair(projectPath.parsedHash32(), meta));
} }
std::sort(metaPairs.begin(), metaPairs.end(), [](const auto& a, const auto& b) -> bool { std::sort(metaPairs.begin(), metaPairs.end(), [](const auto& a, const auto& b) -> bool {
@ -208,21 +132,13 @@ struct SpecMP1 : SpecBase {
std::unique_ptr<uint8_t[]> m_dolBuf; std::unique_ptr<uint8_t[]> m_dolBuf;
IDRestorer<UniqueID32> m_idRestorer;
std::unordered_map<hecl::Hash, hecl::blender::Matrix4f> m_mreaPathToXF; std::unordered_map<hecl::Hash, hecl::blender::Matrix4f> m_mreaPathToXF;
void setThreadProject() override {
SpecBase::setThreadProject();
UniqueIDBridge::SetIDRestorer(&m_idRestorer);
}
SpecMP1(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) SpecMP1(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc)
: SpecBase(specEntry, project, pc) : SpecBase(specEntry, project, pc)
, m_workPath(project.getProjectWorkingPath(), _SYS_STR("MP1")) , m_workPath(project.getProjectWorkingPath(), _SYS_STR("MP1"))
, m_cookPath(project.getProjectCookedPath(SpecEntMP1), _SYS_STR("MP1")) , m_cookPath(project.getProjectCookedPath(SpecEntMP1), _SYS_STR("MP1"))
, m_pakRouter(*this, m_workPath, m_cookPath) , m_pakRouter(*this, m_workPath, m_cookPath) {
, m_idRestorer({project.getProjectWorkingPath(), "MP1/!original_ids.yaml"}, project) {
setThreadProject(); setThreadProject();
} }
@ -236,7 +152,7 @@ struct SpecMP1 : SpecBase {
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
if (name.size() > 4) { if (name.size() > 4) {
std::string::iterator extit = lowerName.end() - 4; std::string::iterator extit = lowerName.end() - 4;
if (!std::string(extit, lowerName.end()).compare(".pak")) { if (std::string(extit, lowerName.end()) == ".pak") {
/* This is a pak */ /* This is a pak */
isPak = true; isPak = true;
std::string lowerBase(lowerName.begin(), extit); std::string lowerBase(lowerName.begin(), extit);
@ -454,8 +370,6 @@ struct SpecMP1 : SpecBase {
hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), _SYS_STR("MP1/NoARAM")); hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), _SYS_STR("MP1/NoARAM"));
extractRandomStaticEntropy(m_dolBuf.get() + 0x4f60, noAramPath); extractRandomStaticEntropy(m_dolBuf.get() + 0x4f60, noAramPath);
/* Generate original ID mapping for MLVL and SCAN entries - marks complete project */
OriginalIDs::Generate(m_pakRouter, m_project);
/* Generate Texture Cache containing meta data for every texture file */ /* Generate Texture Cache containing meta data for every texture file */
TextureCache::Generate(m_pakRouter, m_project); TextureCache::Generate(m_pakRouter, m_project);
@ -475,90 +389,86 @@ struct SpecMP1 : SpecBase {
bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override { bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override {
athena::io::YAMLDocReader reader; athena::io::YAMLDocReader reader;
yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp); yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp);
return reader.ClassTypeOperation([](const char* classType) { return reader.ClassTypeOperation([](std::string_view classType) {
if (!strcmp(classType, DNAMP1::MLVL::DNAType())) if (classType == DNAMP1::MLVL::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::STRG::DNAType())) else if (classType == DNAMP1::STRG::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::SCAN::DNAType())) else if (classType == DNAMP1::SCAN::DNAType())
return true; return true;
else if (!strcmp(classType, DNAParticle::GPSM<UniqueID32>::DNAType())) else if (classType == DNAParticle::GPSM<UniqueID32>::DNAType())
return true; return true;
else if (!strcmp(classType, DNAParticle::SWSH<UniqueID32>::DNAType())) else if (classType == DNAParticle::SWSH<UniqueID32>::DNAType())
return true; return true;
else if (!strcmp(classType, DNAParticle::ELSM<UniqueID32>::DNAType())) else if (classType == DNAParticle::ELSM<UniqueID32>::DNAType())
return true; return true;
else if (!strcmp(classType, DNAParticle::WPSM<UniqueID32>::DNAType())) else if (classType == DNAParticle::WPSM<UniqueID32>::DNAType())
return true; return true;
else if (!strcmp(classType, DNAParticle::CRSM<UniqueID32>::DNAType())) else if (classType == DNAParticle::CRSM<UniqueID32>::DNAType())
return true; return true;
else if (!strcmp(classType, DNAParticle::DPSM<UniqueID32>::DNAType())) else if (classType == DNAParticle::DPSM<UniqueID32>::DNAType())
return true; return true;
else if (!strcmp(classType, DNADGRP::DGRP<UniqueID32>::DNAType())) else if (classType == DNADGRP::DGRP<UniqueID32>::DNAType())
return true; return true;
else if (!strcmp(classType, DNAFont::FONT<UniqueID32>::DNAType())) else if (classType == DNAFont::FONT<UniqueID32>::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakPlayerRes::DNAType())) else if (classType == DNAMP1::CTweakPlayerRes::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakGunRes::DNAType())) else if (classType == DNAMP1::CTweakGunRes::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakSlideShow::DNAType())) else if (classType == DNAMP1::CTweakSlideShow::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakPlayer::DNAType())) else if (classType == DNAMP1::CTweakPlayer::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakCameraBob::DNAType())) else if (classType == DNAMP1::CTweakCameraBob::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakGame::DNAType())) else if (classType == DNAMP1::CTweakGame::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakAutoMapper::DNAType())) else if (classType == DNAMP1::CTweakAutoMapper::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakTargeting::DNAType())) else if (classType == DNAMP1::CTweakTargeting::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakGui::DNAType())) else if (classType == DNAMP1::CTweakGui::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakPlayerControl::DNAType())) else if (classType == DNAMP1::CTweakPlayerControl::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakBall::DNAType())) else if (classType == DNAMP1::CTweakBall::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakParticle::DNAType())) else if (classType == DNAMP1::CTweakParticle::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakGuiColors::DNAType())) else if (classType == DNAMP1::CTweakGuiColors::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::CTweakPlayerGun::DNAType())) else if (classType == DNAMP1::CTweakPlayerGun::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::HINT::DNAType())) else if (classType == DNAMP1::HINT::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::EVNT::DNAType())) else if (classType == DNAMP1::EVNT::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::MazeSeeds::DNAType())) else if (classType == DNAMP1::MazeSeeds::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP1::SnowForces::DNAType())) else if (classType == DNAMP1::SnowForces::DNAType())
return true; return true;
else if (!strcmp(classType, "ATBL")) else if (classType == "ATBL")
return true; return true;
else if (!strcmp(classType, DNAMP1::AFSM::DNAType())) else if (classType == DNAMP1::AFSM::DNAType())
return true; return true;
else if (!strcmp(classType, "MP1OriginalIDs")) else if (classType == "MP1TextureCache")
return true;
else if (!strcmp(classType, "MP1TextureCache"))
return true; return true;
return false; return false;
}); });
} }
urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const override { urde::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const override {
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CINF"))) if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CSKR")))
return {SBIG('CINF'), path.hash().val32()}; return {SBIG('CSKR'), path.parsedHash32()};
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CSKR")))
return {SBIG('CSKR'), path.hash().val32()};
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".ANIM"))) else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".ANIM")))
return {SBIG('ANIM'), path.hash().val32()}; return {SBIG('ANIM'), path.parsedHash32()};
else if (const hecl::SystemChar* ext = path.getLastComponentExt().data()) { else if (const hecl::SystemChar* ext = path.getLastComponentExt().data()) {
if (ext[0] == _SYS_STR('*') || !hecl::StrCmp(ext, _SYS_STR("mid"))) { if (ext[0] == _SYS_STR('*') || !hecl::StrCmp(ext, _SYS_STR("mid"))) {
if (path.getWithExtension(_SYS_STR(".mid"), true).isFile() && if (path.getWithExtension(_SYS_STR(".mid"), true).isFile() &&
path.getWithExtension(_SYS_STR(".yaml"), true).isFile()) { path.getWithExtension(_SYS_STR(".yaml"), true).isFile()) {
hecl::ProjectPath glob = path.getWithExtension(_SYS_STR(".*"), true); hecl::ProjectPath glob = path.getWithExtension(_SYS_STR(".*"), true);
return {SBIG('CSNG'), glob.hash().val32()}; return {SBIG('CSNG'), glob.parsedHash32()};
} }
} }
} }
@ -566,7 +476,7 @@ struct SpecMP1 : SpecBase {
if (path.getPathType() == hecl::ProjectPath::Type::Directory) { if (path.getPathType() == hecl::ProjectPath::Type::Directory) {
if (hecl::ProjectPath(path, _SYS_STR("!project.yaml")).isFile() && if (hecl::ProjectPath(path, _SYS_STR("!project.yaml")).isFile() &&
hecl::ProjectPath(path, _SYS_STR("!pool.yaml")).isFile()) hecl::ProjectPath(path, _SYS_STR("!pool.yaml")).isFile())
return {SBIG('AGSC'), path.hash().val32()}; return {SBIG('AGSC'), path.parsedHash32()};
} }
hecl::ProjectPath asBlend; hecl::ProjectPath asBlend;
@ -578,43 +488,36 @@ struct SpecMP1 : SpecBase {
if (hecl::IsPathBlend(asBlend)) { if (hecl::IsPathBlend(asBlend)) {
switch (hecl::blender::GetBlendType(asBlend.getAbsolutePath())) { switch (hecl::blender::GetBlendType(asBlend.getAbsolutePath())) {
case hecl::blender::BlendType::Mesh: case hecl::blender::BlendType::Mesh:
return {SBIG('CMDL'), path.hash().val32()}; return {SBIG('CMDL'), path.parsedHash32()};
case hecl::blender::BlendType::ColMesh: case hecl::blender::BlendType::ColMesh:
return {SBIG('DCLN'), path.hash().val32()}; return {SBIG('DCLN'), path.parsedHash32()};
case hecl::blender::BlendType::Armature:
return {SBIG('CINF'), path.parsedHash32()};
case hecl::blender::BlendType::PathMesh: case hecl::blender::BlendType::PathMesh:
return {SBIG('PATH'), path.hash().val32()}; return {SBIG('PATH'), path.parsedHash32()};
case hecl::blender::BlendType::Actor: case hecl::blender::BlendType::Actor:
if (path.getAuxInfo().size()) { if (path.getAuxInfo().size()) {
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CINF"))) if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CSKR")))
return {SBIG('CINF'), path.getWithExtension(_SYS_STR(".*"), true).hash().val32()}; return {SBIG('CSKR'), path.getWithExtension(_SYS_STR(".*"), true).parsedHash32()};
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".CSKR")))
return {SBIG('CSKR'), path.getWithExtension(_SYS_STR(".*"), true).hash().val32()};
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".ANIM"))) else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR(".ANIM")))
return {SBIG('ANIM'), path.getWithExtension(_SYS_STR(".*"), true).hash().val32()}; return {SBIG('ANIM'), path.getWithExtension(_SYS_STR(".*"), true).parsedHash32()};
} }
return {SBIG('ANCS'), path.getWithExtension(_SYS_STR(".*"), true).hash().val32()}; return {SBIG('ANCS'), path.getWithExtension(_SYS_STR(".*"), true).parsedHash32()};
case hecl::blender::BlendType::Area: case hecl::blender::BlendType::Area:
return {SBIG('MREA'), path.hash().val32()}; return {SBIG('MREA'), path.parsedHash32()};
case hecl::blender::BlendType::World: { case hecl::blender::BlendType::World:
if (path.getAuxInfo().size()) { return {SBIG('MLVL'), path.getWithExtension(_SYS_STR(".*"), true).parsedHash32()};
if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR("MAPW")))
return {SBIG('MAPW'), path.getWithExtension(_SYS_STR(".*"), true).hash().val32()};
else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _SYS_STR("SAVW")))
return {SBIG('SAVW'), path.getWithExtension(_SYS_STR(".*"), true).hash().val32()};
}
return {SBIG('MLVL'), path.getWithExtension(_SYS_STR(".*"), true).hash().val32()};
}
case hecl::blender::BlendType::MapArea: case hecl::blender::BlendType::MapArea:
return {SBIG('MAPA'), path.hash().val32()}; return {SBIG('MAPA'), path.parsedHash32()};
case hecl::blender::BlendType::MapUniverse: case hecl::blender::BlendType::MapUniverse:
return {SBIG('MAPU'), path.hash().val32()}; return {SBIG('MAPU'), path.parsedHash32()};
case hecl::blender::BlendType::Frame: case hecl::blender::BlendType::Frame:
return {SBIG('FRME'), path.hash().val32()}; return {SBIG('FRME'), path.parsedHash32()};
default: default:
return {}; return {};
} }
} else if (hecl::IsPathPNG(path)) { } else if (hecl::IsPathPNG(path)) {
return {SBIG('TXTR'), path.hash().val32()}; return {SBIG('TXTR'), path.parsedHash32()};
} else if (hecl::IsPathYAML(path)) { } else if (hecl::IsPathYAML(path)) {
auto fp = hecl::FopenUnique(path.getAbsolutePath().data(), _SYS_STR("r")); auto fp = hecl::FopenUnique(path.getAbsolutePath().data(), _SYS_STR("r"));
if (fp == nullptr) { if (fp == nullptr) {
@ -625,85 +528,88 @@ struct SpecMP1 : SpecBase {
yaml_parser_set_input_file(reader.getParser(), fp.get()); yaml_parser_set_input_file(reader.getParser(), fp.get());
urde::SObjectTag resTag; urde::SObjectTag resTag;
if (reader.ClassTypeOperation([&](const char* className) -> bool { if (reader.ClassTypeOperation([&](std::string_view className) {
if (!strcmp(className, DNAParticle::GPSM<UniqueID32>::DNAType())) { if (className == DNAParticle::GPSM<UniqueID32>::DNAType()) {
resTag.type = SBIG('PART'); resTag.type = SBIG('PART');
return true; return true;
} }
if (!strcmp(className, DNAParticle::SWSH<UniqueID32>::DNAType())) { if (className == DNAParticle::SWSH<UniqueID32>::DNAType()) {
resTag.type = SBIG('SWHC'); resTag.type = SBIG('SWHC');
return true; return true;
} }
if (!strcmp(className, DNAParticle::ELSM<UniqueID32>::DNAType())) { if (className == DNAParticle::ELSM<UniqueID32>::DNAType()) {
resTag.type = SBIG('ELSC'); resTag.type = SBIG('ELSC');
return true; return true;
} }
if (!strcmp(className, DNAParticle::WPSM<UniqueID32>::DNAType())) { if (className == DNAParticle::WPSM<UniqueID32>::DNAType()) {
resTag.type = SBIG('WPSC'); resTag.type = SBIG('WPSC');
return true; return true;
} }
if (!strcmp(className, DNAParticle::CRSM<UniqueID32>::DNAType())) { if (className == DNAParticle::CRSM<UniqueID32>::DNAType()) {
resTag.type = SBIG('CRSC'); resTag.type = SBIG('CRSC');
return true; return true;
} }
if (!strcmp(className, DNAParticle::DPSM<UniqueID32>::DNAType())) { if (className == DNAParticle::DPSM<UniqueID32>::DNAType()) {
resTag.type = SBIG('DPSC'); resTag.type = SBIG('DPSC');
return true; return true;
} else if (!strcmp(className, DNAFont::FONT<UniqueID32>::DNAType())) { } else if (className == DNAFont::FONT<UniqueID32>::DNAType()) {
resTag.type = SBIG('FONT'); resTag.type = SBIG('FONT');
return true; return true;
} else if (!strcmp(className, DNAMP1::EVNT::DNAType())) { } else if (className == DNAMP1::EVNT::DNAType()) {
resTag.type = SBIG('EVNT'); resTag.type = SBIG('EVNT');
return true; return true;
} else if (!strcmp(className, DNADGRP::DGRP<UniqueID32>::DNAType())) { } else if (className == DNADGRP::DGRP<UniqueID32>::DNAType()) {
resTag.type = SBIG('DGRP'); resTag.type = SBIG('DGRP');
return true; return true;
} else if (!strcmp(className, DataSpec::DNAMP1::STRG::DNAType())) { } else if (className == DataSpec::DNAMP1::STRG::DNAType()) {
resTag.type = SBIG('STRG'); resTag.type = SBIG('STRG');
return true; return true;
} else if (!strcmp(className, DataSpec::DNAMP1::SCAN::DNAType())) { } else if (className == DataSpec::DNAMP1::SCAN::DNAType()) {
resTag.type = SBIG('SCAN'); resTag.type = SBIG('SCAN');
return true; return true;
} else if (!strcmp(className, DataSpec::DNAMP1::CTweakPlayerRes::DNAType()) || } else if (className == DataSpec::DNAMP1::CTweakPlayerRes::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakGunRes::DNAType()) || className == DataSpec::DNAMP1::CTweakGunRes::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakSlideShow::DNAType()) || className == DataSpec::DNAMP1::CTweakSlideShow::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakPlayer::DNAType()) || className == DataSpec::DNAMP1::CTweakPlayer::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakCameraBob::DNAType()) || className == DataSpec::DNAMP1::CTweakCameraBob::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakGame::DNAType()) || className == DataSpec::DNAMP1::CTweakGame::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakTargeting::DNAType()) || className == DataSpec::DNAMP1::CTweakTargeting::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakAutoMapper::DNAType()) || className == DataSpec::DNAMP1::CTweakAutoMapper::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakGui::DNAType()) || className == DataSpec::DNAMP1::CTweakGui::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakPlayerControl::DNAType()) || className == DataSpec::DNAMP1::CTweakPlayerControl::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakBall::DNAType()) || className == DataSpec::DNAMP1::CTweakBall::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakParticle::DNAType()) || className == DataSpec::DNAMP1::CTweakParticle::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakGuiColors::DNAType()) || className == DataSpec::DNAMP1::CTweakGuiColors::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::CTweakPlayerGun::DNAType())) { className == DataSpec::DNAMP1::CTweakPlayerGun::DNAType()) {
resTag.type = SBIG('CTWK'); resTag.type = SBIG('CTWK');
return true; return true;
} else if (!strcmp(className, DataSpec::DNAMP1::MazeSeeds::DNAType()) || } else if (className == DataSpec::DNAMP1::MazeSeeds::DNAType() ||
!strcmp(className, DataSpec::DNAMP1::SnowForces::DNAType())) { className == DataSpec::DNAMP1::SnowForces::DNAType()) {
resTag.type = SBIG('DUMB'); resTag.type = SBIG('DUMB');
return true; return true;
} else if (!strcmp(className, DataSpec::DNAMP1::HINT::DNAType())) { } else if (className == DataSpec::DNAMP1::HINT::DNAType()) {
resTag.type = SBIG('HINT'); resTag.type = SBIG('HINT');
return true; return true;
} else if (!strcmp(className, "ATBL")) { } else if (className == "ATBL") {
resTag.type = SBIG('ATBL'); resTag.type = SBIG('ATBL');
return true; return true;
} else if (!strcmp(className, DataSpec::DNAMP1::AFSM::DNAType())) { } else if (className == DataSpec::DNAMP1::AFSM::DNAType()) {
resTag.type = SBIG('AFSM'); resTag.type = SBIG('AFSM');
return true; return true;
} else if (!strcmp(className, "MP1OriginalIDs")) { } else if (className == "MP1TextureCache") {
resTag.type = SBIG('OIDS');
return true;
} else if (!strcmp(className, "MP1TextureCache")) {
resTag.type = SBIG('TMET'); resTag.type = SBIG('TMET');
return true; return true;
} else if (className == "DataSpec::DNAMP1::SAVW") {
resTag.type = SBIG('SAVW');
return true;
} else if (className == "DataSpec::DNAMP1::MAPW") {
resTag.type = SBIG('MAPW');
return true;
} }
return false; return false;
})) { })) {
resTag.id = path.hash().val32(); resTag.id = path.parsedHash32();
fp.reset(); fp.reset();
return resTag; return resTag;
} }
@ -739,6 +645,13 @@ struct SpecMP1 : SpecBase {
DNAMP1::DCLN::Cook(out, mesh); DNAMP1::DCLN::Cook(out, mesh);
} }
void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override {
Armature armature = ds.compileArmature();
ds.close();
DNAMP1::CINF::Cook(out, in, armature);
}
void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override { hecl::blender::Token& btok, FCookProgress progress) override {
PathMesh mesh = ds.compilePathMesh(); PathMesh mesh = ds.compilePathMesh();
@ -748,10 +661,7 @@ struct SpecMP1 : SpecBase {
void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override { hecl::blender::Token& btok, FCookProgress progress) override {
if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR(".CINF"))) { if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR(".CSKR"))) {
Actor actor = ds.compileActorCharacterOnly();
DNAMP1::ANCS::CookCINF(out, in, actor);
} else if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR(".CSKR"))) {
Actor actor = ds.compileActorCharacterOnly(); Actor actor = ds.compileActorCharacterOnly();
ds.close(); ds.close();
if (m_pc) { if (m_pc) {
@ -783,14 +693,21 @@ struct SpecMP1 : SpecBase {
hecl::ProjectPath pakPath(m_workPath, ent.m_name); hecl::ProjectPath pakPath(m_workPath, ent.m_name);
for (const auto& ent2 : pakPath.enumerateDir()) { for (const auto& ent2 : pakPath.enumerateDir()) {
if (ent2.m_isDir) { if (ent2.m_isDir) {
hecl::ProjectPath wldPath(pakPath, ent2.m_name + _SYS_STR("/!world.blend")); hecl::ProjectPath wldDir(pakPath, ent2.m_name);
if (wldPath.isFile()) { for (const auto& ent3 : wldDir.enumerateDir()) {
if (!conn.openBlend(wldPath)) if (hecl::StringUtils::BeginsWith(ent3.m_name, _SYS_STR("!world_")) &&
continue; hecl::StringUtils::EndsWith(ent3.m_name, _SYS_STR(".blend"))) {
hecl::blender::DataStream ds = conn.beginData(); hecl::ProjectPath wldPath(wldDir, ent3.m_name);
hecl::blender::World world = ds.compileWorld(); if (wldPath.isFile()) {
for (const auto& area : world.areas) if (!conn.openBlend(wldPath))
m_mreaPathToXF[area.path.hash()] = area.transform; continue;
hecl::blender::DataStream ds = conn.beginData();
hecl::blender::World world = ds.compileWorld();
for (const auto& area : world.areas)
m_mreaPathToXF[area.path.hash()] = area.transform;
}
break;
}
} }
} }
} }
@ -808,7 +725,7 @@ struct SpecMP1 : SpecBase {
for (const std::string& mesh : meshes) { for (const std::string& mesh : meshes) {
hecl::SystemStringConv meshSys(mesh); hecl::SystemStringConv meshSys(mesh);
if (!mesh.compare("CMESH")) { if (mesh == "CMESH") {
colMesh = ds.compileColMesh(mesh); colMesh = ds.compileColMesh(mesh);
progress(_SYS_STR("Collision Mesh")); progress(_SYS_STR("Collision Mesh"));
continue; continue;
@ -836,19 +753,9 @@ struct SpecMP1 : SpecBase {
void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override { hecl::blender::Token& btok, FCookProgress progress) override {
if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR("MAPW"))) { hecl::blender::World world = ds.compileWorld();
hecl::blender::World world = ds.compileWorld(); ds.close();
ds.close(); DNAMP1::MLVL::Cook(out, in, world, btok);
DNAMP1::MLVL::CookMAPW(out, world);
} else if (hecl::StringUtils::EndsWith(in.getAuxInfo(), _SYS_STR("SAVW"))) {
hecl::blender::World world = ds.compileWorld();
ds.close();
DNAMP1::MLVL::CookSAVW(out, world);
} else {
hecl::blender::World world = ds.compileWorld();
ds.close();
DNAMP1::MLVL::Cook(out, in, world, btok);
}
} }
void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
@ -862,133 +769,131 @@ struct SpecMP1 : SpecBase {
} }
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin,
FCookProgress progress) override { hecl::blender::Token& btok, FCookProgress progress) override {
athena::io::YAMLDocReader reader; athena::io::YAMLDocReader reader;
if (reader.parse(&fin)) { if (reader.parse(&fin)) {
std::string classStr = reader.readString("DNAType"); std::string classStr = reader.readString("DNAType");
if (classStr.empty()) if (classStr.empty())
return; return;
if (!classStr.compare(DNAMP1::STRG::DNAType())) { if (classStr == DNAMP1::STRG::DNAType()) {
DNAMP1::STRG strg; DNAMP1::STRG strg;
strg.read(reader); strg.read(reader);
DNAMP1::STRG::Cook(strg, out); DNAMP1::STRG::Cook(strg, out);
} else if (!classStr.compare(DNAMP1::SCAN::DNAType())) { } else if (classStr == DNAMP1::SCAN::DNAType()) {
DNAMP1::SCAN scan; DNAMP1::SCAN scan;
scan.read(reader); scan.read(reader);
DNAMP1::SCAN::Cook(scan, out); DNAMP1::SCAN::Cook(scan, out);
} else if (!classStr.compare(DNAParticle::GPSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::GPSM<UniqueID32>::DNAType()) {
DNAParticle::GPSM<UniqueID32> gpsm; DNAParticle::GPSM<UniqueID32> gpsm;
gpsm.read(reader); gpsm.read(reader);
DNAParticle::WriteGPSM(gpsm, out); DNAParticle::WriteGPSM(gpsm, out);
} else if (!classStr.compare(DNAParticle::SWSH<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::SWSH<UniqueID32>::DNAType()) {
DNAParticle::SWSH<UniqueID32> swsh; DNAParticle::SWSH<UniqueID32> swsh;
swsh.read(reader); swsh.read(reader);
DNAParticle::WriteSWSH(swsh, out); DNAParticle::WriteSWSH(swsh, out);
} else if (!classStr.compare(DNAParticle::ELSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::ELSM<UniqueID32>::DNAType()) {
DNAParticle::ELSM<UniqueID32> elsm; DNAParticle::ELSM<UniqueID32> elsm;
elsm.read(reader); elsm.read(reader);
DNAParticle::WriteELSM(elsm, out); DNAParticle::WriteELSM(elsm, out);
} else if (!classStr.compare(DNAParticle::WPSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::WPSM<UniqueID32>::DNAType()) {
DNAParticle::WPSM<UniqueID32> wpsm; DNAParticle::WPSM<UniqueID32> wpsm;
wpsm.read(reader); wpsm.read(reader);
DNAParticle::WriteWPSM(wpsm, out); DNAParticle::WriteWPSM(wpsm, out);
} else if (!classStr.compare(DNAParticle::CRSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::CRSM<UniqueID32>::DNAType()) {
DNAParticle::CRSM<UniqueID32> crsm; DNAParticle::CRSM<UniqueID32> crsm;
crsm.read(reader); crsm.read(reader);
DNAParticle::WriteCRSM(crsm, out); DNAParticle::WriteCRSM(crsm, out);
} else if (!classStr.compare(DNAParticle::DPSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::DPSM<UniqueID32>::DNAType()) {
DNAParticle::DPSM<UniqueID32> dpsm; DNAParticle::DPSM<UniqueID32> dpsm;
dpsm.read(reader); dpsm.read(reader);
DNAParticle::WriteDPSM(dpsm, out); DNAParticle::WriteDPSM(dpsm, out);
} else if (!classStr.compare(DNADGRP::DGRP<UniqueID32>::DNAType())) { } else if (classStr == DNADGRP::DGRP<UniqueID32>::DNAType()) {
DNADGRP::DGRP<UniqueID32> dgrp; DNADGRP::DGRP<UniqueID32> dgrp;
dgrp.read(reader); dgrp.read(reader);
dgrp.validateDeps(); dgrp.validateDeps();
DNADGRP::WriteDGRP(dgrp, out); DNADGRP::WriteDGRP(dgrp, out);
} else if (!classStr.compare(DNAFont::FONT<UniqueID32>::DNAType())) { } else if (classStr == DNAFont::FONT<UniqueID32>::DNAType()) {
DNAFont::FONT<UniqueID32> font; DNAFont::FONT<UniqueID32> font;
font.read(reader); font.read(reader);
DNAFont::WriteFONT(font, out); DNAFont::WriteFONT(font, out);
} else if (!classStr.compare(DNAMP1::CTweakPlayerRes::DNAType())) { } else if (classStr == DNAMP1::CTweakPlayerRes::DNAType()) {
DNAMP1::CTweakPlayerRes playerRes; DNAMP1::CTweakPlayerRes playerRes;
playerRes.read(reader); playerRes.read(reader);
WriteTweak(playerRes, out); WriteTweak(playerRes, out);
} else if (!classStr.compare(DNAMP1::CTweakGunRes::DNAType())) { } else if (classStr == DNAMP1::CTweakGunRes::DNAType()) {
DNAMP1::CTweakGunRes gunRes; DNAMP1::CTweakGunRes gunRes;
gunRes.read(reader); gunRes.read(reader);
WriteTweak(gunRes, out); WriteTweak(gunRes, out);
} else if (!classStr.compare(DNAMP1::CTweakSlideShow::DNAType())) { } else if (classStr == DNAMP1::CTweakSlideShow::DNAType()) {
DNAMP1::CTweakSlideShow slideShow; DNAMP1::CTweakSlideShow slideShow;
slideShow.read(reader); slideShow.read(reader);
WriteTweak(slideShow, out); WriteTweak(slideShow, out);
} else if (!classStr.compare(DNAMP1::CTweakPlayer::DNAType())) { } else if (classStr == DNAMP1::CTweakPlayer::DNAType()) {
DNAMP1::CTweakPlayer player; DNAMP1::CTweakPlayer player;
player.read(reader); player.read(reader);
WriteTweak(player, out); WriteTweak(player, out);
} else if (!classStr.compare(DNAMP1::CTweakCameraBob::DNAType())) { } else if (classStr == DNAMP1::CTweakCameraBob::DNAType()) {
DNAMP1::CTweakCameraBob cBob; DNAMP1::CTweakCameraBob cBob;
cBob.read(reader); cBob.read(reader);
WriteTweak(cBob, out); WriteTweak(cBob, out);
} else if (!classStr.compare(DNAMP1::CTweakGame::DNAType())) { } else if (classStr == DNAMP1::CTweakGame::DNAType()) {
DNAMP1::CTweakGame cGame; DNAMP1::CTweakGame cGame;
cGame.read(reader); cGame.read(reader);
WriteTweak(cGame, out); WriteTweak(cGame, out);
} else if (!classStr.compare(DNAMP1::CTweakAutoMapper::DNAType())) { } else if (classStr == DNAMP1::CTweakAutoMapper::DNAType()) {
DNAMP1::CTweakAutoMapper autoMapper; DNAMP1::CTweakAutoMapper autoMapper;
autoMapper.read(reader); autoMapper.read(reader);
WriteTweak(autoMapper, out); WriteTweak(autoMapper, out);
} else if (!classStr.compare(DNAMP1::CTweakTargeting::DNAType())) { } else if (classStr == DNAMP1::CTweakTargeting::DNAType()) {
DNAMP1::CTweakTargeting targeting; DNAMP1::CTweakTargeting targeting;
targeting.read(reader); targeting.read(reader);
WriteTweak(targeting, out); WriteTweak(targeting, out);
} else if (!classStr.compare(DNAMP1::CTweakGui::DNAType())) { } else if (classStr == DNAMP1::CTweakGui::DNAType()) {
DNAMP1::CTweakGui gui; DNAMP1::CTweakGui gui;
gui.read(reader); gui.read(reader);
WriteTweak(gui, out); WriteTweak(gui, out);
} else if (!classStr.compare(DNAMP1::CTweakPlayerControl::DNAType())) { } else if (classStr == DNAMP1::CTweakPlayerControl::DNAType()) {
DNAMP1::CTweakPlayerControl pc; DNAMP1::CTweakPlayerControl pc;
pc.read(reader); pc.read(reader);
WriteTweak(pc, out); WriteTweak(pc, out);
} else if (!classStr.compare(DNAMP1::CTweakBall::DNAType())) { } else if (classStr == DNAMP1::CTweakBall::DNAType()) {
DNAMP1::CTweakBall ball; DNAMP1::CTweakBall ball;
ball.read(reader); ball.read(reader);
WriteTweak(ball, out); WriteTweak(ball, out);
} else if (!classStr.compare(DNAMP1::CTweakParticle::DNAType())) { } else if (classStr == DNAMP1::CTweakParticle::DNAType()) {
DNAMP1::CTweakParticle part; DNAMP1::CTweakParticle part;
part.read(reader); part.read(reader);
WriteTweak(part, out); WriteTweak(part, out);
} else if (!classStr.compare(DNAMP1::CTweakGuiColors::DNAType())) { } else if (classStr == DNAMP1::CTweakGuiColors::DNAType()) {
DNAMP1::CTweakGuiColors gColors; DNAMP1::CTweakGuiColors gColors;
gColors.read(reader); gColors.read(reader);
WriteTweak(gColors, out); WriteTweak(gColors, out);
} else if (!classStr.compare(DNAMP1::CTweakPlayerGun::DNAType())) { } else if (classStr == DNAMP1::CTweakPlayerGun::DNAType()) {
DNAMP1::CTweakPlayerGun pGun; DNAMP1::CTweakPlayerGun pGun;
pGun.read(reader); pGun.read(reader);
WriteTweak(pGun, out); WriteTweak(pGun, out);
} else if (!classStr.compare(DNAMP1::CTweakPlayerControl::DNAType())) { } else if (classStr == DNAMP1::CTweakPlayerControl::DNAType()) {
DNAMP1::CTweakPlayerControl pControl; DNAMP1::CTweakPlayerControl pControl;
pControl.read(reader); pControl.read(reader);
WriteTweak(pControl, out); WriteTweak(pControl, out);
} else if (!classStr.compare(DNAMP1::MazeSeeds::DNAType())) { } else if (classStr == DNAMP1::MazeSeeds::DNAType()) {
DNAMP1::MazeSeeds mSeeds; DNAMP1::MazeSeeds mSeeds;
mSeeds.read(reader); mSeeds.read(reader);
WriteTweak(mSeeds, out); WriteTweak(mSeeds, out);
} else if (!classStr.compare(DNAMP1::SnowForces::DNAType())) { } else if (classStr == DNAMP1::SnowForces::DNAType()) {
DNAMP1::SnowForces sForces; DNAMP1::SnowForces sForces;
sForces.read(reader); sForces.read(reader);
WriteTweak(sForces, out); WriteTweak(sForces, out);
} else if (!classStr.compare(DNAMP1::HINT::DNAType())) { } else if (classStr == DNAMP1::HINT::DNAType()) {
DNAMP1::HINT::Cook(in, out); DNAMP1::HINT::Cook(in, out);
} else if (!classStr.compare(DNAMP1::EVNT::DNAType())) { } else if (classStr == DNAMP1::EVNT::DNAType()) {
DNAMP1::EVNT::Cook(in, out); DNAMP1::EVNT::Cook(in, out);
} else if (!classStr.compare("ATBL")) { } else if (classStr == "ATBL") {
DNAAudio::ATBL::Cook(in, out); DNAAudio::ATBL::Cook(in, out);
} else if (!classStr.compare(DNAMP1::AFSM::DNAType())) { } else if (classStr == DNAMP1::AFSM::DNAType()) {
DNAMP1::AFSM::Cook(in, out); DNAMP1::AFSM::Cook(in, out);
} else if (!classStr.compare("MP1OriginalIDs")) { } else if (classStr == "MP1TextureCache") {
OriginalIDs::Cook(in, out);
} else if (!classStr.compare("MP1TextureCache")) {
TextureCache::Cook(in, out); TextureCache::Cook(in, out);
} }
} }
@ -998,48 +903,48 @@ struct SpecMP1 : SpecBase {
void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector<hecl::ProjectPath>& pathsOut) override { void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector<hecl::ProjectPath>& pathsOut) override {
athena::io::YAMLDocReader reader; athena::io::YAMLDocReader reader;
if (reader.parse(&fin)) { if (reader.parse(&fin)) {
std::string classStr = reader.readString("DNAType"); std::string classStr = reader.readString("DNAType"sv);
if (classStr.empty()) if (classStr.empty())
return; return;
if (!classStr.compare(DNAMP1::STRG::DNAType())) { if (classStr == DNAMP1::STRG::DNAType()) {
DNAMP1::STRG strg; DNAMP1::STRG strg;
strg.read(reader); strg.read(reader);
strg.gatherDependencies(pathsOut); strg.gatherDependencies(pathsOut);
} }
if (!classStr.compare(DNAMP1::SCAN::DNAType())) { if (classStr == DNAMP1::SCAN::DNAType()) {
DNAMP1::SCAN scan; DNAMP1::SCAN scan;
scan.read(reader); scan.read(reader);
scan.gatherDependencies(pathsOut); scan.gatherDependencies(pathsOut);
} else if (!classStr.compare(DNAParticle::GPSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::GPSM<UniqueID32>::DNAType()) {
DNAParticle::GPSM<UniqueID32> gpsm; DNAParticle::GPSM<UniqueID32> gpsm;
gpsm.read(reader); gpsm.read(reader);
gpsm.gatherDependencies(pathsOut); gpsm.gatherDependencies(pathsOut);
} else if (!classStr.compare(DNAParticle::SWSH<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::SWSH<UniqueID32>::DNAType()) {
DNAParticle::SWSH<UniqueID32> swsh; DNAParticle::SWSH<UniqueID32> swsh;
swsh.read(reader); swsh.read(reader);
swsh.gatherDependencies(pathsOut); swsh.gatherDependencies(pathsOut);
} else if (!classStr.compare(DNAParticle::ELSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::ELSM<UniqueID32>::DNAType()) {
DNAParticle::ELSM<UniqueID32> elsm; DNAParticle::ELSM<UniqueID32> elsm;
elsm.read(reader); elsm.read(reader);
elsm.gatherDependencies(pathsOut); elsm.gatherDependencies(pathsOut);
} else if (!classStr.compare(DNAParticle::WPSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::WPSM<UniqueID32>::DNAType()) {
DNAParticle::WPSM<UniqueID32> wpsm; DNAParticle::WPSM<UniqueID32> wpsm;
wpsm.read(reader); wpsm.read(reader);
wpsm.gatherDependencies(pathsOut); wpsm.gatherDependencies(pathsOut);
} else if (!classStr.compare(DNAParticle::CRSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::CRSM<UniqueID32>::DNAType()) {
DNAParticle::CRSM<UniqueID32> crsm; DNAParticle::CRSM<UniqueID32> crsm;
crsm.read(reader); crsm.read(reader);
crsm.gatherDependencies(pathsOut); crsm.gatherDependencies(pathsOut);
} else if (!classStr.compare(DNAParticle::DPSM<UniqueID32>::DNAType())) { } else if (classStr == DNAParticle::DPSM<UniqueID32>::DNAType()) {
DNAParticle::DPSM<UniqueID32> dpsm; DNAParticle::DPSM<UniqueID32> dpsm;
dpsm.read(reader); dpsm.read(reader);
dpsm.gatherDependencies(pathsOut); dpsm.gatherDependencies(pathsOut);
} else if (!classStr.compare(DNAFont::FONT<UniqueID32>::DNAType())) { } else if (classStr == DNAFont::FONT<UniqueID32>::DNAType()) {
DNAFont::FONT<UniqueID32> font; DNAFont::FONT<UniqueID32> font;
font.read(reader); font.read(reader);
font.gatherDependencies(pathsOut); font.gatherDependencies(pathsOut);
} else if (!classStr.compare(DNAMP1::EVNT::DNAType())) { } else if (classStr == DNAMP1::EVNT::DNAType()) {
DNAMP1::EVNT evnt; DNAMP1::EVNT evnt;
evnt.read(reader); evnt.read(reader);
evnt.gatherDependencies(pathsOut); evnt.gatherDependencies(pathsOut);
@ -1052,7 +957,7 @@ struct SpecMP1 : SpecBase {
athena::io::YAMLDocReader reader; athena::io::YAMLDocReader reader;
if (reader.parse(&fin)) { if (reader.parse(&fin)) {
std::string classStr = reader.readString("DNAType"); std::string classStr = reader.readString("DNAType");
if (!classStr.compare(DNAMP1::ANCS::DNAType())) { if (classStr == DNAMP1::ANCS::DNAType()) {
DNAMP1::ANCS ancs; DNAMP1::ANCS ancs;
ancs.read(reader); ancs.read(reader);
ancs.gatherDependencies(pathsOut, charIdx); ancs.gatherDependencies(pathsOut, charIdx);
@ -1060,20 +965,6 @@ struct SpecMP1 : SpecBase {
} }
} }
UniqueID32 newToOriginal(urde::CAssetId id) const {
UniqueID32 origId = m_idRestorer.newToOriginal({uint32_t(id.Value()), true});
if (origId.isValid())
return {origId.toUint32(), true};
return {uint32_t(id.Value()), true};
}
urde::CAssetId originalToNew(UniqueID32 id) const {
UniqueID32 newId = m_idRestorer.originalToNew(id);
if (newId.isValid())
return newId.toUint32();
return id.toUint32();
}
void buildWorldPakList(const hecl::ProjectPath& worldPath, const hecl::ProjectPath& worldPathCooked, void buildWorldPakList(const hecl::ProjectPath& worldPath, const hecl::ProjectPath& worldPathCooked,
hecl::blender::Token& btok, athena::io::FileWriter& w, std::vector<urde::SObjectTag>& listOut, hecl::blender::Token& btok, athena::io::FileWriter& w, std::vector<urde::SObjectTag>& listOut,
atUint64& resTableOffset, atUint64& resTableOffset,
@ -1108,24 +999,24 @@ struct SpecMP1 : SpecBase {
DNAMP1::PAK::NameEntry nameEnt; DNAMP1::PAK::NameEntry nameEnt;
hecl::ProjectPath parentDir = worldPath.getParentPath(); hecl::ProjectPath parentDir = worldPath.getParentPath();
nameEnt.type = worldTag.type; nameEnt.type = worldTag.type;
nameEnt.id = newToOriginal(worldTag.id); nameEnt.id = worldTag.id.Value();
nameEnt.nameLen = atUint32(parentDir.getLastComponent().size()); nameEnt.nameLen = atUint32(parentDir.getLastComponent().size());
nameEnt.name = parentDir.getLastComponentUTF8(); nameEnt.name = parentDir.getLastComponentUTF8();
nameEnt.write(w); nameEnt.write(w);
std::unordered_set<urde::CAssetId> addedTags; std::unordered_set<urde::CAssetId> addedTags;
for (auto& area : mlvl.areas) { for (auto& area : mlvl.areas) {
urde::SObjectTag areaTag(FOURCC('MREA'), originalToNew(area.areaMREAId)); urde::SObjectTag areaTag(FOURCC('MREA'), area.areaMREAId.toUint64());
bool dupeRes = false; bool dupeRes = false;
if (hecl::ProjectPath areaDir = pathFromTag(areaTag).getParentPath()) if (hecl::ProjectPath areaDir = pathFromTag(areaTag).getParentPath())
dupeRes = hecl::ProjectPath(areaDir, _SYS_STR("!duperes")).isFile(); dupeRes = hecl::ProjectPath(areaDir, _SYS_STR("!duperes")).isFile();
urde::SObjectTag nameTag(FOURCC('STRG'), originalToNew(area.areaNameId)); urde::SObjectTag nameTag(FOURCC('STRG'), area.areaNameId.toUint64());
if (nameTag) if (nameTag)
listOut.push_back(nameTag); listOut.push_back(nameTag);
for (const auto& dep : area.deps) { for (const auto& dep : area.deps) {
urde::CAssetId newId = originalToNew(dep.id); urde::CAssetId newId = dep.id.toUint64();
if (dupeRes || addedTags.find(newId) == addedTags.end()) { if (dupeRes || addedTags.find(newId) == addedTags.end()) {
listOut.push_back({dep.type, newId}); listOut.push_back({dep.type, newId});
addedTags.insert(newId); addedTags.insert(newId);
@ -1160,18 +1051,18 @@ struct SpecMP1 : SpecBase {
area.depLayers = std::move(strippedDepLayers); area.depLayers = std::move(strippedDepLayers);
} }
urde::SObjectTag nameTag(FOURCC('STRG'), originalToNew(mlvl.worldNameId)); urde::SObjectTag nameTag(FOURCC('STRG'), mlvl.worldNameId.toUint64());
if (nameTag) if (nameTag)
listOut.push_back(nameTag); listOut.push_back(nameTag);
urde::SObjectTag savwTag(FOURCC('SAVW'), originalToNew(mlvl.saveWorldId)); urde::SObjectTag savwTag(FOURCC('SAVW'), mlvl.saveWorldId.toUint64());
if (savwTag) { if (savwTag) {
if (hecl::ProjectPath savwPath = pathFromTag(savwTag)) if (hecl::ProjectPath savwPath = pathFromTag(savwTag))
m_project.cookPath(savwPath, {}, false, true); m_project.cookPath(savwPath, {}, false, true);
listOut.push_back(savwTag); listOut.push_back(savwTag);
} }
urde::SObjectTag mapTag(FOURCC('MAPW'), originalToNew(mlvl.worldMap)); urde::SObjectTag mapTag(FOURCC('MAPW'), mlvl.worldMap.toUint64());
if (mapTag) { if (mapTag) {
if (hecl::ProjectPath mapPath = pathFromTag(mapTag)) { if (hecl::ProjectPath mapPath = pathFromTag(mapTag)) {
m_project.cookPath(mapPath, {}, false, true); m_project.cookPath(mapPath, {}, false, true);
@ -1187,14 +1078,14 @@ struct SpecMP1 : SpecBase {
for (atUint32 i = 0; i < mapaCount; ++i) { for (atUint32 i = 0; i < mapaCount; ++i) {
UniqueID32 id; UniqueID32 id;
id.read(r); id.read(r);
listOut.push_back({FOURCC('MAPA'), originalToNew(id)}); listOut.push_back({FOURCC('MAPA'), id.toUint64()});
} }
} }
} }
listOut.push_back(mapTag); listOut.push_back(mapTag);
} }
urde::SObjectTag skyboxTag(FOURCC('CMDL'), originalToNew(mlvl.worldSkyboxId)); urde::SObjectTag skyboxTag(FOURCC('CMDL'), mlvl.worldSkyboxId.toUint64());
if (skyboxTag) { if (skyboxTag) {
listOut.push_back(skyboxTag); listOut.push_back(skyboxTag);
hecl::ProjectPath skyboxPath = pathFromTag(skyboxTag); hecl::ProjectPath skyboxPath = pathFromTag(skyboxTag);
@ -1218,7 +1109,7 @@ struct SpecMP1 : SpecBase {
DNAMP1::PAK::Entry ent; DNAMP1::PAK::Entry ent;
ent.compressed = 0; ent.compressed = 0;
ent.type = item.type; ent.type = item.type;
ent.id = newToOriginal(item.id.Value()); ent.id = item.id.Value();
ent.size = 0; ent.size = 0;
ent.offset = 0; ent.offset = 0;
ent.write(w); ent.write(w);
@ -1229,8 +1120,8 @@ struct SpecMP1 : SpecBase {
size_t mlvlSize = 0; size_t mlvlSize = 0;
mlvl.binarySize(mlvlSize); mlvl.binarySize(mlvlSize);
mlvlOut.resize(mlvlSize); mlvlOut.resize(mlvlSize);
athena::io::MemoryWriter w(&mlvlOut[0], mlvlSize); athena::io::MemoryWriter mw(&mlvlOut[0], mlvlSize);
mlvl.write(w); mlvl.write(mw);
} }
} }
@ -1243,7 +1134,7 @@ struct SpecMP1 : SpecBase {
for (const auto& item : nameList) { for (const auto& item : nameList) {
DNAMP1::PAK::NameEntry nameEnt; DNAMP1::PAK::NameEntry nameEnt;
nameEnt.type = item.first.type; nameEnt.type = item.first.type;
nameEnt.id = newToOriginal(item.first.id); nameEnt.id = item.first.id.Value();
nameEnt.nameLen = atUint32(item.second.size()); nameEnt.nameLen = atUint32(item.second.size());
nameEnt.name = item.second; nameEnt.name = item.second;
nameEnt.write(w); nameEnt.write(w);
@ -1255,7 +1146,7 @@ struct SpecMP1 : SpecBase {
DNAMP1::PAK::Entry ent; DNAMP1::PAK::Entry ent;
ent.compressed = 0; ent.compressed = 0;
ent.type = item.type; ent.type = item.type;
ent.id = newToOriginal(item.id); ent.id = item.id.Value();
ent.size = 0; ent.size = 0;
ent.offset = 0; ent.offset = 0;
ent.write(w); ent.write(w);
@ -1272,7 +1163,7 @@ struct SpecMP1 : SpecBase {
DNAMP1::PAK::Entry ent; DNAMP1::PAK::Entry ent;
ent.compressed = atUint32(std::get<2>(item)); ent.compressed = atUint32(std::get<2>(item));
ent.type = tag.type; ent.type = tag.type;
ent.id = newToOriginal(tag.id); ent.id = tag.id.Value();
ent.size = atUint32(std::get<1>(item)); ent.size = atUint32(std::get<1>(item));
ent.offset = atUint32(std::get<0>(item)); ent.offset = atUint32(std::get<0>(item));
ent.write(w); ent.write(w);

View File

@ -25,80 +25,6 @@ static logvisor::Module Log("urde::SpecMP2");
extern hecl::Database::DataSpecEntry SpecEntMP2; extern hecl::Database::DataSpecEntry SpecEntMP2;
extern hecl::Database::DataSpecEntry SpecEntMP2ORIG; extern hecl::Database::DataSpecEntry SpecEntMP2ORIG;
static const std::unordered_set<uint32_t> IndividualOrigIDs = {
0xB7BBD0B4, 0x1F9DA858, 0x2A13C23E, 0xF13452F8, 0xA91A7703, 0xC042EC91, 0x12A12131, 0x5F556002, 0xA9798329,
0xB306E26F, 0xCD7B1ACA, 0x8ADA8184, 0x1A29C0E6, 0x5D9F9796, 0x951546A8, 0x7946C4C5, 0x409AA72E,
};
struct OriginalIDs {
static void Generate(PAKRouter<DNAMP2::PAKBridge>& pakRouter, hecl::Database::Project& project) {
std::unordered_set<UniqueID32> addedIDs;
std::vector<UniqueID32> originalIDs;
pakRouter.enumerateResources([&](const DNAMP2::PAK::Entry* ent) {
if (ent->type == FOURCC('MLVL') || ent->type == FOURCC('SCAN') || ent->type == FOURCC('MREA') ||
IndividualOrigIDs.find(ent->id.toUint32()) != IndividualOrigIDs.end()) {
if (addedIDs.find(ent->id) == addedIDs.cend()) {
addedIDs.insert(ent->id);
originalIDs.push_back(ent->id);
}
}
return true;
});
std::sort(originalIDs.begin(), originalIDs.end());
athena::io::YAMLDocWriter yamlW("MP2OriginalIDs");
for (const UniqueID32& id : originalIDs) {
hecl::ProjectPath path = pakRouter.getWorking(id);
yamlW.writeString(id.toString().c_str(), path.getRelativePathUTF8());
}
hecl::ProjectPath path(project.getProjectWorkingPath(), "MP2/!original_ids.yaml");
path.makeDirChain(false);
athena::io::FileWriter fileW(path.getAbsolutePath());
yamlW.finish(&fileW);
}
static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
hecl::Database::Project& project = inPath.getProject();
athena::io::YAMLDocReader r;
athena::io::FileReader fr(inPath.getAbsolutePath());
if (!fr.isOpen() || !r.parse(&fr))
return;
std::vector<std::pair<UniqueID32, UniqueID32>> originalIDs;
originalIDs.reserve(r.getRootNode()->m_mapChildren.size());
for (const auto& node : r.getRootNode()->m_mapChildren) {
char* end = const_cast<char*>(node.first.c_str());
u32 id = strtoul(end, &end, 16);
if (end != node.first.c_str() + 8)
continue;
hecl::ProjectPath path(project.getProjectWorkingPath(), node.second->m_scalarString.c_str());
originalIDs.push_back(std::make_pair(id, path.hash().val32()));
}
std::sort(originalIDs.begin(), originalIDs.end(),
[](const std::pair<UniqueID32, UniqueID32>& a, const std::pair<UniqueID32, UniqueID32>& b) {
return a.first < b.first;
});
athena::io::FileWriter w(outPath.getAbsolutePath());
w.writeUint32Big(originalIDs.size());
for (const auto& idPair : originalIDs) {
idPair.first.write(w);
idPair.second.write(w);
}
std::sort(originalIDs.begin(), originalIDs.end(),
[](const std::pair<UniqueID32, UniqueID32>& a, const std::pair<UniqueID32, UniqueID32>& b) {
return a.second < b.second;
});
for (const auto& idPair : originalIDs) {
idPair.second.write(w);
idPair.first.write(w);
}
}
};
struct SpecMP2 : SpecBase { struct SpecMP2 : SpecBase {
bool checkStandaloneID(const char* id) const override { bool checkStandaloneID(const char* id) const override {
if (!memcmp(id, "G2M", 3)) if (!memcmp(id, "G2M", 3))
@ -113,19 +39,12 @@ struct SpecMP2 : SpecBase {
hecl::ProjectPath m_workPath; hecl::ProjectPath m_workPath;
hecl::ProjectPath m_cookPath; hecl::ProjectPath m_cookPath;
PAKRouter<DNAMP2::PAKBridge> m_pakRouter; PAKRouter<DNAMP2::PAKBridge> m_pakRouter;
IDRestorer<UniqueID32> m_idRestorer;
void setThreadProject() override {
SpecBase::setThreadProject();
UniqueIDBridge::SetIDRestorer(&m_idRestorer);
}
SpecMP2(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) SpecMP2(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc)
: SpecBase(specEntry, project, pc) : SpecBase(specEntry, project, pc)
, m_workPath(project.getProjectWorkingPath(), _SYS_STR("MP2")) , m_workPath(project.getProjectWorkingPath(), _SYS_STR("MP2"))
, m_cookPath(project.getProjectCookedPath(SpecEntMP2), _SYS_STR("MP2")) , m_cookPath(project.getProjectCookedPath(SpecEntMP2), _SYS_STR("MP2"))
, m_pakRouter(*this, m_workPath, m_cookPath) , m_pakRouter(*this, m_workPath, m_cookPath) {
, m_idRestorer({project.getProjectWorkingPath(), "MP2/!original_ids.yaml"}, project) {
setThreadProject(); setThreadProject();
} }
@ -139,7 +58,7 @@ struct SpecMP2 : SpecBase {
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
if (name.size() > 4) { if (name.size() > 4) {
std::string::iterator extit = lowerName.end() - 4; std::string::iterator extit = lowerName.end() - 4;
if (!std::string(extit, lowerName.end()).compare(".pak")) { if (std::string(extit, lowerName.end()) == ".pak") {
/* This is a pak */ /* This is a pak */
isPak = true; isPak = true;
std::string lowerBase(lowerName.begin(), extit); std::string lowerBase(lowerName.begin(), extit);
@ -329,9 +248,6 @@ struct SpecMP2 : SpecBase {
process.waitUntilComplete(); process.waitUntilComplete();
/* Generate original ID mapping for MLVL and SCAN entries - marks complete project */
OriginalIDs::Generate(m_pakRouter, m_project);
return true; return true;
} }
@ -348,12 +264,12 @@ struct SpecMP2 : SpecBase {
bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override { bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override {
athena::io::YAMLDocReader reader; athena::io::YAMLDocReader reader;
yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp); yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp);
return reader.ClassTypeOperation([](const char* classType) { return reader.ClassTypeOperation([](std::string_view classType) {
if (!strcmp(classType, DNAMP2::MLVL::DNAType())) if (classType == DNAMP2::MLVL::DNAType())
return true; return true;
else if (!strcmp(classType, DNAMP2::STRG::DNAType())) else if (classType == DNAMP2::STRG::DNAType())
return true; return true;
else if (!strcmp(classType, "ATBL")) else if (classType == "ATBL")
return true; return true;
return false; return false;
}); });
@ -367,6 +283,9 @@ struct SpecMP2 : SpecBase {
void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override {} hecl::blender::Token& btok, FCookProgress progress) override {}
void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override {}
void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override {} hecl::blender::Token& btok, FCookProgress progress) override {}
@ -383,7 +302,7 @@ struct SpecMP2 : SpecBase {
hecl::blender::Token& btok, FCookProgress progress) override {} hecl::blender::Token& btok, FCookProgress progress) override {}
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin,
FCookProgress progress) override {} hecl::blender::Token& btok, FCookProgress progress) override {}
void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector<hecl::ProjectPath>& pathsOut) override {} void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector<hecl::ProjectPath>& pathsOut) override {}
@ -415,20 +334,6 @@ struct SpecMP2 : SpecBase {
DNAMAPU::MAPU::Cook(mapu, out); DNAMAPU::MAPU::Cook(mapu, out);
progress(_SYS_STR("Done")); progress(_SYS_STR("Done"));
} }
UniqueID32 newToOriginal(urde::CAssetId id) const {
UniqueID32 origId = m_idRestorer.newToOriginal({uint32_t(id.Value()), true});
if (origId.isValid())
return {origId.toUint32(), true};
return {uint32_t(id.Value()), true};
}
urde::CAssetId originalToNew(UniqueID32 id) const {
UniqueID32 newId = m_idRestorer.originalToNew(id);
if (newId.isValid())
return newId.toUint32();
return id.toUint32();
}
}; };
hecl::Database::DataSpecEntry SpecEntMP2( hecl::Database::DataSpecEntry SpecEntMP2(

View File

@ -24,77 +24,6 @@ static logvisor::Module Log("urde::SpecMP3");
extern hecl::Database::DataSpecEntry SpecEntMP3; extern hecl::Database::DataSpecEntry SpecEntMP3;
extern hecl::Database::DataSpecEntry SpecEntMP3ORIG; extern hecl::Database::DataSpecEntry SpecEntMP3ORIG;
static const std::unordered_set<uint64_t> IndividualOrigIDs = {};
struct OriginalIDs {
static void Generate(PAKRouter<DNAMP3::PAKBridge>& pakRouter, hecl::Database::Project& project) {
std::unordered_set<UniqueID64> addedIDs;
std::vector<UniqueID64> originalIDs;
pakRouter.enumerateResources([&](const DNAMP3::PAK::Entry* ent) {
if (ent->type == FOURCC('MLVL') || ent->type == FOURCC('SCAN') || ent->type == FOURCC('MREA') ||
IndividualOrigIDs.find(ent->id.toUint64()) != IndividualOrigIDs.end()) {
if (addedIDs.find(ent->id) == addedIDs.cend()) {
addedIDs.insert(ent->id);
originalIDs.push_back(ent->id);
}
}
return true;
});
std::sort(originalIDs.begin(), originalIDs.end());
athena::io::YAMLDocWriter yamlW("MP3OriginalIDs");
for (const UniqueID64& id : originalIDs) {
hecl::ProjectPath path = pakRouter.getWorking(id);
yamlW.writeString(id.toString().c_str(), path.getRelativePathUTF8());
}
hecl::ProjectPath path(project.getProjectWorkingPath(), "MP3/!original_ids.yaml");
path.makeDirChain(false);
athena::io::FileWriter fileW(path.getAbsolutePath());
yamlW.finish(&fileW);
}
static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) {
hecl::Database::Project& project = inPath.getProject();
athena::io::YAMLDocReader r;
athena::io::FileReader fr(inPath.getAbsolutePath());
if (!fr.isOpen() || !r.parse(&fr))
return;
std::vector<std::pair<UniqueID64, UniqueID64>> originalIDs;
originalIDs.reserve(r.getRootNode()->m_mapChildren.size());
for (const auto& node : r.getRootNode()->m_mapChildren) {
char* end = const_cast<char*>(node.first.c_str());
u32 id = strtoul(end, &end, 16);
if (end != node.first.c_str() + 8)
continue;
hecl::ProjectPath path(project.getProjectWorkingPath(), node.second->m_scalarString.c_str());
originalIDs.push_back(std::make_pair(id, path.hash().val32()));
}
std::sort(originalIDs.begin(), originalIDs.end(),
[](const std::pair<UniqueID64, UniqueID64>& a, const std::pair<UniqueID64, UniqueID64>& b) {
return a.first < b.first;
});
athena::io::FileWriter w(outPath.getAbsolutePath());
w.writeUint32Big(originalIDs.size());
for (const auto& idPair : originalIDs) {
idPair.first.write(w);
idPair.second.write(w);
}
std::sort(originalIDs.begin(), originalIDs.end(),
[](const std::pair<UniqueID64, UniqueID64>& a, const std::pair<UniqueID64, UniqueID64>& b) {
return a.second < b.second;
});
for (const auto& idPair : originalIDs) {
idPair.second.write(w);
idPair.first.write(w);
}
}
};
struct SpecMP3 : SpecBase { struct SpecMP3 : SpecBase {
bool checkStandaloneID(const char* id) const override { bool checkStandaloneID(const char* id) const override {
if (!memcmp(id, "RM3", 3)) if (!memcmp(id, "RM3", 3))
@ -120,12 +49,6 @@ struct SpecMP3 : SpecBase {
hecl::ProjectPath m_feWorkPath; hecl::ProjectPath m_feWorkPath;
hecl::ProjectPath m_feCookPath; hecl::ProjectPath m_feCookPath;
PAKRouter<DNAMP3::PAKBridge> m_fePakRouter; PAKRouter<DNAMP3::PAKBridge> m_fePakRouter;
IDRestorer<UniqueID64> m_idRestorer;
void setThreadProject() override {
SpecBase::setThreadProject();
UniqueIDBridge::SetIDRestorer(&m_idRestorer);
}
SpecMP3(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) SpecMP3(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc)
: SpecBase(specEntry, project, pc) : SpecBase(specEntry, project, pc)
@ -134,8 +57,7 @@ struct SpecMP3 : SpecBase {
, m_pakRouter(*this, m_workPath, m_cookPath) , m_pakRouter(*this, m_workPath, m_cookPath)
, m_feWorkPath(project.getProjectWorkingPath(), _SYS_STR("fe")) , m_feWorkPath(project.getProjectWorkingPath(), _SYS_STR("fe"))
, m_feCookPath(project.getProjectCookedPath(SpecEntMP3), _SYS_STR("fe")) , m_feCookPath(project.getProjectCookedPath(SpecEntMP3), _SYS_STR("fe"))
, m_fePakRouter(*this, m_feWorkPath, m_feCookPath) , m_fePakRouter(*this, m_feWorkPath, m_feCookPath) {
, m_idRestorer({project.getProjectWorkingPath(), "MP3/!original_ids.yaml"}, project) {
setThreadProject(); setThreadProject();
} }
@ -154,7 +76,7 @@ struct SpecMP3 : SpecBase {
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
if (name.size() > 4) { if (name.size() > 4) {
std::string::iterator extit = lowerName.end() - 4; std::string::iterator extit = lowerName.end() - 4;
if (!std::string(extit, lowerName.end()).compare(".pak")) { if (std::string(extit, lowerName.end()) == ".pak") {
/* This is a pak */ /* This is a pak */
isPak = true; isPak = true;
std::string lowerBase(lowerName.begin(), extit); std::string lowerBase(lowerName.begin(), extit);
@ -217,13 +139,13 @@ struct SpecMP3 : SpecBase {
ExtractReport& childRep = rep.childOpts.back(); ExtractReport& childRep = rep.childOpts.back();
hecl::SystemStringConv nameView(item.first); hecl::SystemStringConv nameView(item.first);
childRep.name = hecl::SystemString(nameView.sys_str()); childRep.name = hecl::SystemString(nameView.sys_str());
if (!item.first.compare("Worlds.pak")) if (item.first == "Worlds.pak")
continue; continue;
else if (!item.first.compare("Metroid6.pak")) { else if (item.first == "Metroid6.pak") {
/* Phaaze doesn't have a world name D: */ /* Phaaze doesn't have a world name D: */
childRep.desc = _SYS_STR("Phaaze"); childRep.desc = _SYS_STR("Phaaze");
continue; continue;
} else if (!item.first.compare("Metroid8.pak")) { } else if (item.first == "Metroid8.pak") {
/* Space world is misnamed */ /* Space world is misnamed */
childRep.desc = _SYS_STR("Space"); childRep.desc = _SYS_STR("Space");
continue; continue;
@ -440,9 +362,6 @@ struct SpecMP3 : SpecBase {
} }
process.waitUntilComplete(); process.waitUntilComplete();
/* Generate original ID mapping for MLVL and SCAN entries - marks complete project */
OriginalIDs::Generate(m_pakRouter, m_project);
} }
if (doMPTFE) { if (doMPTFE) {
@ -525,6 +444,9 @@ struct SpecMP3 : SpecBase {
void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override {} hecl::blender::Token& btok, FCookProgress progress) override {}
void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override {}
void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
hecl::blender::Token& btok, FCookProgress progress) override {} hecl::blender::Token& btok, FCookProgress progress) override {}
@ -541,7 +463,7 @@ struct SpecMP3 : SpecBase {
hecl::blender::Token& btok, FCookProgress progress) override {} hecl::blender::Token& btok, FCookProgress progress) override {}
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin,
FCookProgress progress) override {} hecl::blender::Token& btok, FCookProgress progress) override {}
void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector<hecl::ProjectPath>& pathsOut) override {} void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector<hecl::ProjectPath>& pathsOut) override {}
@ -562,20 +484,6 @@ struct SpecMP3 : SpecBase {
void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
hecl::blender::Token& btok, FCookProgress progress) override {} hecl::blender::Token& btok, FCookProgress progress) override {}
UniqueID64 newToOriginal(urde::CAssetId id) const {
UniqueID64 origId = m_idRestorer.newToOriginal({id.Value(), true});
if (origId.isValid())
return {origId.toUint64(), true};
return {uint32_t(id.Value()), true};
}
urde::CAssetId originalToNew(UniqueID64 id) const {
UniqueID64 newId = m_idRestorer.originalToNew(id);
if (newId.isValid())
return newId.toUint64();
return id.toUint64();
}
}; };
hecl::Database::DataSpecEntry SpecEntMP3( hecl::Database::DataSpecEntry SpecEntMP3(

View File

@ -35,7 +35,6 @@
#include "Runtime/CDependencyGroup.hpp" #include "Runtime/CDependencyGroup.hpp"
#include "DataSpec/DNACommon/TXTR.hpp" #include "DataSpec/DNACommon/TXTR.hpp"
#include "CSimplePool.hpp" #include "CSimplePool.hpp"
#include "MP1/MP1OriginalIDs.hpp"
#include "GameGlobalObjects.hpp" #include "GameGlobalObjects.hpp"
namespace DataSpec { namespace DataSpec {
@ -66,7 +65,6 @@ ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& client
m_factoryMgr.AddFactory(FOURCC('HINT'), FFactoryFunc(FHintFactory)); m_factoryMgr.AddFactory(FOURCC('HINT'), FFactoryFunc(FHintFactory));
m_factoryMgr.AddFactory(FOURCC('SAVW'), FFactoryFunc(FSaveWorldFactory)); m_factoryMgr.AddFactory(FOURCC('SAVW'), FFactoryFunc(FSaveWorldFactory));
m_factoryMgr.AddFactory(FOURCC('MAPW'), FFactoryFunc(FMapWorldFactory)); m_factoryMgr.AddFactory(FOURCC('MAPW'), FFactoryFunc(FMapWorldFactory));
m_factoryMgr.AddFactory(FOURCC('OIDS'), FFactoryFunc(FMP1OriginalIDsFactory));
m_factoryMgr.AddFactory(FOURCC('SCAN'), FFactoryFunc(FScannableObjectInfoFactory)); m_factoryMgr.AddFactory(FOURCC('SCAN'), FFactoryFunc(FScannableObjectInfoFactory));
m_factoryMgr.AddFactory(FOURCC('CRSC'), FFactoryFunc(FCollisionResponseDataFactory)); m_factoryMgr.AddFactory(FOURCC('CRSC'), FFactoryFunc(FCollisionResponseDataFactory));
m_factoryMgr.AddFactory(FOURCC('SWHC'), FFactoryFunc(FParticleSwooshDataFactory)); m_factoryMgr.AddFactory(FOURCC('SWHC'), FFactoryFunc(FParticleSwooshDataFactory));
@ -80,20 +78,6 @@ ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& client
void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj, CSimplePool& sp) { void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj, CSimplePool& sp) {
BeginBackgroundIndex(proj, DataSpec::SpecEntMP1, DataSpec::SpecEntMP1PC); BeginBackgroundIndex(proj, DataSpec::SpecEntMP1, DataSpec::SpecEntMP1PC);
m_origIds = sp.GetObj("MP1OriginalIDs");
}
void ProjectResourceFactoryMP1::Shutdown() {
m_origIds = TLockedToken<MP1OriginalIDs>();
ProjectResourceFactoryBase::Shutdown();
}
CAssetId ProjectResourceFactoryMP1::TranslateOriginalToNew(CAssetId id) const {
return m_origIds->TranslateOriginalToNew(id);
}
CAssetId ProjectResourceFactoryMP1::TranslateNewToOriginal(CAssetId id) const {
return m_origIds->TranslateNewToOriginal(id);
} }
} // namespace urde } // namespace urde

View File

@ -8,15 +8,9 @@ class MP1OriginalIDs;
class CSimplePool; class CSimplePool;
class ProjectResourceFactoryMP1 : public ProjectResourceFactoryBase { class ProjectResourceFactoryMP1 : public ProjectResourceFactoryBase {
TLockedToken<MP1OriginalIDs> m_origIds;
public: public:
ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc); ProjectResourceFactoryMP1(hecl::ClientProcess& clientProc);
void IndexMP1Resources(hecl::Database::Project& proj, CSimplePool& sp); void IndexMP1Resources(hecl::Database::Project& proj, CSimplePool& sp);
void Shutdown();
CAssetId TranslateOriginalToNew(CAssetId id) const override;
CAssetId TranslateNewToOriginal(CAssetId id) const override;
}; };
} // namespace urde } // namespace urde

View File

@ -40,7 +40,7 @@ void ResourceBrowser::pathButtonActivated(size_t idx) {
for (const hecl::SystemString& d : m_comps) { for (const hecl::SystemString& d : m_comps) {
if (needSlash) if (needSlash)
dir += _SYS_STR('/'); dir += _SYS_STR('/');
if (d.compare(_SYS_STR("/"))) if (d != _SYS_STR("/"))
needSlash = true; needSlash = true;
dir += d; dir += d;
if (++i > idx) if (++i > idx)

@ -1 +1 @@
Subproject commit c8a6e95514d8e54bd57b4420d2957ac33c12baa8 Subproject commit 9b765b58cf7389014f7e89a9dfb92da98ce89962

View File

@ -150,7 +150,7 @@ static const u8 MinesPostTransformIndices[] = {
}; };
zeus::CTransform CMapArea::GetAreaPostTransform(const IWorld& world, TAreaId aid) const { zeus::CTransform CMapArea::GetAreaPostTransform(const IWorld& world, TAreaId aid) const {
if (world.IGetWorldAssetId() == g_ResFactory->TranslateOriginalToNew(0xB1AC4D65)) // Phazon Mines if (world.IGetWorldAssetId() == 0xB1AC4D65) // Phazon Mines
{ {
const zeus::CTransform& areaXf = world.IGetAreaAlways(aid)->IGetTM(); const zeus::CTransform& areaXf = world.IGetAreaAlways(aid)->IGetTM();
const zeus::CVector3f& postVec = MinesPostTransforms[MinesPostTransformIndices[aid]]; const zeus::CVector3f& postVec = MinesPostTransforms[MinesPostTransformIndices[aid]];
@ -161,7 +161,7 @@ zeus::CTransform CMapArea::GetAreaPostTransform(const IWorld& world, TAreaId aid
} }
const zeus::CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, TAreaId aid) { const zeus::CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, TAreaId aid) {
if (world.IGetWorldAssetId() == g_ResFactory->TranslateOriginalToNew(0xB1AC4D65)) // Phazon Mines if (world.IGetWorldAssetId() == 0xB1AC4D65) // Phazon Mines
return MinesPostTransforms[MinesPostTransformIndices[aid]]; return MinesPostTransforms[MinesPostTransformIndices[aid]];
else else
return zeus::skZero3f; return zeus::skZero3f;

View File

@ -33,7 +33,7 @@ CGameHintInfo::SHintLocation::SHintLocation(CInputStream& in, s32)
int CGameHintInfo::FindHintIndex(const char* str) { int CGameHintInfo::FindHintIndex(const char* str) {
const std::vector<CGameHint>& gameHints = g_MemoryCardSys->GetHints(); const std::vector<CGameHint>& gameHints = g_MemoryCardSys->GetHints();
const auto& it = std::find_if(gameHints.begin(), gameHints.end(), const auto& it = std::find_if(gameHints.begin(), gameHints.end(),
[&str](const CGameHint& gh) -> bool { return !gh.GetName().compare(str); }); [&str](const CGameHint& gh) -> bool { return gh.GetName() == str; });
return (it != gameHints.end() ? it - gameHints.begin() : -1); return (it != gameHints.end() ? it - gameHints.begin() : -1);
} }

View File

@ -336,10 +336,6 @@ const std::array<std::pair<CAssetId, CAssetId>, 5> CStickOutlineToDPadRemap{{
{0x409AA72E, 0x8ADA8184}, {0x409AA72E, 0x8ADA8184},
}}; }};
static std::pair<CAssetId, CAssetId> TranslatePairToNew(const std::pair<CAssetId, CAssetId>& p) {
return {g_ResFactory->TranslateOriginalToNew(p.first), g_ResFactory->TranslateOriginalToNew(p.second)};
}
void CGameOptions::ResetControllerAssets(int controls) { void CGameOptions::ResetControllerAssets(int controls) {
if (controls != 1) { if (controls != 1) {
x6c_controlTxtrMap.clear(); x6c_controlTxtrMap.clear();
@ -347,12 +343,12 @@ void CGameOptions::ResetControllerAssets(int controls) {
x6c_controlTxtrMap.reserve(15); x6c_controlTxtrMap.reserve(15);
for (const auto& entry : CStickToDPadRemap) { for (const auto& entry : CStickToDPadRemap) {
const auto& emplaced = x6c_controlTxtrMap.emplace_back(TranslatePairToNew(entry)); const auto& emplaced = x6c_controlTxtrMap.emplace_back(entry);
x6c_controlTxtrMap.emplace_back(emplaced.second, emplaced.first); x6c_controlTxtrMap.emplace_back(emplaced.second, emplaced.first);
} }
for (const auto& entry : CStickOutlineToDPadRemap) for (const auto& entry : CStickOutlineToDPadRemap)
x6c_controlTxtrMap.emplace_back(TranslatePairToNew(entry)); x6c_controlTxtrMap.emplace_back(entry);
std::sort(x6c_controlTxtrMap.begin(), x6c_controlTxtrMap.end(), std::sort(x6c_controlTxtrMap.begin(), x6c_controlTxtrMap.end(),
[](const std::pair<CAssetId, CAssetId>& a, const std::pair<CAssetId, CAssetId>& b) { [](const std::pair<CAssetId, CAssetId>& a, const std::pair<CAssetId, CAssetId>& b) {

View File

@ -100,7 +100,7 @@ CGameState::GameFileStateInfo CGameState::LoadGameFileState(const u8* data) {
ret.x20_hardMode = stream.ReadEncoded(1); ret.x20_hardMode = stream.ReadEncoded(1);
stream.ReadEncoded(1); stream.ReadEncoded(1);
CAssetId origMLVL = u32(stream.ReadEncoded(32)); CAssetId origMLVL = u32(stream.ReadEncoded(32));
ret.x8_mlvlId = g_ResFactory->TranslateOriginalToNew(origMLVL); ret.x8_mlvlId = origMLVL;
BitsToDouble conv; BitsToDouble conv;
conv.low = stream.ReadEncoded(32); conv.low = stream.ReadEncoded(32);
@ -146,7 +146,7 @@ CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx) : x20c_saveFileIdx
x228_24_hardMode = stream.ReadEncoded(1); x228_24_hardMode = stream.ReadEncoded(1);
x228_25_initPowerupsAtFirstSpawn = stream.ReadEncoded(1); x228_25_initPowerupsAtFirstSpawn = stream.ReadEncoded(1);
x84_mlvlId = g_ResFactory->TranslateOriginalToNew(u32(stream.ReadEncoded(32))); x84_mlvlId = u32(stream.ReadEncoded(32));
MP1::CMain::EnsureWorldPakReady(x84_mlvlId); MP1::CMain::EnsureWorldPakReady(x84_mlvlId);
BitsToDouble conv; BitsToDouble conv;
@ -209,7 +209,7 @@ void CGameState::PutTo(CBitStreamWriter& writer) const {
writer.WriteEncoded(CBasics::ToWiiTime(std::chrono::system_clock::now()) / CBasics::TICKS_PER_SECOND, 32); writer.WriteEncoded(CBasics::ToWiiTime(std::chrono::system_clock::now()) / CBasics::TICKS_PER_SECOND, 32);
writer.WriteEncoded(x228_24_hardMode, 1); writer.WriteEncoded(x228_24_hardMode, 1);
writer.WriteEncoded(x228_25_initPowerupsAtFirstSpawn, 1); writer.WriteEncoded(x228_25_initPowerupsAtFirstSpawn, 1);
writer.WriteEncoded(g_ResFactory->TranslateNewToOriginal(x84_mlvlId).Value(), 32); writer.WriteEncoded(x84_mlvlId.Value(), 32);
BitsToDouble conv; BitsToDouble conv;
conv.doub = xa0_playTime; conv.doub = xa0_playTime;

View File

@ -71,22 +71,19 @@ CMemoryCardSys::CMemoryCardSys() {
x1c_worldInter.emplace(); x1c_worldInter.emplace();
x1c_worldInter->reserve(16); x1c_worldInter->reserve(16);
std::vector<std::pair<CAssetId, CAssetId>> orderedMLVLs; std::vector<CAssetId> orderedMLVLs;
orderedMLVLs.reserve(16); orderedMLVLs.reserve(16);
g_ResFactory->EnumerateNamedResources([&](std::string_view name, const SObjectTag& tag) -> bool { g_ResFactory->EnumerateNamedResources([&](std::string_view name, const SObjectTag& tag) -> bool {
if (tag.type == FOURCC('MLVL')) { if (tag.type == FOURCC('MLVL'))
CAssetId origId = g_ResFactory->TranslateNewToOriginal(tag.id); orderedMLVLs.emplace_back(tag.id);
orderedMLVLs.emplace_back(origId, tag.id);
}
return true; return true;
}); });
std::sort(orderedMLVLs.begin(), orderedMLVLs.end(), std::sort(orderedMLVLs.begin(), orderedMLVLs.end());
[](const auto& a, const auto& b) -> bool { return a.first < b.first; });
for (const auto& mlvl : orderedMLVLs) { for (const auto& mlvl : orderedMLVLs) {
if (!HasSaveWorldMemory(mlvl.second)) { if (!HasSaveWorldMemory(mlvl)) {
xc_memoryWorlds.emplace_back(mlvl.second, CSaveWorldMemory{}); xc_memoryWorlds.emplace_back(mlvl, CSaveWorldMemory{});
x1c_worldInter->emplace_back(mlvl.second, -1); x1c_worldInter->emplace_back(mlvl, CAssetId{});
} }
} }
@ -143,8 +140,8 @@ bool CMemoryCardSys::InitializePump() {
} }
if (done) { if (done) {
std::sort(x20_scanStates.begin(), x20_scanStates.end(), [&](const auto& a, const auto& b) -> bool { std::sort(x20_scanStates.begin(), x20_scanStates.end(), [&](const auto& a, const auto& b) {
return g_ResFactory->TranslateNewToOriginal(a.first) < g_ResFactory->TranslateNewToOriginal(b.first); return a.first < b.first;
}); });
x1c_worldInter = std::nullopt; x1c_worldInter = std::nullopt;
} }

View File

@ -110,28 +110,4 @@ void CResFactory::LoadPersistentResources(CSimplePool& sp) {
} }
} }
void CResFactory::LoadOriginalIDs(CSimplePool& sp) {
#if RUNTIME_ORIGINAL_IDS
m_origIds = sp.GetObj("MP1OriginalIDs");
#endif
}
CAssetId CResFactory::TranslateOriginalToNew(CAssetId id) const {
#if RUNTIME_ORIGINAL_IDS
return m_origIds->TranslateOriginalToNew(id);
#else
/* The packager will have restored these ahead of time */
return id;
#endif
}
CAssetId CResFactory::TranslateNewToOriginal(CAssetId id) const {
#if RUNTIME_ORIGINAL_IDS
return m_origIds->TranslateNewToOriginal(id);
#else
/* The packager will have restored these ahead of time */
return id;
#endif
}
} // namespace urde } // namespace urde

View File

@ -4,7 +4,6 @@
#include "IFactory.hpp" #include "IFactory.hpp"
#include "CResLoader.hpp" #include "CResLoader.hpp"
#include "IVParamObj.hpp" #include "IVParamObj.hpp"
#include "MP1/MP1OriginalIDs.hpp"
#include "CToken.hpp" #include "CToken.hpp"
namespace urde { namespace urde {
@ -14,9 +13,6 @@ class CSimplePool;
class CResFactory : public IFactory { class CResFactory : public IFactory {
CResLoader x4_loader; CResLoader x4_loader;
CFactoryMgr x5c_factoryMgr; CFactoryMgr x5c_factoryMgr;
#if RUNTIME_ORIGINAL_IDS
TLockedToken<MP1OriginalIDs> m_origIds;
#endif
public: public:
struct SLoadingData { struct SLoadingData {
@ -97,10 +93,6 @@ public:
void LoadPersistentResources(CSimplePool& sp); void LoadPersistentResources(CSimplePool& sp);
void UnloadPersistentResources() { m_nonWorldTokens.clear(); } void UnloadPersistentResources() { m_nonWorldTokens.clear(); }
void LoadOriginalIDs(CSimplePool& sp) override;
CAssetId TranslateOriginalToNew(CAssetId id) const override;
CAssetId TranslateNewToOriginal(CAssetId id) const override;
CResLoader* GetResLoader() override { return &x4_loader; } CResLoader* GetResLoader() override { return &x4_loader; }
CFactoryMgr* GetFactoryMgr() override { return &x5c_factoryMgr; } CFactoryMgr* GetFactoryMgr() override { return &x5c_factoryMgr; }
}; };

View File

@ -165,21 +165,21 @@ u32 CAnimSourceReaderBase::VGetSoundPOIList(const CCharAnimTime& time, CSoundPOI
bool CAnimSourceReaderBase::VGetBoolPOIState(const char* name) const { bool CAnimSourceReaderBase::VGetBoolPOIState(const char* name) const {
for (const auto& node : x24_boolStates) for (const auto& node : x24_boolStates)
if (!node.first.compare(name)) if (node.first == name)
return node.second; return node.second;
return false; return false;
} }
s32 CAnimSourceReaderBase::VGetInt32POIState(const char* name) const { s32 CAnimSourceReaderBase::VGetInt32POIState(const char* name) const {
for (const auto& node : x34_int32States) for (const auto& node : x34_int32States)
if (!node.first.compare(name)) if (node.first == name)
return node.second; return node.second;
return 0; return 0;
} }
CParticleData::EParentedMode CAnimSourceReaderBase::VGetParticlePOIState(const char* name) const { CParticleData::EParentedMode CAnimSourceReaderBase::VGetParticlePOIState(const char* name) const {
for (const auto& node : x44_particleStates) for (const auto& node : x44_particleStates)
if (!node.first.compare(name)) if (node.first == name)
return node.second; return node.second;
return CParticleData::EParentedMode::Initial; return CParticleData::EParentedMode::Initial;
} }

View File

@ -88,7 +88,7 @@ CCharacterInfo::CCharacterInfo(CInputStream& in)
const s32 CCharacterInfo::GetAnimationIndex(std::string_view name) const { const s32 CCharacterInfo::GetAnimationIndex(std::string_view name) const {
for (const auto& pair : x20_animInfo) { for (const auto& pair : x20_animInfo) {
if (pair.second.second.compare(name.data()) == 0) if (pair.second.second == name)
return pair.first; return pair.first;
} }

View File

@ -37,7 +37,7 @@ CCharAnimTime IMetaAnim::GetTime(const CPreAdvanceIndicator& ind, const IAnimRea
const char* cmpStr = ind.GetString(); const char* cmpStr = ind.GetString();
for (u32 i = 0; i < count; ++i) { for (u32 i = 0; i < count; ++i) {
CBoolPOINode& node = nodes[i]; CBoolPOINode& node = nodes[i];
if (node.GetString().compare(cmpStr) || !node.GetValue()) if (node.GetString() != cmpStr || !node.GetValue())
continue; continue;
return node.GetTime(); return node.GetTime();
} }

View File

@ -222,7 +222,7 @@ void CGuiTextSupport::AddText(std::u16string_view str) {
} }
void CGuiTextSupport::SetText(std::u16string_view str, bool multipage) { void CGuiTextSupport::SetText(std::u16string_view str, bool multipage) {
if (x0_string.compare(str)) { if (x0_string != str) {
x40_primStartTimes.clear(); x40_primStartTimes.clear();
x3c_curTime = 0.f; x3c_curTime = 0.f;
x0_string = str; x0_string = str;

View File

@ -33,7 +33,6 @@ public:
EnumerateNamedResources(const std::function<bool(std::string_view, const SObjectTag&)>& lambda) const = 0; EnumerateNamedResources(const std::function<bool(std::string_view, const SObjectTag&)>& lambda) const = 0;
virtual CResLoader* GetResLoader() { return nullptr; } virtual CResLoader* GetResLoader() { return nullptr; }
virtual CFactoryMgr* GetFactoryMgr() { return nullptr; } virtual CFactoryMgr* GetFactoryMgr() { return nullptr; }
virtual void LoadOriginalIDs(CSimplePool& sp) {}
virtual void AsyncIdle() {} virtual void AsyncIdle() {}
/* Non-factory versions, replaces CResLoader */ /* Non-factory versions, replaces CResLoader */
@ -44,9 +43,6 @@ public:
virtual std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag) = 0; virtual std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag) = 0;
virtual std::unique_ptr<u8[]> LoadNewResourcePartSync(const urde::SObjectTag& tag, u32 off, u32 size) = 0; virtual std::unique_ptr<u8[]> LoadNewResourcePartSync(const urde::SObjectTag& tag, u32 off, u32 size) = 0;
virtual void GetTagListForFile(const char* pakName, std::vector<SObjectTag>& out) const {} virtual void GetTagListForFile(const char* pakName, std::vector<SObjectTag>& out) const {}
virtual CAssetId TranslateOriginalToNew(CAssetId id) const { return {}; }
virtual CAssetId TranslateNewToOriginal(CAssetId id) const { return {}; }
}; };
} // namespace urde } // namespace urde

View File

@ -49,9 +49,8 @@ CArtifactDoll::CArtifactDoll() {
} }
int CArtifactDoll::GetArtifactHeadScanIndex(CAssetId scanId) { int CArtifactDoll::GetArtifactHeadScanIndex(CAssetId scanId) {
CAssetId orig = g_ResFactory->TranslateNewToOriginal(scanId);
for (int i = 0; i < 12; ++i) for (int i = 0; i < 12; ++i)
if (ArtifactHeadScans[i] == orig) if (ArtifactHeadScans[i] == scanId)
return i; return i;
return -1; return -1;
} }
@ -59,15 +58,15 @@ int CArtifactDoll::GetArtifactHeadScanIndex(CAssetId scanId) {
CAssetId CArtifactDoll::GetArtifactHeadScanFromItemType(CPlayerState::EItemType item) { CAssetId CArtifactDoll::GetArtifactHeadScanFromItemType(CPlayerState::EItemType item) {
if (item < CPlayerState::EItemType::Truth || item > CPlayerState::EItemType::Newborn) if (item < CPlayerState::EItemType::Truth || item > CPlayerState::EItemType::Newborn)
return -1; return -1;
return g_ResFactory->TranslateOriginalToNew(ArtifactHeadScans[int(item) - 29]); return ArtifactHeadScans[int(item) - 29];
} }
void CArtifactDoll::UpdateArtifactHeadScan(const CStateManager& mgr, float delta) { void CArtifactDoll::UpdateArtifactHeadScan(const CStateManager& mgr, float delta) {
CPlayerState& playerState = *mgr.GetPlayerState(); CPlayerState& playerState = *mgr.GetPlayerState();
for (int i = 0; i < 12; ++i) { for (int i = 0; i < 12; ++i) {
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType(i + 29))) { if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType(i + 29))) {
CAssetId newId = g_ResFactory->TranslateOriginalToNew(ArtifactHeadScans[i]); CAssetId id = ArtifactHeadScans[i];
playerState.SetScanTime(newId, std::min(playerState.GetScanTime(newId) + delta, 1.f)); playerState.SetScanTime(id, std::min(playerState.GetScanTime(id) + delta, 1.f));
} }
} }
} }
@ -94,8 +93,7 @@ void CArtifactDoll::Draw(float alpha, const CStateManager& mgr, bool inArtifactC
zeus::CColor color = ArtifactPreColor; zeus::CColor color = ArtifactPreColor;
if (playerState.HasPowerUp(CPlayerState::EItemType(i + 29))) { if (playerState.HasPowerUp(CPlayerState::EItemType(i + 29))) {
if (ArtifactHeadScans[i].IsValid()) { if (ArtifactHeadScans[i].IsValid()) {
CAssetId newId = g_ResFactory->TranslateOriginalToNew(ArtifactHeadScans[i]); float interp = (playerState.GetScanTime(ArtifactHeadScans[i]) - 0.5f) * 2.f;
float interp = (playerState.GetScanTime(newId) - 0.5f) * 2.f;
if (interp < 0.5f) if (interp < 0.5f)
color = zeus::CColor::lerp(ArtifactPreColor, zeus::skWhite, 2.f * interp); color = zeus::CColor::lerp(ArtifactPreColor, zeus::skWhite, 2.f * interp);
else else

View File

@ -1721,7 +1721,7 @@ CFrontEndUI::CFrontEndUI() : CIOWin("FrontEndUI") {
xdc_saveUI = std::make_unique<CSaveGameScreen>(ESaveContext::FrontEnd, g_GameState->GetCardSerial()); xdc_saveUI = std::make_unique<CSaveGameScreen>(ESaveContext::FrontEnd, g_GameState->GetCardSerial());
m->ResetGameState(); m->ResetGameState();
g_GameState->SetCurrentWorldId(g_ResFactory->TranslateOriginalToNew(g_DefaultWorldTag.id)); g_GameState->SetCurrentWorldId(g_DefaultWorldTag.id);
g_GameState->GameOptions().ResetToDefaults(); g_GameState->GameOptions().ResetToDefaults();
g_GameState->WriteBackupBuf(); g_GameState->WriteBackupBuf();

View File

@ -259,8 +259,7 @@ CMFGameLoader::CMFGameLoader() : CMFGameLoaderBase("CMFGameLoader") {
if (g_MemoryCardSys->HasSaveWorldMemory(mlvlId)) { if (g_MemoryCardSys->HasSaveWorldMemory(mlvlId)) {
const CSaveWorldMemory& savwMem = g_MemoryCardSys->GetSaveWorldMemory(mlvlId); const CSaveWorldMemory& savwMem = g_MemoryCardSys->GetSaveWorldMemory(mlvlId);
if (savwMem.GetWorldNameId().IsValid()) { if (savwMem.GetWorldNameId().IsValid()) {
CAssetId wtMgrFont = g_ResFactory->TranslateOriginalToNew(0xB7BBD0B4); g_GameState->GetWorldTransitionManager()->EnableTransition(0xB7BBD0B4, savwMem.GetWorldNameId(), 1, false, 0.1f,
g_GameState->GetWorldTransitionManager()->EnableTransition(wtMgrFont, savwMem.GetWorldNameId(), 1, false, 0.1f,
16.f, 1.f); 16.f, 1.f);
} }
} }
@ -270,7 +269,7 @@ CMFGameLoader::CMFGameLoader() : CMFGameLoaderBase("CMFGameLoader") {
break; break;
} }
if (g_GameState->CurrentWorldAssetId() == g_ResFactory->TranslateOriginalToNew(0x158EFE17) && if (g_GameState->CurrentWorldAssetId() == 0x158EFE17 &&
g_GameState->CurrentWorldState().GetCurrentAreaId() == 0) { g_GameState->CurrentWorldState().GetCurrentAreaId() == 0) {
const SObjectTag* strgTag = g_ResFactory->GetResourceIdByName("STRG_IntroLevelLoad"); const SObjectTag* strgTag = g_ResFactory->GetResourceIdByName("STRG_IntroLevelLoad");
if (strgTag) if (strgTag)

Some files were not shown because too many files have changed in this diff Show More