From d53c5b5481e29cfb39203ab941490b00ab87e54d Mon Sep 17 00:00:00 2001
From: Orestis <orestis.malaspinas@pm.me>
Date: Fri, 5 Mar 2021 22:19:26 +0100
Subject: [PATCH] added logistic map orbit with sdl

---
 travaux_pratiques/tpChaos/Makefile | 12 ++++
 travaux_pratiques/tpChaos/gfx.c    | 95 ++++++++++++++++++++++++++++++
 travaux_pratiques/tpChaos/gfx.h    | 41 +++++++++++++
 travaux_pratiques/tpChaos/map.c    | 37 +++++++++---
 4 files changed, 178 insertions(+), 7 deletions(-)
 create mode 100644 travaux_pratiques/tpChaos/Makefile
 create mode 100644 travaux_pratiques/tpChaos/gfx.c
 create mode 100644 travaux_pratiques/tpChaos/gfx.h

diff --git a/travaux_pratiques/tpChaos/Makefile b/travaux_pratiques/tpChaos/Makefile
new file mode 100644
index 0000000..e5cf4ae
--- /dev/null
+++ b/travaux_pratiques/tpChaos/Makefile
@@ -0,0 +1,12 @@
+CC=gcc
+CFLAGS=-Wall -Wextra -pedantic -std=c11 -g -fsanitize=leak -fsanitize=undefined  -fsanitize=address -O3
+LFLAGS=-lSDL2
+TARGET=map
+
+all: map
+
+map: map.c gfx.c
+	$(CC) $(CFLAGS) $^ -o $@ $(LFLAGS)
+
+clean:
+	rm -f *.o $(TARGET)
diff --git a/travaux_pratiques/tpChaos/gfx.c b/travaux_pratiques/tpChaos/gfx.c
new file mode 100644
index 0000000..aca1933
--- /dev/null
+++ b/travaux_pratiques/tpChaos/gfx.c
@@ -0,0 +1,95 @@
+/// @file gfx.c
+/// @author Florent Gluck
+/// @date November 6, 2016
+/// Helper routines to render pixels in fullscreen graphic mode.
+/// Uses the SDL2 library.
+
+#include "gfx.h"
+
+/// Create a fullscreen graphic window.
+/// @param title Title of the window.
+/// @param width Width of the window in pixels.
+/// @param height Height of the window in pixels.
+/// @return a pointer to the graphic context or NULL if it failed.
+struct gfx_context_t* gfx_create(char *title, uint width, uint height) {
+	if (SDL_Init(SDL_INIT_VIDEO) != 0) goto error;
+	SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED,
+		SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_RESIZABLE);
+	SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
+	SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
+			SDL_TEXTUREACCESS_STREAMING, width, height);
+	uint32_t *pixels = malloc(width*height*sizeof(uint32_t));
+	struct gfx_context_t *ctxt = malloc(sizeof(struct gfx_context_t));
+
+	if (!window || !renderer || !texture || !pixels || !ctxt) goto error;
+
+	ctxt->renderer = renderer;
+	ctxt->texture = texture;
+	ctxt->window = window;
+	ctxt->width = width;
+	ctxt->height = height;
+	ctxt->pixels = pixels;
+
+	SDL_ShowCursor(SDL_DISABLE);
+	gfx_clear(ctxt, COLOR_BLACK);
+	return ctxt;
+
+error:
+	return NULL;
+}
+
+/// Draw a pixel in the specified graphic context.
+/// @param ctxt Graphic context where the pixel is to be drawn.
+/// @param x X coordinate of the pixel.
+/// @param y Y coordinate of the pixel.
+/// @param color Color of the pixel.
+void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color) {
+	if (x < ctxt->width && y < ctxt->height)
+		ctxt->pixels[ctxt->width*y+x] = color;
+}
+
+/// Clear the specified graphic context.
+/// @param ctxt Graphic context to clear.
+/// @param color Color to use.
+void gfx_clear(struct gfx_context_t *ctxt, uint32_t color) {
+	int n = ctxt->width*ctxt->height;
+	while (n)
+		ctxt->pixels[--n] = color;
+}
+
+/// Display the graphic context.
+/// @param ctxt Graphic context to clear.
+void gfx_present(struct gfx_context_t *ctxt) {
+	SDL_UpdateTexture(ctxt->texture, NULL, ctxt->pixels, ctxt->width*sizeof(uint32_t));
+	SDL_RenderCopy(ctxt->renderer, ctxt->texture, NULL, NULL);
+	SDL_RenderPresent(ctxt->renderer);
+}
+
+/// Destroy a graphic window.
+/// @param ctxt Graphic context of the window to close.
+void gfx_destroy(struct gfx_context_t *ctxt) {
+	SDL_ShowCursor(SDL_ENABLE);
+	SDL_DestroyTexture(ctxt->texture);
+	SDL_DestroyRenderer(ctxt->renderer);
+	SDL_DestroyWindow(ctxt->window);
+	free(ctxt->pixels);
+	ctxt->texture = NULL;
+	ctxt->renderer = NULL;
+	ctxt->window = NULL;
+	ctxt->pixels = NULL;
+	SDL_Quit();
+	free(ctxt);
+}
+
+/// If a key was pressed, returns its key code (non blocking call).
+/// List of key codes: https://wiki.libsdl.org/SDL_Keycode
+/// @return the key that was pressed or 0 if none was pressed.
+SDL_Keycode gfx_keypressed() {
+	SDL_Event event;
+	if (SDL_PollEvent(&event)) {
+		if (event.type == SDL_KEYDOWN)
+			return event.key.keysym.sym;
+	}
+	return 0;
+}
+
diff --git a/travaux_pratiques/tpChaos/gfx.h b/travaux_pratiques/tpChaos/gfx.h
new file mode 100644
index 0000000..72bbdc3
--- /dev/null
+++ b/travaux_pratiques/tpChaos/gfx.h
@@ -0,0 +1,41 @@
+#ifndef _GFX_H_
+#define _GFX_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <SDL2/SDL.h>
+
+#define MAKE_COLOR(r,g,b) ((uint32_t)b|((uint32_t)g<<8)|((uint32_t)r<<16))
+
+#define COLOR_GET_B(color) (color & 0xff)
+#define COLOR_GET_G(color) ((color >> 8) & 0xff)
+#define COLOR_GET_R(color) ((color >> 16) & 0xff)
+
+#define COLOR_BLACK  0x00000000
+#define COLOR_RED    0x00FF0000
+#define COLOR_GREEN  0x0000FF00
+#define COLOR_BLUE   0x000000FF
+#define COLOR_WHITE  0x00FFFFFF
+#define COLOR_YELLOW 0x00FFFF00
+
+typedef unsigned int  uint;
+typedef unsigned long ulong;
+typedef unsigned char uchar;
+
+struct gfx_context_t {
+	SDL_Window *window;
+	SDL_Renderer *renderer;
+	SDL_Texture *texture;
+	uint32_t *pixels;
+	int width;
+	int height;
+};
+
+extern void gfx_putpixel(struct gfx_context_t *ctxt, int x, int y, uint32_t color);
+extern void gfx_clear(struct gfx_context_t *ctxt, uint32_t color);
+extern struct gfx_context_t* gfx_create(char *text, uint width, uint height);
+extern void gfx_destroy(struct gfx_context_t *ctxt);
+extern void gfx_present(struct gfx_context_t *ctxt);
+extern SDL_Keycode gfx_keypressed();
+
+#endif
diff --git a/travaux_pratiques/tpChaos/map.c b/travaux_pratiques/tpChaos/map.c
index 5750975..bbfe075 100644
--- a/travaux_pratiques/tpChaos/map.c
+++ b/travaux_pratiques/tpChaos/map.c
@@ -1,23 +1,46 @@
 #include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "gfx.h"
 
 double map(double x, double lambda) {
     return lambda * x * (1.0 - x);
 }
 
 int main() {
-    const double lambda_min = 0.0;
-    const double lambda_max = 4.0;
-    const int N = 100;
+    const double lambda_min = 0;
+    const double lambda_max = 4;
+    const int N = 1920;
+    const int M = 960;
     const double dl = (lambda_max - lambda_min) / N;
+
+    struct gfx_context_t *ctxt = gfx_create("Example", N, M);
+	if (!ctxt) {
+		fprintf(stderr, "Graphics initialization failed!\n");
+		return EXIT_FAILURE;
+	}
+    gfx_clear(ctxt, COLOR_BLACK);
     
-    int max_iter = 1000;
-    for (double lambda = 0.0; lambda < lambda_max; lambda += dl) {
+    int max_iter = 100000;
+    for (double i_lambda = 0; i_lambda < N; ++i_lambda) {
         double x = 0.5;
         for (int i = 0; i < max_iter; ++i) {
-            printf("x(%d, %g) = %g\n", i, lambda, x);
+            double lambda = lambda_min + i_lambda * dl;
             x = map(x, lambda);
+            if (i > max_iter - M) {
+		        gfx_putpixel(ctxt, i_lambda, x * M, COLOR_WHITE);
+                // printf("x(%d, %g) = %g\n", i, i_lambda * dl, x);
+
+                // usleep((unsigned int)1000);
+            }
         }
-        printf("\n");
+        gfx_present(ctxt);
+
+        // printf("\n");
     }
+    while (gfx_keypressed() != SDLK_ESCAPE) {
+	}
 
+	gfx_destroy(ctxt);
+	return EXIT_SUCCESS;
 }
-- 
GitLab