--- /dev/null
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "../structs.h"
+
+worker_arg warg;
+int waiting_workers;
+int should_quit = 0;
+
+extern FVec2 ** grid;
+extern FVec2 ** grid_prime;
+extern FVec2 ** grid_temp;
+extern IVec2 grid_size;
+
+pthread_t* threads;
+pthread_mutex_t mutex;
+pthread_barrier_t barrier;
+
+float rd_a_prime(FVec2 **source_grid, RD_Opts opts, int x, int y, Mat3 kernel, float A, float B);
+float rd_b_prime(FVec2** source_grid, RD_Opts opts, int x, int y, Mat3 kernel, float A, float B);
+
+void* iterator(void* _arg)
+{
+ worker_arg* warg = (worker_arg*)_arg;
+ RD_Opts opts = warg->opts;
+ int start_x = warg->start_x;
+ int start_y = warg->start_y;
+ int w = warg->width;
+ int h = warg->height;
+
+ for (warg->iterations = 0; warg->iterations < warg->max_iterations; warg->iterations++)
+ {
+ for (int x = start_x; x < w + start_x && x < grid_size.x; x++)
+ {
+ for (int y = start_y; y < h + start_y && y < grid_size.y; y++)
+ {
+ FVec2 each = grid[x][y];
+ if (each.c >= 0.5f)
+ {
+ each.b = 1.0f;
+ each.c -= 5.0f/((float)(opts.max_iterations/100.0f));
+ }
+ grid_prime[x][y].a = rd_a_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b);
+ grid_prime[x][y].b = rd_b_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b);
+ }
+ }
+
+ pthread_mutex_lock(&mutex);
+ if (++waiting_workers == warg->worker_count)
+ {
+ grid_temp = grid;
+ grid = grid_prime;
+ grid_prime = grid_temp;
+ waiting_workers = 0;
+ }
+ pthread_mutex_unlock(&mutex);
+ pthread_barrier_wait(&barrier);
+
+ }
+
+ // One last synchronization so boss thread doesn't die early
+ pthread_barrier_wait(&barrier);
+ should_quit = 1;
+
+ return _arg;
+}
+
+void start(int worker_count, RD_Opts active_opt)
+{
+ worker_arg warg = (worker_arg){
+ active_opt, grid, grid_prime,
+ 0, 0, (grid_size.x), (grid_size.y),
+ .worker_count = worker_count,
+ .max_iterations = active_opt.max_iterations
+ };
+
+ threads = (pthread_t*)malloc(sizeof(pthread_t) * worker_count);
+ pthread_mutex_init(&mutex, NULL);
+ pthread_barrier_init(&barrier, NULL, warg.worker_count);
+
+ worker_arg wargs[worker_count];
+
+ for (int t = 0; t < warg.worker_count; t++)
+ {
+ wargs[t] = warg;
+ wargs[t].worker_id = t;
+ wargs[t].width = (grid_size.x/worker_count) + ((t == worker_count-1) ? 0 : 4);
+ wargs[t].start_x = (wargs[t].width * t);
+ pthread_create(&threads[t], NULL, iterator, &wargs[t]);
+ }
+}
+
+int cleanup()
+{
+ for (int t = 0; t < warg.worker_count; t++)
+ {
+ pthread_join(threads[t], NULL);
+ }
+
+ free(grid);
+ free(grid_prime);
+ free(threads);
+
+ return 0;
+}
#include <stdint.h>
#include <math.h>
+#warning TODO: I think this header is only posix, check for alt platform replacements
+#include <time.h>
+
#include "structs.h"
+#include "platform.h"
+
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#define printf(a,...)
#endif
-worker_arg warg;
-int waiting_workers = 0;
-int should_quit = 0;
-
-pthread_t* threads;
-pthread_mutex_t mutex;
-pthread_barrier_t barrier;
-
+extern int should_quit;
FVec2 ** grid;
FVec2 ** grid_prime;
FVec2 ** grid_temp;
return result;
}
-float rd_a_prime(FVec2 **source_grid, RD_Opts opts, int x, int y, Mat3 kernel,
- float A, float B) {
+float rd_a_prime(FVec2 **source_grid, RD_Opts opts, int x, int y, Mat3 kernel, float A, float B) {
float a_prime = 1.0f;
int x_less = (x - 1 < 0) ? x : x - 1;
int y_less = (y - 1 < 0) ? y : y - 1;
return b_prime;
}
-void* iterator(void* _arg)
-{
- worker_arg* warg = (worker_arg*)_arg;
- RD_Opts opts = warg->opts;
- int start_x = warg->start_x;
- int start_y = warg->start_y;
- int w = warg->width;
- int h = warg->height;
-
- for (warg->iterations = 0; warg->iterations < warg->max_iterations; warg->iterations++)
- {
- printf("worker %d: work unit %d/%d\n", warg->worker_id, warg->iterations, warg->max_iterations);
- for (int x = start_x; x < w + start_x && x < grid_size.x; x++)
- {
- for (int y = start_y; y < h + start_y && y < grid_size.y; y++)
- {
- FVec2 each = grid[x][y];
- if (each.c >= 0.5f)
- {
- each.b = 1.0f;
- each.c -= 5.0f/((float)(opts.max_iterations/100.0f));
- }
- grid_prime[x][y].a = rd_a_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b);
- grid_prime[x][y].b = rd_b_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b);
- }
- }
-
- pthread_mutex_lock(&mutex);
- if (++waiting_workers == warg->worker_count)
- {
- grid_temp = grid;
- grid = grid_prime;
- grid_prime = grid_temp;
- waiting_workers = 0;
- printf("worker-boss %d: completing report\n", warg->worker_id);
- }
- pthread_mutex_unlock(&mutex);
- pthread_barrier_wait(&barrier);
-
- }
-
- // One last synchronization so boss thread doesn't die early
- pthread_barrier_wait(&barrier);
- should_quit = 1;
-
- printf("worker %d: exiting\n", warg->worker_id);
- return _arg;
-}
-
int initialize(int worker_count, RD_Opts active_opt)
{
grid_prime = (FVec2**)malloc(grid_size.x * sizeof(FVec2*));
srand(time(NULL));
+ /* Set up as a circle */
float radius = grid_size.x/2.1f;
int center_x = grid_size.x/2;
int center_y = grid_size.y/2;
+
for (int x = 0; x < grid_size.x; x++)
{
for (int y = 0; y < grid_size.y; y++)
grid[x][y].a = 1.0f;
grid[x][y].b = 0.0f;
- switch (active_opt.shape)
+ if ((sqrtf(((x-center_x)*(x-center_x))+((y-center_y)*(y-center_y))) < radius))
{
- case eCircle:
- {
- if ((sqrtf(((x-center_x)*(x-center_x))+((y-center_y)*(y-center_y))) < radius))
- {
- grid[x][y].c = 0.0f;
- }
- else {
- grid[x][y].c = 1.0f;
- }
- } break;
-
- case eSquare:
- default:
- {
- grid[x][y].c = 0.0f;
- } break;
-
- case eBarrow:
- {
- if ((sqrtf(((x-center_x)*(x-center_x))+((y-center_y)*(y-center_y))) < radius))
- {
- grid[x][y].c = 0.0f;
- }
- else {
- grid[x][y].c = 1.0f;
- }
-
- // Slap in an entrance or something here
- // or add support for post-processing
- if (abs(x-center_x) < 3 && (y <= (5 * (grid_size.y/8))))
- {
- grid[x][y].c = 1.0f;
- }
-
- if (abs(y-center_y) < 8 && (x <= (6 * (grid_size.x/8))) && (x >= (2 * (grid_size.x/8))))
- {
- grid[x][y].c = 1.0f;
- }
-
- } break;
+ grid[x][y].c = 0.0f;
+ }
+ else {
+ grid[x][y].c = 1.0f;
}
}
}
- /* Big seeds good for rooms */
+ /* Set up seed-points to create connected rooms */
const int seed_count = sqrt(grid_size.x) * 2;
const int width = 12 * (grid_size.x/128);
const int height = width * 1;
}
}
- warg = (worker_arg){
- active_opt, grid, grid_prime,
- 0, 0, (grid_size.x), (grid_size.y),
- .worker_count = worker_count,
- .max_iterations = active_opt.max_iterations
- };
-
- threads = (pthread_t*)malloc(sizeof(pthread_t) * worker_count);
- pthread_mutex_init(&mutex, NULL);
- pthread_barrier_init(&barrier, NULL, warg.worker_count);
-
- worker_arg wargs[worker_count];
-
- for (int t = 0; t < warg.worker_count; t++)
- {
- wargs[t] = warg;
- wargs[t].worker_id = t;
- wargs[t].width = (grid_size.x/worker_count) + ((t == worker_count-1) ? 0 : 4);
- wargs[t].start_x = (wargs[t].width * t);
- printf("worker %d x_span %d, %d\n", t, wargs[t].start_x, wargs[t].width);
- pthread_create(&threads[t], NULL, iterator, &wargs[t]);
- }
- return 0;
-}
-
-int cleanup()
-{
- printf("boss: exiting loop\n");
- for (int t = 0; t < warg.worker_count; t++)
- {
- pthread_join(threads[t], NULL);
- }
-
- free(grid);
- free(grid_prime);
- free(threads);
-
return 0;
}
grid_size = pgrid_size;
initialize(worker_count, active_opt);
+ start(worker_count, active_opt);
while(!should_quit) {}