From 6ed3bdb941b014e04f68e0beb23b9be3de4adb04 Mon Sep 17 00:00:00 2001 From: Bob Polis Date: Sun, 26 Oct 2025 22:56:46 +0100 Subject: [PATCH] Add module Polygon --- modules/Polygon/Makefile | 53 +++++++++++++++++++ modules/Polygon/Polygon.cpp | 99 ++++++++++++++++++++++++++++++++++++ modules/Polygon/Polygon.hpp | 10 ++++ modules/Polygon/Polygon.json | 8 +++ modules/Polygon/premake.make | 6 +++ 5 files changed, 176 insertions(+) create mode 100644 modules/Polygon/Makefile create mode 100644 modules/Polygon/Polygon.cpp create mode 100644 modules/Polygon/Polygon.hpp create mode 100644 modules/Polygon/Polygon.json create mode 100644 modules/Polygon/premake.make diff --git a/modules/Polygon/Makefile b/modules/Polygon/Makefile new file mode 100644 index 0000000..c22234e --- /dev/null +++ b/modules/Polygon/Makefile @@ -0,0 +1,53 @@ +include premake.make + +# some important install locations +PREFIX ?= /usr/local +DATADIR ?= $(PREFIX)/share +INSTALLDIR ?= $(DATADIR)/$(INSTALLDIRNAME) + +SRCS := $(wildcard *.cpp) +OBJS := $(SRCS:.cpp=.o) +DEPS := $(SRCS:.cpp=.dep) + +CXX ?= g++ + +CXXFLAGS += -Wshadow -Wall -Wpedantic -Wextra -Wno-unused-parameter +CXXFLAGS += -g3 -std=c++20 -fPIC +ifeq ($(DEBUG),1) + CXXFLAGS += -D DEBUG -O0 +else + CXXFLAGS += -D NDEBUG -O3 +endif + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -o $@ -MMD -MP -MT $@ -MF $*.dep -c $< + +%.dep: ; + +.PHONY: all clean install uninstall + +all: $(PLUGIN) + +$(PLUGIN): $(OBJS) +ifeq ($(UNAME_S),Darwin) + $(CXX) -g3 -dynamiclib -o $(PLUGIN) $(LDFLAGS) $(OBJS) $(LDLIBS) +else + $(CXX) -g3 -shared -o $(PLUGIN) $(LDFLAGS) $(OBJS) $(LDLIBS) +endif + +-include $(DEPS) + +clean: + rm -f $(OBJS) $(DEPS) $(PLUGIN) + +$(INSTALLDIR): + install -m 0755 -d $@ + +install: $(INSTALLDIR) + install -m 0644 $(PLUGIN) $(INSTALLDIR) +ifdef EXTRAFILES + install -m 0644 $(EXTRAFILES) $(INSTALLDIR) +endif + +uninstall: + rm -f $(INSTALLDIR)/$(PLUGIN) $(addprefix $(INSTALLDIR)/, $(EXTRAFILES)) diff --git a/modules/Polygon/Polygon.cpp b/modules/Polygon/Polygon.cpp new file mode 100644 index 0000000..70008d5 --- /dev/null +++ b/modules/Polygon/Polygon.cpp @@ -0,0 +1,99 @@ +#include "Polygon.hpp" +#include +#include +#include +#include +#include + +struct Point { + double x; + double y; + double speed_x; + double speed_y; +}; + +class Polygon : public ScreensaverPlugin { +public: + Polygon() = default; + ~Polygon() = default; + + void setup(cairo_t *context, const cairo_rectangle_t &rect) override; + void configure() override; + int fps() const override; + void update() override; + void render() override; + std::string version() const override; + +private: + int _num_points {10}; + double _min_speed {0.2}; + double _max_speed {2.0}; + double _stroke_width {1.0}; + Color _stroke_color {"#FFFFFF"}; + Color _fill_color {"#006600"}; + std::vector _points; +}; + +ScreensaverPlugin *create_instance() { return new Polygon; } + +void Polygon::setup(cairo_t* context, const cairo_rectangle_t& rect) { + ScreensaverPlugin::setup(context, rect); + for (int i = 0; i < _num_points; ++i) { + Point p; + p.x = sc::random::double_between(0, _r.width); + p.y = sc::random::double_between(0, _r.height); + p.speed_x = sc::random::double_between(_min_speed, _max_speed); + p.speed_x *= sc::random::boolean() ? 1 : -1; + p.speed_y = sc::random::double_between(_min_speed, _max_speed); + p.speed_y *= sc::random::boolean() ? 1 : -1; + _points.push_back(p); + } +} + +void Polygon::configure() { + _num_points = _j["num-points"]; + _min_speed = _j["min-speed"]; + _max_speed = _j["max-speed"]; + _stroke_width = _j["stroke-width"]; + _stroke_color = _j["stroke-color"]; + _fill_color = _j["fill-color"]; + setup(_c, _r); +} + +std::string Polygon::version() const { return "1.0.0"; } + +int Polygon::fps() const { return 30; } + +void Polygon::update() { + for (Point& p : _points) { + p.x += p.speed_x; + if (p.x < 0 || p.x > _r.width) { + p.speed_x *= -1; + p.x += p.speed_x; + } + p.y += p.speed_y; + if (p.y < 0 || p.y > _r.height) { + p.speed_y *= -1; + p.y += p.speed_y; + } + } +} + +void Polygon::render() { + make_black(); + Point first = _points[0]; + cairo_new_path(_c); + cairo_move_to(_c, first.x, first.y); + for (size_t i = 1; i < _points.size(); ++i) { + Point& p = _points[i]; + cairo_line_to(_c, p.x, p.y); + } + cairo_close_path(_c); + RGB c = RGB(_stroke_color); + cairo_set_source_rgb(_c, c.r, c.g, c.b); + cairo_set_line_width(_c, _stroke_width); + cairo_stroke_preserve(_c); + RGB f = RGB(_fill_color); + cairo_set_source_rgb(_c, f.r, f.g, f.b); + cairo_fill(_c); +} diff --git a/modules/Polygon/Polygon.hpp b/modules/Polygon/Polygon.hpp new file mode 100644 index 0000000..3e0242a --- /dev/null +++ b/modules/Polygon/Polygon.hpp @@ -0,0 +1,10 @@ +#ifndef _Polygon_H_ +#define _Polygon_H_ + +class ScreensaverPlugin; + +extern "C" { + ScreensaverPlugin* create_instance(); +} + +#endif // _Polygon_H_ diff --git a/modules/Polygon/Polygon.json b/modules/Polygon/Polygon.json new file mode 100644 index 0000000..13be468 --- /dev/null +++ b/modules/Polygon/Polygon.json @@ -0,0 +1,8 @@ +{ + "num-points": 5, + "min-speed": 0.2, + "max-speed": 2.0, + "stroke-width": 1.0, + "stroke-color": "#FFFFFF", + "fill-color": "#006000" +} diff --git a/modules/Polygon/premake.make b/modules/Polygon/premake.make new file mode 100644 index 0000000..3d75bf4 --- /dev/null +++ b/modules/Polygon/premake.make @@ -0,0 +1,6 @@ +LDLIBS := -lcairo -lscscreensaver -lsccolor -lscnumerics +UNAME_S := $(shell uname -s) +PROJ := $(shell basename $$(pwd)) +PLUGIN := $(PROJ).saver +INSTALLDIRNAME := screensaver/plugins +EXTRAFILES := $(PROJ).json