ソースを参照

fixed more stuff

UwU 5 日 前
親
コミット
fd3398562f

+ 0 - 1
src/WallpaperEngine/Audio/AudioStream.h

@@ -17,7 +17,6 @@ extern "C" {
 
 #include "WallpaperEngine/Audio/AudioContext.h"
 
-// TODO: FIND A BETTER PLACE TO DO THIS? OLD_API MIGHT EXIST BUT THIS DEFINE MIGHT NOT BE DEFINED...
 #ifndef FF_API_FIFO_OLD_API
 #define FF_API_FIFO_OLD_API (LIBAVUTIL_VERSION_MAJOR < 59)
 #endif

+ 12 - 4
src/WallpaperEngine/Data/Model/Object.h

@@ -72,14 +72,21 @@ struct ImageAnimationLayer {
     UserSettingUniquePtr animation;
 };
 
+enum ImageAlignment {
+    ImageAlignment_Center = 0,
+    ImageAlignment_Top = 1,
+    ImageAlignment_Bottom = 2,
+    ImageAlignment_Left = 4,
+    ImageAlignment_Right = 8,
+};
+
 struct ImageData {
     UserSettingUniquePtr scale;
     UserSettingUniquePtr angles;
     UserSettingUniquePtr visible;
     UserSettingUniquePtr alpha;
     UserSettingUniquePtr color;
-    // TODO: write a couple of enums for this
-    std::string alignment;
+    uint32_t alignment;
     /** In pixels */
     glm::vec2 size;
     UserSettingUniquePtr parallaxDepth;
@@ -100,9 +107,10 @@ public:
     ~Image () override = default;
 };
 
+enum SoundPlaybackMode { PlaybackMode_Single = 0, PlaybackMode_Loop = 1, PlaybackMode_Random = 2 };
+
 struct SoundData {
-    // TODO: write an enum for this
-    std::optional<std::string> playbackmode;
+    SoundPlaybackMode playbackmode;
     std::vector<std::string> sounds;
     /** Per-object volume (0-1), independent of the global volume - lets a wallpaper with several
      *  Sound objects (e.g. alternate music tracks) mute all but one via --set-property */

+ 34 - 2
src/WallpaperEngine/Data/Parsers/ObjectParser.cpp

@@ -117,7 +117,7 @@ SoundUniquePtr ObjectParser::parseSound (const JSON& it, const Project& project,
     return std::make_unique<Sound> (
 	std::move (base),
 	SoundData {
-	    .playbackmode = it.optional<std::string> ("playbackmode"),
+	    .playbackmode = parsePlaybackMode (it.optional ("playbackmode", std::string ("single"))),
 	    .sounds = sounds,
 	    .volume = it.user<float> ("volume", project.properties, 1.0f),
 	    .startsilent = it.optional<bool> ("startsilent"),
@@ -125,6 +125,36 @@ SoundUniquePtr ObjectParser::parseSound (const JSON& it, const Project& project,
     );
 }
 
+SoundPlaybackMode ObjectParser::parsePlaybackMode (const std::string& mode) {
+    if (mode == "loop") {
+	return PlaybackMode_Loop;
+    }
+
+    if (mode == "random") {
+	return PlaybackMode_Random;
+    }
+
+    return PlaybackMode_Single;
+}
+
+uint32_t ObjectParser::parseAlignment (const std::string& alignment) {
+    uint32_t result = ImageAlignment_Center;
+
+    if (alignment.find ("top") != std::string::npos) {
+	result |= ImageAlignment_Top;
+    } else if (alignment.find ("bottom") != std::string::npos) {
+	result |= ImageAlignment_Bottom;
+    }
+
+    if (alignment.find ("left") != std::string::npos) {
+	result |= ImageAlignment_Left;
+    } else if (alignment.find ("right") != std::string::npos) {
+	result |= ImageAlignment_Right;
+    }
+
+    return result;
+}
+
 TextUniquePtr ObjectParser::parseText (const JSON& it, const Project& project, ObjectData base) {
     const auto& effects = it.optional ("effects");
 
@@ -167,7 +197,9 @@ ObjectParser::parseImage (const JSON& it, const Project& project, ObjectData bas
 	    .visible = it.user ("visible", properties, true),
 	    .alpha = it.user ("alpha", properties, 1.0f),
 	    .color = it.color ("color", properties, Builders::ColorBuilder::White),
-	    .alignment = it.optional ("horizontalalign", it.optional ("alignment", std::string ("center"))),
+	    .alignment = parseAlignment (
+		it.optional ("horizontalalign", it.optional ("alignment", std::string ("center")))
+	    ),
 	    .size = it.user ("size", properties, glm::vec2 (0.0f))->value->getVec2 (),
 	    .parallaxDepth = it.user ("parallaxDepth", properties, glm::vec2 (0.0f)),
 	    .colorBlendMode = it.user ("colorBlendMode", properties, 0),

+ 2 - 0
src/WallpaperEngine/Data/Parsers/ObjectParser.h

@@ -20,6 +20,8 @@ public:
 private:
     static std::vector<int> parseDependencies (const JSON& it);
     static SoundUniquePtr parseSound (const JSON& it, const Project& project, ObjectData base);
+    static SoundPlaybackMode parsePlaybackMode (const std::string& mode);
+    static uint32_t parseAlignment (const std::string& alignment);
     static ImageUniquePtr
     parseImage (const JSON& it, const Project& project, ObjectData base, const std::string& image);
     static ParticleUniquePtr parseParticle (const JSON& it, const Project& project, ObjectData base);

+ 0 - 1
src/WallpaperEngine/Data/Parsers/UserSettingParser.cpp

@@ -36,7 +36,6 @@ UserSettingUniquePtr UserSettingParser::parse (const json& data, const Propertie
 	}
     }
 
-    // TODO: might need removing if it causes issues with default values
     // connect to property so overrides can propagate
     if (property != nullptr) {
 	if (condition.has_value ()) {

+ 0 - 2
src/WallpaperEngine/Data/Parsers/WallpaperParser.cpp

@@ -30,8 +30,6 @@ SceneUniquePtr WallpaperParser::parseScene (const JSON& file, Project& project)
     const auto objects = scene.require ("objects", "Scenes must have an objects section");
     const auto& properties = project.properties;
 
-    // TODO: verify these defaults are sensible and validate when camera preview/parallax are present
-
     return std::make_unique <Scene> (
         WallpaperData {
             .filename = "",

+ 36 - 43
src/WallpaperEngine/Render/Objects/CImage.cpp

@@ -893,8 +893,6 @@ CImage::CImage (Wallpapers::CScene& scene, const Image& image) :
     if (this->getImage ().model->fullscreen) {
 	size = { static_cast<float> (scene.getCanvasWidth ()), static_cast<float> (scene.getCanvasHeight ()) };
 	origin = { scene_width / 2, scene_height / 2, 0 };
-
-	// TODO: CHANGE ALIGNMENT TOO?
     }
     this->m_size = size;
 
@@ -905,33 +903,7 @@ CImage::CImage (Wallpapers::CScene& scene, const Image& image) :
 	bufferSize = glm::min (bufferSize, glm::vec2 (scene.getCanvasWidth (), scene.getCanvasHeight ()));
     }
 
-    glm::vec2 scaledSize = size * glm::vec2 (scale);
-
-    this->m_pos.x = origin.x - (scaledSize.x / 2);
-    this->m_pos.w = origin.y + (scaledSize.y / 2);
-    this->m_pos.z = origin.x + (scaledSize.x / 2);
-    this->m_pos.y = origin.y - (scaledSize.y / 2);
-
-    if (this->getImage ().alignment.find ("top") != std::string::npos) {
-	this->m_pos.y -= scaledSize.y / 2;
-	this->m_pos.w -= scaledSize.y / 2;
-    } else if (this->getImage ().alignment.find ("bottom") != std::string::npos) {
-	this->m_pos.y += scaledSize.y / 2;
-	this->m_pos.w += scaledSize.y / 2;
-    }
-
-    if (this->getImage ().alignment.find ("left") != std::string::npos) {
-	this->m_pos.x += scaledSize.x / 2;
-	this->m_pos.z += scaledSize.x / 2;
-    } else if (this->getImage ().alignment.find ("right") != std::string::npos) {
-	this->m_pos.x -= scaledSize.x / 2;
-	this->m_pos.z -= scaledSize.x / 2;
-    }
-
-    this->m_pos.x -= scene_width / 2;
-    this->m_pos.y = scene_height / 2 - this->m_pos.y;
-    this->m_pos.z -= scene_width / 2;
-    this->m_pos.w = scene_height / 2 - this->m_pos.w;
+    this->updateScenePosition (origin, size, scale, scene_width, scene_height);
 
     // register both FBOs into the scene
     std::ostringstream nameA, nameB;
@@ -1901,8 +1873,6 @@ void CImage::setup () {
 	return;
     }
 
-    // TODO: CHECK ORDER OF THINGS, 2419444134'S ID 27 DEPENDS ON 104'S COMPOSITE_A WHEN OUR LAST RENDER IS ON
-    // COMPOSITE_B
     // TODO: SUPPORT PASSTHROUGH (IT'S A SHADER)
     // passthrough without effects has nothing to draw
     if (this->m_image.model->passthrough && this->m_image.effects.empty ()) {
@@ -2000,17 +1970,24 @@ void CImage::setup () {
 	}
     }
 
-    if (!debug.baseOnly && this->m_image.colorBlendMode->value->getInt () > 0) {
+    const int colorBlendMode = this->m_image.colorBlendMode->value->getInt ();
+    const bool readByOtherLayer = std::ranges::any_of (this->getScene ().getScene ().objects, [this] (const auto& object) {
+	return object->id != this->getImage ().id
+	    && std::ranges::find (object->dependencies, this->getImage ().id) != object->dependencies.end ();
+    });
+    // WE keeps the result of a layer another one reads in _a and only copies it to the screen from there,
+    // drawing the last effect pass straight to the screen would leave _a one pass behind (or empty)
+    const bool copyForReaders = readByOtherLayer && this->getImage ().visible->value->getBool ();
+
+    if (!debug.baseOnly && (colorBlendMode > 0 || copyForReaders)) {
 	this->m_materials.colorBlending.material
 	    = MaterialParser::load (this->getScene ().getScene ().project, "materials/util/effectpassthrough.json");
 	this->m_materials.colorBlending.override = std::make_unique<ImageEffectPassOverride> (ImageEffectPassOverride {
-            .id = -1,
-            .combos = {
-                {"BLENDMODE", this->m_image.colorBlendMode->value->getInt()},
-            },
-            .constants = {},
-            .textures = {},
-        });
+	    .id = -1,
+	    .combos = colorBlendMode > 0 ? ComboMap { { "BLENDMODE", colorBlendMode } } : ComboMap {},
+	    .constants = {},
+	    .textures = {},
+	});
 
 	this->m_passes.push_back (new CPass (
 	    *this, std::make_shared<FBOProvider> (this), **this->m_materials.colorBlending.material->passes.begin (),
@@ -2112,6 +2089,20 @@ void CImage::rebuildActivePasses () {
 }
 
 void CImage::setupPasses () {
+    // like WE, start on whichever buffer makes the last offscreen pass land in _a, which is what other layers read
+    auto offscreenPasses = std::ranges::count_if (this->m_passes, [] (const Effects::CPass* pass) {
+	return !pass->getTarget ().has_value ();
+    });
+
+    if (!this->m_passes.empty () && !this->m_passes.back ()->getTarget ().has_value ()
+	&& this->shouldRenderFinalPass (true)) {
+	offscreenPasses--;
+    }
+
+    if (offscreenPasses % 2 == 0) {
+	std::swap (this->m_currentMainFBO, this->m_currentSubFBO);
+    }
+
     std::shared_ptr<const CFBO> drawTo = this->m_currentMainFBO;
     std::shared_ptr<const TextureProvider> asInput = this->getTexture ();
     GLuint texcoord = this->getTexCoordCopy ();
@@ -2362,18 +2353,20 @@ void CImage::updateScenePosition (
     this->m_pos.z = origin.x + (scaledSize.x / 2.0f);
     this->m_pos.y = origin.y - (scaledSize.y / 2.0f);
 
-    if (this->getImage ().alignment.find ("top") != std::string::npos) {
+    const uint32_t alignment = this->getImage ().alignment;
+
+    if (alignment & ImageAlignment_Top) {
 	this->m_pos.y -= scaledSize.y / 2.0f;
 	this->m_pos.w -= scaledSize.y / 2.0f;
-    } else if (this->getImage ().alignment.find ("bottom") != std::string::npos) {
+    } else if (alignment & ImageAlignment_Bottom) {
 	this->m_pos.y += scaledSize.y / 2.0f;
 	this->m_pos.w += scaledSize.y / 2.0f;
     }
 
-    if (this->getImage ().alignment.find ("left") != std::string::npos) {
+    if (alignment & ImageAlignment_Left) {
 	this->m_pos.x += scaledSize.x / 2.0f;
 	this->m_pos.z += scaledSize.x / 2.0f;
-    } else if (this->getImage ().alignment.find ("right") != std::string::npos) {
+    } else if (alignment & ImageAlignment_Right) {
 	this->m_pos.x -= scaledSize.x / 2.0f;
 	this->m_pos.z -= scaledSize.x / 2.0f;
     }

+ 1 - 1
src/WallpaperEngine/Render/Objects/CSound.cpp

@@ -29,7 +29,7 @@ void CSound::load () {
 	auto stream
 	    = new Audio::AudioStream (this->getScene ().getAudioContext (), this->getAssetLocator ().read (cur));
 
-	stream->setRepeat (this->m_sound.playbackmode.has_value () && this->m_sound.playbackmode == "loop");
+	stream->setRepeat (this->m_sound.playbackmode == PlaybackMode_Loop);
 
 	this->m_audioStreams.insert_or_assign (this->getScene ().getAudioContext ().addStream (stream), stream);
     }

+ 5 - 6
src/WallpaperEngine/Render/Objects/Effects/CPass.cpp

@@ -516,24 +516,23 @@ void CPass::setupRenderUniforms () {
 	    case Integer:
 		glUniform1iv (value->id, value->count, static_cast<const int*> (value->value));
 		break;
-	    // TODO: THESE MIGHT NEED SPECIAL TREATMENT? IDK ONLY SUPPORT 1 FOR NOW
 	    case Vector4:
-		glUniform4fv (value->id, 1, glm::value_ptr (*static_cast<const glm::vec4*> (value->value)));
+		glUniform4fv (value->id, value->count, glm::value_ptr (*static_cast<const glm::vec4*> (value->value)));
 		break;
 	    case Vector3:
-		glUniform3fv (value->id, 1, glm::value_ptr (*static_cast<const glm::vec3*> (value->value)));
+		glUniform3fv (value->id, value->count, glm::value_ptr (*static_cast<const glm::vec3*> (value->value)));
 		break;
 	    case Vector2:
-		glUniform2fv (value->id, 1, glm::value_ptr (*static_cast<const glm::vec2*> (value->value)));
+		glUniform2fv (value->id, value->count, glm::value_ptr (*static_cast<const glm::vec2*> (value->value)));
 		break;
 	    case Matrix4:
 		glUniformMatrix4fv (
-		    value->id, 1, GL_FALSE, glm::value_ptr (*static_cast<const glm::mat4*> (value->value))
+		    value->id, value->count, GL_FALSE, glm::value_ptr (*static_cast<const glm::mat4*> (value->value))
 		);
 		break;
 	    case Matrix3:
 		glUniformMatrix3fv (
-		    value->id, 1, GL_FALSE, glm::value_ptr (*static_cast<const glm::mat3*> (value->value))
+		    value->id, value->count, GL_FALSE, glm::value_ptr (*static_cast<const glm::mat3*> (value->value))
 		);
 		break;
 	}

+ 5 - 0
src/WallpaperEngine/Render/Wallpapers/CScene.cpp

@@ -711,6 +711,11 @@ const CObject* CScene::getObject (int id) const {
     return object == this->m_objects.end () ? nullptr : object->second;
 }
 
+CObject* CScene::getObject (int id) {
+    const auto object = this->m_objects.find (id);
+    return object == this->m_objects.end () ? nullptr : object->second;
+}
+
 void CScene::setSoundPlaying (int id, bool playing) {
     this->m_soundPlayRequests[id] = playing;
 

+ 1 - 0
src/WallpaperEngine/Render/Wallpapers/CScene.h

@@ -57,6 +57,7 @@ public:
 
     [[nodiscard]] const std::vector<CObject*>& getObjectsByRenderOrder () const;
     [[nodiscard]] const CObject* getObject (int id) const;
+    [[nodiscard]] CObject* getObject (int id);
     /** True when any group above the object (through "parent") is hidden */
     [[nodiscard]] bool isHiddenByAncestor (const CObject& object) const;
     [[nodiscard]] int getObjectIndex (const CObject* object) const;

+ 1 - 4
src/WallpaperEngine/Scripting/SceneObject.cpp

@@ -198,10 +198,7 @@ JSValue get_layer (JSContext* ctx, JSValueConst this_val, int argc, JSValueConst
 	    return JS_UNDEFINED;
 	}
 
-	// TODO: REMOVE THIS CONST_CAST?
-	return container->getEngine ().getAdapters ().object->instantiate (
-	    const_cast<ScriptableObject&> (*object->as<ScriptableObject> ())
-	);
+	return container->getEngine ().getAdapters ().object->instantiate (*object->as<ScriptableObject> ());
     } else if (JS_IsString (layer)) {
 	const char* result = JS_ToCString (ctx, layer);