/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* minirt.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: bszilas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/09/08 16:33:29 by victor #+# #+# */ /* Updated: 2025/05/31 18:22:50 by victor ### ########.fr */ /* */ /* ************************************************************************** */ #include "../minirt.h" #include t_data data = { 0 }; uint ratio_x = 0; uint ratio_y = 0; uint max_res_x = 1; uint max_res_y = 1; void create_display() { InitWindow(800, 600, "miniRT"); int monitor = GetCurrentMonitor(); int w = GetMonitorWidth(monitor); int h = GetMonitorHeight(monitor); SetWindowSize(w, h); data.scene.w = w; data.scene.h = h; SetTargetFPS(60); } void data_destroy_func(void *data_ptr) { t_data *data; data = data_ptr; #ifndef __EMSCRIPTEN__ data->go = false; pthread_rwlock_unlock(&data->rwlock); while (data->thread_count--) pthread_join(data->threads[data->thread_count].thread, NULL); pthread_barrier_destroy(&data->barrier); pthread_rwlock_destroy(&data->rwlock); #endif /* ifndef __EMSCRIPTEN__ */ UnloadTexture(data->texture); CloseWindow(); } t_container *menu_init(t_data *data) { t_container *menu; t_item item; menu = ft_calloc(16, sizeof(*menu)); lst_memory(menu, free, ADD); menu[ID_GROUP_MENU_MAIN - 1] = container_create("Main menu", \ NULL, CONTAINER_GRID); item = container_item_button_create("add sphere", \ NULL, scene_add_sphere_func); container_item_add(&menu[ID_GROUP_MENU_MAIN - 1], &item); item = container_item_button_create("add plane", NULL, \ scene_add_plane_func); container_item_add(&menu[ID_GROUP_MENU_MAIN - 1], &item); item = container_item_button_create("add cylinder", NULL, \ scene_add_cylinder); container_item_add(&menu[ID_GROUP_MENU_MAIN - 1], &item); item = container_item_button_create("add disk", NULL, \ scene_add_disk); container_item_add(&menu[ID_GROUP_MENU_MAIN - 1], &item); item = container_item_button_create("show_help", NULL, help_menu_draw); container_item_add(&menu[ID_GROUP_MENU_MAIN - 1], &item); item = container_item_button_create("Load Scene", NULL, explorer_read_dir); item.param = (t_param){&data->scene, NULL, PARAM_SCENE}; container_item_add(&menu[ID_GROUP_MENU_MAIN - 1], &item); return (menu); } t_container *menus_create(t_data *data) { t_container *menu; uint i; menu = menu_init(data); sphere_menu_create(&menu[ID_GROUP_SPHERE]); plane_menu_create(&menu[ID_GROUP_PLANE]); cone_menu_create(&menu[ID_GROUP_CONE]); disc_menu_create(&menu[ID_GROUP_DISC]); cylinder_menu_create(&menu[ID_GROUP_CYLINDER]); i = 0; while (i < 16) menu[i++].data = data; return (menu); } void initialize_data(t_data *data, char *path) { scene_create(path, &data->scene); create_display(); data->pixel = pixel_plane_create(); data->func_ptr = help_menu_draw; data->mouse.data = data; data->scene.pixel = data->pixel; data->menu = menus_create(data); Image img = GenImageColor(data->scene.w, data->scene.h, BLACK); data->pixel_colors = img.data; data->texture = LoadTextureFromImage(img); data->should_rerender = true; pixels_image_syncronize(data->pixel_colors, data->pixel); } char* validate_file_extension(int argc, char **argv) { if (argc == 2 && ft_strlen(argv[1]) > 3 && ft_memcmp(&argv[1][ft_strlen(argv[1]) - 3], ".rt\0", 4) == 0) return argv[1]; ft_fprintf(STDERR_FILENO, "Invalid Argument to Program!\nExiting...\n"); fflush(stderr); exit(EXIT_FAILURE); } void get_key_code(int keys[]) { uint c = 0; if (IsKeyPressed(KEY_ESCAPE)) { keys[c++] = KEY_ESCAPE; if (c == 3) return; } if ((IsKeyPressed(KEY_W) || IsKeyDown(KEY_W))) { keys[c++] = KEY_W; if (c == 3) return; } if ((IsKeyPressed(KEY_E) || IsKeyDown(KEY_E))) { keys[c++] = KEY_E; if (c == 3) return ; } if ((IsKeyPressed(KEY_Q) || IsKeyDown(KEY_Q))) { keys[c++] = KEY_Q; if (c == 3) return ; } if ((IsKeyPressed(KEY_A) || IsKeyDown(KEY_A))) { keys[c++] = KEY_A; if (c == 3) return ; } if ((IsKeyPressed(KEY_S) || IsKeyDown(KEY_S))) { keys[c++] = KEY_S; if (c == 3) return ; } if ((IsKeyPressed(KEY_D) || IsKeyDown(KEY_D))) { keys[c++] = KEY_D; if (c == 3) return ; } if (IsKeyPressed(KEY_ENTER)) { keys[c++] = KEY_ENTER; if (c == 3) return ; } if (IsKeyPressed(KEY_BACKSPACE)) { keys[c++] = KEY_BACKSPACE; if (c == 3) return ; } if (IsKeyPressed(KEY_SLASH)) { keys[c++] = KEY_SLASH; if (c == 3) return ; } if (IsKeyPressed(KEY_PERIOD)) { keys[c++] = KEY_PERIOD; if (c == 3) return ; } if (IsKeyPressed(KEY_M)) { keys[c++] = KEY_M; if (c == 3) return ; } if (IsKeyPressed(KEY_P)) { keys[c++] = KEY_P; if (c == 3) return ; } if (IsKeyPressed(KEY_EQUAL)) { keys[c++] = KEY_EQUAL; if (c == 3) return ; } if (IsKeyPressed(KEY_Y)) { keys[c++] = KEY_Y; if (c == 3) return ; } if (IsKeyPressed(KEY_MINUS)) { keys[c++] = KEY_MINUS; if (c == 3) return ; } if (IsKeyDown(KEY_ONE)) { keys[c++] = KEY_ONE; if (c == 3) return ; } if (IsKeyDown(KEY_TWO)) { keys[c++] = KEY_TWO; if (c == 3) return ; } if (IsKeyDown(KEY_THREE)) { keys[c++] = KEY_THREE; if (c == 3) return ; } if (IsKeyDown(KEY_FOUR)) { keys[c++] = KEY_FOUR; if (c == 3) return ; } if ((IsKeyPressed(KEY_UP) || IsKeyDown(KEY_UP))) { keys[c++] = KEY_UP; if (c == 3) return ; } if ((IsKeyPressed(KEY_DOWN) || IsKeyDown(KEY_DOWN))) { keys[c++] = KEY_DOWN; if (c == 3) return ; } if ((IsKeyPressed(KEY_LEFT) || IsKeyDown(KEY_LEFT))) { keys[c++] = KEY_LEFT; if (c == 3) return ; } if ((IsKeyPressed(KEY_RIGHT) || IsKeyDown(KEY_RIGHT))) { keys[c++] = KEY_RIGHT; if (c == 3) return ; } } bool key_was_pressed = false; void main_loop() { int keys[3] = { 0 }; Vector2 mouse_pos = GetMousePosition(); if (data.mouse.left_is_pressed || data.mouse.right_is_pressed) { mouse_move(mouse_pos.x, mouse_pos.y, &data); mouse_release(mouse_pos.x, mouse_pos.y, &data); } else mouse_press(mouse_pos.x, mouse_pos.y, &data); bzero(keys, sizeof(keys)); get_key_code(keys); for (int i = 0; i < 3; i++) { if (keys[i]) { key_was_pressed = true; data.should_rerender = true; #ifdef __EMSCRIPTEN__ data.scene.resolution_x = ratio_x * 2; data.scene.resolution_y = ratio_y * 2; #else data.scene.resolution_x = ratio_x; data.scene.resolution_y = ratio_y; #endif /* ifdef __EMSCRIPTEN__ */ key_press(keys[i], &data); } } rendering_loop(&data); data.scene.resolution_x = max_res_x; data.scene.resolution_y = max_res_y; if (key_was_pressed) { key_was_pressed = false; } else { data.should_rerender = false; data.func_ptr = NULL; } } int gcd(int a, int b) { while (b != 0) { int temp = b; b = a % b; a = temp; } return a; } int main(int argc, char **argv) { char *path; #ifndef __EMSCRIPTEN__ t_thread thread[THREAD_COUNT]; #endif /* ifndef __EMSCRIPTEN__ */ if (argc == 1) { path = SCENES_PATH"/multilight.rt"; } else path = validate_file_extension(argc, argv); initialize_data(&data, path); lst_memory(&data, data_destroy_func, ADD); int divisor = gcd(data.scene.w, data.scene.h); ratio_x = data.scene.w / divisor; ratio_y = data.scene.h / divisor; #ifndef __EMSCRIPTEN__ threads_init(thread, &data); data.threads = thread; #endif #ifdef __EMSCRIPTEN__ max_res_y = ratio_y; max_res_x = ratio_x; emscripten_set_main_loop(main_loop, 0, 1); #else while(!WindowShouldClose()) { main_loop(); } #endif /* ifdef __EMSCRIPTEN__ */ return (0); }