DEVELOPMENT ENVIRONMENT

~alex/mandelbrot-set-gen

7af1c941940228fef83293bfd902e65b7d54cc9c — Alejandro Laguna a month ago 4e07116 master
feat: getopts_long
2 files changed, 70 insertions(+), 10 deletions(-)

M include/mandelbrot.h
M src/main.c
M include/mandelbrot.h => include/mandelbrot.h +2 -0
@@ 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

M src/main.c => src/main.c +68 -10
@@ 14,10 14,61 @@

extern int points[WINDOW_WIDTH * WINDOW_HEIGHT];

#include <getopt.h>

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);