diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-05-19 13:22:59 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-05-19 13:22:59 +0200 |
| commit | 6a80b1b70ec069b051c0e31aafac6eb596e20261 (patch) | |
| tree | edf9856bcd2b4415796a2a49f0232ba830e69560 | |
| parent | c5008a4e62fb83eb71f5f94f622c01f2d8fe8b6b (diff) | |
| download | mandelbrot-6a80b1b70ec069b051c0e31aafac6eb596e20261.tar.gz mandelbrot-6a80b1b70ec069b051c0e31aafac6eb596e20261.tar.bz2 mandelbrot-6a80b1b70ec069b051c0e31aafac6eb596e20261.zip | |
Back to basic SDL application boilerplate
| -rw-r--r-- | Makefile | 38 | ||||
| -rw-r--r-- | graphics.c | 302 | ||||
| -rw-r--r-- | header.h | 88 | ||||
| -rw-r--r-- | helper.c | 48 | ||||
| -rw-r--r-- | inc/config.h | 9 | ||||
| -rw-r--r-- | inc/mandel.h | 55 | ||||
| -rw-r--r-- | main.c | 72 | ||||
| -rw-r--r-- | mandelbrot.c | 125 | ||||
| -rw-r--r-- | src/color.c | 22 | ||||
| -rw-r--r-- | src/error.c | 13 | ||||
| -rw-r--r-- | src/event.c | 56 | ||||
| -rw-r--r-- | src/main.c | 12 | ||||
| -rw-r--r-- | src/mandelbrot.c | 22 | ||||
| -rw-r--r-- | src/state.c | 34 |
14 files changed, 245 insertions, 651 deletions
@@ -1,34 +1,40 @@ +RM = rm -f + NAME = mandel + +SRC_DIR = src +INC_DIR = inc +OBJ_DIR = obj + CC = gcc -CCFLAGS = -Wall -Wextra +OFLAG = -O0 +CCFLAGS = -I$(INC_DIR) -Wall -Wextra $(OFLAG) LDFLAGS = -lm -lpthread $(shell sdl2-config --libs --cflags) -HEADER = header.h -SRC = main.c graphics.c mandelbrot.c helper.c -OBJ = $(SRC:.c=.o) +INC = $(shell find $(INC_DIR) -type f -name '*.h') +SRC = $(shell find $(SRC_DIR) -type f -name '*.c') +OBJ = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) -RM = rm -f +all: prebuild $(NAME) -.PHONY: all -all: $(NAME) +prebuild: + mkdir -p $(OBJ_DIR) $(NAME): $(OBJ) - $(CC) $(LDFLAGS) $(CCFLAGS) -o $@ $(OBJ) + $(CC) -o $@ $(OBJ) $(LDFLAGS) -%.o: %.c $(HEADER) - $(CC) $(LDFLAGS) $(CCFLAGS) -c -o $@ $< +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(HEADER) + $(CC) $(CCFLAGS) -c -o $@ $< -.PHONY: debug -debug: CCFLAGS += -g -fsanitize=address -debug: re +debug: OFLAG = -g +debug: all -.PHONY: clean clean: $(RM) $(OBJ) -.PHONY: fclean fclean: clean $(RM) $(NAME) -.PHONY: re re: fclean all + +.PHONY: all debug clean fclean re diff --git a/graphics.c b/graphics.c deleted file mode 100644 index e422071..0000000 --- a/graphics.c +++ /dev/null @@ -1,302 +0,0 @@ -#include <stdbool.h> -#include <pthread.h> -#include <SDL2/SDL.h> -#include "header.h" - -#define WINDOW_TITLE "Mandelbrot" -#define WINDOW_X 20 -#define WINDOW_Y 20 -#define REFRESH_RATE 2 -#define MOVE_RATIO 10 -#define ZOOM_RATIO 1.1 -#define REAL_LO(state) (state->center.x - state->real_range / 2) -#define REAL_HI(state) (state->center.x + state->real_range / 2) -#define IMAG_LO(state) (state->center.y - state->imag_range / 2) -#define IMAG_HI(state) (state->center.y + state->imag_range / 2) - -#define IN_SET_COLOR 0x050505 -#define PALETTE_START 0x000022 -#define PALETTE_END 0xd62f2f -/* #define PALETTE_START 0x000000 */ -/* #define PALETTE_END 0xffffff */ -#define SET_DRAW_COLOR(renderer, c) ( \ - SDL_SetRenderDrawColor(renderer, c.rgb.r, c.rgb.g, c.rgb.b, SDL_ALPHA_OPAQUE)); - -#define RED_MASK 0x0000ff -#define GREEN_MASK 0x00ff00 -#define BLUE_MASK 0xff0000 -#define PITCH(ch, width) (ch * width) - -static void update(GState *state); -static void event_handler(GState *state); -static Color *create_palette(Color start, Color end); -/* static void move_center(GState *state, int motion_x, int motion_y); */ -static void recenter(GState *state, int x, int y); -static void recenter_x(GState *state, int x); -static void recenter_y(GState *state, int y); -static void zoom_in(GState *state, double ratio); -static void zoom_out(GState *state, double ratio); -static void destroy_state(GState *state); -static void error_exit_state(GState *state, const char *msg); -static void error_exit(const char *msg); - -GState *graphics_init(Config *config) -{ - Color start, end; - - if (SDL_Init(SDL_INIT_VIDEO) < 0) - error_exit("unable to init SDL"); - GState *state = (GState*)malloc(sizeof(GState)); - if (state == NULL) - error_exit("state allocation failed"); - state->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_X, WINDOW_Y, - config->window_w, config->window_h, 0); - if (state->window == NULL) - error_exit_state(state, "unable to create window"); - state->renderer = SDL_CreateRenderer(state->window, -1, 0); - if (state->renderer == NULL) - error_exit_state(state, "unable to create renderer"); - start.hexcode = PALETTE_START; - end.hexcode = PALETTE_END; - state->palette = create_palette(start, end); - if (state->palette == NULL) - error_exit_state(state, "unable to create color palette"); - state->canvas = SDL_CreateTexture( - state->renderer, SDL_PIXELFORMAT_RGBA8888, - SDL_TEXTUREACCESS_TARGET, config->window_w, config->window_h - ); - if (state->canvas == NULL) - error_exit_state(state, "unable to create canvas texture"); - state->running = true; - state->window_w = config->window_w; - state->window_h = config->window_h; - state->real_range = config->real_range; - state->imag_range = config->imag_range; - state->center.x = config->center_x; - state->center.y = config->center_y; - state->in_set_color.hexcode = IN_SET_COLOR; - state->moving = false; - state->changed = true; - return state; -} - -void graphics_quit(GState *state) -{ - destroy_state(state); - SDL_Quit(); -} - -void graphics_run(GState *state) -{ - while (state->running) - { - event_handler(state); - if (state->changed) - { - update(state); - state->changed = false; - } - SDL_Delay(REFRESH_RATE); - } -} - -static void update(GState *state) -{ - void *pixels = mandelbrot_pixels(REAL_LO(state), REAL_HI(state), - IMAG_LO(state), IMAG_HI(state), - state->window_w, state->window_h, state->palette); - if (pixels == NULL) - error_exit_state(state, "unable to create pixels"); - SDL_Surface *surface = SDL_CreateRGBSurfaceFrom( - pixels, state->window_w, state->window_h, - PIXELS_DEPTH, PITCH(PIXELS_CHANELS, state->window_w), - RED_MASK, BLUE_MASK, GREEN_MASK, 0 - ); - if (surface == NULL) - { - free(pixels); - error_exit_state(state, "unable to create pixels surface"); - } - SDL_Texture *texture = SDL_CreateTextureFromSurface(state->renderer, surface); - free(pixels); - SDL_FreeSurface(surface); - if (texture == NULL) - error_exit_state(state, "unable to create texture"); - SDL_Rect frame; - if (SDL_QueryTexture(texture, NULL, NULL, &frame.w, &frame.h) != 0) - { - SDL_DestroyTexture(texture); - error_exit_state(state, "unable to load texture"); - } - frame.x = 0; - frame.y = 0; - if (SDL_RenderCopy(state->renderer, texture, NULL, &frame) != 0) - { - SDL_DestroyTexture(texture); - error_exit_state(state, "unable to render texture"); - } - SDL_RenderPresent(state->renderer); - SDL_DestroyTexture(texture); -} - -static void event_handler(GState *state) -{ - SDL_Event e; - while (SDL_PollEvent(&e)) - { - switch (e.type) - { - case SDL_QUIT: - state->running = false; - break; - case SDL_KEYDOWN: - switch (e.key.keysym.sym) - { - case SDLK_UP: - case SDLK_k: - state->center.y -= state->imag_range / MOVE_RATIO; - break; - case SDLK_DOWN: - case SDLK_j: - state->center.y += state->imag_range / MOVE_RATIO; - break; - case SDLK_LEFT: - case SDLK_h: - state->center.x -= state->real_range / MOVE_RATIO; - break; - case SDLK_RIGHT: - case SDLK_l: - state->center.x += state->real_range / MOVE_RATIO; - break; - case SDLK_PLUS: - case SDLK_p: - zoom_in(state, ZOOM_RATIO); - break; - case SDLK_MINUS: - case SDLK_m: - zoom_out(state, ZOOM_RATIO); - break; - case SDLK_q: - state->running = false; - } - break; - case SDL_MOUSEWHEEL: - if (e.wheel.y == -1) - zoom_in(state, ZOOM_RATIO); - else if (e.wheel.y == 1) - zoom_out(state, ZOOM_RATIO); - break; - case SDL_MOUSEBUTTONDOWN: - /* printf("> %d, %d\n", e.button.x, e.button.y); */ - if (e.button.button == SDL_BUTTON_RIGHT) - recenter(state, e.button.x, e.button.y); - // TODO - /* case SDL_MOUSEBUTTONUP: */ - /* if (e.button.button == SDL_BUTTON_LEFT) */ - /* { */ - /* if (!state->moving && e.button.state == SDL_PRESSED) */ - /* state->moving = true; */ - /* else if (state->moving && e.button.state == SDL_RELEASED) */ - /* state->moving = false; */ - /* printf("%d %d\n", state->moving, e.button.state); */ - /* } */ - /* break; */ - /* case SDL_MOUSEMOTION: */ - /* if (state->moving) */ - /* { */ - /* printf("%d, %d\n", e.motion.x, e.motion.y); */ - /* move_center(state, e.motion.xrel, e.motion.yrel); */ - /* printf("%f, %f\n", state->center.x, state->center.y); */ - /* } */ - } - state->changed = true; - } -} - - static Color *create_palette(Color start, Color end) -{ - int red_step = abs(end.rgb.r - start.rgb.r) / MAX_ITERATION; - int green_step = abs(end.rgb.g - start.rgb.g) / MAX_ITERATION; - int blue_step = abs(end.rgb.b - start.rgb.b) / MAX_ITERATION; - - Color *palette = (Color*)malloc(sizeof(Color) * (MAX_ITERATION + 1)); - if (palette == NULL) - return NULL; - for (int i = 0; i < MAX_ITERATION; i++) - { - /* palette[i] = helper_HSL_to_RGB(i, 0.6, 1.0); */ - /* printf("%x\n", palette[i].hexcode); */ - palette[i].rgb.r = i * red_step + start.rgb.r; - palette[i].rgb.g = i * green_step + start.rgb.g; - palette[i].rgb.b = i * blue_step + start.rgb.b; - } - palette[MAX_ITERATION].hexcode = 0x0; - return palette; -} - -// TODO -/* static void move_center(GState *state, int motion_x, int motion_y) */ -/* { */ -/* printf("%d, %d\n", motion_x, motion_y); */ -/* if (motion_x != 0) */ -/* state->center.x -= map_range(150 - motion_x, 0, state->window_w, */ -/* REAL_LO(state), REAL_HI(state)); */ -/* if (motion_y != 0) */ -/* state->center.y -= map_range(150 - motion_y, 0, state->window_h, */ -/* IMAG_LO(state), IMAG_HI(state)); */ -/* printf(">> %f, %f\n", state->center.x, state->center.y); */ -/* } */ - -static void recenter(GState *state, int x, int y) -{ - recenter_x(state, x); - recenter_y(state, y); -} - -static void recenter_x(GState *state, int x) -{ - state->center.x = map_range(x, 0, state->window_w, - REAL_LO(state), REAL_HI(state)); -} - -static void recenter_y(GState *state, int y) -{ - state->center.y = map_range(y, 0, state->window_w, - IMAG_LO(state), IMAG_HI(state)); -} - -static void zoom_in(GState *state, double ratio) -{ - state->real_range /= ratio; - state->imag_range /= ratio; -} - -static void zoom_out(GState *state, double ratio) -{ - state->real_range *= ratio; - state->imag_range *= ratio; -} - -static void destroy_state(GState *state) -{ - if (state == NULL) - return; - free(state->palette); - SDL_DestroyTexture(state->canvas); - SDL_DestroyRenderer(state->renderer); - SDL_DestroyWindow(state->window); - free(state); -} - -static void error_exit_state(GState *state, const char *msg) -{ - destroy_state(state); - error_exit(msg); -} - -static void error_exit(const char *msg) -{ - SDL_Log("ERROR: %s: %s", SDL_GetError(), msg); - SDL_Quit(); - exit(EXIT_FAILURE); -} diff --git a/header.h b/header.h deleted file mode 100644 index 92b4d83..0000000 --- a/header.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef HEADER_H -# define HEADER_H - -# include <stdbool.h> -# include <SDL2/SDL.h> - -# define MAX_ITERATION 200 -# define ESCAPE_RADIUS 10 -# define ESCAPE_RADIUS_SQUARED (ESCAPE_RADIUS * ESCAPE_RADIUS) - -# define PIXELS_CHANELS 3 -# define PIXELS_DEPTH (PIXELS_CHANELS * 8) - -typedef uint8_t Byte; -typedef int ColorHexcode; - -typedef union -{ - ColorHexcode hexcode; - struct - { - Byte b; - Byte g; - Byte r; - } rgb; -} Color; - -typedef struct -{ - double x; - double y; -} Point; - -typedef struct -{ - SDL_Window *window; - SDL_Renderer *renderer; - bool running; - int window_w; - int window_h; - Point center; - double real_range; - double imag_range; - Color *palette; - Color in_set_color; - bool moving; - bool changed; - SDL_Texture *canvas; -} GState; - -typedef struct -{ - int window_w; - int window_h; - double real_range; - double imag_range; - double center_x; - double center_y; -} Config; - -typedef struct -{ - double real_lo; - double real_hi; - double imag_step; - int width; - double imag; - Color *palette; - uint8_t *row; -} ThreadArgs; - -// mandelbrot.c -int mandelbrot_in_set(double a, double b); -void mandelbrot_print(void); -void *mandelbrot_pixels(double real_lo, double real_hi, double imag_lo, - double imag_hi, int width, int height, Color *palette); - -// graphics.c -GState *graphics_init(Config *config); -void graphics_quit(GState *state); -void graphics_run(GState *state); - -// helper.c -double map_range(double x, double src_lo, double src_hi, double dest_lo, double dest_hi); -Color helper_HSL_to_RGB(int hue, double saturation, double lightness); -double double_rand(void); - -#endif diff --git a/helper.c b/helper.c deleted file mode 100644 index 3e02182..0000000 --- a/helper.c +++ /dev/null @@ -1,48 +0,0 @@ -#include <math.h> -#include "header.h" - -#define MAX(x, y) ((x) > (y) ? (x) : (y)) -#define MIN(x, y) ((x) < (y) ? (x) : (y)) -#define MIN3(x, y, z) (MIN(x, MIN(y, z))) - -double map_range(double x, double src_lo, double src_hi, double dest_lo, double dest_hi) -{ - double src_len = src_hi - src_lo; - double dest_len = dest_hi - dest_lo; - return (x - src_lo) / src_len * dest_len + dest_lo; -} - -Color helper_HSL_to_RGB(int hue, double saturation, double lightness) -{ - /* double chroma = (1 - fabs(2 * lightness - 1)) * saturation; */ - /* int hue_p = hue / 60; */ - /* double x = chroma * (1 - abs(hue_p % 2 - 1)); */ - Color color; - - /* if (hue == 0) */ - /* { */ - /* color.hexcode = 0x000000; */ - /* return color; */ - /* } */ - /* */ - /* if (hue_p */ - - double a = saturation * MIN(lightness, 1 - lightness); - int kn0 = (0 + hue / 30) % 12; - int kn8 = (8 + hue / 30) % 12; - int kn4 = (4 + hue / 30) % 12; - Byte f0 = lightness - a * MAX(MIN3(kn0 - 3, 9 - kn0, 1), -1); - Byte f8 = lightness - a * MAX(MIN3(kn8 - 3, 9 - kn8, 1), -1); - Byte f4 = lightness - a * MAX(MIN3(kn4 - 3, 9 - kn4, 1), -1); - - color.rgb.r = f0; - color.rgb.g = f8; - color.rgb.b = f4; - - return color; -} - -double double_rand(void) -{ - return (double)rand() / RAND_MAX; -} diff --git a/inc/config.h b/inc/config.h new file mode 100644 index 0000000..4085dba --- /dev/null +++ b/inc/config.h @@ -0,0 +1,9 @@ +#ifndef CONFIG_H +# define CONFIG_H + +# define MANDEL_WINDOW_WIDTH 640 +# define MANDEL_WINDOW_HEIGHT 480 + +# define MANDEL_WINDOW_TITLE "Mandelbrot" + +#endif diff --git a/inc/mandel.h b/inc/mandel.h new file mode 100644 index 0000000..e6f3e10 --- /dev/null +++ b/inc/mandel.h @@ -0,0 +1,55 @@ +#ifndef MANDEL_H +# define MANDEL_H + +# include <stdlib.h> +# include <stdbool.h> +# include <math.h> +# include <SDL2/SDL.h> + +#define SDL_CALL(x) do { \ + SDL_ClearError(); \ + x; \ + error_check_sdl(#x, __FILE__, __LINE__); \ +} while (0) + +typedef union +{ + uint32_t data; + struct + { + uint8_t b; + uint8_t g; + uint8_t r; + }; +} Color; + +typedef struct +{ + double x; + double y; +} Point; + +typedef struct +{ + SDL_Window *window; + SDL_Renderer *renderer; + bool running; + SDL_Surface *surface; + Color *palette; +} State; + +// mandelbrot.c +int mandelbrot(double a, double b); + +// state.c +bool state_init(State *state); +void state_quit(State *state); +void state_run(State *state); + +// event.c +void event_handle(State *state); + +// error.c +void error_check_sdl(const char *code, const char *filename, int line_num); + +#endif @@ -1,72 +0,0 @@ -#include <getopt.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include "header.h" - -#define DEFAULT_WINDOW_W 300 -#define DEFAULT_WINDOW_H 300 -#define DEFAULT_CENTER_X 0.0 -#define DEFAULT_CENTER_Y 0.0 -#define DEFAULT_REAL_RANGE 4.0 -#define DEFAULT_IMAG_RANGE 4.0 - -static void print_help(void); - -int main(int argc, char **argv) -{ - int opt; - Config config; - /* Image *image = NULL; */ - - config.window_w = DEFAULT_WINDOW_W; - config.window_h = DEFAULT_WINDOW_H; - config.center_x = DEFAULT_CENTER_X; - config.center_y = DEFAULT_CENTER_Y; - config.real_range = DEFAULT_REAL_RANGE; - config.imag_range = DEFAULT_IMAG_RANGE; - while ((opt = getopt(argc, argv, "hps:r:c:")) != -1) - { - switch (opt) - { - case 'p': - mandelbrot_print(); - exit(EXIT_SUCCESS); - break; - /* case 'i': */ - /* image = image_init(); */ - case 'h': - print_help(); - exit(EXIT_SUCCESS); - break; - case 's': - sscanf(optarg, "%d,%d", &config.window_w, &config.window_h); - break; - case 'r': - sscanf(optarg, "%lf,%lf", &config.real_range, &config.imag_range); - break; - case 'c': - sscanf(optarg, "%lf,%lf", &config.center_x, &config.center_y); - break; - case '?': - default: - fprintf(stderr, "Try: %s -h for more information", argv[0]); - exit(EXIT_FAILURE); - } - - } - /* if (image != NULL) */ - /* { */ - /* */ - /* return EXIT_SUCCESS; */ - /* } */ - GState *gstate = graphics_init(&config); - graphics_run(gstate); - graphics_quit(gstate); - return EXIT_SUCCESS; -} - -static void print_help(void) -{ - printf("help"); -} diff --git a/mandelbrot.c b/mandelbrot.c deleted file mode 100644 index 7017a54..0000000 --- a/mandelbrot.c +++ /dev/null @@ -1,125 +0,0 @@ -#include <stdio.h> -#include <math.h> -#include <pthread.h> -#include "header.h" - -#define PRINT_REAL_LO -2.0 -#define PRINT_REAL_HI 2.0 -#define PRINT_IMAG_LO -2.0 -#define PRINT_IMAG_HI 2.0 -#define AXIS_DIV 46.0 -#define REAL_AXIS_STEP ((PRINT_REAL_HI - PRINT_REAL_LO) / AXIS_DIV) -#define IMAG_AXIS_STEP ((PRINT_IMAG_HI - PRINT_IMAG_LO) / AXIS_DIV) -#define SAMPLES 1 - -#define IN_CHAR '*' -#define OUT_CHAR ' ' - -static void *pixel_row(void *args); - -int mandelbrot_in_set(double ca, double cb) -{ - double zr = ca; - double zi = cb; - double zr_square; - double zi_square; - int n; - for (n = 0; n < MAX_ITERATION; n++) - { - zi_square = zi * zi; - zr_square = zr * zr; - if (zr_square + zi_square > ESCAPE_RADIUS_SQUARED) - return n; - /* return n + 5 - clog(ESCAPE_RADIUS) / log(2); */ - zi = 2 * zr * zi; - zr = zr_square - zi_square; - zi += cb; - zr += ca; - } - return n; -} - - -int mandelbrot_in_set_super_sampled(double ca, double cb, double real_step, double imag_step) -{ - int total = 0; - for (int i = 0; i < SAMPLES; i++) - total += mandelbrot_in_set(ca - (double_rand() * real_step) / 2, - cb - (double_rand() * imag_step) / 2); - return total / SAMPLES; -} - -void *mandelbrot_pixels(double real_lo, double real_hi, double imag_lo, - double imag_hi, int width, int height, Color *palette) -{ - Byte *pixels = (Byte*)malloc(width * height * PIXELS_CHANELS); - if (pixels == NULL) - return NULL; - pthread_t *threads = (pthread_t*)malloc(sizeof(pthread_t) * height); - if (threads == NULL) - return NULL; - for (int y = 0; y < height; y++) - { - ThreadArgs *args = (ThreadArgs*)malloc(sizeof(ThreadArgs)); - if (args == NULL) - return NULL; - args->real_lo = real_lo; - args->real_hi = real_hi; - args->width = width; - args->imag = map_range((double)y, 0, height, imag_lo, imag_hi); - args->imag_step = (imag_hi - imag_lo) / (0.5 + (height - 1)); - args->palette = palette; - args->row = pixels + PIXELS_CHANELS * width * y; - pthread_create(&threads[y], NULL, pixel_row, args); - } - for (int y = 0; y < height; y++) - pthread_join(threads[y], NULL); - free(threads); - return (void*)pixels; -} - -static void *pixel_row(void *void_args) -{ - ThreadArgs *args = (ThreadArgs*)void_args; - int iterations; - double real_step = (args->real_hi - args->real_lo) / (0.5 + (args->width - 1)); - for (int x = 0; x < args->width; x++) - { - double a = map_range((double)x, 0, args->width, args->real_lo, args->real_hi); - if (SAMPLES == 1) - iterations = mandelbrot_in_set(a, args->imag); - else - { - iterations = mandelbrot_in_set_super_sampled( - a, args->imag, real_step, args->imag_step); - } - - /* double logBase = 1.0 / log(2.0); */ - /* double logHalfBase = log(0.5) * logBase; */ - /* int color_index = (int)(5 + iterations - logHalfBase */ - /* - log(log(a * a + args->imag * args->imag)) * logBase); */ - Color color = args->palette[iterations]; - int row_index = x * PIXELS_CHANELS; - args->row[row_index] = color.rgb.r; - args->row[row_index + 1] = color.rgb.g; - args->row[row_index + 2] = color.rgb.b; - } - free(args); - return NULL; -} - -void mandelbrot_print(void) -{ - for (double i = PRINT_IMAG_LO; i < PRINT_IMAG_HI; i += IMAG_AXIS_STEP) - { - for (double r = PRINT_REAL_LO; r < PRINT_REAL_HI; r += REAL_AXIS_STEP) - { - if (mandelbrot_in_set(r, i) == -1) - putchar(IN_CHAR); - else - putchar(OUT_CHAR); - putchar(' '); - } - putchar('\n'); - } -} diff --git a/src/color.c b/src/color.c new file mode 100644 index 0000000..f758595 --- /dev/null +++ b/src/color.c @@ -0,0 +1,22 @@ +#include "mandel.h" + +/* static Color *create_palette(Color start, Color end) */ +/* { */ + /* int red_step = abs(end.rgb.r - start.rgb.r) / MAX_ITERATION; */ + /* int green_step = abs(end.rgb.g - start.rgb.g) / MAX_ITERATION; */ + /* int blue_step = abs(end.rgb.b - start.rgb.b) / MAX_ITERATION; */ + /* */ + /* Color *palette = (Color*)malloc(sizeof(Color) * (MAX_ITERATION + 1)); */ + /* if (palette == NULL) */ + /* return NULL; */ + /* for (int i = 0; i < MAX_ITERATION; i++) */ + /* { */ + /* #<{(| palette[i] = helper_HSL_to_RGB(i, 0.6, 1.0); |)}># */ + /* #<{(| printf("%x\n", palette[i].hexcode); |)}># */ + /* palette[i].rgb.r = i * red_step + start.rgb.r; */ + /* palette[i].rgb.g = i * green_step + start.rgb.g; */ + /* palette[i].rgb.b = i * blue_step + start.rgb.b; */ + /* } */ + /* palette[MAX_ITERATION].hexcode = 0x0; */ + /* return palette; */ +/* } */ diff --git a/src/error.c b/src/error.c new file mode 100644 index 0000000..92e3a71 --- /dev/null +++ b/src/error.c @@ -0,0 +1,13 @@ +#include "mandel.h" + +void error_check_sdl(const char *code, const char *filename, int line_num) +{ + const char *err; + + err = SDL_GetError(); + if (*err == '\0') + return ; + SDL_Log("[ERROR SDL] %s\n\t(%s) at %s:%d", err, code, filename, line_num); + SDL_Quit(); + exit(EXIT_FAILURE); +} diff --git a/src/event.c b/src/event.c new file mode 100644 index 0000000..d0354eb --- /dev/null +++ b/src/event.c @@ -0,0 +1,56 @@ +#include "mandel.h" + +void event_handle(State *state) +{ + SDL_Event e; + + while (SDL_PollEvent(&e)) + { + switch (e.type) + { + case SDL_QUIT: + state->running = false; + break; + case SDL_KEYDOWN: + switch (e.key.keysym.sym) + { + case SDLK_UP: + case SDLK_k: + + break; + case SDLK_DOWN: + case SDLK_j: + + break; + case SDLK_LEFT: + case SDLK_h: + + break; + case SDLK_RIGHT: + case SDLK_l: + + break; + case SDLK_PLUS: + case SDLK_p: + + break; + case SDLK_MINUS: + case SDLK_m: + + break; + case SDLK_q: + state->running = false; + } + break; + case SDL_MOUSEWHEEL: + if (e.wheel.y == -1) + ; + else if (e.wheel.y == 1) + ; + break; + case SDL_MOUSEBUTTONDOWN: + break; + } + } +} + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..c19d32a --- /dev/null +++ b/src/main.c @@ -0,0 +1,12 @@ +#include "mandel.h" + +int main(void) +{ + State state; + + if (!state_init(&state)) + return (1); + state_run(&state); + state_quit(&state); + return EXIT_SUCCESS; +} diff --git a/src/mandelbrot.c b/src/mandelbrot.c new file mode 100644 index 0000000..a996b26 --- /dev/null +++ b/src/mandelbrot.c @@ -0,0 +1,22 @@ +#include "mandel.h" + +int mandelbrot(double ca, double cb) +{ + double zr = ca; + double zi = cb; + double zr_square; + double zi_square; + int n; + for (n = 0; n < 20; n++) + { + zi_square = zi * zi; + zr_square = zr * zr; + if (zr_square + zi_square > 4) + return n; + zi = 2 * zr * zi; + zr = zr_square - zi_square; + zi += cb; + zr += ca; + } + return n; +} diff --git a/src/state.c b/src/state.c new file mode 100644 index 0000000..ee68b77 --- /dev/null +++ b/src/state.c @@ -0,0 +1,34 @@ +#include "config.h" +#include "mandel.h" + +bool state_init(State *state) +{ + SDL_CALL(SDL_Init(SDL_INIT_VIDEO)); + SDL_CALL(state->window = SDL_CreateWindow( + MANDEL_WINDOW_TITLE, + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + MANDEL_WINDOW_WIDTH, + MANDEL_WINDOW_HEIGHT, + 0)); + SDL_CALL(state->renderer = SDL_CreateRenderer(state->window, -1, 0)); + state->running = true; + return state; +} + +void state_run(State *state) +{ + while (state->running) + { + event_handle(state); + } +} + +void state_quit(State *state) +{ + /* free(state->palette); */ + /* SDL_FreeSurface(state->surface); */ + SDL_DestroyRenderer(state->renderer); + SDL_DestroyWindow(state->window); + SDL_Quit(); +} |
