diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a75aa5..b97853e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ target_sources(cloudlife PUBLIC mtron.cpp timer.cpp ifs.cpp - vermiculate.cpp) + vermiculate.cpp + discrete.cpp) target_link_libraries(cloudlife IMGUI glfw GL colormap) set_target_properties(cloudlife PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/art.hpp b/art.hpp index 23f4cfb..ae96727 100644 --- a/art.hpp +++ b/art.hpp @@ -17,29 +17,34 @@ class Art { : m_name(_name) {} const char * name() {return m_name.c_str();} virtual bool render_gui() = 0; - virtual void resize(int _w, int _h) {}; + virtual void resize(int _w, int _h) {default_resize(_w, _h);}; virtual void render(uint32_t *p) = 0; virtual void load(std::string json) {}; virtual std::string save() { return ""; }; virtual bool override_texture_size(int &w, int &h) { return false; }; - void drawdot(int x, int y, double o, uint32_t c) { - if (x+1 > w || y+1 > h) return; - uint32_t *p = data(); - p[ y*w + x ] = c | ((unsigned)(0xff*o)<<24); + void drawdot(uint32_t x, uint32_t y, double o, uint32_t c) { + drawdot(x, y, c | ((unsigned)(0xff*o)<<24)); } - void drawdot(int x, int y, uint32_t c) { - if (x+1 > w || y+1 > h) return; + void drawdot(uint32_t x, uint32_t y, uint32_t c) { + if (x >= w || y >= h) { + ++pixels_discarded; + return; + } uint32_t *p = data(); p[ y*w + x ] = c; + ++pixels_drawn; } virtual void reinit() { resize(w, h); } virtual ~Art() = default; + unsigned pixels_drawn = 0; + unsigned pixels_discarded = 0; + protected: void default_resize(int _w, int _h) { w = _w; @@ -56,7 +61,8 @@ class Art { } void clear() { fill0(pixels); - //std::fill(pixels.begin(), pixels.end(), 0); + pixels_drawn = 0; + pixels_discarded = 0; } int w, h; //uint8_t *data() { return reinterpret_cast(pixels.data()); } diff --git a/discrete.cpp b/discrete.cpp index 2831da5..dccc7bd 100644 --- a/discrete.cpp +++ b/discrete.cpp @@ -1,10 +1,6 @@ /* -*- Mode: C; tab-width: 4 -*- */ /* discrete --- chaotic mappings */ -#if 0 -static const char sccsid[] = "@(#)discrete.c 5.00 2000/11/01 xlockmore"; -#endif - /*- * Copyright (c) 1996 by Tim Auckland * @@ -26,49 +22,20 @@ static const char sccsid[] = "@(#)discrete.c 5.00 2000/11/01 xlockmore"; * Map" and the "Bird in a Thornbush" fractal. * * Revision History: + * 27-May-2023: Dear ImGui port by Pavel Vasilyev * 01-Nov-2000: Allocation checks * 31-Jul-1997: Ported to xlockmore-4 * 08-Aug-1996: Adapted from hop.c Copyright (c) 1991 by Patrick J. Naughton. */ -#ifdef STANDALONE -# define MODE_discrete -#define DEFAULTS "*delay: 20000 \n" \ - "*count: 4096 \n" \ - "*cycles: 2500 \n" \ - "*ncolors: 100 \n" \ - "*fpsSolid: true \n" \ - "*ignoreRotation: True \n" \ - -/* "*lowrez: True \n" \ */ - -# define SMOOTH_COLORS -# define release_discrete 0 -# define discrete_handle_event 0 -# include "xlockmore.h" /* in xscreensaver distribution */ -#else /* STANDALONE */ -# include "xlock.h" /* in xlockmore distribution */ -#endif /* STANDALONE */ - -#ifdef MODE_discrete +#include "imgui_elements.h" +#include "discrete.h" +#include "random.h" +// from yarandom.h +#define LRAND() ((long) (xoshiro256plus() & 0x7fffffff)) +#define MAXRAND (2147483648.0) /* unsigned 1<<31 as a float */ -ENTRYPOINT ModeSpecOpt discrete_opts = -{0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL}; - -#ifdef USE_MODULES -ModStruct discrete_description = -{"discrete", "init_discrete", "draw_discrete", (char *) NULL, - "refresh_discrete", "init_discrete", "free_discrete", &discrete_opts, - 1000, 4096, 2500, 1, 64, 1.0, "", - "Shows various discrete maps", 0, NULL}; - -#endif - -enum ftypes { - SQRT, BIRDIE, STANDARD, TRIG, CUBIC, HENON, AILUJ, HSHOE, DELOG -}; - -/*#define TEST STANDARD */ +#include #define BIASES 18 static enum ftypes bias[BIASES] = @@ -82,48 +49,17 @@ static enum ftypes bias[BIASES] = HENON, }; -typedef struct { - int maxx; - int maxy; /* max of the screen */ - double a; - double b; - double c; - double d; - double e; - double i; - double j; /* discrete parameters */ - double ic; - double jc; - double is; - double js; - int inc; - int pix; - enum ftypes op; - int count; - XPoint *pointBuffer; /* pointer for XDrawPoints */ - - int sqrt_sign, std_sign; - -} discretestruct; -static discretestruct *discretes = (discretestruct *) NULL; - -ENTRYPOINT void -init_discrete (ModeInfo * mi) +void Discrete::init_discrete() { + discrete = discretestruct{}; double range; - discretestruct *hp; - - MI_INIT (mi, discretes); - hp = &discretes[MI_SCREEN(mi)]; + discretestruct *hp = &discrete; - hp->maxx = MI_WIDTH(mi); - hp->maxy = MI_HEIGHT(mi); -#ifdef TEST - hp->op = TEST; -#else - hp->op = bias[LRAND() % BIASES]; -#endif + hp->maxx = w; + hp->maxy = h; + //hp->op = bias[LRAND() % BIASES]; + hp->op = (ftypes)bias; switch (hp->op) { case HSHOE: hp->ic = 0; @@ -235,55 +171,24 @@ init_discrete (ModeInfo * mi) break; } } - hp->pix = 0; hp->inc = 0; - if (hp->pointBuffer == NULL) { - hp->pointBuffer = (XPoint *) malloc(sizeof (XPoint) * MI_COUNT(mi)); - /* if fails will check later */ - } - - /* Clear the background. */ - MI_CLEARWINDOW(mi); + pal.rescale(count); - XSetForeground(MI_DISPLAY(mi), MI_GC(mi), MI_WHITE_PIXEL(mi)); hp->count = 0; hp->sqrt_sign = 1; hp->std_sign = 1; } - -static void -draw_discrete_1 (ModeInfo * mi) +void Discrete::draw_discrete_1() { - Display *dsp = MI_DISPLAY(mi); - Window win = MI_WINDOW(mi); double oldj, oldi; - int count = MI_COUNT(mi); - int cycles = MI_CYCLES(mi); - int k; - XPoint *xp; - GC gc = MI_GC(mi); - discretestruct *hp; - - if (discretes == NULL) - return; - hp = &discretes[MI_SCREEN(mi)]; - if (hp->pointBuffer == NULL) - return; - - k = count; - xp = hp->pointBuffer; + int k = count; + discretestruct *hp = &discrete; + unsigned x, y; hp->inc++; - MI_IS_DRAWN(mi) = True; - - if (MI_NPIXELS(mi) > 2) { - XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix)); - if (++hp->pix >= MI_NPIXELS(mi)) - hp->pix = 0; - } while (k--) { oldj = hp->j; oldi = hp->i; @@ -291,14 +196,6 @@ draw_discrete_1 (ModeInfo * mi) case HSHOE: { int i; - -#if 0 - if (!k) { - XSetForeground(dsp, gc, MI_BLACK_PIXEL(mi)); - XFillRectangle(dsp, win, gc, 0, 0, hp->maxx, hp->maxy); - XSetForeground(dsp, gc, MI_PIXEL(mi, hp->pix)); - } else -#endif #define HD #ifdef HD if (k < count / 4) { @@ -383,59 +280,53 @@ draw_discrete_1 (ModeInfo * mi) hp->j = (oldj - hp->b) / (2 * hp->i); break; } - xp->x = hp->maxx / 2 + (int) ((hp->i - hp->ic) * hp->is); - xp->y = hp->maxy / 2 - (int) ((hp->j - hp->jc) * hp->js); - xp++; + x = hp->maxx / 2 + (int) ((hp->i - hp->ic) * hp->is); + y = hp->maxy / 2 - (int) ((hp->j - hp->jc) * hp->js); + drawdot(x, y, pal.get_color(k)); } - XDrawPoints(dsp, win, gc, hp->pointBuffer, count, CoordModeOrigin); + } -ENTRYPOINT void -draw_discrete (ModeInfo * mi) +void Discrete::render(uint32_t *p) { - discretestruct *hp = &discretes[MI_SCREEN(mi)]; - int cycles = MI_CYCLES(mi); - int i; + discretestruct *hp = &discrete; + int i; + + for (i = 0; i < 10; i++) { + draw_discrete_1(); + hp->count++; + } - for (i = 0; i < 10; i++) { - draw_discrete_1 (mi); - hp->count++; - } + std::copy(pixels.begin(), pixels.end(), p); - if (hp->count > cycles) { - init_discrete(mi); - } + if (hp->count > cycles) { + resize(w, h); + } } -ENTRYPOINT void -reshape_discrete(ModeInfo * mi, int width, int height) +bool Discrete::render_gui () { - discretestruct *hp = &discretes[MI_SCREEN(mi)]; - hp->maxx = width; - hp->maxy = height; - XClearWindow (MI_DISPLAY (mi), MI_WINDOW(mi)); -} + bool up = false; + discretestruct *hp = &discrete; + + up |= ScrollableSliderInt("cycles", &cycles, 0, 1024*10, "%d", 256); + up |= ScrollableSliderInt("count", &count, 0, 1024*10, "%d", 256); + up |= ScrollableSliderInt("bias", &bias, 0, 8, "%d", 1); + up |= pal.RenderGui(); + + ImGui::Text("hp->count %d, bias %d", hp->count, hp->op); -ENTRYPOINT void -free_discrete(ModeInfo * mi) -{ - discretestruct *hp = &discretes[MI_SCREEN(mi)]; - if (hp->pointBuffer != NULL) { - (void) free((void *) hp->pointBuffer); - /* hp->pointBuffer = NULL; */ + if (up) { + resize(w, h); } -} -#ifndef STANDALONE -ENTRYPOINT void -refresh_discrete(ModeInfo * mi) -{ - MI_CLEARWINDOW(mi); + return up; } -#endif -XSCREENSAVER_MODULE ("Discrete", discrete) +void Discrete::resize(int _w, int _h) { + default_resize(_w, _h); -#endif /* MODE_discrete */ + init_discrete(); +} diff --git a/main.cpp b/main.cpp index 4cca237..703aa12 100644 --- a/main.cpp +++ b/main.cpp @@ -24,6 +24,7 @@ #include "mtron.hpp" #include "ifs.h" #include "vermiculate.h" +#include "discrete.h" std::unique_ptr art; @@ -164,7 +165,8 @@ int main(int argc, char *argv[]) //art.reset(new Cloudlife); //art.reset(new Minskytron); //art.reset(new IFS); - art.reset(new Vermiculate); + //art.reset(new Vermiculate); + art.reset(new Discrete); IMGUI_CHECKVERSION(); @@ -198,6 +200,9 @@ int main(int argc, char *argv[]) art->render_gui(); + ImGui::Text("pixels drawn %d, discarded %d", + art->pixels_drawn, art->pixels_discarded); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); diff --git a/settings.cpp b/settings.cpp index 3f34d0f..3c5f5cb 100644 --- a/settings.cpp +++ b/settings.cpp @@ -39,13 +39,16 @@ bool PaletteSetting::RenderGui() { void PaletteSetting::rescale(uint32_t ncolours) { value = value.rescale(0., ncolours); + color_max = ncolours; } uint32_t PaletteSetting::get_color(uint32_t color_n) { - auto c = value(color_n); - return 0xff000000 | - c.getRed().getValue() << 0 | - c.getGreen().getValue() << 8 | - c.getBlue().getValue() << 16; + if (color_n > color_max) + printf("%d>%d ", color_n, (int)color_max); + auto c = value(color_n); + return 0xff000000 | + c.getRed().getValue() << 0 | + c.getGreen().getValue() << 8 | + c.getBlue().getValue() << 16; } diff --git a/settings.hpp b/settings.hpp index d12bf9a..6e5adbb 100644 --- a/settings.hpp +++ b/settings.hpp @@ -34,5 +34,7 @@ class PaletteSetting : public Setting { private: int item_current_idx = 0; + + double color_max = 1; };