mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-13 12:52:32 +08:00
chore: clang-format and code formatting done with an extra of code cleanup
Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
parent
f89cc438f8
commit
b8fd1eefac
225
.clang-format
Normal file
225
.clang-format
Normal file
@ -0,0 +1,225 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: true
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
PadOperators: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments:
|
||||
Kind: Always
|
||||
OverEmptyLines: 0
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterExternBlock: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakAfterAttributes: Never
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakArrays: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInlineASMColon: OnlyMultiline
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertBraces: false
|
||||
InsertNewlineAtEOF: false
|
||||
InsertTrailingCommas: None
|
||||
IntegerLiteralSeparator:
|
||||
Binary: 0
|
||||
BinaryMinDigits: 0
|
||||
Decimal: 0
|
||||
DecimalMinDigits: 0
|
||||
Hex: 0
|
||||
HexMinDigits: 0
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
LambdaBodyIndentation: Signature
|
||||
LineEnding: DeriveLF
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PackConstructorInitializers: CurrentLine
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 1000
|
||||
PointerAlignment: Left
|
||||
PPIndentWidth: -1
|
||||
QualifierAlignment: Left
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
RemoveBracesLLVM: false
|
||||
RemoveSemicolon: false
|
||||
RequiresClausePosition: OwnLine
|
||||
RequiresExpressionIndentation: OuterScope
|
||||
SeparateDefinitionBlocks: Always
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: LexicographicNumeric
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: Always
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: true
|
||||
AfterFunctionDeclarationName: true
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: true
|
||||
AfterRequiresInClause: true
|
||||
AfterRequiresInExpression: true
|
||||
BeforeNonEmptyParentheses: true
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
WhitespaceSensitiveMacros:
|
||||
- BOOST_PP_STRINGIZE
|
||||
- CF_SWIFT_NAME
|
||||
- NS_SWIFT_NAME
|
||||
- PP_STRINGIZE
|
||||
- STRINGIZE
|
||||
...
|
||||
|
239
src/External/Android/fft.cpp
vendored
239
src/External/Android/fft.cpp
vendored
@ -1,7 +1,6 @@
|
||||
#include "fft.h"
|
||||
|
||||
namespace External::Android
|
||||
{
|
||||
namespace External::Android {
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
@ -31,155 +30,133 @@ namespace External::Android
|
||||
#endif
|
||||
#define LOG_FFT_SIZE 10
|
||||
#define MAX_FFT_SIZE (1 << LOG_FFT_SIZE)
|
||||
static const int32_t twiddle[MAX_FFT_SIZE / 4] = {
|
||||
0x00008000, 0xff378001, 0xfe6e8002, 0xfda58006, 0xfcdc800a, 0xfc13800f,
|
||||
0xfb4a8016, 0xfa81801e, 0xf9b88027, 0xf8ef8032, 0xf827803e, 0xf75e804b,
|
||||
0xf6958059, 0xf5cd8068, 0xf5058079, 0xf43c808b, 0xf374809e, 0xf2ac80b2,
|
||||
0xf1e480c8, 0xf11c80de, 0xf05580f6, 0xef8d8110, 0xeec6812a, 0xedff8146,
|
||||
0xed388163, 0xec718181, 0xebab81a0, 0xeae481c1, 0xea1e81e2, 0xe9588205,
|
||||
0xe892822a, 0xe7cd824f, 0xe7078276, 0xe642829d, 0xe57d82c6, 0xe4b982f1,
|
||||
0xe3f4831c, 0xe3308349, 0xe26d8377, 0xe1a983a6, 0xe0e683d6, 0xe0238407,
|
||||
0xdf61843a, 0xde9e846e, 0xdddc84a3, 0xdd1b84d9, 0xdc598511, 0xdb998549,
|
||||
0xdad88583, 0xda1885be, 0xd95885fa, 0xd8988637, 0xd7d98676, 0xd71b86b6,
|
||||
0xd65c86f6, 0xd59e8738, 0xd4e1877b, 0xd42487c0, 0xd3678805, 0xd2ab884c,
|
||||
0xd1ef8894, 0xd13488dd, 0xd0798927, 0xcfbe8972, 0xcf0489be, 0xce4b8a0c,
|
||||
0xcd928a5a, 0xccd98aaa, 0xcc218afb, 0xcb698b4d, 0xcab28ba0, 0xc9fc8bf5,
|
||||
0xc9468c4a, 0xc8908ca1, 0xc7db8cf8, 0xc7278d51, 0xc6738dab, 0xc5c08e06,
|
||||
0xc50d8e62, 0xc45b8ebf, 0xc3a98f1d, 0xc2f88f7d, 0xc2488fdd, 0xc198903e,
|
||||
0xc0e990a1, 0xc03a9105, 0xbf8c9169, 0xbedf91cf, 0xbe329236, 0xbd86929e,
|
||||
0xbcda9307, 0xbc2f9371, 0xbb8593dc, 0xbadc9448, 0xba3394b5, 0xb98b9523,
|
||||
0xb8e39592, 0xb83c9603, 0xb7969674, 0xb6f196e6, 0xb64c9759, 0xb5a897ce,
|
||||
0xb5059843, 0xb46298b9, 0xb3c09930, 0xb31f99a9, 0xb27f9a22, 0xb1df9a9c,
|
||||
0xb1409b17, 0xb0a29b94, 0xb0059c11, 0xaf689c8f, 0xaecc9d0e, 0xae319d8e,
|
||||
0xad979e0f, 0xacfd9e91, 0xac659f14, 0xabcd9f98, 0xab36a01c, 0xaaa0a0a2,
|
||||
0xaa0aa129, 0xa976a1b0, 0xa8e2a238, 0xa84fa2c2, 0xa7bda34c, 0xa72ca3d7,
|
||||
0xa69ca463, 0xa60ca4f0, 0xa57ea57e, 0xa4f0a60c, 0xa463a69c, 0xa3d7a72c,
|
||||
0xa34ca7bd, 0xa2c2a84f, 0xa238a8e2, 0xa1b0a976, 0xa129aa0a, 0xa0a2aaa0,
|
||||
0xa01cab36, 0x9f98abcd, 0x9f14ac65, 0x9e91acfd, 0x9e0fad97, 0x9d8eae31,
|
||||
0x9d0eaecc, 0x9c8faf68, 0x9c11b005, 0x9b94b0a2, 0x9b17b140, 0x9a9cb1df,
|
||||
0x9a22b27f, 0x99a9b31f, 0x9930b3c0, 0x98b9b462, 0x9843b505, 0x97ceb5a8,
|
||||
0x9759b64c, 0x96e6b6f1, 0x9674b796, 0x9603b83c, 0x9592b8e3, 0x9523b98b,
|
||||
0x94b5ba33, 0x9448badc, 0x93dcbb85, 0x9371bc2f, 0x9307bcda, 0x929ebd86,
|
||||
0x9236be32, 0x91cfbedf, 0x9169bf8c, 0x9105c03a, 0x90a1c0e9, 0x903ec198,
|
||||
0x8fddc248, 0x8f7dc2f8, 0x8f1dc3a9, 0x8ebfc45b, 0x8e62c50d, 0x8e06c5c0,
|
||||
0x8dabc673, 0x8d51c727, 0x8cf8c7db, 0x8ca1c890, 0x8c4ac946, 0x8bf5c9fc,
|
||||
0x8ba0cab2, 0x8b4dcb69, 0x8afbcc21, 0x8aaaccd9, 0x8a5acd92, 0x8a0cce4b,
|
||||
0x89becf04, 0x8972cfbe, 0x8927d079, 0x88ddd134, 0x8894d1ef, 0x884cd2ab,
|
||||
0x8805d367, 0x87c0d424, 0x877bd4e1, 0x8738d59e, 0x86f6d65c, 0x86b6d71b,
|
||||
0x8676d7d9, 0x8637d898, 0x85fad958, 0x85beda18, 0x8583dad8, 0x8549db99,
|
||||
0x8511dc59, 0x84d9dd1b, 0x84a3dddc, 0x846ede9e, 0x843adf61, 0x8407e023,
|
||||
0x83d6e0e6, 0x83a6e1a9, 0x8377e26d, 0x8349e330, 0x831ce3f4, 0x82f1e4b9,
|
||||
0x82c6e57d, 0x829de642, 0x8276e707, 0x824fe7cd, 0x822ae892, 0x8205e958,
|
||||
0x81e2ea1e, 0x81c1eae4, 0x81a0ebab, 0x8181ec71, 0x8163ed38, 0x8146edff,
|
||||
0x812aeec6, 0x8110ef8d, 0x80f6f055, 0x80def11c, 0x80c8f1e4, 0x80b2f2ac,
|
||||
0x809ef374, 0x808bf43c, 0x8079f505, 0x8068f5cd, 0x8059f695, 0x804bf75e,
|
||||
0x803ef827, 0x8032f8ef, 0x8027f9b8, 0x801efa81, 0x8016fb4a, 0x800ffc13,
|
||||
static const int32_t twiddle [MAX_FFT_SIZE / 4] = {
|
||||
0x00008000, 0xff378001, 0xfe6e8002, 0xfda58006, 0xfcdc800a, 0xfc13800f, 0xfb4a8016, 0xfa81801e, 0xf9b88027,
|
||||
0xf8ef8032, 0xf827803e, 0xf75e804b, 0xf6958059, 0xf5cd8068, 0xf5058079, 0xf43c808b, 0xf374809e, 0xf2ac80b2,
|
||||
0xf1e480c8, 0xf11c80de, 0xf05580f6, 0xef8d8110, 0xeec6812a, 0xedff8146, 0xed388163, 0xec718181, 0xebab81a0,
|
||||
0xeae481c1, 0xea1e81e2, 0xe9588205, 0xe892822a, 0xe7cd824f, 0xe7078276, 0xe642829d, 0xe57d82c6, 0xe4b982f1,
|
||||
0xe3f4831c, 0xe3308349, 0xe26d8377, 0xe1a983a6, 0xe0e683d6, 0xe0238407, 0xdf61843a, 0xde9e846e, 0xdddc84a3,
|
||||
0xdd1b84d9, 0xdc598511, 0xdb998549, 0xdad88583, 0xda1885be, 0xd95885fa, 0xd8988637, 0xd7d98676, 0xd71b86b6,
|
||||
0xd65c86f6, 0xd59e8738, 0xd4e1877b, 0xd42487c0, 0xd3678805, 0xd2ab884c, 0xd1ef8894, 0xd13488dd, 0xd0798927,
|
||||
0xcfbe8972, 0xcf0489be, 0xce4b8a0c, 0xcd928a5a, 0xccd98aaa, 0xcc218afb, 0xcb698b4d, 0xcab28ba0, 0xc9fc8bf5,
|
||||
0xc9468c4a, 0xc8908ca1, 0xc7db8cf8, 0xc7278d51, 0xc6738dab, 0xc5c08e06, 0xc50d8e62, 0xc45b8ebf, 0xc3a98f1d,
|
||||
0xc2f88f7d, 0xc2488fdd, 0xc198903e, 0xc0e990a1, 0xc03a9105, 0xbf8c9169, 0xbedf91cf, 0xbe329236, 0xbd86929e,
|
||||
0xbcda9307, 0xbc2f9371, 0xbb8593dc, 0xbadc9448, 0xba3394b5, 0xb98b9523, 0xb8e39592, 0xb83c9603, 0xb7969674,
|
||||
0xb6f196e6, 0xb64c9759, 0xb5a897ce, 0xb5059843, 0xb46298b9, 0xb3c09930, 0xb31f99a9, 0xb27f9a22, 0xb1df9a9c,
|
||||
0xb1409b17, 0xb0a29b94, 0xb0059c11, 0xaf689c8f, 0xaecc9d0e, 0xae319d8e, 0xad979e0f, 0xacfd9e91, 0xac659f14,
|
||||
0xabcd9f98, 0xab36a01c, 0xaaa0a0a2, 0xaa0aa129, 0xa976a1b0, 0xa8e2a238, 0xa84fa2c2, 0xa7bda34c, 0xa72ca3d7,
|
||||
0xa69ca463, 0xa60ca4f0, 0xa57ea57e, 0xa4f0a60c, 0xa463a69c, 0xa3d7a72c, 0xa34ca7bd, 0xa2c2a84f, 0xa238a8e2,
|
||||
0xa1b0a976, 0xa129aa0a, 0xa0a2aaa0, 0xa01cab36, 0x9f98abcd, 0x9f14ac65, 0x9e91acfd, 0x9e0fad97, 0x9d8eae31,
|
||||
0x9d0eaecc, 0x9c8faf68, 0x9c11b005, 0x9b94b0a2, 0x9b17b140, 0x9a9cb1df, 0x9a22b27f, 0x99a9b31f, 0x9930b3c0,
|
||||
0x98b9b462, 0x9843b505, 0x97ceb5a8, 0x9759b64c, 0x96e6b6f1, 0x9674b796, 0x9603b83c, 0x9592b8e3, 0x9523b98b,
|
||||
0x94b5ba33, 0x9448badc, 0x93dcbb85, 0x9371bc2f, 0x9307bcda, 0x929ebd86, 0x9236be32, 0x91cfbedf, 0x9169bf8c,
|
||||
0x9105c03a, 0x90a1c0e9, 0x903ec198, 0x8fddc248, 0x8f7dc2f8, 0x8f1dc3a9, 0x8ebfc45b, 0x8e62c50d, 0x8e06c5c0,
|
||||
0x8dabc673, 0x8d51c727, 0x8cf8c7db, 0x8ca1c890, 0x8c4ac946, 0x8bf5c9fc, 0x8ba0cab2, 0x8b4dcb69, 0x8afbcc21,
|
||||
0x8aaaccd9, 0x8a5acd92, 0x8a0cce4b, 0x89becf04, 0x8972cfbe, 0x8927d079, 0x88ddd134, 0x8894d1ef, 0x884cd2ab,
|
||||
0x8805d367, 0x87c0d424, 0x877bd4e1, 0x8738d59e, 0x86f6d65c, 0x86b6d71b, 0x8676d7d9, 0x8637d898, 0x85fad958,
|
||||
0x85beda18, 0x8583dad8, 0x8549db99, 0x8511dc59, 0x84d9dd1b, 0x84a3dddc, 0x846ede9e, 0x843adf61, 0x8407e023,
|
||||
0x83d6e0e6, 0x83a6e1a9, 0x8377e26d, 0x8349e330, 0x831ce3f4, 0x82f1e4b9, 0x82c6e57d, 0x829de642, 0x8276e707,
|
||||
0x824fe7cd, 0x822ae892, 0x8205e958, 0x81e2ea1e, 0x81c1eae4, 0x81a0ebab, 0x8181ec71, 0x8163ed38, 0x8146edff,
|
||||
0x812aeec6, 0x8110ef8d, 0x80f6f055, 0x80def11c, 0x80c8f1e4, 0x80b2f2ac, 0x809ef374, 0x808bf43c, 0x8079f505,
|
||||
0x8068f5cd, 0x8059f695, 0x804bf75e, 0x803ef827, 0x8032f8ef, 0x8027f9b8, 0x801efa81, 0x8016fb4a, 0x800ffc13,
|
||||
0x800afcdc, 0x8006fda5, 0x8002fe6e, 0x8001ff37,
|
||||
};
|
||||
};
|
||||
|
||||
/* Returns the multiplication of \conj{a} and {b}. */
|
||||
static inline int32_t mult (int32_t a, int32_t b)
|
||||
{
|
||||
static inline int32_t mult (int32_t a, int32_t b) {
|
||||
#if __ARM_ARCH__ >= 6
|
||||
int32_t t = b;
|
||||
__asm__("smuad %0, %0, %1" : "+r" (t) : "r" (a));
|
||||
__asm__("smusdx %0, %0, %1" : "+r" (b) : "r" (a));
|
||||
__asm__("pkhtb %0, %0, %1, ASR #16" : "+r" (t) : "r" (b));
|
||||
__asm__ ("smuad %0, %0, %1" : "+r"(t) : "r"(a));
|
||||
__asm__ ("smusdx %0, %0, %1" : "+r"(b) : "r"(a));
|
||||
__asm__ ("pkhtb %0, %0, %1, ASR #16" : "+r"(t) : "r"(b));
|
||||
return t;
|
||||
#else
|
||||
return (((a >> 16) * (b >> 16) + (int16_t) a * (int16_t) b) & ~0xFFFF) |
|
||||
((((a >> 16) * (int16_t) b - (int16_t) a * (b >> 16)) >> 16) & 0xFFFF);
|
||||
return (((a >> 16) * (b >> 16) + static_cast<int16_t> (a) * static_cast<int16_t> (b)) & ~0xFFFF) |
|
||||
((((a >> 16) * static_cast<int16_t> (b) - static_cast<int16_t> (a) * (b >> 16)) >> 16) & 0xFFFF);
|
||||
#endif
|
||||
}
|
||||
static inline int32_t half (int32_t a)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int32_t half (int32_t a) {
|
||||
#if __ARM_ARCH__ >= 6
|
||||
__asm__("shadd16 %0, %0, %1" : "+r" (a) : "r" (0));
|
||||
__asm__ ("shadd16 %0, %0, %1" : "+r"(a) : "r"(0));
|
||||
return a;
|
||||
#else
|
||||
return ((a >> 1) & ~0x8000) | (a & 0x8000);
|
||||
#endif
|
||||
}
|
||||
void fixed_fft (int n, int32_t* v)
|
||||
{
|
||||
}
|
||||
|
||||
void fixed_fft (int n, int32_t* v) {
|
||||
int scale = LOG_FFT_SIZE, i, p, r;
|
||||
for (r = 0, i = 1; i < n; ++i)
|
||||
{
|
||||
for (p = n; !(p & r); p >>= 1, r ^= p);
|
||||
if (i < r)
|
||||
{
|
||||
int32_t t = v[i];
|
||||
v[i] = v[r];
|
||||
v[r] = t;
|
||||
for (r = 0, i = 1; i < n; ++i) {
|
||||
for (p = n; !(p & r); p >>= 1, r ^= p)
|
||||
;
|
||||
if (i < r) {
|
||||
int32_t t = v [i];
|
||||
v [i] = v [r];
|
||||
v [r] = t;
|
||||
}
|
||||
}
|
||||
for (p = 1; p < n; p <<= 1)
|
||||
{
|
||||
for (p = 1; p < n; p <<= 1) {
|
||||
--scale;
|
||||
for (i = 0; i < n; i += p << 1)
|
||||
{
|
||||
int32_t x = half (v[i]);
|
||||
int32_t y = half (v[i + p]);
|
||||
v[i] = x + y;
|
||||
v[i + p] = x - y;
|
||||
for (i = 0; i < n; i += p << 1) {
|
||||
int32_t x = half (v [i]);
|
||||
int32_t y = half (v [i + p]);
|
||||
v [i] = x + y;
|
||||
v [i + p] = x - y;
|
||||
}
|
||||
for (r = 1; r < p; ++r)
|
||||
{
|
||||
for (r = 1; r < p; ++r) {
|
||||
int32_t w = MAX_FFT_SIZE / 4 - (r << scale);
|
||||
i = w >> 31;
|
||||
w = twiddle[(w ^ i) - i] ^ (i << 16);
|
||||
for (i = r; i < n; i += p << 1)
|
||||
{
|
||||
int32_t x = half (v[i]);
|
||||
int32_t y = mult (w, v[i + p]);
|
||||
v[i] = x - y;
|
||||
v[i + p] = x + y;
|
||||
w = twiddle [(w ^ i) - i] ^ (i << 16);
|
||||
for (i = r; i < n; i += p << 1) {
|
||||
int32_t x = half (v [i]);
|
||||
int32_t y = mult (w, v [i + p]);
|
||||
v [i] = x - y;
|
||||
v [i + p] = x + y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void fixed_fft_real (int n, int32_t* v)
|
||||
{
|
||||
int scale = LOG_FFT_SIZE, m = n >> 1, i;
|
||||
fixed_fft (n, v);
|
||||
for (i = 1; i <= n; i <<= 1, --scale);
|
||||
v[0] = mult (~v[0], 0x80008000);
|
||||
v[m] = half (v[m]);
|
||||
for (i = 1; i < n >> 1; ++i)
|
||||
{
|
||||
int32_t x = half (v[i]);
|
||||
int32_t z = half (v[n - i]);
|
||||
int32_t y = z - (x ^ 0xFFFF);
|
||||
x = half (x + (z ^ 0xFFFF));
|
||||
y = mult (y, twiddle[i << scale]);
|
||||
v[i] = x - y;
|
||||
v[n - i] = (x + y) ^ 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
bool doFft (uint8_t* fft, uint8_t* waveform)
|
||||
{
|
||||
int32_t workspace[WAVE_BUFFER_SIZE >> 1];
|
||||
int32_t nonzero = 0;
|
||||
for (uint32_t i = 0; i < WAVE_BUFFER_SIZE; i += 2)
|
||||
{
|
||||
workspace[i >> 1] =
|
||||
((waveform[i] ^ 0x80) << 24) | ((waveform[i + 1] ^ 0x80) << 8);
|
||||
nonzero |= workspace[i >> 1];
|
||||
}
|
||||
if (nonzero)
|
||||
{
|
||||
fixed_fft_real (WAVE_BUFFER_SIZE >> 1, workspace);
|
||||
}
|
||||
for (uint32_t i = 0; i < WAVE_BUFFER_SIZE; i += 2)
|
||||
{
|
||||
short tmp = workspace[i >> 1] >> 21;
|
||||
while (tmp > 127 || tmp < -128) tmp >>= 1;
|
||||
fft[i] = tmp;
|
||||
tmp = workspace[i >> 1];
|
||||
tmp >>= 5;
|
||||
while (tmp > 127 || tmp < -128) tmp >>= 1;
|
||||
fft[i + 1] = tmp;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void fixed_fft_real (int n, int32_t* v) {
|
||||
int scale = LOG_FFT_SIZE, m = n >> 1, i;
|
||||
fixed_fft (n, v);
|
||||
for (i = 1; i <= n; i <<= 1, --scale)
|
||||
;
|
||||
v [0] = mult (~v [0], 0x80008000);
|
||||
v [m] = half (v [m]);
|
||||
for (i = 1; i < n >> 1; ++i) {
|
||||
int32_t x = half (v [i]);
|
||||
int32_t z = half (v [n - i]);
|
||||
int32_t y = z - (x ^ 0xFFFF);
|
||||
x = half (x + (z ^ 0xFFFF));
|
||||
y = mult (y, twiddle [i << scale]);
|
||||
v [i] = x - y;
|
||||
v [n - i] = (x + y) ^ 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
bool doFft (uint8_t* fft, uint8_t* waveform) {
|
||||
int32_t workspace [WAVE_BUFFER_SIZE >> 1];
|
||||
int32_t nonzero = 0;
|
||||
for (uint32_t i = 0; i < WAVE_BUFFER_SIZE; i += 2) {
|
||||
workspace [i >> 1] = ((waveform [i] ^ 0x80) << 24) | ((waveform [i + 1] ^ 0x80) << 8);
|
||||
nonzero |= workspace [i >> 1];
|
||||
}
|
||||
if (nonzero) {
|
||||
fixed_fft_real (WAVE_BUFFER_SIZE >> 1, workspace);
|
||||
}
|
||||
for (uint32_t i = 0; i < WAVE_BUFFER_SIZE; i += 2) {
|
||||
short tmp = workspace [i >> 1] >> 21;
|
||||
while (tmp > 127 || tmp < -128)
|
||||
tmp >>= 1;
|
||||
fft [i] = tmp;
|
||||
tmp = workspace [i >> 1];
|
||||
tmp >>= 5;
|
||||
while (tmp > 127 || tmp < -128)
|
||||
tmp >>= 1;
|
||||
fft [i + 1] = tmp;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace External::Android
|
9
src/External/Android/fft.h
vendored
9
src/External/Android/fft.h
vendored
@ -1,12 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
|
||||
#define WAVE_BUFFER_SIZE 1024
|
||||
|
||||
namespace External::Android
|
||||
{
|
||||
bool doFft (uint8_t* fft, uint8_t* waveform);
|
||||
namespace External::Android {
|
||||
bool doFft (uint8_t* fft, uint8_t* waveform);
|
||||
}
|
@ -2,34 +2,26 @@
|
||||
#include "WallpaperEngine/Logging/CLog.h"
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <filesystem>
|
||||
#include <sstream>
|
||||
#include <sys/stat.h>
|
||||
|
||||
const char* assets_default_paths [] = {
|
||||
".steam/steam/steamapps/common",
|
||||
".local/share/Steam/steamapps/common",
|
||||
const char* assets_default_paths [] = {".steam/steam/steamapps/common", ".local/share/Steam/steamapps/common",
|
||||
".var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common",
|
||||
"snap/steam/common/.local/share/Steam/steamapps/common",
|
||||
nullptr
|
||||
};
|
||||
"snap/steam/common/.local/share/Steam/steamapps/common", nullptr};
|
||||
|
||||
const char* workshop_content_default_paths [] = {
|
||||
".local/share/Steam/steamapps/workshop/content",
|
||||
".steam/steam/steamapps/workshop/content",
|
||||
".local/share/Steam/steamapps/workshop/content", ".steam/steam/steamapps/workshop/content",
|
||||
".var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/workshop/content",
|
||||
"snap/steam/common/.local/share/Steam/steamapps/workshop/content",
|
||||
nullptr
|
||||
};
|
||||
"snap/steam/common/.local/share/Steam/steamapps/workshop/content", nullptr};
|
||||
|
||||
std::filesystem::path detectHomepath ()
|
||||
{
|
||||
std::filesystem::path detectHomepath () {
|
||||
char* home = getenv ("HOME");
|
||||
|
||||
if (home == nullptr)
|
||||
sLog.exception ("Cannot find home directory for the current user");
|
||||
|
||||
std::filesystem::path path = home;
|
||||
const std::filesystem::path path = home;
|
||||
|
||||
if (!std::filesystem::is_directory (path))
|
||||
sLog.exception ("Cannot find home directory for current user, ", home, " is not a directory");
|
||||
@ -37,12 +29,10 @@ std::filesystem::path detectHomepath ()
|
||||
return home;
|
||||
}
|
||||
|
||||
std::filesystem::path Steam::FileSystem::workshopDirectory (int appID, const std::string& contentID)
|
||||
{
|
||||
std::filesystem::path Steam::FileSystem::workshopDirectory (int appID, const std::string& contentID) {
|
||||
auto homepath = detectHomepath ();
|
||||
|
||||
for (const char** current = workshop_content_default_paths; *current != nullptr; current ++)
|
||||
{
|
||||
for (const char** current = workshop_content_default_paths; *current != nullptr; current++) {
|
||||
auto currentpath = std::filesystem::path (homepath) / *current / std::to_string (appID) / contentID;
|
||||
|
||||
if (!std::filesystem::exists (currentpath) || !std::filesystem::is_directory (currentpath))
|
||||
@ -54,12 +44,10 @@ std::filesystem::path Steam::FileSystem::workshopDirectory (int appID, const std
|
||||
sLog.exception ("Cannot find workshop directory for steam app ", appID, " and content ", contentID);
|
||||
}
|
||||
|
||||
std::filesystem::path Steam::FileSystem::appDirectory (const std::string& appDirectory, const std::string& path)
|
||||
{
|
||||
std::filesystem::path Steam::FileSystem::appDirectory (const std::string& appDirectory, const std::string& path) {
|
||||
auto homepath = detectHomepath ();
|
||||
|
||||
for (const char** current = assets_default_paths; *current != nullptr; current ++)
|
||||
{
|
||||
for (const char** current = assets_default_paths; *current != nullptr; current++) {
|
||||
auto currentpath = std::filesystem::path (homepath) / *current / appDirectory / path;
|
||||
|
||||
if (!std::filesystem::exists (currentpath) || !std::filesystem::is_directory (currentpath))
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
namespace Steam::FileSystem
|
||||
{
|
||||
std::filesystem::path workshopDirectory (int appID, const std::string& contentID);
|
||||
std::filesystem::path appDirectory (const std::string& appDirectory, const std::string& path);
|
||||
}
|
||||
#include <string>
|
||||
|
||||
namespace Steam::FileSystem {
|
||||
std::filesystem::path workshopDirectory (int appID, const std::string& contentID);
|
||||
std::filesystem::path appDirectory (const std::string& appDirectory, const std::string& path);
|
||||
} // namespace Steam::FileSystem
|
@ -12,67 +12,60 @@
|
||||
|
||||
using namespace WallpaperEngine::Application;
|
||||
|
||||
struct option long_options[] = {
|
||||
{ "screen-root", required_argument, nullptr, 'r' },
|
||||
{ "bg", required_argument, nullptr, 'b' },
|
||||
{ "window", required_argument, nullptr, 'w' },
|
||||
{ "pkg", required_argument, nullptr, 'p' },
|
||||
{ "dir", required_argument, nullptr, 'd' },
|
||||
{ "silent", no_argument, nullptr, 's' },
|
||||
{ "volume", required_argument, nullptr, 'v' },
|
||||
{ "help", no_argument, nullptr, 'h' },
|
||||
{ "fps", required_argument, nullptr, 'f' },
|
||||
{ "assets-dir", required_argument, nullptr, 'a' },
|
||||
{ "screenshot", required_argument, nullptr, 'c' },
|
||||
{ "list-properties", no_argument, nullptr, 'l' },
|
||||
{ "set-property", required_argument, nullptr, 'o' },
|
||||
{ "noautomute", no_argument, nullptr, 'm' },
|
||||
{ "no-fullscreen-pause", no_argument, nullptr, 'n' },
|
||||
{ "disable-mouse", no_argument, nullptr, 'e' },
|
||||
{ "scaling", required_argument, nullptr, 't' },
|
||||
{ "clamping", required_argument, nullptr, 't' },
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
struct option long_options [] = {{"screen-root", required_argument, nullptr, 'r'},
|
||||
{"bg", required_argument, nullptr, 'b'},
|
||||
{"window", required_argument, nullptr, 'w'},
|
||||
{"pkg", required_argument, nullptr, 'p'},
|
||||
{"dir", required_argument, nullptr, 'd'},
|
||||
{"silent", no_argument, nullptr, 's'},
|
||||
{"volume", required_argument, nullptr, 'v'},
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{"fps", required_argument, nullptr, 'f'},
|
||||
{"assets-dir", required_argument, nullptr, 'a'},
|
||||
{"screenshot", required_argument, nullptr, 'c'},
|
||||
{"list-properties", no_argument, nullptr, 'l'},
|
||||
{"set-property", required_argument, nullptr, 'o'},
|
||||
{"noautomute", no_argument, nullptr, 'm'},
|
||||
{"no-fullscreen-pause", no_argument, nullptr, 'n'},
|
||||
{"disable-mouse", no_argument, nullptr, 'e'},
|
||||
{"scaling", required_argument, nullptr, 't'},
|
||||
{"clamping", required_argument, nullptr, 't'},
|
||||
{nullptr, 0, nullptr, 0}};
|
||||
|
||||
/* std::hash::operator() isn't constexpr, so it can't be used to get hash values as compile-time constants
|
||||
* So here is customHash. It skips all spaces, so hashes for " find " and "fi nd" are the same
|
||||
* Basicly got it from here: https://stackoverflow.com/questions/8317508/hash-function-for-a-string
|
||||
*/
|
||||
constexpr size_t customHash(const char* str) {
|
||||
*/
|
||||
constexpr size_t customHash (const char* str) {
|
||||
constexpr size_t A = 54059; /* a prime */
|
||||
constexpr size_t B = 76963; /* another prime */
|
||||
constexpr size_t C = 86969; /* yet another prime */
|
||||
constexpr size_t FIRSTH = 37; /* also prime */
|
||||
size_t hash = FIRSTH;
|
||||
while (*str) {
|
||||
if(*str != ' ') // Skip spaces
|
||||
if (*str != ' ') // Skip spaces
|
||||
hash = (hash * A) ^ (*str * B);
|
||||
++str;
|
||||
}
|
||||
return hash % C;
|
||||
}
|
||||
|
||||
std::string stringPathFixes (const std::string& s)
|
||||
{
|
||||
std::string stringPathFixes (const std::string& s) {
|
||||
if (s.empty ())
|
||||
return s;
|
||||
|
||||
std::string str (s);
|
||||
|
||||
// remove single-quotes from the arguments
|
||||
if (str[0] == '\'' && str[str.size () - 1] == '\'')
|
||||
str
|
||||
.erase (str.size () - 1, 1)
|
||||
.erase (0, 1);
|
||||
if (str [0] == '\'' && str [str.size () - 1] == '\'')
|
||||
str.erase (str.size () - 1, 1).erase (0, 1);
|
||||
|
||||
return std::move (str);
|
||||
}
|
||||
|
||||
CApplicationContext::CApplicationContext (int argc, char* argv[])
|
||||
{
|
||||
CApplicationContext::CApplicationContext (int argc, char* argv []) {
|
||||
// setup structs with sane default values for now
|
||||
this->settings =
|
||||
{
|
||||
this->settings = {
|
||||
.general =
|
||||
{
|
||||
.onlyListProperties = false,
|
||||
@ -86,15 +79,14 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
|
||||
.mode = NORMAL_WINDOW,
|
||||
.maximumFPS = 30,
|
||||
.pauseOnFullscreen = true,
|
||||
.window = { .geometry = {}, .clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs,
|
||||
.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs, },
|
||||
},
|
||||
.audio =
|
||||
.window =
|
||||
{
|
||||
.enabled = true,
|
||||
.volume = 15,
|
||||
.automute = true
|
||||
.geometry = {},
|
||||
.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs,
|
||||
.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs,
|
||||
},
|
||||
},
|
||||
.audio = {.enabled = true, .volume = 15, .automute = true},
|
||||
.mouse =
|
||||
{
|
||||
.enabled = true,
|
||||
@ -111,13 +103,9 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
|
||||
|
||||
std::string lastScreen;
|
||||
|
||||
while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w:mnt:", long_options, nullptr)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'n':
|
||||
this->settings.render.pauseOnFullscreen = false;
|
||||
break;
|
||||
while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w:mnt:", long_options, nullptr)) != -1) {
|
||||
switch (c) {
|
||||
case 'n': this->settings.render.pauseOnFullscreen = false; break;
|
||||
|
||||
case 'b':
|
||||
if (lastScreen.empty ())
|
||||
@ -125,45 +113,41 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
|
||||
|
||||
// no need to check for previous screen being in the list, as it's the only way for this variable
|
||||
// to have any value
|
||||
this->settings.general.screenBackgrounds[lastScreen] = translateBackground (optarg);
|
||||
this->settings.general.screenScalings[lastScreen] = this->settings.render.window.scalingMode;
|
||||
this->settings.general.screenBackgrounds [lastScreen] = translateBackground (optarg);
|
||||
this->settings.general.screenScalings [lastScreen] = this->settings.render.window.scalingMode;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
{
|
||||
case 'o': {
|
||||
std::string value = optarg;
|
||||
std::string::size_type equals = value.find ('=');
|
||||
const std::string::size_type equals = value.find ('=');
|
||||
|
||||
// properties without value are treated as booleans for now
|
||||
if (equals == std::string::npos)
|
||||
this->settings.general.properties[value] = "1";
|
||||
this->settings.general.properties [value] = "1";
|
||||
else
|
||||
this->settings.general.properties[value.substr (0, equals)] = value.substr (equals + 1);
|
||||
}
|
||||
break;
|
||||
this->settings.general.properties [value.substr (0, equals)] = value.substr (equals + 1);
|
||||
} break;
|
||||
|
||||
case 'l':
|
||||
this->settings.general.onlyListProperties = true;
|
||||
break;
|
||||
case 'l': this->settings.general.onlyListProperties = true; break;
|
||||
|
||||
case 'r':
|
||||
if (this->settings.general.screenBackgrounds.find (optarg) != this->settings.general.screenBackgrounds.end ())
|
||||
if (this->settings.general.screenBackgrounds.find (optarg) !=
|
||||
this->settings.general.screenBackgrounds.end ())
|
||||
sLog.exception ("Cannot specify the same screen more than once: ", optarg);
|
||||
if (this->settings.render.mode == EXPLICIT_WINDOW)
|
||||
sLog.exception ("Cannot run in both background and window mode");
|
||||
|
||||
this->settings.render.mode = DESKTOP_BACKGROUND;
|
||||
lastScreen = optarg;
|
||||
this->settings.general.screenBackgrounds[lastScreen] = "";
|
||||
this->settings.general.screenScalings[lastScreen] = this->settings.render.window.scalingMode;
|
||||
this->settings.general.screenBackgrounds [lastScreen] = "";
|
||||
this->settings.general.screenScalings [lastScreen] = this->settings.render.window.scalingMode;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if (this->settings.render.mode == DESKTOP_BACKGROUND)
|
||||
sLog.exception ("Cannot run in both background and window mode");
|
||||
|
||||
if (optarg != nullptr)
|
||||
{
|
||||
if (optarg != nullptr) {
|
||||
this->settings.render.mode = EXPLICIT_WINDOW;
|
||||
// read window geometry
|
||||
char* pos = optarg;
|
||||
@ -185,92 +169,77 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
|
||||
this->settings.general.defaultBackground = translateBackground (stringPathFixes (optarg));
|
||||
break;
|
||||
|
||||
case 's':
|
||||
this->settings.audio.enabled = false;
|
||||
break;
|
||||
case 's': this->settings.audio.enabled = false; break;
|
||||
|
||||
case 'h':
|
||||
printHelp (argv[0]);
|
||||
std::exit(0);
|
||||
printHelp (argv [0]);
|
||||
std::exit (0);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
this->settings.render.maximumFPS = atoi (optarg);
|
||||
break;
|
||||
case 'f': this->settings.render.maximumFPS = atoi (optarg); break;
|
||||
|
||||
case 'a':
|
||||
this->settings.general.assets = stringPathFixes (optarg);
|
||||
break;
|
||||
case 'a': this->settings.general.assets = stringPathFixes (optarg); break;
|
||||
|
||||
case 'v':
|
||||
this->settings.audio.volume = std::max (atoi (optarg), 128);
|
||||
break;
|
||||
case 'v': this->settings.audio.volume = std::max (atoi (optarg), 128); break;
|
||||
|
||||
case 'c':
|
||||
this->settings.screenshot.take = true;
|
||||
this->settings.screenshot.path = stringPathFixes (optarg);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
this->settings.audio.automute = false;
|
||||
break;
|
||||
case 'm': this->settings.audio.automute = false; break;
|
||||
|
||||
case 'e':
|
||||
this->settings.mouse.enabled = false;
|
||||
break;
|
||||
case 'e': this->settings.mouse.enabled = false; break;
|
||||
|
||||
case 't':
|
||||
{
|
||||
size_t hash = customHash(optarg);
|
||||
case 't': {
|
||||
size_t hash = customHash (optarg);
|
||||
// Use a switch statement with the hash
|
||||
switch (hash) {
|
||||
// --scale options
|
||||
case customHash("stretch"):
|
||||
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::StretchUVs;
|
||||
case customHash ("stretch"):
|
||||
this->settings.render.window.scalingMode =
|
||||
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::StretchUVs;
|
||||
break;
|
||||
case customHash("fit"):
|
||||
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFitUVs;
|
||||
case customHash ("fit"):
|
||||
this->settings.render.window.scalingMode =
|
||||
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFitUVs;
|
||||
break;
|
||||
case customHash("fill"):
|
||||
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFillUVs;
|
||||
case customHash ("fill"):
|
||||
this->settings.render.window.scalingMode =
|
||||
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFillUVs;
|
||||
break;
|
||||
case customHash("default"):
|
||||
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs;
|
||||
case customHash ("default"):
|
||||
this->settings.render.window.scalingMode =
|
||||
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs;
|
||||
break;
|
||||
// --clamp options
|
||||
case customHash("clamp"):
|
||||
case customHash ("clamp"):
|
||||
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs;
|
||||
break;
|
||||
case customHash("border"):
|
||||
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVsBorder;
|
||||
case customHash ("border"):
|
||||
this->settings.render.window.clamp =
|
||||
WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVsBorder;
|
||||
break;
|
||||
case customHash("repeat"):
|
||||
case customHash ("repeat"):
|
||||
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::NoFlags;
|
||||
break;
|
||||
default:
|
||||
sLog.error("Wrong argument:");
|
||||
sLog.error(optarg);
|
||||
sLog.exception("Wrong argument provided for --scale or --clamp option.");
|
||||
sLog.error ("Wrong argument:");
|
||||
sLog.error (optarg);
|
||||
sLog.exception ("Wrong argument provided for --scale or --clamp option.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sLog.out ("Default on path parsing: ", optarg);
|
||||
break;
|
||||
} break;
|
||||
default: sLog.out ("Default on path parsing: ", optarg); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->settings.general.defaultBackground.empty ())
|
||||
{
|
||||
if (optind < argc && strlen (argv[optind]) > 0)
|
||||
{
|
||||
this->settings.general.defaultBackground = translateBackground (argv[optind]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printHelp (argv[0]);
|
||||
std::exit(0);
|
||||
if (this->settings.general.defaultBackground.empty ()) {
|
||||
if (optind < argc && strlen (argv [optind]) > 0) {
|
||||
this->settings.general.defaultBackground = translateBackground (argv [optind]);
|
||||
} else {
|
||||
printHelp (argv [0]);
|
||||
std::exit (0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,42 +253,36 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
|
||||
this->state.audio.volume = this->settings.audio.volume;
|
||||
}
|
||||
|
||||
std::filesystem::path CApplicationContext::translateBackground (const std::string& bgIdOrPath)
|
||||
{
|
||||
std::filesystem::path CApplicationContext::translateBackground (const std::string& bgIdOrPath) {
|
||||
if (bgIdOrPath.find ('/') == std::string::npos)
|
||||
return Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, bgIdOrPath);
|
||||
|
||||
return bgIdOrPath;
|
||||
}
|
||||
|
||||
void CApplicationContext::validateAssets ()
|
||||
{
|
||||
if (!this->settings.general.assets.empty ())
|
||||
{
|
||||
sLog.out ("Using wallpaper engine's assets at ", this->settings.general.assets, " based on --assets-dir parameter");
|
||||
void CApplicationContext::validateAssets () {
|
||||
if (!this->settings.general.assets.empty ()) {
|
||||
sLog.out ("Using wallpaper engine's assets at ", this->settings.general.assets,
|
||||
" based on --assets-dir parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
this->settings.general.assets = Steam::FileSystem::appDirectory (APP_DIRECTORY, "assets");
|
||||
}
|
||||
catch (std::runtime_error&)
|
||||
{
|
||||
} catch (std::runtime_error&) {
|
||||
// set current path as assets' folder
|
||||
std::filesystem::path directory = std::filesystem::canonical ("/proc/self/exe").parent_path () / "assets";
|
||||
}
|
||||
}
|
||||
|
||||
void CApplicationContext::validateScreenshot ()
|
||||
{
|
||||
void CApplicationContext::validateScreenshot () {
|
||||
if (!this->settings.screenshot.take)
|
||||
return;
|
||||
|
||||
if (!this->settings.screenshot.path.has_extension ())
|
||||
sLog.exception ("Cannot determine screenshot format");
|
||||
|
||||
std::string extension = this->settings.screenshot.path.extension ();
|
||||
const std::string extension = this->settings.screenshot.path.extension ();
|
||||
|
||||
if (extension == ".bmp")
|
||||
this->settings.screenshot.format = FIF_BMP;
|
||||
@ -331,8 +294,7 @@ void CApplicationContext::validateScreenshot ()
|
||||
sLog.exception ("Cannot determine screenshot format, unknown extension ", extension);
|
||||
}
|
||||
|
||||
void CApplicationContext::printHelp (const char* route)
|
||||
{
|
||||
void CApplicationContext::printHelp (const char* route) {
|
||||
sLog.out ("Usage: ", route, " [options] background_path/background_id");
|
||||
sLog.out ("");
|
||||
sLog.out ("where background_path/background_id can be:");
|
||||
@ -344,7 +306,8 @@ void CApplicationContext::printHelp (const char* route)
|
||||
sLog.out ("\t--volume <amount>\t\t\tSets the volume for all the sounds in the background");
|
||||
sLog.out ("\t--noautomute\t\t\t\tDisables the automute when an app is playing sound");
|
||||
sLog.out ("\t--screen-root <screen name>\tDisplay as screen's background");
|
||||
sLog.out ("\t--window <geometry>\tRuns in window mode, geometry has to be XxYxWxH and sets the position and size of the window");
|
||||
sLog.out (
|
||||
"\t--window <geometry>\tRuns in window mode, geometry has to be XxYxWxH and sets the position and size of the window");
|
||||
sLog.out ("\t--fps <maximum-fps>\t\t\tLimits the FPS to the given number, useful to keep battery consumption low");
|
||||
sLog.out ("\t--assets-dir <path>\t\t\tFolder where the assets are stored");
|
||||
sLog.out ("\t--screenshot\t\t\t\tTakes a screenshot of the background");
|
||||
@ -352,8 +315,10 @@ void CApplicationContext::printHelp (const char* route)
|
||||
sLog.out ("\t--set-property <name=value>\tOverrides the default value of the given property");
|
||||
sLog.out ("\t--no-fullscreen-pause\tPrevents the background pausing when an app is fullscreen");
|
||||
sLog.out ("\t--disable-mouse\tDisables mouse interactions");
|
||||
sLog.out ("\t--scaling <mode>\t Scaling mode for wallpaper. Can be stretch, fit, fill, default. Must be used before wallpaper provided.\n\
|
||||
sLog.out (
|
||||
"\t--scaling <mode>\t Scaling mode for wallpaper. Can be stretch, fit, fill, default. Must be used before wallpaper provided.\n\
|
||||
\t\t For default wallpaper last specified value will be used.\n\
|
||||
\t\t Example: ./wallengine --scaling stretch --screen-root eDP-1 --bg 2667198601 --scaling fill --screen-root eDP-2 2667198602");
|
||||
sLog.out ("\t--clamping <mode>\t Clamping mode for all wallpapers. Can be clamp, border, repeat. Enables GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, GL_REPEAT accordingly. Default is clamp.");
|
||||
sLog.out (
|
||||
"\t--clamping <mode>\t Clamping mode for all wallpapers. Can be clamp, border, repeat. Enables GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, GL_REPEAT accordingly. Default is clamp.");
|
||||
}
|
||||
|
@ -14,18 +14,15 @@
|
||||
#include "WallpaperEngine/Assets/ITexture.h"
|
||||
#include "WallpaperEngine/Render/CWallpaperState.h"
|
||||
|
||||
namespace WallpaperEngine::Application
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Application {
|
||||
/**
|
||||
* Application information as parsed off the command line arguments
|
||||
*/
|
||||
class CApplicationContext
|
||||
{
|
||||
class CApplicationContext {
|
||||
public:
|
||||
CApplicationContext (int argc, char* argv[]);
|
||||
CApplicationContext (int argc, char* argv []);
|
||||
|
||||
enum WINDOW_MODE
|
||||
{
|
||||
enum WINDOW_MODE {
|
||||
/** Default window mode */
|
||||
NORMAL_WINDOW = 0,
|
||||
/** Draw to the window server desktop */
|
||||
@ -34,13 +31,11 @@ namespace WallpaperEngine::Application
|
||||
EXPLICIT_WINDOW = 2,
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
/**
|
||||
* General settings
|
||||
*/
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
/** If the user requested a list of properties for the given background */
|
||||
bool onlyListProperties;
|
||||
|
||||
@ -50,18 +45,17 @@ namespace WallpaperEngine::Application
|
||||
std::filesystem::path defaultBackground;
|
||||
|
||||
/** The backgrounds specified for different screens */
|
||||
std::map <std::string, std::filesystem::path> screenBackgrounds;
|
||||
std::map<std::string, std::filesystem::path> screenBackgrounds;
|
||||
/** Properties to change values for */
|
||||
std::map <std::string, std::string> properties;
|
||||
std::map<std::string, std::string> properties;
|
||||
/** The scaling mode for different screens */
|
||||
std::map <std::string, WallpaperEngine::Render::CWallpaperState::TextureUVsScaling> screenScalings;
|
||||
std::map<std::string, WallpaperEngine::Render::CWallpaperState::TextureUVsScaling> screenScalings;
|
||||
} general;
|
||||
|
||||
/**
|
||||
* Render settings
|
||||
*/
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
/** The mode to run the background in */
|
||||
WINDOW_MODE mode;
|
||||
/** Maximum FPS */
|
||||
@ -69,8 +63,7 @@ namespace WallpaperEngine::Application
|
||||
/** Indicates if pausing should happen when something goes fullscreen */
|
||||
bool pauseOnFullscreen;
|
||||
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
/** The window size used in explicit window */
|
||||
glm::ivec4 geometry;
|
||||
WallpaperEngine::Assets::ITexture::TextureFlags clamp;
|
||||
@ -81,8 +74,7 @@ namespace WallpaperEngine::Application
|
||||
/**
|
||||
* Audio settings
|
||||
*/
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
/** If the audio system is enabled */
|
||||
bool enabled;
|
||||
/** Sound volume (0-128) */
|
||||
@ -94,8 +86,7 @@ namespace WallpaperEngine::Application
|
||||
/**
|
||||
* Mouse input settings
|
||||
*/
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
/** If the mouse movement is enabled */
|
||||
bool enabled;
|
||||
} mouse;
|
||||
@ -103,8 +94,7 @@ namespace WallpaperEngine::Application
|
||||
/**
|
||||
* Screenshot settings
|
||||
*/
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
/** If an screenshot should be taken */
|
||||
bool take;
|
||||
/** The path to where the screenshot must be saved */
|
||||
@ -139,5 +129,5 @@ namespace WallpaperEngine::Application
|
||||
* Prints the normal help message
|
||||
*/
|
||||
static void printHelp (const char* route);
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Application
|
@ -2,28 +2,23 @@
|
||||
|
||||
#include "CApplicationContext.h"
|
||||
|
||||
namespace WallpaperEngine::Application
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Application {
|
||||
/**
|
||||
* Represents current application state
|
||||
*/
|
||||
class CApplicationState
|
||||
{
|
||||
class CApplicationState {
|
||||
public:
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
bool keepRunning;
|
||||
} general{};
|
||||
} general {};
|
||||
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
bool enabled;
|
||||
int volume;
|
||||
} audio{};
|
||||
} audio {};
|
||||
|
||||
struct
|
||||
{
|
||||
struct {
|
||||
bool enabled;
|
||||
} mouse{};
|
||||
};
|
||||
}
|
||||
} mouse {};
|
||||
};
|
||||
} // namespace WallpaperEngine::Application
|
@ -1,15 +1,15 @@
|
||||
#include "CWallpaperApplication.h"
|
||||
|
||||
#include "Steam/FileSystem/FileSystem.h"
|
||||
#include "WallpaperEngine/Assets/CDirectory.h"
|
||||
#include "WallpaperEngine/Assets/CVirtualContainer.h"
|
||||
#include "WallpaperEngine/Core/CVideo.h"
|
||||
#include "WallpaperEngine/Logging/CLog.h"
|
||||
#include "WallpaperEngine/Render/CRenderContext.h"
|
||||
#include "WallpaperEngine/Application/CApplicationState.h"
|
||||
#include "WallpaperEngine/Assets/CAssetLoadException.h"
|
||||
#include "WallpaperEngine/Assets/CDirectory.h"
|
||||
#include "WallpaperEngine/Assets/CVirtualContainer.h"
|
||||
#include "WallpaperEngine/Audio/Drivers/Detectors/CPulseAudioPlayingDetector.h"
|
||||
#include "WallpaperEngine/Core/CVideo.h"
|
||||
#include "WallpaperEngine/Input/Drivers/CGLFWMouseInput.h"
|
||||
#include "WallpaperEngine/Logging/CLog.h"
|
||||
#include "WallpaperEngine/Render/CRenderContext.h"
|
||||
|
||||
#include "WallpaperEngine/Input/Drivers/CWaylandMouseInput.h"
|
||||
#include "WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h"
|
||||
@ -18,28 +18,24 @@ float g_Time;
|
||||
float g_TimeLast;
|
||||
float g_Daytime;
|
||||
|
||||
namespace WallpaperEngine::Application
|
||||
{
|
||||
CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) :
|
||||
namespace WallpaperEngine::Application {
|
||||
CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) :
|
||||
m_context (context),
|
||||
m_defaultBackground (nullptr)
|
||||
{
|
||||
m_defaultBackground (nullptr) {
|
||||
this->loadBackgrounds ();
|
||||
this->setupProperties ();
|
||||
}
|
||||
}
|
||||
|
||||
CWallpaperApplication::~CWallpaperApplication ()
|
||||
{
|
||||
CWallpaperApplication::~CWallpaperApplication () {
|
||||
delete context;
|
||||
delete videoDriver;
|
||||
delete audioContext;
|
||||
delete audioDriver;
|
||||
delete inputContext;
|
||||
}
|
||||
}
|
||||
|
||||
void CWallpaperApplication::setupContainer (CCombinedContainer& container, const std::string& bg) const
|
||||
{
|
||||
std::filesystem::path basepath = bg;
|
||||
void CWallpaperApplication::setupContainer (CCombinedContainer& container, const std::string& bg) const {
|
||||
const std::filesystem::path basepath = bg;
|
||||
|
||||
container.add (new CDirectory (basepath));
|
||||
container.addPkg (basepath / "scene.pkg");
|
||||
@ -51,29 +47,21 @@ namespace WallpaperEngine::Application
|
||||
bool relative = true;
|
||||
bool absolute = true;
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
container.add (new CDirectory ("../share/"));
|
||||
}
|
||||
catch (CAssetLoadException& ex)
|
||||
{
|
||||
} catch (CAssetLoadException&) {
|
||||
relative = false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
container.add (new CDirectory (DATADIR));
|
||||
}
|
||||
catch (CAssetLoadException& ex)
|
||||
{
|
||||
} catch (CAssetLoadException&) {
|
||||
absolute = false;
|
||||
}
|
||||
|
||||
if (!relative && !absolute)
|
||||
sLog.error (
|
||||
"WARNING: Shader patches directory cannot be found, this might make some backgrounds not work "
|
||||
"properly"
|
||||
);
|
||||
sLog.error ("WARNING: Shader patches directory cannot be found, this might make some backgrounds not work "
|
||||
"properly");
|
||||
|
||||
// TODO: move this somewhere else?
|
||||
auto* virtualContainer = new CVirtualContainer ();
|
||||
@ -87,8 +75,7 @@ namespace WallpaperEngine::Application
|
||||
// add the effect file for screen bloom
|
||||
|
||||
// add some model for the image element even if it's going to waste rendering cycles
|
||||
virtualContainer->add (
|
||||
"effects/wpenginelinux/bloomeffect.json",
|
||||
virtualContainer->add ("effects/wpenginelinux/bloomeffect.json",
|
||||
"{"
|
||||
"\t\"name\":\"camerabloom_wpengine_linux\","
|
||||
"\t\"group\":\"wpengine_linux_camera\","
|
||||
@ -144,20 +131,14 @@ namespace WallpaperEngine::Application
|
||||
"\t\t\t]"
|
||||
"\t\t}"
|
||||
"\t]"
|
||||
"}"
|
||||
);
|
||||
"}");
|
||||
|
||||
virtualContainer->add (
|
||||
"models/wpenginelinux.json",
|
||||
"{"
|
||||
virtualContainer->add ("models/wpenginelinux.json", "{"
|
||||
"\t\"material\":\"materials/wpenginelinux.json\""
|
||||
"}"
|
||||
);
|
||||
"}");
|
||||
|
||||
// models require materials, so add that too
|
||||
virtualContainer->add (
|
||||
"materials/wpenginelinux.json",
|
||||
"{"
|
||||
virtualContainer->add ("materials/wpenginelinux.json", "{"
|
||||
"\t\"passes\":"
|
||||
"\t\t["
|
||||
"\t\t\t{"
|
||||
@ -169,48 +150,41 @@ namespace WallpaperEngine::Application
|
||||
"\t\t\t\t\"textures\": [\"_rt_FullFrameBuffer\"]"
|
||||
"\t\t\t}"
|
||||
"\t\t]"
|
||||
"}"
|
||||
);
|
||||
"}");
|
||||
|
||||
container.add (virtualContainer);
|
||||
}
|
||||
}
|
||||
|
||||
void CWallpaperApplication::loadBackgrounds ()
|
||||
{
|
||||
for (const auto& it : this->m_context.settings.general.screenBackgrounds)
|
||||
{
|
||||
void CWallpaperApplication::loadBackgrounds () {
|
||||
for (const auto& [background, path] : this->m_context.settings.general.screenBackgrounds) {
|
||||
// ignore the screen settings if there was no background specified
|
||||
// the default will be used
|
||||
if (it.second.empty ())
|
||||
if (path.empty ())
|
||||
continue;
|
||||
|
||||
this->m_backgrounds[it.first] = this->loadBackground (it.second);
|
||||
this->m_backgrounds [background] = this->loadBackground (path);
|
||||
}
|
||||
|
||||
// load the default project if required
|
||||
if (!this->m_context.settings.general.defaultBackground.empty ())
|
||||
this->m_defaultBackground = this->loadBackground (this->m_context.settings.general.defaultBackground);
|
||||
}
|
||||
}
|
||||
|
||||
Core::CProject* CWallpaperApplication::loadBackground (const std::string& bg)
|
||||
{
|
||||
Core::CProject* CWallpaperApplication::loadBackground (const std::string& bg) {
|
||||
auto* container = new CCombinedContainer ();
|
||||
|
||||
this->setupContainer (*container, bg);
|
||||
|
||||
return Core::CProject::fromFile ("project.json", container);
|
||||
}
|
||||
}
|
||||
|
||||
void CWallpaperApplication::setupPropertiesForProject (Core::CProject* project)
|
||||
{
|
||||
void CWallpaperApplication::setupPropertiesForProject (const Core::CProject* project) {
|
||||
// show properties if required
|
||||
for (auto cur : project->getProperties ())
|
||||
{
|
||||
for (const auto cur : project->getProperties ()) {
|
||||
// update the value of the property
|
||||
auto override = this->m_context.settings.general.properties.find (cur->getName ());
|
||||
|
||||
if (override != this->m_context.settings.general.properties.end ())
|
||||
{
|
||||
if (override != this->m_context.settings.general.properties.end ()) {
|
||||
sLog.out ("Applying override value for ", cur->getName ());
|
||||
|
||||
cur->update (override->second);
|
||||
@ -219,91 +193,83 @@ namespace WallpaperEngine::Application
|
||||
if (this->m_context.settings.general.onlyListProperties)
|
||||
sLog.out (cur->dump ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWallpaperApplication::setupProperties ()
|
||||
{
|
||||
for (const auto& it : this->m_backgrounds)
|
||||
this->setupPropertiesForProject (it.second);
|
||||
void CWallpaperApplication::setupProperties () {
|
||||
for (const auto& [backgrounc, info] : this->m_backgrounds)
|
||||
this->setupPropertiesForProject (info);
|
||||
|
||||
if (this->m_defaultBackground != nullptr)
|
||||
this->setupPropertiesForProject (this->m_defaultBackground);
|
||||
}
|
||||
}
|
||||
|
||||
void CWallpaperApplication::takeScreenshot (
|
||||
const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format
|
||||
)
|
||||
{
|
||||
void CWallpaperApplication::takeScreenshot (const Render::CRenderContext& context,
|
||||
const std::filesystem::path& filename, FREE_IMAGE_FORMAT format) {
|
||||
// this should be getting called at the end of the frame, so the right thing should be bound already
|
||||
int width = context.getOutput ().getFullWidth ();
|
||||
int height = context.getOutput ().getFullHeight ();
|
||||
const int width = context.getOutput ().getFullWidth ();
|
||||
const int height = context.getOutput ().getFullHeight ();
|
||||
|
||||
// build the output file with FreeImage
|
||||
static FIBITMAP* bitmap = FreeImage_Allocate (width, height, 24);
|
||||
RGBQUAD color;
|
||||
int xoffset = 0;
|
||||
|
||||
for (const auto& viewport : context.getOutput ().getViewports ())
|
||||
{
|
||||
for (const auto& [screen, viewport] : context.getOutput ().getViewports ()) {
|
||||
// activate opengl context so we can read from the framebuffer
|
||||
viewport.second->makeCurrent ();
|
||||
viewport->makeCurrent ();
|
||||
// make room for storing the pixel of this viewport
|
||||
uint8_t* buffer = new uint8_t[viewport.second->viewport.z * viewport.second->viewport.w * sizeof (uint8_t) * 3];
|
||||
uint8_t* pixel = buffer;
|
||||
auto* buffer = new uint8_t [viewport->viewport.z * viewport->viewport.w * sizeof (uint8_t) * 3];
|
||||
const uint8_t* pixel = buffer;
|
||||
|
||||
// read the viewport data into the pixel buffer
|
||||
glReadPixels (
|
||||
viewport.second->viewport.x, viewport.second->viewport.y,
|
||||
viewport.second->viewport.z, viewport.second->viewport.w,
|
||||
GL_RGB, GL_UNSIGNED_BYTE, buffer
|
||||
);
|
||||
glReadPixels (viewport->viewport.x, viewport->viewport.y, viewport->viewport.z, viewport->viewport.w, GL_RGB,
|
||||
GL_UNSIGNED_BYTE, buffer);
|
||||
|
||||
// now get access to the pixels
|
||||
for (int y = viewport.second->viewport.w; y > 0; y--)
|
||||
{
|
||||
for (int x = 0; x < viewport.second->viewport.z; x++)
|
||||
{
|
||||
for (int y = viewport->viewport.w; y > 0; y--) {
|
||||
for (int x = 0; x < viewport->viewport.z; x++) {
|
||||
color.rgbRed = *pixel++;
|
||||
color.rgbGreen = *pixel++;
|
||||
color.rgbBlue = *pixel++;
|
||||
|
||||
// set the pixel in the destination
|
||||
FreeImage_SetPixelColor (bitmap, x + xoffset, context.getOutput ().renderVFlip() ? (viewport.second->viewport.w - y) : y, &color);
|
||||
FreeImage_SetPixelColor (bitmap, x + xoffset,
|
||||
context.getOutput ().renderVFlip () ? (viewport->viewport.w - y) : y, &color);
|
||||
}
|
||||
}
|
||||
|
||||
if (viewport.second->single)
|
||||
xoffset += viewport.second->viewport.z;
|
||||
if (viewport->single)
|
||||
xoffset += viewport->viewport.z;
|
||||
|
||||
// free the buffer allocated for the viewport
|
||||
delete[] buffer;
|
||||
delete [] buffer;
|
||||
}
|
||||
|
||||
// finally save the file
|
||||
FreeImage_Save (format, bitmap, filename.c_str (), 0);
|
||||
|
||||
FreeImage_Unload (bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
void CWallpaperApplication::show ()
|
||||
{
|
||||
void CWallpaperApplication::show () {
|
||||
#ifdef ENABLE_WAYLAND
|
||||
const bool WAYLAND_DISPLAY = getenv ("WAYLAND_DISPLAY");
|
||||
|
||||
// setup the right video driver based on the environment and the startup mode requested
|
||||
if (WAYLAND_DISPLAY && this->m_context.settings.render.mode == CApplicationContext::DESKTOP_BACKGROUND)
|
||||
{
|
||||
auto waylandDriver = new WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver (this->m_context, *this);
|
||||
inputContext = new WallpaperEngine::Input::CInputContext (new WallpaperEngine::Input::Drivers::CWaylandMouseInput (waylandDriver));
|
||||
if (WAYLAND_DISPLAY && this->m_context.settings.render.mode == CApplicationContext::DESKTOP_BACKGROUND) {
|
||||
const auto waylandDriver = new WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver (this->m_context, *this);
|
||||
inputContext = new WallpaperEngine::Input::CInputContext (
|
||||
new WallpaperEngine::Input::Drivers::CWaylandMouseInput (waylandDriver));
|
||||
|
||||
videoDriver = waylandDriver;
|
||||
}
|
||||
else
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
auto x11Driver = new WallpaperEngine::Render::Drivers::CX11OpenGLDriver ("wallpaperengine", this->m_context, *this);
|
||||
const auto x11Driver =
|
||||
new WallpaperEngine::Render::Drivers::CX11OpenGLDriver ("wallpaperengine", this->m_context, *this);
|
||||
// no wayland detected, try the old X11 method
|
||||
inputContext = new WallpaperEngine::Input::CInputContext (new WallpaperEngine::Input::Drivers::CGLFWMouseInput (x11Driver));
|
||||
inputContext = new WallpaperEngine::Input::CInputContext (
|
||||
new WallpaperEngine::Input::Drivers::CGLFWMouseInput (x11Driver));
|
||||
|
||||
videoDriver = x11Driver;
|
||||
}
|
||||
@ -311,7 +277,8 @@ namespace WallpaperEngine::Application
|
||||
// stereo mix recorder for audio processing
|
||||
WallpaperEngine::Audio::Drivers::Recorders::CPulseAudioPlaybackRecorder audioRecorder;
|
||||
// audio playing detector
|
||||
WallpaperEngine::Audio::Drivers::Detectors::CPulseAudioPlayingDetector audioDetector (this->m_context, videoDriver->getFullscreenDetector ());
|
||||
WallpaperEngine::Audio::Drivers::Detectors::CPulseAudioPlayingDetector audioDetector (
|
||||
this->m_context, videoDriver->getFullscreenDetector ());
|
||||
// initialize sdl audio driver
|
||||
audioDriver = new WallpaperEngine::Audio::Drivers::CSDLAudioDriver (this->m_context, audioDetector, audioRecorder);
|
||||
// initialize audio context
|
||||
@ -320,26 +287,24 @@ namespace WallpaperEngine::Application
|
||||
context = new WallpaperEngine::Render::CRenderContext (*videoDriver, *inputContext, *this);
|
||||
|
||||
// set all the specific wallpapers required
|
||||
for (const auto& it : this->m_backgrounds)
|
||||
context->setWallpaper (
|
||||
it.first,
|
||||
WallpaperEngine::Render::CWallpaper::fromWallpaper (it.second->getWallpaper (), *context, *audioContext, this->m_context.settings.general.screenScalings[it.first])
|
||||
);
|
||||
for (const auto& [background, info] : this->m_backgrounds)
|
||||
context->setWallpaper (background, WallpaperEngine::Render::CWallpaper::fromWallpaper (
|
||||
info->getWallpaper (), *context, *audioContext,
|
||||
this->m_context.settings.general.screenScalings [background]));
|
||||
|
||||
// set the default rendering wallpaper if available
|
||||
if (this->m_defaultBackground != nullptr)
|
||||
context->setDefaultWallpaper (WallpaperEngine::Render::CWallpaper::fromWallpaper (
|
||||
this->m_defaultBackground->getWallpaper (), *context, *audioContext, this->m_context.settings.render.window.scalingMode
|
||||
));
|
||||
this->m_defaultBackground->getWallpaper (), *context, *audioContext,
|
||||
this->m_context.settings.render.window.scalingMode));
|
||||
|
||||
static time_t seconds;
|
||||
static struct tm* timeinfo;
|
||||
|
||||
while (this->m_context.state.general.keepRunning && !videoDriver->closeRequested ())
|
||||
{
|
||||
while (this->m_context.state.general.keepRunning && !videoDriver->closeRequested ()) {
|
||||
// update g_Daytime
|
||||
time (&seconds);
|
||||
timeinfo = localtime(&seconds);
|
||||
timeinfo = localtime (&seconds);
|
||||
g_Daytime = ((timeinfo->tm_hour * 60) + timeinfo->tm_min) / (24.0 * 60.0);
|
||||
|
||||
// keep track of the previous frame's time
|
||||
@ -356,7 +321,8 @@ namespace WallpaperEngine::Application
|
||||
if (!this->m_context.settings.screenshot.take || videoDriver->getFrameCounter () < 5)
|
||||
continue;
|
||||
|
||||
this->takeScreenshot (*context, this->m_context.settings.screenshot.path, this->m_context.settings.screenshot.format);
|
||||
this->takeScreenshot (*context, this->m_context.settings.screenshot.path,
|
||||
this->m_context.settings.screenshot.format);
|
||||
this->m_context.settings.screenshot.take = false;
|
||||
}
|
||||
|
||||
@ -366,31 +332,30 @@ namespace WallpaperEngine::Application
|
||||
sLog.out ("Stop requested");
|
||||
|
||||
SDL_Quit ();
|
||||
}
|
||||
}
|
||||
|
||||
void CWallpaperApplication::update(Render::Drivers::Output::COutputViewport* viewport)
|
||||
{
|
||||
void CWallpaperApplication::update (Render::Drivers::Output::COutputViewport* viewport) {
|
||||
// render the scene
|
||||
context->render (viewport);
|
||||
}
|
||||
|
||||
void CWallpaperApplication::signal (int signal)
|
||||
{
|
||||
this->m_context.state.general.keepRunning = false;
|
||||
}
|
||||
|
||||
const std::map<std::string, Core::CProject*>& CWallpaperApplication::getBackgrounds () const
|
||||
{
|
||||
return this->m_backgrounds;
|
||||
}
|
||||
|
||||
Core::CProject* CWallpaperApplication::getDefaultBackground () const
|
||||
{
|
||||
return this->m_defaultBackground;
|
||||
}
|
||||
|
||||
CApplicationContext& CWallpaperApplication::getContext () const
|
||||
{
|
||||
return this->m_context;
|
||||
}
|
||||
}
|
||||
|
||||
void CWallpaperApplication::signal (int signal) {
|
||||
this->m_context.state.general.keepRunning = false;
|
||||
}
|
||||
|
||||
const std::map<std::string, Core::CProject*>& CWallpaperApplication::getBackgrounds () const {
|
||||
return this->m_backgrounds;
|
||||
}
|
||||
|
||||
Core::CProject* CWallpaperApplication::getDefaultBackground () const {
|
||||
return this->m_defaultBackground;
|
||||
}
|
||||
|
||||
CApplicationContext& CWallpaperApplication::getContext () const {
|
||||
return this->m_context;
|
||||
}
|
||||
|
||||
const WallpaperEngine::Render::Drivers::Output::COutput& CWallpaperApplication::getOutput () const {
|
||||
return this->context->getOutput ();
|
||||
}
|
||||
} // namespace WallpaperEngine::Application
|
@ -6,8 +6,8 @@
|
||||
|
||||
#include "WallpaperEngine/Core/CProject.h"
|
||||
|
||||
#include "WallpaperEngine/Render/CWallpaper.h"
|
||||
#include "WallpaperEngine/Render/CRenderContext.h"
|
||||
#include "WallpaperEngine/Render/CWallpaper.h"
|
||||
#include "WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h"
|
||||
#ifdef ENABLE_WAYLAND
|
||||
#include "WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h"
|
||||
@ -28,15 +28,13 @@
|
||||
|
||||
#include "WallpaperEngine/Input/CInputContext.h"
|
||||
|
||||
namespace WallpaperEngine::Application
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Application {
|
||||
/**
|
||||
* Small wrapper class over the actual wallpaper's main application skeleton
|
||||
*
|
||||
* @author Alexis Maiquez <almamu@almamu.com>
|
||||
*/
|
||||
class CWallpaperApplication
|
||||
{
|
||||
class CWallpaperApplication {
|
||||
public:
|
||||
explicit CWallpaperApplication (CApplicationContext& context);
|
||||
~CWallpaperApplication ();
|
||||
@ -54,7 +52,7 @@ namespace WallpaperEngine::Application
|
||||
/**
|
||||
* @return Maps screens to loaded backgrounds
|
||||
*/
|
||||
[[nodiscard]] const std::map <std::string, Core::CProject*>& getBackgrounds () const;
|
||||
[[nodiscard]] const std::map<std::string, Core::CProject*>& getBackgrounds () const;
|
||||
/**
|
||||
* @return The default background to use if no specific project is loaded
|
||||
*/
|
||||
@ -66,11 +64,11 @@ namespace WallpaperEngine::Application
|
||||
/**
|
||||
* Renders a frame
|
||||
*/
|
||||
void update(Render::Drivers::Output::COutputViewport* viewport);
|
||||
void update (Render::Drivers::Output::COutputViewport* viewport);
|
||||
/**
|
||||
* Gets the output
|
||||
*/
|
||||
WallpaperEngine::Render::Drivers::Output::COutput* getOutput() const;
|
||||
[[nodiscard]] const WallpaperEngine::Render::Drivers::Output::COutput& getOutput () const;
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -100,7 +98,7 @@ namespace WallpaperEngine::Application
|
||||
*
|
||||
* @param project
|
||||
*/
|
||||
void setupPropertiesForProject (Core::CProject* project);
|
||||
void setupPropertiesForProject (const Core::CProject* project);
|
||||
/**
|
||||
* Takes an screenshot of the background and saves it to the specified path
|
||||
*
|
||||
@ -108,19 +106,20 @@ namespace WallpaperEngine::Application
|
||||
* @param filename
|
||||
* @param format
|
||||
*/
|
||||
static void takeScreenshot (const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format);
|
||||
static void takeScreenshot (const Render::CRenderContext& context, const std::filesystem::path& filename,
|
||||
FREE_IMAGE_FORMAT format);
|
||||
|
||||
/** The default background to display if no specific background was loaded */
|
||||
Core::CProject* m_defaultBackground;
|
||||
/** The application context that contains the current app settings */
|
||||
CApplicationContext& m_context;
|
||||
/** Maps screens to backgrounds */
|
||||
std::map <std::string, Core::CProject*> m_backgrounds;
|
||||
std::map<std::string, Core::CProject*> m_backgrounds;
|
||||
|
||||
WallpaperEngine::Render::Drivers::CVideoDriver* videoDriver;
|
||||
WallpaperEngine::Input::CInputContext* inputContext;
|
||||
WallpaperEngine::Audio::Drivers::CSDLAudioDriver* audioDriver;
|
||||
WallpaperEngine::Render::CRenderContext* context;
|
||||
WallpaperEngine::Audio::CAudioContext* audioContext;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Application
|
||||
|
@ -2,12 +2,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
CAssetLoadException::CAssetLoadException(const std::string& filename, const std::string& extrainfo)
|
||||
: m_message("Cannot find file " + filename + ": " + extrainfo)
|
||||
{
|
||||
}
|
||||
CAssetLoadException::CAssetLoadException (const std::string& filename, const std::string& extrainfo) :
|
||||
m_message ("Cannot find file " + filename + ": " + extrainfo) {}
|
||||
|
||||
const char *CAssetLoadException::what() const noexcept
|
||||
{
|
||||
const char* CAssetLoadException::what () const noexcept {
|
||||
return this->m_message.c_str ();
|
||||
}
|
||||
|
@ -3,15 +3,13 @@
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
class CAssetLoadException : public std::exception
|
||||
{
|
||||
namespace WallpaperEngine::Assets {
|
||||
class CAssetLoadException final : public std::exception {
|
||||
public:
|
||||
explicit CAssetLoadException (const std::string& filename, const std::string& extrainfo = "");
|
||||
[[nodiscard]] const char* what () const noexcept override;
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Assets
|
@ -6,50 +6,33 @@
|
||||
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
CCombinedContainer::CCombinedContainer () :
|
||||
CContainer (),
|
||||
m_containers ()
|
||||
{
|
||||
}
|
||||
CCombinedContainer::CCombinedContainer () : CContainer () {}
|
||||
|
||||
void CCombinedContainer::add (CContainer* container)
|
||||
{
|
||||
void CCombinedContainer::add (CContainer* container) {
|
||||
this->m_containers.emplace_back (container);
|
||||
}
|
||||
|
||||
void CCombinedContainer::addPkg (const std::filesystem::path& path)
|
||||
{
|
||||
try
|
||||
{
|
||||
void CCombinedContainer::addPkg (const std::filesystem::path& path) {
|
||||
try {
|
||||
// add the package to the list
|
||||
this->add (new CPackage (path));
|
||||
sLog.out ("Detected ", path.filename (), " file at ", path, ". Adding to list of searchable paths");
|
||||
}
|
||||
catch (CPackageLoadException& ex)
|
||||
{
|
||||
} catch (CPackageLoadException&) {
|
||||
// ignore this error, the package file was not found
|
||||
sLog.out ("No ", path.filename (), " file found at ", path, ". Defaulting to normal folder storage");
|
||||
}
|
||||
catch (std::runtime_error& ex)
|
||||
{
|
||||
} catch (std::runtime_error& ex) {
|
||||
// the package was found but there was an error loading it (wrong header or something)
|
||||
sLog.exception ("Failed to load scene.pkg file: ", ex.what());
|
||||
sLog.exception ("Failed to load scene.pkg file: ", ex.what ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::filesystem::path CCombinedContainer::resolveRealFile (const std::string& filename) const
|
||||
{
|
||||
for (auto cur : this->m_containers)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::path CCombinedContainer::resolveRealFile (const std::string& filename) const {
|
||||
for (const auto cur : this->m_containers) {
|
||||
try {
|
||||
// try to read the file on the current container, if the file doesn't exists
|
||||
// an exception will be thrown
|
||||
return cur->resolveRealFile (filename);
|
||||
}
|
||||
catch (CAssetLoadException& ex)
|
||||
{
|
||||
} catch (CAssetLoadException&) {
|
||||
// not found in this container, next try
|
||||
}
|
||||
}
|
||||
@ -58,18 +41,13 @@ std::filesystem::path CCombinedContainer::resolveRealFile (const std::string& fi
|
||||
throw CAssetLoadException (filename, "Cannot resolve file in any of the containers");
|
||||
}
|
||||
|
||||
const void* CCombinedContainer::readFile (const std::string& filename, uint32_t* length) const
|
||||
{
|
||||
for (auto cur : this->m_containers)
|
||||
{
|
||||
try
|
||||
{
|
||||
const void* CCombinedContainer::readFile (const std::string& filename, uint32_t* length) const {
|
||||
for (const auto cur : this->m_containers) {
|
||||
try {
|
||||
// try to read the file on the current container, if the file doesn't exists
|
||||
// an exception will be thrown
|
||||
return cur->readFile (filename, length);
|
||||
}
|
||||
catch (CAssetLoadException& ex)
|
||||
{
|
||||
} catch (CAssetLoadException&) {
|
||||
// not found in this container, next try
|
||||
}
|
||||
}
|
||||
|
@ -6,13 +6,11 @@
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Assets {
|
||||
/**
|
||||
* A meta-container that allows backgrounds to have files spread across different containers
|
||||
*/
|
||||
class CCombinedContainer : public CContainer
|
||||
{
|
||||
class CCombinedContainer final : public CContainer {
|
||||
public:
|
||||
CCombinedContainer ();
|
||||
|
||||
@ -37,5 +35,5 @@ namespace WallpaperEngine::Assets
|
||||
private:
|
||||
/** The list of containers to search files off from */
|
||||
std::vector<CContainer*> m_containers;
|
||||
};
|
||||
};
|
||||
}; // namespace WallpaperEngine::Assets
|
@ -1,27 +1,25 @@
|
||||
#include "CContainer.h"
|
||||
#include "CAssetLoadException.h"
|
||||
#include "CTexture.h"
|
||||
#include "WallpaperEngine/Logging/CLog.h"
|
||||
#include "CAssetLoadException.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
#include <filesystem>
|
||||
#include <utility>
|
||||
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
std::filesystem::path CContainer::resolveRealFile (const std::string& filename) const
|
||||
{
|
||||
std::filesystem::path CContainer::resolveRealFile (const std::string& filename) const {
|
||||
throw CAssetLoadException (filename, "Cannot resolve physical file in this container");
|
||||
}
|
||||
|
||||
const ITexture* CContainer::readTexture (const std::string& filename) const
|
||||
{
|
||||
const ITexture* CContainer::readTexture (const std::string& filename) const {
|
||||
// get the texture's filename (usually .tex)
|
||||
std::string texture = "materials/" + filename + ".tex";
|
||||
const std::string texture = "materials/" + filename + ".tex";
|
||||
|
||||
const void* textureContents = this->readFile (texture, nullptr);
|
||||
|
||||
ITexture* result = new CTexture (textureContents);
|
||||
const ITexture* result = new CTexture (textureContents);
|
||||
|
||||
#if !NDEBUG
|
||||
glObjectLabel (GL_TEXTURE, result->getTextureID (), -1, texture.c_str ());
|
||||
@ -29,22 +27,19 @@ const ITexture* CContainer::readTexture (const std::string& filename) const
|
||||
|
||||
return result;
|
||||
}
|
||||
std::string CContainer::readShader (const std::string& filename) const
|
||||
{
|
||||
|
||||
std::string CContainer::readShader (const std::string& filename) const {
|
||||
std::filesystem::path shader = filename;
|
||||
auto it = shader.begin ();
|
||||
|
||||
// detect workshop shaders and check if there's a
|
||||
if (*it++ == "workshop")
|
||||
{
|
||||
std::filesystem::path workshopId = *it++;
|
||||
if (*it++ == "workshop") {
|
||||
const std::filesystem::path workshopId = *it++;
|
||||
|
||||
if (++it != shader.end ())
|
||||
{
|
||||
std::filesystem::path shaderfile = *it;
|
||||
if (++it != shader.end ()) {
|
||||
const std::filesystem::path shaderfile = *it;
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
shader = std::filesystem::path ("zcompat") / "scene" / "shaders" / workshopId / shaderfile;
|
||||
// replace the old path with the new one
|
||||
std::string contents = this->readFileAsString (shader);
|
||||
@ -52,34 +47,26 @@ std::string CContainer::readShader (const std::string& filename) const
|
||||
sLog.out ("Replaced ", filename, " with compat ", shader);
|
||||
|
||||
return contents;
|
||||
}
|
||||
catch (CAssetLoadException&)
|
||||
{
|
||||
|
||||
}
|
||||
} catch (CAssetLoadException&) {}
|
||||
}
|
||||
}
|
||||
|
||||
return this->readFileAsString ("shaders/" + filename);
|
||||
}
|
||||
|
||||
std::string CContainer::readVertexShader (const std::string& filename) const
|
||||
{
|
||||
std::string CContainer::readVertexShader (const std::string& filename) const {
|
||||
return this->readShader (filename + ".vert");
|
||||
}
|
||||
|
||||
std::string CContainer::readFragmentShader (const std::string& filename) const
|
||||
{
|
||||
std::string CContainer::readFragmentShader (const std::string& filename) const {
|
||||
return this->readShader (filename + ".frag");
|
||||
}
|
||||
|
||||
std::string CContainer::readIncludeShader (const std::string& filename) const
|
||||
{
|
||||
std::string CContainer::readIncludeShader (const std::string& filename) const {
|
||||
return this->readFileAsString ("shaders/" + filename);
|
||||
}
|
||||
|
||||
std::string CContainer::readFileAsString (const std::string& filename) const
|
||||
{
|
||||
std::string CContainer::readFileAsString (const std::string& filename) const {
|
||||
uint32_t length = 0;
|
||||
|
||||
// read file contents and allocate a buffer for a string
|
||||
@ -94,7 +81,7 @@ std::string CContainer::readFileAsString (const std::string& filename) const
|
||||
std::string result = buffer;
|
||||
|
||||
// free the intermediate buffer used to generate the std::string
|
||||
delete[] buffer;
|
||||
delete [] buffer;
|
||||
|
||||
return result;
|
||||
}
|
@ -5,14 +5,14 @@
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Assets {
|
||||
/**
|
||||
* File container, provides access to files for backgrounds
|
||||
*/
|
||||
class CContainer
|
||||
{
|
||||
class CContainer {
|
||||
public:
|
||||
virtual ~CContainer () = default;
|
||||
|
||||
/**
|
||||
* Resolves the full path to the specified file in the filesystem
|
||||
*
|
||||
@ -85,5 +85,5 @@ namespace WallpaperEngine::Assets
|
||||
* @return The file's contents as string
|
||||
*/
|
||||
[[nodiscard]] std::string readFileAsString (const std::string& filename) const;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Assets
|
@ -3,63 +3,54 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "CDirectory.h"
|
||||
#include "CAssetLoadException.h"
|
||||
#include "CDirectory.h"
|
||||
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
CDirectory::CDirectory (std::filesystem::path basepath) :
|
||||
m_basepath (std::move(basepath))
|
||||
{
|
||||
CDirectory::CDirectory (std::filesystem::path basepath) : m_basepath (std::move (basepath)) {
|
||||
// ensure the specified path exists
|
||||
struct stat buffer {};
|
||||
|
||||
if (stat (this->m_basepath.c_str (), &buffer) != 0)
|
||||
throw CAssetLoadException (this->m_basepath, "Cannot find directory");
|
||||
|
||||
if (!S_ISDIR(buffer.st_mode))
|
||||
if (!S_ISDIR (buffer.st_mode))
|
||||
throw CAssetLoadException (this->m_basepath, "Expected directory but found a file");
|
||||
}
|
||||
|
||||
CDirectory::~CDirectory ()
|
||||
= default;
|
||||
|
||||
std::filesystem::path CDirectory::resolveRealFile (const std::string& filename) const
|
||||
{
|
||||
std::filesystem::path CDirectory::resolveRealFile (const std::string& filename) const {
|
||||
return std::filesystem::path (this->m_basepath) / filename;
|
||||
}
|
||||
|
||||
const void* CDirectory::readFile (const std::string& filename, uint32_t* length) const
|
||||
{
|
||||
std::filesystem::path final = std::filesystem::path (this->m_basepath) / filename;
|
||||
const void* CDirectory::readFile (const std::string& filename, uint32_t* length) const {
|
||||
const std::filesystem::path final = std::filesystem::path (this->m_basepath) / filename;
|
||||
|
||||
// first check the cache, if the file is there already just return the data in there
|
||||
auto it = this->m_cache.find (final);
|
||||
const auto it = this->m_cache.find (final);
|
||||
|
||||
if (it != this->m_cache.end ())
|
||||
{
|
||||
if (it != this->m_cache.end ()) {
|
||||
if (length != nullptr)
|
||||
*length = (*it).second.length;
|
||||
*length = it->second.length;
|
||||
|
||||
return (*it).second.address;
|
||||
return it->second.address;
|
||||
}
|
||||
|
||||
FILE* fp = fopen (final.c_str (), "rb");
|
||||
|
||||
if (fp == nullptr)
|
||||
throw CAssetLoadException(filename, "Cannot find file");
|
||||
throw CAssetLoadException (filename, "Cannot find file");
|
||||
|
||||
// go to the end, get the position and return to the beginning
|
||||
fseek (fp, 0, SEEK_END);
|
||||
long size = ftell (fp);
|
||||
const long size = ftell (fp);
|
||||
fseek (fp, 0, SEEK_SET);
|
||||
|
||||
// now read the whole file
|
||||
char* contents = new char[size];
|
||||
auto* contents = new char [size];
|
||||
|
||||
if (fread (contents, size, 1, fp) != 1)
|
||||
{
|
||||
delete[] contents;
|
||||
if (fread (contents, size, 1, fp) != 1) {
|
||||
delete [] contents;
|
||||
throw CAssetLoadException (filename, "Unexpected error when reading the file");
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "CContainer.h"
|
||||
#include "CFileEntry.h"
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Assets {
|
||||
/**
|
||||
* Directory container implementation, provides access to background files under a specific directory
|
||||
*/
|
||||
class CDirectory : public CContainer
|
||||
{
|
||||
class CDirectory final : public CContainer {
|
||||
public:
|
||||
explicit CDirectory (std::filesystem::path basepath);
|
||||
~CDirectory ();
|
||||
|
||||
/** @inheritdoc */
|
||||
[[nodiscard]] std::filesystem::path resolveRealFile (const std::string& filename) const override;
|
||||
@ -28,6 +25,6 @@ namespace WallpaperEngine::Assets
|
||||
/** The basepath for the directory */
|
||||
std::filesystem::path m_basepath;
|
||||
/** File cache to simplify access to data */
|
||||
std::map <std::string, CFileEntry> m_cache;
|
||||
};
|
||||
}
|
||||
std::map<std::string, CFileEntry> m_cache;
|
||||
};
|
||||
} // namespace WallpaperEngine::Assets
|
@ -2,21 +2,21 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Assets {
|
||||
/**
|
||||
* File cache entry to prevent hit the disk when loading the same file multiple times
|
||||
*/
|
||||
class CFileEntry
|
||||
{
|
||||
class CFileEntry {
|
||||
public:
|
||||
CFileEntry (const void* address, uint32_t length) :
|
||||
address (address),
|
||||
length (length) { }
|
||||
CFileEntry (const char* address, uint32_t length) : address (address), length (length) {}
|
||||
|
||||
~CFileEntry () {
|
||||
delete [] address;
|
||||
}
|
||||
|
||||
/** File contents */
|
||||
const void* address;
|
||||
const char* address;
|
||||
/** File length */
|
||||
uint32_t length;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Assets
|
||||
|
@ -1,53 +1,48 @@
|
||||
#include "common.h"
|
||||
#include "CPackage.h"
|
||||
#include "CAssetLoadException.h"
|
||||
#include "CPackageLoadException.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <utility>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
class CPackageEntry
|
||||
{
|
||||
public:
|
||||
class CPackageEntry {
|
||||
public:
|
||||
CPackageEntry (std::string filename, uint32_t offset, uint32_t length) :
|
||||
filename (std::move(filename)),
|
||||
filename (std::move (filename)),
|
||||
offset (offset),
|
||||
length (length) { }
|
||||
length (length) {}
|
||||
|
||||
std::string filename;
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
CPackage::CPackage (std::filesystem::path path) :
|
||||
m_path (std::move(path)),
|
||||
m_contents ()
|
||||
{
|
||||
CPackage::CPackage (std::filesystem::path path) : m_path (std::move (path)) {
|
||||
this->init ();
|
||||
}
|
||||
|
||||
CPackage::~CPackage()
|
||||
= default;
|
||||
|
||||
|
||||
const void* CPackage::readFile (const std::string& filename, uint32_t* length) const
|
||||
{
|
||||
auto it = this->m_contents.find (filename);
|
||||
const void* CPackage::readFile (const std::string& filename, uint32_t* length) const {
|
||||
const auto it = this->m_contents.find (filename);
|
||||
|
||||
if (it == this->m_contents.end ())
|
||||
throw CAssetLoadException(filename, "Cannot find the file in the package");
|
||||
throw CAssetLoadException (filename, "Cannot find the file in the package");
|
||||
|
||||
// set file length if required
|
||||
if (length != nullptr)
|
||||
*length = (*it).second.length;
|
||||
*length = it->second->length;
|
||||
|
||||
return (*it).second.address;
|
||||
// clone original first
|
||||
auto* result = new char [it->second->length];
|
||||
|
||||
memcpy (result, it->second->address, it->second->length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CPackage::init ()
|
||||
{
|
||||
void CPackage::init () {
|
||||
FILE* fp = fopen (this->m_path.c_str (), "rb+");
|
||||
|
||||
if (fp == nullptr)
|
||||
@ -61,21 +56,20 @@ void CPackage::init ()
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
char* CPackage::readSizedString (FILE* fp)
|
||||
{
|
||||
char* CPackage::readSizedString (FILE* fp) {
|
||||
unsigned int length = 0;
|
||||
|
||||
if (fread (&length, sizeof (unsigned int), 1, fp) != 1)
|
||||
sLog.exception ("Cannot read sized string length on file ", this->m_path);
|
||||
|
||||
// account for 0 termination of the string
|
||||
length ++;
|
||||
length++;
|
||||
|
||||
char* pointer = new char [length];
|
||||
memset (pointer, 0, length);
|
||||
|
||||
// read only the string bytes so the last one in the memory is 0
|
||||
length --;
|
||||
length--;
|
||||
|
||||
// read data from file
|
||||
if (fread (pointer, sizeof (char), length, fp) != length)
|
||||
@ -84,8 +78,7 @@ char* CPackage::readSizedString (FILE* fp)
|
||||
return pointer;
|
||||
}
|
||||
|
||||
uint32_t CPackage::readInteger (FILE* fp)
|
||||
{
|
||||
uint32_t CPackage::readInteger (FILE* fp) {
|
||||
uint32_t output;
|
||||
|
||||
if (fread (&output, sizeof (uint32_t), 1, fp) != 1)
|
||||
@ -94,46 +87,41 @@ uint32_t CPackage::readInteger (FILE* fp)
|
||||
return output;
|
||||
}
|
||||
|
||||
void CPackage::validateHeader (FILE* fp)
|
||||
{
|
||||
char* pointer = this->readSizedString (fp);
|
||||
void CPackage::validateHeader (FILE* fp) {
|
||||
const char* pointer = this->readSizedString (fp);
|
||||
|
||||
if (strncmp ("PKGV", pointer, 4) != 0)
|
||||
{
|
||||
if (strncmp ("PKGV", pointer, 4) != 0) {
|
||||
std::stringstream msg;
|
||||
msg << "Expected PKGV indicator, found " << pointer;
|
||||
delete[] pointer;
|
||||
throw std::runtime_error(msg.str());
|
||||
delete [] pointer;
|
||||
throw std::runtime_error (msg.str ());
|
||||
}
|
||||
|
||||
// free memory
|
||||
delete[] pointer;
|
||||
delete [] pointer;
|
||||
}
|
||||
|
||||
void CPackage::loadFiles (FILE* fp)
|
||||
{
|
||||
uint32_t count = this->readInteger (fp);
|
||||
void CPackage::loadFiles (FILE* fp) {
|
||||
const uint32_t count = this->readInteger (fp);
|
||||
std::vector<CPackageEntry> list;
|
||||
|
||||
for (uint32_t index = 0; index < count; index ++)
|
||||
{
|
||||
for (uint32_t index = 0; index < count; index++) {
|
||||
// first read the filename
|
||||
char* filename = this->readSizedString (fp);
|
||||
uint32_t offset = this->readInteger (fp);
|
||||
uint32_t length = this->readInteger (fp);
|
||||
|
||||
// add the file to the list
|
||||
list.emplace_back(filename, offset, length);
|
||||
list.emplace_back (filename, offset, length);
|
||||
// only free filename, the file's contents are stored in a map for a later use
|
||||
delete[] filename;
|
||||
delete [] filename;
|
||||
}
|
||||
|
||||
// get current baseOffset, this is where the files start
|
||||
long baseOffset = ftell (fp);
|
||||
const long baseOffset = ftell (fp);
|
||||
|
||||
for (const auto& cur : list)
|
||||
{
|
||||
long offset = cur.offset + baseOffset;
|
||||
for (const auto& cur : list) {
|
||||
const long offset = cur.offset + baseOffset;
|
||||
|
||||
// with all the data we can jump to the offset and read the content
|
||||
if (fseek (fp, offset, SEEK_SET) != 0)
|
||||
@ -142,14 +130,13 @@ void CPackage::loadFiles (FILE* fp)
|
||||
// allocate memory for the file's contents and read it from the file
|
||||
char* fileContents = new char [cur.length];
|
||||
|
||||
if (fread (fileContents, cur.length, 1, fp) != 1)
|
||||
{
|
||||
delete[] fileContents;
|
||||
if (fread (fileContents, cur.length, 1, fp) != 1) {
|
||||
delete [] fileContents;
|
||||
|
||||
sLog.exception ("Cannot read file ", cur.filename, " contents from package ", this->m_path);
|
||||
}
|
||||
|
||||
// add the file to the map
|
||||
this->m_contents.insert_or_assign (cur.filename, CFileEntry (fileContents, cur.length));
|
||||
this->m_contents.insert_or_assign (cur.filename, new CFileEntry (fileContents, cur.length));
|
||||
}
|
||||
}
|
@ -1,27 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <exception>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
|
||||
#include "CContainer.h"
|
||||
#include "CFileEntry.h"
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Assets {
|
||||
/**
|
||||
* Package container implementation, provides access to background files that are stored
|
||||
* inside the WallpaperEngine's pkg format
|
||||
*/
|
||||
class CPackage : public CContainer
|
||||
{
|
||||
class CPackage final : public CContainer {
|
||||
public:
|
||||
explicit CPackage (std::filesystem::path path);
|
||||
~CPackage ();
|
||||
|
||||
[[nodiscard]] const void* readFile (const std::string& filename, uint32_t* length) const override;
|
||||
|
||||
@ -66,6 +63,6 @@ namespace WallpaperEngine::Assets
|
||||
/** The path to the package file */
|
||||
std::filesystem::path m_path;
|
||||
/** Contents of the package file */
|
||||
std::map <std::string, CFileEntry> m_contents;
|
||||
};
|
||||
}
|
||||
std::map<std::string, CFileEntry*> m_contents;
|
||||
};
|
||||
} // namespace WallpaperEngine::Assets
|
||||
|
@ -3,11 +3,8 @@
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
CPackageLoadException::CPackageLoadException (const std::string& filename, const std::string& extrainfo) :
|
||||
m_message ("Cannot load package " + filename + ": " + extrainfo)
|
||||
{
|
||||
}
|
||||
m_message ("Cannot load package " + filename + ": " + extrainfo) {}
|
||||
|
||||
const char *CPackageLoadException::what () const noexcept
|
||||
{
|
||||
const char* CPackageLoadException::what () const noexcept {
|
||||
return this->m_message.c_str ();
|
||||
}
|
||||
|
@ -3,15 +3,13 @@
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
class CPackageLoadException : public std::exception
|
||||
{
|
||||
namespace WallpaperEngine::Assets {
|
||||
class CPackageLoadException final : public std::exception {
|
||||
public:
|
||||
explicit CPackageLoadException (const std::string& message, const std::string& extrainfo = "");
|
||||
explicit CPackageLoadException (const std::string& filename, const std::string& extrainfo = "");
|
||||
[[nodiscard]] const char* what () const noexcept override;
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Assets
|
@ -1,53 +1,37 @@
|
||||
#include "common.h"
|
||||
#include "CTexture.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <lz4.h>
|
||||
#include <string>
|
||||
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
CTexture::CTexture (const void* fileData) :
|
||||
m_resolution ()
|
||||
{
|
||||
CTexture::CTexture (const void* fileData) : m_resolution () {
|
||||
// ensure the header is parsed
|
||||
this->m_header = parseHeader (static_cast <const char*> (fileData));
|
||||
this->m_header = parseHeader (static_cast<const char*> (fileData));
|
||||
|
||||
GLint internalFormat;
|
||||
|
||||
if (this->isAnimated ())
|
||||
{
|
||||
this->m_resolution = {
|
||||
this->m_header->textureWidth, this->m_header->textureHeight,
|
||||
this->m_header->gifWidth, this->m_header->gifHeight
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN)
|
||||
{
|
||||
if (this->isAnimated ()) {
|
||||
this->m_resolution = {this->m_header->textureWidth, this->m_header->textureHeight, this->m_header->gifWidth,
|
||||
this->m_header->gifHeight};
|
||||
} else {
|
||||
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN) {
|
||||
// wpengine-texture format always has one mipmap
|
||||
// get first image size
|
||||
auto element = this->m_header->images.find (0)->second.begin ();
|
||||
|
||||
// set the texture resolution
|
||||
this->m_resolution = {
|
||||
(*element)->width, (*element)->height,
|
||||
this->m_header->width, this->m_header->height
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_resolution = {(*element)->width, (*element)->height, this->m_header->width, this->m_header->height};
|
||||
} else {
|
||||
// set the texture resolution
|
||||
this->m_resolution = {
|
||||
this->m_header->textureWidth, this->m_header->textureHeight,
|
||||
this->m_header->width, this->m_header->height
|
||||
};
|
||||
this->m_resolution = {this->m_header->textureWidth, this->m_header->textureHeight, this->m_header->width,
|
||||
this->m_header->height};
|
||||
}
|
||||
}
|
||||
|
||||
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN)
|
||||
{
|
||||
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN) {
|
||||
internalFormat = GL_RGBA8;
|
||||
// set some extra information too as it's used for image sizing
|
||||
// this ensures that a_TexCoord uses the full image instead of just part of it
|
||||
@ -56,33 +40,16 @@ CTexture::CTexture (const void* fileData) :
|
||||
this->m_header->height = this->m_header->mipmaps [0]->height;
|
||||
this->m_header->textureWidth = this->m_header->mipmaps [0]->width;
|
||||
this->m_header->textureHeight = this->m_header->mipmaps [0]->height;*/
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// detect the image format and hand it to openGL to be used
|
||||
switch (this->m_header->format)
|
||||
{
|
||||
case TextureFormat::DXT5:
|
||||
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
break;
|
||||
case TextureFormat::DXT3:
|
||||
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
break;
|
||||
case TextureFormat::DXT1:
|
||||
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
break;
|
||||
case TextureFormat::ARGB8888:
|
||||
internalFormat = GL_RGBA8;
|
||||
break;
|
||||
case TextureFormat::R8:
|
||||
internalFormat = GL_R8;
|
||||
break;
|
||||
case TextureFormat::RG88:
|
||||
internalFormat = GL_RG8;
|
||||
break;
|
||||
default:
|
||||
delete this->m_header;
|
||||
sLog.exception ("Cannot determine texture format");
|
||||
switch (this->m_header->format) {
|
||||
case TextureFormat::DXT5: internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
|
||||
case TextureFormat::DXT3: internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
|
||||
case TextureFormat::DXT1: internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
|
||||
case TextureFormat::ARGB8888: internalFormat = GL_RGBA8; break;
|
||||
case TextureFormat::R8: internalFormat = GL_R8; break;
|
||||
case TextureFormat::RG88: internalFormat = GL_RG8; break;
|
||||
default: delete this->m_header; sLog.exception ("Cannot determine texture format");
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,8 +61,7 @@ CTexture::CTexture (const void* fileData) :
|
||||
auto imgCur = this->m_header->images.begin ();
|
||||
auto imgEnd = this->m_header->images.end ();
|
||||
|
||||
for (int index = 0; imgCur != imgEnd; imgCur ++, index ++)
|
||||
{
|
||||
for (int index = 0; imgCur != imgEnd; ++imgCur, index++) {
|
||||
// bind the texture to assign information to it
|
||||
glBindTexture (GL_TEXTURE_2D, this->m_textureID [index]);
|
||||
|
||||
@ -104,35 +70,28 @@ CTexture::CTexture (const void* fileData) :
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, this->m_header->mipmapCount - 1);
|
||||
|
||||
// setup texture wrapping and filtering
|
||||
if (this->m_header->flags & TextureFlags::ClampUVs)
|
||||
{
|
||||
if (this->m_header->flags & TextureFlags::ClampUVs) {
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
}
|
||||
|
||||
if (this->m_header->flags & TextureFlags::NoInterpolation)
|
||||
{
|
||||
if (this->m_header->flags & TextureFlags::NoInterpolation) {
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
|
||||
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 8.0f);
|
||||
|
||||
auto cur = (*imgCur).second.begin ();
|
||||
auto end = (*imgCur).second.end ();
|
||||
auto cur = imgCur->second.begin ();
|
||||
auto end = imgCur->second.end ();
|
||||
|
||||
for (int32_t level = 0; cur != end; cur ++, level ++)
|
||||
{
|
||||
for (int32_t level = 0; cur != end; ++cur, level++) {
|
||||
FIBITMAP* bitmap = nullptr;
|
||||
FIBITMAP* converted = nullptr;
|
||||
FIMEMORY* memory = nullptr;
|
||||
@ -142,9 +101,9 @@ CTexture::CTexture (const void* fileData) :
|
||||
uint32_t bufferSize = (*cur)->uncompressedSize;
|
||||
GLenum textureFormat = GL_RGBA;
|
||||
|
||||
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN)
|
||||
{
|
||||
memory = FreeImage_OpenMemory (reinterpret_cast <BYTE *> ((*cur)->uncompressedData), (*cur)->uncompressedSize);
|
||||
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN) {
|
||||
memory =
|
||||
FreeImage_OpenMemory (reinterpret_cast<BYTE*> ((*cur)->uncompressedData), (*cur)->uncompressedSize);
|
||||
|
||||
// load the image and setup pointers so they can be used
|
||||
bitmap = FreeImage_LoadFromMemory (this->m_header->freeImageFormat, memory);
|
||||
@ -158,47 +117,33 @@ CTexture::CTexture (const void* fileData) :
|
||||
height = FreeImage_GetHeight (converted);
|
||||
bufferSize = FreeImage_GetMemorySize (converted);
|
||||
textureFormat = GL_BGRA;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->m_header->format == TextureFormat::R8)
|
||||
{
|
||||
} else {
|
||||
if (this->m_header->format == TextureFormat::R8) {
|
||||
// red textures are 1-byte-per-pixel, so it's alignment has to be set manually
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
||||
textureFormat = GL_RED;
|
||||
}
|
||||
else if (this->m_header->format == TextureFormat::RG88)
|
||||
} else if (this->m_header->format == TextureFormat::RG88)
|
||||
textureFormat = GL_RG;
|
||||
}
|
||||
|
||||
switch (internalFormat)
|
||||
{
|
||||
switch (internalFormat) {
|
||||
case GL_RGBA8:
|
||||
case GL_RG8:
|
||||
case GL_R8:
|
||||
glTexImage2D (
|
||||
GL_TEXTURE_2D, level, internalFormat,
|
||||
width, height, 0,
|
||||
textureFormat, GL_UNSIGNED_BYTE,
|
||||
dataptr
|
||||
);
|
||||
glTexImage2D (GL_TEXTURE_2D, level, internalFormat, width, height, 0, textureFormat,
|
||||
GL_UNSIGNED_BYTE, dataptr);
|
||||
break;
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
glCompressedTexImage2D (
|
||||
GL_TEXTURE_2D, level, internalFormat,
|
||||
width, height, 0,
|
||||
bufferSize, dataptr
|
||||
);
|
||||
glCompressedTexImage2D (GL_TEXTURE_2D, level, internalFormat, width, height, 0, bufferSize,
|
||||
dataptr);
|
||||
break;
|
||||
default:
|
||||
sLog.exception ("Cannot load texture, unknown format", this->m_header->format);
|
||||
default: sLog.exception ("Cannot load texture, unknown format", this->m_header->format);
|
||||
}
|
||||
|
||||
// freeimage buffer won't be used anymore, so free memory
|
||||
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN)
|
||||
{
|
||||
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN) {
|
||||
FreeImage_Unload (bitmap);
|
||||
FreeImage_Unload (converted);
|
||||
FreeImage_CloseMemory (memory);
|
||||
@ -207,8 +152,7 @@ CTexture::CTexture (const void* fileData) :
|
||||
}
|
||||
}
|
||||
|
||||
CTexture::~CTexture ()
|
||||
{
|
||||
CTexture::~CTexture () {
|
||||
if (this->getHeader () == nullptr)
|
||||
return;
|
||||
|
||||
@ -216,8 +160,7 @@ CTexture::~CTexture ()
|
||||
delete this->getHeader ();
|
||||
}
|
||||
|
||||
const GLuint CTexture::getTextureID (uint32_t imageIndex) const
|
||||
{
|
||||
const GLuint CTexture::getTextureID (uint32_t imageIndex) const {
|
||||
// ensure we do not go out of bounds
|
||||
if (imageIndex > this->m_header->imageCount)
|
||||
return this->m_textureID [0];
|
||||
@ -225,87 +168,73 @@ const GLuint CTexture::getTextureID (uint32_t imageIndex) const
|
||||
return this->m_textureID [imageIndex];
|
||||
}
|
||||
|
||||
const uint32_t CTexture::getTextureWidth (uint32_t imageIndex) const
|
||||
{
|
||||
const uint32_t CTexture::getTextureWidth (uint32_t imageIndex) const {
|
||||
if (imageIndex > this->m_header->imageCount)
|
||||
return this->getHeader ()->textureWidth;
|
||||
|
||||
return (*this->m_header->images [imageIndex].begin ())->width;
|
||||
}
|
||||
|
||||
const uint32_t CTexture::getTextureHeight (uint32_t imageIndex) const
|
||||
{
|
||||
const uint32_t CTexture::getTextureHeight (uint32_t imageIndex) const {
|
||||
if (imageIndex > this->m_header->imageCount)
|
||||
return this->getHeader ()->textureHeight;
|
||||
|
||||
return (*this->m_header->images [imageIndex].begin ())->height;
|
||||
}
|
||||
|
||||
const uint32_t CTexture::getRealWidth () const
|
||||
{
|
||||
const uint32_t CTexture::getRealWidth () const {
|
||||
return this->isAnimated () ? this->getHeader ()->gifWidth : this->getHeader ()->width;
|
||||
}
|
||||
|
||||
const uint32_t CTexture::getRealHeight () const
|
||||
{
|
||||
const uint32_t CTexture::getRealHeight () const {
|
||||
return this->isAnimated () ? this->getHeader ()->gifHeight : this->getHeader ()->height;
|
||||
}
|
||||
|
||||
const ITexture::TextureFormat CTexture::getFormat () const
|
||||
{
|
||||
const ITexture::TextureFormat CTexture::getFormat () const {
|
||||
return this->getHeader ()->format;
|
||||
}
|
||||
|
||||
const ITexture::TextureFlags CTexture::getFlags () const
|
||||
{
|
||||
const ITexture::TextureFlags CTexture::getFlags () const {
|
||||
return this->getHeader ()->flags;
|
||||
}
|
||||
|
||||
const CTexture::TextureHeader* CTexture::getHeader () const
|
||||
{
|
||||
const CTexture::TextureHeader* CTexture::getHeader () const {
|
||||
return this->m_header;
|
||||
}
|
||||
|
||||
const glm::vec4* CTexture::getResolution () const
|
||||
{
|
||||
const glm::vec4* CTexture::getResolution () const {
|
||||
return &this->m_resolution;
|
||||
}
|
||||
|
||||
const std::vector<ITexture::TextureFrame*>& CTexture::getFrames () const
|
||||
{
|
||||
const std::vector<ITexture::TextureFrame*>& CTexture::getFrames () const {
|
||||
return this->getHeader ()->frames;
|
||||
}
|
||||
|
||||
const bool CTexture::isAnimated () const
|
||||
{
|
||||
const bool CTexture::isAnimated () const {
|
||||
return this->getHeader ()->isAnimated ();
|
||||
}
|
||||
|
||||
CTexture::TextureMipmap::TextureMipmap ()
|
||||
= default;
|
||||
CTexture::TextureMipmap::TextureMipmap () = default;
|
||||
|
||||
CTexture::TextureMipmap::~TextureMipmap ()
|
||||
{
|
||||
CTexture::TextureMipmap::~TextureMipmap () {
|
||||
if (this->compression == 1)
|
||||
delete this->compressedData;
|
||||
|
||||
delete this->uncompressedData;
|
||||
}
|
||||
|
||||
void CTexture::TextureMipmap::decompressData ()
|
||||
{
|
||||
if (this->compression == 1)
|
||||
{
|
||||
void CTexture::TextureMipmap::decompressData () {
|
||||
if (this->compression != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->uncompressedData = new char [this->uncompressedSize];
|
||||
|
||||
int result = LZ4_decompress_safe (
|
||||
this->compressedData, this->uncompressedData,
|
||||
this->compressedSize, this->uncompressedSize
|
||||
);
|
||||
const int result = LZ4_decompress_safe (this->compressedData, this->uncompressedData, this->compressedSize,
|
||||
this->uncompressedSize);
|
||||
|
||||
if (!result)
|
||||
sLog.exception ("Cannot decompress texture data, LZ4_decompress_safe returned an error");
|
||||
}
|
||||
}
|
||||
|
||||
CTexture::TextureFrame::TextureFrame () :
|
||||
@ -316,12 +245,7 @@ CTexture::TextureFrame::TextureFrame () :
|
||||
width1 (0),
|
||||
width2 (0),
|
||||
height1 (0),
|
||||
height2 (0)
|
||||
{
|
||||
}
|
||||
|
||||
CTexture::TextureFrame::~TextureFrame ()
|
||||
= default;
|
||||
height2 (0) {}
|
||||
|
||||
CTexture::TextureHeader::TextureHeader () :
|
||||
flags (NoFlags),
|
||||
@ -333,130 +257,109 @@ CTexture::TextureHeader::TextureHeader () :
|
||||
gifHeight (0),
|
||||
format (TextureFormat::UNKNOWN),
|
||||
imageCount (0),
|
||||
mipmapCount (0)
|
||||
{
|
||||
}
|
||||
mipmapCount (0) {}
|
||||
|
||||
CTexture::TextureHeader::~TextureHeader ()
|
||||
{
|
||||
for (const auto& imgCur : this->images)
|
||||
for (auto cur : imgCur.second)
|
||||
CTexture::TextureHeader::~TextureHeader () {
|
||||
for (const auto& [index, mipmaps] : this->images)
|
||||
for (const auto cur : mipmaps)
|
||||
delete cur;
|
||||
}
|
||||
|
||||
CTexture::TextureHeader* CTexture::parseHeader (const char* fileData)
|
||||
{
|
||||
CTexture::TextureHeader* CTexture::parseHeader (const char* fileData) {
|
||||
// check the magic value on the header first
|
||||
if (memcmp (fileData, "TEXV0005", 9) != 0)
|
||||
if (strncmp (fileData, "TEXV0005", 9) != 0)
|
||||
sLog.exception ("unexpected texture container type: ", std::string_view (fileData, 9));
|
||||
// jump to the next value
|
||||
fileData += 9;
|
||||
// check the sub-magic value on the header
|
||||
if (memcmp (fileData, "TEXI0001", 9) != 0)
|
||||
if (strncmp (fileData, "TEXI0001", 9) != 0)
|
||||
sLog.exception ("unexpected texture sub-container type: ", std::string_view (fileData, 9));
|
||||
// jump through the string again
|
||||
fileData += 9;
|
||||
|
||||
auto* header = new TextureHeader;
|
||||
|
||||
const auto* pointer = reinterpret_cast <const uint32_t*> (fileData);
|
||||
const auto* pointer = reinterpret_cast<const uint32_t*> (fileData);
|
||||
|
||||
header->format = static_cast <TextureFormat>(*pointer ++);
|
||||
header->flags = static_cast <TextureFlags> (*pointer ++);
|
||||
header->textureWidth = *pointer ++;
|
||||
header->textureHeight = *pointer ++;
|
||||
header->width = *pointer ++;
|
||||
header->height = *pointer ++;
|
||||
pointer ++; // ignore some more bytes
|
||||
header->format = static_cast<TextureFormat> (*pointer++);
|
||||
header->flags = static_cast<TextureFlags> (*pointer++);
|
||||
header->textureWidth = *pointer++;
|
||||
header->textureHeight = *pointer++;
|
||||
header->width = *pointer++;
|
||||
header->height = *pointer++;
|
||||
pointer++; // ignore some more bytes
|
||||
|
||||
// now we're going to parse some more data that is string
|
||||
// so get the current position back as string
|
||||
fileData = reinterpret_cast <const char*> (pointer);
|
||||
fileData = reinterpret_cast<const char*> (pointer);
|
||||
// get the position of what comes after the texture data
|
||||
pointer = reinterpret_cast <const uint32_t*> (fileData + 9);
|
||||
pointer = reinterpret_cast<const uint32_t*> (fileData + 9);
|
||||
|
||||
if (memcmp (fileData, "TEXB0003", 9) == 0)
|
||||
{
|
||||
if (strncmp (fileData, "TEXB0003", 9) == 0) {
|
||||
header->containerVersion = ContainerVersion::TEXB0003;
|
||||
header->imageCount = *pointer ++;
|
||||
header->freeImageFormat = static_cast <FREE_IMAGE_FORMAT> (*pointer++);
|
||||
}
|
||||
else if(memcmp (fileData, "TEXB0002", 9) == 0)
|
||||
{
|
||||
header->imageCount = *pointer++;
|
||||
header->freeImageFormat = static_cast<FREE_IMAGE_FORMAT> (*pointer++);
|
||||
} else if (strncmp (fileData, "TEXB0002", 9) == 0) {
|
||||
header->containerVersion = ContainerVersion::TEXB0002;
|
||||
header->imageCount = *pointer ++;
|
||||
}
|
||||
else if (memcmp (fileData, "TEXB0001", 9) == 0)
|
||||
{
|
||||
header->imageCount = *pointer++;
|
||||
} else if (strncmp (fileData, "TEXB0001", 9) == 0) {
|
||||
header->containerVersion = ContainerVersion::TEXB0001;
|
||||
header->imageCount = *pointer ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
header->imageCount = *pointer++;
|
||||
} else {
|
||||
delete header;
|
||||
sLog.exception ("unknown texture format type: ", std::string_view (fileData, 9));
|
||||
}
|
||||
|
||||
for (uint32_t image = 0; image < header->imageCount; image ++)
|
||||
{
|
||||
for (uint32_t image = 0; image < header->imageCount; image++) {
|
||||
// read the number of mipmaps available for this image
|
||||
header->mipmapCount = *pointer ++;
|
||||
std::vector <TextureMipmap*> mipmaps;
|
||||
header->mipmapCount = *pointer++;
|
||||
std::vector<TextureMipmap*> mipmaps;
|
||||
|
||||
fileData = reinterpret_cast <const char*> (pointer);
|
||||
fileData = reinterpret_cast<const char*> (pointer);
|
||||
|
||||
for (uint32_t i = 0; i < header->mipmapCount; i ++)
|
||||
for (uint32_t i = 0; i < header->mipmapCount; i++)
|
||||
mipmaps.emplace_back (parseMipmap (header, &fileData));
|
||||
|
||||
// add the pixmaps back
|
||||
header->images.insert (std::pair <uint32_t, std::vector <TextureMipmap*>> (image, mipmaps));
|
||||
header->images.insert (std::pair (image, mipmaps));
|
||||
|
||||
pointer = reinterpret_cast <const uint32_t*> (fileData);
|
||||
pointer = reinterpret_cast<const uint32_t*> (fileData);
|
||||
}
|
||||
|
||||
// gifs have extra information after the mipmaps
|
||||
if (header->isAnimated () == true)
|
||||
{
|
||||
if (memcmp (fileData, "TEXS0002", 9) == 0)
|
||||
{
|
||||
if (header->isAnimated () == true) {
|
||||
if (strncmp (fileData, "TEXS0002", 9) == 0) {
|
||||
header->animatedVersion = AnimatedVersion::TEXS0002;
|
||||
}
|
||||
else if (memcmp (fileData, "TEXS0003", 9) == 0)
|
||||
{
|
||||
} else if (strncmp (fileData, "TEXS0003", 9) == 0) {
|
||||
header->animatedVersion = AnimatedVersion::TEXS0003;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
delete header;
|
||||
sLog.exception ("found animation information of unknown type: ", std::string_view (fileData, 9));
|
||||
}
|
||||
|
||||
// get an integer pointer back to read the frame count
|
||||
pointer = reinterpret_cast <const uint32_t*> (fileData + 9);
|
||||
pointer = reinterpret_cast<const uint32_t*> (fileData + 9);
|
||||
uint32_t framecount = *pointer++;
|
||||
|
||||
if (header->animatedVersion == AnimatedVersion::TEXS0003)
|
||||
{
|
||||
if (header->animatedVersion == AnimatedVersion::TEXS0003) {
|
||||
// ignore two extra integers as those are width and height of the git
|
||||
header->gifWidth = *pointer ++;
|
||||
header->gifHeight = *pointer ++;
|
||||
header->gifWidth = *pointer++;
|
||||
header->gifHeight = *pointer++;
|
||||
}
|
||||
|
||||
// get back the pointer into filedata
|
||||
fileData = reinterpret_cast <const char*> (pointer);
|
||||
fileData = reinterpret_cast<const char*> (pointer);
|
||||
|
||||
while (framecount > 0)
|
||||
{
|
||||
while (framecount > 0) {
|
||||
// add the frame to the list
|
||||
header->frames.push_back (parseAnimation (&fileData));
|
||||
|
||||
framecount --;
|
||||
framecount--;
|
||||
}
|
||||
|
||||
// ensure gif width and height is right for TEXS0002
|
||||
if (header->animatedVersion == AnimatedVersion::TEXS0002)
|
||||
{
|
||||
TextureFrame* first = *header->frames.begin ();
|
||||
if (header->animatedVersion == AnimatedVersion::TEXS0002) {
|
||||
const TextureFrame* first = *header->frames.begin ();
|
||||
|
||||
header->gifWidth = first->width1;
|
||||
header->gifHeight = first->height1;
|
||||
@ -466,50 +369,47 @@ CTexture::TextureHeader* CTexture::parseHeader (const char* fileData)
|
||||
return header;
|
||||
}
|
||||
|
||||
CTexture::TextureFrame* CTexture::parseAnimation (const char** originalFileData)
|
||||
{
|
||||
CTexture::TextureFrame* CTexture::parseAnimation (const char** originalFileData) {
|
||||
const char* fileData = *originalFileData;
|
||||
// get back the pointer into integer
|
||||
const auto* pointer = reinterpret_cast <const uint32_t*> (fileData);
|
||||
const auto* pointer = reinterpret_cast<const uint32_t*> (fileData);
|
||||
|
||||
// start reading frame information
|
||||
auto* frame = new TextureFrame();
|
||||
auto* frame = new TextureFrame ();
|
||||
|
||||
frame->frameNumber = *pointer++;
|
||||
|
||||
// reinterpret the pointer into float
|
||||
const auto* fPointer = reinterpret_cast <const float*> (pointer);
|
||||
const auto* fPointer = reinterpret_cast<const float*> (pointer);
|
||||
|
||||
frame->frametime = *fPointer ++;
|
||||
frame->x = *fPointer ++;
|
||||
frame->y = *fPointer ++;
|
||||
frame->width1 = *fPointer ++;
|
||||
frame->width2 = *fPointer ++;
|
||||
frame->height2 = *fPointer ++;
|
||||
frame->height1 = *fPointer ++;
|
||||
frame->frametime = *fPointer++;
|
||||
frame->x = *fPointer++;
|
||||
frame->y = *fPointer++;
|
||||
frame->width1 = *fPointer++;
|
||||
frame->width2 = *fPointer++;
|
||||
frame->height2 = *fPointer++;
|
||||
frame->height1 = *fPointer++;
|
||||
|
||||
// get back the pointer into fileData so it can be reused later
|
||||
*originalFileData = reinterpret_cast <const char*> (fPointer);
|
||||
*originalFileData = reinterpret_cast<const char*> (fPointer);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const char** originalFileData)
|
||||
{
|
||||
CTexture::TextureMipmap* CTexture::parseMipmap (const TextureHeader* header, const char** originalFileData) {
|
||||
auto* mipmap = new TextureMipmap ();
|
||||
|
||||
// get the current position
|
||||
const char* fileData = *originalFileData;
|
||||
|
||||
// get an integer pointer
|
||||
const auto* pointer = reinterpret_cast <const uint32_t*> (fileData);
|
||||
const auto* pointer = reinterpret_cast<const uint32_t*> (fileData);
|
||||
|
||||
mipmap->width = *pointer++;
|
||||
mipmap->height = *pointer++;
|
||||
|
||||
if (header->containerVersion == ContainerVersion::TEXB0002 ||
|
||||
header->containerVersion == ContainerVersion::TEXB0003)
|
||||
{
|
||||
header->containerVersion == ContainerVersion::TEXB0003) {
|
||||
mipmap->compression = *pointer++;
|
||||
mipmap->uncompressedSize = *pointer++;
|
||||
}
|
||||
@ -517,10 +417,9 @@ CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const cha
|
||||
mipmap->compressedSize = *pointer++;
|
||||
|
||||
// get back a normal char pointer
|
||||
fileData = reinterpret_cast <const char*> (pointer);
|
||||
fileData = reinterpret_cast<const char*> (pointer);
|
||||
|
||||
if (mipmap->compression == 0)
|
||||
{
|
||||
if (mipmap->compression == 0) {
|
||||
// this might be better named as mipmap_bytes_size instead of compressedSize
|
||||
// as in uncompressed files this variable actually holds the file length
|
||||
mipmap->uncompressedSize = mipmap->compressedSize;
|
||||
@ -528,8 +427,7 @@ CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const cha
|
||||
|
||||
mipmap->uncompressedData = new char [mipmap->uncompressedSize];
|
||||
|
||||
if (mipmap->compression == 1)
|
||||
{
|
||||
if (mipmap->compression == 1) {
|
||||
mipmap->compressedData = new char [mipmap->compressedSize];
|
||||
|
||||
memcpy (mipmap->compressedData, fileData, mipmap->compressedSize);
|
||||
@ -537,9 +435,7 @@ CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const cha
|
||||
mipmap->decompressData ();
|
||||
// advance to the end of the mipmap
|
||||
fileData += mipmap->compressedSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
memcpy (mipmap->uncompressedData, fileData, mipmap->uncompressedSize);
|
||||
// advance to the end of the mipmap
|
||||
fileData += mipmap->uncompressedSize;
|
||||
@ -551,7 +447,6 @@ CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const cha
|
||||
return mipmap;
|
||||
}
|
||||
|
||||
bool CTexture::TextureHeader::isAnimated () const
|
||||
{
|
||||
bool CTexture::TextureHeader::isAnimated () const {
|
||||
return this->flags & TextureFlags::IsGif;
|
||||
}
|
@ -10,19 +10,15 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Assets {
|
||||
/**
|
||||
* A normal texture file in WallpaperEngine's format
|
||||
*/
|
||||
class CTexture : public ITexture
|
||||
{
|
||||
private:
|
||||
class CTexture final : public ITexture {
|
||||
/**
|
||||
* Different texture container versions supported
|
||||
*/
|
||||
enum ContainerVersion : int
|
||||
{
|
||||
enum ContainerVersion : int {
|
||||
UNKNOWN = -1,
|
||||
TEXB0003 = 3,
|
||||
TEXB0002 = 2,
|
||||
@ -32,8 +28,7 @@ namespace WallpaperEngine::Assets
|
||||
/**
|
||||
* Different texture animation versions supported
|
||||
*/
|
||||
enum AnimatedVersion : int
|
||||
{
|
||||
enum AnimatedVersion : int {
|
||||
TEXSUNKN = -1,
|
||||
TEXS0002 = 0,
|
||||
TEXS0003 = 1,
|
||||
@ -42,8 +37,7 @@ namespace WallpaperEngine::Assets
|
||||
/**
|
||||
* Texture mipmap data
|
||||
*/
|
||||
class TextureMipmap
|
||||
{
|
||||
class TextureMipmap {
|
||||
public:
|
||||
TextureMipmap ();
|
||||
~TextureMipmap ();
|
||||
@ -71,8 +65,7 @@ namespace WallpaperEngine::Assets
|
||||
/**
|
||||
* Texture header data
|
||||
*/
|
||||
class TextureHeader
|
||||
{
|
||||
class TextureHeader {
|
||||
public:
|
||||
TextureHeader ();
|
||||
~TextureHeader ();
|
||||
@ -113,7 +106,7 @@ namespace WallpaperEngine::Assets
|
||||
|
||||
public:
|
||||
explicit CTexture (const void* fileData);
|
||||
~CTexture ();
|
||||
~CTexture () override;
|
||||
|
||||
/** @inheritdoc */
|
||||
[[nodiscard]] const GLuint getTextureID (uint32_t imageIndex = 0) const override;
|
||||
@ -163,7 +156,7 @@ namespace WallpaperEngine::Assets
|
||||
* @param fileData The point at which to start reading data off from
|
||||
* @return
|
||||
*/
|
||||
static TextureMipmap* parseMipmap (TextureHeader* header, const char** fileData);
|
||||
static TextureMipmap* parseMipmap (const TextureHeader* header, const char** fileData);
|
||||
|
||||
/** The texture header */
|
||||
TextureHeader* m_header;
|
||||
@ -171,5 +164,5 @@ namespace WallpaperEngine::Assets
|
||||
GLuint* m_textureID;
|
||||
/** Resolution vector of the texture */
|
||||
glm::vec4 m_resolution;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Assets
|
@ -1,19 +1,15 @@
|
||||
#include <memory.h>
|
||||
|
||||
#include "CVirtualContainer.h"
|
||||
#include "CAssetLoadException.h"
|
||||
#include "CVirtualContainer.h"
|
||||
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
void CVirtualContainer::add (const std::string& filename, void* contents, uint32_t length)
|
||||
{
|
||||
this->m_virtualFiles.insert (
|
||||
std::make_pair (filename, CFileEntry (contents, length))
|
||||
);
|
||||
void CVirtualContainer::add (const std::string& filename, const char* contents, uint32_t length) {
|
||||
this->m_virtualFiles.insert (std::make_pair (filename, new CFileEntry (contents, length)));
|
||||
}
|
||||
|
||||
void CVirtualContainer::add (const std::string& filename, const std::string& contents)
|
||||
{
|
||||
void CVirtualContainer::add (const std::string& filename, const std::string& contents) {
|
||||
char* copy = new char [contents.length () + 1];
|
||||
|
||||
// copy the text AND the \0
|
||||
@ -23,14 +19,19 @@ void CVirtualContainer::add (const std::string& filename, const std::string& con
|
||||
this->add (filename, copy, contents.length () + 1);
|
||||
}
|
||||
|
||||
const void* CVirtualContainer::readFile (const std::string& filename, uint32_t* length) const
|
||||
{
|
||||
auto cur = this->m_virtualFiles.find (filename);
|
||||
const void* CVirtualContainer::readFile (const std::string& filename, uint32_t* length) const {
|
||||
const auto cur = this->m_virtualFiles.find (filename);
|
||||
|
||||
if (cur == this->m_virtualFiles.end ())
|
||||
throw CAssetLoadException (filename, "Cannot find file in the virtual container");
|
||||
|
||||
*length = (*cur).second.length;
|
||||
if (length != nullptr)
|
||||
*length = cur->second->length;
|
||||
|
||||
return (*cur).second.address;
|
||||
// clone original first
|
||||
char* result = new char [cur->second->length];
|
||||
|
||||
memcpy (result, cur->second->address, cur->second->length);
|
||||
|
||||
return result;
|
||||
}
|
@ -1,22 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "CFileEntry.h"
|
||||
#include "CContainer.h"
|
||||
#include "CFileEntry.h"
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Assets {
|
||||
/**
|
||||
* Virtual container implementation, provides virtual files for the backgrounds to use
|
||||
*/
|
||||
class CVirtualContainer : public CContainer
|
||||
{
|
||||
class CVirtualContainer final : public CContainer {
|
||||
public:
|
||||
CVirtualContainer () = default;
|
||||
~CVirtualContainer () = default;
|
||||
|
||||
/**
|
||||
* Adds a new file to the virtual container
|
||||
*
|
||||
@ -24,7 +19,7 @@ namespace WallpaperEngine::Assets
|
||||
* @param contents
|
||||
* @param length
|
||||
*/
|
||||
void add (const std::string& filename, void* contents, uint32_t length);
|
||||
void add (const std::string& filename, const char* contents, uint32_t length);
|
||||
|
||||
/**
|
||||
* Adds a new file to the virtual container
|
||||
@ -38,6 +33,6 @@ namespace WallpaperEngine::Assets
|
||||
|
||||
private:
|
||||
/** The recorded files in this virtual container */
|
||||
std::map <std::string, CFileEntry> m_virtualFiles;
|
||||
};
|
||||
}
|
||||
std::map<std::string, CFileEntry*> m_virtualFiles;
|
||||
};
|
||||
} // namespace WallpaperEngine::Assets
|
@ -4,23 +4,22 @@
|
||||
#include <glm/vec4.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Assets {
|
||||
/**
|
||||
* Base interface that describes the minimum information required for a texture
|
||||
* to be displayed by the engine
|
||||
*/
|
||||
class ITexture
|
||||
{
|
||||
class ITexture {
|
||||
public:
|
||||
virtual ~ITexture () = default;
|
||||
|
||||
/**
|
||||
* Texture frame information for animated textures
|
||||
*/
|
||||
class TextureFrame
|
||||
{
|
||||
class TextureFrame final {
|
||||
public:
|
||||
TextureFrame();
|
||||
~TextureFrame();
|
||||
TextureFrame ();
|
||||
virtual ~TextureFrame () = default;
|
||||
|
||||
/** The image index of this frame */
|
||||
uint32_t frameNumber;
|
||||
@ -41,8 +40,7 @@ namespace WallpaperEngine::Assets
|
||||
/**
|
||||
* Data formats for textures in memory
|
||||
*/
|
||||
enum TextureFormat : uint32_t
|
||||
{
|
||||
enum TextureFormat : uint32_t {
|
||||
UNKNOWN = 0xFFFFFFFF,
|
||||
ARGB8888 = 0,
|
||||
RGB888 = 1,
|
||||
@ -63,8 +61,7 @@ namespace WallpaperEngine::Assets
|
||||
/**
|
||||
* Different settings of the textures
|
||||
*/
|
||||
enum TextureFlags : uint32_t
|
||||
{
|
||||
enum TextureFlags : uint32_t {
|
||||
NoFlags = 0,
|
||||
NoInterpolation = 1,
|
||||
ClampUVs = 2,
|
||||
@ -115,5 +112,5 @@ namespace WallpaperEngine::Assets
|
||||
* @return If the texture is animated or not
|
||||
*/
|
||||
[[nodiscard]] virtual const bool isAnimated () const = 0;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Assets
|
@ -1,40 +1,30 @@
|
||||
#include "CAudioContext.h"
|
||||
#include "WallpaperEngine/Audio/Drivers/CAudioDriver.h"
|
||||
|
||||
namespace WallpaperEngine::Audio
|
||||
{
|
||||
CAudioContext::CAudioContext (Drivers::CAudioDriver& driver) :
|
||||
m_driver (driver)
|
||||
{
|
||||
}
|
||||
namespace WallpaperEngine::Audio {
|
||||
CAudioContext::CAudioContext (Drivers::CAudioDriver& driver) : m_driver (driver) {}
|
||||
|
||||
void CAudioContext::addStream (CAudioStream* stream)
|
||||
{
|
||||
void CAudioContext::addStream (CAudioStream* stream) {
|
||||
this->m_driver.addStream (stream);
|
||||
}
|
||||
|
||||
AVSampleFormat CAudioContext::getFormat () const
|
||||
{
|
||||
return this->m_driver.getFormat ();
|
||||
}
|
||||
|
||||
int CAudioContext::getSampleRate () const
|
||||
{
|
||||
return this->m_driver.getSampleRate ();
|
||||
}
|
||||
|
||||
int CAudioContext::getChannels () const
|
||||
{
|
||||
return this->m_driver.getChannels ();
|
||||
}
|
||||
|
||||
Application::CApplicationContext& CAudioContext::getApplicationContext ()
|
||||
{
|
||||
return this->m_driver.getApplicationContext ();
|
||||
}
|
||||
|
||||
Drivers::Recorders::CPlaybackRecorder& CAudioContext::getRecorder ()
|
||||
{
|
||||
return this->m_driver.getRecorder ();
|
||||
}
|
||||
}
|
||||
|
||||
AVSampleFormat CAudioContext::getFormat () const {
|
||||
return this->m_driver.getFormat ();
|
||||
}
|
||||
|
||||
int CAudioContext::getSampleRate () const {
|
||||
return this->m_driver.getSampleRate ();
|
||||
}
|
||||
|
||||
int CAudioContext::getChannels () const {
|
||||
return this->m_driver.getChannels ();
|
||||
}
|
||||
|
||||
Application::CApplicationContext& CAudioContext::getApplicationContext () {
|
||||
return this->m_driver.getApplicationContext ();
|
||||
}
|
||||
|
||||
Drivers::Recorders::CPlaybackRecorder& CAudioContext::getRecorder () {
|
||||
return this->m_driver.getRecorder ();
|
||||
}
|
||||
} // namespace WallpaperEngine::Audio
|
@ -3,32 +3,26 @@
|
||||
#include <libavutil/samplefmt.h>
|
||||
#include <vector>
|
||||
|
||||
#include "WallpaperEngine/Audio/Drivers/Recorders/CPulseAudioPlaybackRecorder.h"
|
||||
#include "WallpaperEngine/Application/CApplicationContext.h"
|
||||
#include "WallpaperEngine/Audio/Drivers/Recorders/CPulseAudioPlaybackRecorder.h"
|
||||
|
||||
namespace WallpaperEngine
|
||||
{
|
||||
namespace Application
|
||||
{
|
||||
class CApplicationContext;
|
||||
}
|
||||
namespace WallpaperEngine {
|
||||
namespace Application {
|
||||
class CApplicationContext;
|
||||
}
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
namespace Drivers
|
||||
{
|
||||
class CAudioDriver;
|
||||
namespace Audio {
|
||||
namespace Drivers {
|
||||
class CAudioDriver;
|
||||
|
||||
namespace Recorders
|
||||
{
|
||||
class CPulseAudioPlaybackRecorder;
|
||||
}
|
||||
}
|
||||
namespace Recorders {
|
||||
class CPulseAudioPlaybackRecorder;
|
||||
}
|
||||
} // namespace Drivers
|
||||
|
||||
class CAudioStream;
|
||||
class CAudioStream;
|
||||
|
||||
class CAudioContext
|
||||
{
|
||||
class CAudioContext {
|
||||
public:
|
||||
explicit CAudioContext (Drivers::CAudioDriver& driver);
|
||||
|
||||
@ -65,6 +59,6 @@ namespace WallpaperEngine
|
||||
private:
|
||||
/** The audio driver in use */
|
||||
Drivers::CAudioDriver& m_driver;
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Audio
|
||||
} // namespace WallpaperEngine
|
@ -1,5 +1,5 @@
|
||||
#include "common.h"
|
||||
#include "CAudioStream.h"
|
||||
#include "common.h"
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
@ -10,25 +10,20 @@
|
||||
|
||||
using namespace WallpaperEngine::Audio;
|
||||
|
||||
int audio_read_thread (void* arg)
|
||||
{
|
||||
int audio_read_thread (void* arg) {
|
||||
SDL_mutex* waitMutex = SDL_CreateMutex ();
|
||||
auto* stream = static_cast <CAudioStream*> (arg);
|
||||
auto* stream = static_cast<CAudioStream*> (arg);
|
||||
AVPacket* packet = av_packet_alloc ();
|
||||
int ret = 0;
|
||||
|
||||
if (waitMutex == nullptr)
|
||||
sLog.exception ("Cannot create mutex for audio playback waiting");
|
||||
|
||||
while (ret >= 0 && stream->getAudioContext ().getApplicationContext ().state.general.keepRunning)
|
||||
{
|
||||
while (ret >= 0 && stream->getAudioContext ().getApplicationContext ().state.general.keepRunning) {
|
||||
// give the cpu some time to play the queued frames if there's enough info there
|
||||
if (
|
||||
stream->getQueueSize () >= MAX_QUEUE_SIZE ||
|
||||
if (stream->getQueueSize () >= MAX_QUEUE_SIZE ||
|
||||
(stream->getQueuePacketCount () > MIN_FRAMES &&
|
||||
(av_q2d (stream->getTimeBase ()) * stream->getQueueDuration () > 1.0))
|
||||
)
|
||||
{
|
||||
(av_q2d (stream->getTimeBase ()) * stream->getQueueDuration () > 1.0))) {
|
||||
SDL_LockMutex (waitMutex);
|
||||
SDL_CondWaitTimeout (stream->getWaitCondition (), waitMutex, 10);
|
||||
SDL_UnlockMutex (waitMutex);
|
||||
@ -37,14 +32,13 @@ int audio_read_thread (void* arg)
|
||||
|
||||
ret = av_read_frame (stream->getFormatContext (), packet);
|
||||
|
||||
if (ret == AVERROR_EOF)
|
||||
{
|
||||
if (ret == AVERROR_EOF) {
|
||||
// seek to the beginning of the file again
|
||||
avformat_seek_file (stream->getFormatContext (), stream->getAudioStream (), 0, 0, 0, ~AVSEEK_FLAG_FRAME);
|
||||
avcodec_flush_buffers (stream->getContext ());
|
||||
|
||||
// ensure the thread is not killed if audio has to be looped
|
||||
if (stream->isRepeat())
|
||||
if (stream->isRepeat ())
|
||||
ret = 0;
|
||||
|
||||
continue;
|
||||
@ -67,36 +61,29 @@ int audio_read_thread (void* arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int audio_read_data_callback (void* streamarg, uint8_t* buffer, int buffer_size)
|
||||
{
|
||||
auto stream = static_cast <CAudioStream*> (streamarg);
|
||||
int left = stream->getLength () - stream->getPosition ();
|
||||
static int audio_read_data_callback (void* streamarg, uint8_t* buffer, int buffer_size) {
|
||||
const auto stream = static_cast<CAudioStream*> (streamarg);
|
||||
const int left = stream->getLength () - stream->getPosition ();
|
||||
|
||||
buffer_size = FFMIN (buffer_size, left);
|
||||
|
||||
memcpy (buffer, (uint8_t*) stream->getBuffer () + stream->getPosition (), buffer_size);
|
||||
memcpy (buffer, stream->getBuffer () + stream->getPosition (), buffer_size);
|
||||
// update position
|
||||
stream->setPosition (stream->getPosition () + buffer_size);
|
||||
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
int64_t audio_seek_data_callback (void* streamarg, int64_t offset, int whence)
|
||||
{
|
||||
auto stream = static_cast <CAudioStream*> (streamarg);
|
||||
int64_t audio_seek_data_callback (void* streamarg, int64_t offset, int whence) {
|
||||
const auto stream = static_cast<CAudioStream*> (streamarg);
|
||||
|
||||
if (whence & AVSEEK_SIZE)
|
||||
return stream->getLength ();
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_CUR:
|
||||
stream->setPosition (stream->getPosition () + offset);
|
||||
break;
|
||||
switch (whence) {
|
||||
case SEEK_CUR: stream->setPosition (stream->getPosition () + offset); break;
|
||||
|
||||
case SEEK_SET:
|
||||
stream->setPosition (offset);
|
||||
break;
|
||||
case SEEK_SET: stream->setPosition (offset); break;
|
||||
}
|
||||
|
||||
return offset;
|
||||
@ -104,15 +91,13 @@ int64_t audio_seek_data_callback (void* streamarg, int64_t offset, int whence)
|
||||
|
||||
CAudioStream::CAudioStream (CAudioContext& context, const std::string& filename) :
|
||||
m_audioContext (context),
|
||||
m_swrctx (nullptr)
|
||||
{
|
||||
m_swrctx (nullptr) {
|
||||
this->loadCustomContent (filename.c_str ());
|
||||
}
|
||||
|
||||
CAudioStream::CAudioStream (CAudioContext& context, const void* buffer, int length) :
|
||||
m_audioContext (context),
|
||||
m_swrctx (nullptr)
|
||||
{
|
||||
m_swrctx (nullptr) {
|
||||
// setup a custom context first
|
||||
this->m_formatContext = avformat_alloc_context ();
|
||||
|
||||
@ -124,15 +109,8 @@ CAudioStream::CAudioStream (CAudioContext& context, const void* buffer, int leng
|
||||
this->m_position = 0;
|
||||
|
||||
// setup custom io for it
|
||||
this->m_formatContext->pb = avio_alloc_context (
|
||||
static_cast <uint8_t*> (av_malloc (4096)),
|
||||
4096,
|
||||
0,
|
||||
static_cast <void*> (this),
|
||||
&audio_read_data_callback,
|
||||
nullptr,
|
||||
&audio_seek_data_callback
|
||||
);
|
||||
this->m_formatContext->pb = avio_alloc_context (static_cast<uint8_t*> (av_malloc (4096)), 4096, 0, this,
|
||||
&audio_read_data_callback, nullptr, &audio_seek_data_callback);
|
||||
|
||||
if (this->m_formatContext->pb == nullptr)
|
||||
sLog.exception ("Cannot create avio context");
|
||||
@ -141,17 +119,15 @@ CAudioStream::CAudioStream (CAudioContext& context, const void* buffer, int leng
|
||||
this->loadCustomContent ();
|
||||
}
|
||||
|
||||
CAudioStream::CAudioStream(CAudioContext& audioContext, AVCodecContext* context) :
|
||||
CAudioStream::CAudioStream (CAudioContext& audioContext, AVCodecContext* context) :
|
||||
m_context (context),
|
||||
m_queue (new PacketQueue),
|
||||
m_audioContext (audioContext),
|
||||
m_swrctx (nullptr)
|
||||
{
|
||||
m_swrctx (nullptr) {
|
||||
this->initialize ();
|
||||
}
|
||||
|
||||
CAudioStream::~CAudioStream()
|
||||
{
|
||||
CAudioStream::~CAudioStream () {
|
||||
if (this->m_swrctx != nullptr && swr_is_initialized (this->m_swrctx) == true)
|
||||
swr_close (this->m_swrctx);
|
||||
if (this->m_swrctx != nullptr)
|
||||
@ -160,19 +136,14 @@ CAudioStream::~CAudioStream()
|
||||
// TODO: FREE EVERYTHING ELSE THAT THIS CLASS HOLDS!
|
||||
}
|
||||
|
||||
void CAudioStream::loadCustomContent (const char* filename)
|
||||
{
|
||||
const AVCodec* aCodec;
|
||||
AVCodecContext* avCodecContext;
|
||||
|
||||
void CAudioStream::loadCustomContent (const char* filename) {
|
||||
if (avformat_open_input (&this->m_formatContext, filename, nullptr, nullptr) != 0)
|
||||
sLog.exception ("Cannot open audio file: ", filename);
|
||||
if (avformat_find_stream_info (this->m_formatContext, nullptr) < 0)
|
||||
sLog.exception ("Cannot determine file format: ", filename);
|
||||
|
||||
// find the audio stream
|
||||
for (int i = 0; i< this->m_formatContext->nb_streams; i ++)
|
||||
{
|
||||
for (int i = 0; i < this->m_formatContext->nb_streams; i++) {
|
||||
if (this->m_formatContext->streams [i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && this->m_audioStream < 0)
|
||||
this->m_audioStream = i;
|
||||
}
|
||||
@ -181,15 +152,17 @@ void CAudioStream::loadCustomContent (const char* filename)
|
||||
sLog.exception ("Cannot find an audio stream in file ", filename);
|
||||
|
||||
// get the decoder for it and alloc the required context
|
||||
aCodec = avcodec_find_decoder (this->m_formatContext->streams [this->m_audioStream]->codecpar->codec_id);
|
||||
const AVCodec* aCodec =
|
||||
avcodec_find_decoder (this->m_formatContext->streams [this->m_audioStream]->codecpar->codec_id);
|
||||
|
||||
if (aCodec == nullptr)
|
||||
sLog.exception ("Cannot initialize audio decoder for file: ", filename);
|
||||
|
||||
// alocate context
|
||||
avCodecContext = avcodec_alloc_context3 (aCodec);
|
||||
AVCodecContext* avCodecContext = avcodec_alloc_context3 (aCodec);
|
||||
|
||||
if (avcodec_parameters_to_context (avCodecContext, this->m_formatContext->streams [this->m_audioStream]->codecpar) != 0)
|
||||
if (avcodec_parameters_to_context (avCodecContext,
|
||||
this->m_formatContext->streams [this->m_audioStream]->codecpar) != 0)
|
||||
sLog.exception ("Cannot initialize audio decoder parameters");
|
||||
|
||||
// finally open
|
||||
@ -205,8 +178,7 @@ void CAudioStream::loadCustomContent (const char* filename)
|
||||
SDL_CreateThread (audio_read_thread, filename, this);
|
||||
}
|
||||
|
||||
void CAudioStream::initialize ()
|
||||
{
|
||||
void CAudioStream::initialize () {
|
||||
#if FF_API_FIFO_OLD_API
|
||||
// allocate the FIFO buffer
|
||||
this->m_queue->packetList = av_fifo_alloc2 (1, sizeof (MyAVPacketList), AV_FIFO_FLAG_AUTO_GROW);
|
||||
@ -217,8 +189,7 @@ void CAudioStream::initialize ()
|
||||
int64_t out_channel_layout;
|
||||
|
||||
// set output audio channels based on the input audio channels
|
||||
switch (this->m_audioContext.getChannels ())
|
||||
{
|
||||
switch (this->m_audioContext.getChannels ()) {
|
||||
case 1: out_channel_layout = AV_CH_LAYOUT_MONO; break;
|
||||
case 2: out_channel_layout = AV_CH_LAYOUT_STEREO; break;
|
||||
default: out_channel_layout = AV_CH_LAYOUT_SURROUND; break;
|
||||
@ -227,37 +198,21 @@ void CAudioStream::initialize ()
|
||||
#if FF_API_OLD_CHANNEL_LAYOUT
|
||||
av_channel_layout_from_mask (&this->m_out_channel_layout, out_channel_layout);
|
||||
|
||||
swr_alloc_set_opts2 (
|
||||
&this->m_swrctx,
|
||||
&this->m_out_channel_layout,
|
||||
this->m_audioContext.getFormat (),
|
||||
this->m_audioContext.getSampleRate (),
|
||||
&this->m_context->ch_layout,
|
||||
this->m_context->sample_fmt,
|
||||
this->m_context->sample_rate,
|
||||
0,
|
||||
nullptr
|
||||
);
|
||||
swr_alloc_set_opts2 (&this->m_swrctx, &this->m_out_channel_layout, this->m_audioContext.getFormat (),
|
||||
this->m_audioContext.getSampleRate (), &this->m_context->ch_layout,
|
||||
this->m_context->sample_fmt, this->m_context->sample_rate, 0, nullptr);
|
||||
#else
|
||||
// initialize swrctx
|
||||
this->m_swrctx = swr_alloc_set_opts (
|
||||
nullptr,
|
||||
out_channel_layout,
|
||||
this->m_audioContext.getFormat (),
|
||||
this->m_audioContext.getSampleRate (),
|
||||
this->getContext ()->channel_layout,
|
||||
this->getContext ()->sample_fmt,
|
||||
this->getContext ()->sample_rate,
|
||||
0,
|
||||
nullptr
|
||||
);
|
||||
this->m_swrctx = swr_alloc_set_opts (nullptr, out_channel_layout, this->m_audioContext.getFormat (),
|
||||
this->m_audioContext.getSampleRate (), this->getContext ()->channel_layout,
|
||||
this->getContext ()->sample_fmt, this->getContext ()->sample_rate, 0, nullptr);
|
||||
#endif
|
||||
if (this->m_swrctx == nullptr)
|
||||
sLog.exception ("Cannot initialize swrctx for audio resampling");
|
||||
|
||||
// initialize the context
|
||||
if (swr_init (this->m_swrctx) < 0)
|
||||
sLog.exception("Failed to initialize the resampling context.");
|
||||
sLog.exception ("Failed to initialize the resampling context.");
|
||||
|
||||
// setup the queue information
|
||||
this->m_queue->mutex = SDL_CreateMutex ();
|
||||
@ -267,13 +222,11 @@ void CAudioStream::initialize ()
|
||||
this->m_initialized = true;
|
||||
}
|
||||
|
||||
void CAudioStream::queuePacket(AVPacket *pkt)
|
||||
{
|
||||
void CAudioStream::queuePacket (AVPacket* pkt) {
|
||||
// clone the packet
|
||||
AVPacket* clone = av_packet_alloc ();
|
||||
|
||||
if (clone == nullptr)
|
||||
{
|
||||
if (clone == nullptr) {
|
||||
av_packet_unref (clone);
|
||||
return;
|
||||
}
|
||||
@ -281,16 +234,15 @@ void CAudioStream::queuePacket(AVPacket *pkt)
|
||||
av_packet_move_ref (clone, pkt);
|
||||
|
||||
SDL_LockMutex (this->m_queue->mutex);
|
||||
bool gotQueued = this->doQueue (clone);
|
||||
const bool gotQueued = this->doQueue (clone);
|
||||
SDL_UnlockMutex (this->m_queue->mutex);
|
||||
|
||||
if (!gotQueued)
|
||||
av_packet_free (&pkt);
|
||||
}
|
||||
|
||||
bool CAudioStream::doQueue (AVPacket* pkt)
|
||||
{
|
||||
MyAVPacketList entry { pkt };
|
||||
bool CAudioStream::doQueue (AVPacket* pkt) {
|
||||
MyAVPacketList entry {pkt};
|
||||
|
||||
#if FF_API_FIFO_OLD_API
|
||||
// write the entry if possible
|
||||
@ -304,7 +256,7 @@ bool CAudioStream::doQueue (AVPacket* pkt)
|
||||
av_fifo_generic_write (this->m_queue->packetList, &entry, sizeof (entry), nullptr);
|
||||
#endif
|
||||
|
||||
this->m_queue->nb_packets ++;
|
||||
this->m_queue->nb_packets++;
|
||||
this->m_queue->size += entry.packet->size + sizeof (entry);
|
||||
this->m_queue->duration += entry.packet->duration;
|
||||
|
||||
@ -313,14 +265,12 @@ bool CAudioStream::doQueue (AVPacket* pkt)
|
||||
return true;
|
||||
}
|
||||
|
||||
void CAudioStream::dequeuePacket (AVPacket* output)
|
||||
{
|
||||
void CAudioStream::dequeuePacket (AVPacket* output) {
|
||||
MyAVPacketList entry;
|
||||
|
||||
SDL_LockMutex (this->m_queue->mutex);
|
||||
|
||||
while (this->m_audioContext.getApplicationContext ().state.general.keepRunning)
|
||||
{
|
||||
while (this->m_audioContext.getApplicationContext ().state.general.keepRunning) {
|
||||
|
||||
#if FF_API_FIFO_OLD_API
|
||||
int ret = av_fifo_read (this->m_queue->packetList, &entry, 1);
|
||||
@ -332,9 +282,8 @@ void CAudioStream::dequeuePacket (AVPacket* output)
|
||||
#endif
|
||||
|
||||
// enough data available, read it
|
||||
if (ret >= 0)
|
||||
{
|
||||
this->m_queue->nb_packets --;
|
||||
if (ret >= 0) {
|
||||
this->m_queue->nb_packets--;
|
||||
this->m_queue->size -= entry.packet->size + sizeof (entry);
|
||||
this->m_queue->duration -= entry.packet->duration;
|
||||
|
||||
@ -351,93 +300,75 @@ void CAudioStream::dequeuePacket (AVPacket* output)
|
||||
SDL_UnlockMutex (this->m_queue->mutex);
|
||||
}
|
||||
|
||||
AVCodecContext* CAudioStream::getContext ()
|
||||
{
|
||||
AVCodecContext* CAudioStream::getContext () {
|
||||
return this->m_context;
|
||||
}
|
||||
|
||||
AVFormatContext* CAudioStream::getFormatContext ()
|
||||
{
|
||||
AVFormatContext* CAudioStream::getFormatContext () {
|
||||
return this->m_formatContext;
|
||||
}
|
||||
|
||||
int CAudioStream::getAudioStream ()
|
||||
{
|
||||
int CAudioStream::getAudioStream () {
|
||||
return this->m_audioStream;
|
||||
}
|
||||
|
||||
bool CAudioStream::isInitialized ()
|
||||
{
|
||||
bool CAudioStream::isInitialized () {
|
||||
return this->m_initialized;
|
||||
}
|
||||
|
||||
void CAudioStream::setRepeat (bool newRepeat)
|
||||
{
|
||||
void CAudioStream::setRepeat (bool newRepeat) {
|
||||
this->m_repeat = newRepeat;
|
||||
}
|
||||
|
||||
bool CAudioStream::isRepeat ()
|
||||
{
|
||||
bool CAudioStream::isRepeat () {
|
||||
return this->m_repeat;
|
||||
}
|
||||
|
||||
const void* CAudioStream::getBuffer ()
|
||||
{
|
||||
const void* CAudioStream::getBuffer () {
|
||||
return this->m_buffer;
|
||||
}
|
||||
|
||||
int CAudioStream::getLength ()
|
||||
{
|
||||
int CAudioStream::getLength () {
|
||||
return this->m_length;
|
||||
}
|
||||
|
||||
int CAudioStream::getPosition ()
|
||||
{
|
||||
int CAudioStream::getPosition () {
|
||||
return this->m_position;
|
||||
}
|
||||
|
||||
void CAudioStream::setPosition (int current)
|
||||
{
|
||||
void CAudioStream::setPosition (int current) {
|
||||
this->m_position = current;
|
||||
}
|
||||
|
||||
SDL_cond* CAudioStream::getWaitCondition ()
|
||||
{
|
||||
SDL_cond* CAudioStream::getWaitCondition () {
|
||||
return this->m_queue->wait;
|
||||
}
|
||||
|
||||
int CAudioStream::getQueueSize ()
|
||||
{
|
||||
int CAudioStream::getQueueSize () {
|
||||
return this->m_queue->size;
|
||||
}
|
||||
|
||||
int CAudioStream::getQueuePacketCount ()
|
||||
{
|
||||
int CAudioStream::getQueuePacketCount () {
|
||||
return this->m_queue->nb_packets;
|
||||
}
|
||||
|
||||
AVRational CAudioStream::getTimeBase ()
|
||||
{
|
||||
AVRational CAudioStream::getTimeBase () {
|
||||
return this->m_formatContext->streams [this->m_audioStream]->time_base;
|
||||
}
|
||||
|
||||
int64_t CAudioStream::getQueueDuration ()
|
||||
{
|
||||
int64_t CAudioStream::getQueueDuration () {
|
||||
return this->m_queue->duration;
|
||||
}
|
||||
|
||||
bool CAudioStream::isQueueEmpty ()
|
||||
{
|
||||
bool CAudioStream::isQueueEmpty () {
|
||||
return this->m_queue->nb_packets == 0;
|
||||
}
|
||||
|
||||
SDL_mutex* CAudioStream::getMutex ()
|
||||
{
|
||||
SDL_mutex* CAudioStream::getMutex () {
|
||||
return this->m_queue->mutex;
|
||||
}
|
||||
|
||||
void CAudioStream::stop ()
|
||||
{
|
||||
void CAudioStream::stop () {
|
||||
if (!this->isInitialized ())
|
||||
return;
|
||||
|
||||
@ -445,36 +376,27 @@ void CAudioStream::stop ()
|
||||
this->m_initialized = false;
|
||||
}
|
||||
|
||||
int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_buf)
|
||||
{
|
||||
int CAudioStream::resampleAudio (const AVFrame* decoded_audio_frame, uint8_t* out_buf) {
|
||||
int out_linesize = 0;
|
||||
int ret;
|
||||
int out_nb_channels;
|
||||
int in_nb_samples;
|
||||
int out_nb_samples;
|
||||
int max_out_nb_samples;
|
||||
uint8_t** resampled_data = nullptr;
|
||||
int resampled_data_size;
|
||||
|
||||
// retrieve number of audio samples (per channel)
|
||||
in_nb_samples = decoded_audio_frame->nb_samples;
|
||||
if (in_nb_samples <= 0)
|
||||
{
|
||||
sLog.error("in_nb_samples error.");
|
||||
const int in_nb_samples = decoded_audio_frame->nb_samples;
|
||||
if (in_nb_samples <= 0) {
|
||||
sLog.error ("in_nb_samples error.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
max_out_nb_samples = out_nb_samples = av_rescale_rnd(
|
||||
in_nb_samples,
|
||||
this->m_audioContext.getSampleRate (),
|
||||
this->getContext ()->sample_rate,
|
||||
AV_ROUND_UP
|
||||
);
|
||||
int max_out_nb_samples = out_nb_samples = av_rescale_rnd (in_nb_samples, this->m_audioContext.getSampleRate (),
|
||||
this->getContext ()->sample_rate, AV_ROUND_UP);
|
||||
|
||||
// check rescaling was successful
|
||||
if (max_out_nb_samples <= 0)
|
||||
{
|
||||
sLog.error("av_rescale_rnd error.");
|
||||
if (max_out_nb_samples <= 0) {
|
||||
sLog.error ("av_rescale_rnd error.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -485,64 +407,44 @@ int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_bu
|
||||
int64_t out_channel_layout;
|
||||
|
||||
// set output audio channels based on the input audio channels
|
||||
switch (this->m_audioContext.getChannels ())
|
||||
{
|
||||
switch (this->m_audioContext.getChannels ()) {
|
||||
case 1: out_channel_layout = AV_CH_LAYOUT_MONO; break;
|
||||
case 2: out_channel_layout = AV_CH_LAYOUT_STEREO; break;
|
||||
default: out_channel_layout = AV_CH_LAYOUT_SURROUND; break;
|
||||
}
|
||||
|
||||
out_nb_channels = av_get_channel_layout_nb_channels(out_channel_layout);
|
||||
out_nb_channels = av_get_channel_layout_nb_channels (out_channel_layout);
|
||||
#endif
|
||||
ret = av_samples_alloc_array_and_samples(
|
||||
&resampled_data,
|
||||
&out_linesize,
|
||||
out_nb_channels,
|
||||
out_nb_samples,
|
||||
this->m_audioContext.getFormat (),
|
||||
0
|
||||
);
|
||||
ret = av_samples_alloc_array_and_samples (&resampled_data, &out_linesize, out_nb_channels, out_nb_samples,
|
||||
this->m_audioContext.getFormat (), 0);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
sLog.error("av_samples_alloc_array_and_samples() error: Could not allocate destination samples.");
|
||||
if (ret < 0) {
|
||||
sLog.error ("av_samples_alloc_array_and_samples() error: Could not allocate destination samples.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// retrieve output samples number taking into account the progressive delay
|
||||
out_nb_samples = av_rescale_rnd(
|
||||
swr_get_delay(this->m_swrctx, this->getContext ()->sample_rate) + in_nb_samples,
|
||||
this->m_audioContext.getSampleRate (),
|
||||
this->getContext ()->sample_rate,
|
||||
AV_ROUND_UP
|
||||
);
|
||||
out_nb_samples =
|
||||
av_rescale_rnd (swr_get_delay (this->m_swrctx, this->getContext ()->sample_rate) + in_nb_samples,
|
||||
this->m_audioContext.getSampleRate (), this->getContext ()->sample_rate, AV_ROUND_UP);
|
||||
|
||||
// check output samples number was correctly retrieved
|
||||
if (out_nb_samples <= 0)
|
||||
{
|
||||
sLog.error("av_rescale_rnd error");
|
||||
if (out_nb_samples <= 0) {
|
||||
sLog.error ("av_rescale_rnd error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (out_nb_samples > max_out_nb_samples)
|
||||
{
|
||||
if (out_nb_samples > max_out_nb_samples) {
|
||||
// free memory block and set pointer to NULL
|
||||
av_free(resampled_data[0]);
|
||||
av_free (resampled_data [0]);
|
||||
|
||||
// Allocate a samples buffer for out_nb_samples samples
|
||||
ret = av_samples_alloc(
|
||||
resampled_data,
|
||||
&out_linesize,
|
||||
out_nb_channels,
|
||||
out_nb_samples,
|
||||
this->m_audioContext.getFormat (),
|
||||
1
|
||||
);
|
||||
ret = av_samples_alloc (resampled_data, &out_linesize, out_nb_channels, out_nb_samples,
|
||||
this->m_audioContext.getFormat (), 1);
|
||||
|
||||
// check samples buffer correctly allocated
|
||||
if (ret < 0)
|
||||
{
|
||||
sLog.error("av_samples_alloc failed.");
|
||||
if (ret < 0) {
|
||||
sLog.error ("av_samples_alloc failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -550,69 +452,54 @@ int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_bu
|
||||
}
|
||||
|
||||
// do the actual audio data resampling
|
||||
ret = swr_convert(
|
||||
this->m_swrctx,
|
||||
resampled_data,
|
||||
max_out_nb_samples,
|
||||
(const uint8_t **) decoded_audio_frame->data,
|
||||
decoded_audio_frame->nb_samples
|
||||
);
|
||||
ret = swr_convert (this->m_swrctx, resampled_data, max_out_nb_samples,
|
||||
const_cast<const uint8_t**> (decoded_audio_frame->data), decoded_audio_frame->nb_samples);
|
||||
|
||||
// check audio conversion was successful
|
||||
if (ret < 0)
|
||||
{
|
||||
sLog.error("swr_convert_error.");
|
||||
if (ret < 0) {
|
||||
sLog.error ("swr_convert_error.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get the required buffer size for the given audio parameters
|
||||
resampled_data_size = av_samples_get_buffer_size(
|
||||
&out_linesize,
|
||||
out_nb_channels,
|
||||
ret,
|
||||
this->m_audioContext.getFormat (),
|
||||
1
|
||||
);
|
||||
resampled_data_size =
|
||||
av_samples_get_buffer_size (&out_linesize, out_nb_channels, ret, this->m_audioContext.getFormat (), 1);
|
||||
|
||||
// check audio buffer size
|
||||
if (resampled_data_size < 0)
|
||||
{
|
||||
if (resampled_data_size < 0) {
|
||||
sLog.error ("av_samples_get_buffer_size error.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// copy the resampled data to the output buffer
|
||||
memcpy(out_buf, resampled_data[0], resampled_data_size);
|
||||
memcpy (out_buf, resampled_data [0], resampled_data_size);
|
||||
|
||||
/*
|
||||
* Memory Cleanup.
|
||||
*/
|
||||
if (resampled_data)
|
||||
{
|
||||
if (resampled_data) {
|
||||
// free memory block and set pointer to NULL
|
||||
av_freep(&resampled_data[0]);
|
||||
av_freep (&resampled_data [0]);
|
||||
}
|
||||
|
||||
av_freep(&resampled_data);
|
||||
resampled_data = NULL;
|
||||
av_freep (&resampled_data);
|
||||
resampled_data = nullptr;
|
||||
|
||||
return resampled_data_size;
|
||||
}
|
||||
|
||||
int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize)
|
||||
{
|
||||
AVPacket *pkt = av_packet_alloc ();
|
||||
static uint8_t *audio_pkt_data = NULL;
|
||||
int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize) {
|
||||
AVPacket* pkt = av_packet_alloc ();
|
||||
static uint8_t* audio_pkt_data = nullptr;
|
||||
static int audio_pkt_size = 0;
|
||||
|
||||
int len1, data_size;
|
||||
|
||||
// allocate a new frame, used to decode audio packets
|
||||
static AVFrame * avFrame = NULL;
|
||||
avFrame = av_frame_alloc();
|
||||
if (!avFrame)
|
||||
{
|
||||
sLog.error("Could not allocate AVFrame.\n");
|
||||
static AVFrame* avFrame = nullptr;
|
||||
avFrame = av_frame_alloc ();
|
||||
if (!avFrame) {
|
||||
sLog.error ("Could not allocate AVFrame.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -620,21 +507,20 @@ int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize)
|
||||
while (this->m_audioContext.getApplicationContext ().state.general.keepRunning) {
|
||||
while (audio_pkt_size > 0) {
|
||||
int got_frame = 0;
|
||||
int ret = avcodec_receive_frame(this->getContext (), avFrame);
|
||||
int ret = avcodec_receive_frame (this->getContext (), avFrame);
|
||||
|
||||
if (ret == 0)
|
||||
got_frame = 1;
|
||||
if (ret == AVERROR(EAGAIN))
|
||||
if (ret == AVERROR (EAGAIN))
|
||||
ret = 0;
|
||||
if (ret == 0)
|
||||
ret = avcodec_send_packet(this->getContext (), pkt);
|
||||
ret = avcodec_send_packet (this->getContext (), pkt);
|
||||
if (ret < 0 && ret != AVERROR (EAGAIN))
|
||||
return -1;
|
||||
|
||||
len1 = pkt->size;
|
||||
|
||||
if (len1 < 0)
|
||||
{
|
||||
if (len1 < 0) {
|
||||
// if error, skip frame
|
||||
audio_pkt_size = 0;
|
||||
break;
|
||||
@ -647,7 +533,7 @@ int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize)
|
||||
if (got_frame) {
|
||||
// audio resampling
|
||||
data_size = this->resampleAudio (avFrame, audioBuffer);
|
||||
assert(data_size <= bufferSize);
|
||||
assert (data_size <= bufferSize);
|
||||
}
|
||||
if (data_size <= 0) {
|
||||
// no data found, keep waiting
|
||||
@ -657,7 +543,7 @@ int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize)
|
||||
return data_size;
|
||||
}
|
||||
if (pkt->data)
|
||||
av_packet_unref(pkt);
|
||||
av_packet_unref (pkt);
|
||||
|
||||
this->dequeuePacket (pkt);
|
||||
|
||||
@ -668,7 +554,6 @@ int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize)
|
||||
return 0;
|
||||
}
|
||||
|
||||
CAudioContext& CAudioStream::getAudioContext () const
|
||||
{
|
||||
CAudioContext& CAudioStream::getAudioContext () const {
|
||||
return this->m_audioContext;
|
||||
}
|
@ -2,14 +2,13 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <libavutil/fifo.h>
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libswresample/swresample.h>
|
||||
#include <libavutil/fifo.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libswresample/swresample.h>
|
||||
#include <libswscale/swscale.h>
|
||||
}
|
||||
|
||||
#include <SDL.h>
|
||||
@ -17,15 +16,13 @@ extern "C"
|
||||
|
||||
#include "WallpaperEngine/Audio/CAudioContext.h"
|
||||
|
||||
namespace WallpaperEngine::Audio
|
||||
{
|
||||
class CAudioContext;
|
||||
namespace WallpaperEngine::Audio {
|
||||
class CAudioContext;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Represents a playable audio stream for the audio driver
|
||||
*/
|
||||
class CAudioStream
|
||||
{
|
||||
class CAudioStream {
|
||||
public:
|
||||
CAudioStream (CAudioContext& context, const std::string& filename);
|
||||
CAudioStream (CAudioContext& context, const void* buffer, int length);
|
||||
@ -148,7 +145,7 @@ namespace WallpaperEngine::Audio
|
||||
* @param out_buf
|
||||
* @return
|
||||
*/
|
||||
int resampleAudio (AVFrame* decoded_audio_frame, uint8_t* out_buf);
|
||||
int resampleAudio (const AVFrame* decoded_audio_frame, uint8_t* out_buf);
|
||||
/**
|
||||
* Queues a packet into the play queue
|
||||
*
|
||||
@ -163,16 +160,16 @@ namespace WallpaperEngine::Audio
|
||||
|
||||
#if FF_API_OLD_CHANNEL_LAYOUT
|
||||
/** Chanel layout needed for old FFMPEG versions */
|
||||
AVChannelLayout m_out_channel_layout;
|
||||
AVChannelLayout m_out_channel_layout {};
|
||||
#endif
|
||||
/** The SwrContext that handles resampling */
|
||||
SwrContext* m_swrctx;
|
||||
/** The audio context this stream will be played under */
|
||||
CAudioContext& m_audioContext;
|
||||
/** If this stream was properly initialized or not */
|
||||
bool m_initialized;
|
||||
bool m_initialized {};
|
||||
/** Repeat enabled? */
|
||||
bool m_repeat;
|
||||
bool m_repeat {};
|
||||
/** The codec context that contains the original audio format information */
|
||||
AVCodecContext* m_context = nullptr;
|
||||
/** The format context that controls how data is read off the file */
|
||||
@ -180,22 +177,20 @@ namespace WallpaperEngine::Audio
|
||||
/** The stream index for the audio being played */
|
||||
int m_audioStream = -1;
|
||||
/** File data pointer */
|
||||
const void* m_buffer;
|
||||
const void* m_buffer {};
|
||||
/** The length of the file data pointer */
|
||||
int m_length;
|
||||
int m_length {};
|
||||
/** The read position on the file data pointer */
|
||||
int m_position = 0;
|
||||
|
||||
struct MyAVPacketList
|
||||
{
|
||||
struct MyAVPacketList {
|
||||
AVPacket* packet;
|
||||
};
|
||||
|
||||
/**
|
||||
* Packet queue information
|
||||
*/
|
||||
struct PacketQueue
|
||||
{
|
||||
struct PacketQueue {
|
||||
#if FF_API_FIFO_OLD_API
|
||||
AVFifo* packetList;
|
||||
#else
|
||||
@ -207,6 +202,6 @@ namespace WallpaperEngine::Audio
|
||||
SDL_mutex* mutex;
|
||||
SDL_cond* wait;
|
||||
SDL_cond* cond;
|
||||
}* m_queue;
|
||||
};
|
||||
}
|
||||
}* m_queue {};
|
||||
};
|
||||
} // namespace WallpaperEngine::Audio
|
||||
|
@ -1,31 +1,26 @@
|
||||
#include "CAudioDriver.h"
|
||||
|
||||
namespace WallpaperEngine::Audio::Drivers
|
||||
{
|
||||
CAudioDriver::CAudioDriver (Application::CApplicationContext& applicationContext, Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder) :
|
||||
namespace WallpaperEngine::Audio::Drivers {
|
||||
CAudioDriver::CAudioDriver (Application::CApplicationContext& applicationContext,
|
||||
Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder) :
|
||||
m_applicationContext (applicationContext),
|
||||
m_detector (detector),
|
||||
m_recorder (recorder)
|
||||
{
|
||||
}
|
||||
m_recorder (recorder) {}
|
||||
|
||||
void CAudioDriver::update ()
|
||||
{
|
||||
void CAudioDriver::update () {
|
||||
this->m_recorder.update ();
|
||||
this->m_detector.update ();
|
||||
}
|
||||
|
||||
Application::CApplicationContext& CAudioDriver::getApplicationContext ()
|
||||
{
|
||||
return this->m_applicationContext;
|
||||
}
|
||||
Detectors::CAudioPlayingDetector& CAudioDriver::getAudioDetector ()
|
||||
{
|
||||
return this->m_detector;
|
||||
}
|
||||
|
||||
Recorders::CPlaybackRecorder& CAudioDriver::getRecorder ()
|
||||
{
|
||||
return this->m_recorder;
|
||||
}
|
||||
}
|
||||
|
||||
Application::CApplicationContext& CAudioDriver::getApplicationContext () {
|
||||
return this->m_applicationContext;
|
||||
}
|
||||
|
||||
Detectors::CAudioPlayingDetector& CAudioDriver::getAudioDetector () {
|
||||
return this->m_detector;
|
||||
}
|
||||
|
||||
Recorders::CPlaybackRecorder& CAudioDriver::getRecorder () {
|
||||
return this->m_recorder;
|
||||
}
|
||||
} // namespace WallpaperEngine::Audio::Drivers
|
||||
|
@ -2,42 +2,37 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "WallpaperEngine/Audio/Drivers/Detectors/CAudioPlayingDetector.h"
|
||||
#include "WallpaperEngine/Audio/Drivers/Recorders/CPlaybackRecorder.h"
|
||||
#include "WallpaperEngine/Application/CApplicationContext.h"
|
||||
#include "WallpaperEngine/Audio/CAudioStream.h"
|
||||
#include "WallpaperEngine/Audio/Drivers/Detectors/CAudioPlayingDetector.h"
|
||||
#include "WallpaperEngine/Audio/Drivers/Recorders/CPlaybackRecorder.h"
|
||||
|
||||
namespace WallpaperEngine
|
||||
{
|
||||
namespace Application
|
||||
{
|
||||
class CApplicationContext;
|
||||
}
|
||||
namespace WallpaperEngine {
|
||||
namespace Application {
|
||||
class CApplicationContext;
|
||||
}
|
||||
|
||||
namespace Audio
|
||||
{
|
||||
class CAudioStream;
|
||||
namespace Audio {
|
||||
class CAudioStream;
|
||||
|
||||
namespace Drivers
|
||||
{
|
||||
namespace Detectors
|
||||
{
|
||||
class CAudioPlayingDetector;
|
||||
}
|
||||
namespace Drivers {
|
||||
namespace Detectors {
|
||||
class CAudioPlayingDetector;
|
||||
}
|
||||
|
||||
namespace Recorders
|
||||
{
|
||||
class CPulseAudioPlaybackRecorder;
|
||||
}
|
||||
namespace Recorders {
|
||||
class CPulseAudioPlaybackRecorder;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Base class for audio driver implementations
|
||||
*/
|
||||
class CAudioDriver
|
||||
{
|
||||
class CAudioDriver {
|
||||
public:
|
||||
explicit CAudioDriver (Application::CApplicationContext& applicationContext, Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder);
|
||||
explicit CAudioDriver (Application::CApplicationContext& applicationContext,
|
||||
Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder);
|
||||
|
||||
virtual ~CAudioDriver () = default;
|
||||
/**
|
||||
* Registers the given stream in the driver for playing
|
||||
*
|
||||
@ -81,7 +76,7 @@ namespace WallpaperEngine
|
||||
Application::CApplicationContext& m_applicationContext;
|
||||
Detectors::CAudioPlayingDetector& m_detector;
|
||||
Recorders::CPlaybackRecorder& m_recorder;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Drivers
|
||||
} // namespace Audio
|
||||
} // namespace WallpaperEngine
|
@ -1,5 +1,5 @@
|
||||
#include "common.h"
|
||||
#include "CSDLAudioDriver.h"
|
||||
#include "common.h"
|
||||
|
||||
#define SDL_AUDIO_BUFFER_SIZE 4096
|
||||
#define MAX_AUDIO_FRAME_SIZE 192000
|
||||
@ -7,9 +7,8 @@
|
||||
using namespace WallpaperEngine::Audio;
|
||||
using namespace WallpaperEngine::Audio::Drivers;
|
||||
|
||||
void audio_callback (void* userdata, uint8_t* streamData, int length)
|
||||
{
|
||||
auto* driver = reinterpret_cast <CSDLAudioDriver*> (userdata);
|
||||
void audio_callback (void* userdata, uint8_t* streamData, int length) {
|
||||
auto* driver = static_cast<CSDLAudioDriver*> (userdata);
|
||||
|
||||
memset (streamData, 0, length);
|
||||
|
||||
@ -17,11 +16,9 @@ void audio_callback (void* userdata, uint8_t* streamData, int length)
|
||||
if (driver->getAudioDetector ().anythingPlaying ())
|
||||
return;
|
||||
|
||||
for (const auto& buffer : driver->getStreams ())
|
||||
{
|
||||
for (const auto& buffer : driver->getStreams ()) {
|
||||
uint8_t* streamDataPointer = streamData;
|
||||
int streamLength = length;
|
||||
int len1, audio_size;
|
||||
|
||||
// sound is not initialized or stopped and is not in loop mode
|
||||
// ignore mixing it in
|
||||
@ -29,43 +26,35 @@ void audio_callback (void* userdata, uint8_t* streamData, int length)
|
||||
continue;
|
||||
|
||||
// check if queue is empty and signal the read thread
|
||||
if (buffer->stream->isQueueEmpty ())
|
||||
{
|
||||
if (buffer->stream->isQueueEmpty ()) {
|
||||
SDL_CondSignal (buffer->stream->getWaitCondition ());
|
||||
continue;
|
||||
}
|
||||
|
||||
while (streamLength > 0 && driver->getApplicationContext ().state.general.keepRunning)
|
||||
{
|
||||
if (buffer->audio_buf_index >= buffer->audio_buf_size)
|
||||
{
|
||||
while (streamLength > 0 && driver->getApplicationContext ().state.general.keepRunning) {
|
||||
if (buffer->audio_buf_index >= buffer->audio_buf_size) {
|
||||
// get more data to fill the buffer
|
||||
audio_size = buffer->stream->decodeFrame (buffer->audio_buf, sizeof (buffer->audio_buf));
|
||||
int audio_size = buffer->stream->decodeFrame (buffer->audio_buf, sizeof (buffer->audio_buf));
|
||||
|
||||
if (audio_size < 0)
|
||||
{
|
||||
if (audio_size < 0) {
|
||||
// fallback for errors, silence
|
||||
buffer->audio_buf_size = 1024;
|
||||
memset(buffer->audio_buf, 0, buffer->audio_buf_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset (buffer->audio_buf, 0, buffer->audio_buf_size);
|
||||
} else {
|
||||
buffer->audio_buf_size = audio_size;
|
||||
}
|
||||
|
||||
buffer->audio_buf_index = 0;
|
||||
}
|
||||
|
||||
len1 = buffer->audio_buf_size - buffer->audio_buf_index;
|
||||
int len1 = buffer->audio_buf_size - buffer->audio_buf_index;
|
||||
|
||||
if (len1 > streamLength)
|
||||
len1 = streamLength;
|
||||
|
||||
// mix the audio
|
||||
SDL_MixAudioFormat (
|
||||
streamDataPointer, &buffer->audio_buf [buffer->audio_buf_index],
|
||||
driver->getSpec ().format, len1, driver->getApplicationContext ().state.audio.volume
|
||||
);
|
||||
SDL_MixAudioFormat (streamDataPointer, &buffer->audio_buf [buffer->audio_buf_index],
|
||||
driver->getSpec ().format, len1, driver->getApplicationContext ().state.audio.volume);
|
||||
|
||||
streamLength -= len1;
|
||||
streamDataPointer += len1;
|
||||
@ -74,34 +63,29 @@ void audio_callback (void* userdata, uint8_t* streamData, int length)
|
||||
}
|
||||
}
|
||||
|
||||
CSDLAudioDriver::CSDLAudioDriver (Application::CApplicationContext& applicationContext, Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder) :
|
||||
CSDLAudioDriver::CSDLAudioDriver (Application::CApplicationContext& applicationContext,
|
||||
Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder) :
|
||||
CAudioDriver (applicationContext, detector, recorder),
|
||||
m_initialized (false),
|
||||
m_audioSpec ()
|
||||
{
|
||||
if (SDL_InitSubSystem (SDL_INIT_AUDIO) < 0)
|
||||
{
|
||||
m_audioSpec () {
|
||||
if (SDL_InitSubSystem (SDL_INIT_AUDIO) < 0) {
|
||||
sLog.error ("Cannot initialize SDL audio system, SDL_GetError: ", SDL_GetError ());
|
||||
sLog.error ("Continuing without audio support");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_AudioSpec requestedSpec;
|
||||
const SDL_AudioSpec requestedSpec = {.freq = 48000,
|
||||
.format = AUDIO_F32,
|
||||
.channels = 2,
|
||||
.samples = SDL_AUDIO_BUFFER_SIZE,
|
||||
.callback = audio_callback,
|
||||
.userdata = this};
|
||||
|
||||
memset (&requestedSpec, 0, sizeof (requestedSpec));
|
||||
this->m_deviceID =
|
||||
SDL_OpenAudioDevice (nullptr, false, &requestedSpec, &this->m_audioSpec, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||
|
||||
requestedSpec.freq = 48000;
|
||||
requestedSpec.format = AUDIO_F32;
|
||||
requestedSpec.channels = 2;
|
||||
requestedSpec.samples = SDL_AUDIO_BUFFER_SIZE;
|
||||
requestedSpec.callback = audio_callback;
|
||||
requestedSpec.userdata = this;
|
||||
|
||||
this->m_deviceID = SDL_OpenAudioDevice (nullptr, false, &requestedSpec, &this->m_audioSpec, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||
|
||||
if (this->m_deviceID == 0)
|
||||
{
|
||||
if (this->m_deviceID == 0) {
|
||||
sLog.error ("SDL_OpenAudioDevice: ", SDL_GetError ());
|
||||
return;
|
||||
}
|
||||
@ -111,8 +95,7 @@ CSDLAudioDriver::CSDLAudioDriver (Application::CApplicationContext& applicationC
|
||||
this->m_initialized = true;
|
||||
}
|
||||
|
||||
CSDLAudioDriver::~CSDLAudioDriver ()
|
||||
{
|
||||
CSDLAudioDriver::~CSDLAudioDriver () {
|
||||
if (!this->m_initialized)
|
||||
return;
|
||||
|
||||
@ -120,39 +103,39 @@ CSDLAudioDriver::~CSDLAudioDriver ()
|
||||
SDL_QuitSubSystem (SDL_INIT_AUDIO);
|
||||
}
|
||||
|
||||
void CSDLAudioDriver::addStream (CAudioStream* stream)
|
||||
{
|
||||
this->m_streams.push_back (new CSDLAudioBuffer { stream });
|
||||
void CSDLAudioDriver::addStream (CAudioStream* stream) {
|
||||
this->m_streams.push_back (new CSDLAudioBuffer {stream});
|
||||
}
|
||||
|
||||
const std::vector <CSDLAudioBuffer*>& CSDLAudioDriver::getStreams ()
|
||||
{
|
||||
const std::vector<CSDLAudioBuffer*>& CSDLAudioDriver::getStreams () {
|
||||
return this->m_streams;
|
||||
}
|
||||
|
||||
AVSampleFormat CSDLAudioDriver::getFormat () const
|
||||
{
|
||||
switch (this->m_audioSpec.format)
|
||||
{
|
||||
case AUDIO_U8: case AUDIO_S8: return AV_SAMPLE_FMT_U8;
|
||||
case AUDIO_U16MSB: case AUDIO_U16LSB: case AUDIO_S16LSB: case AUDIO_S16MSB: return AV_SAMPLE_FMT_S16;
|
||||
case AUDIO_S32LSB: case AUDIO_S32MSB: return AV_SAMPLE_FMT_S32;
|
||||
case AUDIO_F32LSB: case AUDIO_F32MSB: return AV_SAMPLE_FMT_FLT;
|
||||
AVSampleFormat CSDLAudioDriver::getFormat () const {
|
||||
switch (this->m_audioSpec.format) {
|
||||
case AUDIO_U8:
|
||||
case AUDIO_S8: return AV_SAMPLE_FMT_U8;
|
||||
case AUDIO_U16MSB:
|
||||
case AUDIO_U16LSB:
|
||||
case AUDIO_S16LSB:
|
||||
case AUDIO_S16MSB: return AV_SAMPLE_FMT_S16;
|
||||
case AUDIO_S32LSB:
|
||||
case AUDIO_S32MSB: return AV_SAMPLE_FMT_S32;
|
||||
case AUDIO_F32LSB:
|
||||
case AUDIO_F32MSB: return AV_SAMPLE_FMT_FLT;
|
||||
}
|
||||
|
||||
sLog.exception ("Cannot convert from SDL format to ffmpeg format, aborting...");
|
||||
}
|
||||
|
||||
int CSDLAudioDriver::getSampleRate () const
|
||||
{
|
||||
int CSDLAudioDriver::getSampleRate () const {
|
||||
return this->m_audioSpec.freq;
|
||||
}
|
||||
|
||||
int CSDLAudioDriver::getChannels () const
|
||||
{
|
||||
int CSDLAudioDriver::getChannels () const {
|
||||
return this->m_audioSpec.channels;
|
||||
}
|
||||
const SDL_AudioSpec& CSDLAudioDriver::getSpec () const
|
||||
{
|
||||
|
||||
const SDL_AudioSpec& CSDLAudioDriver::getSpec () const {
|
||||
return this->m_audioSpec;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "WallpaperEngine/Audio/CAudioStream.h"
|
||||
#include "WallpaperEngine/Audio/Drivers/CAudioDriver.h"
|
||||
@ -10,34 +10,32 @@
|
||||
|
||||
#define MAX_AUDIO_FRAME_SIZE 192000
|
||||
|
||||
namespace WallpaperEngine::Audio::Drivers
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Audio::Drivers {
|
||||
/**
|
||||
* Audio output buffers for streams being played under SDL
|
||||
*/
|
||||
struct CSDLAudioBuffer
|
||||
{
|
||||
struct CSDLAudioBuffer {
|
||||
CAudioStream* stream;
|
||||
uint8_t audio_buf[(MAX_AUDIO_FRAME_SIZE * 3) / 2] = {0};
|
||||
uint8_t audio_buf [(MAX_AUDIO_FRAME_SIZE * 3) / 2] = {0};
|
||||
unsigned int audio_buf_size = 0;
|
||||
unsigned int audio_buf_index = 0;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* SDL's audio driver implementation
|
||||
*/
|
||||
class CSDLAudioDriver : public CAudioDriver
|
||||
{
|
||||
class CSDLAudioDriver final : public CAudioDriver {
|
||||
public:
|
||||
CSDLAudioDriver (Application::CApplicationContext& applicationContext, Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder);
|
||||
~CSDLAudioDriver ();
|
||||
CSDLAudioDriver (Application::CApplicationContext& applicationContext, Detectors::CAudioPlayingDetector& detector,
|
||||
Recorders::CPlaybackRecorder& recorder);
|
||||
~CSDLAudioDriver () override;
|
||||
|
||||
/** @inheritdoc */
|
||||
void addStream (CAudioStream* stream) override;
|
||||
/**
|
||||
* @return All the registered audio streams
|
||||
*/
|
||||
const std::vector <CSDLAudioBuffer*>& getStreams ();
|
||||
const std::vector<CSDLAudioBuffer*>& getStreams ();
|
||||
|
||||
/** @inheritdoc */
|
||||
[[nodiscard]] AVSampleFormat getFormat () const override;
|
||||
@ -58,6 +56,6 @@ namespace WallpaperEngine::Audio::Drivers
|
||||
/** The sound output configuration */
|
||||
SDL_AudioSpec m_audioSpec;
|
||||
/** All the playable steams */
|
||||
std::vector <CSDLAudioBuffer*> m_streams;
|
||||
};
|
||||
}
|
||||
std::vector<CSDLAudioBuffer*> m_streams;
|
||||
};
|
||||
} // namespace WallpaperEngine::Audio::Drivers
|
@ -1,33 +1,26 @@
|
||||
#include "CAudioPlayingDetector.h"
|
||||
|
||||
namespace WallpaperEngine::Audio::Drivers::Detectors
|
||||
{
|
||||
CAudioPlayingDetector::CAudioPlayingDetector (
|
||||
namespace WallpaperEngine::Audio::Drivers::Detectors {
|
||||
CAudioPlayingDetector::CAudioPlayingDetector (
|
||||
Application::CApplicationContext& appContext,
|
||||
const Render::Drivers::Detectors::CFullScreenDetector& fullscreenDetector) :
|
||||
m_applicationContext (appContext),
|
||||
m_fullscreenDetector (fullscreenDetector),
|
||||
m_isPlaying (false)
|
||||
{
|
||||
}
|
||||
m_isPlaying (false) {}
|
||||
|
||||
bool CAudioPlayingDetector::anythingPlaying () const
|
||||
{
|
||||
bool CAudioPlayingDetector::anythingPlaying () const {
|
||||
return this->m_isPlaying;
|
||||
}
|
||||
|
||||
Application::CApplicationContext& CAudioPlayingDetector::getApplicationContext ()
|
||||
{
|
||||
return this->m_applicationContext;
|
||||
}
|
||||
|
||||
const Render::Drivers::Detectors::CFullScreenDetector& CAudioPlayingDetector::getFullscreenDetector () const
|
||||
{
|
||||
return this->m_fullscreenDetector;
|
||||
}
|
||||
|
||||
void CAudioPlayingDetector::setIsPlaying (bool newState)
|
||||
{
|
||||
this->m_isPlaying = newState;
|
||||
}
|
||||
}
|
||||
|
||||
Application::CApplicationContext& CAudioPlayingDetector::getApplicationContext () {
|
||||
return this->m_applicationContext;
|
||||
}
|
||||
|
||||
const Render::Drivers::Detectors::CFullScreenDetector& CAudioPlayingDetector::getFullscreenDetector () const {
|
||||
return this->m_fullscreenDetector;
|
||||
}
|
||||
|
||||
void CAudioPlayingDetector::setIsPlaying (bool newState) {
|
||||
this->m_isPlaying = newState;
|
||||
}
|
||||
} // namespace WallpaperEngine::Audio::Drivers::Detectors
|
@ -1,29 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h"
|
||||
#include "WallpaperEngine/Application/CApplicationContext.h"
|
||||
#include "WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h"
|
||||
|
||||
namespace WallpaperEngine
|
||||
{
|
||||
namespace Application
|
||||
{
|
||||
class CApplicationContext;
|
||||
}
|
||||
namespace WallpaperEngine {
|
||||
namespace Application {
|
||||
class CApplicationContext;
|
||||
}
|
||||
|
||||
namespace Render::Drivers::Detectors
|
||||
{
|
||||
class CFullScreenDetector;
|
||||
}
|
||||
namespace Render::Drivers::Detectors {
|
||||
class CFullScreenDetector;
|
||||
}
|
||||
|
||||
namespace Audio::Drivers::Detectors
|
||||
{
|
||||
/**
|
||||
namespace Audio::Drivers::Detectors {
|
||||
/**
|
||||
* Base class for any implementation of audio playing detection
|
||||
*/
|
||||
class CAudioPlayingDetector
|
||||
{
|
||||
class CAudioPlayingDetector {
|
||||
public:
|
||||
CAudioPlayingDetector (Application::CApplicationContext& appContext, const Render::Drivers::Detectors::CFullScreenDetector& fullscreenDetector);
|
||||
CAudioPlayingDetector (Application::CApplicationContext& appContext,
|
||||
const Render::Drivers::Detectors::CFullScreenDetector& fullscreenDetector);
|
||||
|
||||
virtual ~CAudioPlayingDetector () = default;
|
||||
|
||||
/**
|
||||
* @return If any kind of sound is currently playing on the default audio device
|
||||
@ -55,6 +53,6 @@ namespace WallpaperEngine
|
||||
|
||||
Application::CApplicationContext& m_applicationContext;
|
||||
const Render::Drivers::Detectors::CFullScreenDetector& m_fullscreenDetector;
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace Audio::Drivers::Detectors
|
||||
} // namespace WallpaperEngine
|
||||
|
@ -3,11 +3,9 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
namespace WallpaperEngine::Audio::Drivers::Detectors
|
||||
{
|
||||
void sinkInputInfoCallback (pa_context* context, const pa_sink_input_info* info, int eol, void* userdata)
|
||||
{
|
||||
auto* detector = static_cast <CPulseAudioPlayingDetector*> (userdata);
|
||||
namespace WallpaperEngine::Audio::Drivers::Detectors {
|
||||
void sinkInputInfoCallback (pa_context* context, const pa_sink_input_info* info, int eol, void* userdata) {
|
||||
auto* detector = static_cast<CPulseAudioPlayingDetector*> (userdata);
|
||||
|
||||
if (info == nullptr)
|
||||
return;
|
||||
@ -20,26 +18,24 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
|
||||
|
||||
if (value && atoi (value) != getpid () && pa_cvolume_avg (&info->volume) != PA_VOLUME_MUTED)
|
||||
detector->setIsPlaying (true);
|
||||
}
|
||||
}
|
||||
|
||||
void defaultSinkInfoCallback (pa_context* context, const pa_server_info* info, void* userdata)
|
||||
{
|
||||
void defaultSinkInfoCallback (pa_context* context, const pa_server_info* info, void* userdata) {
|
||||
if (info == nullptr)
|
||||
return;
|
||||
|
||||
pa_operation* op = pa_context_get_sink_input_info_list (context, sinkInputInfoCallback, userdata);
|
||||
|
||||
pa_operation_unref (op);
|
||||
}
|
||||
}
|
||||
|
||||
CPulseAudioPlayingDetector::CPulseAudioPlayingDetector (
|
||||
CPulseAudioPlayingDetector::CPulseAudioPlayingDetector (
|
||||
Application::CApplicationContext& appContext,
|
||||
const Render::Drivers::Detectors::CFullScreenDetector& fullscreenDetector) :
|
||||
CAudioPlayingDetector (appContext, fullscreenDetector),
|
||||
m_mainloop (nullptr),
|
||||
m_mainloopApi (nullptr),
|
||||
m_context (nullptr)
|
||||
{
|
||||
m_context (nullptr) {
|
||||
this->m_mainloop = pa_mainloop_new ();
|
||||
this->m_mainloopApi = pa_mainloop_get_api (this->m_mainloop);
|
||||
this->m_context = pa_context_new (this->m_mainloopApi, "wallpaperengine");
|
||||
@ -49,23 +45,19 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
|
||||
// lock until pulseaudio allows connection
|
||||
while (pa_context_get_state (this->m_context) != PA_CONTEXT_READY)
|
||||
pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
CPulseAudioPlayingDetector::~CPulseAudioPlayingDetector ()
|
||||
{
|
||||
if (this->m_context)
|
||||
{
|
||||
CPulseAudioPlayingDetector::~CPulseAudioPlayingDetector () {
|
||||
if (this->m_context) {
|
||||
pa_context_disconnect (this->m_context);
|
||||
pa_context_unref (this->m_context);
|
||||
}
|
||||
|
||||
if (this->m_mainloop)
|
||||
pa_mainloop_free (this->m_mainloop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CPulseAudioPlayingDetector::update ()
|
||||
{
|
||||
void CPulseAudioPlayingDetector::update () {
|
||||
if (!this->getApplicationContext ().settings.audio.automute)
|
||||
return this->setIsPlaying (false);
|
||||
if (this->getFullscreenDetector ().anythingFullscreen ())
|
||||
@ -75,12 +67,12 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
|
||||
this->setIsPlaying (false);
|
||||
|
||||
// start discovery of sinks
|
||||
pa_operation* op = pa_context_get_server_info (this->m_context, defaultSinkInfoCallback, (void*) this);
|
||||
pa_operation* op = pa_context_get_server_info (this->m_context, defaultSinkInfoCallback, this);
|
||||
|
||||
// wait until all the operations are done
|
||||
while (pa_operation_get_state (op) == PA_OPERATION_RUNNING)
|
||||
pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
|
||||
|
||||
pa_operation_unref (op);
|
||||
}
|
||||
}
|
||||
} // namespace WallpaperEngine::Audio::Drivers::Detectors
|
@ -1,17 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "CAudioPlayingDetector.h"
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include "CAudioPlayingDetector.h"
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
namespace WallpaperEngine::Audio::Drivers::Detectors
|
||||
{
|
||||
class CPulseAudioPlayingDetector : public CAudioPlayingDetector
|
||||
{
|
||||
namespace WallpaperEngine::Audio::Drivers::Detectors {
|
||||
class CPulseAudioPlayingDetector final : public CAudioPlayingDetector {
|
||||
public:
|
||||
explicit CPulseAudioPlayingDetector (Application::CApplicationContext& appContext, const Render::Drivers::Detectors::CFullScreenDetector&);
|
||||
~CPulseAudioPlayingDetector ();
|
||||
explicit CPulseAudioPlayingDetector (Application::CApplicationContext& appContext,
|
||||
const Render::Drivers::Detectors::CFullScreenDetector&);
|
||||
~CPulseAudioPlayingDetector () override;
|
||||
|
||||
void update () override;
|
||||
|
||||
@ -19,5 +18,5 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
|
||||
pa_mainloop* m_mainloop;
|
||||
pa_mainloop_api* m_mainloopApi;
|
||||
pa_context* m_context;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Audio::Drivers::Detectors
|
||||
|
@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
{
|
||||
class CPlaybackRecorder
|
||||
{
|
||||
namespace WallpaperEngine::Audio::Drivers::Recorders {
|
||||
class CPlaybackRecorder {
|
||||
public:
|
||||
virtual ~CPlaybackRecorder () = default;
|
||||
|
||||
virtual void update () = 0;
|
||||
|
||||
float audio16[16] = {0};
|
||||
float audio32[32] = {0};
|
||||
float audio64[64] = {0};
|
||||
};
|
||||
}
|
||||
float audio16 [16] = {0};
|
||||
float audio32 [32] = {0};
|
||||
float audio64 [64] = {0};
|
||||
};
|
||||
} // namespace WallpaperEngine::Audio::Drivers::Recorders
|
@ -1,42 +1,33 @@
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <glm/common.hpp>
|
||||
#include "CPulseAudioPlaybackRecorder.h"
|
||||
#include "WallpaperEngine/Logging/CLog.h"
|
||||
#include "External/Android/fft.h"
|
||||
#include "WallpaperEngine/Logging/CLog.h"
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <glm/common.hpp>
|
||||
|
||||
namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
{
|
||||
float movetowards(float current, float target, float maxDelta)
|
||||
{
|
||||
if (abs(target - current) <= maxDelta)
|
||||
namespace WallpaperEngine::Audio::Drivers::Recorders {
|
||||
float movetowards (float current, float target, float maxDelta) {
|
||||
if (abs (target - current) <= maxDelta)
|
||||
return target;
|
||||
|
||||
return current + glm::sign(target - current) * maxDelta;
|
||||
}
|
||||
return current + glm::sign (target - current) * maxDelta;
|
||||
}
|
||||
|
||||
void pa_stream_notify_cb(pa_stream *stream, void* /*userdata*/)
|
||||
{
|
||||
const pa_stream_state state = pa_stream_get_state(stream);
|
||||
switch (state) {
|
||||
case PA_STREAM_FAILED:
|
||||
sLog.error ("Cannot open stream for capture. Audio processing is disabled");
|
||||
break;
|
||||
case PA_STREAM_READY:
|
||||
sLog.debug ("Capture stream ready");
|
||||
break;
|
||||
}
|
||||
void pa_stream_notify_cb (pa_stream* stream, void* /*userdata*/) {
|
||||
switch (pa_stream_get_state (stream)) {
|
||||
case PA_STREAM_FAILED: sLog.error ("Cannot open stream for capture. Audio processing is disabled"); break;
|
||||
case PA_STREAM_READY: sLog.debug ("Capture stream ready"); break;
|
||||
}
|
||||
}
|
||||
|
||||
void pa_stream_read_cb(pa_stream *stream, const size_t /*nbytes*/, void* userdata)
|
||||
{
|
||||
auto* recorder = reinterpret_cast<CPulseAudioPlaybackRecorder*>(userdata);
|
||||
void pa_stream_read_cb (pa_stream* stream, const size_t /*nbytes*/, void* userdata) {
|
||||
auto* recorder = static_cast<CPulseAudioPlaybackRecorder*> (userdata);
|
||||
|
||||
// Careful when to pa_stream_peek() and pa_stream_drop()!
|
||||
// c.f. https://www.freedesktop.org/software/pulseaudio/doxygen/stream_8h.html#ac2838c449cde56e169224d7fe3d00824
|
||||
uint8_t *data = nullptr;
|
||||
const void* data = nullptr;
|
||||
size_t currentSize;
|
||||
if (pa_stream_peek(stream, (const void**)&data, ¤tSize) != 0) {
|
||||
if (pa_stream_peek (stream, &data, ¤tSize) != 0) {
|
||||
sLog.error ("Failed to peek at stream data...");
|
||||
return;
|
||||
}
|
||||
@ -44,9 +35,11 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
if (data == nullptr && currentSize == 0) {
|
||||
// No data in the buffer, ignore.
|
||||
return;
|
||||
} else if (data == nullptr && currentSize > 0) {
|
||||
}
|
||||
|
||||
if (data == nullptr && currentSize > 0) {
|
||||
// Hole in the buffer. We must drop it.
|
||||
if (pa_stream_drop(stream) != 0) {
|
||||
if (pa_stream_drop (stream) != 0) {
|
||||
sLog.error ("Failed to drop a hole while capturing!");
|
||||
return;
|
||||
}
|
||||
@ -77,69 +70,61 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
}
|
||||
}
|
||||
|
||||
if (pa_stream_drop(stream) != 0) {
|
||||
if (pa_stream_drop (stream) != 0) {
|
||||
sLog.error ("Failed to drop data after peeking");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pa_server_info_cb(pa_context *ctx, const pa_server_info *info, void* userdata)
|
||||
{
|
||||
auto* recorder = reinterpret_cast<CPulseAudioPlaybackRecorder*>(userdata);
|
||||
void pa_server_info_cb (pa_context* ctx, const pa_server_info* info, void* userdata) {
|
||||
auto* recorder = static_cast<CPulseAudioPlaybackRecorder*> (userdata);
|
||||
|
||||
pa_sample_spec spec;
|
||||
spec.format = PA_SAMPLE_U8;
|
||||
spec.rate = 44100;
|
||||
spec.channels = 1;
|
||||
|
||||
if (recorder->getCaptureStream ())
|
||||
{
|
||||
if (recorder->getCaptureStream ()) {
|
||||
pa_stream_unref (recorder->getCaptureStream ());
|
||||
// get rid of the reference just in case
|
||||
recorder->setCaptureStream (nullptr);
|
||||
}
|
||||
|
||||
pa_stream* captureStream = pa_stream_new(ctx, "output monitor", &spec, nullptr);
|
||||
pa_stream* captureStream = pa_stream_new (ctx, "output monitor", &spec, nullptr);
|
||||
|
||||
// store the stream first, if the record start fails there'll still be a reference to it
|
||||
// so it can be free'd later
|
||||
recorder->setCaptureStream (captureStream),
|
||||
|
||||
pa_stream_set_state_callback(captureStream, &pa_stream_notify_cb, userdata);
|
||||
pa_stream_set_read_callback(captureStream, &pa_stream_read_cb, userdata);
|
||||
pa_stream_set_state_callback (captureStream, &pa_stream_notify_cb, userdata);
|
||||
pa_stream_set_read_callback (captureStream, &pa_stream_read_cb, userdata);
|
||||
|
||||
std::string monitor_name(info->default_sink_name);
|
||||
std::string monitor_name (info->default_sink_name);
|
||||
monitor_name += ".monitor";
|
||||
if (pa_stream_connect_record(captureStream, monitor_name.c_str(), nullptr, PA_STREAM_NOFLAGS) != 0) {
|
||||
if (pa_stream_connect_record (captureStream, monitor_name.c_str (), nullptr, PA_STREAM_NOFLAGS) != 0) {
|
||||
sLog.error ("Failed to connect to input for recording");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pa_context_subscribe_cb (pa_context *ctx, pa_subscription_event_type_t t, uint32_t idx, void *userdata)
|
||||
{
|
||||
void pa_context_subscribe_cb (pa_context* ctx, pa_subscription_event_type_t t, uint32_t idx, void* userdata) {
|
||||
// sink changes mean re-take the stream
|
||||
pa_context_get_server_info(ctx, &pa_server_info_cb, userdata);
|
||||
}
|
||||
pa_context_get_server_info (ctx, &pa_server_info_cb, userdata);
|
||||
}
|
||||
|
||||
void pa_context_notify_cb(pa_context *ctx, void* userdata)
|
||||
{
|
||||
const pa_context_state state = pa_context_get_state(ctx);
|
||||
switch (state) {
|
||||
case PA_CONTEXT_READY:
|
||||
{
|
||||
//set callback
|
||||
void pa_context_notify_cb (pa_context* ctx, void* userdata) {
|
||||
switch (pa_context_get_state (ctx)) {
|
||||
case PA_CONTEXT_READY: {
|
||||
// set callback
|
||||
pa_context_set_subscribe_callback (ctx, pa_context_subscribe_cb, userdata);
|
||||
//set events mask and enable event callback.
|
||||
// set events mask and enable event callback.
|
||||
pa_operation* o = pa_context_subscribe (
|
||||
ctx, static_cast<pa_subscription_mask_t>(PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE),
|
||||
NULL, NULL
|
||||
);
|
||||
ctx, static_cast<pa_subscription_mask_t> (PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE),
|
||||
nullptr, nullptr);
|
||||
|
||||
if (o)
|
||||
pa_operation_unref (o);
|
||||
|
||||
// context being ready means to fetch the sink too
|
||||
pa_context_get_server_info(ctx, &pa_server_info_cb, userdata);
|
||||
pa_context_get_server_info (ctx, &pa_server_info_cb, userdata);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -147,18 +132,16 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
sLog.error ("PulseAudio context initialization failed. Audio processing is disabled");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CPulseAudioPlaybackRecorder::CPulseAudioPlaybackRecorder () :
|
||||
m_captureStream (nullptr)
|
||||
{
|
||||
CPulseAudioPlaybackRecorder::CPulseAudioPlaybackRecorder () : m_captureStream (nullptr) {
|
||||
this->m_mainloop = pa_mainloop_new ();
|
||||
this->m_mainloopApi = pa_mainloop_get_api (this->m_mainloop);
|
||||
this->m_context = pa_context_new (this->m_mainloopApi, "wallpaperengine-audioprocessing");
|
||||
|
||||
pa_context_set_state_callback (this->m_context, &pa_context_notify_cb, this);
|
||||
|
||||
if (pa_context_connect(this->m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr) < 0) {
|
||||
if (pa_context_connect (this->m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr) < 0) {
|
||||
sLog.error ("PulseAudio connection failed! Audio processing is disabled");
|
||||
return;
|
||||
}
|
||||
@ -166,37 +149,33 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
// wait until the context is ready
|
||||
while (pa_context_get_state (this->m_context) != PA_CONTEXT_READY)
|
||||
pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
CPulseAudioPlaybackRecorder::~CPulseAudioPlaybackRecorder ()
|
||||
{
|
||||
pa_context_disconnect(this->m_context);
|
||||
pa_mainloop_free(this->m_mainloop);
|
||||
}
|
||||
CPulseAudioPlaybackRecorder::~CPulseAudioPlaybackRecorder () {
|
||||
pa_context_disconnect (this->m_context);
|
||||
pa_mainloop_free (this->m_mainloop);
|
||||
}
|
||||
|
||||
pa_stream* CPulseAudioPlaybackRecorder::getCaptureStream ()
|
||||
{
|
||||
pa_stream* CPulseAudioPlaybackRecorder::getCaptureStream () {
|
||||
return this->m_captureStream;
|
||||
}
|
||||
}
|
||||
|
||||
void CPulseAudioPlaybackRecorder::setCaptureStream (pa_stream* stream)
|
||||
{
|
||||
void CPulseAudioPlaybackRecorder::setCaptureStream (pa_stream* stream) {
|
||||
this->m_captureStream = stream;
|
||||
}
|
||||
}
|
||||
|
||||
void CPulseAudioPlaybackRecorder::update ()
|
||||
{
|
||||
void CPulseAudioPlaybackRecorder::update () {
|
||||
pa_mainloop_iterate (this->m_mainloop, 0, nullptr);
|
||||
|
||||
// interpolate current values to the destination
|
||||
for (int i = 0; i < 64; i ++) {
|
||||
this->audio64 [i] = movetowards (this->audio64[i], fft_destination64[i], 0.1f);
|
||||
for (int i = 0; i < 64; i++) {
|
||||
this->audio64 [i] = movetowards (this->audio64 [i], fft_destination64 [i], 0.1f);
|
||||
if (i >= 32)
|
||||
continue;
|
||||
this->audio32 [i] = movetowards (this->audio32[i], fft_destination32[i], 0.1f);
|
||||
this->audio32 [i] = movetowards (this->audio32 [i], fft_destination32 [i], 0.1f);
|
||||
if (i >= 16)
|
||||
continue;
|
||||
this->audio16 [i] = movetowards (this->audio16[i], fft_destination16[i], 0.1f);
|
||||
this->audio16 [i] = movetowards (this->audio16 [i], fft_destination16 [i], 0.1f);
|
||||
}
|
||||
|
||||
if (!this->fullframeReady)
|
||||
@ -206,18 +185,21 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
|
||||
External::Android::doFft (audio_fft, audio_buffer);
|
||||
|
||||
for (int i = 0; i < 64; i ++) {
|
||||
int paramInt = (i + 2) * 2;
|
||||
float f1 = audio_fft[paramInt];
|
||||
float f2 = audio_fft[paramInt + 1];
|
||||
for (int i = 0; i < 64; i++) {
|
||||
const int paramInt = (i + 2) * 2;
|
||||
float f1 = audio_fft [paramInt];
|
||||
float f2 = audio_fft [paramInt + 1];
|
||||
f2 = f1 * f1 + f2 * f2;
|
||||
f1 = 0.0F;
|
||||
if (f2 > 0.0F)
|
||||
f1 = 0.35F * (float)log10(f2);
|
||||
f1 = 0.35F * static_cast<float> (log10 (f2));
|
||||
|
||||
this->fft_destination64[i] = fmin(1.0F, f1 * (float)(2.0f - pow(M_E, (1.0F - i / 63.0F) * 1.0f - 0.5f)));
|
||||
this->fft_destination32[i >> 1] = fmin(1.0F, f1 * (float)(2.0f - pow(M_E, (1.0F - i / 31.0F) * 1.0f - 0.5f)));
|
||||
this->fft_destination16[i >> 2] = fmin(1.0F, f1 * (float)(2.0f - pow(M_E, (1.0F - i / 15.0F) * 1.0f - 0.5f)));
|
||||
}
|
||||
this->fft_destination64 [i] =
|
||||
fmin (1.0F, f1 * static_cast<float> (2.0f - pow (M_E, (1.0F - i / 63.0F) * 1.0f - 0.5f)));
|
||||
this->fft_destination32 [i >> 1] =
|
||||
fmin (1.0F, f1 * static_cast<float> (2.0f - pow (M_E, (1.0F - i / 31.0F) * 1.0f - 0.5f)));
|
||||
this->fft_destination16 [i >> 2] =
|
||||
fmin (1.0F, f1 * static_cast<float> (2.0f - pow (M_E, (1.0F - i / 15.0F) * 1.0f - 0.5f)));
|
||||
}
|
||||
}
|
||||
} // namespace WallpaperEngine::Audio::Drivers::Recorders
|
@ -1,18 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include "External/Android/fft.h"
|
||||
#include "CPlaybackRecorder.h"
|
||||
#include "External/Android/fft.h"
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
{
|
||||
class CPlaybackRecorder;
|
||||
namespace WallpaperEngine::Audio::Drivers::Recorders {
|
||||
class CPlaybackRecorder;
|
||||
|
||||
class CPulseAudioPlaybackRecorder : public CPlaybackRecorder
|
||||
{
|
||||
class CPulseAudioPlaybackRecorder final : public CPlaybackRecorder {
|
||||
public:
|
||||
CPulseAudioPlaybackRecorder ();
|
||||
~CPulseAudioPlaybackRecorder ();
|
||||
~CPulseAudioPlaybackRecorder () override;
|
||||
|
||||
void update () override;
|
||||
|
||||
@ -38,8 +36,8 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
pa_context* m_context;
|
||||
pa_stream* m_captureStream;
|
||||
|
||||
float fft_destination64[64];
|
||||
float fft_destination32[32];
|
||||
float fft_destination16[16];
|
||||
};
|
||||
}
|
||||
float fft_destination64 [64];
|
||||
float fft_destination32 [32];
|
||||
float fft_destination16 [16];
|
||||
};
|
||||
} // namespace WallpaperEngine::Audio::Drivers::Recorders
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include "common.h"
|
||||
#include "CObject.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <utility>
|
||||
#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
|
||||
#include "WallpaperEngine/Core/Objects/CImage.h"
|
||||
#include "WallpaperEngine/Core/Objects/CSound.h"
|
||||
#include "WallpaperEngine/Core/Objects/CParticle.h"
|
||||
#include "WallpaperEngine/Core/CScene.h"
|
||||
#include "WallpaperEngine/Core/CProject.h"
|
||||
#include "WallpaperEngine/Core/CScene.h"
|
||||
#include "WallpaperEngine/Core/Objects/CImage.h"
|
||||
#include "WallpaperEngine/Core/Objects/CParticle.h"
|
||||
#include "WallpaperEngine/Core/Objects/CSound.h"
|
||||
#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
|
||||
#include <utility>
|
||||
|
||||
#include "WallpaperEngine/Assets/CContainer.h"
|
||||
|
||||
@ -15,35 +15,25 @@ using namespace WallpaperEngine::Core;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
|
||||
CObject::CObject (
|
||||
CScene* scene,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
std::string type,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale,
|
||||
const glm::vec3& angles) :
|
||||
CObject::CObject (CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name, std::string type,
|
||||
CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles) :
|
||||
m_scene (scene),
|
||||
m_visible (visible),
|
||||
m_id (id),
|
||||
m_name (std::move(name)),
|
||||
m_type (std::move(type)),
|
||||
m_name (std::move (name)),
|
||||
m_type (std::move (type)),
|
||||
m_origin (origin),
|
||||
m_scale (scale),
|
||||
m_angles (angles)
|
||||
{
|
||||
}
|
||||
m_angles (angles) {}
|
||||
|
||||
CObject* CObject::fromJSON (json data, CScene* scene, CContainer* container)
|
||||
{
|
||||
CObject* CObject::fromJSON (json data, CScene* scene, CContainer* container) {
|
||||
std::string json = data.dump ();
|
||||
|
||||
auto id_it = jsonFindRequired (data, "id", "Objects must have id");
|
||||
auto visible = jsonFindUserConfig <CUserSettingBoolean> (data, "visible", false);
|
||||
auto origin = jsonFindUserConfig <CUserSettingVector3> (data, "origin", {0, 0, 0});
|
||||
auto scale = jsonFindUserConfig <CUserSettingVector3> (data, "scale", {1, 1, 1});
|
||||
auto angles_val = jsonFindDefault <std::string> (data, "angles", "0.0 0.0 0.0");
|
||||
auto visible = jsonFindUserConfig<CUserSettingBoolean> (data, "visible", false);
|
||||
auto origin = jsonFindUserConfig<CUserSettingVector3> (data, "origin", {0, 0, 0});
|
||||
auto scale = jsonFindUserConfig<CUserSettingVector3> (data, "scale", {1, 1, 1});
|
||||
auto angles_val = jsonFindDefault<std::string> (data, "angles", "0.0 0.0 0.0");
|
||||
auto name_it = jsonFindRequired (data, "name", "Objects must have name");
|
||||
auto effects_it = data.find ("effects");
|
||||
auto dependencies_it = data.find ("dependencies");
|
||||
@ -56,142 +46,89 @@ CObject* CObject::fromJSON (json data, CScene* scene, CContainer* container)
|
||||
|
||||
CObject* object;
|
||||
|
||||
if (image_it != data.end () && !(*image_it).is_null ())
|
||||
{
|
||||
object = Objects::CImage::fromJSON (
|
||||
scene,
|
||||
data,
|
||||
container,
|
||||
visible,
|
||||
*id_it,
|
||||
*name_it,
|
||||
origin,
|
||||
scale,
|
||||
WallpaperEngine::Core::aToVector3 (angles_val)
|
||||
);
|
||||
}
|
||||
else if (sound_it != data.end () && !(*sound_it).is_null ())
|
||||
{
|
||||
object = Objects::CSound::fromJSON (
|
||||
scene,
|
||||
data,
|
||||
visible,
|
||||
*id_it,
|
||||
*name_it,
|
||||
origin,
|
||||
scale,
|
||||
WallpaperEngine::Core::aToVector3 (angles_val)
|
||||
);
|
||||
}
|
||||
else if (particle_it != data.end () && !(*particle_it).is_null ())
|
||||
{
|
||||
if (image_it != data.end () && !image_it->is_null ()) {
|
||||
object = Objects::CImage::fromJSON (scene, data, container, visible, *id_it, *name_it, origin, scale,
|
||||
WallpaperEngine::Core::aToVector3 (angles_val));
|
||||
} else if (sound_it != data.end () && !sound_it->is_null ()) {
|
||||
object = Objects::CSound::fromJSON (scene, data, visible, *id_it, *name_it, origin, scale,
|
||||
WallpaperEngine::Core::aToVector3 (angles_val));
|
||||
} else if (particle_it != data.end () && !particle_it->is_null ()) {
|
||||
/// TODO: XXXHACK -- TO REMOVE WHEN PARTICLE SUPPORT IS PROPERLY IMPLEMENTED
|
||||
try
|
||||
{
|
||||
object = Objects::CParticle::fromFile (
|
||||
scene,
|
||||
(*particle_it).get <std::string> (),
|
||||
container,
|
||||
visible,
|
||||
*id_it,
|
||||
*name_it,
|
||||
origin,
|
||||
scale
|
||||
);
|
||||
}
|
||||
catch (std::runtime_error& ex)
|
||||
{
|
||||
try {
|
||||
object = Objects::CParticle::fromFile (scene, particle_it->get<std::string> (), container, visible, *id_it,
|
||||
*name_it, origin, scale);
|
||||
} catch (std::runtime_error&) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if (text_it != data.end () && !(*text_it).is_null ())
|
||||
{
|
||||
} else if (text_it != data.end () && !text_it->is_null ()) {
|
||||
/// TODO: XXXHACK -- TO REMOVE WHEN TEXT SUPPORT IS IMPLEMENTED
|
||||
return nullptr;
|
||||
}
|
||||
else if (light_it != data.end () && !(*light_it).is_null ())
|
||||
{
|
||||
} else if (light_it != data.end () && !light_it->is_null ()) {
|
||||
/// TODO: XXXHACK -- TO REMOVE WHEN LIGHT SUPPORT IS IMPLEMENTED
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
sLog.exception ("Unknown object type detected: ", *name_it);
|
||||
}
|
||||
|
||||
if (effects_it != data.end () && (*effects_it).is_array ())
|
||||
{
|
||||
for (auto& cur : *effects_it)
|
||||
{
|
||||
auto effectVisible = jsonFindUserConfig <CUserSettingBoolean> (cur, "visible", true);
|
||||
if (effects_it != data.end () && effects_it->is_array ()) {
|
||||
for (auto& cur : *effects_it) {
|
||||
auto effectVisible = jsonFindUserConfig<CUserSettingBoolean> (cur, "visible", true);
|
||||
|
||||
if (!effectVisible->processValue (scene->getProject ().getProperties ()))
|
||||
continue;
|
||||
|
||||
object->insertEffect (
|
||||
Objects::CEffect::fromJSON (cur, effectVisible, object, container)
|
||||
);
|
||||
object->insertEffect (Objects::CEffect::fromJSON (cur, effectVisible, object, container));
|
||||
}
|
||||
}
|
||||
|
||||
if (dependencies_it != data.end () && (*dependencies_it).is_array ())
|
||||
if (dependencies_it != data.end () && dependencies_it->is_array ())
|
||||
for (const auto& cur : *dependencies_it)
|
||||
object->insertDependency (cur);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
glm::vec3 CObject::getOrigin () const
|
||||
{
|
||||
glm::vec3 CObject::getOrigin () const {
|
||||
return this->m_origin->processValue (this->getScene ()->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
glm::vec3 CObject::getScale () const
|
||||
{
|
||||
glm::vec3 CObject::getScale () const {
|
||||
return this->m_scale->processValue (this->getScene ()->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
const glm::vec3& CObject::getAngles () const
|
||||
{
|
||||
const glm::vec3& CObject::getAngles () const {
|
||||
return this->m_angles;
|
||||
}
|
||||
|
||||
const std::string& CObject::getName () const
|
||||
{
|
||||
const std::string& CObject::getName () const {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
const std::vector<Objects::CEffect*>& CObject::getEffects () const
|
||||
{
|
||||
const std::vector<Objects::CEffect*>& CObject::getEffects () const {
|
||||
return this->m_effects;
|
||||
}
|
||||
|
||||
const std::vector<uint32_t>& CObject::getDependencies () const
|
||||
{
|
||||
const std::vector<uint32_t>& CObject::getDependencies () const {
|
||||
return this->m_dependencies;
|
||||
}
|
||||
|
||||
bool CObject::isVisible () const
|
||||
{
|
||||
bool CObject::isVisible () const {
|
||||
// TODO: cache this
|
||||
return this->m_visible->processValue (this->getScene ()->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
CScene* CObject::getScene () const
|
||||
{
|
||||
CScene* CObject::getScene () const {
|
||||
return this->m_scene;
|
||||
}
|
||||
|
||||
int CObject::getId () const
|
||||
{
|
||||
int CObject::getId () const {
|
||||
return this->m_id;
|
||||
}
|
||||
|
||||
void CObject::insertEffect (Objects::CEffect* effect)
|
||||
{
|
||||
void CObject::insertEffect (Objects::CEffect* effect) {
|
||||
this->m_effects.push_back (effect);
|
||||
}
|
||||
void CObject::insertDependency (uint32_t dependency)
|
||||
{
|
||||
|
||||
void CObject::insertDependency (uint32_t dependency) {
|
||||
this->m_dependencies.push_back (dependency);
|
||||
}
|
@ -8,37 +8,42 @@
|
||||
#include "WallpaperEngine/Core/UserSettings/CUserSettingFloat.h"
|
||||
#include "WallpaperEngine/Core/UserSettings/CUserSettingVector3.h"
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
class CScene;
|
||||
namespace WallpaperEngine::Core {
|
||||
class CScene;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Core::Objects
|
||||
{
|
||||
class CEffect;
|
||||
namespace WallpaperEngine::Core::Objects {
|
||||
class CEffect;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Core::UserSettings
|
||||
{
|
||||
class CUserSettingBoolean;
|
||||
namespace WallpaperEngine::Core::UserSettings {
|
||||
class CUserSettingBoolean;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
namespace WallpaperEngine::Core {
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
|
||||
class CObject
|
||||
{
|
||||
class CObject {
|
||||
friend class CScene;
|
||||
|
||||
public:
|
||||
static CObject* fromJSON (json data, CScene* scene, CContainer* container);
|
||||
|
||||
template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; }
|
||||
template<class T> T* as () { assert (is <T> ()); return (T*) this; }
|
||||
template <class T> const T* as () const {
|
||||
assert (is<T> ());
|
||||
return reinterpret_cast<const T*> (this);
|
||||
}
|
||||
|
||||
template<class T> bool is () { return this->m_type == T::Type; }
|
||||
template <class T> T* as () {
|
||||
assert (is<T> ());
|
||||
return reinterpret_cast<T*> (this);
|
||||
}
|
||||
|
||||
template <class T> bool is () {
|
||||
return this->m_type == T::Type;
|
||||
}
|
||||
|
||||
const std::vector<Objects::CEffect*>& getEffects () const;
|
||||
const std::vector<uint32_t>& getDependencies () const;
|
||||
@ -51,20 +56,14 @@ namespace WallpaperEngine::Core
|
||||
|
||||
bool isVisible () const;
|
||||
CScene* getScene () const;
|
||||
|
||||
protected:
|
||||
CObject (
|
||||
CScene* scene,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
std::string type,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale,
|
||||
const glm::vec3& angles
|
||||
);
|
||||
CObject (CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name, std::string type,
|
||||
CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles);
|
||||
|
||||
void insertEffect (Objects::CEffect* effect);
|
||||
void insertDependency (uint32_t dependency);
|
||||
|
||||
private:
|
||||
std::string m_type;
|
||||
|
||||
@ -79,5 +78,5 @@ namespace WallpaperEngine::Core
|
||||
std::vector<uint32_t> m_dependencies;
|
||||
|
||||
CScene* m_scene;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core
|
||||
|
@ -12,18 +12,16 @@ using namespace WallpaperEngine::Assets;
|
||||
CProject::CProject (std::string title, std::string type, CContainer* container) :
|
||||
m_title (std::move (title)),
|
||||
m_type (std::move (type)),
|
||||
m_container (container)
|
||||
{
|
||||
}
|
||||
m_wallpaper (nullptr),
|
||||
m_container (container) {}
|
||||
|
||||
CProject* CProject::fromFile (const std::string& filename, CContainer* container)
|
||||
{
|
||||
CProject* CProject::fromFile (const std::string& filename, CContainer* container) {
|
||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
|
||||
|
||||
std::string title = *jsonFindRequired (content, "title", "Project title missing");
|
||||
const std::string title = *jsonFindRequired (content, "title", "Project title missing");
|
||||
std::string type = *jsonFindRequired (content, "type", "Project type missing");
|
||||
std::string file = *jsonFindRequired (content, "file", "Project's main file missing");
|
||||
auto general = content.find ("general");
|
||||
const std::string file = *jsonFindRequired (content, "file", "Project's main file missing");
|
||||
const auto general = content.find ("general");
|
||||
CWallpaper* wallpaper;
|
||||
|
||||
std::transform (type.begin (), type.end (), type.begin (), tolower);
|
||||
@ -33,7 +31,7 @@ CProject* CProject::fromFile (const std::string& filename, CContainer* container
|
||||
if (type == "scene")
|
||||
wallpaper = CScene::fromFile (file, *project, container);
|
||||
else if (type == "video")
|
||||
wallpaper = new CVideo (file.c_str (), *project);
|
||||
wallpaper = new CVideo (file, *project);
|
||||
else if (type == "web")
|
||||
sLog.exception ("Web wallpapers are not supported yet");
|
||||
else
|
||||
@ -41,14 +39,11 @@ CProject* CProject::fromFile (const std::string& filename, CContainer* container
|
||||
|
||||
project->setWallpaper (wallpaper);
|
||||
|
||||
if (general != content.end ())
|
||||
{
|
||||
auto properties = (*general).find ("properties");
|
||||
if (general != content.end ()) {
|
||||
const auto properties = general->find ("properties");
|
||||
|
||||
if (properties != (*general).end ())
|
||||
{
|
||||
for (const auto& cur : (*properties).items ())
|
||||
{
|
||||
if (properties != general->end ()) {
|
||||
for (const auto& cur : properties->items ()) {
|
||||
Projects::CProperty* property = Projects::CProperty::fromJSON (cur.value (), cur.key ());
|
||||
|
||||
if (property != nullptr)
|
||||
@ -60,37 +55,30 @@ CProject* CProject::fromFile (const std::string& filename, CContainer* container
|
||||
return project;
|
||||
}
|
||||
|
||||
void CProject::setWallpaper (CWallpaper* wallpaper)
|
||||
{
|
||||
void CProject::setWallpaper (CWallpaper* wallpaper) {
|
||||
this->m_wallpaper = wallpaper;
|
||||
}
|
||||
|
||||
CWallpaper* CProject::getWallpaper () const
|
||||
{
|
||||
CWallpaper* CProject::getWallpaper () const {
|
||||
return this->m_wallpaper;
|
||||
}
|
||||
|
||||
const std::string& CProject::getTitle () const
|
||||
{
|
||||
const std::string& CProject::getTitle () const {
|
||||
return this->m_title;
|
||||
}
|
||||
|
||||
const std::string& CProject::getType () const
|
||||
{
|
||||
const std::string& CProject::getType () const {
|
||||
return this->m_type;
|
||||
}
|
||||
|
||||
const std::vector<Projects::CProperty*>& CProject::getProperties () const
|
||||
{
|
||||
const std::vector<Projects::CProperty*>& CProject::getProperties () const {
|
||||
return this->m_properties;
|
||||
}
|
||||
|
||||
CContainer* CProject::getContainer ()
|
||||
{
|
||||
CContainer* CProject::getContainer () {
|
||||
return this->m_container;
|
||||
}
|
||||
|
||||
void CProject::insertProperty (Projects::CProperty* property)
|
||||
{
|
||||
void CProject::insertProperty (Projects::CProperty* property) {
|
||||
this->m_properties.push_back (property);
|
||||
}
|
@ -6,15 +6,13 @@
|
||||
|
||||
#include "WallpaperEngine/Assets/CContainer.h"
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
namespace WallpaperEngine::Core {
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
class CWallpaper;
|
||||
class CWallpaper;
|
||||
|
||||
class CProject
|
||||
{
|
||||
class CProject {
|
||||
public:
|
||||
static CProject* fromFile (const std::string& filename, CContainer* container);
|
||||
|
||||
@ -31,6 +29,7 @@ namespace WallpaperEngine::Core
|
||||
|
||||
void setWallpaper (CWallpaper* wallpaper);
|
||||
void insertProperty (Projects::CProperty* property);
|
||||
|
||||
private:
|
||||
std::vector<Projects::CProperty*> m_properties;
|
||||
|
||||
@ -38,5 +37,5 @@ namespace WallpaperEngine::Core
|
||||
std::string m_type;
|
||||
CWallpaper* m_wallpaper;
|
||||
CContainer* m_container;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core
|
||||
|
@ -8,27 +8,12 @@
|
||||
|
||||
using namespace WallpaperEngine::Core;
|
||||
|
||||
CScene::CScene (
|
||||
CProject& project,
|
||||
CContainer* container,
|
||||
Scenes::CCamera* camera,
|
||||
glm::vec3 ambientColor,
|
||||
CUserSettingBoolean* bloom,
|
||||
CUserSettingFloat* bloomStrength,
|
||||
CUserSettingFloat* bloomThreshold,
|
||||
bool cameraFade,
|
||||
bool cameraParallax,
|
||||
double cameraParallaxAmount,
|
||||
double cameraParallaxDelay,
|
||||
double cameraParallaxMouseInfluence,
|
||||
bool cameraPreview,
|
||||
bool cameraShake,
|
||||
double cameraShakeAmplitude,
|
||||
double cameraShakeRoughness,
|
||||
double cameraShakeSpeed,
|
||||
CUserSettingVector3* clearColor,
|
||||
Scenes::CProjection* orthogonalProjection,
|
||||
glm::vec3 skylightColor) :
|
||||
CScene::CScene (CProject& project, CContainer* container, Scenes::CCamera* camera, glm::vec3 ambientColor,
|
||||
CUserSettingBoolean* bloom, CUserSettingFloat* bloomStrength, CUserSettingFloat* bloomThreshold,
|
||||
bool cameraFade, bool cameraParallax, double cameraParallaxAmount, double cameraParallaxDelay,
|
||||
double cameraParallaxMouseInfluence, bool cameraPreview, bool cameraShake, double cameraShakeAmplitude,
|
||||
double cameraShakeRoughness, double cameraShakeSpeed, CUserSettingVector3* clearColor,
|
||||
Scenes::CProjection* orthogonalProjection, glm::vec3 skylightColor) :
|
||||
CWallpaper (Type, project),
|
||||
m_container (container),
|
||||
m_camera (camera),
|
||||
@ -48,60 +33,44 @@ CScene::CScene (
|
||||
m_cameraShakeSpeed (cameraShakeSpeed),
|
||||
m_clearColor (clearColor),
|
||||
m_orthogonalProjection (orthogonalProjection),
|
||||
m_skylightColor (skylightColor)
|
||||
{
|
||||
}
|
||||
m_skylightColor (skylightColor) {}
|
||||
|
||||
CScene* CScene::fromFile (const std::string& filename, CProject& project, CContainer* container)
|
||||
{
|
||||
CScene* CScene::fromFile (const std::string& filename, CProject& project, CContainer* container) {
|
||||
std::string stringContent = WallpaperEngine::FileSystem::loadFullFile (filename, container);
|
||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
|
||||
|
||||
auto camera_it = jsonFindRequired (content, "camera", "Scenes must have a defined camera");
|
||||
auto general_it = jsonFindRequired (content, "general", "Scenes must have a general section");
|
||||
auto objects_it = jsonFindRequired (content, "objects", "Scenes must have a list of objects to display");
|
||||
const auto camera_it = jsonFindRequired (content, "camera", "Scenes must have a defined camera");
|
||||
const auto general_it = jsonFindRequired (content, "general", "Scenes must have a general section");
|
||||
const auto objects_it = jsonFindRequired (content, "objects", "Scenes must have a list of objects to display");
|
||||
|
||||
// TODO: FIND IF THESE DEFAULTS ARE SENSIBLE OR NOT AND PERFORM PROPER VALIDATION WHEN CAMERA PREVIEW AND CAMERA PARALLAX ARE PRESENT
|
||||
auto ambientcolor = jsonFindDefault <std::string> (*general_it, "ambientcolor", "0 0 0");
|
||||
auto bloom = jsonFindUserConfig <CUserSettingBoolean> (*general_it, "bloom", false);
|
||||
auto bloomstrength = jsonFindUserConfig <CUserSettingFloat> (*general_it, "bloomstrength", 0.0);
|
||||
auto bloomthreshold = jsonFindUserConfig <CUserSettingFloat> (*general_it, "bloomthreshold", 0.0);
|
||||
auto camerafade = jsonFindDefault <bool> (*general_it, "camerafade", false);
|
||||
auto cameraparallax = jsonFindDefault <bool> (*general_it, "cameraparallax", true);
|
||||
auto cameraparallaxamount = jsonFindDefault <double> (*general_it, "cameraparallaxamount", 1.0f);
|
||||
auto cameraparallaxdelay = jsonFindDefault <double> (*general_it, "cameraparallaxdelay", 0.0f);
|
||||
auto cameraparallaxmouseinfluence = jsonFindDefault <double> (*general_it, "cameraparallaxmouseinfluence", 1.0f);
|
||||
auto camerapreview = jsonFindDefault <bool> (*general_it, "camerapreview", false);
|
||||
auto camerashake = jsonFindDefault <bool> (*general_it, "camerashake", false);
|
||||
auto camerashakeamplitude = jsonFindDefault <double> (*general_it, "camerashakeamplitude", 0.0f);
|
||||
auto camerashakeroughness = jsonFindDefault <double> (*general_it, "camerashakeroughness", 0.0f);
|
||||
auto camerashakespeed = jsonFindDefault <double> (*general_it, "camerashakespeed", 0.0f);
|
||||
auto clearcolor = jsonFindUserConfig <CUserSettingVector3> (*general_it, "clearcolor", {1, 1, 1});
|
||||
auto orthogonalprojection_it = jsonFindRequired (*general_it, "orthogonalprojection", "General section must have orthogonal projection info");
|
||||
auto skylightcolor = jsonFindDefault <std::string> (*general_it, "skylightcolor", "0 0 0");
|
||||
// TODO: FIND IF THESE DEFAULTS ARE SENSIBLE OR NOT AND PERFORM PROPER VALIDATION WHEN CAMERA PREVIEW AND CAMERA
|
||||
// PARALLAX ARE PRESENT
|
||||
const auto ambientcolor = jsonFindDefault<std::string> (*general_it, "ambientcolor", "0 0 0");
|
||||
const auto bloom = jsonFindUserConfig<CUserSettingBoolean> (*general_it, "bloom", false);
|
||||
const auto bloomstrength = jsonFindUserConfig<CUserSettingFloat> (*general_it, "bloomstrength", 0.0);
|
||||
const auto bloomthreshold = jsonFindUserConfig<CUserSettingFloat> (*general_it, "bloomthreshold", 0.0);
|
||||
const auto camerafade = jsonFindDefault<bool> (*general_it, "camerafade", false);
|
||||
const auto cameraparallax = jsonFindDefault<bool> (*general_it, "cameraparallax", true);
|
||||
const auto cameraparallaxamount = jsonFindDefault<double> (*general_it, "cameraparallaxamount", 1.0f);
|
||||
const auto cameraparallaxdelay = jsonFindDefault<double> (*general_it, "cameraparallaxdelay", 0.0f);
|
||||
const auto cameraparallaxmouseinfluence =
|
||||
jsonFindDefault<double> (*general_it, "cameraparallaxmouseinfluence", 1.0f);
|
||||
const auto camerapreview = jsonFindDefault<bool> (*general_it, "camerapreview", false);
|
||||
const auto camerashake = jsonFindDefault<bool> (*general_it, "camerashake", false);
|
||||
const auto camerashakeamplitude = jsonFindDefault<double> (*general_it, "camerashakeamplitude", 0.0f);
|
||||
const auto camerashakeroughness = jsonFindDefault<double> (*general_it, "camerashakeroughness", 0.0f);
|
||||
const auto camerashakespeed = jsonFindDefault<double> (*general_it, "camerashakespeed", 0.0f);
|
||||
const auto clearcolor = jsonFindUserConfig<CUserSettingVector3> (*general_it, "clearcolor", {1, 1, 1});
|
||||
const auto orthogonalprojection_it =
|
||||
jsonFindRequired (*general_it, "orthogonalprojection", "General section must have orthogonal projection info");
|
||||
const auto skylightcolor = jsonFindDefault<std::string> (*general_it, "skylightcolor", "0 0 0");
|
||||
|
||||
CScene* scene = new CScene (
|
||||
project,
|
||||
container,
|
||||
Scenes::CCamera::fromJSON (*camera_it),
|
||||
WallpaperEngine::Core::aToColorf(ambientcolor),
|
||||
bloom,
|
||||
bloomstrength,
|
||||
bloomthreshold,
|
||||
camerafade,
|
||||
cameraparallax,
|
||||
cameraparallaxamount,
|
||||
cameraparallaxdelay,
|
||||
cameraparallaxmouseinfluence,
|
||||
camerapreview,
|
||||
camerashake,
|
||||
camerashakeamplitude,
|
||||
camerashakeroughness,
|
||||
camerashakespeed,
|
||||
clearcolor,
|
||||
Scenes::CProjection::fromJSON (*orthogonalprojection_it),
|
||||
WallpaperEngine::Core::aToColorf(skylightcolor)
|
||||
);
|
||||
auto* scene = new CScene (
|
||||
project, container, Scenes::CCamera::fromJSON (*camera_it), WallpaperEngine::Core::aToColorf (ambientcolor),
|
||||
bloom, bloomstrength, bloomthreshold, camerafade, cameraparallax, cameraparallaxamount, cameraparallaxdelay,
|
||||
cameraparallaxmouseinfluence, camerapreview, camerashake, camerashakeamplitude, camerashakeroughness,
|
||||
camerashakespeed, clearcolor, Scenes::CProjection::fromJSON (*orthogonalprojection_it),
|
||||
WallpaperEngine::Core::aToColorf (skylightcolor));
|
||||
|
||||
for (const auto& cur : *objects_it)
|
||||
scene->insertObject (CObject::fromJSON (cur, scene, container));
|
||||
@ -109,117 +78,95 @@ CScene* CScene::fromFile (const std::string& filename, CProject& project, CConta
|
||||
return scene;
|
||||
}
|
||||
|
||||
const std::map<uint32_t, CObject*>& CScene::getObjects () const
|
||||
{
|
||||
const std::map<uint32_t, CObject*>& CScene::getObjects () const {
|
||||
return this->m_objects;
|
||||
}
|
||||
const std::vector<CObject*>& CScene::getObjectsByRenderOrder () const
|
||||
{
|
||||
|
||||
const std::vector<CObject*>& CScene::getObjectsByRenderOrder () const {
|
||||
return this->m_objectsByRenderOrder;
|
||||
}
|
||||
|
||||
void CScene::insertObject (CObject* object)
|
||||
{
|
||||
void CScene::insertObject (CObject* object) {
|
||||
/// TODO: XXXHACK -- TO REMOVE WHEN PARTICLE SUPPORT IS PROPERLY IMPLEMENTED
|
||||
if (object != nullptr)
|
||||
{
|
||||
if (object != nullptr) {
|
||||
this->m_objects.insert (std::make_pair (object->getId (), object));
|
||||
this->m_objectsByRenderOrder.emplace_back (object);
|
||||
}
|
||||
}
|
||||
|
||||
CContainer* CScene::getContainer ()
|
||||
{
|
||||
CContainer* CScene::getContainer () {
|
||||
return this->m_container;
|
||||
}
|
||||
|
||||
const Scenes::CCamera* CScene::getCamera () const
|
||||
{
|
||||
const Scenes::CCamera* CScene::getCamera () const {
|
||||
return this->m_camera;
|
||||
}
|
||||
|
||||
const glm::vec3 &CScene::getAmbientColor() const
|
||||
{
|
||||
const glm::vec3& CScene::getAmbientColor () const {
|
||||
return this->m_ambientColor;
|
||||
}
|
||||
|
||||
const bool CScene::isBloom () const
|
||||
{
|
||||
const bool CScene::isBloom () const {
|
||||
return this->m_bloom->processValue (this->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
double CScene::getBloomStrength () const
|
||||
{
|
||||
double CScene::getBloomStrength () const {
|
||||
return this->m_bloomStrength->processValue (this->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
double CScene::getBloomThreshold () const
|
||||
{
|
||||
double CScene::getBloomThreshold () const {
|
||||
return this->m_bloomThreshold->processValue (this->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
const bool CScene::isCameraFade () const
|
||||
{
|
||||
const bool CScene::isCameraFade () const {
|
||||
return this->m_cameraFade;
|
||||
}
|
||||
|
||||
const bool CScene::isCameraParallax () const
|
||||
{
|
||||
const bool CScene::isCameraParallax () const {
|
||||
return this->m_cameraParallax;
|
||||
}
|
||||
|
||||
const double CScene::getCameraParallaxAmount () const
|
||||
{
|
||||
const double CScene::getCameraParallaxAmount () const {
|
||||
return this->m_cameraParallaxAmount;
|
||||
}
|
||||
|
||||
const double CScene::getCameraParallaxDelay () const
|
||||
{
|
||||
const double CScene::getCameraParallaxDelay () const {
|
||||
return this->m_cameraParallaxDelay;
|
||||
}
|
||||
|
||||
const double CScene::getCameraParallaxMouseInfluence () const
|
||||
{
|
||||
const double CScene::getCameraParallaxMouseInfluence () const {
|
||||
return this->m_cameraParallaxMouseInfluence;
|
||||
}
|
||||
|
||||
const bool CScene::isCameraPreview () const
|
||||
{
|
||||
const bool CScene::isCameraPreview () const {
|
||||
return this->m_cameraPreview;
|
||||
}
|
||||
|
||||
const bool CScene::isCameraShake () const
|
||||
{
|
||||
const bool CScene::isCameraShake () const {
|
||||
return this->m_cameraShake;
|
||||
}
|
||||
|
||||
const double CScene::getCameraShakeAmplitude () const
|
||||
{
|
||||
const double CScene::getCameraShakeAmplitude () const {
|
||||
return this->m_cameraShakeAmplitude;
|
||||
}
|
||||
|
||||
const double CScene::getCameraShakeRoughness () const
|
||||
{
|
||||
const double CScene::getCameraShakeRoughness () const {
|
||||
return this->m_cameraShakeRoughness;
|
||||
}
|
||||
|
||||
const double CScene::getCameraShakeSpeed () const
|
||||
{
|
||||
const double CScene::getCameraShakeSpeed () const {
|
||||
return this->m_cameraShakeSpeed;
|
||||
}
|
||||
|
||||
glm::vec3 CScene::getClearColor () const
|
||||
{
|
||||
glm::vec3 CScene::getClearColor () const {
|
||||
return this->m_clearColor->processValue (this->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
Scenes::CProjection* CScene::getOrthogonalProjection () const
|
||||
{
|
||||
Scenes::CProjection* CScene::getOrthogonalProjection () const {
|
||||
return this->m_orthogonalProjection;
|
||||
}
|
||||
|
||||
const glm::vec3& CScene::getSkylightColor () const
|
||||
{
|
||||
const glm::vec3& CScene::getSkylightColor () const {
|
||||
return this->m_skylightColor;
|
||||
}
|
||||
|
||||
|
@ -8,70 +8,53 @@
|
||||
#include "WallpaperEngine/Core/Scenes/CCamera.h"
|
||||
#include "WallpaperEngine/Core/Scenes/CProjection.h"
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
namespace WallpaperEngine::Core {
|
||||
using json = nlohmann::json;
|
||||
|
||||
class CObject;
|
||||
class CObject;
|
||||
|
||||
class CScene : public CWallpaper
|
||||
{
|
||||
class CScene : public CWallpaper {
|
||||
public:
|
||||
static CScene* fromFile (const std::string& filename, CProject& project, CContainer* container);
|
||||
|
||||
const std::map<uint32_t, CObject*>& getObjects () const;
|
||||
const std::vector<CObject*>& getObjectsByRenderOrder () const;
|
||||
|
||||
const glm::vec3& getAmbientColor() const;
|
||||
const bool isBloom() const;
|
||||
double getBloomStrength() const;
|
||||
double getBloomThreshold() const;
|
||||
const bool isCameraFade() const;
|
||||
const bool isCameraParallax() const;
|
||||
const double getCameraParallaxAmount() const;
|
||||
const double getCameraParallaxDelay() const;
|
||||
const double getCameraParallaxMouseInfluence() const;
|
||||
const bool isCameraPreview() const;
|
||||
const bool isCameraShake() const;
|
||||
const double getCameraShakeAmplitude() const;
|
||||
const double getCameraShakeRoughness() const;
|
||||
const double getCameraShakeSpeed() const;
|
||||
glm::vec3 getClearColor() const;
|
||||
Scenes::CProjection* getOrthogonalProjection() const;
|
||||
const glm::vec3& getSkylightColor() const;
|
||||
const glm::vec3& getAmbientColor () const;
|
||||
const bool isBloom () const;
|
||||
double getBloomStrength () const;
|
||||
double getBloomThreshold () const;
|
||||
const bool isCameraFade () const;
|
||||
const bool isCameraParallax () const;
|
||||
const double getCameraParallaxAmount () const;
|
||||
const double getCameraParallaxDelay () const;
|
||||
const double getCameraParallaxMouseInfluence () const;
|
||||
const bool isCameraPreview () const;
|
||||
const bool isCameraShake () const;
|
||||
const double getCameraShakeAmplitude () const;
|
||||
const double getCameraShakeRoughness () const;
|
||||
const double getCameraShakeSpeed () const;
|
||||
glm::vec3 getClearColor () const;
|
||||
Scenes::CProjection* getOrthogonalProjection () const;
|
||||
const glm::vec3& getSkylightColor () const;
|
||||
const Scenes::CCamera* getCamera () const;
|
||||
|
||||
protected:
|
||||
friend class CWallpaper;
|
||||
|
||||
CScene (
|
||||
CProject& project,
|
||||
CContainer* container,
|
||||
Scenes::CCamera* camera,
|
||||
glm::vec3 ambientColor,
|
||||
CUserSettingBoolean* bloom,
|
||||
CUserSettingFloat* bloomStrength,
|
||||
CUserSettingFloat* bloomThreshold,
|
||||
bool cameraFade,
|
||||
bool cameraParallax,
|
||||
double cameraParallaxAmount,
|
||||
double cameraParallaxDelay,
|
||||
double cameraParallaxMouseInfluence,
|
||||
bool cameraPreview,
|
||||
bool cameraShake,
|
||||
double cameraShakeAmplitude,
|
||||
double cameraShakeRoughness,
|
||||
double cameraShakeSpeed,
|
||||
CUserSettingVector3* clearColor,
|
||||
Scenes::CProjection* orthogonalProjection,
|
||||
glm::vec3 skylightColor
|
||||
);
|
||||
CScene (CProject& project, CContainer* container, Scenes::CCamera* camera, glm::vec3 ambientColor,
|
||||
CUserSettingBoolean* bloom, CUserSettingFloat* bloomStrength, CUserSettingFloat* bloomThreshold,
|
||||
bool cameraFade, bool cameraParallax, double cameraParallaxAmount, double cameraParallaxDelay,
|
||||
double cameraParallaxMouseInfluence, bool cameraPreview, bool cameraShake, double cameraShakeAmplitude,
|
||||
double cameraShakeRoughness, double cameraShakeSpeed, CUserSettingVector3* clearColor,
|
||||
Scenes::CProjection* orthogonalProjection, glm::vec3 skylightColor);
|
||||
|
||||
static const std::string Type;
|
||||
|
||||
void insertObject (CObject* object);
|
||||
|
||||
CContainer* getContainer ();
|
||||
|
||||
private:
|
||||
CContainer* m_container;
|
||||
Scenes::CCamera* m_camera;
|
||||
@ -97,5 +80,5 @@ namespace WallpaperEngine::Core
|
||||
|
||||
std::map<uint32_t, CObject*> m_objects;
|
||||
std::vector<CObject*> m_objectsByRenderOrder;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core
|
||||
|
@ -6,12 +6,9 @@ using namespace WallpaperEngine::Core;
|
||||
|
||||
CVideo::CVideo (std::string filename, CProject& project) :
|
||||
CWallpaper (Type, project),
|
||||
m_filename (std::move(filename))
|
||||
{
|
||||
}
|
||||
m_filename (std::move (filename)) {}
|
||||
|
||||
const std::string& CVideo::getFilename ()
|
||||
{
|
||||
const std::string& CVideo::getFilename () {
|
||||
return this->m_filename;
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "Core.h"
|
||||
#include "CWallpaper.h"
|
||||
#include "Core.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libswscale/swscale.h>
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
class CVideo : public CWallpaper
|
||||
{
|
||||
namespace WallpaperEngine::Core {
|
||||
class CVideo : public CWallpaper {
|
||||
public:
|
||||
explicit CVideo (std::string filename, CProject& project);
|
||||
|
||||
@ -26,7 +23,5 @@ namespace WallpaperEngine::Core
|
||||
const std::string m_filename;
|
||||
|
||||
static const std::string Type;
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core
|
||||
|
@ -4,13 +4,8 @@
|
||||
|
||||
using namespace WallpaperEngine::Core;
|
||||
|
||||
CWallpaper::CWallpaper (std::string type, CProject& project) :
|
||||
m_type (std::move(type)),
|
||||
m_project (project)
|
||||
{
|
||||
}
|
||||
CWallpaper::CWallpaper (std::string type, CProject& project) : m_type (std::move (type)), m_project (project) {}
|
||||
|
||||
CProject& CWallpaper::getProject () const
|
||||
{
|
||||
CProject& CWallpaper::getProject () const {
|
||||
return this->m_project;
|
||||
}
|
||||
|
@ -4,17 +4,24 @@
|
||||
|
||||
#include "CProject.h"
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
class CProject;
|
||||
namespace WallpaperEngine::Core {
|
||||
class CProject;
|
||||
|
||||
class CWallpaper
|
||||
{
|
||||
class CWallpaper {
|
||||
public:
|
||||
template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; }
|
||||
template<class T> T* as () { assert (is <T> ()); return (T*) this; }
|
||||
template <class T> const T* as () const {
|
||||
assert (is<T> ());
|
||||
return reinterpret_cast<const T*> (this);
|
||||
}
|
||||
|
||||
template<class T> bool is () { return this->m_type == T::Type; }
|
||||
template <class T> T* as () {
|
||||
assert (is<T> ());
|
||||
return reinterpret_cast<T*> (this);
|
||||
}
|
||||
|
||||
template <class T> bool is () {
|
||||
return this->m_type == T::Type;
|
||||
}
|
||||
|
||||
CWallpaper (std::string type, CProject& project);
|
||||
|
||||
@ -27,5 +34,5 @@ namespace WallpaperEngine::Core
|
||||
CProject& m_project;
|
||||
|
||||
std::string m_type;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core
|
||||
|
@ -9,78 +9,87 @@
|
||||
using namespace WallpaperEngine;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
|
||||
glm::vec4 Core::aToVector4 (const char* str)
|
||||
{
|
||||
float x = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++;
|
||||
float y = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++;
|
||||
float z = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++;
|
||||
float w = strtof (str, const_cast <char**> (&str));
|
||||
glm::vec4 Core::aToVector4 (const char* str) {
|
||||
float x = strtof (str, const_cast<char**> (&str));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
float y = strtof (str, const_cast<char**> (&str));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
float z = strtof (str, const_cast<char**> (&str));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
float w = strtof (str, const_cast<char**> (&str));
|
||||
|
||||
return {x, y, z, w};
|
||||
}
|
||||
|
||||
glm::vec3 Core::aToVector3 (const char* str)
|
||||
{
|
||||
float x = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++;
|
||||
float y = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++;
|
||||
float z = strtof (str, const_cast <char**> (&str));
|
||||
glm::vec3 Core::aToVector3 (const char* str) {
|
||||
float x = strtof (str, const_cast<char**> (&str));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
float y = strtof (str, const_cast<char**> (&str));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
float z = strtof (str, const_cast<char**> (&str));
|
||||
|
||||
return {x, y, z};
|
||||
}
|
||||
|
||||
glm::vec2 Core::aToVector2 (const char* str)
|
||||
{
|
||||
float x = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++;
|
||||
float y = strtof (str, const_cast <char**> (&str));
|
||||
glm::vec2 Core::aToVector2 (const char* str) {
|
||||
float x = strtof (str, const_cast<char**> (&str));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
float y = strtof (str, const_cast<char**> (&str));
|
||||
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
glm::vec4 Core::aToVector4 (const std::string& str)
|
||||
{
|
||||
glm::vec4 Core::aToVector4 (const std::string& str) {
|
||||
return Core::aToVector4 (str.c_str ());
|
||||
}
|
||||
|
||||
glm::vec3 Core::aToVector3 (const std::string& str)
|
||||
{
|
||||
glm::vec3 Core::aToVector3 (const std::string& str) {
|
||||
return Core::aToVector3 (str.c_str ());
|
||||
}
|
||||
|
||||
glm::vec2 Core::aToVector2 (const std::string& str)
|
||||
{
|
||||
glm::vec2 Core::aToVector2 (const std::string& str) {
|
||||
return Core::aToVector2 (str.c_str ());
|
||||
}
|
||||
|
||||
glm::vec3 Core::aToColorf (const char* str)
|
||||
{
|
||||
float r = strtof (str, const_cast<char **>(&str)); while (*str == ' ') str ++;
|
||||
float g = strtof (str, const_cast<char **>(&str)); while (*str == ' ') str ++;
|
||||
float b = strtof (str, const_cast<char **>(&str));
|
||||
glm::vec3 Core::aToColorf (const char* str) {
|
||||
float r = strtof (str, const_cast<char**> (&str));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
float g = strtof (str, const_cast<char**> (&str));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
float b = strtof (str, const_cast<char**> (&str));
|
||||
|
||||
return {r, g, b};
|
||||
}
|
||||
|
||||
glm::vec3 Core::aToColorf (const std::string& str)
|
||||
{
|
||||
glm::vec3 Core::aToColorf (const std::string& str) {
|
||||
return aToColorf (str.c_str ());
|
||||
}
|
||||
|
||||
glm::ivec3 Core::aToColori (const char* str)
|
||||
{
|
||||
auto r = static_cast <uint8_t> (strtol (str, const_cast<char **>(&str), 10)); while (*str == ' ') str ++;
|
||||
auto g = static_cast <uint8_t> (strtol (str, const_cast<char **>(&str), 10)); while (*str == ' ') str ++;
|
||||
auto b = static_cast <uint8_t> (strtol (str, const_cast<char **>(&str), 10));
|
||||
glm::ivec3 Core::aToColori (const char* str) {
|
||||
auto r = static_cast<uint8_t> (strtol (str, const_cast<char**> (&str), 10));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
auto g = static_cast<uint8_t> (strtol (str, const_cast<char**> (&str), 10));
|
||||
while (*str == ' ')
|
||||
str++;
|
||||
auto b = static_cast<uint8_t> (strtol (str, const_cast<char**> (&str), 10));
|
||||
|
||||
return {r, g, b};
|
||||
}
|
||||
|
||||
glm::ivec3 Core::aToColori (const std::string& str)
|
||||
{
|
||||
glm::ivec3 Core::aToColori (const std::string& str) {
|
||||
return aToColori (str.c_str ());
|
||||
}
|
||||
|
||||
nlohmann::json::iterator Core::jsonFindRequired (nlohmann::json& data, const char *key, const char *notFoundMsg)
|
||||
{
|
||||
nlohmann::json::iterator Core::jsonFindRequired (nlohmann::json& data, const char* key, const char* notFoundMsg) {
|
||||
auto value = data.find (key);
|
||||
|
||||
if (value == data.end ())
|
||||
@ -89,41 +98,34 @@ nlohmann::json::iterator Core::jsonFindRequired (nlohmann::json& data, const cha
|
||||
return value;
|
||||
}
|
||||
|
||||
nlohmann::json::iterator Core::jsonFindRequired (nlohmann::json::iterator& data, const char *key, const char *notFoundMsg)
|
||||
{
|
||||
auto value = (*data).find (key);
|
||||
nlohmann::json::iterator Core::jsonFindRequired (const nlohmann::json::iterator& data, const char* key,
|
||||
const char* notFoundMsg) {
|
||||
auto value = data->find (key);
|
||||
|
||||
if (value == (*data).end ())
|
||||
if (value == data->end ())
|
||||
sLog.exception ("Cannot find required key (", key, ") in json: ", notFoundMsg);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T> T Core::jsonFindDefault (nlohmann::json& data, const char *key, T defaultValue)
|
||||
{
|
||||
auto value = data.find (key);
|
||||
template <typename T> T Core::jsonFindDefault (nlohmann::json& data, const char* key, T defaultValue) {
|
||||
const auto value = data.find (key);
|
||||
|
||||
if (value == data.end () || value->type () == nlohmann::detail::value_t::null)
|
||||
return defaultValue;
|
||||
|
||||
// type checks
|
||||
if ((std::is_same <T, float>::value || std::is_same <T, double>::value))
|
||||
{
|
||||
if ((std::is_same_v<T, float> || std::is_same_v<T, double>) ) {
|
||||
if (value->type () != nlohmann::detail::value_t::number_float &&
|
||||
value->type () != nlohmann::detail::value_t::number_integer &&
|
||||
value->type () != nlohmann::detail::value_t::number_unsigned)
|
||||
{
|
||||
value->type () != nlohmann::detail::value_t::number_unsigned) {
|
||||
sLog.error (key, " is not of type double or integer, returning default value");
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
else if (std::is_same <T, std::string>::value && value->type () != nlohmann::detail::value_t::string)
|
||||
{
|
||||
} else if (std::is_same_v<T, std::string> && value->type () != nlohmann::detail::value_t::string) {
|
||||
sLog.error (key, " is not of type string, returning default value");
|
||||
return defaultValue;
|
||||
}
|
||||
else if (std::is_same <T, bool>::value && value->type () != nlohmann::detail::value_t::boolean)
|
||||
{
|
||||
} else if (std::is_same_v<T, bool> && value->type () != nlohmann::detail::value_t::boolean) {
|
||||
sLog.error (key, " is not of type boolean, returning default value");
|
||||
return defaultValue;
|
||||
}
|
||||
@ -133,20 +135,20 @@ template <typename T> T Core::jsonFindDefault (nlohmann::json& data, const char
|
||||
return *value;
|
||||
}
|
||||
|
||||
template bool Core::jsonFindDefault (nlohmann::json& data, const char *key, bool defaultValue);
|
||||
template std::string Core::jsonFindDefault (nlohmann::json& data, const char *key, std::string defaultValue);
|
||||
template int16_t Core::jsonFindDefault (nlohmann::json& data, const char *key, int16_t defaultValue);
|
||||
template uint16_t Core::jsonFindDefault (nlohmann::json& data, const char *key, uint16_t defaultValue);
|
||||
template int32_t Core::jsonFindDefault (nlohmann::json& data, const char *key, int32_t defaultValue);
|
||||
template uint32_t Core::jsonFindDefault (nlohmann::json& data, const char *key, uint32_t defaultValue);
|
||||
template int64_t Core::jsonFindDefault (nlohmann::json& data, const char *key, int64_t defaultValue);
|
||||
template uint64_t Core::jsonFindDefault (nlohmann::json& data, const char *key, uint64_t defaultValue);
|
||||
template float Core::jsonFindDefault (nlohmann::json& data, const char *key, float defaultValue);
|
||||
template double Core::jsonFindDefault (nlohmann::json& data, const char *key, double defaultValue);
|
||||
template bool Core::jsonFindDefault (nlohmann::json& data, const char* key, bool defaultValue);
|
||||
template std::string Core::jsonFindDefault (nlohmann::json& data, const char* key, std::string defaultValue);
|
||||
template int16_t Core::jsonFindDefault (nlohmann::json& data, const char* key, int16_t defaultValue);
|
||||
template uint16_t Core::jsonFindDefault (nlohmann::json& data, const char* key, uint16_t defaultValue);
|
||||
template int32_t Core::jsonFindDefault (nlohmann::json& data, const char* key, int32_t defaultValue);
|
||||
template uint32_t Core::jsonFindDefault (nlohmann::json& data, const char* key, uint32_t defaultValue);
|
||||
template int64_t Core::jsonFindDefault (nlohmann::json& data, const char* key, int64_t defaultValue);
|
||||
template uint64_t Core::jsonFindDefault (nlohmann::json& data, const char* key, uint64_t defaultValue);
|
||||
template float Core::jsonFindDefault (nlohmann::json& data, const char* key, float defaultValue);
|
||||
template double Core::jsonFindDefault (nlohmann::json& data, const char* key, double defaultValue);
|
||||
|
||||
template <typename T> T* Core::jsonFindUserConfig (nlohmann::json& data, const char *key, typename T::data_type defaultValue)
|
||||
{
|
||||
auto it = data.find (key);
|
||||
template <typename T>
|
||||
T* Core::jsonFindUserConfig (nlohmann::json& data, const char* key, typename T::data_type defaultValue) {
|
||||
const auto it = data.find (key);
|
||||
|
||||
if (it == data.end () || it->type () == nlohmann::detail::value_t::null)
|
||||
return T::fromScalar (defaultValue);
|
||||
@ -154,6 +156,9 @@ template <typename T> T* Core::jsonFindUserConfig (nlohmann::json& data, const c
|
||||
return T::fromJSON (*it);
|
||||
}
|
||||
|
||||
template CUserSettingBoolean* Core::jsonFindUserConfig (nlohmann::json& data, const char *key, CUserSettingBoolean::data_type defaultValue);
|
||||
template CUserSettingVector3* Core::jsonFindUserConfig (nlohmann::json& data, const char *key, CUserSettingVector3::data_type defaultValue);
|
||||
template CUserSettingFloat* Core::jsonFindUserConfig (nlohmann::json& data, const char *key, CUserSettingFloat::data_type defaultValue);
|
||||
template CUserSettingBoolean* Core::jsonFindUserConfig (nlohmann::json& data, const char* key,
|
||||
CUserSettingBoolean::data_type defaultValue);
|
||||
template CUserSettingVector3* Core::jsonFindUserConfig (nlohmann::json& data, const char* key,
|
||||
CUserSettingVector3::data_type defaultValue);
|
||||
template CUserSettingFloat* Core::jsonFindUserConfig (nlohmann::json& data, const char* key,
|
||||
CUserSettingFloat::data_type defaultValue);
|
@ -1,29 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/mat4x4.hpp>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
glm::vec4 aToVector4 (const char* str);
|
||||
glm::vec3 aToVector3 (const char* str);
|
||||
glm::vec2 aToVector2 (const char* str);
|
||||
namespace WallpaperEngine::Core {
|
||||
glm::vec4 aToVector4 (const char* str);
|
||||
glm::vec3 aToVector3 (const char* str);
|
||||
glm::vec2 aToVector2 (const char* str);
|
||||
|
||||
glm::vec4 aToVector4 (const std::string& str);
|
||||
glm::vec3 aToVector3 (const std::string& str);
|
||||
glm::vec2 aToVector2 (const std::string& str);
|
||||
glm::vec4 aToVector4 (const std::string& str);
|
||||
glm::vec3 aToVector3 (const std::string& str);
|
||||
glm::vec2 aToVector2 (const std::string& str);
|
||||
|
||||
glm::vec3 aToColorf (const char* str);
|
||||
glm::vec3 aToColorf (const std::string& str);
|
||||
glm::vec3 aToColorf (const char* str);
|
||||
glm::vec3 aToColorf (const std::string& str);
|
||||
|
||||
glm::ivec3 aToColori (const char* str);
|
||||
glm::ivec3 aToColori (const std::string& str);
|
||||
glm::ivec3 aToColori (const char* str);
|
||||
glm::ivec3 aToColori (const std::string& str);
|
||||
|
||||
nlohmann::json::iterator jsonFindRequired (nlohmann::json& data, const char *key, const char *notFoundMsg);
|
||||
nlohmann::json::iterator jsonFindRequired (nlohmann::json::iterator& data, const char *key, const char *notFoundMsg);
|
||||
template <typename T> T jsonFindDefault (nlohmann::json& data, const char *key, T defaultValue);
|
||||
template <typename T> T* jsonFindUserConfig (nlohmann::json& data, const char *key, typename T::data_type defaultValue);
|
||||
}
|
||||
nlohmann::json::iterator jsonFindRequired (nlohmann::json& data, const char* key, const char* notFoundMsg);
|
||||
nlohmann::json::iterator jsonFindRequired (const nlohmann::json::iterator& data, const char* key,
|
||||
const char* notFoundMsg);
|
||||
template <typename T> T jsonFindDefault (nlohmann::json& data, const char* key, T defaultValue);
|
||||
template <typename T> T* jsonFindUserConfig (nlohmann::json& data, const char* key, typename T::data_type defaultValue);
|
||||
} // namespace WallpaperEngine::Core
|
||||
|
@ -1,16 +1,16 @@
|
||||
#include "common.h"
|
||||
#include "CEffect.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#include "WallpaperEngine/Core/CScene.h"
|
||||
#include "WallpaperEngine/Core/CProject.h"
|
||||
#include "WallpaperEngine/Core/CScene.h"
|
||||
#include "WallpaperEngine/Core/Objects/CImage.h"
|
||||
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
|
||||
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h"
|
||||
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h"
|
||||
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h"
|
||||
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h"
|
||||
|
||||
#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
|
||||
|
||||
@ -20,45 +20,30 @@ using namespace WallpaperEngine;
|
||||
using namespace WallpaperEngine::Core::Objects;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
|
||||
CEffect::CEffect (
|
||||
std::string name,
|
||||
std::string description,
|
||||
std::string group,
|
||||
std::string preview,
|
||||
CObject* object,
|
||||
CUserSettingBoolean* visible):
|
||||
m_name (std::move(name)),
|
||||
m_description (std::move(description)),
|
||||
m_group (std::move(group)),
|
||||
m_preview (std::move(preview)),
|
||||
CEffect::CEffect (std::string name, std::string description, std::string group, std::string preview, CObject* object,
|
||||
CUserSettingBoolean* visible) :
|
||||
m_name (std::move (name)),
|
||||
m_description (std::move (description)),
|
||||
m_group (std::move (group)),
|
||||
m_preview (std::move (preview)),
|
||||
m_object (object),
|
||||
m_visible (visible)
|
||||
{
|
||||
}
|
||||
m_visible (visible) {}
|
||||
|
||||
CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, CObject* object, CContainer* container)
|
||||
{
|
||||
CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, CObject* object, CContainer* container) {
|
||||
auto file_it = jsonFindRequired (data, "file", "Object effect must have a file");
|
||||
auto effectpasses_it = data.find ("passes");
|
||||
|
||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*file_it).get <std::string> (), container));
|
||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (file_it->get<std::string> (), container));
|
||||
|
||||
auto name_it = jsonFindRequired (content, "name", "Effect must have a name");
|
||||
auto description = jsonFindDefault <std::string> (content, "description", "");
|
||||
auto description = jsonFindDefault<std::string> (content, "description", "");
|
||||
auto group_it = jsonFindRequired (content, "group", "Effect must have a group");
|
||||
auto preview = jsonFindDefault <std::string> (content, "preview", "");
|
||||
auto preview = jsonFindDefault<std::string> (content, "preview", "");
|
||||
auto passes_it = jsonFindRequired (content, "passes", "Effect must have a pass list");
|
||||
auto dependencies_it = jsonFindRequired (content, "dependencies", "");
|
||||
auto fbos_it = content.find ("fbos");
|
||||
|
||||
auto* effect = new CEffect (
|
||||
*name_it,
|
||||
description,
|
||||
*group_it,
|
||||
preview,
|
||||
object,
|
||||
visible
|
||||
);
|
||||
auto* effect = new CEffect (*name_it, description, *group_it, preview, object, visible);
|
||||
|
||||
CEffect::materialsFromJSON (passes_it, effect, container);
|
||||
CEffect::dependencyFromJSON (dependencies_it, effect);
|
||||
@ -66,47 +51,36 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, CObject* ob
|
||||
if (fbos_it != content.end ())
|
||||
CEffect::fbosFromJSON (fbos_it, effect);
|
||||
|
||||
if (effectpasses_it != data.end ())
|
||||
{
|
||||
auto cur = (*effectpasses_it).begin ();
|
||||
auto end = (*effectpasses_it).end ();
|
||||
if (effectpasses_it != data.end ()) {
|
||||
auto cur = effectpasses_it->begin ();
|
||||
auto end = effectpasses_it->end ();
|
||||
|
||||
for (int passNumber = 0; cur != end; cur ++, passNumber ++)
|
||||
{
|
||||
auto constants_it = (*cur).find ("constantshadervalues");
|
||||
auto combos_it = (*cur).find ("combos");
|
||||
auto textures_it = (*cur).find ("textures");
|
||||
for (int passNumber = 0; cur != end; ++cur, passNumber++) {
|
||||
auto constants_it = cur->find ("constantshadervalues");
|
||||
auto combos_it = cur->find ("combos");
|
||||
auto textures_it = cur->find ("textures");
|
||||
|
||||
if (constants_it == (*cur).end () && combos_it == (*cur).end () && textures_it == (*cur).end ())
|
||||
if (constants_it == cur->end () && combos_it == cur->end () && textures_it == cur->end ())
|
||||
continue;
|
||||
|
||||
Images::CMaterial* material = effect->getMaterials ().at (passNumber);
|
||||
|
||||
for (const auto& passCur : material->getPasses ())
|
||||
{
|
||||
if (textures_it != (*cur).end ())
|
||||
{
|
||||
for (const auto& passCur : material->getPasses ()) {
|
||||
if (textures_it != cur->end ()) {
|
||||
int textureNumber = 0;
|
||||
|
||||
for (const auto& texturesCur : (*textures_it))
|
||||
{
|
||||
for (const auto& texturesCur : (*textures_it)) {
|
||||
std::string texture;
|
||||
|
||||
if (texturesCur.is_null ())
|
||||
{
|
||||
if (textureNumber == 0)
|
||||
{
|
||||
auto* image = object->as <CImage> ();
|
||||
if (texturesCur.is_null ()) {
|
||||
if (textureNumber == 0) {
|
||||
auto* image = object->as<CImage> ();
|
||||
|
||||
texture = (*(*image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
texture = "";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
texture = texturesCur;
|
||||
}
|
||||
|
||||
@ -117,17 +91,15 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, CObject* ob
|
||||
else
|
||||
passCur->insertTexture (texture);
|
||||
|
||||
textureNumber ++;
|
||||
textureNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
if (combos_it != (*cur).end ())
|
||||
{
|
||||
if (combos_it != cur->end ()) {
|
||||
CEffect::combosFromJSON (combos_it, passCur);
|
||||
}
|
||||
|
||||
if (constants_it != (*cur).end ())
|
||||
{
|
||||
if (constants_it != cur->end ()) {
|
||||
CEffect::constantsFromJSON (constants_it, passCur);
|
||||
}
|
||||
}
|
||||
@ -137,16 +109,14 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, CObject* ob
|
||||
return effect;
|
||||
}
|
||||
|
||||
void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass)
|
||||
{
|
||||
for (const auto& cur : (*combos_it).items ())
|
||||
void CEffect::combosFromJSON (const json::const_iterator& combos_it, Core::Objects::Images::Materials::CPass* pass) {
|
||||
for (const auto& cur : combos_it->items ())
|
||||
pass->insertCombo (cur.key (), cur.value ());
|
||||
}
|
||||
|
||||
void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass)
|
||||
{
|
||||
for (auto& cur : (*constants_it).items ())
|
||||
{
|
||||
void CEffect::constantsFromJSON (const json::const_iterator& constants_it,
|
||||
Core::Objects::Images::Materials::CPass* pass) {
|
||||
for (auto& cur : constants_it->items ()) {
|
||||
auto val = cur.value ();
|
||||
|
||||
Effects::Constants::CShaderConstant* constant;
|
||||
@ -155,12 +125,10 @@ void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Object
|
||||
// for the UI, take the value, which is what we need
|
||||
|
||||
// TODO: SUPPORT USER SETTINGS HERE
|
||||
if (cur.value ().is_object ())
|
||||
{
|
||||
if (cur.value ().is_object ()) {
|
||||
auto it = cur.value ().find ("value");
|
||||
|
||||
if (it == cur.value ().end ())
|
||||
{
|
||||
if (it == cur.value ().end ()) {
|
||||
sLog.error ("Found object for shader constant without \"value\" member");
|
||||
continue;
|
||||
}
|
||||
@ -168,21 +136,14 @@ void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Object
|
||||
val = it.value ();
|
||||
}
|
||||
|
||||
if (val.is_number_float ())
|
||||
{
|
||||
constant = new Effects::Constants::CShaderConstantFloat (val.get <float> ());
|
||||
}
|
||||
else if (val.is_number_integer ())
|
||||
{
|
||||
constant = new Effects::Constants::CShaderConstantInteger (val.get <int> ());
|
||||
}
|
||||
else if (val.is_string ())
|
||||
{
|
||||
if (val.is_number_float ()) {
|
||||
constant = new Effects::Constants::CShaderConstantFloat (val.get<float> ());
|
||||
} else if (val.is_number_integer ()) {
|
||||
constant = new Effects::Constants::CShaderConstantInteger (val.get<int> ());
|
||||
} else if (val.is_string ()) {
|
||||
// try a vector 4 first, then a vector3 and then a vector 2
|
||||
constant = new Effects::Constants::CShaderConstantVector4 (WallpaperEngine::Core::aToVector4 (val));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
sLog.exception ("unknown shader constant type ", val);
|
||||
}
|
||||
|
||||
@ -190,22 +151,18 @@ void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Object
|
||||
}
|
||||
}
|
||||
|
||||
void CEffect::fbosFromJSON (json::const_iterator fbos_it, CEffect* effect)
|
||||
{
|
||||
void CEffect::fbosFromJSON (const json::const_iterator& fbos_it, CEffect* effect) {
|
||||
for (const auto& cur : (*fbos_it))
|
||||
effect->insertFBO (Effects::CFBO::fromJSON (cur));
|
||||
}
|
||||
|
||||
void CEffect::dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect)
|
||||
{
|
||||
void CEffect::dependencyFromJSON (const json::const_iterator& dependencies_it, CEffect* effect) {
|
||||
for (const auto& cur : (*dependencies_it))
|
||||
effect->insertDependency (cur);
|
||||
}
|
||||
|
||||
void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect, CContainer* container)
|
||||
{
|
||||
for (const auto& cur : (*passes_it))
|
||||
{
|
||||
void CEffect::materialsFromJSON (const json::const_iterator& passes_it, CEffect* effect, CContainer* container) {
|
||||
for (const auto& cur : (*passes_it)) {
|
||||
auto materialfile = cur.find ("material");
|
||||
auto target = cur.find ("target");
|
||||
auto bind = cur.find ("bind");
|
||||
@ -216,12 +173,11 @@ void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect
|
||||
Images::CMaterial* material;
|
||||
|
||||
if (target == cur.end ())
|
||||
material = Images::CMaterial::fromFile ((*materialfile).get <std::string> (), container);
|
||||
material = Images::CMaterial::fromFile (materialfile->get<std::string> (), container);
|
||||
else
|
||||
material = Images::CMaterial::fromFile ((*materialfile).get <std::string> (), *target, container);
|
||||
material = Images::CMaterial::fromFile (materialfile->get<std::string> (), *target, container);
|
||||
|
||||
if (bind != cur.end ())
|
||||
{
|
||||
if (bind != cur.end ()) {
|
||||
for (const auto& bindCur : (*bind))
|
||||
material->insertTextureBind (Effects::CBind::fromJSON (bindCur));
|
||||
}
|
||||
@ -230,28 +186,23 @@ void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<std::string>& CEffect::getDependencies () const
|
||||
{
|
||||
const std::vector<std::string>& CEffect::getDependencies () const {
|
||||
return this->m_dependencies;
|
||||
}
|
||||
|
||||
const std::vector<Images::CMaterial*>& CEffect::getMaterials () const
|
||||
{
|
||||
const std::vector<Images::CMaterial*>& CEffect::getMaterials () const {
|
||||
return this->m_materials;
|
||||
}
|
||||
|
||||
const std::vector<Effects::CFBO*>& CEffect::getFbos () const
|
||||
{
|
||||
const std::vector<Effects::CFBO*>& CEffect::getFbos () const {
|
||||
return this->m_fbos;
|
||||
}
|
||||
|
||||
bool CEffect::isVisible () const
|
||||
{
|
||||
bool CEffect::isVisible () const {
|
||||
return this->m_visible->processValue (this->m_object->getScene ()->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
Effects::CFBO* CEffect::findFBO (const std::string& name)
|
||||
{
|
||||
Effects::CFBO* CEffect::findFBO (const std::string& name) {
|
||||
for (const auto& cur : this->m_fbos)
|
||||
if (cur->getName () == name)
|
||||
return cur;
|
||||
@ -259,17 +210,14 @@ Effects::CFBO* CEffect::findFBO (const std::string& name)
|
||||
sLog.exception ("cannot find fbo ", name);
|
||||
}
|
||||
|
||||
void CEffect::insertDependency (const std::string& dep)
|
||||
{
|
||||
void CEffect::insertDependency (const std::string& dep) {
|
||||
this->m_dependencies.push_back (dep);
|
||||
}
|
||||
|
||||
void CEffect::insertMaterial (Images::CMaterial* material)
|
||||
{
|
||||
void CEffect::insertMaterial (Images::CMaterial* material) {
|
||||
this->m_materials.push_back (material);
|
||||
}
|
||||
|
||||
void CEffect::insertFBO (Effects::CFBO* fbo)
|
||||
{
|
||||
void CEffect::insertFBO (Effects::CFBO* fbo) {
|
||||
this->m_fbos.push_back (fbo);
|
||||
}
|
@ -1,44 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include "WallpaperEngine/Assets/CContainer.h"
|
||||
#include "WallpaperEngine/Core/CObject.h"
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
#include "WallpaperEngine/Core/Objects/Effects/CFBO.h"
|
||||
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
|
||||
#include "WallpaperEngine/Core/CObject.h"
|
||||
#include "WallpaperEngine/Core/Objects/Images/CMaterial.h"
|
||||
#include "WallpaperEngine/Assets/CContainer.h"
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
class CObject;
|
||||
namespace WallpaperEngine::Core {
|
||||
class CObject;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Core::UserSettings
|
||||
{
|
||||
class CUserSettingBoolean;
|
||||
namespace WallpaperEngine::Core::UserSettings {
|
||||
class CUserSettingBoolean;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Core::Objects
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
namespace WallpaperEngine::Core::Objects {
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Represents an effect applied to background objects
|
||||
*/
|
||||
class CEffect
|
||||
{
|
||||
class CEffect {
|
||||
public:
|
||||
CEffect (
|
||||
std::string name,
|
||||
std::string description,
|
||||
std::string group,
|
||||
std::string preview,
|
||||
CObject* object,
|
||||
CUserSettingBoolean* visible
|
||||
);
|
||||
CEffect (std::string name, std::string description, std::string group, std::string preview, CObject* object,
|
||||
CUserSettingBoolean* visible);
|
||||
|
||||
static CEffect* fromJSON (json data, UserSettings::CUserSettingBoolean* visible, CObject* object, CContainer* container);
|
||||
static CEffect* fromJSON (json data, UserSettings::CUserSettingBoolean* visible, CObject* object,
|
||||
CContainer* container);
|
||||
|
||||
/**
|
||||
* @return List of dependencies for the effect to work
|
||||
@ -64,12 +55,14 @@ namespace WallpaperEngine::Core::Objects
|
||||
* @return
|
||||
*/
|
||||
Effects::CFBO* findFBO (const std::string& name);
|
||||
|
||||
protected:
|
||||
static void constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass);
|
||||
static void combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass);
|
||||
static void fbosFromJSON (json::const_iterator fbos_it, CEffect* effect);
|
||||
static void dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect);
|
||||
static void materialsFromJSON (json::const_iterator passes_it, CEffect* effect, CContainer* container);
|
||||
static void constantsFromJSON (const json::const_iterator& constants_it,
|
||||
Core::Objects::Images::Materials::CPass* pass);
|
||||
static void combosFromJSON (const json::const_iterator& combos_it, Core::Objects::Images::Materials::CPass* pass);
|
||||
static void fbosFromJSON (const json::const_iterator& fbos_it, CEffect* effect);
|
||||
static void dependencyFromJSON (const json::const_iterator& dependencies_it, CEffect* effect);
|
||||
static void materialsFromJSON (const json::const_iterator& passes_it, CEffect* effect, CContainer* container);
|
||||
|
||||
void insertDependency (const std::string& dep);
|
||||
void insertMaterial (Images::CMaterial* material);
|
||||
@ -95,5 +88,5 @@ namespace WallpaperEngine::Core::Objects
|
||||
std::vector<Images::CMaterial*> m_materials;
|
||||
/** List of FBOs required for this effect */
|
||||
std::vector<Effects::CFBO*> m_fbos;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects
|
||||
|
@ -12,143 +12,91 @@
|
||||
using namespace WallpaperEngine::Core::Objects;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
|
||||
CImage::CImage (
|
||||
CScene* scene,
|
||||
Images::CMaterial* material,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale,
|
||||
const glm::vec3& angles,
|
||||
const glm::vec2& size,
|
||||
std::string alignment,
|
||||
CUserSettingVector3* color,
|
||||
CUserSettingFloat* alpha,
|
||||
float brightness,
|
||||
uint32_t colorBlendMode,
|
||||
const glm::vec2& parallaxDepth,
|
||||
bool fullscreen,
|
||||
bool passthrough,
|
||||
bool autosize
|
||||
) :
|
||||
CObject (scene, visible, id, std::move(name), Type, origin, scale, angles),
|
||||
CImage::CImage (CScene* scene, Images::CMaterial* material, CUserSettingBoolean* visible, uint32_t id, std::string name,
|
||||
CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles, const glm::vec2& size,
|
||||
std::string alignment, CUserSettingVector3* color, CUserSettingFloat* alpha, float brightness,
|
||||
uint32_t colorBlendMode, const glm::vec2& parallaxDepth, bool fullscreen, bool passthrough,
|
||||
bool autosize) :
|
||||
CObject (scene, visible, id, std::move (name), Type, origin, scale, angles),
|
||||
m_size (size),
|
||||
m_material (material),
|
||||
m_alignment (std::move(alignment)),
|
||||
m_alignment (std::move (alignment)),
|
||||
m_color (color),
|
||||
m_alpha (alpha),
|
||||
m_brightness (brightness),
|
||||
m_colorBlendMode (colorBlendMode),
|
||||
m_parallaxDepth(parallaxDepth),
|
||||
m_parallaxDepth (parallaxDepth),
|
||||
m_fullscreen (fullscreen),
|
||||
m_passthrough (passthrough),
|
||||
m_autosize (autosize)
|
||||
{
|
||||
m_autosize (autosize) {}
|
||||
|
||||
WallpaperEngine::Core::CObject* CImage::fromJSON (CScene* scene, json data, CContainer* container,
|
||||
CUserSettingBoolean* visible, uint32_t id, std::string name,
|
||||
CUserSettingVector3* origin, CUserSettingVector3* scale,
|
||||
const glm::vec3& angles) {
|
||||
const auto image_it = data.find ("image");
|
||||
const auto size_val = jsonFindDefault<std::string> (data, "size", "0.0 0.0"); // this one might need some adjustment
|
||||
const auto alignment = jsonFindDefault<std::string> (data, "alignment", "center");
|
||||
const auto alpha = jsonFindUserConfig<CUserSettingFloat> (data, "alpha", 1.0);
|
||||
const auto color = jsonFindUserConfig<CUserSettingVector3> (data, "color", {1, 1, 1});
|
||||
const auto brightness_val = jsonFindDefault<float> (data, "brightness", 1.0);
|
||||
const auto colorBlendMode_val = jsonFindDefault<uint32_t> (data, "colorBlendMode", 0);
|
||||
const auto parallaxDepth_val = jsonFindDefault<std::string> (data, "parallaxDepth", "0 0");
|
||||
|
||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile (image_it->get<std::string> (), container));
|
||||
|
||||
const auto material_it = jsonFindRequired (content, "material", "Image must have a material");
|
||||
const auto fullscreen = jsonFindDefault<bool> (content, "fullscreen", false);
|
||||
const auto passthrough = jsonFindDefault<bool> (content, "passthrough", false);
|
||||
const auto autosize = jsonFindDefault<bool> (content, "autosize", false);
|
||||
|
||||
return new CImage (scene, Images::CMaterial::fromFile (material_it->get<std::string> (), container), visible, id,
|
||||
std::move (name), origin, scale, angles, WallpaperEngine::Core::aToVector2 (size_val), alignment,
|
||||
color, alpha, brightness_val, colorBlendMode_val,
|
||||
WallpaperEngine::Core::aToVector2 (parallaxDepth_val), fullscreen, passthrough, autosize);
|
||||
}
|
||||
|
||||
WallpaperEngine::Core::CObject* CImage::fromJSON (
|
||||
CScene* scene,
|
||||
json data,
|
||||
CContainer* container,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale,
|
||||
const glm::vec3& angles)
|
||||
{
|
||||
auto image_it = data.find ("image");
|
||||
auto size_val = jsonFindDefault <std::string> (data, "size", "0.0 0.0"); // this one might need some adjustment
|
||||
auto alignment = jsonFindDefault <std::string> (data, "alignment", "center");
|
||||
auto alpha = jsonFindUserConfig <CUserSettingFloat> (data, "alpha", 1.0);
|
||||
auto color = jsonFindUserConfig <CUserSettingVector3> (data, "color", {1, 1, 1});
|
||||
auto brightness_val = jsonFindDefault <float> (data, "brightness", 1.0);
|
||||
auto colorBlendMode_val = jsonFindDefault <uint32_t> (data, "colorBlendMode", 0);
|
||||
auto parallaxDepth_val = jsonFindDefault <std::string> (data, "parallaxDepth", "0 0");
|
||||
|
||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*image_it).get <std::string> (), container));
|
||||
|
||||
auto material_it = jsonFindRequired (content, "material", "Image must have a material");
|
||||
auto fullscreen = jsonFindDefault <bool> (content, "fullscreen", false);
|
||||
auto passthrough = jsonFindDefault <bool> (content, "passthrough", false);
|
||||
auto autosize = jsonFindDefault <bool> (content, "autosize", false);
|
||||
|
||||
return new CImage (
|
||||
scene,
|
||||
Images::CMaterial::fromFile ((*material_it).get <std::string> (), container),
|
||||
visible,
|
||||
id,
|
||||
std::move(name),
|
||||
origin,
|
||||
scale,
|
||||
angles,
|
||||
WallpaperEngine::Core::aToVector2 (size_val),
|
||||
alignment,
|
||||
color,
|
||||
alpha,
|
||||
brightness_val,
|
||||
colorBlendMode_val,
|
||||
WallpaperEngine::Core::aToVector2 (parallaxDepth_val),
|
||||
fullscreen,
|
||||
passthrough,
|
||||
autosize
|
||||
);
|
||||
}
|
||||
|
||||
const Images::CMaterial* CImage::getMaterial () const
|
||||
{
|
||||
const Images::CMaterial* CImage::getMaterial () const {
|
||||
return this->m_material;
|
||||
}
|
||||
|
||||
const glm::vec2& CImage::getSize () const
|
||||
{
|
||||
const glm::vec2& CImage::getSize () const {
|
||||
return this->m_size;
|
||||
}
|
||||
|
||||
const std::string& CImage::getAlignment () const
|
||||
{
|
||||
const std::string& CImage::getAlignment () const {
|
||||
return this->m_alignment;
|
||||
}
|
||||
|
||||
float CImage::getAlpha () const
|
||||
{
|
||||
float CImage::getAlpha () const {
|
||||
return this->m_alpha->processValue (this->getScene ()->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
glm::vec3 CImage::getColor () const
|
||||
{
|
||||
glm::vec3 CImage::getColor () const {
|
||||
return this->m_color->processValue (this->getScene ()->getProject ().getProperties ());
|
||||
}
|
||||
|
||||
float CImage::getBrightness () const
|
||||
{
|
||||
float CImage::getBrightness () const {
|
||||
return this->m_brightness;
|
||||
}
|
||||
|
||||
uint32_t CImage::getColorBlendMode () const
|
||||
{
|
||||
uint32_t CImage::getColorBlendMode () const {
|
||||
return this->m_colorBlendMode;
|
||||
}
|
||||
|
||||
|
||||
const glm::vec2& CImage::getParallaxDepth () const
|
||||
{
|
||||
const glm::vec2& CImage::getParallaxDepth () const {
|
||||
return this->m_parallaxDepth;
|
||||
}
|
||||
|
||||
bool CImage::isFullscreen () const
|
||||
{
|
||||
bool CImage::isFullscreen () const {
|
||||
return this->m_fullscreen;
|
||||
}
|
||||
|
||||
bool CImage::isPassthrough () const
|
||||
{
|
||||
bool CImage::isPassthrough () const {
|
||||
return this->m_passthrough;
|
||||
}
|
||||
|
||||
bool CImage::isAutosize () const
|
||||
{
|
||||
bool CImage::isAutosize () const {
|
||||
return this->m_autosize;
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
#include "WallpaperEngine/Core/Objects/Images/CMaterial.h"
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
#include "WallpaperEngine/Core/CObject.h"
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
|
||||
#include "WallpaperEngine/Assets/CContainer.h"
|
||||
|
||||
@ -11,28 +11,25 @@
|
||||
#include "WallpaperEngine/Core/UserSettings/CUserSettingFloat.h"
|
||||
#include "WallpaperEngine/Core/UserSettings/CUserSettingVector3.h"
|
||||
|
||||
namespace WallpaperEngine::Core
|
||||
{
|
||||
class CScene;
|
||||
namespace WallpaperEngine::Core {
|
||||
class CScene;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Core::Objects
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
namespace WallpaperEngine::Core::Objects {
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Represents an image in a background
|
||||
*/
|
||||
class CImage : public CObject
|
||||
{
|
||||
class CImage : public CObject {
|
||||
friend class CObject;
|
||||
|
||||
public:
|
||||
static CObject* fromJSON (
|
||||
CScene* scene, json data, CContainer* container, CUserSettingBoolean* visible, uint32_t id,
|
||||
std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles
|
||||
);
|
||||
static CObject* fromJSON (CScene* scene, json data, CContainer* container, CUserSettingBoolean* visible,
|
||||
uint32_t id, std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale,
|
||||
const glm::vec3& angles);
|
||||
|
||||
/**
|
||||
* @return The base material to use for the image
|
||||
@ -80,12 +77,10 @@ namespace WallpaperEngine::Core::Objects
|
||||
[[nodiscard]] bool isAutosize () const;
|
||||
|
||||
protected:
|
||||
CImage (
|
||||
CScene* scene, Images::CMaterial* material, CUserSettingBoolean* visible, uint32_t id, std::string name,
|
||||
CImage (CScene* scene, Images::CMaterial* material, CUserSettingBoolean* visible, uint32_t id, std::string name,
|
||||
CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles, const glm::vec2& size,
|
||||
std::string alignment, CUserSettingVector3* color, CUserSettingFloat* alpha, float brightness,
|
||||
uint32_t colorBlendMode, const glm::vec2& parallaxDepth, bool fullscreen, bool passthrough, bool autosize
|
||||
);
|
||||
uint32_t colorBlendMode, const glm::vec2& parallaxDepth, bool fullscreen, bool passthrough, bool autosize);
|
||||
|
||||
/**
|
||||
* Type value used to differentiate the different types of objects in a background
|
||||
@ -115,5 +110,5 @@ namespace WallpaperEngine::Core::Objects
|
||||
bool m_passthrough;
|
||||
/** If the image's size should be automatically determined */
|
||||
bool m_autosize;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects
|
||||
|
@ -1,37 +1,21 @@
|
||||
#include "CParticle.h"
|
||||
|
||||
#include <utility>
|
||||
#include "WallpaperEngine/FileSystem/FileSystem.h"
|
||||
#include <utility>
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects;
|
||||
|
||||
CParticle* CParticle::fromFile (
|
||||
CScene* scene,
|
||||
const std::string& filename,
|
||||
CContainer* container,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale)
|
||||
{
|
||||
CParticle* CParticle::fromFile (CScene* scene, const std::string& filename, CContainer* container,
|
||||
CUserSettingBoolean* visible, uint32_t id, std::string name,
|
||||
CUserSettingVector3* origin, CUserSettingVector3* scale) {
|
||||
json data = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
|
||||
auto controlpoint_it = data.find ("controlpoint");
|
||||
auto starttime_it = jsonFindRequired (data, "starttime", "Particles must have start time");
|
||||
auto maxcount_it = jsonFindRequired (data, "maxcount", "Particles must have maximum count");
|
||||
auto emitter_it = jsonFindRequired (data, "emitter", "Particles must have emitters");
|
||||
auto initializer_it = jsonFindRequired (data, "initializer", "Particles must have initializers");
|
||||
const auto controlpoint_it = data.find ("controlpoint");
|
||||
const auto starttime_it = jsonFindRequired (data, "starttime", "Particles must have start time");
|
||||
const auto maxcount_it = jsonFindRequired (data, "maxcount", "Particles must have maximum count");
|
||||
const auto emitter_it = jsonFindRequired (data, "emitter", "Particles must have emitters");
|
||||
const auto initializer_it = jsonFindRequired (data, "initializer", "Particles must have initializers");
|
||||
|
||||
auto* particle = new CParticle (
|
||||
scene,
|
||||
*starttime_it,
|
||||
*maxcount_it,
|
||||
visible,
|
||||
id,
|
||||
std::move(name),
|
||||
origin,
|
||||
scale
|
||||
);
|
||||
auto* particle = new CParticle (scene, *starttime_it, *maxcount_it, visible, id, std::move (name), origin, scale);
|
||||
|
||||
if (controlpoint_it != data.end ())
|
||||
for (const auto& cur : (*controlpoint_it))
|
||||
@ -39,54 +23,39 @@ CParticle* CParticle::fromFile (
|
||||
|
||||
for (const auto& cur : (*emitter_it))
|
||||
particle->insertEmitter (Particles::CEmitter::fromJSON (cur));
|
||||
for (const auto&cur : (*initializer_it))
|
||||
for (const auto& cur : (*initializer_it))
|
||||
particle->insertInitializer (Particles::CInitializer::fromJSON (cur));
|
||||
|
||||
return particle;
|
||||
}
|
||||
|
||||
CParticle::CParticle (
|
||||
CScene* scene,
|
||||
uint32_t starttime,
|
||||
uint32_t maxcount,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale):
|
||||
CObject (scene, visible, id, std::move(name), Type, origin, scale, glm::vec3 ()),
|
||||
CParticle::CParticle (CScene* scene, uint32_t starttime, uint32_t maxcount, CUserSettingBoolean* visible, uint32_t id,
|
||||
std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale) :
|
||||
CObject (scene, visible, id, std::move (name), Type, origin, scale, glm::vec3 ()),
|
||||
m_starttime (starttime),
|
||||
m_maxcount (maxcount)
|
||||
{
|
||||
}
|
||||
m_maxcount (maxcount) {}
|
||||
|
||||
const std::vector<Particles::CEmitter*>& CParticle::getEmitters () const
|
||||
{
|
||||
const std::vector<Particles::CEmitter*>& CParticle::getEmitters () const {
|
||||
return this->m_emitters;
|
||||
}
|
||||
|
||||
const std::vector<Particles::CControlPoint*>& CParticle::getControlPoints () const
|
||||
{
|
||||
const std::vector<Particles::CControlPoint*>& CParticle::getControlPoints () const {
|
||||
return this->m_controlpoints;
|
||||
}
|
||||
|
||||
const std::vector<Particles::CInitializer*>& CParticle::getInitializers () const
|
||||
{
|
||||
const std::vector<Particles::CInitializer*>& CParticle::getInitializers () const {
|
||||
return this->m_initializers;
|
||||
}
|
||||
|
||||
void CParticle::insertControlPoint (Particles::CControlPoint* controlpoint)
|
||||
{
|
||||
void CParticle::insertControlPoint (Particles::CControlPoint* controlpoint) {
|
||||
this->m_controlpoints.push_back (controlpoint);
|
||||
}
|
||||
|
||||
void CParticle::insertEmitter (Particles::CEmitter* emitter)
|
||||
{
|
||||
void CParticle::insertEmitter (Particles::CEmitter* emitter) {
|
||||
this->m_emitters.push_back (emitter);
|
||||
}
|
||||
|
||||
void CParticle::insertInitializer (Particles::CInitializer* initializer)
|
||||
{
|
||||
void CParticle::insertInitializer (Particles::CInitializer* initializer) {
|
||||
this->m_initializers.push_back (initializer);
|
||||
}
|
||||
|
||||
|
@ -4,31 +4,22 @@
|
||||
#include "WallpaperEngine/Core/Objects/Particles/CEmitter.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.h"
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
#include "WallpaperEngine/Core/CObject.h"
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
namespace WallpaperEngine::Core::Objects {
|
||||
using json = nlohmann::json;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Represents a particle system in the background
|
||||
*/
|
||||
class CParticle : public CObject
|
||||
{
|
||||
class CParticle : public CObject {
|
||||
friend class CObject;
|
||||
|
||||
public:
|
||||
static CParticle* fromFile (
|
||||
CScene* scene,
|
||||
const std::string& filename,
|
||||
CContainer* container,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale
|
||||
);
|
||||
static CParticle* fromFile (CScene* scene, const std::string& filename, CContainer* container,
|
||||
CUserSettingBoolean* visible, uint32_t id, std::string name,
|
||||
CUserSettingVector3* origin, CUserSettingVector3* scale);
|
||||
|
||||
/**
|
||||
* @return The list of emitters for the particle system
|
||||
@ -44,16 +35,8 @@ namespace WallpaperEngine::Core::Objects
|
||||
[[nodiscard]] const std::vector<Particles::CInitializer*>& getInitializers () const;
|
||||
|
||||
protected:
|
||||
CParticle (
|
||||
CScene* scene,
|
||||
uint32_t starttime,
|
||||
uint32_t maxcount,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale
|
||||
);
|
||||
CParticle (CScene* scene, uint32_t starttime, uint32_t maxcount, CUserSettingBoolean* visible, uint32_t id,
|
||||
std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale);
|
||||
|
||||
/**
|
||||
* @param controlpoint The control point to add to the particle system
|
||||
@ -84,5 +67,5 @@ namespace WallpaperEngine::Core::Objects
|
||||
std::vector<Particles::CEmitter*> m_emitters;
|
||||
/** List of initializers */
|
||||
std::vector<Particles::CInitializer*> m_initializers;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects
|
||||
|
@ -1,55 +1,29 @@
|
||||
#include "common.h"
|
||||
#include "WallpaperEngine/Core/CObject.h"
|
||||
#include "CSound.h"
|
||||
#include "WallpaperEngine/Core/CObject.h"
|
||||
#include "common.h"
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects;
|
||||
|
||||
CSound::CSound (
|
||||
CScene* scene,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale,
|
||||
const glm::vec3& angles,
|
||||
bool repeat
|
||||
) :
|
||||
CObject (scene, visible, id, std::move(name), Type, origin, scale, angles),
|
||||
m_repeat (repeat)
|
||||
{
|
||||
}
|
||||
CSound::CSound (CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name, CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale, const glm::vec3& angles, bool repeat) :
|
||||
CObject (scene, visible, id, std::move (name), Type, origin, scale, angles),
|
||||
m_repeat (repeat) {}
|
||||
|
||||
WallpaperEngine::Core::CObject* CSound::fromJSON (
|
||||
CScene* scene,
|
||||
json data,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
const std::string& name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale,
|
||||
const glm::vec3& angles)
|
||||
{
|
||||
WallpaperEngine::Core::CObject* CSound::fromJSON (CScene* scene, json data, CUserSettingBoolean* visible, uint32_t id,
|
||||
const std::string& name, CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale, const glm::vec3& angles) {
|
||||
bool repeat = false;
|
||||
// TODO: PARSE AUDIO VOLUME
|
||||
auto sound_it = jsonFindRequired (data, "sound", "Sound information not present");
|
||||
auto playbackmode = jsonFindDefault <std::string> (data, "playbackmode", "");
|
||||
const auto sound_it = jsonFindRequired (data, "sound", "Sound information not present");
|
||||
const auto playbackmode = jsonFindDefault<std::string> (data, "playbackmode", "");
|
||||
|
||||
if (playbackmode == "loop")
|
||||
repeat = true;
|
||||
|
||||
if (!(*sound_it).is_array ())
|
||||
if (!sound_it->is_array ())
|
||||
sLog.exception ("Expected sound list on element ", name);
|
||||
|
||||
auto* sound = new CSound (
|
||||
scene,
|
||||
visible,
|
||||
id,
|
||||
name,
|
||||
origin,
|
||||
scale,
|
||||
angles,
|
||||
repeat
|
||||
);
|
||||
auto* sound = new CSound (scene, visible, id, name, origin, scale, angles, repeat);
|
||||
|
||||
for (const auto& cur : (*sound_it))
|
||||
sound->insertSound (cur);
|
||||
@ -57,17 +31,15 @@ WallpaperEngine::Core::CObject* CSound::fromJSON (
|
||||
return sound;
|
||||
}
|
||||
|
||||
void CSound::insertSound (const std::string& filename)
|
||||
{
|
||||
void CSound::insertSound (const std::string& filename) {
|
||||
this->m_sounds.push_back (filename);
|
||||
}
|
||||
|
||||
const std::vector<std::string>& CSound::getSounds () const
|
||||
{
|
||||
const std::vector<std::string>& CSound::getSounds () const {
|
||||
return this->m_sounds;
|
||||
}
|
||||
bool CSound::isRepeat () const
|
||||
{
|
||||
|
||||
bool CSound::isRepeat () const {
|
||||
return this->m_repeat;
|
||||
}
|
||||
|
||||
|
@ -1,32 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
#include "WallpaperEngine/Core/CObject.h"
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
namespace WallpaperEngine::Core::Objects {
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Core::UserSettings;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Represents a sound played while the background is working
|
||||
*/
|
||||
class CSound : public CObject
|
||||
{
|
||||
class CSound : public CObject {
|
||||
friend class CObject;
|
||||
|
||||
public:
|
||||
static CObject* fromJSON (
|
||||
CScene* scene,
|
||||
json data,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
const std::string& name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale,
|
||||
const glm::vec3& angles
|
||||
);
|
||||
static CObject* fromJSON (CScene* scene, json data, CUserSettingBoolean* visible, uint32_t id,
|
||||
const std::string& name, CUserSettingVector3* origin, CUserSettingVector3* scale,
|
||||
const glm::vec3& angles);
|
||||
|
||||
/**
|
||||
* @return The list of sounds to play
|
||||
@ -38,16 +29,8 @@ namespace WallpaperEngine::Core::Objects
|
||||
[[nodiscard]] bool isRepeat () const;
|
||||
|
||||
protected:
|
||||
CSound (
|
||||
CScene* scene,
|
||||
CUserSettingBoolean* visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale,
|
||||
const glm::vec3& angles,
|
||||
bool repeat
|
||||
);
|
||||
CSound (CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name, CUserSettingVector3* origin,
|
||||
CUserSettingVector3* scale, const glm::vec3& angles, bool repeat);
|
||||
|
||||
/**
|
||||
* @param filename The sound to add
|
||||
@ -64,5 +47,5 @@ namespace WallpaperEngine::Core::Objects
|
||||
bool m_repeat;
|
||||
/** The list of sounds to play */
|
||||
std::vector<std::string> m_sounds;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects
|
||||
|
@ -4,26 +4,19 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Effects;
|
||||
|
||||
CBind::CBind (std::string name, uint32_t index) :
|
||||
m_name (std::move(name)),
|
||||
m_index (index)
|
||||
{
|
||||
}
|
||||
CBind::CBind (std::string name, uint32_t index) : m_name (std::move (name)), m_index (index) {}
|
||||
|
||||
CBind* CBind::fromJSON (json data)
|
||||
{
|
||||
auto name_it = jsonFindRequired (data, "name", "bind must have texture name");
|
||||
auto index_it = jsonFindRequired (data, "index", "bind must have index");
|
||||
CBind* CBind::fromJSON (json data) {
|
||||
const auto name_it = jsonFindRequired (data, "name", "bind must have texture name");
|
||||
const auto index_it = jsonFindRequired (data, "index", "bind must have index");
|
||||
|
||||
return new CBind (*name_it, *index_it);
|
||||
}
|
||||
|
||||
const std::string& CBind::getName () const
|
||||
{
|
||||
const std::string& CBind::getName () const {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
const uint32_t& CBind::getIndex () const
|
||||
{
|
||||
const uint32_t& CBind::getIndex () const {
|
||||
return this->m_index;
|
||||
}
|
@ -4,17 +4,15 @@
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Effects
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
namespace WallpaperEngine::Core::Objects::Effects {
|
||||
using json = nlohmann::json;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Material's bind information, describes for passes what textures to bind
|
||||
* in what positions for shaders. Used to override the textures specified inside
|
||||
* the object's passes
|
||||
*/
|
||||
class CBind
|
||||
{
|
||||
class CBind {
|
||||
public:
|
||||
/**
|
||||
* Parses bind information off the given json data
|
||||
@ -40,5 +38,5 @@ namespace WallpaperEngine::Core::Objects::Effects
|
||||
std::string m_name;
|
||||
/** The texture index to replace */
|
||||
uint32_t m_index;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Effects
|
||||
|
@ -6,36 +6,26 @@ using namespace WallpaperEngine::Core;
|
||||
using namespace WallpaperEngine::Core::Objects::Effects;
|
||||
|
||||
CFBO::CFBO (std::string name, float scale, std::string format) :
|
||||
m_name (std::move(name)),
|
||||
m_name (std::move (name)),
|
||||
m_scale (scale),
|
||||
m_format(std::move(format))
|
||||
{
|
||||
m_format (std::move (format)) {}
|
||||
|
||||
CFBO* CFBO::fromJSON (json data) {
|
||||
const auto name_it = jsonFindRequired (data, "name", "Name for an FBO is required");
|
||||
const auto scale = jsonFindDefault<float> (data, "scale", 1.0);
|
||||
const auto format = jsonFindDefault<std::string> (data, "format", "");
|
||||
|
||||
return new CFBO (*name_it, scale, format);
|
||||
}
|
||||
|
||||
CFBO* CFBO::fromJSON (json data)
|
||||
{
|
||||
auto name_it = jsonFindRequired (data, "name", "Name for an FBO is required");
|
||||
auto scale = jsonFindDefault <float> (data, "scale", 1.0);
|
||||
auto format = jsonFindDefault <std::string> (data, "format", "");
|
||||
|
||||
return new CFBO (
|
||||
*name_it,
|
||||
scale,
|
||||
format
|
||||
);
|
||||
}
|
||||
|
||||
const std::string& CFBO::getName () const
|
||||
{
|
||||
const std::string& CFBO::getName () const {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
const float& CFBO::getScale () const
|
||||
{
|
||||
const float& CFBO::getScale () const {
|
||||
return this->m_scale;
|
||||
}
|
||||
|
||||
const std::string& CFBO::getFormat () const
|
||||
{
|
||||
const std::string& CFBO::getFormat () const {
|
||||
return this->m_format;
|
||||
}
|
@ -5,17 +5,15 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Effects
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
namespace WallpaperEngine::Core::Objects::Effects {
|
||||
using json = nlohmann::json;
|
||||
|
||||
/**
|
||||
/**
|
||||
* FBO = Frame Buffer Object
|
||||
*
|
||||
* Represents a framebuffer object used in objects with multiple effects or render passes
|
||||
*/
|
||||
class CFBO
|
||||
{
|
||||
class CFBO {
|
||||
public:
|
||||
CFBO (std::string name, float scale, std::string format);
|
||||
|
||||
@ -41,5 +39,5 @@ namespace WallpaperEngine::Core::Objects::Effects
|
||||
float m_scale;
|
||||
/** The FBO's format for the render */
|
||||
std::string m_format;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Effects
|
@ -2,12 +2,8 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
|
||||
|
||||
CShaderConstant::CShaderConstant (std::string type) :
|
||||
m_type (std::move(type))
|
||||
{
|
||||
}
|
||||
CShaderConstant::CShaderConstant (std::string type) : m_type (std::move (type)) {}
|
||||
|
||||
const std::string& CShaderConstant::getType () const
|
||||
{
|
||||
const std::string& CShaderConstant::getType () const {
|
||||
return this->m_type;
|
||||
}
|
||||
|
@ -2,20 +2,27 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants {
|
||||
/**
|
||||
* Shader constants base class
|
||||
*/
|
||||
class CShaderConstant
|
||||
{
|
||||
class CShaderConstant {
|
||||
public:
|
||||
explicit CShaderConstant (std::string type);
|
||||
|
||||
template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; }
|
||||
template<class T> T* as () { assert (is <T> ()); return (T*) this; }
|
||||
template <class T> const T* as () const {
|
||||
assert (is<T> ());
|
||||
return reinterpret_cast<const T*> (this);
|
||||
}
|
||||
|
||||
template<class T> bool is () { return this->m_type == T::Type; }
|
||||
template <class T> T* as () {
|
||||
assert (is<T> ());
|
||||
return reinterpret_cast<T*> (this);
|
||||
}
|
||||
|
||||
template <class T> bool is () {
|
||||
return this->m_type == T::Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The type name of this constant
|
||||
@ -24,5 +31,5 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
|
||||
private:
|
||||
std::string m_type;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
|
@ -2,14 +2,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
|
||||
|
||||
CShaderConstantFloat::CShaderConstantFloat (float value) :
|
||||
CShaderConstant (Type),
|
||||
m_value (value)
|
||||
{
|
||||
}
|
||||
CShaderConstantFloat::CShaderConstantFloat (float value) : CShaderConstant (Type), m_value (value) {}
|
||||
|
||||
float* CShaderConstantFloat::getValue ()
|
||||
{
|
||||
float* CShaderConstantFloat::getValue () {
|
||||
return &this->m_value;
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,11 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants {
|
||||
/**
|
||||
* Shader constant of type float
|
||||
*/
|
||||
class CShaderConstantFloat : public CShaderConstant
|
||||
{
|
||||
class CShaderConstantFloat : public CShaderConstant {
|
||||
public:
|
||||
explicit CShaderConstantFloat (float value);
|
||||
|
||||
@ -23,8 +21,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
* Type string indicator
|
||||
*/
|
||||
static const std::string Type;
|
||||
|
||||
protected:
|
||||
/** The constant's value */
|
||||
float m_value;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
|
@ -2,14 +2,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
|
||||
|
||||
CShaderConstantInteger::CShaderConstantInteger (int32_t value) :
|
||||
CShaderConstant (Type),
|
||||
m_value (value)
|
||||
{
|
||||
}
|
||||
CShaderConstantInteger::CShaderConstantInteger (int32_t value) : CShaderConstant (Type), m_value (value) {}
|
||||
|
||||
int32_t* CShaderConstantInteger::getValue ()
|
||||
{
|
||||
int32_t* CShaderConstantInteger::getValue () {
|
||||
return &this->m_value;
|
||||
}
|
||||
|
||||
|
@ -4,13 +4,11 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants {
|
||||
/**
|
||||
* Shader constant of type integer
|
||||
*/
|
||||
class CShaderConstantInteger : public CShaderConstant
|
||||
{
|
||||
class CShaderConstantInteger : public CShaderConstant {
|
||||
public:
|
||||
explicit CShaderConstantInteger (int32_t value);
|
||||
|
||||
@ -23,8 +21,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
* Type string indicator
|
||||
*/
|
||||
static const std::string Type;
|
||||
|
||||
protected:
|
||||
/** The constant's value */
|
||||
int32_t m_value;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
|
@ -2,15 +2,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
|
||||
|
||||
CShaderConstantVector2::CShaderConstantVector2 (glm::vec2 value) : CShaderConstant (Type), m_value (value) {}
|
||||
|
||||
CShaderConstantVector2::CShaderConstantVector2 (glm::vec2 value) :
|
||||
CShaderConstant (Type),
|
||||
m_value (value)
|
||||
{
|
||||
}
|
||||
|
||||
glm::vec2* CShaderConstantVector2::getValue ()
|
||||
{
|
||||
glm::vec2* CShaderConstantVector2::getValue () {
|
||||
return &this->m_value;
|
||||
}
|
||||
|
||||
|
@ -2,17 +2,15 @@
|
||||
|
||||
#include "CShaderConstant.h"
|
||||
|
||||
#include <string>
|
||||
#include <glm/vec2.hpp>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants {
|
||||
/**
|
||||
* Shader constant of vector2 type
|
||||
*/
|
||||
class CShaderConstantVector2 : public CShaderConstant
|
||||
{
|
||||
class CShaderConstantVector2 : public CShaderConstant {
|
||||
public:
|
||||
explicit CShaderConstantVector2 (glm::vec2 value);
|
||||
|
||||
@ -25,8 +23,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
* Type string indicator
|
||||
*/
|
||||
static const std::string Type;
|
||||
|
||||
protected:
|
||||
/** The constant's value */
|
||||
glm::vec2 m_value;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
|
@ -2,14 +2,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
|
||||
|
||||
CShaderConstantVector3::CShaderConstantVector3 (glm::vec3 value) :
|
||||
CShaderConstant (Type),
|
||||
m_value (value)
|
||||
{
|
||||
}
|
||||
CShaderConstantVector3::CShaderConstantVector3 (glm::vec3 value) : CShaderConstant (Type), m_value (value) {}
|
||||
|
||||
glm::vec3* CShaderConstantVector3::getValue ()
|
||||
{
|
||||
glm::vec3* CShaderConstantVector3::getValue () {
|
||||
return &this->m_value;
|
||||
}
|
||||
|
||||
|
@ -2,16 +2,14 @@
|
||||
|
||||
#include "CShaderConstant.h"
|
||||
|
||||
#include <string>
|
||||
#include <glm/vec3.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants {
|
||||
/**
|
||||
* Shader constant of vector3 type
|
||||
*/
|
||||
class CShaderConstantVector3 : public CShaderConstant
|
||||
{
|
||||
class CShaderConstantVector3 : public CShaderConstant {
|
||||
public:
|
||||
explicit CShaderConstantVector3 (glm::vec3 value);
|
||||
|
||||
@ -24,8 +22,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
* Type string indicator
|
||||
*/
|
||||
static const std::string Type;
|
||||
|
||||
protected:
|
||||
/** The constant's value */
|
||||
glm::vec3 m_value;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
|
@ -2,15 +2,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
|
||||
|
||||
CShaderConstantVector4::CShaderConstantVector4 (glm::vec4 value) : CShaderConstant (Type), m_value (value) {}
|
||||
|
||||
CShaderConstantVector4::CShaderConstantVector4 (glm::vec4 value) :
|
||||
CShaderConstant (Type),
|
||||
m_value (value)
|
||||
{
|
||||
}
|
||||
|
||||
glm::vec4* CShaderConstantVector4::getValue ()
|
||||
{
|
||||
glm::vec4* CShaderConstantVector4::getValue () {
|
||||
return &this->m_value;
|
||||
}
|
||||
|
||||
|
@ -2,16 +2,14 @@
|
||||
|
||||
#include "CShaderConstant.h"
|
||||
|
||||
#include <string>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Effects::Constants {
|
||||
/**
|
||||
* Shader constant of vector4 type
|
||||
*/
|
||||
class CShaderConstantVector4 : public CShaderConstant
|
||||
{
|
||||
class CShaderConstantVector4 : public CShaderConstant {
|
||||
public:
|
||||
explicit CShaderConstantVector4 (glm::vec4 value);
|
||||
|
||||
@ -24,8 +22,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
* Type string indicator
|
||||
*/
|
||||
static const std::string Type;
|
||||
|
||||
protected:
|
||||
/** The constant's value */
|
||||
glm::vec4 m_value;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Effects::Constants
|
||||
|
@ -10,37 +10,26 @@ using namespace WallpaperEngine::Assets;
|
||||
using namespace WallpaperEngine::Core::Objects;
|
||||
using namespace WallpaperEngine::Core::Objects::Images;
|
||||
|
||||
CMaterial::CMaterial (std::string name) :
|
||||
m_target (),
|
||||
m_name (std::move(name))
|
||||
{
|
||||
CMaterial::CMaterial (std::string name) : m_name (std::move (name)) {}
|
||||
|
||||
CMaterial* CMaterial::fromFile (const std::string& filename, CContainer* container) {
|
||||
return fromJSON (filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)));
|
||||
}
|
||||
|
||||
CMaterial* CMaterial::fromFile (const std::string& filename, CContainer* container)
|
||||
{
|
||||
return fromJSON (
|
||||
filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container))
|
||||
);
|
||||
}
|
||||
CMaterial* CMaterial::fromFile (const std::string& filename, const std::string& target, CContainer* container)
|
||||
{
|
||||
return fromJSON (
|
||||
filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)), target
|
||||
);
|
||||
CMaterial* CMaterial::fromFile (const std::string& filename, const std::string& target, CContainer* container) {
|
||||
return fromJSON (filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)), target);
|
||||
}
|
||||
|
||||
CMaterial* CMaterial::fromJSON (const std::string& name, json data, const std::string& target)
|
||||
{
|
||||
CMaterial* material = fromJSON (name, std::move(data));
|
||||
CMaterial* CMaterial::fromJSON (const std::string& name, json data, const std::string& target) {
|
||||
CMaterial* material = fromJSON (name, std::move (data));
|
||||
|
||||
material->setTarget (target);
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
CMaterial* CMaterial::fromJSON (const std::string& name, json data)
|
||||
{
|
||||
auto passes_it = jsonFindRequired (data, "passes", "Material must have at least one pass");
|
||||
CMaterial* CMaterial::fromJSON (const std::string& name, json data) {
|
||||
const auto passes_it = jsonFindRequired (data, "passes", "Material must have at least one pass");
|
||||
|
||||
auto* material = new CMaterial (name);
|
||||
|
||||
@ -50,41 +39,34 @@ CMaterial* CMaterial::fromJSON (const std::string& name, json data)
|
||||
return material;
|
||||
}
|
||||
|
||||
void CMaterial::insertPass (Materials::CPass* mass)
|
||||
{
|
||||
this->m_passes.push_back (mass);
|
||||
void CMaterial::insertPass (Materials::CPass* pass) {
|
||||
this->m_passes.push_back (pass);
|
||||
}
|
||||
|
||||
void CMaterial::insertTextureBind (Effects::CBind* bind)
|
||||
{
|
||||
void CMaterial::insertTextureBind (Effects::CBind* bind) {
|
||||
this->m_textureBindings.insert (std::make_pair (bind->getIndex (), bind));
|
||||
}
|
||||
|
||||
void CMaterial::setTarget (const std::string& target)
|
||||
{
|
||||
void CMaterial::setTarget (const std::string& target) {
|
||||
this->m_target = target;
|
||||
}
|
||||
|
||||
const std::vector <Materials::CPass*>& CMaterial::getPasses () const
|
||||
{
|
||||
const std::vector<Materials::CPass*>& CMaterial::getPasses () const {
|
||||
return this->m_passes;
|
||||
}
|
||||
const std::map <int, Effects::CBind*>& CMaterial::getTextureBinds () const
|
||||
{
|
||||
|
||||
const std::map<int, Effects::CBind*>& CMaterial::getTextureBinds () const {
|
||||
return this->m_textureBindings;
|
||||
}
|
||||
|
||||
const std::string& CMaterial::getTarget () const
|
||||
{
|
||||
const std::string& CMaterial::getTarget () const {
|
||||
return this->m_target;
|
||||
}
|
||||
|
||||
const std::string& CMaterial::getName () const
|
||||
{
|
||||
const std::string& CMaterial::getName () const {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
bool CMaterial::hasTarget () const
|
||||
{
|
||||
bool CMaterial::hasTarget () const {
|
||||
return !this->m_target.empty ();
|
||||
}
|
@ -1,21 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "WallpaperEngine/Core/Objects/Images/Materials/CPass.h"
|
||||
#include "WallpaperEngine/Core/Objects/Effects/CBind.h"
|
||||
#include "WallpaperEngine/Core/Objects/Images/Materials/CPass.h"
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
#include "WallpaperEngine/Assets/CContainer.h"
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Images
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
namespace WallpaperEngine::Core::Objects::Images {
|
||||
using json = nlohmann::json;
|
||||
using namespace WallpaperEngine::Assets;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Represents a material in use in the background
|
||||
*/
|
||||
class CMaterial
|
||||
{
|
||||
class CMaterial {
|
||||
public:
|
||||
static CMaterial* fromFile (const std::string& filename, Assets::CContainer* container);
|
||||
static CMaterial* fromJSON (const std::string& name, json data);
|
||||
@ -34,12 +32,12 @@ namespace WallpaperEngine::Core::Objects::Images
|
||||
/**
|
||||
* @return All the rendering passes that happen for this material
|
||||
*/
|
||||
[[nodiscard]] const std::vector <Materials::CPass*>& getPasses () const;
|
||||
[[nodiscard]] const std::vector<Materials::CPass*>& getPasses () const;
|
||||
/**
|
||||
* @return The textures that have to be bound while rendering the material.
|
||||
* These act as an override of the textures specified by the parent effect
|
||||
*/
|
||||
[[nodiscard]] const std::map <int, Effects::CBind*>& getTextureBinds () const;
|
||||
[[nodiscard]] const std::map<int, Effects::CBind*>& getTextureBinds () const;
|
||||
/**
|
||||
* @return The materials destination (fbo) if required
|
||||
*/
|
||||
@ -63,12 +61,12 @@ namespace WallpaperEngine::Core::Objects::Images
|
||||
|
||||
private:
|
||||
/** All the shader passes required to render this material */
|
||||
std::vector <Materials::CPass*> m_passes;
|
||||
std::vector<Materials::CPass*> m_passes;
|
||||
/** List of texture bind overrides to use for this material */
|
||||
std::map <int, Effects::CBind*> m_textureBindings;
|
||||
std::map<int, Effects::CBind*> m_textureBindings;
|
||||
/** The FBO target to render to (if any) */
|
||||
std::string m_target;
|
||||
/** The material's name */
|
||||
std::string m_name;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Images
|
||||
|
@ -1,54 +1,43 @@
|
||||
#include "common.h"
|
||||
#include "CPass.h"
|
||||
#include "common.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Effects::Constants;
|
||||
using namespace WallpaperEngine::Core::Objects::Images::Materials;
|
||||
|
||||
CPass::CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader) :
|
||||
m_blending (std::move(blending)),
|
||||
m_cullmode (std::move(cullmode)),
|
||||
m_depthtest (std::move(depthtest)),
|
||||
m_depthwrite (std::move(depthwrite)),
|
||||
m_shader (std::move(shader))
|
||||
{
|
||||
}
|
||||
CPass::CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite,
|
||||
std::string shader) :
|
||||
m_blending (std::move (blending)),
|
||||
m_cullmode (std::move (cullmode)),
|
||||
m_depthtest (std::move (depthtest)),
|
||||
m_depthwrite (std::move (depthwrite)),
|
||||
m_shader (std::move (shader)) {}
|
||||
|
||||
CPass* CPass::fromJSON (json data)
|
||||
{
|
||||
CPass* CPass::fromJSON (json data) {
|
||||
// TODO: FIGURE OUT DEFAULT BLENDING MODE
|
||||
auto blending = jsonFindDefault <std::string> (data, "blending", "normal");
|
||||
auto cullmode = jsonFindDefault <std::string> (data, "cullmode", "nocull");
|
||||
auto depthtest_it = jsonFindRequired (data, "depthtest", "Material pass must have depthtest specified");
|
||||
auto depthwrite_it = jsonFindRequired (data, "depthwrite", "Material pass must have depthwrite specified");
|
||||
auto shader_it = jsonFindRequired (data, "shader", "Material pass must have shader specified");
|
||||
auto textures_it = data.find ("textures");
|
||||
auto combos_it = data.find ("combos");
|
||||
const auto blending = jsonFindDefault<std::string> (data, "blending", "normal");
|
||||
const auto cullmode = jsonFindDefault<std::string> (data, "cullmode", "nocull");
|
||||
const auto depthtest_it = jsonFindRequired (data, "depthtest", "Material pass must have depthtest specified");
|
||||
const auto depthwrite_it = jsonFindRequired (data, "depthwrite", "Material pass must have depthwrite specified");
|
||||
const auto shader_it = jsonFindRequired (data, "shader", "Material pass must have shader specified");
|
||||
const auto textures_it = data.find ("textures");
|
||||
const auto combos_it = data.find ("combos");
|
||||
|
||||
if (textures_it != data.end ())
|
||||
{
|
||||
if (textures_it != data.end ()) {
|
||||
// TODO: FETCH THIS FROM CImage TO MAKE IT COMPATIBLE WITH OLDER WALLPAPERS
|
||||
if (!(*textures_it).is_array ())
|
||||
if (!textures_it->is_array ())
|
||||
sLog.exception ("Material's textures must be a list");
|
||||
}
|
||||
|
||||
auto* pass = new CPass (
|
||||
blending,
|
||||
cullmode,
|
||||
*depthtest_it,
|
||||
*depthwrite_it,
|
||||
*shader_it
|
||||
);
|
||||
auto* pass = new CPass (blending, cullmode, *depthtest_it, *depthwrite_it, *shader_it);
|
||||
|
||||
if (textures_it != data.end ())
|
||||
for (const auto& cur : (*textures_it))
|
||||
pass->insertTexture (cur.is_null () ? "" : cur);
|
||||
|
||||
if (combos_it != data.end ())
|
||||
{
|
||||
for (const auto& cur : (*combos_it).items ())
|
||||
{
|
||||
if (combos_it != data.end ()) {
|
||||
for (const auto& cur : combos_it->items ()) {
|
||||
if (cur.value ().is_number_integer ())
|
||||
pass->insertCombo (cur.key (), cur.value ());
|
||||
else
|
||||
@ -59,70 +48,57 @@ CPass* CPass::fromJSON (json data)
|
||||
return pass;
|
||||
}
|
||||
|
||||
void CPass::insertTexture (const std::string& texture)
|
||||
{
|
||||
void CPass::insertTexture (const std::string& texture) {
|
||||
this->m_textures.push_back (texture);
|
||||
}
|
||||
|
||||
void CPass::setTexture (int index, const std::string& texture)
|
||||
{
|
||||
void CPass::setTexture (int index, const std::string& texture) {
|
||||
this->m_textures.at (index) = texture;
|
||||
}
|
||||
|
||||
void CPass::insertCombo (const std::string& name, int value)
|
||||
{
|
||||
void CPass::insertCombo (const std::string& name, int value) {
|
||||
std::string uppercase = std::string (name);
|
||||
|
||||
std::transform (uppercase.begin (), uppercase.end (), uppercase.begin (), ::toupper);
|
||||
this->m_combos.insert (std::pair <std::string, int> (uppercase, value));
|
||||
this->m_combos.insert (std::pair (uppercase, value));
|
||||
}
|
||||
|
||||
const std::vector<std::string>& CPass::getTextures () const
|
||||
{
|
||||
const std::vector<std::string>& CPass::getTextures () const {
|
||||
return this->m_textures;
|
||||
}
|
||||
|
||||
const std::map<std::string, CShaderConstant*>& CPass::getConstants () const
|
||||
{
|
||||
const std::map<std::string, CShaderConstant*>& CPass::getConstants () const {
|
||||
return this->m_constants;
|
||||
}
|
||||
|
||||
std::map<std::string, int>* CPass::getCombos ()
|
||||
{
|
||||
std::map<std::string, int>* CPass::getCombos () {
|
||||
return &this->m_combos;
|
||||
}
|
||||
|
||||
const std::string& CPass::getShader () const
|
||||
{
|
||||
const std::string& CPass::getShader () const {
|
||||
return this->m_shader;
|
||||
}
|
||||
|
||||
const std::string& CPass::getBlendingMode () const
|
||||
{
|
||||
const std::string& CPass::getBlendingMode () const {
|
||||
return this->m_blending;
|
||||
}
|
||||
|
||||
const std::string& CPass::getCullingMode () const
|
||||
{
|
||||
const std::string& CPass::getCullingMode () const {
|
||||
return this->m_cullmode;
|
||||
}
|
||||
|
||||
const std::string& CPass::getDepthTest () const
|
||||
{
|
||||
const std::string& CPass::getDepthTest () const {
|
||||
return this->m_depthtest;
|
||||
}
|
||||
|
||||
const std::string& CPass::getDepthWrite ()const
|
||||
{
|
||||
const std::string& CPass::getDepthWrite () const {
|
||||
return this->m_depthwrite;
|
||||
}
|
||||
|
||||
void CPass::setBlendingMode (const std::string& mode)
|
||||
{
|
||||
void CPass::setBlendingMode (const std::string& mode) {
|
||||
this->m_blending = mode;
|
||||
}
|
||||
|
||||
void CPass::insertConstant (const std::string& name, CShaderConstant* constant)
|
||||
{
|
||||
this->m_constants.insert (std::pair <std::string, CShaderConstant*> (name, constant));
|
||||
void CPass::insertConstant (const std::string& name, CShaderConstant* constant) {
|
||||
this->m_constants.insert (std::pair (name, constant));
|
||||
}
|
@ -4,21 +4,19 @@
|
||||
|
||||
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects
|
||||
{
|
||||
class CEffect;
|
||||
namespace WallpaperEngine::Core::Objects {
|
||||
class CEffect;
|
||||
}
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Images::Materials
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
namespace WallpaperEngine::Core::Objects::Images::Materials {
|
||||
using json = nlohmann::json;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Represents a shader pass of an object
|
||||
*/
|
||||
class CPass
|
||||
{
|
||||
class CPass {
|
||||
friend class WallpaperEngine::Core::Objects::CEffect;
|
||||
|
||||
public:
|
||||
static CPass* fromJSON (json data);
|
||||
|
||||
@ -75,7 +73,8 @@ namespace WallpaperEngine::Core::Objects::Images::Materials
|
||||
void insertConstant (const std::string& name, Effects::Constants::CShaderConstant* constant);
|
||||
|
||||
protected:
|
||||
CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader);
|
||||
CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite,
|
||||
std::string shader);
|
||||
|
||||
/**
|
||||
* Adds a new texture to the list of textures to bind while rendering
|
||||
@ -109,5 +108,5 @@ namespace WallpaperEngine::Core::Objects::Images::Materials
|
||||
std::map<std::string, int> m_combos;
|
||||
/** Shader constant values to use for the shaders */
|
||||
std::map<std::string, Core::Objects::Effects::Constants::CShaderConstant*> m_constants;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Images::Materials
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Particles;
|
||||
|
||||
CControlPoint* CControlPoint::fromJSON (json data)
|
||||
{
|
||||
auto flags_it = data.find ("flags");
|
||||
auto id_it = jsonFindRequired (data, "id", "Particle's control point must have id");
|
||||
auto offset_it = data.find ("offset");
|
||||
CControlPoint* CControlPoint::fromJSON (json data) {
|
||||
const auto flags_it = data.find ("flags");
|
||||
const auto id_it = jsonFindRequired (data, "id", "Particle's control point must have id");
|
||||
const auto offset_it = data.find ("offset");
|
||||
|
||||
auto* controlpoint = new CControlPoint (*id_it, 0);
|
||||
|
||||
@ -19,33 +18,24 @@ CControlPoint* CControlPoint::fromJSON (json data)
|
||||
return controlpoint;
|
||||
}
|
||||
|
||||
CControlPoint::CControlPoint (uint32_t id, uint32_t flags) :
|
||||
m_id (id),
|
||||
m_flags (flags),
|
||||
m_offset (glm::vec3 ())
|
||||
{
|
||||
}
|
||||
CControlPoint::CControlPoint (uint32_t id, uint32_t flags) : m_id (id), m_flags (flags), m_offset (glm::vec3 ()) {}
|
||||
|
||||
void CControlPoint::setOffset (const glm::vec3& offset)
|
||||
{
|
||||
void CControlPoint::setOffset (const glm::vec3& offset) {
|
||||
this->m_offset = offset;
|
||||
}
|
||||
|
||||
void CControlPoint::setFlags (uint32_t flags)
|
||||
{
|
||||
void CControlPoint::setFlags (uint32_t flags) {
|
||||
this->m_flags = flags;
|
||||
}
|
||||
uint32_t CControlPoint::getId () const
|
||||
{
|
||||
|
||||
uint32_t CControlPoint::getId () const {
|
||||
return this->m_id;
|
||||
}
|
||||
|
||||
const glm::vec3& CControlPoint::getOffset () const
|
||||
{
|
||||
const glm::vec3& CControlPoint::getOffset () const {
|
||||
return this->m_offset;
|
||||
}
|
||||
|
||||
uint32_t CControlPoint::getFlags () const
|
||||
{
|
||||
uint32_t CControlPoint::getFlags () const {
|
||||
return this->m_flags;
|
||||
}
|
@ -2,15 +2,13 @@
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Particles
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
namespace WallpaperEngine::Core::Objects::Particles {
|
||||
using json = nlohmann::json;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Control point for particles
|
||||
*/
|
||||
class CControlPoint
|
||||
{
|
||||
class CControlPoint {
|
||||
public:
|
||||
static CControlPoint* fromJSON (json data);
|
||||
|
||||
@ -46,5 +44,5 @@ namespace WallpaperEngine::Core::Objects::Particles
|
||||
uint32_t m_flags;
|
||||
/** The offset from starting position */
|
||||
glm::vec3 m_offset;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Particles
|
||||
|
@ -2,76 +2,54 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Particles;
|
||||
|
||||
CEmitter* CEmitter::fromJSON (json data)
|
||||
{
|
||||
auto directions_it = jsonFindRequired (data, "directions", "Particle emitter must have direction specified");
|
||||
auto distancemax_it = jsonFindRequired (data, "distancemax", "Particle emitter must have maximum distance");
|
||||
auto distancemin_it = jsonFindRequired (data, "distancemin", "Particle emitter must have minimum distance");
|
||||
auto id_it = data.find ("id");
|
||||
auto name_it = jsonFindRequired (data, "name", "Particle emitter must have a name");
|
||||
auto origin_it = jsonFindRequired (data, "origin", "Particle emitter must have an origin");
|
||||
auto rate_it = jsonFindRequired (data, "rate", "Particle emitter must have a rate");
|
||||
CEmitter* CEmitter::fromJSON (json data) {
|
||||
const auto directions_it = jsonFindRequired (data, "directions", "Particle emitter must have direction specified");
|
||||
const auto distancemax_it = jsonFindRequired (data, "distancemax", "Particle emitter must have maximum distance");
|
||||
const auto distancemin_it = jsonFindRequired (data, "distancemin", "Particle emitter must have minimum distance");
|
||||
const auto id_it = data.find ("id");
|
||||
const auto name_it = jsonFindRequired (data, "name", "Particle emitter must have a name");
|
||||
const auto origin_it = jsonFindRequired (data, "origin", "Particle emitter must have an origin");
|
||||
const auto rate_it = jsonFindRequired (data, "rate", "Particle emitter must have a rate");
|
||||
|
||||
return new CEmitter (
|
||||
WallpaperEngine::Core::aToVector3 (*directions_it),
|
||||
*distancemax_it,
|
||||
*distancemin_it,
|
||||
(id_it == data.end () ? 0 : (uint32_t) (*id_it)),
|
||||
*name_it,
|
||||
WallpaperEngine::Core::aToVector3 (*origin_it),
|
||||
*rate_it
|
||||
);
|
||||
return new CEmitter (WallpaperEngine::Core::aToVector3 (*directions_it), *distancemax_it, *distancemin_it,
|
||||
(id_it == data.end () ? 0 : static_cast<uint32_t> (*id_it)), *name_it,
|
||||
WallpaperEngine::Core::aToVector3 (*origin_it), *rate_it);
|
||||
}
|
||||
|
||||
CEmitter::CEmitter (
|
||||
const glm::vec3& directions,
|
||||
uint32_t distancemax,
|
||||
uint32_t distancemin,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
const glm::vec3& origin,
|
||||
double rate):
|
||||
CEmitter::CEmitter (const glm::vec3& directions, uint32_t distancemax, uint32_t distancemin, uint32_t id,
|
||||
std::string name, const glm::vec3& origin, double rate) :
|
||||
m_directions (directions),
|
||||
m_distancemax (distancemax),
|
||||
m_distancemin (distancemin),
|
||||
m_id (id),
|
||||
m_name (std::move(name)),
|
||||
m_name (std::move (name)),
|
||||
m_origin (origin),
|
||||
m_rate (rate)
|
||||
{
|
||||
}
|
||||
m_rate (rate) {}
|
||||
|
||||
uint32_t CEmitter::getId () const
|
||||
{
|
||||
uint32_t CEmitter::getId () const {
|
||||
return this->m_id;
|
||||
}
|
||||
|
||||
const std::string& CEmitter::getName () const
|
||||
{
|
||||
const std::string& CEmitter::getName () const {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
const uint32_t CEmitter::getDistanceMax () const
|
||||
{
|
||||
const uint32_t CEmitter::getDistanceMax () const {
|
||||
return this->m_distancemax;
|
||||
}
|
||||
|
||||
const uint32_t CEmitter::getDistanceMin () const
|
||||
{
|
||||
const uint32_t CEmitter::getDistanceMin () const {
|
||||
return this->m_distancemin;
|
||||
}
|
||||
|
||||
const glm::vec3& CEmitter::getDirections () const
|
||||
{
|
||||
const glm::vec3& CEmitter::getDirections () const {
|
||||
return this->m_directions;
|
||||
}
|
||||
|
||||
const glm::vec3& CEmitter::getOrigin () const
|
||||
{
|
||||
const glm::vec3& CEmitter::getOrigin () const {
|
||||
return this->m_origin;
|
||||
}
|
||||
|
||||
const double CEmitter::getRate () const
|
||||
{
|
||||
const double CEmitter::getRate () const {
|
||||
return this->m_rate;
|
||||
}
|
@ -2,15 +2,13 @@
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Particles
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
namespace WallpaperEngine::Core::Objects::Particles {
|
||||
using json = nlohmann::json;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Particle emitter, controls the area where the particles have to be created
|
||||
*/
|
||||
class CEmitter
|
||||
{
|
||||
class CEmitter {
|
||||
public:
|
||||
static CEmitter* fromJSON (json data);
|
||||
|
||||
@ -44,10 +42,8 @@ namespace WallpaperEngine::Core::Objects::Particles
|
||||
[[nodiscard]] const double getRate () const;
|
||||
|
||||
protected:
|
||||
CEmitter (
|
||||
const glm::vec3& directions, uint32_t distancemax, uint32_t distancemin, uint32_t id, std::string name,
|
||||
const glm::vec3& origin, double rate
|
||||
);
|
||||
CEmitter (const glm::vec3& directions, uint32_t distancemax, uint32_t distancemin, uint32_t id, std::string name,
|
||||
const glm::vec3& origin, double rate);
|
||||
|
||||
private:
|
||||
/** Direction the particles should move to */
|
||||
@ -64,5 +60,5 @@ namespace WallpaperEngine::Core::Objects::Particles
|
||||
glm::vec3 m_origin;
|
||||
/** The rate of emission */
|
||||
double m_rate;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Particles
|
||||
|
@ -1,75 +1,56 @@
|
||||
#include "common.h"
|
||||
#include "CInitializer.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CLifeTimeRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CSizeRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CRotationRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CVelocityRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CColorRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CAlphaRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CAngularVelocityRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CColorRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CLifeTimeRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CRotationRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CSizeRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CTurbulentVelocityRandom.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CVelocityRandom.h"
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Particles;
|
||||
|
||||
CInitializer* CInitializer::fromJSON (json data)
|
||||
{
|
||||
auto id_it = data.find ("id");
|
||||
auto name_it = jsonFindRequired (data, "name", "Particle's initializer must have a name");
|
||||
uint32_t id = ((id_it == data.end ()) ? 0 : (uint32_t) (*id_it));
|
||||
CInitializer* CInitializer::fromJSON (json data) {
|
||||
const auto id_it = data.find ("id");
|
||||
const auto name_it = jsonFindRequired (data, "name", "Particle's initializer must have a name");
|
||||
const uint32_t id = ((id_it == data.end ()) ? 0 : static_cast<uint32_t> (*id_it));
|
||||
|
||||
if (*name_it == "lifetimerandom")
|
||||
{
|
||||
if (*name_it == "lifetimerandom") {
|
||||
return Initializers::CLifeTimeRandom::fromJSON (data, id);
|
||||
}
|
||||
else if (*name_it == "sizerandom")
|
||||
{
|
||||
if (*name_it == "sizerandom") {
|
||||
return Initializers::CSizeRandom::fromJSON (data, id);
|
||||
}
|
||||
else if (*name_it == "rotationrandom")
|
||||
{
|
||||
if (*name_it == "rotationrandom") {
|
||||
return Initializers::CRotationRandom::fromJSON (data, id);
|
||||
}
|
||||
else if (*name_it == "velocityrandom")
|
||||
{
|
||||
if (*name_it == "velocityrandom") {
|
||||
return Initializers::CVelocityRandom::fromJSON (data, id);
|
||||
}
|
||||
else if (*name_it == "colorrandom")
|
||||
{
|
||||
if (*name_it == "colorrandom") {
|
||||
return Initializers::CColorRandom::fromJSON (data, id);
|
||||
}
|
||||
else if (*name_it == "alpharandom")
|
||||
{
|
||||
if (*name_it == "alpharandom") {
|
||||
return Initializers::CAlphaRandom::fromJSON (data, id);
|
||||
}
|
||||
else if (*name_it == "angularvelocityrandom")
|
||||
{
|
||||
if (*name_it == "angularvelocityrandom") {
|
||||
return Initializers::CAngularVelocityRandom::fromJSON (data, id);
|
||||
}
|
||||
else if (*name_it == "turbulentvelocityrandom")
|
||||
{
|
||||
if (*name_it == "turbulentvelocityrandom") {
|
||||
return Initializers::CTurbulentVelocityRandom::fromJSON (data, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
sLog.exception ("Found unknown initializer for particles: ", *name_it);
|
||||
}
|
||||
}
|
||||
|
||||
CInitializer::CInitializer (uint32_t id, std::string name) : m_id (id), m_name (std::move (name)) {}
|
||||
|
||||
CInitializer::CInitializer (uint32_t id, std::string name) :
|
||||
m_id (id),
|
||||
m_name (std::move(name))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const std::string& CInitializer::getName () const
|
||||
{
|
||||
const std::string& CInitializer::getName () const {
|
||||
return this->m_name;
|
||||
}
|
||||
|
||||
uint32_t CInitializer::getId () const
|
||||
{
|
||||
uint32_t CInitializer::getId () const {
|
||||
return this->m_id;
|
||||
}
|
@ -2,16 +2,14 @@
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Particles
|
||||
{
|
||||
using json = nlohmann::json;
|
||||
namespace WallpaperEngine::Core::Objects::Particles {
|
||||
using json = nlohmann::json;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Initializer for particles, controls the different attributes a particle will have
|
||||
* on emission
|
||||
*/
|
||||
class CInitializer
|
||||
{
|
||||
class CInitializer {
|
||||
public:
|
||||
static CInitializer* fromJSON (json data);
|
||||
|
||||
@ -32,5 +30,5 @@ namespace WallpaperEngine::Core::Objects::Particles
|
||||
uint32_t m_id;
|
||||
/** The name of the initializer, indicates what type of initialization to do */
|
||||
std::string m_name;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Particles
|
||||
|
@ -2,10 +2,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
|
||||
|
||||
CAlphaRandom* CAlphaRandom::fromJSON (json data, uint32_t id)
|
||||
{
|
||||
auto min_it = jsonFindRequired (data, "min", "Alpharandom initializer must have a minimum value");
|
||||
auto max_it = jsonFindRequired (data, "max", "Alpharandom initializer must have a maximum value");
|
||||
CAlphaRandom* CAlphaRandom::fromJSON (json data, uint32_t id) {
|
||||
const auto min_it = jsonFindRequired (data, "min", "Alpharandom initializer must have a minimum value");
|
||||
const auto max_it = jsonFindRequired (data, "max", "Alpharandom initializer must have a maximum value");
|
||||
|
||||
return new CAlphaRandom (id, *min_it, *max_it);
|
||||
}
|
||||
@ -13,16 +12,12 @@ CAlphaRandom* CAlphaRandom::fromJSON (json data, uint32_t id)
|
||||
CAlphaRandom::CAlphaRandom (uint32_t id, double min, double max) :
|
||||
CInitializer (id, "alpharandom"),
|
||||
m_min (min),
|
||||
m_max (max)
|
||||
{
|
||||
}
|
||||
m_max (max) {}
|
||||
|
||||
double CAlphaRandom::getMinimum () const
|
||||
{
|
||||
double CAlphaRandom::getMinimum () const {
|
||||
return this->m_min;
|
||||
}
|
||||
|
||||
double CAlphaRandom::getMaximum () const
|
||||
{
|
||||
double CAlphaRandom::getMaximum () const {
|
||||
return this->m_max;
|
||||
}
|
@ -3,13 +3,11 @@
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers {
|
||||
/**
|
||||
* Initializer for particles that decides the base alpha for the particles
|
||||
*/
|
||||
class CAlphaRandom : CInitializer
|
||||
{
|
||||
class CAlphaRandom : CInitializer {
|
||||
public:
|
||||
/**
|
||||
* @return The minimum alpha value to be used
|
||||
@ -32,5 +30,5 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
double m_max;
|
||||
/** Minimum alpha */
|
||||
double m_min;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
|
@ -2,32 +2,23 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
|
||||
|
||||
CAngularVelocityRandom* CAngularVelocityRandom::fromJSON (json data, uint32_t id)
|
||||
{
|
||||
auto min_it = jsonFindRequired (data, "min", "Angularvelocityrandom initializer must have a minimum value");
|
||||
auto max_it = jsonFindRequired (data, "max", "Angularvelocityrandom initializer must have a maximum value");
|
||||
CAngularVelocityRandom* CAngularVelocityRandom::fromJSON (json data, uint32_t id) {
|
||||
const auto min_it = jsonFindRequired (data, "min", "Angularvelocityrandom initializer must have a minimum value");
|
||||
const auto max_it = jsonFindRequired (data, "max", "Angularvelocityrandom initializer must have a maximum value");
|
||||
|
||||
return new CAngularVelocityRandom (
|
||||
id,
|
||||
WallpaperEngine::Core::aToVector3 (*min_it),
|
||||
WallpaperEngine::Core::aToVector3 (*max_it)
|
||||
);
|
||||
return new CAngularVelocityRandom (id, WallpaperEngine::Core::aToVector3 (*min_it),
|
||||
WallpaperEngine::Core::aToVector3 (*max_it));
|
||||
}
|
||||
|
||||
|
||||
CAngularVelocityRandom::CAngularVelocityRandom (uint32_t id, glm::vec3 min, glm::vec3 max) :
|
||||
CInitializer (id, "angularvelocityrandom"),
|
||||
m_min (min),
|
||||
m_max (max)
|
||||
{
|
||||
}
|
||||
m_max (max) {}
|
||||
|
||||
const glm::vec3& CAngularVelocityRandom::getMinimum () const
|
||||
{
|
||||
const glm::vec3& CAngularVelocityRandom::getMinimum () const {
|
||||
return this->m_min;
|
||||
}
|
||||
|
||||
const glm::vec3& CAngularVelocityRandom::getMaximum () const
|
||||
{
|
||||
const glm::vec3& CAngularVelocityRandom::getMaximum () const {
|
||||
return this->m_max;
|
||||
}
|
@ -3,13 +3,11 @@
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers {
|
||||
/**
|
||||
* Initializer for particles that decides the base angular velocity for particles
|
||||
*/
|
||||
class CAngularVelocityRandom : CInitializer
|
||||
{
|
||||
class CAngularVelocityRandom : CInitializer {
|
||||
public:
|
||||
/**
|
||||
* @return Minimum angular velocity (direction * speed)
|
||||
@ -32,5 +30,5 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
glm::vec3 m_max;
|
||||
/** Minimum velocity (direction * speed) */
|
||||
glm::vec3 m_min;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
|
@ -2,32 +2,23 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
|
||||
|
||||
CColorRandom* CColorRandom::fromJSON (json data, uint32_t id)
|
||||
{
|
||||
auto min_it = jsonFindRequired (data, "min", "Colorrandom initializer must have a minimum value");
|
||||
auto max_it = jsonFindRequired (data, "max", "Colorrandom initializer must have a maximum value");
|
||||
CColorRandom* CColorRandom::fromJSON (json data, uint32_t id) {
|
||||
const auto min_it = jsonFindRequired (data, "min", "Colorrandom initializer must have a minimum value");
|
||||
const auto max_it = jsonFindRequired (data, "max", "Colorrandom initializer must have a maximum value");
|
||||
|
||||
return new CColorRandom (
|
||||
id,
|
||||
WallpaperEngine::Core::aToColori (*min_it),
|
||||
WallpaperEngine::Core::aToColori (*max_it)
|
||||
);
|
||||
return new CColorRandom (id, WallpaperEngine::Core::aToColori (*min_it),
|
||||
WallpaperEngine::Core::aToColori (*max_it));
|
||||
}
|
||||
|
||||
|
||||
CColorRandom::CColorRandom (uint32_t id, glm::ivec3 min, glm::ivec3 max) :
|
||||
CInitializer (id, "colorrandom"),
|
||||
m_min (min),
|
||||
m_max (max)
|
||||
{
|
||||
}
|
||||
m_max (max) {}
|
||||
|
||||
const glm::ivec3& CColorRandom::getMinimum () const
|
||||
{
|
||||
const glm::ivec3& CColorRandom::getMinimum () const {
|
||||
return this->m_min;
|
||||
}
|
||||
|
||||
const glm::ivec3& CColorRandom::getMaximum () const
|
||||
{
|
||||
const glm::ivec3& CColorRandom::getMaximum () const {
|
||||
return this->m_max;
|
||||
}
|
@ -4,13 +4,11 @@
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers {
|
||||
/**
|
||||
* Initializer for particles that decides the base color
|
||||
*/
|
||||
class CColorRandom : CInitializer
|
||||
{
|
||||
class CColorRandom : CInitializer {
|
||||
public:
|
||||
/**
|
||||
* @return The minimum color to use (RGB)
|
||||
@ -33,5 +31,5 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
glm::ivec3 m_max;
|
||||
/** Minimum color */
|
||||
glm::ivec3 m_min;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
|
@ -2,28 +2,22 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
|
||||
|
||||
CLifeTimeRandom* CLifeTimeRandom::fromJSON (json data, uint32_t id)
|
||||
{
|
||||
auto min_it = jsonFindRequired (data, "min", "Lifetimerandom initializer must have a minimum value");
|
||||
auto max_it = jsonFindRequired (data, "max", "Lifetimerandom initializer must have a maximum value");
|
||||
CLifeTimeRandom* CLifeTimeRandom::fromJSON (json data, uint32_t id) {
|
||||
const auto min_it = jsonFindRequired (data, "min", "Lifetimerandom initializer must have a minimum value");
|
||||
const auto max_it = jsonFindRequired (data, "max", "Lifetimerandom initializer must have a maximum value");
|
||||
|
||||
return new CLifeTimeRandom (id, *min_it, *max_it);
|
||||
}
|
||||
|
||||
|
||||
CLifeTimeRandom::CLifeTimeRandom (uint32_t id, uint32_t min, uint32_t max) :
|
||||
CInitializer (id, "lifetimerandom"),
|
||||
m_min (min),
|
||||
m_max (max)
|
||||
{
|
||||
}
|
||||
m_max (max) {}
|
||||
|
||||
uint32_t CLifeTimeRandom::getMinimum () const
|
||||
{
|
||||
uint32_t CLifeTimeRandom::getMinimum () const {
|
||||
return this->m_min;
|
||||
}
|
||||
|
||||
uint32_t CLifeTimeRandom::getMaximum () const
|
||||
{
|
||||
uint32_t CLifeTimeRandom::getMaximum () const {
|
||||
return this->m_max;
|
||||
}
|
@ -4,13 +4,11 @@
|
||||
|
||||
#include "WallpaperEngine/Core/Core.h"
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers {
|
||||
/**
|
||||
* Initializer for particles that decides the lifetime of each particle on startup
|
||||
*/
|
||||
class CLifeTimeRandom : CInitializer
|
||||
{
|
||||
class CLifeTimeRandom : CInitializer {
|
||||
public:
|
||||
/**
|
||||
* @return The minimum lifetime to be used
|
||||
@ -20,6 +18,7 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
* @return The maximum lifetime to be used
|
||||
*/
|
||||
[[nodiscard]] uint32_t getMaximum () const;
|
||||
|
||||
protected:
|
||||
friend class CInitializer;
|
||||
|
||||
@ -32,5 +31,5 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
uint32_t m_max;
|
||||
/** Minimum lifetime */
|
||||
uint32_t m_min;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
|
@ -4,10 +4,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
|
||||
|
||||
CRotationRandom* CRotationRandom::fromJSON (json data, uint32_t id)
|
||||
{
|
||||
auto min_it = data.find ("minVector");
|
||||
auto max_it = data.find ("max");
|
||||
CRotationRandom* CRotationRandom::fromJSON (json data, uint32_t id) {
|
||||
const auto min_it = data.find ("minVector");
|
||||
const auto max_it = data.find ("max");
|
||||
|
||||
glm::vec3 minVector = glm::vec3 ();
|
||||
glm::vec3 maxVector = glm::vec3 ();
|
||||
@ -16,24 +15,18 @@ CRotationRandom* CRotationRandom::fromJSON (json data, uint32_t id)
|
||||
bool isMinVector = false;
|
||||
bool isMaxVector = false;
|
||||
|
||||
if (min_it != data.end () && min_it->is_string ())
|
||||
{
|
||||
if (min_it != data.end () && min_it->is_string ()) {
|
||||
minVector = WallpaperEngine::Core::aToVector3 (*min_it);
|
||||
isMinVector = true;
|
||||
}
|
||||
else if (min_it != data.end () && min_it->is_number ())
|
||||
{
|
||||
} else if (min_it != data.end () && min_it->is_number ()) {
|
||||
minNumber = *min_it;
|
||||
isMinVector = false;
|
||||
}
|
||||
|
||||
if (max_it != data.end () && max_it->is_string ())
|
||||
{
|
||||
if (max_it != data.end () && max_it->is_string ()) {
|
||||
maxVector = WallpaperEngine::Core::aToVector3 (*max_it);
|
||||
isMaxVector = true;
|
||||
}
|
||||
else if(max_it != data.end () && max_it->is_number ())
|
||||
{
|
||||
} else if (max_it != data.end () && max_it->is_number ()) {
|
||||
maxNumber = *max_it;
|
||||
isMaxVector = false;
|
||||
}
|
||||
@ -41,61 +34,44 @@ CRotationRandom* CRotationRandom::fromJSON (json data, uint32_t id)
|
||||
return new CRotationRandom (id, minVector, minNumber, isMinVector, maxVector, maxNumber, isMaxVector);
|
||||
}
|
||||
|
||||
CRotationRandom::CRotationRandom (
|
||||
uint32_t id,
|
||||
glm::vec3 minVector,
|
||||
double minNumber,
|
||||
bool isMinimumVector,
|
||||
glm::vec3 maxVector,
|
||||
double maxNumber,
|
||||
bool isMaximumVector
|
||||
) :
|
||||
CRotationRandom::CRotationRandom (uint32_t id, glm::vec3 minVector, double minNumber, bool isMinimumVector,
|
||||
glm::vec3 maxVector, double maxNumber, bool isMaximumVector) :
|
||||
CInitializer (id, "rotationrandom"),
|
||||
m_minVector (minVector),
|
||||
m_maxVector (maxVector),
|
||||
m_minNumber (minNumber),
|
||||
m_maxNumber (maxNumber),
|
||||
m_isMinimumVector (isMinimumVector),
|
||||
m_isMaximumVector (isMaximumVector)
|
||||
{
|
||||
}
|
||||
m_isMaximumVector (isMaximumVector) {}
|
||||
|
||||
glm::vec3 CRotationRandom::getMinimumVector () const
|
||||
{
|
||||
glm::vec3 CRotationRandom::getMinimumVector () const {
|
||||
return this->m_minVector;
|
||||
}
|
||||
|
||||
glm::vec3 CRotationRandom::getMaximumVector () const
|
||||
{
|
||||
glm::vec3 CRotationRandom::getMaximumVector () const {
|
||||
return this->m_maxVector;
|
||||
}
|
||||
|
||||
double CRotationRandom::getMinimumNumber () const
|
||||
{
|
||||
double CRotationRandom::getMinimumNumber () const {
|
||||
return this->m_minNumber;
|
||||
}
|
||||
|
||||
double CRotationRandom::getMaximumNumber () const
|
||||
{
|
||||
double CRotationRandom::getMaximumNumber () const {
|
||||
return this->m_maxNumber;
|
||||
}
|
||||
|
||||
bool CRotationRandom::isMinimumVector () const
|
||||
{
|
||||
bool CRotationRandom::isMinimumVector () const {
|
||||
return this->m_isMinimumVector;
|
||||
}
|
||||
|
||||
bool CRotationRandom::isMinimumNumber () const
|
||||
{
|
||||
bool CRotationRandom::isMinimumNumber () const {
|
||||
return !this->m_isMinimumVector;
|
||||
}
|
||||
|
||||
bool CRotationRandom::isMaximumVector () const
|
||||
{
|
||||
bool CRotationRandom::isMaximumVector () const {
|
||||
return this->m_isMaximumVector;
|
||||
}
|
||||
|
||||
bool CRotationRandom::isMaximumNumber () const
|
||||
{
|
||||
bool CRotationRandom::isMaximumNumber () const {
|
||||
return !this->m_isMaximumVector;
|
||||
}
|
@ -4,13 +4,11 @@
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
{
|
||||
/**
|
||||
namespace WallpaperEngine::Core::Objects::Particles::Initializers {
|
||||
/**
|
||||
* Initializer for particles that decides the base rotation for the particles
|
||||
*/
|
||||
class CRotationRandom : CInitializer
|
||||
{
|
||||
class CRotationRandom : CInitializer {
|
||||
public:
|
||||
/**
|
||||
* @return The minimum rotation in vector format if available
|
||||
@ -51,15 +49,8 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
|
||||
static CRotationRandom* fromJSON (json data, uint32_t id);
|
||||
|
||||
CRotationRandom (
|
||||
uint32_t id,
|
||||
glm::vec3 minVector,
|
||||
double minNumber,
|
||||
bool isMinimumVector,
|
||||
glm::vec3 maxVector,
|
||||
double maxNumber,
|
||||
bool isMaximumVector
|
||||
);
|
||||
CRotationRandom (uint32_t id, glm::vec3 minVector, double minNumber, bool isMinimumVector, glm::vec3 maxVector,
|
||||
double maxNumber, bool isMaximumVector);
|
||||
|
||||
private:
|
||||
/** Maximum rotation vector */
|
||||
@ -75,5 +66,5 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
bool m_isMinimumVector;
|
||||
/** If maximum is a vector */
|
||||
bool m_isMaximumVector;
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace WallpaperEngine::Core::Objects::Particles::Initializers
|
||||
|
@ -2,10 +2,9 @@
|
||||
|
||||
using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
|
||||
|
||||
CSizeRandom* CSizeRandom::fromJSON (json data, uint32_t id)
|
||||
{
|
||||
auto min_it = jsonFindRequired (data, "min", "Sizerandom initializer must have a minimum value");
|
||||
auto max_it = jsonFindRequired (data, "max", "Sizerandom initializer must have a maximum value");
|
||||
CSizeRandom* CSizeRandom::fromJSON (json data, uint32_t id) {
|
||||
const auto min_it = jsonFindRequired (data, "min", "Sizerandom initializer must have a minimum value");
|
||||
const auto max_it = jsonFindRequired (data, "max", "Sizerandom initializer must have a maximum value");
|
||||
|
||||
return new CSizeRandom (id, *min_it, *max_it);
|
||||
}
|
||||
@ -13,16 +12,12 @@ CSizeRandom* CSizeRandom::fromJSON (json data, uint32_t id)
|
||||
CSizeRandom::CSizeRandom (uint32_t id, uint32_t min, uint32_t max) :
|
||||
CInitializer (id, "sizerandom"),
|
||||
m_min (min),
|
||||
m_max (max)
|
||||
{
|
||||
}
|
||||
m_max (max) {}
|
||||
|
||||
uint32_t CSizeRandom::getMinimum () const
|
||||
{
|
||||
uint32_t CSizeRandom::getMinimum () const {
|
||||
return this->m_min;
|
||||
}
|
||||
|
||||
uint32_t CSizeRandom::getMaximum () const
|
||||
{
|
||||
uint32_t CSizeRandom::getMaximum () const {
|
||||
return this->m_max;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user