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:
Alexis Maiquez 2023-12-13 23:03:10 +01:00
parent f89cc438f8
commit b8fd1eefac
212 changed files with 8638 additions and 10511 deletions

225
.clang-format Normal file
View 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
...

View File

@ -1,7 +1,6 @@
#include "fft.h" #include "fft.h"
namespace External::Android namespace External::Android {
{
/* /*
* Copyright (C) 2010 The Android Open Source Project * Copyright (C) 2010 The Android Open Source Project
* *
@ -32,53 +31,39 @@ namespace External::Android
#define LOG_FFT_SIZE 10 #define LOG_FFT_SIZE 10
#define MAX_FFT_SIZE (1 << LOG_FFT_SIZE) #define MAX_FFT_SIZE (1 << LOG_FFT_SIZE)
static const int32_t twiddle [MAX_FFT_SIZE / 4] = { static const int32_t twiddle [MAX_FFT_SIZE / 4] = {
0x00008000, 0xff378001, 0xfe6e8002, 0xfda58006, 0xfcdc800a, 0xfc13800f, 0x00008000, 0xff378001, 0xfe6e8002, 0xfda58006, 0xfcdc800a, 0xfc13800f, 0xfb4a8016, 0xfa81801e, 0xf9b88027,
0xfb4a8016, 0xfa81801e, 0xf9b88027, 0xf8ef8032, 0xf827803e, 0xf75e804b, 0xf8ef8032, 0xf827803e, 0xf75e804b, 0xf6958059, 0xf5cd8068, 0xf5058079, 0xf43c808b, 0xf374809e, 0xf2ac80b2,
0xf6958059, 0xf5cd8068, 0xf5058079, 0xf43c808b, 0xf374809e, 0xf2ac80b2, 0xf1e480c8, 0xf11c80de, 0xf05580f6, 0xef8d8110, 0xeec6812a, 0xedff8146, 0xed388163, 0xec718181, 0xebab81a0,
0xf1e480c8, 0xf11c80de, 0xf05580f6, 0xef8d8110, 0xeec6812a, 0xedff8146, 0xeae481c1, 0xea1e81e2, 0xe9588205, 0xe892822a, 0xe7cd824f, 0xe7078276, 0xe642829d, 0xe57d82c6, 0xe4b982f1,
0xed388163, 0xec718181, 0xebab81a0, 0xeae481c1, 0xea1e81e2, 0xe9588205, 0xe3f4831c, 0xe3308349, 0xe26d8377, 0xe1a983a6, 0xe0e683d6, 0xe0238407, 0xdf61843a, 0xde9e846e, 0xdddc84a3,
0xe892822a, 0xe7cd824f, 0xe7078276, 0xe642829d, 0xe57d82c6, 0xe4b982f1, 0xdd1b84d9, 0xdc598511, 0xdb998549, 0xdad88583, 0xda1885be, 0xd95885fa, 0xd8988637, 0xd7d98676, 0xd71b86b6,
0xe3f4831c, 0xe3308349, 0xe26d8377, 0xe1a983a6, 0xe0e683d6, 0xe0238407, 0xd65c86f6, 0xd59e8738, 0xd4e1877b, 0xd42487c0, 0xd3678805, 0xd2ab884c, 0xd1ef8894, 0xd13488dd, 0xd0798927,
0xdf61843a, 0xde9e846e, 0xdddc84a3, 0xdd1b84d9, 0xdc598511, 0xdb998549, 0xcfbe8972, 0xcf0489be, 0xce4b8a0c, 0xcd928a5a, 0xccd98aaa, 0xcc218afb, 0xcb698b4d, 0xcab28ba0, 0xc9fc8bf5,
0xdad88583, 0xda1885be, 0xd95885fa, 0xd8988637, 0xd7d98676, 0xd71b86b6, 0xc9468c4a, 0xc8908ca1, 0xc7db8cf8, 0xc7278d51, 0xc6738dab, 0xc5c08e06, 0xc50d8e62, 0xc45b8ebf, 0xc3a98f1d,
0xd65c86f6, 0xd59e8738, 0xd4e1877b, 0xd42487c0, 0xd3678805, 0xd2ab884c, 0xc2f88f7d, 0xc2488fdd, 0xc198903e, 0xc0e990a1, 0xc03a9105, 0xbf8c9169, 0xbedf91cf, 0xbe329236, 0xbd86929e,
0xd1ef8894, 0xd13488dd, 0xd0798927, 0xcfbe8972, 0xcf0489be, 0xce4b8a0c, 0xbcda9307, 0xbc2f9371, 0xbb8593dc, 0xbadc9448, 0xba3394b5, 0xb98b9523, 0xb8e39592, 0xb83c9603, 0xb7969674,
0xcd928a5a, 0xccd98aaa, 0xcc218afb, 0xcb698b4d, 0xcab28ba0, 0xc9fc8bf5, 0xb6f196e6, 0xb64c9759, 0xb5a897ce, 0xb5059843, 0xb46298b9, 0xb3c09930, 0xb31f99a9, 0xb27f9a22, 0xb1df9a9c,
0xc9468c4a, 0xc8908ca1, 0xc7db8cf8, 0xc7278d51, 0xc6738dab, 0xc5c08e06, 0xb1409b17, 0xb0a29b94, 0xb0059c11, 0xaf689c8f, 0xaecc9d0e, 0xae319d8e, 0xad979e0f, 0xacfd9e91, 0xac659f14,
0xc50d8e62, 0xc45b8ebf, 0xc3a98f1d, 0xc2f88f7d, 0xc2488fdd, 0xc198903e, 0xabcd9f98, 0xab36a01c, 0xaaa0a0a2, 0xaa0aa129, 0xa976a1b0, 0xa8e2a238, 0xa84fa2c2, 0xa7bda34c, 0xa72ca3d7,
0xc0e990a1, 0xc03a9105, 0xbf8c9169, 0xbedf91cf, 0xbe329236, 0xbd86929e, 0xa69ca463, 0xa60ca4f0, 0xa57ea57e, 0xa4f0a60c, 0xa463a69c, 0xa3d7a72c, 0xa34ca7bd, 0xa2c2a84f, 0xa238a8e2,
0xbcda9307, 0xbc2f9371, 0xbb8593dc, 0xbadc9448, 0xba3394b5, 0xb98b9523, 0xa1b0a976, 0xa129aa0a, 0xa0a2aaa0, 0xa01cab36, 0x9f98abcd, 0x9f14ac65, 0x9e91acfd, 0x9e0fad97, 0x9d8eae31,
0xb8e39592, 0xb83c9603, 0xb7969674, 0xb6f196e6, 0xb64c9759, 0xb5a897ce, 0x9d0eaecc, 0x9c8faf68, 0x9c11b005, 0x9b94b0a2, 0x9b17b140, 0x9a9cb1df, 0x9a22b27f, 0x99a9b31f, 0x9930b3c0,
0xb5059843, 0xb46298b9, 0xb3c09930, 0xb31f99a9, 0xb27f9a22, 0xb1df9a9c, 0x98b9b462, 0x9843b505, 0x97ceb5a8, 0x9759b64c, 0x96e6b6f1, 0x9674b796, 0x9603b83c, 0x9592b8e3, 0x9523b98b,
0xb1409b17, 0xb0a29b94, 0xb0059c11, 0xaf689c8f, 0xaecc9d0e, 0xae319d8e, 0x94b5ba33, 0x9448badc, 0x93dcbb85, 0x9371bc2f, 0x9307bcda, 0x929ebd86, 0x9236be32, 0x91cfbedf, 0x9169bf8c,
0xad979e0f, 0xacfd9e91, 0xac659f14, 0xabcd9f98, 0xab36a01c, 0xaaa0a0a2, 0x9105c03a, 0x90a1c0e9, 0x903ec198, 0x8fddc248, 0x8f7dc2f8, 0x8f1dc3a9, 0x8ebfc45b, 0x8e62c50d, 0x8e06c5c0,
0xaa0aa129, 0xa976a1b0, 0xa8e2a238, 0xa84fa2c2, 0xa7bda34c, 0xa72ca3d7, 0x8dabc673, 0x8d51c727, 0x8cf8c7db, 0x8ca1c890, 0x8c4ac946, 0x8bf5c9fc, 0x8ba0cab2, 0x8b4dcb69, 0x8afbcc21,
0xa69ca463, 0xa60ca4f0, 0xa57ea57e, 0xa4f0a60c, 0xa463a69c, 0xa3d7a72c, 0x8aaaccd9, 0x8a5acd92, 0x8a0cce4b, 0x89becf04, 0x8972cfbe, 0x8927d079, 0x88ddd134, 0x8894d1ef, 0x884cd2ab,
0xa34ca7bd, 0xa2c2a84f, 0xa238a8e2, 0xa1b0a976, 0xa129aa0a, 0xa0a2aaa0, 0x8805d367, 0x87c0d424, 0x877bd4e1, 0x8738d59e, 0x86f6d65c, 0x86b6d71b, 0x8676d7d9, 0x8637d898, 0x85fad958,
0xa01cab36, 0x9f98abcd, 0x9f14ac65, 0x9e91acfd, 0x9e0fad97, 0x9d8eae31, 0x85beda18, 0x8583dad8, 0x8549db99, 0x8511dc59, 0x84d9dd1b, 0x84a3dddc, 0x846ede9e, 0x843adf61, 0x8407e023,
0x9d0eaecc, 0x9c8faf68, 0x9c11b005, 0x9b94b0a2, 0x9b17b140, 0x9a9cb1df, 0x83d6e0e6, 0x83a6e1a9, 0x8377e26d, 0x8349e330, 0x831ce3f4, 0x82f1e4b9, 0x82c6e57d, 0x829de642, 0x8276e707,
0x9a22b27f, 0x99a9b31f, 0x9930b3c0, 0x98b9b462, 0x9843b505, 0x97ceb5a8, 0x824fe7cd, 0x822ae892, 0x8205e958, 0x81e2ea1e, 0x81c1eae4, 0x81a0ebab, 0x8181ec71, 0x8163ed38, 0x8146edff,
0x9759b64c, 0x96e6b6f1, 0x9674b796, 0x9603b83c, 0x9592b8e3, 0x9523b98b, 0x812aeec6, 0x8110ef8d, 0x80f6f055, 0x80def11c, 0x80c8f1e4, 0x80b2f2ac, 0x809ef374, 0x808bf43c, 0x8079f505,
0x94b5ba33, 0x9448badc, 0x93dcbb85, 0x9371bc2f, 0x9307bcda, 0x929ebd86, 0x8068f5cd, 0x8059f695, 0x804bf75e, 0x803ef827, 0x8032f8ef, 0x8027f9b8, 0x801efa81, 0x8016fb4a, 0x800ffc13,
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, 0x800afcdc, 0x8006fda5, 0x8002fe6e, 0x8001ff37,
}; };
/* Returns the multiplication of \conj{a} and {b}. */ /* 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 #if __ARM_ARCH__ >= 6
int32_t t = b; int32_t t = b;
__asm__ ("smuad %0, %0, %1" : "+r"(t) : "r"(a)); __asm__ ("smuad %0, %0, %1" : "+r"(t) : "r"(a));
@ -86,12 +71,12 @@ namespace External::Android
__asm__ ("pkhtb %0, %0, %1, ASR #16" : "+r"(t) : "r"(b)); __asm__ ("pkhtb %0, %0, %1, ASR #16" : "+r"(t) : "r"(b));
return t; return t;
#else #else
return (((a >> 16) * (b >> 16) + (int16_t) a * (int16_t) b) & ~0xFFFF) | return (((a >> 16) * (b >> 16) + static_cast<int16_t> (a) * static_cast<int16_t> (b)) & ~0xFFFF) |
((((a >> 16) * (int16_t) b - (int16_t) a * (b >> 16)) >> 16) & 0xFFFF); ((((a >> 16) * static_cast<int16_t> (b) - static_cast<int16_t> (a) * (b >> 16)) >> 16) & 0xFFFF);
#endif #endif
} }
static inline int32_t half (int32_t a)
{ static inline int32_t half (int32_t a) {
#if __ARM_ARCH__ >= 6 #if __ARM_ARCH__ >= 6
__asm__ ("shadd16 %0, %0, %1" : "+r"(a) : "r"(0)); __asm__ ("shadd16 %0, %0, %1" : "+r"(a) : "r"(0));
return a; return a;
@ -99,36 +84,31 @@ namespace External::Android
return ((a >> 1) & ~0x8000) | (a & 0x8000); return ((a >> 1) & ~0x8000) | (a & 0x8000);
#endif #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; int scale = LOG_FFT_SIZE, i, p, r;
for (r = 0, i = 1; i < n; ++i) for (r = 0, i = 1; i < n; ++i) {
{ for (p = n; !(p & r); p >>= 1, r ^= p)
for (p = n; !(p & r); p >>= 1, r ^= p); ;
if (i < r) if (i < r) {
{
int32_t t = v [i]; int32_t t = v [i];
v [i] = v [r]; v [i] = v [r];
v [r] = t; v [r] = t;
} }
} }
for (p = 1; p < n; p <<= 1) for (p = 1; p < n; p <<= 1) {
{
--scale; --scale;
for (i = 0; i < n; i += p << 1) for (i = 0; i < n; i += p << 1) {
{
int32_t x = half (v [i]); int32_t x = half (v [i]);
int32_t y = half (v [i + p]); int32_t y = half (v [i + p]);
v [i] = x + y; v [i] = x + y;
v [i + p] = 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); int32_t w = MAX_FFT_SIZE / 4 - (r << scale);
i = w >> 31; i = w >> 31;
w = twiddle [(w ^ i) - i] ^ (i << 16); w = twiddle [(w ^ i) - i] ^ (i << 16);
for (i = r; i < n; i += p << 1) for (i = r; i < n; i += p << 1) {
{
int32_t x = half (v [i]); int32_t x = half (v [i]);
int32_t y = mult (w, v [i + p]); int32_t y = mult (w, v [i + p]);
v [i] = x - y; v [i] = x - y;
@ -137,15 +117,15 @@ namespace External::Android
} }
} }
} }
void fixed_fft_real (int n, int32_t* v)
{ void fixed_fft_real (int n, int32_t* v) {
int scale = LOG_FFT_SIZE, m = n >> 1, i; int scale = LOG_FFT_SIZE, m = n >> 1, i;
fixed_fft (n, v); fixed_fft (n, v);
for (i = 1; i <= n; i <<= 1, --scale); for (i = 1; i <= n; i <<= 1, --scale)
;
v [0] = mult (~v [0], 0x80008000); v [0] = mult (~v [0], 0x80008000);
v [m] = half (v [m]); v [m] = half (v [m]);
for (i = 1; i < n >> 1; ++i) for (i = 1; i < n >> 1; ++i) {
{
int32_t x = half (v [i]); int32_t x = half (v [i]);
int32_t z = half (v [n - i]); int32_t z = half (v [n - i]);
int32_t y = z - (x ^ 0xFFFF); int32_t y = z - (x ^ 0xFFFF);
@ -156,30 +136,27 @@ namespace External::Android
} }
} }
bool doFft (uint8_t* fft, uint8_t* waveform) bool doFft (uint8_t* fft, uint8_t* waveform) {
{
int32_t workspace [WAVE_BUFFER_SIZE >> 1]; int32_t workspace [WAVE_BUFFER_SIZE >> 1];
int32_t nonzero = 0; int32_t nonzero = 0;
for (uint32_t i = 0; i < WAVE_BUFFER_SIZE; i += 2) for (uint32_t i = 0; i < WAVE_BUFFER_SIZE; i += 2) {
{ workspace [i >> 1] = ((waveform [i] ^ 0x80) << 24) | ((waveform [i + 1] ^ 0x80) << 8);
workspace[i >> 1] =
((waveform[i] ^ 0x80) << 24) | ((waveform[i + 1] ^ 0x80) << 8);
nonzero |= workspace [i >> 1]; nonzero |= workspace [i >> 1];
} }
if (nonzero) if (nonzero) {
{
fixed_fft_real (WAVE_BUFFER_SIZE >> 1, workspace); fixed_fft_real (WAVE_BUFFER_SIZE >> 1, workspace);
} }
for (uint32_t i = 0; i < WAVE_BUFFER_SIZE; i += 2) for (uint32_t i = 0; i < WAVE_BUFFER_SIZE; i += 2) {
{
short tmp = workspace [i >> 1] >> 21; short tmp = workspace [i >> 1] >> 21;
while (tmp > 127 || tmp < -128) tmp >>= 1; while (tmp > 127 || tmp < -128)
tmp >>= 1;
fft [i] = tmp; fft [i] = tmp;
tmp = workspace [i >> 1]; tmp = workspace [i >> 1];
tmp >>= 5; tmp >>= 5;
while (tmp > 127 || tmp < -128) tmp >>= 1; while (tmp > 127 || tmp < -128)
tmp >>= 1;
fft [i + 1] = tmp; fft [i + 1] = tmp;
} }
return true; return true;
} }
} } // namespace External::Android

View File

@ -1,12 +1,11 @@
#pragma once #pragma once
#include <iostream>
#include <cstdio>
#include <cstdint> #include <cstdint>
#include <cstdio>
#include <iostream>
#define WAVE_BUFFER_SIZE 1024 #define WAVE_BUFFER_SIZE 1024
namespace External::Android namespace External::Android {
{
bool doFft (uint8_t* fft, uint8_t* waveform); bool doFft (uint8_t* fft, uint8_t* waveform);
} }

View File

@ -2,34 +2,26 @@
#include "WallpaperEngine/Logging/CLog.h" #include "WallpaperEngine/Logging/CLog.h"
#include <climits> #include <climits>
#include <cstdlib> #include <cstdlib>
#include <sstream>
#include <filesystem> #include <filesystem>
#include <sstream>
#include <sys/stat.h> #include <sys/stat.h>
const char* assets_default_paths [] = { const char* assets_default_paths [] = {".steam/steam/steamapps/common", ".local/share/Steam/steamapps/common",
".steam/steam/steamapps/common",
".local/share/Steam/steamapps/common",
".var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common", ".var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/common",
"snap/steam/common/.local/share/Steam/steamapps/common", "snap/steam/common/.local/share/Steam/steamapps/common", nullptr};
nullptr
};
const char* workshop_content_default_paths [] = { const char* workshop_content_default_paths [] = {
".local/share/Steam/steamapps/workshop/content", ".local/share/Steam/steamapps/workshop/content", ".steam/steam/steamapps/workshop/content",
".steam/steam/steamapps/workshop/content",
".var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/workshop/content", ".var/app/com.valvesoftware.Steam/.local/share/Steam/steamapps/workshop/content",
"snap/steam/common/.local/share/Steam/steamapps/workshop/content", "snap/steam/common/.local/share/Steam/steamapps/workshop/content", nullptr};
nullptr
};
std::filesystem::path detectHomepath () std::filesystem::path detectHomepath () {
{
char* home = getenv ("HOME"); char* home = getenv ("HOME");
if (home == nullptr) if (home == nullptr)
sLog.exception ("Cannot find home directory for the current user"); 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)) if (!std::filesystem::is_directory (path))
sLog.exception ("Cannot find home directory for current user, ", home, " is not a directory"); sLog.exception ("Cannot find home directory for current user, ", home, " is not a directory");
@ -37,12 +29,10 @@ std::filesystem::path detectHomepath ()
return home; 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 (); 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; auto currentpath = std::filesystem::path (homepath) / *current / std::to_string (appID) / contentID;
if (!std::filesystem::exists (currentpath) || !std::filesystem::is_directory (currentpath)) 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); 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 (); 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; auto currentpath = std::filesystem::path (homepath) / *current / appDirectory / path;
if (!std::filesystem::exists (currentpath) || !std::filesystem::is_directory (currentpath)) if (!std::filesystem::exists (currentpath) || !std::filesystem::is_directory (currentpath))

View File

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <string>
#include <filesystem> #include <filesystem>
namespace Steam::FileSystem #include <string>
{
namespace Steam::FileSystem {
std::filesystem::path workshopDirectory (int appID, const std::string& contentID); std::filesystem::path workshopDirectory (int appID, const std::string& contentID);
std::filesystem::path appDirectory (const std::string& appDirectory, const std::string& path); std::filesystem::path appDirectory (const std::string& appDirectory, const std::string& path);
} } // namespace Steam::FileSystem

View File

@ -12,8 +12,7 @@
using namespace WallpaperEngine::Application; using namespace WallpaperEngine::Application;
struct option long_options[] = { struct option long_options [] = {{"screen-root", required_argument, nullptr, 'r'},
{ "screen-root", required_argument, nullptr, 'r' },
{"bg", required_argument, nullptr, 'b'}, {"bg", required_argument, nullptr, 'b'},
{"window", required_argument, nullptr, 'w'}, {"window", required_argument, nullptr, 'w'},
{"pkg", required_argument, nullptr, 'p'}, {"pkg", required_argument, nullptr, 'p'},
@ -31,8 +30,7 @@ struct option long_options[] = {
{"disable-mouse", no_argument, nullptr, 'e'}, {"disable-mouse", no_argument, nullptr, 'e'},
{"scaling", required_argument, nullptr, 't'}, {"scaling", required_argument, nullptr, 't'},
{"clamping", required_argument, nullptr, 't'}, {"clamping", required_argument, nullptr, 't'},
{ nullptr, 0, nullptr, 0 } {nullptr, 0, nullptr, 0}};
};
/* std::hash::operator() isn't constexpr, so it can't be used to get hash values as compile-time constants /* 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 * So here is customHash. It skips all spaces, so hashes for " find " and "fi nd" are the same
@ -52,8 +50,7 @@ constexpr size_t customHash(const char* str) {
return hash % C; return hash % C;
} }
std::string stringPathFixes (const std::string& s) std::string stringPathFixes (const std::string& s) {
{
if (s.empty ()) if (s.empty ())
return s; return s;
@ -61,18 +58,14 @@ std::string stringPathFixes (const std::string& s)
// remove single-quotes from the arguments // remove single-quotes from the arguments
if (str [0] == '\'' && str [str.size () - 1] == '\'') if (str [0] == '\'' && str [str.size () - 1] == '\'')
str str.erase (str.size () - 1, 1).erase (0, 1);
.erase (str.size () - 1, 1)
.erase (0, 1);
return std::move (str); return std::move (str);
} }
CApplicationContext::CApplicationContext (int argc, char* argv[]) CApplicationContext::CApplicationContext (int argc, char* argv []) {
{
// setup structs with sane default values for now // setup structs with sane default values for now
this->settings = this->settings = {
{
.general = .general =
{ {
.onlyListProperties = false, .onlyListProperties = false,
@ -86,15 +79,14 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
.mode = NORMAL_WINDOW, .mode = NORMAL_WINDOW,
.maximumFPS = 30, .maximumFPS = 30,
.pauseOnFullscreen = true, .pauseOnFullscreen = true,
.window = { .geometry = {}, .clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs, .window =
.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs, },
},
.audio =
{ {
.enabled = true, .geometry = {},
.volume = 15, .clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs,
.automute = true .scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs,
}, },
},
.audio = {.enabled = true, .volume = 15, .automute = true},
.mouse = .mouse =
{ {
.enabled = true, .enabled = true,
@ -111,13 +103,9 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
std::string lastScreen; std::string lastScreen;
while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w:mnt:", long_options, nullptr)) != -1) while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w:mnt:", long_options, nullptr)) != -1) {
{ switch (c) {
switch (c) case 'n': this->settings.render.pauseOnFullscreen = false; break;
{
case 'n':
this->settings.render.pauseOnFullscreen = false;
break;
case 'b': case 'b':
if (lastScreen.empty ()) if (lastScreen.empty ())
@ -129,25 +117,22 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
this->settings.general.screenScalings [lastScreen] = this->settings.render.window.scalingMode; this->settings.general.screenScalings [lastScreen] = this->settings.render.window.scalingMode;
break; break;
case 'o': case 'o': {
{
std::string value = optarg; 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 // properties without value are treated as booleans for now
if (equals == std::string::npos) if (equals == std::string::npos)
this->settings.general.properties [value] = "1"; this->settings.general.properties [value] = "1";
else else
this->settings.general.properties [value.substr (0, equals)] = value.substr (equals + 1); this->settings.general.properties [value.substr (0, equals)] = value.substr (equals + 1);
} } break;
break;
case 'l': case 'l': this->settings.general.onlyListProperties = true; break;
this->settings.general.onlyListProperties = true;
break;
case 'r': 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); sLog.exception ("Cannot specify the same screen more than once: ", optarg);
if (this->settings.render.mode == EXPLICIT_WINDOW) if (this->settings.render.mode == EXPLICIT_WINDOW)
sLog.exception ("Cannot run in both background and window mode"); sLog.exception ("Cannot run in both background and window mode");
@ -162,8 +147,7 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
if (this->settings.render.mode == DESKTOP_BACKGROUND) if (this->settings.render.mode == DESKTOP_BACKGROUND)
sLog.exception ("Cannot run in both background and window mode"); sLog.exception ("Cannot run in both background and window mode");
if (optarg != nullptr) if (optarg != nullptr) {
{
this->settings.render.mode = EXPLICIT_WINDOW; this->settings.render.mode = EXPLICIT_WINDOW;
// read window geometry // read window geometry
char* pos = optarg; char* pos = optarg;
@ -185,64 +169,56 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
this->settings.general.defaultBackground = translateBackground (stringPathFixes (optarg)); this->settings.general.defaultBackground = translateBackground (stringPathFixes (optarg));
break; break;
case 's': case 's': this->settings.audio.enabled = false; break;
this->settings.audio.enabled = false;
break;
case 'h': case 'h':
printHelp (argv [0]); printHelp (argv [0]);
std::exit (0); std::exit (0);
break; break;
case 'f': case 'f': this->settings.render.maximumFPS = atoi (optarg); break;
this->settings.render.maximumFPS = atoi (optarg);
break;
case 'a': case 'a': this->settings.general.assets = stringPathFixes (optarg); break;
this->settings.general.assets = stringPathFixes (optarg);
break;
case 'v': case 'v': this->settings.audio.volume = std::max (atoi (optarg), 128); break;
this->settings.audio.volume = std::max (atoi (optarg), 128);
break;
case 'c': case 'c':
this->settings.screenshot.take = true; this->settings.screenshot.take = true;
this->settings.screenshot.path = stringPathFixes (optarg); this->settings.screenshot.path = stringPathFixes (optarg);
break; break;
case 'm': case 'm': this->settings.audio.automute = false; break;
this->settings.audio.automute = false;
break;
case 'e': case 'e': this->settings.mouse.enabled = false; break;
this->settings.mouse.enabled = false;
break;
case 't': case 't': {
{
size_t hash = customHash (optarg); size_t hash = customHash (optarg);
// Use a switch statement with the hash // Use a switch statement with the hash
switch (hash) { switch (hash) {
// --scale options // --scale options
case customHash ("stretch"): case customHash ("stretch"):
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::StretchUVs; this->settings.render.window.scalingMode =
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::StretchUVs;
break; break;
case customHash ("fit"): case customHash ("fit"):
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFitUVs; this->settings.render.window.scalingMode =
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFitUVs;
break; break;
case customHash ("fill"): case customHash ("fill"):
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFillUVs; this->settings.render.window.scalingMode =
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFillUVs;
break; break;
case customHash ("default"): case customHash ("default"):
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs; this->settings.render.window.scalingMode =
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs;
break; break;
// --clamp options // --clamp options
case customHash ("clamp"): case customHash ("clamp"):
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs; this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs;
break; break;
case customHash ("border"): case customHash ("border"):
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVsBorder; this->settings.render.window.clamp =
WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVsBorder;
break; break;
case customHash ("repeat"): case customHash ("repeat"):
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::NoFlags; this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::NoFlags;
@ -253,22 +229,15 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
sLog.exception ("Wrong argument provided for --scale or --clamp option."); sLog.exception ("Wrong argument provided for --scale or --clamp option.");
break; break;
} }
} } break;
break; default: sLog.out ("Default on path parsing: ", optarg); break;
default:
sLog.out ("Default on path parsing: ", optarg);
break;
} }
} }
if (this->settings.general.defaultBackground.empty ()) if (this->settings.general.defaultBackground.empty ()) {
{ if (optind < argc && strlen (argv [optind]) > 0) {
if (optind < argc && strlen (argv[optind]) > 0)
{
this->settings.general.defaultBackground = translateBackground (argv [optind]); this->settings.general.defaultBackground = translateBackground (argv [optind]);
} } else {
else
{
printHelp (argv [0]); printHelp (argv [0]);
std::exit (0); std::exit (0);
} }
@ -284,42 +253,36 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
this->state.audio.volume = this->settings.audio.volume; 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) if (bgIdOrPath.find ('/') == std::string::npos)
return Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, bgIdOrPath); return Steam::FileSystem::workshopDirectory (WORKSHOP_APP_ID, bgIdOrPath);
return bgIdOrPath; return bgIdOrPath;
} }
void CApplicationContext::validateAssets () void CApplicationContext::validateAssets () {
{ if (!this->settings.general.assets.empty ()) {
if (!this->settings.general.assets.empty ()) sLog.out ("Using wallpaper engine's assets at ", this->settings.general.assets,
{ " based on --assets-dir parameter");
sLog.out ("Using wallpaper engine's assets at ", this->settings.general.assets, " based on --assets-dir parameter");
return; return;
} }
try try {
{
this->settings.general.assets = Steam::FileSystem::appDirectory (APP_DIRECTORY, "assets"); this->settings.general.assets = Steam::FileSystem::appDirectory (APP_DIRECTORY, "assets");
} } catch (std::runtime_error&) {
catch (std::runtime_error&)
{
// set current path as assets' folder // set current path as assets' folder
std::filesystem::path directory = std::filesystem::canonical ("/proc/self/exe").parent_path () / "assets"; std::filesystem::path directory = std::filesystem::canonical ("/proc/self/exe").parent_path () / "assets";
} }
} }
void CApplicationContext::validateScreenshot () void CApplicationContext::validateScreenshot () {
{
if (!this->settings.screenshot.take) if (!this->settings.screenshot.take)
return; return;
if (!this->settings.screenshot.path.has_extension ()) if (!this->settings.screenshot.path.has_extension ())
sLog.exception ("Cannot determine screenshot format"); 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") if (extension == ".bmp")
this->settings.screenshot.format = FIF_BMP; this->settings.screenshot.format = FIF_BMP;
@ -331,8 +294,7 @@ void CApplicationContext::validateScreenshot ()
sLog.exception ("Cannot determine screenshot format, unknown extension ", extension); 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 ("Usage: ", route, " [options] background_path/background_id");
sLog.out (""); sLog.out ("");
sLog.out ("where background_path/background_id can be:"); 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--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--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--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--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--assets-dir <path>\t\t\tFolder where the assets are stored");
sLog.out ("\t--screenshot\t\t\t\tTakes a screenshot of the background"); 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--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--no-fullscreen-pause\tPrevents the background pausing when an app is fullscreen");
sLog.out ("\t--disable-mouse\tDisables mouse interactions"); 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 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"); \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.");
} }

View File

@ -14,18 +14,15 @@
#include "WallpaperEngine/Assets/ITexture.h" #include "WallpaperEngine/Assets/ITexture.h"
#include "WallpaperEngine/Render/CWallpaperState.h" #include "WallpaperEngine/Render/CWallpaperState.h"
namespace WallpaperEngine::Application namespace WallpaperEngine::Application {
{
/** /**
* Application information as parsed off the command line arguments * Application information as parsed off the command line arguments
*/ */
class CApplicationContext class CApplicationContext {
{
public: public:
CApplicationContext (int argc, char* argv []); CApplicationContext (int argc, char* argv []);
enum WINDOW_MODE enum WINDOW_MODE {
{
/** Default window mode */ /** Default window mode */
NORMAL_WINDOW = 0, NORMAL_WINDOW = 0,
/** Draw to the window server desktop */ /** Draw to the window server desktop */
@ -34,13 +31,11 @@ namespace WallpaperEngine::Application
EXPLICIT_WINDOW = 2, EXPLICIT_WINDOW = 2,
}; };
struct struct {
{
/** /**
* General settings * General settings
*/ */
struct struct {
{
/** If the user requested a list of properties for the given background */ /** If the user requested a list of properties for the given background */
bool onlyListProperties; bool onlyListProperties;
@ -60,8 +55,7 @@ namespace WallpaperEngine::Application
/** /**
* Render settings * Render settings
*/ */
struct struct {
{
/** The mode to run the background in */ /** The mode to run the background in */
WINDOW_MODE mode; WINDOW_MODE mode;
/** Maximum FPS */ /** Maximum FPS */
@ -69,8 +63,7 @@ namespace WallpaperEngine::Application
/** Indicates if pausing should happen when something goes fullscreen */ /** Indicates if pausing should happen when something goes fullscreen */
bool pauseOnFullscreen; bool pauseOnFullscreen;
struct struct {
{
/** The window size used in explicit window */ /** The window size used in explicit window */
glm::ivec4 geometry; glm::ivec4 geometry;
WallpaperEngine::Assets::ITexture::TextureFlags clamp; WallpaperEngine::Assets::ITexture::TextureFlags clamp;
@ -81,8 +74,7 @@ namespace WallpaperEngine::Application
/** /**
* Audio settings * Audio settings
*/ */
struct struct {
{
/** If the audio system is enabled */ /** If the audio system is enabled */
bool enabled; bool enabled;
/** Sound volume (0-128) */ /** Sound volume (0-128) */
@ -94,8 +86,7 @@ namespace WallpaperEngine::Application
/** /**
* Mouse input settings * Mouse input settings
*/ */
struct struct {
{
/** If the mouse movement is enabled */ /** If the mouse movement is enabled */
bool enabled; bool enabled;
} mouse; } mouse;
@ -103,8 +94,7 @@ namespace WallpaperEngine::Application
/** /**
* Screenshot settings * Screenshot settings
*/ */
struct struct {
{
/** If an screenshot should be taken */ /** If an screenshot should be taken */
bool take; bool take;
/** The path to where the screenshot must be saved */ /** The path to where the screenshot must be saved */
@ -140,4 +130,4 @@ namespace WallpaperEngine::Application
*/ */
static void printHelp (const char* route); static void printHelp (const char* route);
}; };
} } // namespace WallpaperEngine::Application

View File

@ -2,28 +2,23 @@
#include "CApplicationContext.h" #include "CApplicationContext.h"
namespace WallpaperEngine::Application namespace WallpaperEngine::Application {
{
/** /**
* Represents current application state * Represents current application state
*/ */
class CApplicationState class CApplicationState {
{
public: public:
struct struct {
{
bool keepRunning; bool keepRunning;
} general {}; } general {};
struct struct {
{
bool enabled; bool enabled;
int volume; int volume;
} audio {}; } audio {};
struct struct {
{
bool enabled; bool enabled;
} mouse {}; } mouse {};
}; };
} } // namespace WallpaperEngine::Application

View File

@ -1,15 +1,15 @@
#include "CWallpaperApplication.h" #include "CWallpaperApplication.h"
#include "Steam/FileSystem/FileSystem.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/Application/CApplicationState.h"
#include "WallpaperEngine/Assets/CAssetLoadException.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/Audio/Drivers/Detectors/CPulseAudioPlayingDetector.h"
#include "WallpaperEngine/Core/CVideo.h"
#include "WallpaperEngine/Input/Drivers/CGLFWMouseInput.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/Input/Drivers/CWaylandMouseInput.h"
#include "WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h" #include "WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h"
@ -18,18 +18,15 @@ float g_Time;
float g_TimeLast; float g_TimeLast;
float g_Daytime; float g_Daytime;
namespace WallpaperEngine::Application namespace WallpaperEngine::Application {
{
CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) : CWallpaperApplication::CWallpaperApplication (CApplicationContext& context) :
m_context (context), m_context (context),
m_defaultBackground (nullptr) m_defaultBackground (nullptr) {
{
this->loadBackgrounds (); this->loadBackgrounds ();
this->setupProperties (); this->setupProperties ();
} }
CWallpaperApplication::~CWallpaperApplication () CWallpaperApplication::~CWallpaperApplication () {
{
delete context; delete context;
delete videoDriver; delete videoDriver;
delete audioContext; delete audioContext;
@ -37,9 +34,8 @@ namespace WallpaperEngine::Application
delete inputContext; delete inputContext;
} }
void CWallpaperApplication::setupContainer (CCombinedContainer& container, const std::string& bg) const void CWallpaperApplication::setupContainer (CCombinedContainer& container, const std::string& bg) const {
{ const std::filesystem::path basepath = bg;
std::filesystem::path basepath = bg;
container.add (new CDirectory (basepath)); container.add (new CDirectory (basepath));
container.addPkg (basepath / "scene.pkg"); container.addPkg (basepath / "scene.pkg");
@ -51,29 +47,21 @@ namespace WallpaperEngine::Application
bool relative = true; bool relative = true;
bool absolute = true; bool absolute = true;
try try {
{
container.add (new CDirectory ("../share/")); container.add (new CDirectory ("../share/"));
} } catch (CAssetLoadException&) {
catch (CAssetLoadException& ex)
{
relative = false; relative = false;
} }
try try {
{
container.add (new CDirectory (DATADIR)); container.add (new CDirectory (DATADIR));
} } catch (CAssetLoadException&) {
catch (CAssetLoadException& ex)
{
absolute = false; absolute = false;
} }
if (!relative && !absolute) if (!relative && !absolute)
sLog.error ( sLog.error ("WARNING: Shader patches directory cannot be found, this might make some backgrounds not work "
"WARNING: Shader patches directory cannot be found, this might make some backgrounds not work " "properly");
"properly"
);
// TODO: move this somewhere else? // TODO: move this somewhere else?
auto* virtualContainer = new CVirtualContainer (); auto* virtualContainer = new CVirtualContainer ();
@ -87,8 +75,7 @@ namespace WallpaperEngine::Application
// add the effect file for screen bloom // add the effect file for screen bloom
// add some model for the image element even if it's going to waste rendering cycles // add some model for the image element even if it's going to waste rendering cycles
virtualContainer->add ( virtualContainer->add ("effects/wpenginelinux/bloomeffect.json",
"effects/wpenginelinux/bloomeffect.json",
"{" "{"
"\t\"name\":\"camerabloom_wpengine_linux\"," "\t\"name\":\"camerabloom_wpengine_linux\","
"\t\"group\":\"wpengine_linux_camera\"," "\t\"group\":\"wpengine_linux_camera\","
@ -144,20 +131,14 @@ namespace WallpaperEngine::Application
"\t\t\t]" "\t\t\t]"
"\t\t}" "\t\t}"
"\t]" "\t]"
"}" "}");
);
virtualContainer->add ( virtualContainer->add ("models/wpenginelinux.json", "{"
"models/wpenginelinux.json",
"{"
"\t\"material\":\"materials/wpenginelinux.json\"" "\t\"material\":\"materials/wpenginelinux.json\""
"}" "}");
);
// models require materials, so add that too // models require materials, so add that too
virtualContainer->add ( virtualContainer->add ("materials/wpenginelinux.json", "{"
"materials/wpenginelinux.json",
"{"
"\t\"passes\":" "\t\"passes\":"
"\t\t[" "\t\t["
"\t\t\t{" "\t\t\t{"
@ -169,22 +150,19 @@ namespace WallpaperEngine::Application
"\t\t\t\t\"textures\": [\"_rt_FullFrameBuffer\"]" "\t\t\t\t\"textures\": [\"_rt_FullFrameBuffer\"]"
"\t\t\t}" "\t\t\t}"
"\t\t]" "\t\t]"
"}" "}");
);
container.add (virtualContainer); container.add (virtualContainer);
} }
void CWallpaperApplication::loadBackgrounds () void CWallpaperApplication::loadBackgrounds () {
{ for (const auto& [background, path] : this->m_context.settings.general.screenBackgrounds) {
for (const auto& it : this->m_context.settings.general.screenBackgrounds)
{
// ignore the screen settings if there was no background specified // ignore the screen settings if there was no background specified
// the default will be used // the default will be used
if (it.second.empty ()) if (path.empty ())
continue; continue;
this->m_backgrounds[it.first] = this->loadBackground (it.second); this->m_backgrounds [background] = this->loadBackground (path);
} }
// load the default project if required // load the default project if required
@ -192,8 +170,7 @@ namespace WallpaperEngine::Application
this->m_defaultBackground = this->loadBackground (this->m_context.settings.general.defaultBackground); 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 (); auto* container = new CCombinedContainer ();
this->setupContainer (*container, bg); this->setupContainer (*container, bg);
@ -201,16 +178,13 @@ namespace WallpaperEngine::Application
return Core::CProject::fromFile ("project.json", container); return Core::CProject::fromFile ("project.json", container);
} }
void CWallpaperApplication::setupPropertiesForProject (Core::CProject* project) void CWallpaperApplication::setupPropertiesForProject (const Core::CProject* project) {
{
// show properties if required // show properties if required
for (auto cur : project->getProperties ()) for (const auto cur : project->getProperties ()) {
{
// update the value of the property // update the value of the property
auto override = this->m_context.settings.general.properties.find (cur->getName ()); 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 ()); sLog.out ("Applying override value for ", cur->getName ());
cur->update (override->second); cur->update (override->second);
@ -221,59 +195,51 @@ namespace WallpaperEngine::Application
} }
} }
void CWallpaperApplication::setupProperties () void CWallpaperApplication::setupProperties () {
{ for (const auto& [backgrounc, info] : this->m_backgrounds)
for (const auto& it : this->m_backgrounds) this->setupPropertiesForProject (info);
this->setupPropertiesForProject (it.second);
if (this->m_defaultBackground != nullptr) if (this->m_defaultBackground != nullptr)
this->setupPropertiesForProject (this->m_defaultBackground); this->setupPropertiesForProject (this->m_defaultBackground);
} }
void CWallpaperApplication::takeScreenshot ( void CWallpaperApplication::takeScreenshot (const Render::CRenderContext& context,
const Render::CRenderContext& context, const std::filesystem::path& filename, FREE_IMAGE_FORMAT format 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 // this should be getting called at the end of the frame, so the right thing should be bound already
int width = context.getOutput ().getFullWidth (); const int width = context.getOutput ().getFullWidth ();
int height = context.getOutput ().getFullHeight (); const int height = context.getOutput ().getFullHeight ();
// build the output file with FreeImage // build the output file with FreeImage
static FIBITMAP* bitmap = FreeImage_Allocate (width, height, 24); static FIBITMAP* bitmap = FreeImage_Allocate (width, height, 24);
RGBQUAD color; RGBQUAD color;
int xoffset = 0; 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 // activate opengl context so we can read from the framebuffer
viewport.second->makeCurrent (); viewport->makeCurrent ();
// make room for storing the pixel of this viewport // 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]; auto* buffer = new uint8_t [viewport->viewport.z * viewport->viewport.w * sizeof (uint8_t) * 3];
uint8_t* pixel = buffer; const uint8_t* pixel = buffer;
// read the viewport data into the pixel buffer // read the viewport data into the pixel buffer
glReadPixels ( glReadPixels (viewport->viewport.x, viewport->viewport.y, viewport->viewport.z, viewport->viewport.w, GL_RGB,
viewport.second->viewport.x, viewport.second->viewport.y, GL_UNSIGNED_BYTE, buffer);
viewport.second->viewport.z, viewport.second->viewport.w,
GL_RGB, GL_UNSIGNED_BYTE, buffer
);
// now get access to the pixels // now get access to the pixels
for (int y = viewport.second->viewport.w; y > 0; y--) for (int y = viewport->viewport.w; y > 0; y--) {
{ for (int x = 0; x < viewport->viewport.z; x++) {
for (int x = 0; x < viewport.second->viewport.z; x++)
{
color.rgbRed = *pixel++; color.rgbRed = *pixel++;
color.rgbGreen = *pixel++; color.rgbGreen = *pixel++;
color.rgbBlue = *pixel++; color.rgbBlue = *pixel++;
// set the pixel in the destination // 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) if (viewport->single)
xoffset += viewport.second->viewport.z; xoffset += viewport->viewport.z;
// free the buffer allocated for the viewport // free the buffer allocated for the viewport
delete [] buffer; delete [] buffer;
@ -285,25 +251,25 @@ namespace WallpaperEngine::Application
FreeImage_Unload (bitmap); FreeImage_Unload (bitmap);
} }
void CWallpaperApplication::show () void CWallpaperApplication::show () {
{
#ifdef ENABLE_WAYLAND #ifdef ENABLE_WAYLAND
const bool WAYLAND_DISPLAY = getenv ("WAYLAND_DISPLAY"); const bool WAYLAND_DISPLAY = getenv ("WAYLAND_DISPLAY");
// setup the right video driver based on the environment and the startup mode requested // 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) if (WAYLAND_DISPLAY && this->m_context.settings.render.mode == CApplicationContext::DESKTOP_BACKGROUND) {
{ const auto waylandDriver = new WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver (this->m_context, *this);
auto waylandDriver = new WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver (this->m_context, *this); inputContext = new WallpaperEngine::Input::CInputContext (
inputContext = new WallpaperEngine::Input::CInputContext (new WallpaperEngine::Input::Drivers::CWaylandMouseInput (waylandDriver)); new WallpaperEngine::Input::Drivers::CWaylandMouseInput (waylandDriver));
videoDriver = waylandDriver; videoDriver = waylandDriver;
} } else
else
#endif #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 // 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; videoDriver = x11Driver;
} }
@ -311,7 +277,8 @@ namespace WallpaperEngine::Application
// stereo mix recorder for audio processing // stereo mix recorder for audio processing
WallpaperEngine::Audio::Drivers::Recorders::CPulseAudioPlaybackRecorder audioRecorder; WallpaperEngine::Audio::Drivers::Recorders::CPulseAudioPlaybackRecorder audioRecorder;
// audio playing detector // 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 // initialize sdl audio driver
audioDriver = new WallpaperEngine::Audio::Drivers::CSDLAudioDriver (this->m_context, audioDetector, audioRecorder); audioDriver = new WallpaperEngine::Audio::Drivers::CSDLAudioDriver (this->m_context, audioDetector, audioRecorder);
// initialize audio context // initialize audio context
@ -320,23 +287,21 @@ namespace WallpaperEngine::Application
context = new WallpaperEngine::Render::CRenderContext (*videoDriver, *inputContext, *this); context = new WallpaperEngine::Render::CRenderContext (*videoDriver, *inputContext, *this);
// set all the specific wallpapers required // set all the specific wallpapers required
for (const auto& it : this->m_backgrounds) for (const auto& [background, info] : this->m_backgrounds)
context->setWallpaper ( context->setWallpaper (background, WallpaperEngine::Render::CWallpaper::fromWallpaper (
it.first, info->getWallpaper (), *context, *audioContext,
WallpaperEngine::Render::CWallpaper::fromWallpaper (it.second->getWallpaper (), *context, *audioContext, this->m_context.settings.general.screenScalings[it.first]) this->m_context.settings.general.screenScalings [background]));
);
// set the default rendering wallpaper if available // set the default rendering wallpaper if available
if (this->m_defaultBackground != nullptr) if (this->m_defaultBackground != nullptr)
context->setDefaultWallpaper (WallpaperEngine::Render::CWallpaper::fromWallpaper ( 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 time_t seconds;
static struct tm* timeinfo; 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 // update g_Daytime
time (&seconds); time (&seconds);
timeinfo = localtime (&seconds); timeinfo = localtime (&seconds);
@ -356,7 +321,8 @@ namespace WallpaperEngine::Application
if (!this->m_context.settings.screenshot.take || videoDriver->getFrameCounter () < 5) if (!this->m_context.settings.screenshot.take || videoDriver->getFrameCounter () < 5)
continue; 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; this->m_context.settings.screenshot.take = false;
} }
@ -368,29 +334,28 @@ namespace WallpaperEngine::Application
SDL_Quit (); SDL_Quit ();
} }
void CWallpaperApplication::update(Render::Drivers::Output::COutputViewport* viewport) void CWallpaperApplication::update (Render::Drivers::Output::COutputViewport* viewport) {
{
// render the scene // render the scene
context->render (viewport); context->render (viewport);
} }
void CWallpaperApplication::signal (int signal) void CWallpaperApplication::signal (int signal) {
{
this->m_context.state.general.keepRunning = false; this->m_context.state.general.keepRunning = false;
} }
const std::map<std::string, Core::CProject*>& CWallpaperApplication::getBackgrounds () const const std::map<std::string, Core::CProject*>& CWallpaperApplication::getBackgrounds () const {
{
return this->m_backgrounds; return this->m_backgrounds;
} }
Core::CProject* CWallpaperApplication::getDefaultBackground () const Core::CProject* CWallpaperApplication::getDefaultBackground () const {
{
return this->m_defaultBackground; return this->m_defaultBackground;
} }
CApplicationContext& CWallpaperApplication::getContext () const CApplicationContext& CWallpaperApplication::getContext () const {
{
return this->m_context; return this->m_context;
} }
const WallpaperEngine::Render::Drivers::Output::COutput& CWallpaperApplication::getOutput () const {
return this->context->getOutput ();
} }
} // namespace WallpaperEngine::Application

View File

@ -6,8 +6,8 @@
#include "WallpaperEngine/Core/CProject.h" #include "WallpaperEngine/Core/CProject.h"
#include "WallpaperEngine/Render/CWallpaper.h"
#include "WallpaperEngine/Render/CRenderContext.h" #include "WallpaperEngine/Render/CRenderContext.h"
#include "WallpaperEngine/Render/CWallpaper.h"
#include "WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h" #include "WallpaperEngine/Render/Drivers/CX11OpenGLDriver.h"
#ifdef ENABLE_WAYLAND #ifdef ENABLE_WAYLAND
#include "WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h" #include "WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.h"
@ -28,15 +28,13 @@
#include "WallpaperEngine/Input/CInputContext.h" #include "WallpaperEngine/Input/CInputContext.h"
namespace WallpaperEngine::Application namespace WallpaperEngine::Application {
{
/** /**
* Small wrapper class over the actual wallpaper's main application skeleton * Small wrapper class over the actual wallpaper's main application skeleton
* *
* @author Alexis Maiquez <almamu@almamu.com> * @author Alexis Maiquez <almamu@almamu.com>
*/ */
class CWallpaperApplication class CWallpaperApplication {
{
public: public:
explicit CWallpaperApplication (CApplicationContext& context); explicit CWallpaperApplication (CApplicationContext& context);
~CWallpaperApplication (); ~CWallpaperApplication ();
@ -70,7 +68,7 @@ namespace WallpaperEngine::Application
/** /**
* Gets the output * Gets the output
*/ */
WallpaperEngine::Render::Drivers::Output::COutput* getOutput() const; [[nodiscard]] const WallpaperEngine::Render::Drivers::Output::COutput& getOutput () const;
private: private:
/** /**
@ -100,7 +98,7 @@ namespace WallpaperEngine::Application
* *
* @param project * @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 * Takes an screenshot of the background and saves it to the specified path
* *
@ -108,7 +106,8 @@ namespace WallpaperEngine::Application
* @param filename * @param filename
* @param format * @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 */ /** The default background to display if no specific background was loaded */
Core::CProject* m_defaultBackground; Core::CProject* m_defaultBackground;
@ -123,4 +122,4 @@ namespace WallpaperEngine::Application
WallpaperEngine::Render::CRenderContext* context; WallpaperEngine::Render::CRenderContext* context;
WallpaperEngine::Audio::CAudioContext* audioContext; WallpaperEngine::Audio::CAudioContext* audioContext;
}; };
} } // namespace WallpaperEngine::Application

View File

@ -2,12 +2,9 @@
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CAssetLoadException::CAssetLoadException(const std::string& filename, const std::string& extrainfo) CAssetLoadException::CAssetLoadException (const std::string& filename, const std::string& extrainfo) :
: m_message("Cannot find file " + filename + ": " + 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 (); return this->m_message.c_str ();
} }

View File

@ -3,10 +3,8 @@
#include <exception> #include <exception>
#include <string> #include <string>
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{ class CAssetLoadException final : public std::exception {
class CAssetLoadException : public std::exception
{
public: public:
explicit CAssetLoadException (const std::string& filename, const std::string& extrainfo = ""); explicit CAssetLoadException (const std::string& filename, const std::string& extrainfo = "");
[[nodiscard]] const char* what () const noexcept override; [[nodiscard]] const char* what () const noexcept override;
@ -14,4 +12,4 @@ namespace WallpaperEngine::Assets
private: private:
std::string m_message; std::string m_message;
}; };
} } // namespace WallpaperEngine::Assets

View File

@ -6,50 +6,33 @@
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CCombinedContainer::CCombinedContainer () : CCombinedContainer::CCombinedContainer () : CContainer () {}
CContainer (),
m_containers ()
{
}
void CCombinedContainer::add (CContainer* container) void CCombinedContainer::add (CContainer* container) {
{
this->m_containers.emplace_back (container); this->m_containers.emplace_back (container);
} }
void CCombinedContainer::addPkg (const std::filesystem::path& path) void CCombinedContainer::addPkg (const std::filesystem::path& path) {
{ try {
try
{
// add the package to the list // add the package to the list
this->add (new CPackage (path)); this->add (new CPackage (path));
sLog.out ("Detected ", path.filename (), " file at ", path, ". Adding to list of searchable paths"); sLog.out ("Detected ", path.filename (), " file at ", path, ". Adding to list of searchable paths");
} } catch (CPackageLoadException&) {
catch (CPackageLoadException& ex)
{
// ignore this error, the package file was not found // ignore this error, the package file was not found
sLog.out ("No ", path.filename (), " file found at ", path, ". Defaulting to normal folder storage"); 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) // 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 {
std::filesystem::path CCombinedContainer::resolveRealFile (const std::string& filename) const for (const auto cur : this->m_containers) {
{ try {
for (auto cur : this->m_containers)
{
try
{
// try to read the file on the current container, if the file doesn't exists // try to read the file on the current container, if the file doesn't exists
// an exception will be thrown // an exception will be thrown
return cur->resolveRealFile (filename); return cur->resolveRealFile (filename);
} } catch (CAssetLoadException&) {
catch (CAssetLoadException& ex)
{
// not found in this container, next try // 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"); throw CAssetLoadException (filename, "Cannot resolve file in any of the containers");
} }
const void* CCombinedContainer::readFile (const std::string& filename, uint32_t* length) const const void* CCombinedContainer::readFile (const std::string& filename, uint32_t* length) const {
{ for (const auto cur : this->m_containers) {
for (auto cur : this->m_containers) try {
{
try
{
// try to read the file on the current container, if the file doesn't exists // try to read the file on the current container, if the file doesn't exists
// an exception will be thrown // an exception will be thrown
return cur->readFile (filename, length); return cur->readFile (filename, length);
} } catch (CAssetLoadException&) {
catch (CAssetLoadException& ex)
{
// not found in this container, next try // not found in this container, next try
} }
} }

View File

@ -6,13 +6,11 @@
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{
/** /**
* A meta-container that allows backgrounds to have files spread across different containers * A meta-container that allows backgrounds to have files spread across different containers
*/ */
class CCombinedContainer : public CContainer class CCombinedContainer final : public CContainer {
{
public: public:
CCombinedContainer (); CCombinedContainer ();
@ -38,4 +36,4 @@ namespace WallpaperEngine::Assets
/** The list of containers to search files off from */ /** The list of containers to search files off from */
std::vector<CContainer*> m_containers; std::vector<CContainer*> m_containers;
}; };
}; }; // namespace WallpaperEngine::Assets

View File

@ -1,27 +1,25 @@
#include "CContainer.h" #include "CContainer.h"
#include "CAssetLoadException.h"
#include "CTexture.h" #include "CTexture.h"
#include "WallpaperEngine/Logging/CLog.h" #include "WallpaperEngine/Logging/CLog.h"
#include "CAssetLoadException.h"
#include <cstring> #include <cstring>
#include <utility>
#include <filesystem> #include <filesystem>
#include <utility>
using namespace WallpaperEngine::Assets; 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"); 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) // 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); const void* textureContents = this->readFile (texture, nullptr);
ITexture* result = new CTexture (textureContents); const ITexture* result = new CTexture (textureContents);
#if !NDEBUG #if !NDEBUG
glObjectLabel (GL_TEXTURE, result->getTextureID (), -1, texture.c_str ()); glObjectLabel (GL_TEXTURE, result->getTextureID (), -1, texture.c_str ());
@ -29,22 +27,19 @@ const ITexture* CContainer::readTexture (const std::string& filename) const
return result; 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; std::filesystem::path shader = filename;
auto it = shader.begin (); auto it = shader.begin ();
// detect workshop shaders and check if there's a // detect workshop shaders and check if there's a
if (*it++ == "workshop") if (*it++ == "workshop") {
{ const std::filesystem::path workshopId = *it++;
std::filesystem::path workshopId = *it++;
if (++it != shader.end ()) if (++it != shader.end ()) {
{ const std::filesystem::path shaderfile = *it;
std::filesystem::path shaderfile = *it;
try try {
{
shader = std::filesystem::path ("zcompat") / "scene" / "shaders" / workshopId / shaderfile; shader = std::filesystem::path ("zcompat") / "scene" / "shaders" / workshopId / shaderfile;
// replace the old path with the new one // replace the old path with the new one
std::string contents = this->readFileAsString (shader); 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); sLog.out ("Replaced ", filename, " with compat ", shader);
return contents; return contents;
} } catch (CAssetLoadException&) {}
catch (CAssetLoadException&)
{
}
} }
} }
return this->readFileAsString ("shaders/" + filename); 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"); 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"); 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); 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; uint32_t length = 0;
// read file contents and allocate a buffer for a string // read file contents and allocate a buffer for a string

View File

@ -5,14 +5,14 @@
#include <filesystem> #include <filesystem>
#include <string> #include <string>
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{
/** /**
* File container, provides access to files for backgrounds * File container, provides access to files for backgrounds
*/ */
class CContainer class CContainer {
{
public: public:
virtual ~CContainer () = default;
/** /**
* Resolves the full path to the specified file in the filesystem * Resolves the full path to the specified file in the filesystem
* *
@ -86,4 +86,4 @@ namespace WallpaperEngine::Assets
*/ */
[[nodiscard]] std::string readFileAsString (const std::string& filename) const; [[nodiscard]] std::string readFileAsString (const std::string& filename) const;
}; };
} } // namespace WallpaperEngine::Assets

View File

@ -3,14 +3,12 @@
#include <utility> #include <utility>
#include "CDirectory.h"
#include "CAssetLoadException.h" #include "CAssetLoadException.h"
#include "CDirectory.h"
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CDirectory::CDirectory (std::filesystem::path basepath) : CDirectory::CDirectory (std::filesystem::path basepath) : m_basepath (std::move (basepath)) {
m_basepath (std::move(basepath))
{
// ensure the specified path exists // ensure the specified path exists
struct stat buffer {}; struct stat buffer {};
@ -21,27 +19,21 @@ CDirectory::CDirectory (std::filesystem::path basepath) :
throw CAssetLoadException (this->m_basepath, "Expected directory but found a file"); throw CAssetLoadException (this->m_basepath, "Expected directory but found a file");
} }
CDirectory::~CDirectory () std::filesystem::path CDirectory::resolveRealFile (const std::string& filename) const {
= default;
std::filesystem::path CDirectory::resolveRealFile (const std::string& filename) const
{
return std::filesystem::path (this->m_basepath) / filename; return std::filesystem::path (this->m_basepath) / filename;
} }
const void* CDirectory::readFile (const std::string& filename, uint32_t* length) const const void* CDirectory::readFile (const std::string& filename, uint32_t* length) const {
{ const std::filesystem::path final = std::filesystem::path (this->m_basepath) / filename;
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 // 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) 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"); FILE* fp = fopen (final.c_str (), "rb");
@ -51,14 +43,13 @@ const void* CDirectory::readFile (const std::string& filename, uint32_t* length)
// go to the end, get the position and return to the beginning // go to the end, get the position and return to the beginning
fseek (fp, 0, SEEK_END); fseek (fp, 0, SEEK_END);
long size = ftell (fp); const long size = ftell (fp);
fseek (fp, 0, SEEK_SET); fseek (fp, 0, SEEK_SET);
// now read the whole file // now read the whole file
char* contents = new char[size]; auto* contents = new char [size];
if (fread (contents, size, 1, fp) != 1) if (fread (contents, size, 1, fp) != 1) {
{
delete [] contents; delete [] contents;
throw CAssetLoadException (filename, "Unexpected error when reading the file"); throw CAssetLoadException (filename, "Unexpected error when reading the file");
} }

View File

@ -1,23 +1,20 @@
#pragma once #pragma once
#include <string>
#include <stdexcept>
#include <map>
#include <filesystem> #include <filesystem>
#include <map>
#include <stdexcept>
#include <string>
#include "CContainer.h" #include "CContainer.h"
#include "CFileEntry.h" #include "CFileEntry.h"
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{
/** /**
* Directory container implementation, provides access to background files under a specific directory * Directory container implementation, provides access to background files under a specific directory
*/ */
class CDirectory : public CContainer class CDirectory final : public CContainer {
{
public: public:
explicit CDirectory (std::filesystem::path basepath); explicit CDirectory (std::filesystem::path basepath);
~CDirectory ();
/** @inheritdoc */ /** @inheritdoc */
[[nodiscard]] std::filesystem::path resolveRealFile (const std::string& filename) const override; [[nodiscard]] std::filesystem::path resolveRealFile (const std::string& filename) const override;
@ -30,4 +27,4 @@ namespace WallpaperEngine::Assets
/** File cache to simplify access to data */ /** File cache to simplify access to data */
std::map<std::string, CFileEntry> m_cache; std::map<std::string, CFileEntry> m_cache;
}; };
} } // namespace WallpaperEngine::Assets

View File

@ -2,21 +2,21 @@
#include <cstdint> #include <cstdint>
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{
/** /**
* File cache entry to prevent hit the disk when loading the same file multiple times * File cache entry to prevent hit the disk when loading the same file multiple times
*/ */
class CFileEntry class CFileEntry {
{
public: public:
CFileEntry (const void* address, uint32_t length) : CFileEntry (const char* address, uint32_t length) : address (address), length (length) {}
address (address),
length (length) { } ~CFileEntry () {
delete [] address;
}
/** File contents */ /** File contents */
const void* address; const char* address;
/** File length */ /** File length */
uint32_t length; uint32_t length;
}; };
} } // namespace WallpaperEngine::Assets

View File

@ -1,15 +1,14 @@
#include "common.h"
#include "CPackage.h" #include "CPackage.h"
#include "CAssetLoadException.h" #include "CAssetLoadException.h"
#include "CPackageLoadException.h" #include "CPackageLoadException.h"
#include "common.h"
#include <utility>
#include <sstream> #include <sstream>
#include <utility>
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
class CPackageEntry class CPackageEntry {
{
public: public:
CPackageEntry (std::string filename, uint32_t offset, uint32_t length) : CPackageEntry (std::string filename, uint32_t offset, uint32_t length) :
filename (std::move (filename)), filename (std::move (filename)),
@ -21,33 +20,29 @@ public:
uint32_t length; uint32_t length;
}; };
CPackage::CPackage (std::filesystem::path path) : CPackage::CPackage (std::filesystem::path path) : m_path (std::move (path)) {
m_path (std::move(path)),
m_contents ()
{
this->init (); this->init ();
} }
CPackage::~CPackage() const void* CPackage::readFile (const std::string& filename, uint32_t* length) const {
= default; const auto it = this->m_contents.find (filename);
const void* CPackage::readFile (const std::string& filename, uint32_t* length) const
{
auto it = this->m_contents.find (filename);
if (it == this->m_contents.end ()) 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 // set file length if required
if (length != nullptr) 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+"); FILE* fp = fopen (this->m_path.c_str (), "rb+");
if (fp == nullptr) if (fp == nullptr)
@ -61,8 +56,7 @@ void CPackage::init ()
fclose (fp); fclose (fp);
} }
char* CPackage::readSizedString (FILE* fp) char* CPackage::readSizedString (FILE* fp) {
{
unsigned int length = 0; unsigned int length = 0;
if (fread (&length, sizeof (unsigned int), 1, fp) != 1) if (fread (&length, sizeof (unsigned int), 1, fp) != 1)
@ -84,8 +78,7 @@ char* CPackage::readSizedString (FILE* fp)
return pointer; return pointer;
} }
uint32_t CPackage::readInteger (FILE* fp) uint32_t CPackage::readInteger (FILE* fp) {
{
uint32_t output; uint32_t output;
if (fread (&output, sizeof (uint32_t), 1, fp) != 1) if (fread (&output, sizeof (uint32_t), 1, fp) != 1)
@ -94,12 +87,10 @@ uint32_t CPackage::readInteger (FILE* fp)
return output; return output;
} }
void CPackage::validateHeader (FILE* fp) void CPackage::validateHeader (FILE* fp) {
{ const char* pointer = this->readSizedString (fp);
char* pointer = this->readSizedString (fp);
if (strncmp ("PKGV", pointer, 4) != 0) if (strncmp ("PKGV", pointer, 4) != 0) {
{
std::stringstream msg; std::stringstream msg;
msg << "Expected PKGV indicator, found " << pointer; msg << "Expected PKGV indicator, found " << pointer;
delete [] pointer; delete [] pointer;
@ -110,13 +101,11 @@ void CPackage::validateHeader (FILE* fp)
delete [] pointer; delete [] pointer;
} }
void CPackage::loadFiles (FILE* fp) void CPackage::loadFiles (FILE* fp) {
{ const uint32_t count = this->readInteger (fp);
uint32_t count = this->readInteger (fp);
std::vector<CPackageEntry> list; std::vector<CPackageEntry> list;
for (uint32_t index = 0; index < count; index ++) for (uint32_t index = 0; index < count; index++) {
{
// first read the filename // first read the filename
char* filename = this->readSizedString (fp); char* filename = this->readSizedString (fp);
uint32_t offset = this->readInteger (fp); uint32_t offset = this->readInteger (fp);
@ -129,11 +118,10 @@ void CPackage::loadFiles (FILE* fp)
} }
// get current baseOffset, this is where the files start // get current baseOffset, this is where the files start
long baseOffset = ftell (fp); const long baseOffset = ftell (fp);
for (const auto& cur : list) for (const auto& cur : list) {
{ const long offset = cur.offset + baseOffset;
long offset = cur.offset + baseOffset;
// with all the data we can jump to the offset and read the content // with all the data we can jump to the offset and read the content
if (fseek (fp, offset, SEEK_SET) != 0) 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 // allocate memory for the file's contents and read it from the file
char* fileContents = new char [cur.length]; char* fileContents = new char [cur.length];
if (fread (fileContents, cur.length, 1, fp) != 1) if (fread (fileContents, cur.length, 1, fp) != 1) {
{
delete [] fileContents; delete [] fileContents;
sLog.exception ("Cannot read file ", cur.filename, " contents from package ", this->m_path); sLog.exception ("Cannot read file ", cur.filename, " contents from package ", this->m_path);
} }
// add the file to the map // 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));
} }
} }

View File

@ -1,27 +1,24 @@
#pragma once #pragma once
#include <cstring>
#include <exception>
#include <filesystem>
#include <map>
#include <stdexcept>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
#include <exception>
#include <stdexcept>
#include <cstring>
#include <filesystem>
#include "CContainer.h" #include "CContainer.h"
#include "CFileEntry.h" #include "CFileEntry.h"
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{
/** /**
* Package container implementation, provides access to background files that are stored * Package container implementation, provides access to background files that are stored
* inside the WallpaperEngine's pkg format * inside the WallpaperEngine's pkg format
*/ */
class CPackage : public CContainer class CPackage final : public CContainer {
{
public: public:
explicit CPackage (std::filesystem::path path); explicit CPackage (std::filesystem::path path);
~CPackage ();
[[nodiscard]] const void* readFile (const std::string& filename, uint32_t* length) const override; [[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 */ /** The path to the package file */
std::filesystem::path m_path; std::filesystem::path m_path;
/** Contents of the package file */ /** Contents of the package file */
std::map <std::string, CFileEntry> m_contents; std::map<std::string, CFileEntry*> m_contents;
}; };
} } // namespace WallpaperEngine::Assets

View File

@ -3,11 +3,8 @@
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CPackageLoadException::CPackageLoadException (const std::string& filename, const std::string& extrainfo) : 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 (); return this->m_message.c_str ();
} }

View File

@ -3,15 +3,13 @@
#include <exception> #include <exception>
#include <string> #include <string>
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{ class CPackageLoadException final : public std::exception {
class CPackageLoadException : public std::exception
{
public: 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; [[nodiscard]] const char* what () const noexcept override;
private: private:
std::string m_message; std::string m_message;
}; };
} } // namespace WallpaperEngine::Assets

View File

@ -1,53 +1,37 @@
#include "common.h"
#include "CTexture.h" #include "CTexture.h"
#include "common.h"
#include <string>
#include <cstring> #include <cstring>
#include <lz4.h> #include <lz4.h>
#include <string>
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
CTexture::CTexture (const void* fileData) : CTexture::CTexture (const void* fileData) : m_resolution () {
m_resolution ()
{
// ensure the header is parsed // 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; GLint internalFormat;
if (this->isAnimated ()) if (this->isAnimated ()) {
{ this->m_resolution = {this->m_header->textureWidth, this->m_header->textureHeight, this->m_header->gifWidth,
this->m_resolution = { this->m_header->gifHeight};
this->m_header->textureWidth, this->m_header->textureHeight, } else {
this->m_header->gifWidth, this->m_header->gifHeight if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN) {
};
}
else
{
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN)
{
// wpengine-texture format always has one mipmap // wpengine-texture format always has one mipmap
// get first image size // get first image size
auto element = this->m_header->images.find (0)->second.begin (); auto element = this->m_header->images.find (0)->second.begin ();
// set the texture resolution // set the texture resolution
this->m_resolution = { this->m_resolution = {(*element)->width, (*element)->height, this->m_header->width, this->m_header->height};
(*element)->width, (*element)->height, } else {
this->m_header->width, this->m_header->height
};
}
else
{
// set the texture resolution // set the texture resolution
this->m_resolution = { this->m_resolution = {this->m_header->textureWidth, this->m_header->textureHeight, this->m_header->width,
this->m_header->textureWidth, this->m_header->textureHeight, this->m_header->height};
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; internalFormat = GL_RGBA8;
// set some extra information too as it's used for image sizing // 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 // 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->height = this->m_header->mipmaps [0]->height;
this->m_header->textureWidth = this->m_header->mipmaps [0]->width; this->m_header->textureWidth = this->m_header->mipmaps [0]->width;
this->m_header->textureHeight = this->m_header->mipmaps [0]->height;*/ this->m_header->textureHeight = this->m_header->mipmaps [0]->height;*/
} } else {
else
{
// detect the image format and hand it to openGL to be used // detect the image format and hand it to openGL to be used
switch (this->m_header->format) switch (this->m_header->format) {
{ case TextureFormat::DXT5: internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break;
case TextureFormat::DXT5: case TextureFormat::DXT3: internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break;
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; case TextureFormat::DXT1: internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break;
break; case TextureFormat::ARGB8888: internalFormat = GL_RGBA8; break;
case TextureFormat::DXT3: case TextureFormat::R8: internalFormat = GL_R8; break;
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; case TextureFormat::RG88: internalFormat = GL_RG8; break;
break; default: delete this->m_header; sLog.exception ("Cannot determine texture format");
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 imgCur = this->m_header->images.begin ();
auto imgEnd = this->m_header->images.end (); 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 // bind the texture to assign information to it
glBindTexture (GL_TEXTURE_2D, this->m_textureID [index]); 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); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, this->m_header->mipmapCount - 1);
// setup texture wrapping and filtering // 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_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_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_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
} }
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 8.0f); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, 8.0f);
auto cur = (*imgCur).second.begin (); auto cur = imgCur->second.begin ();
auto end = (*imgCur).second.end (); 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* bitmap = nullptr;
FIBITMAP* converted = nullptr; FIBITMAP* converted = nullptr;
FIMEMORY* memory = nullptr; FIMEMORY* memory = nullptr;
@ -142,9 +101,9 @@ CTexture::CTexture (const void* fileData) :
uint32_t bufferSize = (*cur)->uncompressedSize; uint32_t bufferSize = (*cur)->uncompressedSize;
GLenum textureFormat = GL_RGBA; GLenum textureFormat = GL_RGBA;
if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN) if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN) {
{ memory =
memory = FreeImage_OpenMemory (reinterpret_cast <BYTE *> ((*cur)->uncompressedData), (*cur)->uncompressedSize); FreeImage_OpenMemory (reinterpret_cast<BYTE*> ((*cur)->uncompressedData), (*cur)->uncompressedSize);
// load the image and setup pointers so they can be used // load the image and setup pointers so they can be used
bitmap = FreeImage_LoadFromMemory (this->m_header->freeImageFormat, memory); bitmap = FreeImage_LoadFromMemory (this->m_header->freeImageFormat, memory);
@ -158,47 +117,33 @@ CTexture::CTexture (const void* fileData) :
height = FreeImage_GetHeight (converted); height = FreeImage_GetHeight (converted);
bufferSize = FreeImage_GetMemorySize (converted); bufferSize = FreeImage_GetMemorySize (converted);
textureFormat = GL_BGRA; textureFormat = GL_BGRA;
} } else {
else if (this->m_header->format == TextureFormat::R8) {
{
if (this->m_header->format == TextureFormat::R8)
{
// red textures are 1-byte-per-pixel, so it's alignment has to be set manually // red textures are 1-byte-per-pixel, so it's alignment has to be set manually
glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
textureFormat = GL_RED; textureFormat = GL_RED;
} } else if (this->m_header->format == TextureFormat::RG88)
else if (this->m_header->format == TextureFormat::RG88)
textureFormat = GL_RG; textureFormat = GL_RG;
} }
switch (internalFormat) switch (internalFormat) {
{
case GL_RGBA8: case GL_RGBA8:
case GL_RG8: case GL_RG8:
case GL_R8: case GL_R8:
glTexImage2D ( glTexImage2D (GL_TEXTURE_2D, level, internalFormat, width, height, 0, textureFormat,
GL_TEXTURE_2D, level, internalFormat, GL_UNSIGNED_BYTE, dataptr);
width, height, 0,
textureFormat, GL_UNSIGNED_BYTE,
dataptr
);
break; break;
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
glCompressedTexImage2D ( glCompressedTexImage2D (GL_TEXTURE_2D, level, internalFormat, width, height, 0, bufferSize,
GL_TEXTURE_2D, level, internalFormat, dataptr);
width, height, 0,
bufferSize, dataptr
);
break; break;
default: default: sLog.exception ("Cannot load texture, unknown format", this->m_header->format);
sLog.exception ("Cannot load texture, unknown format", this->m_header->format);
} }
// freeimage buffer won't be used anymore, so free memory // 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 (bitmap);
FreeImage_Unload (converted); FreeImage_Unload (converted);
FreeImage_CloseMemory (memory); FreeImage_CloseMemory (memory);
@ -207,8 +152,7 @@ CTexture::CTexture (const void* fileData) :
} }
} }
CTexture::~CTexture () CTexture::~CTexture () {
{
if (this->getHeader () == nullptr) if (this->getHeader () == nullptr)
return; return;
@ -216,8 +160,7 @@ CTexture::~CTexture ()
delete this->getHeader (); 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 // ensure we do not go out of bounds
if (imageIndex > this->m_header->imageCount) if (imageIndex > this->m_header->imageCount)
return this->m_textureID [0]; return this->m_textureID [0];
@ -225,88 +168,74 @@ const GLuint CTexture::getTextureID (uint32_t imageIndex) const
return this->m_textureID [imageIndex]; 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) if (imageIndex > this->m_header->imageCount)
return this->getHeader ()->textureWidth; return this->getHeader ()->textureWidth;
return (*this->m_header->images [imageIndex].begin ())->width; 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) if (imageIndex > this->m_header->imageCount)
return this->getHeader ()->textureHeight; return this->getHeader ()->textureHeight;
return (*this->m_header->images [imageIndex].begin ())->height; 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; 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; 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; return this->getHeader ()->format;
} }
const ITexture::TextureFlags CTexture::getFlags () const const ITexture::TextureFlags CTexture::getFlags () const {
{
return this->getHeader ()->flags; return this->getHeader ()->flags;
} }
const CTexture::TextureHeader* CTexture::getHeader () const const CTexture::TextureHeader* CTexture::getHeader () const {
{
return this->m_header; return this->m_header;
} }
const glm::vec4* CTexture::getResolution () const const glm::vec4* CTexture::getResolution () const {
{
return &this->m_resolution; return &this->m_resolution;
} }
const std::vector<ITexture::TextureFrame*>& CTexture::getFrames () const const std::vector<ITexture::TextureFrame*>& CTexture::getFrames () const {
{
return this->getHeader ()->frames; return this->getHeader ()->frames;
} }
const bool CTexture::isAnimated () const const bool CTexture::isAnimated () const {
{
return this->getHeader ()->isAnimated (); return this->getHeader ()->isAnimated ();
} }
CTexture::TextureMipmap::TextureMipmap () CTexture::TextureMipmap::TextureMipmap () = default;
= default;
CTexture::TextureMipmap::~TextureMipmap () CTexture::TextureMipmap::~TextureMipmap () {
{
if (this->compression == 1) if (this->compression == 1)
delete this->compressedData; delete this->compressedData;
delete this->uncompressedData; delete this->uncompressedData;
} }
void CTexture::TextureMipmap::decompressData () void CTexture::TextureMipmap::decompressData () {
{ if (this->compression != 1) {
if (this->compression == 1) return;
{ }
this->uncompressedData = new char [this->uncompressedSize]; this->uncompressedData = new char [this->uncompressedSize];
int result = LZ4_decompress_safe ( const int result = LZ4_decompress_safe (this->compressedData, this->uncompressedData, this->compressedSize,
this->compressedData, this->uncompressedData, this->uncompressedSize);
this->compressedSize, this->uncompressedSize
);
if (!result) if (!result)
sLog.exception ("Cannot decompress texture data, LZ4_decompress_safe returned an error"); sLog.exception ("Cannot decompress texture data, LZ4_decompress_safe returned an error");
} }
}
CTexture::TextureFrame::TextureFrame () : CTexture::TextureFrame::TextureFrame () :
frameNumber (0), frameNumber (0),
@ -316,12 +245,7 @@ CTexture::TextureFrame::TextureFrame () :
width1 (0), width1 (0),
width2 (0), width2 (0),
height1 (0), height1 (0),
height2 (0) height2 (0) {}
{
}
CTexture::TextureFrame::~TextureFrame ()
= default;
CTexture::TextureHeader::TextureHeader () : CTexture::TextureHeader::TextureHeader () :
flags (NoFlags), flags (NoFlags),
@ -333,26 +257,22 @@ CTexture::TextureHeader::TextureHeader () :
gifHeight (0), gifHeight (0),
format (TextureFormat::UNKNOWN), format (TextureFormat::UNKNOWN),
imageCount (0), imageCount (0),
mipmapCount (0) mipmapCount (0) {}
{
}
CTexture::TextureHeader::~TextureHeader () CTexture::TextureHeader::~TextureHeader () {
{ for (const auto& [index, mipmaps] : this->images)
for (const auto& imgCur : this->images) for (const auto cur : mipmaps)
for (auto cur : imgCur.second)
delete cur; delete cur;
} }
CTexture::TextureHeader* CTexture::parseHeader (const char* fileData) CTexture::TextureHeader* CTexture::parseHeader (const char* fileData) {
{
// check the magic value on the header first // 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)); sLog.exception ("unexpected texture container type: ", std::string_view (fileData, 9));
// jump to the next value // jump to the next value
fileData += 9; fileData += 9;
// check the sub-magic value on the header // 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)); sLog.exception ("unexpected texture sub-container type: ", std::string_view (fileData, 9));
// jump through the string again // jump through the string again
fileData += 9; fileData += 9;
@ -375,30 +295,22 @@ CTexture::TextureHeader* CTexture::parseHeader (const char* fileData)
// get the position of what comes after the texture data // 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->containerVersion = ContainerVersion::TEXB0003;
header->imageCount = *pointer++; header->imageCount = *pointer++;
header->freeImageFormat = static_cast<FREE_IMAGE_FORMAT> (*pointer++); header->freeImageFormat = static_cast<FREE_IMAGE_FORMAT> (*pointer++);
} } else if (strncmp (fileData, "TEXB0002", 9) == 0) {
else if(memcmp (fileData, "TEXB0002", 9) == 0)
{
header->containerVersion = ContainerVersion::TEXB0002; header->containerVersion = ContainerVersion::TEXB0002;
header->imageCount = *pointer++; header->imageCount = *pointer++;
} } else if (strncmp (fileData, "TEXB0001", 9) == 0) {
else if (memcmp (fileData, "TEXB0001", 9) == 0)
{
header->containerVersion = ContainerVersion::TEXB0001; header->containerVersion = ContainerVersion::TEXB0001;
header->imageCount = *pointer++; header->imageCount = *pointer++;
} } else {
else
{
delete header; delete header;
sLog.exception ("unknown texture format type: ", std::string_view (fileData, 9)); 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 // read the number of mipmaps available for this image
header->mipmapCount = *pointer++; header->mipmapCount = *pointer++;
std::vector<TextureMipmap*> mipmaps; std::vector<TextureMipmap*> mipmaps;
@ -409,24 +321,18 @@ CTexture::TextureHeader* CTexture::parseHeader (const char* fileData)
mipmaps.emplace_back (parseMipmap (header, &fileData)); mipmaps.emplace_back (parseMipmap (header, &fileData));
// add the pixmaps back // 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 // gifs have extra information after the mipmaps
if (header->isAnimated () == true) if (header->isAnimated () == true) {
{ if (strncmp (fileData, "TEXS0002", 9) == 0) {
if (memcmp (fileData, "TEXS0002", 9) == 0)
{
header->animatedVersion = AnimatedVersion::TEXS0002; header->animatedVersion = AnimatedVersion::TEXS0002;
} } else if (strncmp (fileData, "TEXS0003", 9) == 0) {
else if (memcmp (fileData, "TEXS0003", 9) == 0)
{
header->animatedVersion = AnimatedVersion::TEXS0003; header->animatedVersion = AnimatedVersion::TEXS0003;
} } else {
else
{
delete header; delete header;
sLog.exception ("found animation information of unknown type: ", std::string_view (fileData, 9)); sLog.exception ("found animation information of unknown type: ", std::string_view (fileData, 9));
} }
@ -435,8 +341,7 @@ CTexture::TextureHeader* CTexture::parseHeader (const char* fileData)
pointer = reinterpret_cast<const uint32_t*> (fileData + 9); pointer = reinterpret_cast<const uint32_t*> (fileData + 9);
uint32_t framecount = *pointer++; 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 // ignore two extra integers as those are width and height of the git
header->gifWidth = *pointer++; header->gifWidth = *pointer++;
header->gifHeight = *pointer++; header->gifHeight = *pointer++;
@ -445,8 +350,7 @@ CTexture::TextureHeader* CTexture::parseHeader (const char* fileData)
// get back the pointer into filedata // 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 // add the frame to the list
header->frames.push_back (parseAnimation (&fileData)); header->frames.push_back (parseAnimation (&fileData));
@ -454,9 +358,8 @@ CTexture::TextureHeader* CTexture::parseHeader (const char* fileData)
} }
// ensure gif width and height is right for TEXS0002 // ensure gif width and height is right for TEXS0002
if (header->animatedVersion == AnimatedVersion::TEXS0002) if (header->animatedVersion == AnimatedVersion::TEXS0002) {
{ const TextureFrame* first = *header->frames.begin ();
TextureFrame* first = *header->frames.begin ();
header->gifWidth = first->width1; header->gifWidth = first->width1;
header->gifHeight = first->height1; header->gifHeight = first->height1;
@ -466,8 +369,7 @@ CTexture::TextureHeader* CTexture::parseHeader (const char* fileData)
return header; return header;
} }
CTexture::TextureFrame* CTexture::parseAnimation (const char** originalFileData) CTexture::TextureFrame* CTexture::parseAnimation (const char** originalFileData) {
{
const char* fileData = *originalFileData; const char* fileData = *originalFileData;
// get back the pointer into integer // get back the pointer into integer
const auto* pointer = reinterpret_cast<const uint32_t*> (fileData); const auto* pointer = reinterpret_cast<const uint32_t*> (fileData);
@ -494,8 +396,7 @@ CTexture::TextureFrame* CTexture::parseAnimation (const char** originalFileData)
return frame; 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 (); auto* mipmap = new TextureMipmap ();
// get the current position // get the current position
@ -508,8 +409,7 @@ CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const cha
mipmap->height = *pointer++; mipmap->height = *pointer++;
if (header->containerVersion == ContainerVersion::TEXB0002 || if (header->containerVersion == ContainerVersion::TEXB0002 ||
header->containerVersion == ContainerVersion::TEXB0003) header->containerVersion == ContainerVersion::TEXB0003) {
{
mipmap->compression = *pointer++; mipmap->compression = *pointer++;
mipmap->uncompressedSize = *pointer++; mipmap->uncompressedSize = *pointer++;
} }
@ -519,8 +419,7 @@ CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const cha
// get back a normal char 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 // this might be better named as mipmap_bytes_size instead of compressedSize
// as in uncompressed files this variable actually holds the file length // as in uncompressed files this variable actually holds the file length
mipmap->uncompressedSize = mipmap->compressedSize; mipmap->uncompressedSize = mipmap->compressedSize;
@ -528,8 +427,7 @@ CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const cha
mipmap->uncompressedData = new char [mipmap->uncompressedSize]; mipmap->uncompressedData = new char [mipmap->uncompressedSize];
if (mipmap->compression == 1) if (mipmap->compression == 1) {
{
mipmap->compressedData = new char [mipmap->compressedSize]; mipmap->compressedData = new char [mipmap->compressedSize];
memcpy (mipmap->compressedData, fileData, mipmap->compressedSize); memcpy (mipmap->compressedData, fileData, mipmap->compressedSize);
@ -537,9 +435,7 @@ CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const cha
mipmap->decompressData (); mipmap->decompressData ();
// advance to the end of the mipmap // advance to the end of the mipmap
fileData += mipmap->compressedSize; fileData += mipmap->compressedSize;
} } else {
else
{
memcpy (mipmap->uncompressedData, fileData, mipmap->uncompressedSize); memcpy (mipmap->uncompressedData, fileData, mipmap->uncompressedSize);
// advance to the end of the mipmap // advance to the end of the mipmap
fileData += mipmap->uncompressedSize; fileData += mipmap->uncompressedSize;
@ -551,7 +447,6 @@ CTexture::TextureMipmap* CTexture::parseMipmap (TextureHeader* header, const cha
return mipmap; return mipmap;
} }
bool CTexture::TextureHeader::isAnimated () const bool CTexture::TextureHeader::isAnimated () const {
{
return this->flags & TextureFlags::IsGif; return this->flags & TextureFlags::IsGif;
} }

View File

@ -10,19 +10,15 @@
#include <string> #include <string>
#include <vector> #include <vector>
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{
/** /**
* A normal texture file in WallpaperEngine's format * A normal texture file in WallpaperEngine's format
*/ */
class CTexture : public ITexture class CTexture final : public ITexture {
{
private:
/** /**
* Different texture container versions supported * Different texture container versions supported
*/ */
enum ContainerVersion : int enum ContainerVersion : int {
{
UNKNOWN = -1, UNKNOWN = -1,
TEXB0003 = 3, TEXB0003 = 3,
TEXB0002 = 2, TEXB0002 = 2,
@ -32,8 +28,7 @@ namespace WallpaperEngine::Assets
/** /**
* Different texture animation versions supported * Different texture animation versions supported
*/ */
enum AnimatedVersion : int enum AnimatedVersion : int {
{
TEXSUNKN = -1, TEXSUNKN = -1,
TEXS0002 = 0, TEXS0002 = 0,
TEXS0003 = 1, TEXS0003 = 1,
@ -42,8 +37,7 @@ namespace WallpaperEngine::Assets
/** /**
* Texture mipmap data * Texture mipmap data
*/ */
class TextureMipmap class TextureMipmap {
{
public: public:
TextureMipmap (); TextureMipmap ();
~TextureMipmap (); ~TextureMipmap ();
@ -71,8 +65,7 @@ namespace WallpaperEngine::Assets
/** /**
* Texture header data * Texture header data
*/ */
class TextureHeader class TextureHeader {
{
public: public:
TextureHeader (); TextureHeader ();
~TextureHeader (); ~TextureHeader ();
@ -113,7 +106,7 @@ namespace WallpaperEngine::Assets
public: public:
explicit CTexture (const void* fileData); explicit CTexture (const void* fileData);
~CTexture (); ~CTexture () override;
/** @inheritdoc */ /** @inheritdoc */
[[nodiscard]] const GLuint getTextureID (uint32_t imageIndex = 0) const override; [[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 * @param fileData The point at which to start reading data off from
* @return * @return
*/ */
static TextureMipmap* parseMipmap (TextureHeader* header, const char** fileData); static TextureMipmap* parseMipmap (const TextureHeader* header, const char** fileData);
/** The texture header */ /** The texture header */
TextureHeader* m_header; TextureHeader* m_header;
@ -172,4 +165,4 @@ namespace WallpaperEngine::Assets
/** Resolution vector of the texture */ /** Resolution vector of the texture */
glm::vec4 m_resolution; glm::vec4 m_resolution;
}; };
} } // namespace WallpaperEngine::Assets

View File

@ -1,19 +1,15 @@
#include <memory.h> #include <memory.h>
#include "CVirtualContainer.h"
#include "CAssetLoadException.h" #include "CAssetLoadException.h"
#include "CVirtualContainer.h"
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
void CVirtualContainer::add (const std::string& filename, void* contents, uint32_t 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)));
this->m_virtualFiles.insert (
std::make_pair (filename, 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]; char* copy = new char [contents.length () + 1];
// copy the text AND the \0 // 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); this->add (filename, copy, contents.length () + 1);
} }
const void* CVirtualContainer::readFile (const std::string& filename, uint32_t* length) const const void* CVirtualContainer::readFile (const std::string& filename, uint32_t* length) const {
{ const auto cur = this->m_virtualFiles.find (filename);
auto cur = this->m_virtualFiles.find (filename);
if (cur == this->m_virtualFiles.end ()) if (cur == this->m_virtualFiles.end ())
throw CAssetLoadException (filename, "Cannot find file in the virtual container"); 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;
} }

View File

@ -1,22 +1,17 @@
#pragma once #pragma once
#include <string>
#include <map> #include <map>
#include <string>
#include "CFileEntry.h"
#include "CContainer.h" #include "CContainer.h"
#include "CFileEntry.h"
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{
/** /**
* Virtual container implementation, provides virtual files for the backgrounds to use * Virtual container implementation, provides virtual files for the backgrounds to use
*/ */
class CVirtualContainer : public CContainer class CVirtualContainer final : public CContainer {
{
public: public:
CVirtualContainer () = default;
~CVirtualContainer () = default;
/** /**
* Adds a new file to the virtual container * Adds a new file to the virtual container
* *
@ -24,7 +19,7 @@ namespace WallpaperEngine::Assets
* @param contents * @param contents
* @param length * @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 * Adds a new file to the virtual container
@ -38,6 +33,6 @@ namespace WallpaperEngine::Assets
private: private:
/** The recorded files in this virtual container */ /** The recorded files in this virtual container */
std::map <std::string, CFileEntry> m_virtualFiles; std::map<std::string, CFileEntry*> m_virtualFiles;
}; };
} } // namespace WallpaperEngine::Assets

View File

@ -4,23 +4,22 @@
#include <glm/vec4.hpp> #include <glm/vec4.hpp>
#include <vector> #include <vector>
namespace WallpaperEngine::Assets namespace WallpaperEngine::Assets {
{
/** /**
* Base interface that describes the minimum information required for a texture * Base interface that describes the minimum information required for a texture
* to be displayed by the engine * to be displayed by the engine
*/ */
class ITexture class ITexture {
{
public: public:
virtual ~ITexture () = default;
/** /**
* Texture frame information for animated textures * Texture frame information for animated textures
*/ */
class TextureFrame class TextureFrame final {
{
public: public:
TextureFrame (); TextureFrame ();
~TextureFrame(); virtual ~TextureFrame () = default;
/** The image index of this frame */ /** The image index of this frame */
uint32_t frameNumber; uint32_t frameNumber;
@ -41,8 +40,7 @@ namespace WallpaperEngine::Assets
/** /**
* Data formats for textures in memory * Data formats for textures in memory
*/ */
enum TextureFormat : uint32_t enum TextureFormat : uint32_t {
{
UNKNOWN = 0xFFFFFFFF, UNKNOWN = 0xFFFFFFFF,
ARGB8888 = 0, ARGB8888 = 0,
RGB888 = 1, RGB888 = 1,
@ -63,8 +61,7 @@ namespace WallpaperEngine::Assets
/** /**
* Different settings of the textures * Different settings of the textures
*/ */
enum TextureFlags : uint32_t enum TextureFlags : uint32_t {
{
NoFlags = 0, NoFlags = 0,
NoInterpolation = 1, NoInterpolation = 1,
ClampUVs = 2, ClampUVs = 2,
@ -116,4 +113,4 @@ namespace WallpaperEngine::Assets
*/ */
[[nodiscard]] virtual const bool isAnimated () const = 0; [[nodiscard]] virtual const bool isAnimated () const = 0;
}; };
} } // namespace WallpaperEngine::Assets

View File

@ -1,40 +1,30 @@
#include "CAudioContext.h" #include "CAudioContext.h"
#include "WallpaperEngine/Audio/Drivers/CAudioDriver.h" #include "WallpaperEngine/Audio/Drivers/CAudioDriver.h"
namespace WallpaperEngine::Audio namespace WallpaperEngine::Audio {
{ CAudioContext::CAudioContext (Drivers::CAudioDriver& driver) : m_driver (driver) {}
CAudioContext::CAudioContext (Drivers::CAudioDriver& driver) :
m_driver (driver)
{
}
void CAudioContext::addStream (CAudioStream* stream) void CAudioContext::addStream (CAudioStream* stream) {
{
this->m_driver.addStream (stream); this->m_driver.addStream (stream);
} }
AVSampleFormat CAudioContext::getFormat () const AVSampleFormat CAudioContext::getFormat () const {
{
return this->m_driver.getFormat (); return this->m_driver.getFormat ();
} }
int CAudioContext::getSampleRate () const int CAudioContext::getSampleRate () const {
{
return this->m_driver.getSampleRate (); return this->m_driver.getSampleRate ();
} }
int CAudioContext::getChannels () const int CAudioContext::getChannels () const {
{
return this->m_driver.getChannels (); return this->m_driver.getChannels ();
} }
Application::CApplicationContext& CAudioContext::getApplicationContext () Application::CApplicationContext& CAudioContext::getApplicationContext () {
{
return this->m_driver.getApplicationContext (); return this->m_driver.getApplicationContext ();
} }
Drivers::Recorders::CPlaybackRecorder& CAudioContext::getRecorder () Drivers::Recorders::CPlaybackRecorder& CAudioContext::getRecorder () {
{
return this->m_driver.getRecorder (); return this->m_driver.getRecorder ();
} }
} } // namespace WallpaperEngine::Audio

View File

@ -3,32 +3,26 @@
#include <libavutil/samplefmt.h> #include <libavutil/samplefmt.h>
#include <vector> #include <vector>
#include "WallpaperEngine/Audio/Drivers/Recorders/CPulseAudioPlaybackRecorder.h"
#include "WallpaperEngine/Application/CApplicationContext.h" #include "WallpaperEngine/Application/CApplicationContext.h"
#include "WallpaperEngine/Audio/Drivers/Recorders/CPulseAudioPlaybackRecorder.h"
namespace WallpaperEngine namespace WallpaperEngine {
{ namespace Application {
namespace Application
{
class CApplicationContext; class CApplicationContext;
} }
namespace Audio namespace Audio {
{ namespace Drivers {
namespace Drivers
{
class CAudioDriver; class CAudioDriver;
namespace Recorders namespace Recorders {
{
class CPulseAudioPlaybackRecorder; class CPulseAudioPlaybackRecorder;
} }
} } // namespace Drivers
class CAudioStream; class CAudioStream;
class CAudioContext class CAudioContext {
{
public: public:
explicit CAudioContext (Drivers::CAudioDriver& driver); explicit CAudioContext (Drivers::CAudioDriver& driver);
@ -66,5 +60,5 @@ namespace WallpaperEngine
/** The audio driver in use */ /** The audio driver in use */
Drivers::CAudioDriver& m_driver; Drivers::CAudioDriver& m_driver;
}; };
} } // namespace Audio
} } // namespace WallpaperEngine

View File

@ -1,5 +1,5 @@
#include "common.h"
#include "CAudioStream.h" #include "CAudioStream.h"
#include "common.h"
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <math.h> #include <math.h>
@ -10,8 +10,7 @@
using namespace WallpaperEngine::Audio; using namespace WallpaperEngine::Audio;
int audio_read_thread (void* arg) int audio_read_thread (void* arg) {
{
SDL_mutex* waitMutex = SDL_CreateMutex (); SDL_mutex* waitMutex = SDL_CreateMutex ();
auto* stream = static_cast<CAudioStream*> (arg); auto* stream = static_cast<CAudioStream*> (arg);
AVPacket* packet = av_packet_alloc (); AVPacket* packet = av_packet_alloc ();
@ -20,15 +19,11 @@ int audio_read_thread (void* arg)
if (waitMutex == nullptr) if (waitMutex == nullptr)
sLog.exception ("Cannot create mutex for audio playback waiting"); 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 // give the cpu some time to play the queued frames if there's enough info there
if ( if (stream->getQueueSize () >= MAX_QUEUE_SIZE ||
stream->getQueueSize () >= MAX_QUEUE_SIZE ||
(stream->getQueuePacketCount () > MIN_FRAMES && (stream->getQueuePacketCount () > MIN_FRAMES &&
(av_q2d (stream->getTimeBase ()) * stream->getQueueDuration () > 1.0)) (av_q2d (stream->getTimeBase ()) * stream->getQueueDuration () > 1.0))) {
)
{
SDL_LockMutex (waitMutex); SDL_LockMutex (waitMutex);
SDL_CondWaitTimeout (stream->getWaitCondition (), waitMutex, 10); SDL_CondWaitTimeout (stream->getWaitCondition (), waitMutex, 10);
SDL_UnlockMutex (waitMutex); SDL_UnlockMutex (waitMutex);
@ -37,8 +32,7 @@ int audio_read_thread (void* arg)
ret = av_read_frame (stream->getFormatContext (), packet); ret = av_read_frame (stream->getFormatContext (), packet);
if (ret == AVERROR_EOF) if (ret == AVERROR_EOF) {
{
// seek to the beginning of the file again // seek to the beginning of the file again
avformat_seek_file (stream->getFormatContext (), stream->getAudioStream (), 0, 0, 0, ~AVSEEK_FLAG_FRAME); avformat_seek_file (stream->getFormatContext (), stream->getAudioStream (), 0, 0, 0, ~AVSEEK_FLAG_FRAME);
avcodec_flush_buffers (stream->getContext ()); avcodec_flush_buffers (stream->getContext ());
@ -67,36 +61,29 @@ int audio_read_thread (void* arg)
return 0; return 0;
} }
static int audio_read_data_callback (void* streamarg, uint8_t* buffer, int buffer_size) static int audio_read_data_callback (void* streamarg, uint8_t* buffer, int buffer_size) {
{ const auto stream = static_cast<CAudioStream*> (streamarg);
auto stream = static_cast <CAudioStream*> (streamarg); const int left = stream->getLength () - stream->getPosition ();
int left = stream->getLength () - stream->getPosition ();
buffer_size = FFMIN (buffer_size, left); 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 // update position
stream->setPosition (stream->getPosition () + buffer_size); stream->setPosition (stream->getPosition () + buffer_size);
return buffer_size; return buffer_size;
} }
int64_t audio_seek_data_callback (void* streamarg, int64_t offset, int whence) int64_t audio_seek_data_callback (void* streamarg, int64_t offset, int whence) {
{ const auto stream = static_cast<CAudioStream*> (streamarg);
auto stream = static_cast <CAudioStream*> (streamarg);
if (whence & AVSEEK_SIZE) if (whence & AVSEEK_SIZE)
return stream->getLength (); return stream->getLength ();
switch (whence) switch (whence) {
{ case SEEK_CUR: stream->setPosition (stream->getPosition () + offset); break;
case SEEK_CUR:
stream->setPosition (stream->getPosition () + offset);
break;
case SEEK_SET: case SEEK_SET: stream->setPosition (offset); break;
stream->setPosition (offset);
break;
} }
return offset; 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) : CAudioStream::CAudioStream (CAudioContext& context, const std::string& filename) :
m_audioContext (context), m_audioContext (context),
m_swrctx (nullptr) m_swrctx (nullptr) {
{
this->loadCustomContent (filename.c_str ()); this->loadCustomContent (filename.c_str ());
} }
CAudioStream::CAudioStream (CAudioContext& context, const void* buffer, int length) : CAudioStream::CAudioStream (CAudioContext& context, const void* buffer, int length) :
m_audioContext (context), m_audioContext (context),
m_swrctx (nullptr) m_swrctx (nullptr) {
{
// setup a custom context first // setup a custom context first
this->m_formatContext = avformat_alloc_context (); this->m_formatContext = avformat_alloc_context ();
@ -124,15 +109,8 @@ CAudioStream::CAudioStream (CAudioContext& context, const void* buffer, int leng
this->m_position = 0; this->m_position = 0;
// setup custom io for it // setup custom io for it
this->m_formatContext->pb = avio_alloc_context ( this->m_formatContext->pb = avio_alloc_context (static_cast<uint8_t*> (av_malloc (4096)), 4096, 0, this,
static_cast <uint8_t*> (av_malloc (4096)), &audio_read_data_callback, nullptr, &audio_seek_data_callback);
4096,
0,
static_cast <void*> (this),
&audio_read_data_callback,
nullptr,
&audio_seek_data_callback
);
if (this->m_formatContext->pb == nullptr) if (this->m_formatContext->pb == nullptr)
sLog.exception ("Cannot create avio context"); sLog.exception ("Cannot create avio context");
@ -145,13 +123,11 @@ CAudioStream::CAudioStream(CAudioContext& audioContext, AVCodecContext* context)
m_context (context), m_context (context),
m_queue (new PacketQueue), m_queue (new PacketQueue),
m_audioContext (audioContext), m_audioContext (audioContext),
m_swrctx (nullptr) m_swrctx (nullptr) {
{
this->initialize (); this->initialize ();
} }
CAudioStream::~CAudioStream() CAudioStream::~CAudioStream () {
{
if (this->m_swrctx != nullptr && swr_is_initialized (this->m_swrctx) == true) if (this->m_swrctx != nullptr && swr_is_initialized (this->m_swrctx) == true)
swr_close (this->m_swrctx); swr_close (this->m_swrctx);
if (this->m_swrctx != nullptr) if (this->m_swrctx != nullptr)
@ -160,19 +136,14 @@ CAudioStream::~CAudioStream()
// TODO: FREE EVERYTHING ELSE THAT THIS CLASS HOLDS! // TODO: FREE EVERYTHING ELSE THAT THIS CLASS HOLDS!
} }
void CAudioStream::loadCustomContent (const char* filename) void CAudioStream::loadCustomContent (const char* filename) {
{
const AVCodec* aCodec;
AVCodecContext* avCodecContext;
if (avformat_open_input (&this->m_formatContext, filename, nullptr, nullptr) != 0) if (avformat_open_input (&this->m_formatContext, filename, nullptr, nullptr) != 0)
sLog.exception ("Cannot open audio file: ", filename); sLog.exception ("Cannot open audio file: ", filename);
if (avformat_find_stream_info (this->m_formatContext, nullptr) < 0) if (avformat_find_stream_info (this->m_formatContext, nullptr) < 0)
sLog.exception ("Cannot determine file format: ", filename); sLog.exception ("Cannot determine file format: ", filename);
// find the audio stream // 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) if (this->m_formatContext->streams [i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && this->m_audioStream < 0)
this->m_audioStream = i; this->m_audioStream = i;
} }
@ -181,15 +152,17 @@ void CAudioStream::loadCustomContent (const char* filename)
sLog.exception ("Cannot find an audio stream in file ", filename); sLog.exception ("Cannot find an audio stream in file ", filename);
// get the decoder for it and alloc the required context // 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) if (aCodec == nullptr)
sLog.exception ("Cannot initialize audio decoder for file: ", filename); sLog.exception ("Cannot initialize audio decoder for file: ", filename);
// alocate context // 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"); sLog.exception ("Cannot initialize audio decoder parameters");
// finally open // finally open
@ -205,8 +178,7 @@ void CAudioStream::loadCustomContent (const char* filename)
SDL_CreateThread (audio_read_thread, filename, this); SDL_CreateThread (audio_read_thread, filename, this);
} }
void CAudioStream::initialize () void CAudioStream::initialize () {
{
#if FF_API_FIFO_OLD_API #if FF_API_FIFO_OLD_API
// allocate the FIFO buffer // allocate the FIFO buffer
this->m_queue->packetList = av_fifo_alloc2 (1, sizeof (MyAVPacketList), AV_FIFO_FLAG_AUTO_GROW); 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; int64_t out_channel_layout;
// set output audio channels based on the input audio channels // 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 1: out_channel_layout = AV_CH_LAYOUT_MONO; break;
case 2: out_channel_layout = AV_CH_LAYOUT_STEREO; break; case 2: out_channel_layout = AV_CH_LAYOUT_STEREO; break;
default: out_channel_layout = AV_CH_LAYOUT_SURROUND; break; default: out_channel_layout = AV_CH_LAYOUT_SURROUND; break;
@ -227,30 +198,14 @@ void CAudioStream::initialize ()
#if FF_API_OLD_CHANNEL_LAYOUT #if FF_API_OLD_CHANNEL_LAYOUT
av_channel_layout_from_mask (&this->m_out_channel_layout, out_channel_layout); av_channel_layout_from_mask (&this->m_out_channel_layout, out_channel_layout);
swr_alloc_set_opts2 ( swr_alloc_set_opts2 (&this->m_swrctx, &this->m_out_channel_layout, this->m_audioContext.getFormat (),
&this->m_swrctx, this->m_audioContext.getSampleRate (), &this->m_context->ch_layout,
&this->m_out_channel_layout, this->m_context->sample_fmt, this->m_context->sample_rate, 0, nullptr);
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 #else
// initialize swrctx // initialize swrctx
this->m_swrctx = swr_alloc_set_opts ( this->m_swrctx = swr_alloc_set_opts (nullptr, out_channel_layout, this->m_audioContext.getFormat (),
nullptr, this->m_audioContext.getSampleRate (), this->getContext ()->channel_layout,
out_channel_layout, this->getContext ()->sample_fmt, this->getContext ()->sample_rate, 0, nullptr);
this->m_audioContext.getFormat (),
this->m_audioContext.getSampleRate (),
this->getContext ()->channel_layout,
this->getContext ()->sample_fmt,
this->getContext ()->sample_rate,
0,
nullptr
);
#endif #endif
if (this->m_swrctx == nullptr) if (this->m_swrctx == nullptr)
sLog.exception ("Cannot initialize swrctx for audio resampling"); sLog.exception ("Cannot initialize swrctx for audio resampling");
@ -267,13 +222,11 @@ void CAudioStream::initialize ()
this->m_initialized = true; this->m_initialized = true;
} }
void CAudioStream::queuePacket(AVPacket *pkt) void CAudioStream::queuePacket (AVPacket* pkt) {
{
// clone the packet // clone the packet
AVPacket* clone = av_packet_alloc (); AVPacket* clone = av_packet_alloc ();
if (clone == nullptr) if (clone == nullptr) {
{
av_packet_unref (clone); av_packet_unref (clone);
return; return;
} }
@ -281,15 +234,14 @@ void CAudioStream::queuePacket(AVPacket *pkt)
av_packet_move_ref (clone, pkt); av_packet_move_ref (clone, pkt);
SDL_LockMutex (this->m_queue->mutex); SDL_LockMutex (this->m_queue->mutex);
bool gotQueued = this->doQueue (clone); const bool gotQueued = this->doQueue (clone);
SDL_UnlockMutex (this->m_queue->mutex); SDL_UnlockMutex (this->m_queue->mutex);
if (!gotQueued) if (!gotQueued)
av_packet_free (&pkt); av_packet_free (&pkt);
} }
bool CAudioStream::doQueue (AVPacket* pkt) bool CAudioStream::doQueue (AVPacket* pkt) {
{
MyAVPacketList entry {pkt}; MyAVPacketList entry {pkt};
#if FF_API_FIFO_OLD_API #if FF_API_FIFO_OLD_API
@ -313,14 +265,12 @@ bool CAudioStream::doQueue (AVPacket* pkt)
return true; return true;
} }
void CAudioStream::dequeuePacket (AVPacket* output) void CAudioStream::dequeuePacket (AVPacket* output) {
{
MyAVPacketList entry; MyAVPacketList entry;
SDL_LockMutex (this->m_queue->mutex); 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 #if FF_API_FIFO_OLD_API
int ret = av_fifo_read (this->m_queue->packetList, &entry, 1); int ret = av_fifo_read (this->m_queue->packetList, &entry, 1);
@ -332,8 +282,7 @@ void CAudioStream::dequeuePacket (AVPacket* output)
#endif #endif
// enough data available, read it // enough data available, read it
if (ret >= 0) if (ret >= 0) {
{
this->m_queue->nb_packets--; this->m_queue->nb_packets--;
this->m_queue->size -= entry.packet->size + sizeof (entry); this->m_queue->size -= entry.packet->size + sizeof (entry);
this->m_queue->duration -= entry.packet->duration; this->m_queue->duration -= entry.packet->duration;
@ -351,93 +300,75 @@ void CAudioStream::dequeuePacket (AVPacket* output)
SDL_UnlockMutex (this->m_queue->mutex); SDL_UnlockMutex (this->m_queue->mutex);
} }
AVCodecContext* CAudioStream::getContext () AVCodecContext* CAudioStream::getContext () {
{
return this->m_context; return this->m_context;
} }
AVFormatContext* CAudioStream::getFormatContext () AVFormatContext* CAudioStream::getFormatContext () {
{
return this->m_formatContext; return this->m_formatContext;
} }
int CAudioStream::getAudioStream () int CAudioStream::getAudioStream () {
{
return this->m_audioStream; return this->m_audioStream;
} }
bool CAudioStream::isInitialized () bool CAudioStream::isInitialized () {
{
return this->m_initialized; return this->m_initialized;
} }
void CAudioStream::setRepeat (bool newRepeat) void CAudioStream::setRepeat (bool newRepeat) {
{
this->m_repeat = newRepeat; this->m_repeat = newRepeat;
} }
bool CAudioStream::isRepeat () bool CAudioStream::isRepeat () {
{
return this->m_repeat; return this->m_repeat;
} }
const void* CAudioStream::getBuffer () const void* CAudioStream::getBuffer () {
{
return this->m_buffer; return this->m_buffer;
} }
int CAudioStream::getLength () int CAudioStream::getLength () {
{
return this->m_length; return this->m_length;
} }
int CAudioStream::getPosition () int CAudioStream::getPosition () {
{
return this->m_position; return this->m_position;
} }
void CAudioStream::setPosition (int current) void CAudioStream::setPosition (int current) {
{
this->m_position = current; this->m_position = current;
} }
SDL_cond* CAudioStream::getWaitCondition () SDL_cond* CAudioStream::getWaitCondition () {
{
return this->m_queue->wait; return this->m_queue->wait;
} }
int CAudioStream::getQueueSize () int CAudioStream::getQueueSize () {
{
return this->m_queue->size; return this->m_queue->size;
} }
int CAudioStream::getQueuePacketCount () int CAudioStream::getQueuePacketCount () {
{
return this->m_queue->nb_packets; return this->m_queue->nb_packets;
} }
AVRational CAudioStream::getTimeBase () AVRational CAudioStream::getTimeBase () {
{
return this->m_formatContext->streams [this->m_audioStream]->time_base; return this->m_formatContext->streams [this->m_audioStream]->time_base;
} }
int64_t CAudioStream::getQueueDuration () int64_t CAudioStream::getQueueDuration () {
{
return this->m_queue->duration; return this->m_queue->duration;
} }
bool CAudioStream::isQueueEmpty () bool CAudioStream::isQueueEmpty () {
{
return this->m_queue->nb_packets == 0; return this->m_queue->nb_packets == 0;
} }
SDL_mutex* CAudioStream::getMutex () SDL_mutex* CAudioStream::getMutex () {
{
return this->m_queue->mutex; return this->m_queue->mutex;
} }
void CAudioStream::stop () void CAudioStream::stop () {
{
if (!this->isInitialized ()) if (!this->isInitialized ())
return; return;
@ -445,35 +376,26 @@ void CAudioStream::stop ()
this->m_initialized = false; 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 out_linesize = 0;
int ret; int ret;
int out_nb_channels; int out_nb_channels;
int in_nb_samples;
int out_nb_samples; int out_nb_samples;
int max_out_nb_samples;
uint8_t** resampled_data = nullptr; uint8_t** resampled_data = nullptr;
int resampled_data_size; int resampled_data_size;
// retrieve number of audio samples (per channel) // retrieve number of audio samples (per channel)
in_nb_samples = decoded_audio_frame->nb_samples; const int in_nb_samples = decoded_audio_frame->nb_samples;
if (in_nb_samples <= 0) if (in_nb_samples <= 0) {
{
sLog.error ("in_nb_samples error."); sLog.error ("in_nb_samples error.");
return -1; return -1;
} }
max_out_nb_samples = out_nb_samples = av_rescale_rnd( int max_out_nb_samples = out_nb_samples = av_rescale_rnd (in_nb_samples, this->m_audioContext.getSampleRate (),
in_nb_samples, this->getContext ()->sample_rate, AV_ROUND_UP);
this->m_audioContext.getSampleRate (),
this->getContext ()->sample_rate,
AV_ROUND_UP
);
// check rescaling was successful // check rescaling was successful
if (max_out_nb_samples <= 0) if (max_out_nb_samples <= 0) {
{
sLog.error ("av_rescale_rnd error."); sLog.error ("av_rescale_rnd error.");
return -1; return -1;
} }
@ -485,8 +407,7 @@ int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_bu
int64_t out_channel_layout; int64_t out_channel_layout;
// set output audio channels based on the input audio channels // 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 1: out_channel_layout = AV_CH_LAYOUT_MONO; break;
case 2: out_channel_layout = AV_CH_LAYOUT_STEREO; break; case 2: out_channel_layout = AV_CH_LAYOUT_STEREO; break;
default: out_channel_layout = AV_CH_LAYOUT_SURROUND; break; default: out_channel_layout = AV_CH_LAYOUT_SURROUND; break;
@ -494,54 +415,35 @@ int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_bu
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 #endif
ret = av_samples_alloc_array_and_samples( ret = av_samples_alloc_array_and_samples (&resampled_data, &out_linesize, out_nb_channels, out_nb_samples,
&resampled_data, this->m_audioContext.getFormat (), 0);
&out_linesize,
out_nb_channels,
out_nb_samples,
this->m_audioContext.getFormat (),
0
);
if (ret < 0) if (ret < 0) {
{
sLog.error ("av_samples_alloc_array_and_samples() error: Could not allocate destination samples."); sLog.error ("av_samples_alloc_array_and_samples() error: Could not allocate destination samples.");
return -1; return -1;
} }
// retrieve output samples number taking into account the progressive delay // retrieve output samples number taking into account the progressive delay
out_nb_samples = av_rescale_rnd( out_nb_samples =
swr_get_delay(this->m_swrctx, this->getContext ()->sample_rate) + in_nb_samples, av_rescale_rnd (swr_get_delay (this->m_swrctx, this->getContext ()->sample_rate) + in_nb_samples,
this->m_audioContext.getSampleRate (), this->m_audioContext.getSampleRate (), this->getContext ()->sample_rate, AV_ROUND_UP);
this->getContext ()->sample_rate,
AV_ROUND_UP
);
// check output samples number was correctly retrieved // check output samples number was correctly retrieved
if (out_nb_samples <= 0) if (out_nb_samples <= 0) {
{
sLog.error ("av_rescale_rnd error"); sLog.error ("av_rescale_rnd error");
return -1; 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 // 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 // Allocate a samples buffer for out_nb_samples samples
ret = av_samples_alloc( ret = av_samples_alloc (resampled_data, &out_linesize, out_nb_channels, out_nb_samples,
resampled_data, this->m_audioContext.getFormat (), 1);
&out_linesize,
out_nb_channels,
out_nb_samples,
this->m_audioContext.getFormat (),
1
);
// check samples buffer correctly allocated // check samples buffer correctly allocated
if (ret < 0) if (ret < 0) {
{
sLog.error ("av_samples_alloc failed."); sLog.error ("av_samples_alloc failed.");
return -1; return -1;
} }
@ -550,33 +452,21 @@ int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_bu
} }
// do the actual audio data resampling // do the actual audio data resampling
ret = swr_convert( ret = swr_convert (this->m_swrctx, resampled_data, max_out_nb_samples,
this->m_swrctx, const_cast<const uint8_t**> (decoded_audio_frame->data), decoded_audio_frame->nb_samples);
resampled_data,
max_out_nb_samples,
(const uint8_t **) decoded_audio_frame->data,
decoded_audio_frame->nb_samples
);
// check audio conversion was successful // check audio conversion was successful
if (ret < 0) if (ret < 0) {
{
sLog.error ("swr_convert_error."); sLog.error ("swr_convert_error.");
return -1; return -1;
} }
// Get the required buffer size for the given audio parameters // Get the required buffer size for the given audio parameters
resampled_data_size = av_samples_get_buffer_size( resampled_data_size =
&out_linesize, av_samples_get_buffer_size (&out_linesize, out_nb_channels, ret, this->m_audioContext.getFormat (), 1);
out_nb_channels,
ret,
this->m_audioContext.getFormat (),
1
);
// check audio buffer size // check audio buffer size
if (resampled_data_size < 0) if (resampled_data_size < 0) {
{
sLog.error ("av_samples_get_buffer_size error."); sLog.error ("av_samples_get_buffer_size error.");
return -1; return -1;
} }
@ -587,31 +477,28 @@ int CAudioStream::resampleAudio (AVFrame * decoded_audio_frame, uint8_t * out_bu
/* /*
* Memory Cleanup. * Memory Cleanup.
*/ */
if (resampled_data) if (resampled_data) {
{
// free memory block and set pointer to NULL // free memory block and set pointer to NULL
av_freep (&resampled_data [0]); av_freep (&resampled_data [0]);
} }
av_freep (&resampled_data); av_freep (&resampled_data);
resampled_data = NULL; resampled_data = nullptr;
return resampled_data_size; return resampled_data_size;
} }
int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize) int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize) {
{
AVPacket* pkt = av_packet_alloc (); AVPacket* pkt = av_packet_alloc ();
static uint8_t *audio_pkt_data = NULL; static uint8_t* audio_pkt_data = nullptr;
static int audio_pkt_size = 0; static int audio_pkt_size = 0;
int len1, data_size; int len1, data_size;
// allocate a new frame, used to decode audio packets // allocate a new frame, used to decode audio packets
static AVFrame * avFrame = NULL; static AVFrame* avFrame = nullptr;
avFrame = av_frame_alloc (); avFrame = av_frame_alloc ();
if (!avFrame) if (!avFrame) {
{
sLog.error ("Could not allocate AVFrame.\n"); sLog.error ("Could not allocate AVFrame.\n");
return -1; return -1;
} }
@ -633,8 +520,7 @@ int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize)
len1 = pkt->size; len1 = pkt->size;
if (len1 < 0) if (len1 < 0) {
{
// if error, skip frame // if error, skip frame
audio_pkt_size = 0; audio_pkt_size = 0;
break; break;
@ -668,7 +554,6 @@ int CAudioStream::decodeFrame (uint8_t* audioBuffer, int bufferSize)
return 0; return 0;
} }
CAudioContext& CAudioStream::getAudioContext () const CAudioContext& CAudioStream::getAudioContext () const {
{
return this->m_audioContext; return this->m_audioContext;
} }

View File

@ -2,14 +2,13 @@
#include <string> #include <string>
extern "C" extern "C" {
{
#include <libavutil/fifo.h>
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libswscale/swscale.h> #include <libavutil/fifo.h>
#include <libswresample/swresample.h>
#include <libavutil/opt.h> #include <libavutil/opt.h>
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>
} }
#include <SDL.h> #include <SDL.h>
@ -17,15 +16,13 @@ extern "C"
#include "WallpaperEngine/Audio/CAudioContext.h" #include "WallpaperEngine/Audio/CAudioContext.h"
namespace WallpaperEngine::Audio namespace WallpaperEngine::Audio {
{
class CAudioContext; class CAudioContext;
/** /**
* Represents a playable audio stream for the audio driver * Represents a playable audio stream for the audio driver
*/ */
class CAudioStream class CAudioStream {
{
public: public:
CAudioStream (CAudioContext& context, const std::string& filename); CAudioStream (CAudioContext& context, const std::string& filename);
CAudioStream (CAudioContext& context, const void* buffer, int length); CAudioStream (CAudioContext& context, const void* buffer, int length);
@ -148,7 +145,7 @@ namespace WallpaperEngine::Audio
* @param out_buf * @param out_buf
* @return * @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 * Queues a packet into the play queue
* *
@ -163,16 +160,16 @@ namespace WallpaperEngine::Audio
#if FF_API_OLD_CHANNEL_LAYOUT #if FF_API_OLD_CHANNEL_LAYOUT
/** Chanel layout needed for old FFMPEG versions */ /** Chanel layout needed for old FFMPEG versions */
AVChannelLayout m_out_channel_layout; AVChannelLayout m_out_channel_layout {};
#endif #endif
/** The SwrContext that handles resampling */ /** The SwrContext that handles resampling */
SwrContext* m_swrctx; SwrContext* m_swrctx;
/** The audio context this stream will be played under */ /** The audio context this stream will be played under */
CAudioContext& m_audioContext; CAudioContext& m_audioContext;
/** If this stream was properly initialized or not */ /** If this stream was properly initialized or not */
bool m_initialized; bool m_initialized {};
/** Repeat enabled? */ /** Repeat enabled? */
bool m_repeat; bool m_repeat {};
/** The codec context that contains the original audio format information */ /** The codec context that contains the original audio format information */
AVCodecContext* m_context = nullptr; AVCodecContext* m_context = nullptr;
/** The format context that controls how data is read off the file */ /** 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 */ /** The stream index for the audio being played */
int m_audioStream = -1; int m_audioStream = -1;
/** File data pointer */ /** File data pointer */
const void* m_buffer; const void* m_buffer {};
/** The length of the file data pointer */ /** The length of the file data pointer */
int m_length; int m_length {};
/** The read position on the file data pointer */ /** The read position on the file data pointer */
int m_position = 0; int m_position = 0;
struct MyAVPacketList struct MyAVPacketList {
{
AVPacket* packet; AVPacket* packet;
}; };
/** /**
* Packet queue information * Packet queue information
*/ */
struct PacketQueue struct PacketQueue {
{
#if FF_API_FIFO_OLD_API #if FF_API_FIFO_OLD_API
AVFifo* packetList; AVFifo* packetList;
#else #else
@ -207,6 +202,6 @@ namespace WallpaperEngine::Audio
SDL_mutex* mutex; SDL_mutex* mutex;
SDL_cond* wait; SDL_cond* wait;
SDL_cond* cond; SDL_cond* cond;
}* m_queue; }* m_queue {};
}; };
} } // namespace WallpaperEngine::Audio

View File

@ -1,31 +1,26 @@
#include "CAudioDriver.h" #include "CAudioDriver.h"
namespace WallpaperEngine::Audio::Drivers namespace WallpaperEngine::Audio::Drivers {
{ CAudioDriver::CAudioDriver (Application::CApplicationContext& applicationContext,
CAudioDriver::CAudioDriver (Application::CApplicationContext& applicationContext, Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder) : Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder) :
m_applicationContext (applicationContext), m_applicationContext (applicationContext),
m_detector (detector), m_detector (detector),
m_recorder (recorder) m_recorder (recorder) {}
{
}
void CAudioDriver::update () void CAudioDriver::update () {
{
this->m_recorder.update (); this->m_recorder.update ();
this->m_detector.update (); this->m_detector.update ();
} }
Application::CApplicationContext& CAudioDriver::getApplicationContext () Application::CApplicationContext& CAudioDriver::getApplicationContext () {
{
return this->m_applicationContext; return this->m_applicationContext;
} }
Detectors::CAudioPlayingDetector& CAudioDriver::getAudioDetector ()
{ Detectors::CAudioPlayingDetector& CAudioDriver::getAudioDetector () {
return this->m_detector; return this->m_detector;
} }
Recorders::CPlaybackRecorder& CAudioDriver::getRecorder () Recorders::CPlaybackRecorder& CAudioDriver::getRecorder () {
{
return this->m_recorder; return this->m_recorder;
} }
} } // namespace WallpaperEngine::Audio::Drivers

View File

@ -2,42 +2,37 @@
#include <vector> #include <vector>
#include "WallpaperEngine/Audio/Drivers/Detectors/CAudioPlayingDetector.h"
#include "WallpaperEngine/Audio/Drivers/Recorders/CPlaybackRecorder.h"
#include "WallpaperEngine/Application/CApplicationContext.h" #include "WallpaperEngine/Application/CApplicationContext.h"
#include "WallpaperEngine/Audio/CAudioStream.h" #include "WallpaperEngine/Audio/CAudioStream.h"
#include "WallpaperEngine/Audio/Drivers/Detectors/CAudioPlayingDetector.h"
#include "WallpaperEngine/Audio/Drivers/Recorders/CPlaybackRecorder.h"
namespace WallpaperEngine namespace WallpaperEngine {
{ namespace Application {
namespace Application
{
class CApplicationContext; class CApplicationContext;
} }
namespace Audio namespace Audio {
{
class CAudioStream; class CAudioStream;
namespace Drivers namespace Drivers {
{ namespace Detectors {
namespace Detectors
{
class CAudioPlayingDetector; class CAudioPlayingDetector;
} }
namespace Recorders namespace Recorders {
{
class CPulseAudioPlaybackRecorder; class CPulseAudioPlaybackRecorder;
} }
/** /**
* Base class for audio driver implementations * Base class for audio driver implementations
*/ */
class CAudioDriver class CAudioDriver {
{
public: 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 * Registers the given stream in the driver for playing
* *
@ -82,6 +77,6 @@ namespace WallpaperEngine
Detectors::CAudioPlayingDetector& m_detector; Detectors::CAudioPlayingDetector& m_detector;
Recorders::CPlaybackRecorder& m_recorder; Recorders::CPlaybackRecorder& m_recorder;
}; };
} } // namespace Drivers
} } // namespace Audio
} } // namespace WallpaperEngine

View File

@ -1,5 +1,5 @@
#include "common.h"
#include "CSDLAudioDriver.h" #include "CSDLAudioDriver.h"
#include "common.h"
#define SDL_AUDIO_BUFFER_SIZE 4096 #define SDL_AUDIO_BUFFER_SIZE 4096
#define MAX_AUDIO_FRAME_SIZE 192000 #define MAX_AUDIO_FRAME_SIZE 192000
@ -7,9 +7,8 @@
using namespace WallpaperEngine::Audio; using namespace WallpaperEngine::Audio;
using namespace WallpaperEngine::Audio::Drivers; using namespace WallpaperEngine::Audio::Drivers;
void audio_callback (void* userdata, uint8_t* streamData, int length) void audio_callback (void* userdata, uint8_t* streamData, int length) {
{ auto* driver = static_cast<CSDLAudioDriver*> (userdata);
auto* driver = reinterpret_cast <CSDLAudioDriver*> (userdata);
memset (streamData, 0, length); memset (streamData, 0, length);
@ -17,11 +16,9 @@ void audio_callback (void* userdata, uint8_t* streamData, int length)
if (driver->getAudioDetector ().anythingPlaying ()) if (driver->getAudioDetector ().anythingPlaying ())
return; return;
for (const auto& buffer : driver->getStreams ()) for (const auto& buffer : driver->getStreams ()) {
{
uint8_t* streamDataPointer = streamData; uint8_t* streamDataPointer = streamData;
int streamLength = length; int streamLength = length;
int len1, audio_size;
// sound is not initialized or stopped and is not in loop mode // sound is not initialized or stopped and is not in loop mode
// ignore mixing it in // ignore mixing it in
@ -29,43 +26,35 @@ void audio_callback (void* userdata, uint8_t* streamData, int length)
continue; continue;
// check if queue is empty and signal the read thread // check if queue is empty and signal the read thread
if (buffer->stream->isQueueEmpty ()) if (buffer->stream->isQueueEmpty ()) {
{
SDL_CondSignal (buffer->stream->getWaitCondition ()); SDL_CondSignal (buffer->stream->getWaitCondition ());
continue; continue;
} }
while (streamLength > 0 && driver->getApplicationContext ().state.general.keepRunning) while (streamLength > 0 && driver->getApplicationContext ().state.general.keepRunning) {
{ if (buffer->audio_buf_index >= buffer->audio_buf_size) {
if (buffer->audio_buf_index >= buffer->audio_buf_size)
{
// get more data to fill the buffer // 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 // fallback for errors, silence
buffer->audio_buf_size = 1024; buffer->audio_buf_size = 1024;
memset (buffer->audio_buf, 0, buffer->audio_buf_size); memset (buffer->audio_buf, 0, buffer->audio_buf_size);
} } else {
else
{
buffer->audio_buf_size = audio_size; buffer->audio_buf_size = audio_size;
} }
buffer->audio_buf_index = 0; 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) if (len1 > streamLength)
len1 = streamLength; len1 = streamLength;
// mix the audio // mix the audio
SDL_MixAudioFormat ( SDL_MixAudioFormat (streamDataPointer, &buffer->audio_buf [buffer->audio_buf_index],
streamDataPointer, &buffer->audio_buf [buffer->audio_buf_index], driver->getSpec ().format, len1, driver->getApplicationContext ().state.audio.volume);
driver->getSpec ().format, len1, driver->getApplicationContext ().state.audio.volume
);
streamLength -= len1; streamLength -= len1;
streamDataPointer += 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), CAudioDriver (applicationContext, detector, recorder),
m_initialized (false), m_initialized (false),
m_audioSpec () m_audioSpec () {
{ if (SDL_InitSubSystem (SDL_INIT_AUDIO) < 0) {
if (SDL_InitSubSystem (SDL_INIT_AUDIO) < 0)
{
sLog.error ("Cannot initialize SDL audio system, SDL_GetError: ", SDL_GetError ()); sLog.error ("Cannot initialize SDL audio system, SDL_GetError: ", SDL_GetError ());
sLog.error ("Continuing without audio support"); sLog.error ("Continuing without audio support");
return; 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; if (this->m_deviceID == 0) {
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)
{
sLog.error ("SDL_OpenAudioDevice: ", SDL_GetError ()); sLog.error ("SDL_OpenAudioDevice: ", SDL_GetError ());
return; return;
} }
@ -111,8 +95,7 @@ CSDLAudioDriver::CSDLAudioDriver (Application::CApplicationContext& applicationC
this->m_initialized = true; this->m_initialized = true;
} }
CSDLAudioDriver::~CSDLAudioDriver () CSDLAudioDriver::~CSDLAudioDriver () {
{
if (!this->m_initialized) if (!this->m_initialized)
return; return;
@ -120,39 +103,39 @@ CSDLAudioDriver::~CSDLAudioDriver ()
SDL_QuitSubSystem (SDL_INIT_AUDIO); SDL_QuitSubSystem (SDL_INIT_AUDIO);
} }
void CSDLAudioDriver::addStream (CAudioStream* stream) void CSDLAudioDriver::addStream (CAudioStream* stream) {
{
this->m_streams.push_back (new CSDLAudioBuffer {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; return this->m_streams;
} }
AVSampleFormat CSDLAudioDriver::getFormat () const AVSampleFormat CSDLAudioDriver::getFormat () const {
{ switch (this->m_audioSpec.format) {
switch (this->m_audioSpec.format) case AUDIO_U8:
{ case AUDIO_S8: return AV_SAMPLE_FMT_U8;
case AUDIO_U8: case AUDIO_S8: return AV_SAMPLE_FMT_U8; case AUDIO_U16MSB:
case AUDIO_U16MSB: case AUDIO_U16LSB: case AUDIO_S16LSB: case AUDIO_S16MSB: return AV_SAMPLE_FMT_S16; case AUDIO_U16LSB:
case AUDIO_S32LSB: case AUDIO_S32MSB: return AV_SAMPLE_FMT_S32; case AUDIO_S16LSB:
case AUDIO_F32LSB: case AUDIO_F32MSB: return AV_SAMPLE_FMT_FLT; 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..."); sLog.exception ("Cannot convert from SDL format to ffmpeg format, aborting...");
} }
int CSDLAudioDriver::getSampleRate () const int CSDLAudioDriver::getSampleRate () const {
{
return this->m_audioSpec.freq; return this->m_audioSpec.freq;
} }
int CSDLAudioDriver::getChannels () const int CSDLAudioDriver::getChannels () const {
{
return this->m_audioSpec.channels; return this->m_audioSpec.channels;
} }
const SDL_AudioSpec& CSDLAudioDriver::getSpec () const
{ const SDL_AudioSpec& CSDLAudioDriver::getSpec () const {
return this->m_audioSpec; return this->m_audioSpec;
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <vector>
#include <map> #include <map>
#include <vector>
#include "WallpaperEngine/Audio/CAudioStream.h" #include "WallpaperEngine/Audio/CAudioStream.h"
#include "WallpaperEngine/Audio/Drivers/CAudioDriver.h" #include "WallpaperEngine/Audio/Drivers/CAudioDriver.h"
@ -10,13 +10,11 @@
#define MAX_AUDIO_FRAME_SIZE 192000 #define MAX_AUDIO_FRAME_SIZE 192000
namespace WallpaperEngine::Audio::Drivers namespace WallpaperEngine::Audio::Drivers {
{
/** /**
* Audio output buffers for streams being played under SDL * Audio output buffers for streams being played under SDL
*/ */
struct CSDLAudioBuffer struct CSDLAudioBuffer {
{
CAudioStream* stream; 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_size = 0;
@ -26,11 +24,11 @@ namespace WallpaperEngine::Audio::Drivers
/** /**
* SDL's audio driver implementation * SDL's audio driver implementation
*/ */
class CSDLAudioDriver : public CAudioDriver class CSDLAudioDriver final : public CAudioDriver {
{
public: public:
CSDLAudioDriver (Application::CApplicationContext& applicationContext, Detectors::CAudioPlayingDetector& detector, Recorders::CPlaybackRecorder& recorder); CSDLAudioDriver (Application::CApplicationContext& applicationContext, Detectors::CAudioPlayingDetector& detector,
~CSDLAudioDriver (); Recorders::CPlaybackRecorder& recorder);
~CSDLAudioDriver () override;
/** @inheritdoc */ /** @inheritdoc */
void addStream (CAudioStream* stream) override; void addStream (CAudioStream* stream) override;
@ -60,4 +58,4 @@ namespace WallpaperEngine::Audio::Drivers
/** All the playable steams */ /** All the playable steams */
std::vector<CSDLAudioBuffer*> m_streams; std::vector<CSDLAudioBuffer*> m_streams;
}; };
} } // namespace WallpaperEngine::Audio::Drivers

View File

@ -1,33 +1,26 @@
#include "CAudioPlayingDetector.h" #include "CAudioPlayingDetector.h"
namespace WallpaperEngine::Audio::Drivers::Detectors namespace WallpaperEngine::Audio::Drivers::Detectors {
{
CAudioPlayingDetector::CAudioPlayingDetector ( CAudioPlayingDetector::CAudioPlayingDetector (
Application::CApplicationContext& appContext, Application::CApplicationContext& appContext,
const Render::Drivers::Detectors::CFullScreenDetector& fullscreenDetector) : const Render::Drivers::Detectors::CFullScreenDetector& fullscreenDetector) :
m_applicationContext (appContext), m_applicationContext (appContext),
m_fullscreenDetector (fullscreenDetector), m_fullscreenDetector (fullscreenDetector),
m_isPlaying (false) m_isPlaying (false) {}
{
}
bool CAudioPlayingDetector::anythingPlaying () const bool CAudioPlayingDetector::anythingPlaying () const {
{
return this->m_isPlaying; return this->m_isPlaying;
} }
Application::CApplicationContext& CAudioPlayingDetector::getApplicationContext () Application::CApplicationContext& CAudioPlayingDetector::getApplicationContext () {
{
return this->m_applicationContext; return this->m_applicationContext;
} }
const Render::Drivers::Detectors::CFullScreenDetector& CAudioPlayingDetector::getFullscreenDetector () const const Render::Drivers::Detectors::CFullScreenDetector& CAudioPlayingDetector::getFullscreenDetector () const {
{
return this->m_fullscreenDetector; return this->m_fullscreenDetector;
} }
void CAudioPlayingDetector::setIsPlaying (bool newState) void CAudioPlayingDetector::setIsPlaying (bool newState) {
{
this->m_isPlaying = newState; this->m_isPlaying = newState;
} }
} } // namespace WallpaperEngine::Audio::Drivers::Detectors

View File

@ -1,29 +1,27 @@
#pragma once #pragma once
#include "WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h"
#include "WallpaperEngine/Application/CApplicationContext.h" #include "WallpaperEngine/Application/CApplicationContext.h"
#include "WallpaperEngine/Render/Drivers/Detectors/CFullScreenDetector.h"
namespace WallpaperEngine namespace WallpaperEngine {
{ namespace Application {
namespace Application
{
class CApplicationContext; class CApplicationContext;
} }
namespace Render::Drivers::Detectors namespace Render::Drivers::Detectors {
{
class CFullScreenDetector; class CFullScreenDetector;
} }
namespace Audio::Drivers::Detectors namespace Audio::Drivers::Detectors {
{
/** /**
* Base class for any implementation of audio playing detection * Base class for any implementation of audio playing detection
*/ */
class CAudioPlayingDetector class CAudioPlayingDetector {
{
public: 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 * @return If any kind of sound is currently playing on the default audio device
@ -56,5 +54,5 @@ namespace WallpaperEngine
Application::CApplicationContext& m_applicationContext; Application::CApplicationContext& m_applicationContext;
const Render::Drivers::Detectors::CFullScreenDetector& m_fullscreenDetector; const Render::Drivers::Detectors::CFullScreenDetector& m_fullscreenDetector;
}; };
} } // namespace Audio::Drivers::Detectors
} } // namespace WallpaperEngine

View File

@ -3,10 +3,8 @@
#include <unistd.h> #include <unistd.h>
namespace WallpaperEngine::Audio::Drivers::Detectors namespace WallpaperEngine::Audio::Drivers::Detectors {
{ void sinkInputInfoCallback (pa_context* context, const pa_sink_input_info* info, int eol, void* userdata) {
void sinkInputInfoCallback (pa_context* context, const pa_sink_input_info* info, int eol, void* userdata)
{
auto* detector = static_cast<CPulseAudioPlayingDetector*> (userdata); auto* detector = static_cast<CPulseAudioPlayingDetector*> (userdata);
if (info == nullptr) if (info == nullptr)
@ -22,8 +20,7 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
detector->setIsPlaying (true); 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) if (info == nullptr)
return; return;
@ -38,8 +35,7 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
CAudioPlayingDetector (appContext, fullscreenDetector), CAudioPlayingDetector (appContext, fullscreenDetector),
m_mainloop (nullptr), m_mainloop (nullptr),
m_mainloopApi (nullptr), m_mainloopApi (nullptr),
m_context (nullptr) m_context (nullptr) {
{
this->m_mainloop = pa_mainloop_new (); this->m_mainloop = pa_mainloop_new ();
this->m_mainloopApi = pa_mainloop_get_api (this->m_mainloop); this->m_mainloopApi = pa_mainloop_get_api (this->m_mainloop);
this->m_context = pa_context_new (this->m_mainloopApi, "wallpaperengine"); this->m_context = pa_context_new (this->m_mainloopApi, "wallpaperengine");
@ -51,10 +47,8 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
pa_mainloop_iterate (this->m_mainloop, 1, nullptr); pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
} }
CPulseAudioPlayingDetector::~CPulseAudioPlayingDetector () CPulseAudioPlayingDetector::~CPulseAudioPlayingDetector () {
{ if (this->m_context) {
if (this->m_context)
{
pa_context_disconnect (this->m_context); pa_context_disconnect (this->m_context);
pa_context_unref (this->m_context); pa_context_unref (this->m_context);
} }
@ -63,9 +57,7 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
pa_mainloop_free (this->m_mainloop); pa_mainloop_free (this->m_mainloop);
} }
void CPulseAudioPlayingDetector::update () {
void CPulseAudioPlayingDetector::update ()
{
if (!this->getApplicationContext ().settings.audio.automute) if (!this->getApplicationContext ().settings.audio.automute)
return this->setIsPlaying (false); return this->setIsPlaying (false);
if (this->getFullscreenDetector ().anythingFullscreen ()) if (this->getFullscreenDetector ().anythingFullscreen ())
@ -75,7 +67,7 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
this->setIsPlaying (false); this->setIsPlaying (false);
// start discovery of sinks // 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 // wait until all the operations are done
while (pa_operation_get_state (op) == PA_OPERATION_RUNNING) while (pa_operation_get_state (op) == PA_OPERATION_RUNNING)
@ -83,4 +75,4 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
pa_operation_unref (op); pa_operation_unref (op);
} }
} } // namespace WallpaperEngine::Audio::Drivers::Detectors

View File

@ -1,17 +1,16 @@
#pragma once #pragma once
#include "CAudioPlayingDetector.h"
#include <condition_variable> #include <condition_variable>
#include <mutex> #include <mutex>
#include "CAudioPlayingDetector.h"
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
namespace WallpaperEngine::Audio::Drivers::Detectors namespace WallpaperEngine::Audio::Drivers::Detectors {
{ class CPulseAudioPlayingDetector final : public CAudioPlayingDetector {
class CPulseAudioPlayingDetector : public CAudioPlayingDetector
{
public: public:
explicit CPulseAudioPlayingDetector (Application::CApplicationContext& appContext, const Render::Drivers::Detectors::CFullScreenDetector&); explicit CPulseAudioPlayingDetector (Application::CApplicationContext& appContext,
~CPulseAudioPlayingDetector (); const Render::Drivers::Detectors::CFullScreenDetector&);
~CPulseAudioPlayingDetector () override;
void update () override; void update () override;
@ -20,4 +19,4 @@ namespace WallpaperEngine::Audio::Drivers::Detectors
pa_mainloop_api* m_mainloopApi; pa_mainloop_api* m_mainloopApi;
pa_context* m_context; pa_context* m_context;
}; };
} } // namespace WallpaperEngine::Audio::Drivers::Detectors

View File

@ -1,14 +1,14 @@
#pragma once #pragma once
namespace WallpaperEngine::Audio::Drivers::Recorders namespace WallpaperEngine::Audio::Drivers::Recorders {
{ class CPlaybackRecorder {
class CPlaybackRecorder
{
public: public:
virtual ~CPlaybackRecorder () = default;
virtual void update () = 0; virtual void update () = 0;
float audio16 [16] = {0}; float audio16 [16] = {0};
float audio32 [32] = {0}; float audio32 [32] = {0};
float audio64 [64] = {0}; float audio64 [64] = {0};
}; };
} } // namespace WallpaperEngine::Audio::Drivers::Recorders

View File

@ -1,42 +1,33 @@
#include <cstring>
#include <cmath>
#include <glm/common.hpp>
#include "CPulseAudioPlaybackRecorder.h" #include "CPulseAudioPlaybackRecorder.h"
#include "WallpaperEngine/Logging/CLog.h"
#include "External/Android/fft.h" #include "External/Android/fft.h"
#include "WallpaperEngine/Logging/CLog.h"
#include <cmath>
#include <cstring>
#include <glm/common.hpp>
namespace WallpaperEngine::Audio::Drivers::Recorders namespace WallpaperEngine::Audio::Drivers::Recorders {
{ float movetowards (float current, float target, float maxDelta) {
float movetowards(float current, float target, float maxDelta)
{
if (abs (target - current) <= maxDelta) if (abs (target - current) <= maxDelta)
return target; 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*/) void pa_stream_notify_cb (pa_stream* stream, void* /*userdata*/) {
{ switch (pa_stream_get_state (stream)) {
const pa_stream_state state = pa_stream_get_state(stream); case PA_STREAM_FAILED: sLog.error ("Cannot open stream for capture. Audio processing is disabled"); break;
switch (state) { case PA_STREAM_READY: sLog.debug ("Capture stream ready"); break;
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) void pa_stream_read_cb (pa_stream* stream, const size_t /*nbytes*/, void* userdata) {
{ auto* recorder = static_cast<CPulseAudioPlaybackRecorder*> (userdata);
auto* recorder = reinterpret_cast<CPulseAudioPlaybackRecorder*>(userdata);
// Careful when to pa_stream_peek() and pa_stream_drop()! // Careful when to pa_stream_peek() and pa_stream_drop()!
// c.f. https://www.freedesktop.org/software/pulseaudio/doxygen/stream_8h.html#ac2838c449cde56e169224d7fe3d00824 // c.f. https://www.freedesktop.org/software/pulseaudio/doxygen/stream_8h.html#ac2838c449cde56e169224d7fe3d00824
uint8_t *data = nullptr; const void* data = nullptr;
size_t currentSize; size_t currentSize;
if (pa_stream_peek(stream, (const void**)&data, &currentSize) != 0) { if (pa_stream_peek (stream, &data, &currentSize) != 0) {
sLog.error ("Failed to peek at stream data..."); sLog.error ("Failed to peek at stream data...");
return; return;
} }
@ -44,7 +35,9 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
if (data == nullptr && currentSize == 0) { if (data == nullptr && currentSize == 0) {
// No data in the buffer, ignore. // No data in the buffer, ignore.
return; return;
} else if (data == nullptr && currentSize > 0) { }
if (data == nullptr && currentSize > 0) {
// Hole in the buffer. We must drop it. // 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!"); sLog.error ("Failed to drop a hole while capturing!");
@ -82,17 +75,15 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
} }
} }
void pa_server_info_cb(pa_context *ctx, const pa_server_info *info, void* userdata) void pa_server_info_cb (pa_context* ctx, const pa_server_info* info, void* userdata) {
{ auto* recorder = static_cast<CPulseAudioPlaybackRecorder*> (userdata);
auto* recorder = reinterpret_cast<CPulseAudioPlaybackRecorder*>(userdata);
pa_sample_spec spec; pa_sample_spec spec;
spec.format = PA_SAMPLE_U8; spec.format = PA_SAMPLE_U8;
spec.rate = 44100; spec.rate = 44100;
spec.channels = 1; spec.channels = 1;
if (recorder->getCaptureStream ()) if (recorder->getCaptureStream ()) {
{
pa_stream_unref (recorder->getCaptureStream ()); pa_stream_unref (recorder->getCaptureStream ());
// get rid of the reference just in case // get rid of the reference just in case
recorder->setCaptureStream (nullptr); recorder->setCaptureStream (nullptr);
@ -111,29 +102,23 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
monitor_name += ".monitor"; 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"); 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 // 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) void pa_context_notify_cb (pa_context* ctx, void* userdata) {
{ switch (pa_context_get_state (ctx)) {
const pa_context_state state = pa_context_get_state(ctx); case PA_CONTEXT_READY: {
switch (state) {
case PA_CONTEXT_READY:
{
// set callback // set callback
pa_context_set_subscribe_callback (ctx, pa_context_subscribe_cb, userdata); 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 ( pa_operation* o = pa_context_subscribe (
ctx, static_cast<pa_subscription_mask_t> (PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE), ctx, static_cast<pa_subscription_mask_t> (PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE),
NULL, NULL nullptr, nullptr);
);
if (o) if (o)
pa_operation_unref (o); pa_operation_unref (o);
@ -149,9 +134,7 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
} }
} }
CPulseAudioPlaybackRecorder::CPulseAudioPlaybackRecorder () : CPulseAudioPlaybackRecorder::CPulseAudioPlaybackRecorder () : m_captureStream (nullptr) {
m_captureStream (nullptr)
{
this->m_mainloop = pa_mainloop_new (); this->m_mainloop = pa_mainloop_new ();
this->m_mainloopApi = pa_mainloop_get_api (this->m_mainloop); this->m_mainloopApi = pa_mainloop_get_api (this->m_mainloop);
this->m_context = pa_context_new (this->m_mainloopApi, "wallpaperengine-audioprocessing"); this->m_context = pa_context_new (this->m_mainloopApi, "wallpaperengine-audioprocessing");
@ -168,24 +151,20 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
pa_mainloop_iterate (this->m_mainloop, 1, nullptr); pa_mainloop_iterate (this->m_mainloop, 1, nullptr);
} }
CPulseAudioPlaybackRecorder::~CPulseAudioPlaybackRecorder () CPulseAudioPlaybackRecorder::~CPulseAudioPlaybackRecorder () {
{
pa_context_disconnect (this->m_context); pa_context_disconnect (this->m_context);
pa_mainloop_free (this->m_mainloop); pa_mainloop_free (this->m_mainloop);
} }
pa_stream* CPulseAudioPlaybackRecorder::getCaptureStream () pa_stream* CPulseAudioPlaybackRecorder::getCaptureStream () {
{
return this->m_captureStream; return this->m_captureStream;
} }
void CPulseAudioPlaybackRecorder::setCaptureStream (pa_stream* stream) void CPulseAudioPlaybackRecorder::setCaptureStream (pa_stream* stream) {
{
this->m_captureStream = stream; this->m_captureStream = stream;
} }
void CPulseAudioPlaybackRecorder::update () void CPulseAudioPlaybackRecorder::update () {
{
pa_mainloop_iterate (this->m_mainloop, 0, nullptr); pa_mainloop_iterate (this->m_mainloop, 0, nullptr);
// interpolate current values to the destination // interpolate current values to the destination
@ -207,17 +186,20 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
External::Android::doFft (audio_fft, audio_buffer); External::Android::doFft (audio_fft, audio_buffer);
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
int paramInt = (i + 2) * 2; const int paramInt = (i + 2) * 2;
float f1 = audio_fft [paramInt]; float f1 = audio_fft [paramInt];
float f2 = audio_fft [paramInt + 1]; float f2 = audio_fft [paramInt + 1];
f2 = f1 * f1 + f2 * f2; f2 = f1 * f1 + f2 * f2;
f1 = 0.0F; f1 = 0.0F;
if (f2 > 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_destination64 [i] =
this->fft_destination32[i >> 1] = fmin(1.0F, f1 * (float)(2.0f - pow(M_E, (1.0F - i / 31.0F) * 1.0f - 0.5f))); fmin (1.0F, f1 * static_cast<float> (2.0f - pow (M_E, (1.0F - i / 63.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_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

View File

@ -1,18 +1,16 @@
#pragma once #pragma once
#include <pulse/pulseaudio.h>
#include "External/Android/fft.h"
#include "CPlaybackRecorder.h" #include "CPlaybackRecorder.h"
#include "External/Android/fft.h"
#include <pulse/pulseaudio.h>
namespace WallpaperEngine::Audio::Drivers::Recorders namespace WallpaperEngine::Audio::Drivers::Recorders {
{
class CPlaybackRecorder; class CPlaybackRecorder;
class CPulseAudioPlaybackRecorder : public CPlaybackRecorder class CPulseAudioPlaybackRecorder final : public CPlaybackRecorder {
{
public: public:
CPulseAudioPlaybackRecorder (); CPulseAudioPlaybackRecorder ();
~CPulseAudioPlaybackRecorder (); ~CPulseAudioPlaybackRecorder () override;
void update () override; void update () override;
@ -42,4 +40,4 @@ namespace WallpaperEngine::Audio::Drivers::Recorders
float fft_destination32 [32]; float fft_destination32 [32];
float fft_destination16 [16]; float fft_destination16 [16];
}; };
} } // namespace WallpaperEngine::Audio::Drivers::Recorders

View File

@ -1,13 +1,13 @@
#include "common.h"
#include "CObject.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/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" #include "WallpaperEngine/Assets/CContainer.h"
@ -15,15 +15,8 @@ using namespace WallpaperEngine::Core;
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
CObject::CObject ( CObject::CObject (CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name, std::string type,
CScene* scene, CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles) :
CUserSettingBoolean* visible,
uint32_t id,
std::string name,
std::string type,
CUserSettingVector3* origin,
CUserSettingVector3* scale,
const glm::vec3& angles) :
m_scene (scene), m_scene (scene),
m_visible (visible), m_visible (visible),
m_id (id), m_id (id),
@ -31,12 +24,9 @@ CObject::CObject (
m_type (std::move (type)), m_type (std::move (type)),
m_origin (origin), m_origin (origin),
m_scale (scale), 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 (); std::string json = data.dump ();
auto id_it = jsonFindRequired (data, "id", "Objects must have id"); auto id_it = jsonFindRequired (data, "id", "Objects must have id");
@ -56,142 +46,89 @@ CObject* CObject::fromJSON (json data, CScene* scene, CContainer* container)
CObject* object; CObject* object;
if (image_it != data.end () && !(*image_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,
object = Objects::CImage::fromJSON ( WallpaperEngine::Core::aToVector3 (angles_val));
scene, } else if (sound_it != data.end () && !sound_it->is_null ()) {
data, object = Objects::CSound::fromJSON (scene, data, visible, *id_it, *name_it, origin, scale,
container, WallpaperEngine::Core::aToVector3 (angles_val));
visible, } else if (particle_it != data.end () && !particle_it->is_null ()) {
*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 /// TODO: XXXHACK -- TO REMOVE WHEN PARTICLE SUPPORT IS PROPERLY IMPLEMENTED
try try {
{ object = Objects::CParticle::fromFile (scene, particle_it->get<std::string> (), container, visible, *id_it,
object = Objects::CParticle::fromFile ( *name_it, origin, scale);
scene, } catch (std::runtime_error&) {
(*particle_it).get <std::string> (),
container,
visible,
*id_it,
*name_it,
origin,
scale
);
}
catch (std::runtime_error& ex)
{
return nullptr; 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 /// TODO: XXXHACK -- TO REMOVE WHEN TEXT SUPPORT IS IMPLEMENTED
return nullptr; 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 /// TODO: XXXHACK -- TO REMOVE WHEN LIGHT SUPPORT IS IMPLEMENTED
return nullptr; return nullptr;
} } else {
else
{
sLog.exception ("Unknown object type detected: ", *name_it); sLog.exception ("Unknown object type detected: ", *name_it);
} }
if (effects_it != data.end () && (*effects_it).is_array ()) if (effects_it != data.end () && effects_it->is_array ()) {
{ for (auto& cur : *effects_it) {
for (auto& cur : *effects_it)
{
auto effectVisible = jsonFindUserConfig<CUserSettingBoolean> (cur, "visible", true); auto effectVisible = jsonFindUserConfig<CUserSettingBoolean> (cur, "visible", true);
if (!effectVisible->processValue (scene->getProject ().getProperties ())) if (!effectVisible->processValue (scene->getProject ().getProperties ()))
continue; continue;
object->insertEffect ( object->insertEffect (Objects::CEffect::fromJSON (cur, effectVisible, object, container));
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) for (const auto& cur : *dependencies_it)
object->insertDependency (cur); object->insertDependency (cur);
return object; return object;
} }
glm::vec3 CObject::getOrigin () const glm::vec3 CObject::getOrigin () const {
{
return this->m_origin->processValue (this->getScene ()->getProject ().getProperties ()); 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 ()); 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; return this->m_angles;
} }
const std::string& CObject::getName () const const std::string& CObject::getName () const {
{
return this->m_name; return this->m_name;
} }
const std::vector<Objects::CEffect*>& CObject::getEffects () const const std::vector<Objects::CEffect*>& CObject::getEffects () const {
{
return this->m_effects; return this->m_effects;
} }
const std::vector<uint32_t>& CObject::getDependencies () const const std::vector<uint32_t>& CObject::getDependencies () const {
{
return this->m_dependencies; return this->m_dependencies;
} }
bool CObject::isVisible () const bool CObject::isVisible () const {
{
// TODO: cache this // TODO: cache this
return this->m_visible->processValue (this->getScene ()->getProject ().getProperties ()); return this->m_visible->processValue (this->getScene ()->getProject ().getProperties ());
} }
CScene* CObject::getScene () const CScene* CObject::getScene () const {
{
return this->m_scene; return this->m_scene;
} }
int CObject::getId () const int CObject::getId () const {
{
return this->m_id; return this->m_id;
} }
void CObject::insertEffect (Objects::CEffect* effect) void CObject::insertEffect (Objects::CEffect* effect) {
{
this->m_effects.push_back (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); this->m_dependencies.push_back (dependency);
} }

View File

@ -8,37 +8,42 @@
#include "WallpaperEngine/Core/UserSettings/CUserSettingFloat.h" #include "WallpaperEngine/Core/UserSettings/CUserSettingFloat.h"
#include "WallpaperEngine/Core/UserSettings/CUserSettingVector3.h" #include "WallpaperEngine/Core/UserSettings/CUserSettingVector3.h"
namespace WallpaperEngine::Core namespace WallpaperEngine::Core {
{
class CScene; class CScene;
} }
namespace WallpaperEngine::Core::Objects namespace WallpaperEngine::Core::Objects {
{
class CEffect; class CEffect;
} }
namespace WallpaperEngine::Core::UserSettings namespace WallpaperEngine::Core::UserSettings {
{
class CUserSettingBoolean; class CUserSettingBoolean;
} }
namespace WallpaperEngine::Core namespace WallpaperEngine::Core {
{
using json = nlohmann::json; using json = nlohmann::json;
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
class CObject class CObject {
{
friend class CScene; friend class CScene;
public: public:
static CObject* fromJSON (json data, CScene* scene, CContainer* container); 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> const T* as () const {
template<class T> T* as () { assert (is <T> ()); return (T*) this; } 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<Objects::CEffect*>& getEffects () const;
const std::vector<uint32_t>& getDependencies () const; const std::vector<uint32_t>& getDependencies () const;
@ -51,20 +56,14 @@ namespace WallpaperEngine::Core
bool isVisible () const; bool isVisible () const;
CScene* getScene () const; CScene* getScene () const;
protected: protected:
CObject ( CObject (CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name, std::string type,
CScene* scene, CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles);
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 insertEffect (Objects::CEffect* effect);
void insertDependency (uint32_t dependency); void insertDependency (uint32_t dependency);
private: private:
std::string m_type; std::string m_type;
@ -80,4 +79,4 @@ namespace WallpaperEngine::Core
CScene* m_scene; CScene* m_scene;
}; };
} } // namespace WallpaperEngine::Core

View File

@ -12,18 +12,16 @@ using namespace WallpaperEngine::Assets;
CProject::CProject (std::string title, std::string type, CContainer* container) : CProject::CProject (std::string title, std::string type, CContainer* container) :
m_title (std::move (title)), m_title (std::move (title)),
m_type (std::move (type)), 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)); 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 type = *jsonFindRequired (content, "type", "Project type missing");
std::string file = *jsonFindRequired (content, "file", "Project's main file missing"); const std::string file = *jsonFindRequired (content, "file", "Project's main file missing");
auto general = content.find ("general"); const auto general = content.find ("general");
CWallpaper* wallpaper; CWallpaper* wallpaper;
std::transform (type.begin (), type.end (), type.begin (), tolower); 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") if (type == "scene")
wallpaper = CScene::fromFile (file, *project, container); wallpaper = CScene::fromFile (file, *project, container);
else if (type == "video") else if (type == "video")
wallpaper = new CVideo (file.c_str (), *project); wallpaper = new CVideo (file, *project);
else if (type == "web") else if (type == "web")
sLog.exception ("Web wallpapers are not supported yet"); sLog.exception ("Web wallpapers are not supported yet");
else else
@ -41,14 +39,11 @@ CProject* CProject::fromFile (const std::string& filename, CContainer* container
project->setWallpaper (wallpaper); project->setWallpaper (wallpaper);
if (general != content.end ()) if (general != content.end ()) {
{ const auto properties = general->find ("properties");
auto properties = (*general).find ("properties");
if (properties != (*general).end ()) if (properties != general->end ()) {
{ for (const auto& cur : properties->items ()) {
for (const auto& cur : (*properties).items ())
{
Projects::CProperty* property = Projects::CProperty::fromJSON (cur.value (), cur.key ()); Projects::CProperty* property = Projects::CProperty::fromJSON (cur.value (), cur.key ());
if (property != nullptr) if (property != nullptr)
@ -60,37 +55,30 @@ CProject* CProject::fromFile (const std::string& filename, CContainer* container
return project; return project;
} }
void CProject::setWallpaper (CWallpaper* wallpaper) void CProject::setWallpaper (CWallpaper* wallpaper) {
{
this->m_wallpaper = wallpaper; this->m_wallpaper = wallpaper;
} }
CWallpaper* CProject::getWallpaper () const CWallpaper* CProject::getWallpaper () const {
{
return this->m_wallpaper; return this->m_wallpaper;
} }
const std::string& CProject::getTitle () const const std::string& CProject::getTitle () const {
{
return this->m_title; return this->m_title;
} }
const std::string& CProject::getType () const const std::string& CProject::getType () const {
{
return this->m_type; return this->m_type;
} }
const std::vector<Projects::CProperty*>& CProject::getProperties () const const std::vector<Projects::CProperty*>& CProject::getProperties () const {
{
return this->m_properties; return this->m_properties;
} }
CContainer* CProject::getContainer () CContainer* CProject::getContainer () {
{
return this->m_container; return this->m_container;
} }
void CProject::insertProperty (Projects::CProperty* property) void CProject::insertProperty (Projects::CProperty* property) {
{
this->m_properties.push_back (property); this->m_properties.push_back (property);
} }

View File

@ -6,15 +6,13 @@
#include "WallpaperEngine/Assets/CContainer.h" #include "WallpaperEngine/Assets/CContainer.h"
namespace WallpaperEngine::Core namespace WallpaperEngine::Core {
{
using json = nlohmann::json; using json = nlohmann::json;
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
class CWallpaper; class CWallpaper;
class CProject class CProject {
{
public: public:
static CProject* fromFile (const std::string& filename, CContainer* container); static CProject* fromFile (const std::string& filename, CContainer* container);
@ -31,6 +29,7 @@ namespace WallpaperEngine::Core
void setWallpaper (CWallpaper* wallpaper); void setWallpaper (CWallpaper* wallpaper);
void insertProperty (Projects::CProperty* property); void insertProperty (Projects::CProperty* property);
private: private:
std::vector<Projects::CProperty*> m_properties; std::vector<Projects::CProperty*> m_properties;
@ -39,4 +38,4 @@ namespace WallpaperEngine::Core
CWallpaper* m_wallpaper; CWallpaper* m_wallpaper;
CContainer* m_container; CContainer* m_container;
}; };
} } // namespace WallpaperEngine::Core

View File

@ -8,27 +8,12 @@
using namespace WallpaperEngine::Core; using namespace WallpaperEngine::Core;
CScene::CScene ( CScene::CScene (CProject& project, CContainer* container, Scenes::CCamera* camera, glm::vec3 ambientColor,
CProject& project, CUserSettingBoolean* bloom, CUserSettingFloat* bloomStrength, CUserSettingFloat* bloomThreshold,
CContainer* container, bool cameraFade, bool cameraParallax, double cameraParallaxAmount, double cameraParallaxDelay,
Scenes::CCamera* camera, double cameraParallaxMouseInfluence, bool cameraPreview, bool cameraShake, double cameraShakeAmplitude,
glm::vec3 ambientColor, double cameraShakeRoughness, double cameraShakeSpeed, CUserSettingVector3* clearColor,
CUserSettingBoolean* bloom, Scenes::CProjection* orthogonalProjection, glm::vec3 skylightColor) :
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), CWallpaper (Type, project),
m_container (container), m_container (container),
m_camera (camera), m_camera (camera),
@ -48,60 +33,44 @@ CScene::CScene (
m_cameraShakeSpeed (cameraShakeSpeed), m_cameraShakeSpeed (cameraShakeSpeed),
m_clearColor (clearColor), m_clearColor (clearColor),
m_orthogonalProjection (orthogonalProjection), 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); std::string stringContent = WallpaperEngine::FileSystem::loadFullFile (filename, container);
json content = json::parse (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"); const auto camera_it = jsonFindRequired (content, "camera", "Scenes must have a defined camera");
auto general_it = jsonFindRequired (content, "general", "Scenes must have a general section"); const 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 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 // TODO: FIND IF THESE DEFAULTS ARE SENSIBLE OR NOT AND PERFORM PROPER VALIDATION WHEN CAMERA PREVIEW AND CAMERA
auto ambientcolor = jsonFindDefault <std::string> (*general_it, "ambientcolor", "0 0 0"); // PARALLAX ARE PRESENT
auto bloom = jsonFindUserConfig <CUserSettingBoolean> (*general_it, "bloom", false); const auto ambientcolor = jsonFindDefault<std::string> (*general_it, "ambientcolor", "0 0 0");
auto bloomstrength = jsonFindUserConfig <CUserSettingFloat> (*general_it, "bloomstrength", 0.0); const auto bloom = jsonFindUserConfig<CUserSettingBoolean> (*general_it, "bloom", false);
auto bloomthreshold = jsonFindUserConfig <CUserSettingFloat> (*general_it, "bloomthreshold", 0.0); const auto bloomstrength = jsonFindUserConfig<CUserSettingFloat> (*general_it, "bloomstrength", 0.0);
auto camerafade = jsonFindDefault <bool> (*general_it, "camerafade", false); const auto bloomthreshold = jsonFindUserConfig<CUserSettingFloat> (*general_it, "bloomthreshold", 0.0);
auto cameraparallax = jsonFindDefault <bool> (*general_it, "cameraparallax", true); const auto camerafade = jsonFindDefault<bool> (*general_it, "camerafade", false);
auto cameraparallaxamount = jsonFindDefault <double> (*general_it, "cameraparallaxamount", 1.0f); const auto cameraparallax = jsonFindDefault<bool> (*general_it, "cameraparallax", true);
auto cameraparallaxdelay = jsonFindDefault <double> (*general_it, "cameraparallaxdelay", 0.0f); const auto cameraparallaxamount = jsonFindDefault<double> (*general_it, "cameraparallaxamount", 1.0f);
auto cameraparallaxmouseinfluence = jsonFindDefault <double> (*general_it, "cameraparallaxmouseinfluence", 1.0f); const auto cameraparallaxdelay = jsonFindDefault<double> (*general_it, "cameraparallaxdelay", 0.0f);
auto camerapreview = jsonFindDefault <bool> (*general_it, "camerapreview", false); const auto cameraparallaxmouseinfluence =
auto camerashake = jsonFindDefault <bool> (*general_it, "camerashake", false); jsonFindDefault<double> (*general_it, "cameraparallaxmouseinfluence", 1.0f);
auto camerashakeamplitude = jsonFindDefault <double> (*general_it, "camerashakeamplitude", 0.0f); const auto camerapreview = jsonFindDefault<bool> (*general_it, "camerapreview", false);
auto camerashakeroughness = jsonFindDefault <double> (*general_it, "camerashakeroughness", 0.0f); const auto camerashake = jsonFindDefault<bool> (*general_it, "camerashake", false);
auto camerashakespeed = jsonFindDefault <double> (*general_it, "camerashakespeed", 0.0f); const auto camerashakeamplitude = jsonFindDefault<double> (*general_it, "camerashakeamplitude", 0.0f);
auto clearcolor = jsonFindUserConfig <CUserSettingVector3> (*general_it, "clearcolor", {1, 1, 1}); const auto camerashakeroughness = jsonFindDefault<double> (*general_it, "camerashakeroughness", 0.0f);
auto orthogonalprojection_it = jsonFindRequired (*general_it, "orthogonalprojection", "General section must have orthogonal projection info"); const auto camerashakespeed = jsonFindDefault<double> (*general_it, "camerashakespeed", 0.0f);
auto skylightcolor = jsonFindDefault <std::string> (*general_it, "skylightcolor", "0 0 0"); 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 ( auto* scene = new CScene (
project, project, container, Scenes::CCamera::fromJSON (*camera_it), WallpaperEngine::Core::aToColorf (ambientcolor),
container, bloom, bloomstrength, bloomthreshold, camerafade, cameraparallax, cameraparallaxamount, cameraparallaxdelay,
Scenes::CCamera::fromJSON (*camera_it), cameraparallaxmouseinfluence, camerapreview, camerashake, camerashakeamplitude, camerashakeroughness,
WallpaperEngine::Core::aToColorf(ambientcolor), camerashakespeed, clearcolor, Scenes::CProjection::fromJSON (*orthogonalprojection_it),
bloom, WallpaperEngine::Core::aToColorf (skylightcolor));
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) for (const auto& cur : *objects_it)
scene->insertObject (CObject::fromJSON (cur, scene, container)); scene->insertObject (CObject::fromJSON (cur, scene, container));
@ -109,117 +78,95 @@ CScene* CScene::fromFile (const std::string& filename, CProject& project, CConta
return scene; return scene;
} }
const std::map<uint32_t, CObject*>& CScene::getObjects () const const std::map<uint32_t, CObject*>& CScene::getObjects () const {
{
return this->m_objects; return this->m_objects;
} }
const std::vector<CObject*>& CScene::getObjectsByRenderOrder () const
{ const std::vector<CObject*>& CScene::getObjectsByRenderOrder () const {
return this->m_objectsByRenderOrder; return this->m_objectsByRenderOrder;
} }
void CScene::insertObject (CObject* object) void CScene::insertObject (CObject* object) {
{
/// TODO: XXXHACK -- TO REMOVE WHEN PARTICLE SUPPORT IS PROPERLY IMPLEMENTED /// 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_objects.insert (std::make_pair (object->getId (), object));
this->m_objectsByRenderOrder.emplace_back (object); this->m_objectsByRenderOrder.emplace_back (object);
} }
} }
CContainer* CScene::getContainer () CContainer* CScene::getContainer () {
{
return this->m_container; return this->m_container;
} }
const Scenes::CCamera* CScene::getCamera () const const Scenes::CCamera* CScene::getCamera () const {
{
return this->m_camera; return this->m_camera;
} }
const glm::vec3 &CScene::getAmbientColor() const const glm::vec3& CScene::getAmbientColor () const {
{
return this->m_ambientColor; return this->m_ambientColor;
} }
const bool CScene::isBloom () const const bool CScene::isBloom () const {
{
return this->m_bloom->processValue (this->getProject ().getProperties ()); return this->m_bloom->processValue (this->getProject ().getProperties ());
} }
double CScene::getBloomStrength () const double CScene::getBloomStrength () const {
{
return this->m_bloomStrength->processValue (this->getProject ().getProperties ()); return this->m_bloomStrength->processValue (this->getProject ().getProperties ());
} }
double CScene::getBloomThreshold () const double CScene::getBloomThreshold () const {
{
return this->m_bloomThreshold->processValue (this->getProject ().getProperties ()); return this->m_bloomThreshold->processValue (this->getProject ().getProperties ());
} }
const bool CScene::isCameraFade () const const bool CScene::isCameraFade () const {
{
return this->m_cameraFade; return this->m_cameraFade;
} }
const bool CScene::isCameraParallax () const const bool CScene::isCameraParallax () const {
{
return this->m_cameraParallax; return this->m_cameraParallax;
} }
const double CScene::getCameraParallaxAmount () const const double CScene::getCameraParallaxAmount () const {
{
return this->m_cameraParallaxAmount; return this->m_cameraParallaxAmount;
} }
const double CScene::getCameraParallaxDelay () const const double CScene::getCameraParallaxDelay () const {
{
return this->m_cameraParallaxDelay; return this->m_cameraParallaxDelay;
} }
const double CScene::getCameraParallaxMouseInfluence () const const double CScene::getCameraParallaxMouseInfluence () const {
{
return this->m_cameraParallaxMouseInfluence; return this->m_cameraParallaxMouseInfluence;
} }
const bool CScene::isCameraPreview () const const bool CScene::isCameraPreview () const {
{
return this->m_cameraPreview; return this->m_cameraPreview;
} }
const bool CScene::isCameraShake () const const bool CScene::isCameraShake () const {
{
return this->m_cameraShake; return this->m_cameraShake;
} }
const double CScene::getCameraShakeAmplitude () const const double CScene::getCameraShakeAmplitude () const {
{
return this->m_cameraShakeAmplitude; return this->m_cameraShakeAmplitude;
} }
const double CScene::getCameraShakeRoughness () const const double CScene::getCameraShakeRoughness () const {
{
return this->m_cameraShakeRoughness; return this->m_cameraShakeRoughness;
} }
const double CScene::getCameraShakeSpeed () const const double CScene::getCameraShakeSpeed () const {
{
return this->m_cameraShakeSpeed; return this->m_cameraShakeSpeed;
} }
glm::vec3 CScene::getClearColor () const glm::vec3 CScene::getClearColor () const {
{
return this->m_clearColor->processValue (this->getProject ().getProperties ()); return this->m_clearColor->processValue (this->getProject ().getProperties ());
} }
Scenes::CProjection* CScene::getOrthogonalProjection () const Scenes::CProjection* CScene::getOrthogonalProjection () const {
{
return this->m_orthogonalProjection; return this->m_orthogonalProjection;
} }
const glm::vec3& CScene::getSkylightColor () const const glm::vec3& CScene::getSkylightColor () const {
{
return this->m_skylightColor; return this->m_skylightColor;
} }

View File

@ -8,14 +8,12 @@
#include "WallpaperEngine/Core/Scenes/CCamera.h" #include "WallpaperEngine/Core/Scenes/CCamera.h"
#include "WallpaperEngine/Core/Scenes/CProjection.h" #include "WallpaperEngine/Core/Scenes/CProjection.h"
namespace WallpaperEngine::Core namespace WallpaperEngine::Core {
{
using json = nlohmann::json; using json = nlohmann::json;
class CObject; class CObject;
class CScene : public CWallpaper class CScene : public CWallpaper {
{
public: public:
static CScene* fromFile (const std::string& filename, CProject& project, CContainer* container); static CScene* fromFile (const std::string& filename, CProject& project, CContainer* container);
@ -44,34 +42,19 @@ namespace WallpaperEngine::Core
protected: protected:
friend class CWallpaper; friend class CWallpaper;
CScene ( CScene (CProject& project, CContainer* container, Scenes::CCamera* camera, glm::vec3 ambientColor,
CProject& project, CUserSettingBoolean* bloom, CUserSettingFloat* bloomStrength, CUserSettingFloat* bloomThreshold,
CContainer* container, bool cameraFade, bool cameraParallax, double cameraParallaxAmount, double cameraParallaxDelay,
Scenes::CCamera* camera, double cameraParallaxMouseInfluence, bool cameraPreview, bool cameraShake, double cameraShakeAmplitude,
glm::vec3 ambientColor, double cameraShakeRoughness, double cameraShakeSpeed, CUserSettingVector3* clearColor,
CUserSettingBoolean* bloom, Scenes::CProjection* orthogonalProjection, glm::vec3 skylightColor);
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; static const std::string Type;
void insertObject (CObject* object); void insertObject (CObject* object);
CContainer* getContainer (); CContainer* getContainer ();
private: private:
CContainer* m_container; CContainer* m_container;
Scenes::CCamera* m_camera; Scenes::CCamera* m_camera;
@ -98,4 +81,4 @@ namespace WallpaperEngine::Core
std::map<uint32_t, CObject*> m_objects; std::map<uint32_t, CObject*> m_objects;
std::vector<CObject*> m_objectsByRenderOrder; std::vector<CObject*> m_objectsByRenderOrder;
}; };
} } // namespace WallpaperEngine::Core

View File

@ -6,12 +6,9 @@ using namespace WallpaperEngine::Core;
CVideo::CVideo (std::string filename, CProject& project) : CVideo::CVideo (std::string filename, CProject& project) :
CWallpaper (Type, 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; return this->m_filename;
} }

View File

@ -1,20 +1,17 @@
#pragma once #pragma once
#include "Core.h"
#include "CWallpaper.h" #include "CWallpaper.h"
#include "Core.h"
extern "C" extern "C" {
{
#include <libavcodec/avcodec.h> #include <libavcodec/avcodec.h>
#include <libavformat/avformat.h> #include <libavformat/avformat.h>
#include <libavutil/imgutils.h> #include <libavutil/imgutils.h>
#include <libswscale/swscale.h> #include <libswscale/swscale.h>
} }
namespace WallpaperEngine::Core namespace WallpaperEngine::Core {
{ class CVideo : public CWallpaper {
class CVideo : public CWallpaper
{
public: public:
explicit CVideo (std::string filename, CProject& project); explicit CVideo (std::string filename, CProject& project);
@ -26,7 +23,5 @@ namespace WallpaperEngine::Core
const std::string m_filename; const std::string m_filename;
static const std::string Type; static const std::string Type;
private:
}; };
} } // namespace WallpaperEngine::Core

View File

@ -4,13 +4,8 @@
using namespace WallpaperEngine::Core; using namespace WallpaperEngine::Core;
CWallpaper::CWallpaper (std::string type, CProject& project) : CWallpaper::CWallpaper (std::string type, CProject& project) : m_type (std::move (type)), m_project (project) {}
m_type (std::move(type)),
m_project (project)
{
}
CProject& CWallpaper::getProject () const CProject& CWallpaper::getProject () const {
{
return this->m_project; return this->m_project;
} }

View File

@ -4,17 +4,24 @@
#include "CProject.h" #include "CProject.h"
namespace WallpaperEngine::Core namespace WallpaperEngine::Core {
{
class CProject; class CProject;
class CWallpaper class CWallpaper {
{
public: public:
template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; } template <class T> const T* as () const {
template<class T> T* as () { assert (is <T> ()); return (T*) this; } 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); CWallpaper (std::string type, CProject& project);
@ -28,4 +35,4 @@ namespace WallpaperEngine::Core
std::string m_type; std::string m_type;
}; };
} } // namespace WallpaperEngine::Core

View File

@ -9,78 +9,87 @@
using namespace WallpaperEngine; using namespace WallpaperEngine;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
glm::vec4 Core::aToVector4 (const char* str) glm::vec4 Core::aToVector4 (const char* str) {
{ float x = strtof (str, const_cast<char**> (&str));
float x = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++; while (*str == ' ')
float y = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++; str++;
float z = 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)); float w = strtof (str, const_cast<char**> (&str));
return {x, y, z, w}; return {x, y, z, w};
} }
glm::vec3 Core::aToVector3 (const char* str) glm::vec3 Core::aToVector3 (const char* str) {
{ float x = strtof (str, const_cast<char**> (&str));
float x = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++; while (*str == ' ')
float y = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++; str++;
float y = strtof (str, const_cast<char**> (&str));
while (*str == ' ')
str++;
float z = strtof (str, const_cast<char**> (&str)); float z = strtof (str, const_cast<char**> (&str));
return {x, y, z}; return {x, y, z};
} }
glm::vec2 Core::aToVector2 (const char* str) glm::vec2 Core::aToVector2 (const char* str) {
{ float x = strtof (str, const_cast<char**> (&str));
float x = strtof (str, const_cast <char**> (&str)); while (*str == ' ') str ++; while (*str == ' ')
str++;
float y = strtof (str, const_cast<char**> (&str)); float y = strtof (str, const_cast<char**> (&str));
return {x, y}; 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 ()); 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 ()); 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 ()); return Core::aToVector2 (str.c_str ());
} }
glm::vec3 Core::aToColorf (const char* str) glm::vec3 Core::aToColorf (const char* str) {
{ float r = strtof (str, const_cast<char**> (&str));
float r = strtof (str, const_cast<char **>(&str)); while (*str == ' ') str ++; while (*str == ' ')
float g = strtof (str, const_cast<char **>(&str)); while (*str == ' ') str ++; str++;
float g = strtof (str, const_cast<char**> (&str));
while (*str == ' ')
str++;
float b = strtof (str, const_cast<char**> (&str)); float b = strtof (str, const_cast<char**> (&str));
return {r, g, b}; 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 ()); return aToColorf (str.c_str ());
} }
glm::ivec3 Core::aToColori (const char* str) glm::ivec3 Core::aToColori (const char* str) {
{ auto r = static_cast<uint8_t> (strtol (str, const_cast<char**> (&str), 10));
auto r = static_cast <uint8_t> (strtol (str, const_cast<char **>(&str), 10)); while (*str == ' ') str ++; while (*str == ' ')
auto g = static_cast <uint8_t> (strtol (str, const_cast<char **>(&str), 10)); while (*str == ' ') 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)); auto b = static_cast<uint8_t> (strtol (str, const_cast<char**> (&str), 10));
return {r, g, b}; 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 ()); 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); auto value = data.find (key);
if (value == data.end ()) if (value == data.end ())
@ -89,41 +98,34 @@ nlohmann::json::iterator Core::jsonFindRequired (nlohmann::json& data, const cha
return value; return value;
} }
nlohmann::json::iterator Core::jsonFindRequired (nlohmann::json::iterator& data, const char *key, const char *notFoundMsg) nlohmann::json::iterator Core::jsonFindRequired (const nlohmann::json::iterator& data, const char* key,
{ const char* notFoundMsg) {
auto value = (*data).find (key); auto value = data->find (key);
if (value == (*data).end ()) if (value == data->end ())
sLog.exception ("Cannot find required key (", key, ") in json: ", notFoundMsg); sLog.exception ("Cannot find required key (", key, ") in json: ", notFoundMsg);
return value; return value;
} }
template <typename T> T Core::jsonFindDefault (nlohmann::json& data, const char *key, T defaultValue) template <typename T> T Core::jsonFindDefault (nlohmann::json& data, const char* key, T defaultValue) {
{ const auto value = data.find (key);
auto value = data.find (key);
if (value == data.end () || value->type () == nlohmann::detail::value_t::null) if (value == data.end () || value->type () == nlohmann::detail::value_t::null)
return defaultValue; return defaultValue;
// type checks // 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 && if (value->type () != nlohmann::detail::value_t::number_float &&
value->type () != nlohmann::detail::value_t::number_integer && 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"); sLog.error (key, " is not of type double or integer, returning default value");
return defaultValue; return defaultValue;
} }
} } else if (std::is_same_v<T, std::string> && value->type () != nlohmann::detail::value_t::string) {
else if (std::is_same <T, std::string>::value && value->type () != nlohmann::detail::value_t::string)
{
sLog.error (key, " is not of type string, returning default value"); sLog.error (key, " is not of type string, returning default value");
return defaultValue; return defaultValue;
} } else if (std::is_same_v<T, bool> && value->type () != nlohmann::detail::value_t::boolean) {
else if (std::is_same <T, bool>::value && value->type () != nlohmann::detail::value_t::boolean)
{
sLog.error (key, " is not of type boolean, returning default value"); sLog.error (key, " is not of type boolean, returning default value");
return defaultValue; return defaultValue;
} }
@ -144,9 +146,9 @@ template uint64_t Core::jsonFindDefault (nlohmann::json& data, const char *key,
template float Core::jsonFindDefault (nlohmann::json& data, const char* key, float 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 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) template <typename T>
{ T* Core::jsonFindUserConfig (nlohmann::json& data, const char* key, typename T::data_type defaultValue) {
auto it = data.find (key); const auto it = data.find (key);
if (it == data.end () || it->type () == nlohmann::detail::value_t::null) if (it == data.end () || it->type () == nlohmann::detail::value_t::null)
return T::fromScalar (defaultValue); return T::fromScalar (defaultValue);
@ -154,6 +156,9 @@ template <typename T> T* Core::jsonFindUserConfig (nlohmann::json& data, const c
return T::fromJSON (*it); return T::fromJSON (*it);
} }
template CUserSettingBoolean* Core::jsonFindUserConfig (nlohmann::json& data, const char *key, CUserSettingBoolean::data_type defaultValue); template CUserSettingBoolean* Core::jsonFindUserConfig (nlohmann::json& data, const char* key,
template CUserSettingVector3* Core::jsonFindUserConfig (nlohmann::json& data, const char *key, CUserSettingVector3::data_type defaultValue); CUserSettingBoolean::data_type defaultValue);
template CUserSettingFloat* Core::jsonFindUserConfig (nlohmann::json& data, const char *key, CUserSettingFloat::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);

View File

@ -1,13 +1,12 @@
#pragma once #pragma once
#include <string>
#include <nlohmann/json.hpp>
#include <glm/vec3.hpp>
#include <glm/vec2.hpp>
#include <glm/mat4x4.hpp> #include <glm/mat4x4.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <nlohmann/json.hpp>
#include <string>
namespace WallpaperEngine::Core namespace WallpaperEngine::Core {
{
glm::vec4 aToVector4 (const char* str); glm::vec4 aToVector4 (const char* str);
glm::vec3 aToVector3 (const char* str); glm::vec3 aToVector3 (const char* str);
glm::vec2 aToVector2 (const char* str); glm::vec2 aToVector2 (const char* str);
@ -23,7 +22,8 @@ namespace WallpaperEngine::Core
glm::ivec3 aToColori (const std::string& 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& data, const char* key, const char* notFoundMsg);
nlohmann::json::iterator jsonFindRequired (nlohmann::json::iterator& 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 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); template <typename T> T* jsonFindUserConfig (nlohmann::json& data, const char* key, typename T::data_type defaultValue);
} } // namespace WallpaperEngine::Core

View File

@ -1,16 +1,16 @@
#include "common.h"
#include "CEffect.h" #include "CEffect.h"
#include "common.h"
#include <utility>
#include <iostream> #include <iostream>
#include <utility>
#include "WallpaperEngine/Core/CScene.h"
#include "WallpaperEngine/Core/CProject.h" #include "WallpaperEngine/Core/CProject.h"
#include "WallpaperEngine/Core/CScene.h"
#include "WallpaperEngine/Core/Objects/CImage.h" #include "WallpaperEngine/Core/Objects/CImage.h"
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.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/CShaderConstantInteger.h"
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h"
#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h" #include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
@ -20,28 +20,20 @@ using namespace WallpaperEngine;
using namespace WallpaperEngine::Core::Objects; using namespace WallpaperEngine::Core::Objects;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
CEffect::CEffect ( CEffect::CEffect (std::string name, std::string description, std::string group, std::string preview, CObject* object,
std::string name,
std::string description,
std::string group,
std::string preview,
CObject* object,
CUserSettingBoolean* visible) : CUserSettingBoolean* visible) :
m_name (std::move (name)), m_name (std::move (name)),
m_description (std::move (description)), m_description (std::move (description)),
m_group (std::move (group)), m_group (std::move (group)),
m_preview (std::move (preview)), m_preview (std::move (preview)),
m_object (object), 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 file_it = jsonFindRequired (data, "file", "Object effect must have a file");
auto effectpasses_it = data.find ("passes"); 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 name_it = jsonFindRequired (content, "name", "Effect must have a name");
auto description = jsonFindDefault<std::string> (content, "description", ""); auto description = jsonFindDefault<std::string> (content, "description", "");
@ -51,14 +43,7 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, CObject* ob
auto dependencies_it = jsonFindRequired (content, "dependencies", ""); auto dependencies_it = jsonFindRequired (content, "dependencies", "");
auto fbos_it = content.find ("fbos"); auto fbos_it = content.find ("fbos");
auto* effect = new CEffect ( auto* effect = new CEffect (*name_it, description, *group_it, preview, object, visible);
*name_it,
description,
*group_it,
preview,
object,
visible
);
CEffect::materialsFromJSON (passes_it, effect, container); CEffect::materialsFromJSON (passes_it, effect, container);
CEffect::dependencyFromJSON (dependencies_it, effect); CEffect::dependencyFromJSON (dependencies_it, effect);
@ -66,47 +51,36 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, CObject* ob
if (fbos_it != content.end ()) if (fbos_it != content.end ())
CEffect::fbosFromJSON (fbos_it, effect); CEffect::fbosFromJSON (fbos_it, effect);
if (effectpasses_it != data.end ()) if (effectpasses_it != data.end ()) {
{ auto cur = effectpasses_it->begin ();
auto cur = (*effectpasses_it).begin (); auto end = effectpasses_it->end ();
auto end = (*effectpasses_it).end ();
for (int passNumber = 0; cur != end; cur ++, passNumber ++) for (int passNumber = 0; cur != end; ++cur, passNumber++) {
{ auto constants_it = cur->find ("constantshadervalues");
auto constants_it = (*cur).find ("constantshadervalues"); auto combos_it = cur->find ("combos");
auto combos_it = (*cur).find ("combos"); auto textures_it = cur->find ("textures");
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; continue;
Images::CMaterial* material = effect->getMaterials ().at (passNumber); Images::CMaterial* material = effect->getMaterials ().at (passNumber);
for (const auto& passCur : material->getPasses ()) for (const auto& passCur : material->getPasses ()) {
{ if (textures_it != cur->end ()) {
if (textures_it != (*cur).end ())
{
int textureNumber = 0; int textureNumber = 0;
for (const auto& texturesCur : (*textures_it)) for (const auto& texturesCur : (*textures_it)) {
{
std::string texture; std::string texture;
if (texturesCur.is_null ()) if (texturesCur.is_null ()) {
{ if (textureNumber == 0) {
if (textureNumber == 0)
{
auto* image = object->as<CImage> (); auto* image = object->as<CImage> ();
texture = (*(*image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ()); texture = (*(*image->getMaterial ()->getPasses ().begin ())->getTextures ().begin ());
} } else {
else
{
texture = ""; texture = "";
} }
} } else {
else
{
texture = texturesCur; texture = texturesCur;
} }
@ -121,13 +95,11 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, CObject* ob
} }
} }
if (combos_it != (*cur).end ()) if (combos_it != cur->end ()) {
{
CEffect::combosFromJSON (combos_it, passCur); CEffect::combosFromJSON (combos_it, passCur);
} }
if (constants_it != (*cur).end ()) if (constants_it != cur->end ()) {
{
CEffect::constantsFromJSON (constants_it, passCur); CEffect::constantsFromJSON (constants_it, passCur);
} }
} }
@ -137,16 +109,14 @@ CEffect* CEffect::fromJSON (json data, CUserSettingBoolean* visible, CObject* ob
return effect; return effect;
} }
void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass) void CEffect::combosFromJSON (const json::const_iterator& combos_it, Core::Objects::Images::Materials::CPass* pass) {
{ for (const auto& cur : combos_it->items ())
for (const auto& cur : (*combos_it).items ())
pass->insertCombo (cur.key (), cur.value ()); pass->insertCombo (cur.key (), cur.value ());
} }
void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass) void CEffect::constantsFromJSON (const json::const_iterator& constants_it,
{ Core::Objects::Images::Materials::CPass* pass) {
for (auto& cur : (*constants_it).items ()) for (auto& cur : constants_it->items ()) {
{
auto val = cur.value (); auto val = cur.value ();
Effects::Constants::CShaderConstant* constant; 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 // for the UI, take the value, which is what we need
// TODO: SUPPORT USER SETTINGS HERE // TODO: SUPPORT USER SETTINGS HERE
if (cur.value ().is_object ()) if (cur.value ().is_object ()) {
{
auto it = cur.value ().find ("value"); 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"); sLog.error ("Found object for shader constant without \"value\" member");
continue; continue;
} }
@ -168,21 +136,14 @@ void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Object
val = it.value (); val = it.value ();
} }
if (val.is_number_float ()) if (val.is_number_float ()) {
{
constant = new Effects::Constants::CShaderConstantFloat (val.get<float> ()); constant = new Effects::Constants::CShaderConstantFloat (val.get<float> ());
} } else if (val.is_number_integer ()) {
else if (val.is_number_integer ())
{
constant = new Effects::Constants::CShaderConstantInteger (val.get<int> ()); constant = new Effects::Constants::CShaderConstantInteger (val.get<int> ());
} } else if (val.is_string ()) {
else if (val.is_string ())
{
// try a vector 4 first, then a vector3 and then a vector 2 // try a vector 4 first, then a vector3 and then a vector 2
constant = new Effects::Constants::CShaderConstantVector4 (WallpaperEngine::Core::aToVector4 (val)); constant = new Effects::Constants::CShaderConstantVector4 (WallpaperEngine::Core::aToVector4 (val));
} } else {
else
{
sLog.exception ("unknown shader constant type ", val); 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)) for (const auto& cur : (*fbos_it))
effect->insertFBO (Effects::CFBO::fromJSON (cur)); 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)) for (const auto& cur : (*dependencies_it))
effect->insertDependency (cur); effect->insertDependency (cur);
} }
void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect, CContainer* container) void CEffect::materialsFromJSON (const json::const_iterator& passes_it, CEffect* effect, CContainer* container) {
{ for (const auto& cur : (*passes_it)) {
for (const auto& cur : (*passes_it))
{
auto materialfile = cur.find ("material"); auto materialfile = cur.find ("material");
auto target = cur.find ("target"); auto target = cur.find ("target");
auto bind = cur.find ("bind"); auto bind = cur.find ("bind");
@ -216,12 +173,11 @@ void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect
Images::CMaterial* material; Images::CMaterial* material;
if (target == cur.end ()) if (target == cur.end ())
material = Images::CMaterial::fromFile ((*materialfile).get <std::string> (), container); material = Images::CMaterial::fromFile (materialfile->get<std::string> (), container);
else 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)) for (const auto& bindCur : (*bind))
material->insertTextureBind (Effects::CBind::fromJSON (bindCur)); 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; return this->m_dependencies;
} }
const std::vector<Images::CMaterial*>& CEffect::getMaterials () const const std::vector<Images::CMaterial*>& CEffect::getMaterials () const {
{
return this->m_materials; return this->m_materials;
} }
const std::vector<Effects::CFBO*>& CEffect::getFbos () const const std::vector<Effects::CFBO*>& CEffect::getFbos () const {
{
return this->m_fbos; return this->m_fbos;
} }
bool CEffect::isVisible () const bool CEffect::isVisible () const {
{
return this->m_visible->processValue (this->m_object->getScene ()->getProject ().getProperties ()); 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) for (const auto& cur : this->m_fbos)
if (cur->getName () == name) if (cur->getName () == name)
return cur; return cur;
@ -259,17 +210,14 @@ Effects::CFBO* CEffect::findFBO (const std::string& name)
sLog.exception ("cannot find fbo ", 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); this->m_dependencies.push_back (dep);
} }
void CEffect::insertMaterial (Images::CMaterial* material) void CEffect::insertMaterial (Images::CMaterial* material) {
{
this->m_materials.push_back (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); this->m_fbos.push_back (fbo);
} }

View File

@ -1,24 +1,21 @@
#pragma once #pragma once
#include "WallpaperEngine/Assets/CContainer.h"
#include "WallpaperEngine/Core/CObject.h"
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/Objects/Effects/CFBO.h" #include "WallpaperEngine/Core/Objects/Effects/CFBO.h"
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
#include "WallpaperEngine/Core/CObject.h"
#include "WallpaperEngine/Core/Objects/Images/CMaterial.h" #include "WallpaperEngine/Core/Objects/Images/CMaterial.h"
#include "WallpaperEngine/Assets/CContainer.h"
namespace WallpaperEngine::Core namespace WallpaperEngine::Core {
{
class CObject; class CObject;
} }
namespace WallpaperEngine::Core::UserSettings namespace WallpaperEngine::Core::UserSettings {
{
class CUserSettingBoolean; class CUserSettingBoolean;
} }
namespace WallpaperEngine::Core::Objects namespace WallpaperEngine::Core::Objects {
{
using json = nlohmann::json; using json = nlohmann::json;
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
@ -26,19 +23,13 @@ namespace WallpaperEngine::Core::Objects
/** /**
* Represents an effect applied to background objects * Represents an effect applied to background objects
*/ */
class CEffect class CEffect {
{
public: public:
CEffect ( CEffect (std::string name, std::string description, std::string group, std::string preview, CObject* object,
std::string name, CUserSettingBoolean* visible);
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 * @return List of dependencies for the effect to work
@ -64,12 +55,14 @@ namespace WallpaperEngine::Core::Objects
* @return * @return
*/ */
Effects::CFBO* findFBO (const std::string& name); Effects::CFBO* findFBO (const std::string& name);
protected: protected:
static void constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass); static void constantsFromJSON (const json::const_iterator& constants_it,
static void combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass); Core::Objects::Images::Materials::CPass* pass);
static void fbosFromJSON (json::const_iterator fbos_it, CEffect* effect); static void combosFromJSON (const json::const_iterator& combos_it, Core::Objects::Images::Materials::CPass* pass);
static void dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect); static void fbosFromJSON (const json::const_iterator& fbos_it, CEffect* effect);
static void materialsFromJSON (json::const_iterator passes_it, CEffect* effect, CContainer* container); 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 insertDependency (const std::string& dep);
void insertMaterial (Images::CMaterial* material); void insertMaterial (Images::CMaterial* material);
@ -96,4 +89,4 @@ namespace WallpaperEngine::Core::Objects
/** List of FBOs required for this effect */ /** List of FBOs required for this effect */
std::vector<Effects::CFBO*> m_fbos; std::vector<Effects::CFBO*> m_fbos;
}; };
} } // namespace WallpaperEngine::Core::Objects

View File

@ -12,26 +12,11 @@
using namespace WallpaperEngine::Core::Objects; using namespace WallpaperEngine::Core::Objects;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
CImage::CImage ( CImage::CImage (CScene* scene, Images::CMaterial* material, CUserSettingBoolean* visible, uint32_t id, std::string name,
CScene* scene, CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles, const glm::vec2& size,
Images::CMaterial* material, std::string alignment, CUserSettingVector3* color, CUserSettingFloat* alpha, float brightness,
CUserSettingBoolean* visible, uint32_t colorBlendMode, const glm::vec2& parallaxDepth, bool fullscreen, bool passthrough,
uint32_t id, bool autosize) :
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), CObject (scene, visible, id, std::move (name), Type, origin, scale, angles),
m_size (size), m_size (size),
m_material (material), m_material (material),
@ -43,112 +28,75 @@ CImage::CImage (
m_parallaxDepth (parallaxDepth), m_parallaxDepth (parallaxDepth),
m_fullscreen (fullscreen), m_fullscreen (fullscreen),
m_passthrough (passthrough), 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 ( const Images::CMaterial* CImage::getMaterial () const {
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
{
return this->m_material; return this->m_material;
} }
const glm::vec2& CImage::getSize () const const glm::vec2& CImage::getSize () const {
{
return this->m_size; return this->m_size;
} }
const std::string& CImage::getAlignment () const const std::string& CImage::getAlignment () const {
{
return this->m_alignment; return this->m_alignment;
} }
float CImage::getAlpha () const float CImage::getAlpha () const {
{
return this->m_alpha->processValue (this->getScene ()->getProject ().getProperties ()); 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 ()); return this->m_color->processValue (this->getScene ()->getProject ().getProperties ());
} }
float CImage::getBrightness () const float CImage::getBrightness () const {
{
return this->m_brightness; return this->m_brightness;
} }
uint32_t CImage::getColorBlendMode () const uint32_t CImage::getColorBlendMode () const {
{
return this->m_colorBlendMode; return this->m_colorBlendMode;
} }
const glm::vec2& CImage::getParallaxDepth () const {
const glm::vec2& CImage::getParallaxDepth () const
{
return this->m_parallaxDepth; return this->m_parallaxDepth;
} }
bool CImage::isFullscreen () const bool CImage::isFullscreen () const {
{
return this->m_fullscreen; return this->m_fullscreen;
} }
bool CImage::isPassthrough () const bool CImage::isPassthrough () const {
{
return this->m_passthrough; return this->m_passthrough;
} }
bool CImage::isAutosize () const bool CImage::isAutosize () const {
{
return this->m_autosize; return this->m_autosize;
} }

View File

@ -2,8 +2,8 @@
#include "WallpaperEngine/Core/Objects/Images/CMaterial.h" #include "WallpaperEngine/Core/Objects/Images/CMaterial.h"
#include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/CObject.h" #include "WallpaperEngine/Core/CObject.h"
#include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Assets/CContainer.h" #include "WallpaperEngine/Assets/CContainer.h"
@ -11,13 +11,11 @@
#include "WallpaperEngine/Core/UserSettings/CUserSettingFloat.h" #include "WallpaperEngine/Core/UserSettings/CUserSettingFloat.h"
#include "WallpaperEngine/Core/UserSettings/CUserSettingVector3.h" #include "WallpaperEngine/Core/UserSettings/CUserSettingVector3.h"
namespace WallpaperEngine::Core namespace WallpaperEngine::Core {
{
class CScene; class CScene;
} }
namespace WallpaperEngine::Core::Objects namespace WallpaperEngine::Core::Objects {
{
using json = nlohmann::json; using json = nlohmann::json;
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
@ -25,14 +23,13 @@ namespace WallpaperEngine::Core::Objects
/** /**
* Represents an image in a background * Represents an image in a background
*/ */
class CImage : public CObject class CImage : public CObject {
{
friend class CObject; friend class CObject;
public: public:
static CObject* fromJSON ( static CObject* fromJSON (CScene* scene, json data, CContainer* container, CUserSettingBoolean* visible,
CScene* scene, json data, CContainer* container, CUserSettingBoolean* visible, uint32_t id, uint32_t id, std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale,
std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles const glm::vec3& angles);
);
/** /**
* @return The base material to use for the image * @return The base material to use for the image
@ -80,12 +77,10 @@ namespace WallpaperEngine::Core::Objects
[[nodiscard]] bool isAutosize () const; [[nodiscard]] bool isAutosize () const;
protected: protected:
CImage ( CImage (CScene* scene, Images::CMaterial* material, CUserSettingBoolean* visible, uint32_t id, std::string name,
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, CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles, const glm::vec2& size,
std::string alignment, CUserSettingVector3* color, CUserSettingFloat* alpha, float brightness, 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 * Type value used to differentiate the different types of objects in a background
@ -116,4 +111,4 @@ namespace WallpaperEngine::Core::Objects
/** If the image's size should be automatically determined */ /** If the image's size should be automatically determined */
bool m_autosize; bool m_autosize;
}; };
} } // namespace WallpaperEngine::Core::Objects

View File

@ -1,37 +1,21 @@
#include "CParticle.h" #include "CParticle.h"
#include <utility>
#include "WallpaperEngine/FileSystem/FileSystem.h" #include "WallpaperEngine/FileSystem/FileSystem.h"
#include <utility>
using namespace WallpaperEngine::Core::Objects; using namespace WallpaperEngine::Core::Objects;
CParticle* CParticle::fromFile ( CParticle* CParticle::fromFile (CScene* scene, const std::string& filename, CContainer* container,
CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name,
const std::string& filename, CUserSettingVector3* origin, CUserSettingVector3* scale) {
CContainer* container,
CUserSettingBoolean* visible,
uint32_t id,
std::string name,
CUserSettingVector3* origin,
CUserSettingVector3* scale)
{
json data = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)); json data = json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container));
auto controlpoint_it = data.find ("controlpoint"); const auto controlpoint_it = data.find ("controlpoint");
auto starttime_it = jsonFindRequired (data, "starttime", "Particles must have start time"); const auto starttime_it = jsonFindRequired (data, "starttime", "Particles must have start time");
auto maxcount_it = jsonFindRequired (data, "maxcount", "Particles must have maximum count"); const auto maxcount_it = jsonFindRequired (data, "maxcount", "Particles must have maximum count");
auto emitter_it = jsonFindRequired (data, "emitter", "Particles must have emitters"); const auto emitter_it = jsonFindRequired (data, "emitter", "Particles must have emitters");
auto initializer_it = jsonFindRequired (data, "initializer", "Particles must have initializers"); const auto initializer_it = jsonFindRequired (data, "initializer", "Particles must have initializers");
auto* particle = new CParticle ( auto* particle = new CParticle (scene, *starttime_it, *maxcount_it, visible, id, std::move (name), origin, scale);
scene,
*starttime_it,
*maxcount_it,
visible,
id,
std::move(name),
origin,
scale
);
if (controlpoint_it != data.end ()) if (controlpoint_it != data.end ())
for (const auto& cur : (*controlpoint_it)) for (const auto& cur : (*controlpoint_it))
@ -45,48 +29,33 @@ CParticle* CParticle::fromFile (
return particle; return particle;
} }
CParticle::CParticle ( CParticle::CParticle (CScene* scene, uint32_t starttime, uint32_t maxcount, CUserSettingBoolean* visible, uint32_t id,
CScene* scene, std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale) :
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 ()), CObject (scene, visible, id, std::move (name), Type, origin, scale, glm::vec3 ()),
m_starttime (starttime), 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; return this->m_emitters;
} }
const std::vector<Particles::CControlPoint*>& CParticle::getControlPoints () const const std::vector<Particles::CControlPoint*>& CParticle::getControlPoints () const {
{
return this->m_controlpoints; return this->m_controlpoints;
} }
const std::vector<Particles::CInitializer*>& CParticle::getInitializers () const const std::vector<Particles::CInitializer*>& CParticle::getInitializers () const {
{
return this->m_initializers; return this->m_initializers;
} }
void CParticle::insertControlPoint (Particles::CControlPoint* controlpoint) void CParticle::insertControlPoint (Particles::CControlPoint* controlpoint) {
{
this->m_controlpoints.push_back (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); this->m_emitters.push_back (emitter);
} }
void CParticle::insertInitializer (Particles::CInitializer* initializer) void CParticle::insertInitializer (Particles::CInitializer* initializer) {
{
this->m_initializers.push_back (initializer); this->m_initializers.push_back (initializer);
} }

View File

@ -4,31 +4,22 @@
#include "WallpaperEngine/Core/Objects/Particles/CEmitter.h" #include "WallpaperEngine/Core/Objects/Particles/CEmitter.h"
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.h" #include "WallpaperEngine/Core/Objects/Particles/CInitializer.h"
#include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/CObject.h" #include "WallpaperEngine/Core/CObject.h"
#include "WallpaperEngine/Core/Core.h"
namespace WallpaperEngine::Core::Objects namespace WallpaperEngine::Core::Objects {
{
using json = nlohmann::json; using json = nlohmann::json;
/** /**
* Represents a particle system in the background * Represents a particle system in the background
*/ */
class CParticle : public CObject class CParticle : public CObject {
{
friend class CObject; friend class CObject;
public: public:
static CParticle* fromFile ( static CParticle* fromFile (CScene* scene, const std::string& filename, CContainer* container,
CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name,
const std::string& filename, CUserSettingVector3* origin, CUserSettingVector3* scale);
CContainer* container,
CUserSettingBoolean* visible,
uint32_t id,
std::string name,
CUserSettingVector3* origin,
CUserSettingVector3* scale
);
/** /**
* @return The list of emitters for the particle system * @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; [[nodiscard]] const std::vector<Particles::CInitializer*>& getInitializers () const;
protected: protected:
CParticle ( CParticle (CScene* scene, uint32_t starttime, uint32_t maxcount, CUserSettingBoolean* visible, uint32_t id,
CScene* scene, std::string name, CUserSettingVector3* origin, CUserSettingVector3* scale);
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 * @param controlpoint The control point to add to the particle system
@ -85,4 +68,4 @@ namespace WallpaperEngine::Core::Objects
/** List of initializers */ /** List of initializers */
std::vector<Particles::CInitializer*> m_initializers; std::vector<Particles::CInitializer*> m_initializers;
}; };
} } // namespace WallpaperEngine::Core::Objects

View File

@ -1,55 +1,29 @@
#include "common.h"
#include "WallpaperEngine/Core/CObject.h"
#include "CSound.h" #include "CSound.h"
#include "WallpaperEngine/Core/CObject.h"
#include "common.h"
using namespace WallpaperEngine::Core::Objects; using namespace WallpaperEngine::Core::Objects;
CSound::CSound ( CSound::CSound (CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name, CUserSettingVector3* origin,
CScene* scene, CUserSettingVector3* scale, const glm::vec3& angles, bool repeat) :
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), CObject (scene, visible, id, std::move (name), Type, origin, scale, angles),
m_repeat (repeat) m_repeat (repeat) {}
{
}
WallpaperEngine::Core::CObject* CSound::fromJSON ( WallpaperEngine::Core::CObject* CSound::fromJSON (CScene* scene, json data, CUserSettingBoolean* visible, uint32_t id,
CScene* scene, const std::string& name, CUserSettingVector3* origin,
json data, CUserSettingVector3* scale, const glm::vec3& angles) {
CUserSettingBoolean* visible,
uint32_t id,
const std::string& name,
CUserSettingVector3* origin,
CUserSettingVector3* scale,
const glm::vec3& angles)
{
bool repeat = false; bool repeat = false;
// TODO: PARSE AUDIO VOLUME // TODO: PARSE AUDIO VOLUME
auto sound_it = jsonFindRequired (data, "sound", "Sound information not present"); const auto sound_it = jsonFindRequired (data, "sound", "Sound information not present");
auto playbackmode = jsonFindDefault <std::string> (data, "playbackmode", ""); const auto playbackmode = jsonFindDefault<std::string> (data, "playbackmode", "");
if (playbackmode == "loop") if (playbackmode == "loop")
repeat = true; repeat = true;
if (!(*sound_it).is_array ()) if (!sound_it->is_array ())
sLog.exception ("Expected sound list on element ", name); sLog.exception ("Expected sound list on element ", name);
auto* sound = new CSound ( auto* sound = new CSound (scene, visible, id, name, origin, scale, angles, repeat);
scene,
visible,
id,
name,
origin,
scale,
angles,
repeat
);
for (const auto& cur : (*sound_it)) for (const auto& cur : (*sound_it))
sound->insertSound (cur); sound->insertSound (cur);
@ -57,17 +31,15 @@ WallpaperEngine::Core::CObject* CSound::fromJSON (
return sound; return sound;
} }
void CSound::insertSound (const std::string& filename) void CSound::insertSound (const std::string& filename) {
{
this->m_sounds.push_back (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; return this->m_sounds;
} }
bool CSound::isRepeat () const
{ bool CSound::isRepeat () const {
return this->m_repeat; return this->m_repeat;
} }

View File

@ -1,32 +1,23 @@
#pragma once #pragma once
#include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/CObject.h" #include "WallpaperEngine/Core/CObject.h"
#include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h" #include "WallpaperEngine/Core/UserSettings/CUserSettingBoolean.h"
namespace WallpaperEngine::Core::Objects namespace WallpaperEngine::Core::Objects {
{
using json = nlohmann::json; using json = nlohmann::json;
using namespace WallpaperEngine::Core::UserSettings; using namespace WallpaperEngine::Core::UserSettings;
/** /**
* Represents a sound played while the background is working * Represents a sound played while the background is working
*/ */
class CSound : public CObject class CSound : public CObject {
{
friend class CObject; friend class CObject;
public: public:
static CObject* fromJSON ( static CObject* fromJSON (CScene* scene, json data, CUserSettingBoolean* visible, uint32_t id,
CScene* scene, const std::string& name, CUserSettingVector3* origin, CUserSettingVector3* scale,
json data, const glm::vec3& angles);
CUserSettingBoolean* visible,
uint32_t id,
const std::string& name,
CUserSettingVector3* origin,
CUserSettingVector3* scale,
const glm::vec3& angles
);
/** /**
* @return The list of sounds to play * @return The list of sounds to play
@ -38,16 +29,8 @@ namespace WallpaperEngine::Core::Objects
[[nodiscard]] bool isRepeat () const; [[nodiscard]] bool isRepeat () const;
protected: protected:
CSound ( CSound (CScene* scene, CUserSettingBoolean* visible, uint32_t id, std::string name, CUserSettingVector3* origin,
CScene* scene, CUserSettingVector3* scale, const glm::vec3& angles, bool repeat);
CUserSettingBoolean* visible,
uint32_t id,
std::string name,
CUserSettingVector3* origin,
CUserSettingVector3* scale,
const glm::vec3& angles,
bool repeat
);
/** /**
* @param filename The sound to add * @param filename The sound to add
@ -65,4 +48,4 @@ namespace WallpaperEngine::Core::Objects
/** The list of sounds to play */ /** The list of sounds to play */
std::vector<std::string> m_sounds; std::vector<std::string> m_sounds;
}; };
} } // namespace WallpaperEngine::Core::Objects

View File

@ -4,26 +4,19 @@
using namespace WallpaperEngine::Core::Objects::Effects; using namespace WallpaperEngine::Core::Objects::Effects;
CBind::CBind (std::string name, uint32_t index) : CBind::CBind (std::string name, uint32_t index) : m_name (std::move (name)), m_index (index) {}
m_name (std::move(name)),
m_index (index)
{
}
CBind* CBind::fromJSON (json data) CBind* CBind::fromJSON (json data) {
{ const auto name_it = jsonFindRequired (data, "name", "bind must have texture name");
auto name_it = jsonFindRequired (data, "name", "bind must have texture name"); const auto index_it = jsonFindRequired (data, "index", "bind must have index");
auto index_it = jsonFindRequired (data, "index", "bind must have index");
return new CBind (*name_it, *index_it); return new CBind (*name_it, *index_it);
} }
const std::string& CBind::getName () const const std::string& CBind::getName () const {
{
return this->m_name; return this->m_name;
} }
const uint32_t& CBind::getIndex () const const uint32_t& CBind::getIndex () const {
{
return this->m_index; return this->m_index;
} }

View File

@ -4,8 +4,7 @@
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
namespace WallpaperEngine::Core::Objects::Effects namespace WallpaperEngine::Core::Objects::Effects {
{
using json = nlohmann::json; using json = nlohmann::json;
/** /**
@ -13,8 +12,7 @@ namespace WallpaperEngine::Core::Objects::Effects
* in what positions for shaders. Used to override the textures specified inside * in what positions for shaders. Used to override the textures specified inside
* the object's passes * the object's passes
*/ */
class CBind class CBind {
{
public: public:
/** /**
* Parses bind information off the given json data * Parses bind information off the given json data
@ -41,4 +39,4 @@ namespace WallpaperEngine::Core::Objects::Effects
/** The texture index to replace */ /** The texture index to replace */
uint32_t m_index; uint32_t m_index;
}; };
} } // namespace WallpaperEngine::Core::Objects::Effects

View File

@ -8,34 +8,24 @@ using namespace WallpaperEngine::Core::Objects::Effects;
CFBO::CFBO (std::string name, float scale, std::string format) : CFBO::CFBO (std::string name, float scale, std::string format) :
m_name (std::move (name)), m_name (std::move (name)),
m_scale (scale), 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) const std::string& CFBO::getName () const {
{
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
{
return this->m_name; return this->m_name;
} }
const float& CFBO::getScale () const const float& CFBO::getScale () const {
{
return this->m_scale; return this->m_scale;
} }
const std::string& CFBO::getFormat () const const std::string& CFBO::getFormat () const {
{
return this->m_format; return this->m_format;
} }

View File

@ -5,8 +5,7 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <string> #include <string>
namespace WallpaperEngine::Core::Objects::Effects namespace WallpaperEngine::Core::Objects::Effects {
{
using json = nlohmann::json; using json = nlohmann::json;
/** /**
@ -14,8 +13,7 @@ namespace WallpaperEngine::Core::Objects::Effects
* *
* Represents a framebuffer object used in objects with multiple effects or render passes * Represents a framebuffer object used in objects with multiple effects or render passes
*/ */
class CFBO class CFBO {
{
public: public:
CFBO (std::string name, float scale, std::string format); CFBO (std::string name, float scale, std::string format);
@ -42,4 +40,4 @@ namespace WallpaperEngine::Core::Objects::Effects
/** The FBO's format for the render */ /** The FBO's format for the render */
std::string m_format; std::string m_format;
}; };
} } // namespace WallpaperEngine::Core::Objects::Effects

View File

@ -2,12 +2,8 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstant::CShaderConstant (std::string type) : CShaderConstant::CShaderConstant (std::string type) : m_type (std::move (type)) {}
m_type (std::move(type))
{
}
const std::string& CShaderConstant::getType () const const std::string& CShaderConstant::getType () const {
{
return this->m_type; return this->m_type;
} }

View File

@ -2,20 +2,27 @@
#include <string> #include <string>
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants {
{
/** /**
* Shader constants base class * Shader constants base class
*/ */
class CShaderConstant class CShaderConstant {
{
public: public:
explicit CShaderConstant (std::string type); explicit CShaderConstant (std::string type);
template<class T> const T* as () const { assert (is <T> ()); return (const T*) this; } template <class T> const T* as () const {
template<class T> T* as () { assert (is <T> ()); return (T*) this; } 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 * @return The type name of this constant
@ -25,4 +32,4 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
private: private:
std::string m_type; std::string m_type;
}; };
} } // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -2,14 +2,9 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantFloat::CShaderConstantFloat (float value) : CShaderConstantFloat::CShaderConstantFloat (float value) : CShaderConstant (Type), m_value (value) {}
CShaderConstant (Type),
m_value (value)
{
}
float* CShaderConstantFloat::getValue () float* CShaderConstantFloat::getValue () {
{
return &this->m_value; return &this->m_value;
} }

View File

@ -4,13 +4,11 @@
#include <string> #include <string>
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants {
{
/** /**
* Shader constant of type float * Shader constant of type float
*/ */
class CShaderConstantFloat : public CShaderConstant class CShaderConstantFloat : public CShaderConstant {
{
public: public:
explicit CShaderConstantFloat (float value); explicit CShaderConstantFloat (float value);
@ -23,8 +21,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
* Type string indicator * Type string indicator
*/ */
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */ /** The constant's value */
float m_value; float m_value;
}; };
} } // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -2,14 +2,9 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantInteger::CShaderConstantInteger (int32_t value) : CShaderConstantInteger::CShaderConstantInteger (int32_t value) : CShaderConstant (Type), m_value (value) {}
CShaderConstant (Type),
m_value (value)
{
}
int32_t* CShaderConstantInteger::getValue () int32_t* CShaderConstantInteger::getValue () {
{
return &this->m_value; return &this->m_value;
} }

View File

@ -4,13 +4,11 @@
#include <string> #include <string>
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants {
{
/** /**
* Shader constant of type integer * Shader constant of type integer
*/ */
class CShaderConstantInteger : public CShaderConstant class CShaderConstantInteger : public CShaderConstant {
{
public: public:
explicit CShaderConstantInteger (int32_t value); explicit CShaderConstantInteger (int32_t value);
@ -23,8 +21,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
* Type string indicator * Type string indicator
*/ */
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */ /** The constant's value */
int32_t m_value; int32_t m_value;
}; };
} } // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -2,15 +2,9 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantVector2::CShaderConstantVector2 (glm::vec2 value) : CShaderConstant (Type), m_value (value) {}
CShaderConstantVector2::CShaderConstantVector2 (glm::vec2 value) : glm::vec2* CShaderConstantVector2::getValue () {
CShaderConstant (Type),
m_value (value)
{
}
glm::vec2* CShaderConstantVector2::getValue ()
{
return &this->m_value; return &this->m_value;
} }

View File

@ -2,17 +2,15 @@
#include "CShaderConstant.h" #include "CShaderConstant.h"
#include <string>
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
#include <string>
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants {
{
/** /**
* Shader constant of vector2 type * Shader constant of vector2 type
*/ */
class CShaderConstantVector2 : public CShaderConstant class CShaderConstantVector2 : public CShaderConstant {
{
public: public:
explicit CShaderConstantVector2 (glm::vec2 value); explicit CShaderConstantVector2 (glm::vec2 value);
@ -25,8 +23,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
* Type string indicator * Type string indicator
*/ */
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */ /** The constant's value */
glm::vec2 m_value; glm::vec2 m_value;
}; };
} } // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -2,14 +2,9 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantVector3::CShaderConstantVector3 (glm::vec3 value) : CShaderConstantVector3::CShaderConstantVector3 (glm::vec3 value) : CShaderConstant (Type), m_value (value) {}
CShaderConstant (Type),
m_value (value)
{
}
glm::vec3* CShaderConstantVector3::getValue () glm::vec3* CShaderConstantVector3::getValue () {
{
return &this->m_value; return &this->m_value;
} }

View File

@ -2,16 +2,14 @@
#include "CShaderConstant.h" #include "CShaderConstant.h"
#include <string>
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
#include <string>
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants {
{
/** /**
* Shader constant of vector3 type * Shader constant of vector3 type
*/ */
class CShaderConstantVector3 : public CShaderConstant class CShaderConstantVector3 : public CShaderConstant {
{
public: public:
explicit CShaderConstantVector3 (glm::vec3 value); explicit CShaderConstantVector3 (glm::vec3 value);
@ -24,8 +22,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
* Type string indicator * Type string indicator
*/ */
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */ /** The constant's value */
glm::vec3 m_value; glm::vec3 m_value;
}; };
} } // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -2,15 +2,9 @@
using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Effects::Constants;
CShaderConstantVector4::CShaderConstantVector4 (glm::vec4 value) : CShaderConstant (Type), m_value (value) {}
CShaderConstantVector4::CShaderConstantVector4 (glm::vec4 value) : glm::vec4* CShaderConstantVector4::getValue () {
CShaderConstant (Type),
m_value (value)
{
}
glm::vec4* CShaderConstantVector4::getValue ()
{
return &this->m_value; return &this->m_value;
} }

View File

@ -2,16 +2,14 @@
#include "CShaderConstant.h" #include "CShaderConstant.h"
#include <string>
#include <glm/vec4.hpp> #include <glm/vec4.hpp>
#include <string>
namespace WallpaperEngine::Core::Objects::Effects::Constants namespace WallpaperEngine::Core::Objects::Effects::Constants {
{
/** /**
* Shader constant of vector4 type * Shader constant of vector4 type
*/ */
class CShaderConstantVector4 : public CShaderConstant class CShaderConstantVector4 : public CShaderConstant {
{
public: public:
explicit CShaderConstantVector4 (glm::vec4 value); explicit CShaderConstantVector4 (glm::vec4 value);
@ -24,8 +22,9 @@ namespace WallpaperEngine::Core::Objects::Effects::Constants
* Type string indicator * Type string indicator
*/ */
static const std::string Type; static const std::string Type;
protected: protected:
/** The constant's value */ /** The constant's value */
glm::vec4 m_value; glm::vec4 m_value;
}; };
} } // namespace WallpaperEngine::Core::Objects::Effects::Constants

View File

@ -10,27 +10,17 @@ using namespace WallpaperEngine::Assets;
using namespace WallpaperEngine::Core::Objects; using namespace WallpaperEngine::Core::Objects;
using namespace WallpaperEngine::Core::Objects::Images; using namespace WallpaperEngine::Core::Objects::Images;
CMaterial::CMaterial (std::string name) : CMaterial::CMaterial (std::string name) : m_name (std::move (name)) {}
m_target (),
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) CMaterial* CMaterial::fromFile (const std::string& filename, const std::string& target, CContainer* container) {
{ return fromJSON (filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)), target);
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::fromJSON (const std::string& name, json data, const std::string& target) CMaterial* CMaterial::fromJSON (const std::string& name, json data, const std::string& target) {
{
CMaterial* material = fromJSON (name, std::move (data)); CMaterial* material = fromJSON (name, std::move (data));
material->setTarget (target); material->setTarget (target);
@ -38,9 +28,8 @@ CMaterial* CMaterial::fromJSON (const std::string& name, json data, const std::s
return material; return material;
} }
CMaterial* CMaterial::fromJSON (const std::string& name, json data) CMaterial* CMaterial::fromJSON (const std::string& name, json data) {
{ const auto passes_it = jsonFindRequired (data, "passes", "Material must have at least one pass");
auto passes_it = jsonFindRequired (data, "passes", "Material must have at least one pass");
auto* material = new CMaterial (name); auto* material = new CMaterial (name);
@ -50,41 +39,34 @@ CMaterial* CMaterial::fromJSON (const std::string& name, json data)
return material; return material;
} }
void CMaterial::insertPass (Materials::CPass* mass) void CMaterial::insertPass (Materials::CPass* pass) {
{ this->m_passes.push_back (pass);
this->m_passes.push_back (mass);
} }
void CMaterial::insertTextureBind (Effects::CBind* bind) void CMaterial::insertTextureBind (Effects::CBind* bind) {
{
this->m_textureBindings.insert (std::make_pair (bind->getIndex (), 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; this->m_target = target;
} }
const std::vector <Materials::CPass*>& CMaterial::getPasses () const const std::vector<Materials::CPass*>& CMaterial::getPasses () const {
{
return this->m_passes; 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; return this->m_textureBindings;
} }
const std::string& CMaterial::getTarget () const const std::string& CMaterial::getTarget () const {
{
return this->m_target; return this->m_target;
} }
const std::string& CMaterial::getName () const const std::string& CMaterial::getName () const {
{
return this->m_name; return this->m_name;
} }
bool CMaterial::hasTarget () const bool CMaterial::hasTarget () const {
{
return !this->m_target.empty (); return !this->m_target.empty ();
} }

View File

@ -1,21 +1,19 @@
#pragma once #pragma once
#include "WallpaperEngine/Core/Objects/Images/Materials/CPass.h"
#include "WallpaperEngine/Core/Objects/Effects/CBind.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/Assets/CContainer.h"
#include "WallpaperEngine/Core/Core.h"
namespace WallpaperEngine::Core::Objects::Images namespace WallpaperEngine::Core::Objects::Images {
{
using json = nlohmann::json; using json = nlohmann::json;
using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Assets;
/** /**
* Represents a material in use in the background * Represents a material in use in the background
*/ */
class CMaterial class CMaterial {
{
public: public:
static CMaterial* fromFile (const std::string& filename, Assets::CContainer* container); static CMaterial* fromFile (const std::string& filename, Assets::CContainer* container);
static CMaterial* fromJSON (const std::string& name, json data); static CMaterial* fromJSON (const std::string& name, json data);
@ -71,4 +69,4 @@ namespace WallpaperEngine::Core::Objects::Images
/** The material's name */ /** The material's name */
std::string m_name; std::string m_name;
}; };
} } // namespace WallpaperEngine::Core::Objects::Images

View File

@ -1,54 +1,43 @@
#include "common.h"
#include "CPass.h" #include "CPass.h"
#include "common.h"
#include <utility> #include <utility>
using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Effects::Constants;
using namespace WallpaperEngine::Core::Objects::Images::Materials; using namespace WallpaperEngine::Core::Objects::Images::Materials;
CPass::CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader) : CPass::CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite,
std::string shader) :
m_blending (std::move (blending)), m_blending (std::move (blending)),
m_cullmode (std::move (cullmode)), m_cullmode (std::move (cullmode)),
m_depthtest (std::move (depthtest)), m_depthtest (std::move (depthtest)),
m_depthwrite (std::move (depthwrite)), m_depthwrite (std::move (depthwrite)),
m_shader (std::move(shader)) m_shader (std::move (shader)) {}
{
}
CPass* CPass::fromJSON (json data) CPass* CPass::fromJSON (json data) {
{
// TODO: FIGURE OUT DEFAULT BLENDING MODE // TODO: FIGURE OUT DEFAULT BLENDING MODE
auto blending = jsonFindDefault <std::string> (data, "blending", "normal"); const auto blending = jsonFindDefault<std::string> (data, "blending", "normal");
auto cullmode = jsonFindDefault <std::string> (data, "cullmode", "nocull"); const auto cullmode = jsonFindDefault<std::string> (data, "cullmode", "nocull");
auto depthtest_it = jsonFindRequired (data, "depthtest", "Material pass must have depthtest specified"); const auto depthtest_it = jsonFindRequired (data, "depthtest", "Material pass must have depthtest specified");
auto depthwrite_it = jsonFindRequired (data, "depthwrite", "Material pass must have depthwrite specified"); const auto depthwrite_it = jsonFindRequired (data, "depthwrite", "Material pass must have depthwrite specified");
auto shader_it = jsonFindRequired (data, "shader", "Material pass must have shader specified"); const auto shader_it = jsonFindRequired (data, "shader", "Material pass must have shader specified");
auto textures_it = data.find ("textures"); const auto textures_it = data.find ("textures");
auto combos_it = data.find ("combos"); 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 // 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"); sLog.exception ("Material's textures must be a list");
} }
auto* pass = new CPass ( auto* pass = new CPass (blending, cullmode, *depthtest_it, *depthwrite_it, *shader_it);
blending,
cullmode,
*depthtest_it,
*depthwrite_it,
*shader_it
);
if (textures_it != data.end ()) if (textures_it != data.end ())
for (const auto& cur : (*textures_it)) for (const auto& cur : (*textures_it))
pass->insertTexture (cur.is_null () ? "" : cur); pass->insertTexture (cur.is_null () ? "" : cur);
if (combos_it != data.end ()) if (combos_it != data.end ()) {
{ for (const auto& cur : combos_it->items ()) {
for (const auto& cur : (*combos_it).items ())
{
if (cur.value ().is_number_integer ()) if (cur.value ().is_number_integer ())
pass->insertCombo (cur.key (), cur.value ()); pass->insertCombo (cur.key (), cur.value ());
else else
@ -59,70 +48,57 @@ CPass* CPass::fromJSON (json data)
return pass; return pass;
} }
void CPass::insertTexture (const std::string& texture) void CPass::insertTexture (const std::string& texture) {
{
this->m_textures.push_back (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; 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::string uppercase = std::string (name);
std::transform (uppercase.begin (), uppercase.end (), uppercase.begin (), ::toupper); 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; 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; return this->m_constants;
} }
std::map<std::string, int>* CPass::getCombos () std::map<std::string, int>* CPass::getCombos () {
{
return &this->m_combos; return &this->m_combos;
} }
const std::string& CPass::getShader () const const std::string& CPass::getShader () const {
{
return this->m_shader; return this->m_shader;
} }
const std::string& CPass::getBlendingMode () const const std::string& CPass::getBlendingMode () const {
{
return this->m_blending; return this->m_blending;
} }
const std::string& CPass::getCullingMode () const const std::string& CPass::getCullingMode () const {
{
return this->m_cullmode; return this->m_cullmode;
} }
const std::string& CPass::getDepthTest () const const std::string& CPass::getDepthTest () const {
{
return this->m_depthtest; return this->m_depthtest;
} }
const std::string& CPass::getDepthWrite ()const const std::string& CPass::getDepthWrite () const {
{
return this->m_depthwrite; return this->m_depthwrite;
} }
void CPass::setBlendingMode (const std::string& mode) void CPass::setBlendingMode (const std::string& mode) {
{
this->m_blending = mode; this->m_blending = mode;
} }
void CPass::insertConstant (const std::string& name, CShaderConstant* constant) void CPass::insertConstant (const std::string& name, CShaderConstant* constant) {
{ this->m_constants.insert (std::pair (name, constant));
this->m_constants.insert (std::pair <std::string, CShaderConstant*> (name, constant));
} }

View File

@ -4,21 +4,19 @@
#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h" #include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h"
namespace WallpaperEngine::Core::Objects namespace WallpaperEngine::Core::Objects {
{
class CEffect; class CEffect;
} }
namespace WallpaperEngine::Core::Objects::Images::Materials namespace WallpaperEngine::Core::Objects::Images::Materials {
{
using json = nlohmann::json; using json = nlohmann::json;
/** /**
* Represents a shader pass of an object * Represents a shader pass of an object
*/ */
class CPass class CPass {
{
friend class WallpaperEngine::Core::Objects::CEffect; friend class WallpaperEngine::Core::Objects::CEffect;
public: public:
static CPass* fromJSON (json data); 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); void insertConstant (const std::string& name, Effects::Constants::CShaderConstant* constant);
protected: 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 * Adds a new texture to the list of textures to bind while rendering
@ -110,4 +109,4 @@ namespace WallpaperEngine::Core::Objects::Images::Materials
/** Shader constant values to use for the shaders */ /** Shader constant values to use for the shaders */
std::map<std::string, Core::Objects::Effects::Constants::CShaderConstant*> m_constants; std::map<std::string, Core::Objects::Effects::Constants::CShaderConstant*> m_constants;
}; };
} } // namespace WallpaperEngine::Core::Objects::Images::Materials

View File

@ -2,11 +2,10 @@
using namespace WallpaperEngine::Core::Objects::Particles; using namespace WallpaperEngine::Core::Objects::Particles;
CControlPoint* CControlPoint::fromJSON (json data) CControlPoint* CControlPoint::fromJSON (json data) {
{ const auto flags_it = data.find ("flags");
auto flags_it = data.find ("flags"); const auto id_it = jsonFindRequired (data, "id", "Particle's control point must have id");
auto id_it = jsonFindRequired (data, "id", "Particle's control point must have id"); const auto offset_it = data.find ("offset");
auto offset_it = data.find ("offset");
auto* controlpoint = new CControlPoint (*id_it, 0); auto* controlpoint = new CControlPoint (*id_it, 0);
@ -19,33 +18,24 @@ CControlPoint* CControlPoint::fromJSON (json data)
return controlpoint; return controlpoint;
} }
CControlPoint::CControlPoint (uint32_t id, uint32_t flags) : CControlPoint::CControlPoint (uint32_t id, uint32_t flags) : m_id (id), m_flags (flags), m_offset (glm::vec3 ()) {}
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; this->m_offset = offset;
} }
void CControlPoint::setFlags (uint32_t flags) void CControlPoint::setFlags (uint32_t flags) {
{
this->m_flags = flags; this->m_flags = flags;
} }
uint32_t CControlPoint::getId () const
{ uint32_t CControlPoint::getId () const {
return this->m_id; return this->m_id;
} }
const glm::vec3& CControlPoint::getOffset () const const glm::vec3& CControlPoint::getOffset () const {
{
return this->m_offset; return this->m_offset;
} }
uint32_t CControlPoint::getFlags () const uint32_t CControlPoint::getFlags () const {
{
return this->m_flags; return this->m_flags;
} }

View File

@ -2,15 +2,13 @@
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
namespace WallpaperEngine::Core::Objects::Particles namespace WallpaperEngine::Core::Objects::Particles {
{
using json = nlohmann::json; using json = nlohmann::json;
/** /**
* Control point for particles * Control point for particles
*/ */
class CControlPoint class CControlPoint {
{
public: public:
static CControlPoint* fromJSON (json data); static CControlPoint* fromJSON (json data);
@ -47,4 +45,4 @@ namespace WallpaperEngine::Core::Objects::Particles
/** The offset from starting position */ /** The offset from starting position */
glm::vec3 m_offset; glm::vec3 m_offset;
}; };
} } // namespace WallpaperEngine::Core::Objects::Particles

View File

@ -2,76 +2,54 @@
using namespace WallpaperEngine::Core::Objects::Particles; using namespace WallpaperEngine::Core::Objects::Particles;
CEmitter* CEmitter::fromJSON (json data) CEmitter* CEmitter::fromJSON (json data) {
{ const auto directions_it = jsonFindRequired (data, "directions", "Particle emitter must have direction specified");
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");
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");
auto distancemin_it = jsonFindRequired (data, "distancemin", "Particle emitter must have minimum distance"); const auto id_it = data.find ("id");
auto id_it = data.find ("id"); const auto name_it = jsonFindRequired (data, "name", "Particle emitter must have a name");
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");
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");
auto rate_it = jsonFindRequired (data, "rate", "Particle emitter must have a rate");
return new CEmitter ( return new CEmitter (WallpaperEngine::Core::aToVector3 (*directions_it), *distancemax_it, *distancemin_it,
WallpaperEngine::Core::aToVector3 (*directions_it), (id_it == data.end () ? 0 : static_cast<uint32_t> (*id_it)), *name_it,
*distancemax_it, WallpaperEngine::Core::aToVector3 (*origin_it), *rate_it);
*distancemin_it,
(id_it == data.end () ? 0 : (uint32_t) (*id_it)),
*name_it,
WallpaperEngine::Core::aToVector3 (*origin_it),
*rate_it
);
} }
CEmitter::CEmitter ( CEmitter::CEmitter (const glm::vec3& directions, uint32_t distancemax, uint32_t distancemin, uint32_t id,
const glm::vec3& directions, std::string name, const glm::vec3& origin, double rate) :
uint32_t distancemax,
uint32_t distancemin,
uint32_t id,
std::string name,
const glm::vec3& origin,
double rate):
m_directions (directions), m_directions (directions),
m_distancemax (distancemax), m_distancemax (distancemax),
m_distancemin (distancemin), m_distancemin (distancemin),
m_id (id), m_id (id),
m_name (std::move (name)), m_name (std::move (name)),
m_origin (origin), m_origin (origin),
m_rate (rate) m_rate (rate) {}
{
}
uint32_t CEmitter::getId () const uint32_t CEmitter::getId () const {
{
return this->m_id; return this->m_id;
} }
const std::string& CEmitter::getName () const const std::string& CEmitter::getName () const {
{
return this->m_name; return this->m_name;
} }
const uint32_t CEmitter::getDistanceMax () const const uint32_t CEmitter::getDistanceMax () const {
{
return this->m_distancemax; return this->m_distancemax;
} }
const uint32_t CEmitter::getDistanceMin () const const uint32_t CEmitter::getDistanceMin () const {
{
return this->m_distancemin; return this->m_distancemin;
} }
const glm::vec3& CEmitter::getDirections () const const glm::vec3& CEmitter::getDirections () const {
{
return this->m_directions; return this->m_directions;
} }
const glm::vec3& CEmitter::getOrigin () const const glm::vec3& CEmitter::getOrigin () const {
{
return this->m_origin; return this->m_origin;
} }
const double CEmitter::getRate () const const double CEmitter::getRate () const {
{
return this->m_rate; return this->m_rate;
} }

View File

@ -2,15 +2,13 @@
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
namespace WallpaperEngine::Core::Objects::Particles namespace WallpaperEngine::Core::Objects::Particles {
{
using json = nlohmann::json; using json = nlohmann::json;
/** /**
* Particle emitter, controls the area where the particles have to be created * Particle emitter, controls the area where the particles have to be created
*/ */
class CEmitter class CEmitter {
{
public: public:
static CEmitter* fromJSON (json data); static CEmitter* fromJSON (json data);
@ -44,10 +42,8 @@ namespace WallpaperEngine::Core::Objects::Particles
[[nodiscard]] const double getRate () const; [[nodiscard]] const double getRate () const;
protected: protected:
CEmitter ( CEmitter (const glm::vec3& directions, uint32_t distancemax, uint32_t distancemin, uint32_t id, std::string name,
const glm::vec3& directions, uint32_t distancemax, uint32_t distancemin, uint32_t id, std::string name, const glm::vec3& origin, double rate);
const glm::vec3& origin, double rate
);
private: private:
/** Direction the particles should move to */ /** Direction the particles should move to */
@ -65,4 +61,4 @@ namespace WallpaperEngine::Core::Objects::Particles
/** The rate of emission */ /** The rate of emission */
double m_rate; double m_rate;
}; };
} } // namespace WallpaperEngine::Core::Objects::Particles

View File

@ -1,75 +1,56 @@
#include "common.h"
#include "CInitializer.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/CAlphaRandom.h"
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CAngularVelocityRandom.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/CTurbulentVelocityRandom.h"
#include "WallpaperEngine/Core/Objects/Particles/Initializers/CVelocityRandom.h"
using namespace WallpaperEngine::Core::Objects::Particles; using namespace WallpaperEngine::Core::Objects::Particles;
CInitializer* CInitializer::fromJSON (json data) CInitializer* CInitializer::fromJSON (json data) {
{ const auto id_it = data.find ("id");
auto id_it = data.find ("id"); const auto name_it = jsonFindRequired (data, "name", "Particle's initializer must have a name");
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));
uint32_t id = ((id_it == data.end ()) ? 0 : (uint32_t) (*id_it));
if (*name_it == "lifetimerandom") if (*name_it == "lifetimerandom") {
{
return Initializers::CLifeTimeRandom::fromJSON (data, id); return Initializers::CLifeTimeRandom::fromJSON (data, id);
} }
else if (*name_it == "sizerandom") if (*name_it == "sizerandom") {
{
return Initializers::CSizeRandom::fromJSON (data, id); return Initializers::CSizeRandom::fromJSON (data, id);
} }
else if (*name_it == "rotationrandom") if (*name_it == "rotationrandom") {
{
return Initializers::CRotationRandom::fromJSON (data, id); return Initializers::CRotationRandom::fromJSON (data, id);
} }
else if (*name_it == "velocityrandom") if (*name_it == "velocityrandom") {
{
return Initializers::CVelocityRandom::fromJSON (data, id); return Initializers::CVelocityRandom::fromJSON (data, id);
} }
else if (*name_it == "colorrandom") if (*name_it == "colorrandom") {
{
return Initializers::CColorRandom::fromJSON (data, id); return Initializers::CColorRandom::fromJSON (data, id);
} }
else if (*name_it == "alpharandom") if (*name_it == "alpharandom") {
{
return Initializers::CAlphaRandom::fromJSON (data, id); return Initializers::CAlphaRandom::fromJSON (data, id);
} }
else if (*name_it == "angularvelocityrandom") if (*name_it == "angularvelocityrandom") {
{
return Initializers::CAngularVelocityRandom::fromJSON (data, id); return Initializers::CAngularVelocityRandom::fromJSON (data, id);
} }
else if (*name_it == "turbulentvelocityrandom") if (*name_it == "turbulentvelocityrandom") {
{
return Initializers::CTurbulentVelocityRandom::fromJSON (data, id); return Initializers::CTurbulentVelocityRandom::fromJSON (data, id);
} }
else
{
sLog.exception ("Found unknown initializer for particles: ", *name_it); 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) : const std::string& CInitializer::getName () const {
m_id (id),
m_name (std::move(name))
{
}
const std::string& CInitializer::getName () const
{
return this->m_name; return this->m_name;
} }
uint32_t CInitializer::getId () const uint32_t CInitializer::getId () const {
{
return this->m_id; return this->m_id;
} }

View File

@ -2,16 +2,14 @@
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
namespace WallpaperEngine::Core::Objects::Particles namespace WallpaperEngine::Core::Objects::Particles {
{
using json = nlohmann::json; using json = nlohmann::json;
/** /**
* Initializer for particles, controls the different attributes a particle will have * Initializer for particles, controls the different attributes a particle will have
* on emission * on emission
*/ */
class CInitializer class CInitializer {
{
public: public:
static CInitializer* fromJSON (json data); static CInitializer* fromJSON (json data);
@ -33,4 +31,4 @@ namespace WallpaperEngine::Core::Objects::Particles
/** The name of the initializer, indicates what type of initialization to do */ /** The name of the initializer, indicates what type of initialization to do */
std::string m_name; std::string m_name;
}; };
} } // namespace WallpaperEngine::Core::Objects::Particles

View File

@ -2,10 +2,9 @@
using namespace WallpaperEngine::Core::Objects::Particles::Initializers; using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
CAlphaRandom* CAlphaRandom::fromJSON (json data, uint32_t id) CAlphaRandom* CAlphaRandom::fromJSON (json data, uint32_t id) {
{ const auto min_it = jsonFindRequired (data, "min", "Alpharandom initializer must have a minimum value");
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");
auto max_it = jsonFindRequired (data, "max", "Alpharandom initializer must have a maximum value");
return new CAlphaRandom (id, *min_it, *max_it); 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) : CAlphaRandom::CAlphaRandom (uint32_t id, double min, double max) :
CInitializer (id, "alpharandom"), CInitializer (id, "alpharandom"),
m_min (min), m_min (min),
m_max (max) m_max (max) {}
{
}
double CAlphaRandom::getMinimum () const double CAlphaRandom::getMinimum () const {
{
return this->m_min; return this->m_min;
} }
double CAlphaRandom::getMaximum () const double CAlphaRandom::getMaximum () const {
{
return this->m_max; return this->m_max;
} }

View File

@ -3,13 +3,11 @@
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.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 * Initializer for particles that decides the base alpha for the particles
*/ */
class CAlphaRandom : CInitializer class CAlphaRandom : CInitializer {
{
public: public:
/** /**
* @return The minimum alpha value to be used * @return The minimum alpha value to be used
@ -33,4 +31,4 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
/** Minimum alpha */ /** Minimum alpha */
double m_min; double m_min;
}; };
} } // namespace WallpaperEngine::Core::Objects::Particles::Initializers

View File

@ -2,32 +2,23 @@
using namespace WallpaperEngine::Core::Objects::Particles::Initializers; using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
CAngularVelocityRandom* CAngularVelocityRandom::fromJSON (json data, uint32_t id) CAngularVelocityRandom* CAngularVelocityRandom::fromJSON (json data, uint32_t id) {
{ const auto min_it = jsonFindRequired (data, "min", "Angularvelocityrandom initializer must have a minimum value");
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");
auto max_it = jsonFindRequired (data, "max", "Angularvelocityrandom initializer must have a maximum value");
return new CAngularVelocityRandom ( return new CAngularVelocityRandom (id, WallpaperEngine::Core::aToVector3 (*min_it),
id, WallpaperEngine::Core::aToVector3 (*max_it));
WallpaperEngine::Core::aToVector3 (*min_it),
WallpaperEngine::Core::aToVector3 (*max_it)
);
} }
CAngularVelocityRandom::CAngularVelocityRandom (uint32_t id, glm::vec3 min, glm::vec3 max) : CAngularVelocityRandom::CAngularVelocityRandom (uint32_t id, glm::vec3 min, glm::vec3 max) :
CInitializer (id, "angularvelocityrandom"), CInitializer (id, "angularvelocityrandom"),
m_min (min), 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; return this->m_min;
} }
const glm::vec3& CAngularVelocityRandom::getMaximum () const const glm::vec3& CAngularVelocityRandom::getMaximum () const {
{
return this->m_max; return this->m_max;
} }

View File

@ -3,13 +3,11 @@
#include "WallpaperEngine/Core/Core.h" #include "WallpaperEngine/Core/Core.h"
#include "WallpaperEngine/Core/Objects/Particles/CInitializer.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 * Initializer for particles that decides the base angular velocity for particles
*/ */
class CAngularVelocityRandom : CInitializer class CAngularVelocityRandom : CInitializer {
{
public: public:
/** /**
* @return Minimum angular velocity (direction * speed) * @return Minimum angular velocity (direction * speed)
@ -33,4 +31,4 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
/** Minimum velocity (direction * speed) */ /** Minimum velocity (direction * speed) */
glm::vec3 m_min; glm::vec3 m_min;
}; };
} } // namespace WallpaperEngine::Core::Objects::Particles::Initializers

View File

@ -2,32 +2,23 @@
using namespace WallpaperEngine::Core::Objects::Particles::Initializers; using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
CColorRandom* CColorRandom::fromJSON (json data, uint32_t id) CColorRandom* CColorRandom::fromJSON (json data, uint32_t id) {
{ const auto min_it = jsonFindRequired (data, "min", "Colorrandom initializer must have a minimum value");
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");
auto max_it = jsonFindRequired (data, "max", "Colorrandom initializer must have a maximum value");
return new CColorRandom ( return new CColorRandom (id, WallpaperEngine::Core::aToColori (*min_it),
id, WallpaperEngine::Core::aToColori (*max_it));
WallpaperEngine::Core::aToColori (*min_it),
WallpaperEngine::Core::aToColori (*max_it)
);
} }
CColorRandom::CColorRandom (uint32_t id, glm::ivec3 min, glm::ivec3 max) : CColorRandom::CColorRandom (uint32_t id, glm::ivec3 min, glm::ivec3 max) :
CInitializer (id, "colorrandom"), CInitializer (id, "colorrandom"),
m_min (min), 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; return this->m_min;
} }
const glm::ivec3& CColorRandom::getMaximum () const const glm::ivec3& CColorRandom::getMaximum () const {
{
return this->m_max; return this->m_max;
} }

View File

@ -4,13 +4,11 @@
#include "WallpaperEngine/Core/Core.h" #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 * Initializer for particles that decides the base color
*/ */
class CColorRandom : CInitializer class CColorRandom : CInitializer {
{
public: public:
/** /**
* @return The minimum color to use (RGB) * @return The minimum color to use (RGB)
@ -34,4 +32,4 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
/** Minimum color */ /** Minimum color */
glm::ivec3 m_min; glm::ivec3 m_min;
}; };
} } // namespace WallpaperEngine::Core::Objects::Particles::Initializers

View File

@ -2,28 +2,22 @@
using namespace WallpaperEngine::Core::Objects::Particles::Initializers; using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
CLifeTimeRandom* CLifeTimeRandom::fromJSON (json data, uint32_t id) CLifeTimeRandom* CLifeTimeRandom::fromJSON (json data, uint32_t id) {
{ const auto min_it = jsonFindRequired (data, "min", "Lifetimerandom initializer must have a minimum value");
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");
auto max_it = jsonFindRequired (data, "max", "Lifetimerandom initializer must have a maximum value");
return new CLifeTimeRandom (id, *min_it, *max_it); return new CLifeTimeRandom (id, *min_it, *max_it);
} }
CLifeTimeRandom::CLifeTimeRandom (uint32_t id, uint32_t min, uint32_t max) : CLifeTimeRandom::CLifeTimeRandom (uint32_t id, uint32_t min, uint32_t max) :
CInitializer (id, "lifetimerandom"), CInitializer (id, "lifetimerandom"),
m_min (min), m_min (min),
m_max (max) m_max (max) {}
{
}
uint32_t CLifeTimeRandom::getMinimum () const uint32_t CLifeTimeRandom::getMinimum () const {
{
return this->m_min; return this->m_min;
} }
uint32_t CLifeTimeRandom::getMaximum () const uint32_t CLifeTimeRandom::getMaximum () const {
{
return this->m_max; return this->m_max;
} }

View File

@ -4,13 +4,11 @@
#include "WallpaperEngine/Core/Core.h" #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 * Initializer for particles that decides the lifetime of each particle on startup
*/ */
class CLifeTimeRandom : CInitializer class CLifeTimeRandom : CInitializer {
{
public: public:
/** /**
* @return The minimum lifetime to be used * @return The minimum lifetime to be used
@ -20,6 +18,7 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
* @return The maximum lifetime to be used * @return The maximum lifetime to be used
*/ */
[[nodiscard]] uint32_t getMaximum () const; [[nodiscard]] uint32_t getMaximum () const;
protected: protected:
friend class CInitializer; friend class CInitializer;
@ -33,4 +32,4 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
/** Minimum lifetime */ /** Minimum lifetime */
uint32_t m_min; uint32_t m_min;
}; };
} } // namespace WallpaperEngine::Core::Objects::Particles::Initializers

View File

@ -4,10 +4,9 @@
using namespace WallpaperEngine::Core::Objects::Particles::Initializers; using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
CRotationRandom* CRotationRandom::fromJSON (json data, uint32_t id) CRotationRandom* CRotationRandom::fromJSON (json data, uint32_t id) {
{ const auto min_it = data.find ("minVector");
auto min_it = data.find ("minVector"); const auto max_it = data.find ("max");
auto max_it = data.find ("max");
glm::vec3 minVector = glm::vec3 (); glm::vec3 minVector = glm::vec3 ();
glm::vec3 maxVector = glm::vec3 (); glm::vec3 maxVector = glm::vec3 ();
@ -16,24 +15,18 @@ CRotationRandom* CRotationRandom::fromJSON (json data, uint32_t id)
bool isMinVector = false; bool isMinVector = false;
bool isMaxVector = 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); minVector = WallpaperEngine::Core::aToVector3 (*min_it);
isMinVector = true; 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; minNumber = *min_it;
isMinVector = false; 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); maxVector = WallpaperEngine::Core::aToVector3 (*max_it);
isMaxVector = true; 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; maxNumber = *max_it;
isMaxVector = false; isMaxVector = false;
} }
@ -41,61 +34,44 @@ CRotationRandom* CRotationRandom::fromJSON (json data, uint32_t id)
return new CRotationRandom (id, minVector, minNumber, isMinVector, maxVector, maxNumber, isMaxVector); return new CRotationRandom (id, minVector, minNumber, isMinVector, maxVector, maxNumber, isMaxVector);
} }
CRotationRandom::CRotationRandom ( CRotationRandom::CRotationRandom (uint32_t id, glm::vec3 minVector, double minNumber, bool isMinimumVector,
uint32_t id, glm::vec3 maxVector, double maxNumber, bool isMaximumVector) :
glm::vec3 minVector,
double minNumber,
bool isMinimumVector,
glm::vec3 maxVector,
double maxNumber,
bool isMaximumVector
) :
CInitializer (id, "rotationrandom"), CInitializer (id, "rotationrandom"),
m_minVector (minVector), m_minVector (minVector),
m_maxVector (maxVector), m_maxVector (maxVector),
m_minNumber (minNumber), m_minNumber (minNumber),
m_maxNumber (maxNumber), m_maxNumber (maxNumber),
m_isMinimumVector (isMinimumVector), m_isMinimumVector (isMinimumVector),
m_isMaximumVector (isMaximumVector) m_isMaximumVector (isMaximumVector) {}
{
}
glm::vec3 CRotationRandom::getMinimumVector () const glm::vec3 CRotationRandom::getMinimumVector () const {
{
return this->m_minVector; return this->m_minVector;
} }
glm::vec3 CRotationRandom::getMaximumVector () const glm::vec3 CRotationRandom::getMaximumVector () const {
{
return this->m_maxVector; return this->m_maxVector;
} }
double CRotationRandom::getMinimumNumber () const double CRotationRandom::getMinimumNumber () const {
{
return this->m_minNumber; return this->m_minNumber;
} }
double CRotationRandom::getMaximumNumber () const double CRotationRandom::getMaximumNumber () const {
{
return this->m_maxNumber; return this->m_maxNumber;
} }
bool CRotationRandom::isMinimumVector () const bool CRotationRandom::isMinimumVector () const {
{
return this->m_isMinimumVector; return this->m_isMinimumVector;
} }
bool CRotationRandom::isMinimumNumber () const bool CRotationRandom::isMinimumNumber () const {
{
return !this->m_isMinimumVector; return !this->m_isMinimumVector;
} }
bool CRotationRandom::isMaximumVector () const bool CRotationRandom::isMaximumVector () const {
{
return this->m_isMaximumVector; return this->m_isMaximumVector;
} }
bool CRotationRandom::isMaximumNumber () const bool CRotationRandom::isMaximumNumber () const {
{
return !this->m_isMaximumVector; return !this->m_isMaximumVector;
} }

View File

@ -4,13 +4,11 @@
#include <nlohmann/json.hpp> #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 * Initializer for particles that decides the base rotation for the particles
*/ */
class CRotationRandom : CInitializer class CRotationRandom : CInitializer {
{
public: public:
/** /**
* @return The minimum rotation in vector format if available * @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); static CRotationRandom* fromJSON (json data, uint32_t id);
CRotationRandom ( CRotationRandom (uint32_t id, glm::vec3 minVector, double minNumber, bool isMinimumVector, glm::vec3 maxVector,
uint32_t id, double maxNumber, bool isMaximumVector);
glm::vec3 minVector,
double minNumber,
bool isMinimumVector,
glm::vec3 maxVector,
double maxNumber,
bool isMaximumVector
);
private: private:
/** Maximum rotation vector */ /** Maximum rotation vector */
@ -76,4 +67,4 @@ namespace WallpaperEngine::Core::Objects::Particles::Initializers
/** If maximum is a vector */ /** If maximum is a vector */
bool m_isMaximumVector; bool m_isMaximumVector;
}; };
} } // namespace WallpaperEngine::Core::Objects::Particles::Initializers

View File

@ -2,10 +2,9 @@
using namespace WallpaperEngine::Core::Objects::Particles::Initializers; using namespace WallpaperEngine::Core::Objects::Particles::Initializers;
CSizeRandom* CSizeRandom::fromJSON (json data, uint32_t id) CSizeRandom* CSizeRandom::fromJSON (json data, uint32_t id) {
{ const auto min_it = jsonFindRequired (data, "min", "Sizerandom initializer must have a minimum value");
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");
auto max_it = jsonFindRequired (data, "max", "Sizerandom initializer must have a maximum value");
return new CSizeRandom (id, *min_it, *max_it); 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) : CSizeRandom::CSizeRandom (uint32_t id, uint32_t min, uint32_t max) :
CInitializer (id, "sizerandom"), CInitializer (id, "sizerandom"),
m_min (min), m_min (min),
m_max (max) m_max (max) {}
{
}
uint32_t CSizeRandom::getMinimum () const uint32_t CSizeRandom::getMinimum () const {
{
return this->m_min; return this->m_min;
} }
uint32_t CSizeRandom::getMaximum () const uint32_t CSizeRandom::getMaximum () const {
{
return this->m_max; return this->m_max;
} }

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