From 7af1c941940228fef83293bfd902e65b7d54cc9c Mon Sep 17 00:00:00 2001 From: Alejandro Laguna Date: Thu, 30 Jul 2026 10:51:20 +0200 Subject: [PATCH] feat: getopts_long --- include/mandelbrot.h | 2 ++ src/main.c | 78 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/include/mandelbrot.h b/include/mandelbrot.h index c2ddcbfaf5cdd42b27eada455859f289728e5ae4..9c502575dd8ffa7b4c8e960a368c37c06236e7ca 100644 --- a/include/mandelbrot.h +++ b/include/mandelbrot.h @@ -22,6 +22,8 @@ typedef struct state_s { SDL_Window* window; SDL_Surface* surface; SDL_Renderer* renderer; + int num_threads; + int max_iteration; } state_t; // math.c diff --git a/src/main.c b/src/main.c index 1538a19f158c49febeb99b8eaa9f4f3497739267..bb2f6081433dc9a143edb81424ff75ca4ae4c867 100644 --- a/src/main.c +++ b/src/main.c @@ -14,10 +14,61 @@ extern int points[WINDOW_WIDTH * WINDOW_HEIGHT]; +#include + +int parse_arguments(int argc, char** argv, int* num_threads, int* max_iter) { + int opt; + int threads = 1; + int max_iterations = 100; + + static struct option long_options[] = {{"threads", required_argument, 0, 't'}, + {"iteration", required_argument, 0, 'i'}, + {"help", no_argument, 0, 'h'}, + {0, 0, 0, 0}}; + + while ((opt = getopt_long(argc, argv, "t:i:h", long_options, NULL)) != -1) { + switch (opt) { + case 't': + threads = atoi(optarg); + if (threads <= 0) { + fprintf(stderr, "Error: threads must be a positive integer\n"); + return -1; + } + break; + case 'i': + max_iterations = atoi(optarg); + if (max_iterations <= 0) { + fprintf(stderr, "Error: max iterations must be a positive integer\n"); + return -1; + } + break; + case 'h': + printf("Usage: %s [options]\n", argv[0]); + printf(" --threads N, -t N Number of threads to use (default: 1)\n"); + printf( + " --iteration N, -i N Maximum iterations for Mandelbrot (default: 100)\n"); + printf(" --help, -h Show this help message\n"); + return -1; + default: + fprintf(stderr, "Use --help for usage information\n"); + return -1; + } + } + *num_threads = threads; + *max_iter = max_iterations; + return 0; +} + state_t* init() { state_t* state = malloc(sizeof(state_t)); + if (!state) { + fprintf(stderr, "malloc failed\n"); + return NULL; + } + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS)) { fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError()); + free(state); return NULL; } SDL_Window* window = @@ -73,10 +124,7 @@ void* calculate_points_thread(void* arg) { return NULL; } -void calculate_points_pthread(position_t* pos) { - int max_iter = 100; - int num_threads = 4; - +void calculate_points_pthread(position_t* pos, int num_threads, int max_iteration) { pthread_t threads[num_threads]; thread_data_t thread_data[num_threads]; @@ -87,7 +135,7 @@ void calculate_points_pthread(position_t* pos) { thread_data[t].pos = pos; thread_data[t].start_row = t * rows_per_thread; thread_data[t].end_row = (t + 1) * rows_per_thread; - thread_data[t].max_iter = max_iter; + thread_data[t].max_iter = max_iteration; if (t == num_threads - 1) { thread_data[t].end_row += remaining_rows; @@ -101,12 +149,25 @@ void calculate_points_pthread(position_t* pos) { } } -int main(void) { +int main(int argc, char** argv) { + int num_threads; + int max_iteration; + + int parse_result = parse_arguments(argc, argv, &num_threads, &max_iteration); + if (parse_result == -1) { + return 1; + } + state_t* state = init(); if (state == NULL) { return -1; } + state->num_threads = num_threads; + state->max_iteration = max_iteration; + + printf("Using %d threads with %d max iterations\n", state->num_threads, state->max_iteration); + SDL_Event e; bool running = true; SDL_ShowWindow(state->window); @@ -156,7 +217,6 @@ int main(void) { is_dragging = true; drag_start_x = (float)e.button.x; drag_start_y = (float)e.button.y; - // store current view drag_start_x_min = position.x_min; drag_start_x_max = position.x_max; drag_start_y_min = position.y_min; @@ -186,7 +246,6 @@ int main(void) { double view_width = drag_start_x_max - drag_start_x_min; double view_height = drag_start_y_max - drag_start_y_min; - // Pan: shift the view opposite to mouse movement double x_shift = dx * view_width / (WINDOW_WIDTH - 1); double y_shift = dy * view_height / (WINDOW_HEIGHT - 1); @@ -206,8 +265,7 @@ int main(void) { } } if (pos_updated) { - // calculate_points(&position); - calculate_points_pthread(&position); + calculate_points_pthread(&position, state->num_threads, state->max_iteration); pos_updated = false; } draw_points(state->surface);