summaryrefslogtreecommitdiff
path: root/project-base/src/platform_shared.c
diff options
context:
space:
mode:
authorAldrik Ramaekers <aldrikboy@gmail.com>2024-11-23 22:33:43 +0100
committerAldrik Ramaekers <aldrikboy@gmail.com>2024-11-23 22:33:43 +0100
commitb1e857cf1471d1871a9396696b22fa531da98249 (patch)
tree3923008a8653057698cb339faf6dcfa92e18364b /project-base/src/platform_shared.c
parent106bb7fcadf637cec883648916cc8d19529d6199 (diff)
add projbase to repo
Diffstat (limited to 'project-base/src/platform_shared.c')
-rw-r--r--project-base/src/platform_shared.c364
1 files changed, 364 insertions, 0 deletions
diff --git a/project-base/src/platform_shared.c b/project-base/src/platform_shared.c
new file mode 100644
index 0000000..1776f21
--- /dev/null
+++ b/project-base/src/platform_shared.c
@@ -0,0 +1,364 @@
+/*
+* BSD 2-Clause “Simplified” License
+* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com
+* All rights reserved.
+*/
+
+void platform_get_name_from_path(char *buffer, char *path)
+{
+ buffer[0] = 0;
+
+ s32 len = strlen(path);
+ if (len == 1)
+ {
+ return;
+ }
+
+ char *path_end = path + len;
+#ifdef OS_LINUX
+ while (*path_end != '/' && path_end >= path)
+ {
+ --path_end;
+ }
+#endif
+#ifdef OS_WIN
+ while (*path_end != '\\' && path_end >= path)
+ {
+ --path_end;
+ }
+#endif
+
+ string_copyn(buffer, path_end+1, MAX_INPUT_LENGTH);
+}
+
+void platform_get_directory_from_path(char *buffer, char *path)
+{
+ buffer[0] = 0;
+
+ s32 len = strlen(path);
+ if (len == 1)
+ {
+ return;
+ }
+
+ char *path_end = path + len;
+#ifdef OS_LINUX
+ while (*path_end != '/' && path_end >= path)
+ {
+ --path_end;
+ }
+#endif
+#ifdef OS_WIN
+ while (*path_end != '\\' && path_end >= path)
+ {
+ --path_end;
+ }
+#endif
+
+ s32 offset = path_end - path;
+ char ch = path[offset+1];
+ path[offset+1] = 0;
+ string_copyn(buffer, path, MAX_INPUT_LENGTH);
+ path[offset+1] = ch;
+}
+
+void platform_autocomplete_path(char *buffer, bool want_dir)
+{
+ char dir[MAX_INPUT_LENGTH];
+ char name[MAX_INPUT_LENGTH];
+ platform_get_directory_from_path(dir, buffer);
+ platform_get_name_from_path(name, buffer);
+
+ // nothing to autocomplete
+ if (name[0] == 0)
+ {
+ return;
+ }
+
+ // create filter
+ string_appendn(name, "*", MAX_INPUT_LENGTH);
+
+ array files = array_create(sizeof(found_file));
+ array filters = string_split(name);
+ bool is_cancelled = false;
+ platform_list_files_block(&files, dir, filters, false, 0, want_dir, &is_cancelled, 0);
+
+ s32 index_to_take = -1;
+ if (want_dir)
+ {
+ for (s32 i = 0; i < files.length; i++)
+ {
+ found_file *file = array_at(&files, i);
+
+ if (platform_directory_exists(file->path))
+ {
+ index_to_take = i;
+ break;
+ }
+ }
+ }
+ else
+ {
+ index_to_take = 0;
+ }
+
+ array_destroy(&filters);
+
+ if (files.length > 0 && index_to_take != -1)
+ {
+ found_file *file = array_at(&files, index_to_take);
+ string_copyn(buffer, file->path, MAX_INPUT_LENGTH);
+ }
+
+ for (s32 i = 0; i < files.length; i++)
+ {
+ found_file *match = array_at(&files, i);
+ mem_free(match->matched_filter);
+ mem_free(match->path);
+ }
+ array_destroy(&files);
+}
+
+void *platform_list_files_thread(void *args)
+{
+ list_file_args *info = args;
+
+ array filters = string_split(info->pattern);
+ platform_list_files_block(info->list, info->start_dir, filters, info->recursive, info->bucket, info->include_directories, info->is_cancelled, info->info);
+
+ mutex_lock(&info->list->mutex);
+ *(info->state) = true;
+ mutex_unlock(&info->list->mutex);
+
+ array_destroy(&filters);
+
+ return 0;
+}
+
+void platform_list_files(array *list, char *start_dir, char *filter, bool recursive, memory_bucket *bucket, bool *is_cancelled, bool *state, search_info *info)
+{
+ list_file_args *args = memory_bucket_reserve(bucket, sizeof(list_file_args));
+ args->list = list;
+ args->start_dir = start_dir;
+ args->pattern = filter;
+ args->recursive = recursive;
+ args->state = state;
+ args->include_directories = 0;
+ args->bucket = bucket;
+ args->is_cancelled = is_cancelled;
+ args->info = info;
+
+ thread thr = thread_start(platform_list_files_thread, args);
+ thread_detach(&thr);
+}
+
+void platform_open_file_dialog(file_dialog_type type, char *buffer, char *file_filter, char *start_path, char *save_file_extension)
+{
+ open_dialog_args *args = mem_alloc(sizeof(open_dialog_args));
+ args->buffer = buffer;
+ args->type = type;
+ args->file_filter = file_filter;
+ args->start_path = start_path;
+ args->default_save_file_extension = save_file_extension;
+
+ thread thr;
+ thr.valid = false;
+
+ while (!thr.valid)
+ thr = thread_start(platform_open_file_dialog_block, args);
+ thread_detach(&thr);
+}
+
+void destroy_found_file_array(array *found_files)
+{
+ for (s32 i = 0; i < found_files->length; i++)
+ {
+ found_file *f = array_at(found_files, i);
+ mem_free(f->matched_filter);
+ mem_free(f->path);
+ }
+ array_destroy(found_files);
+}
+
+char *platform_get_file_extension(char *path)
+{
+ while(*path != '.' && *path)
+ {
+ path++;
+ }
+ return path;
+}
+
+s32 platform_filter_matches(array *filters, char *string, char **matched_filter)
+{
+ for (s32 i = 0; i < filters->length; i++)
+ {
+ char *filter = array_at(filters, i);
+ if (string_match(filter, string))
+ {
+ *matched_filter = filter;
+ return strlen(filter);
+ }
+ }
+ return -1;
+}
+
+void _platform_destroy_shared()
+{
+ _settings_destroy();
+ localization_destroy();
+ ui_destroy();
+ assets_destroy();
+}
+
+void _platform_init_shared(int argc, char **argv, char* config_path)
+{
+ _lib_loader_init();
+
+ // SDL2 audio.
+ {
+ if (SDL_Init(SDL_INIT_AUDIO) < 0) {
+ log_info("Audio setup failed.");
+ }
+ if (Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 512) < 0) {
+ log_info("Failed to open audio mixer.");
+ }
+ if (Mix_AllocateChannels(NUM_AUDIO_CHANNELS) < 0) {
+ log_info("Failed to allocate audio channels.");
+ }
+ log_info("Done setting up audio.");
+ }
+
+ // get fullpath of the directory the exe is residing in
+ binary_path = platform_get_full_path(argv[0]);
+
+ char buf[MAX_PATH_LENGTH];
+ platform_get_directory_from_path(buf, binary_path);
+ string_copyn(binary_path, buf, MAX_INPUT_LENGTH);
+
+ assets_create();
+ for (s32 i = 0; i < ASSET_WORKER_COUNT; i++) {
+ thread asset_queue_worker_thread = thread_start(_assets_queue_worker, NULL);
+ thread_detach(&asset_queue_worker_thread);
+ }
+
+ ui_init(assets_load_font(mono_ttf, mono_ttf+mono_ttf_len, 16));
+ localization_init();
+
+ _settings_init(config_path);
+ set_render_driver(DRIVER_GL); // Default to GL, settings_get_number_or_default("USE_GPU", 1);
+}
+
+u64 __last_stamp = 0;
+bool platform_keep_running(platform_window *window)
+{
+ __last_stamp = platform_get_time(TIME_FULL, TIME_US);
+
+ return window->is_open;
+}
+
+void _platform_register_window(platform_window* window) {
+ if (!array_exists(&window_registry)) {
+ window_registry = array_create(sizeof(platform_window*));
+ array_reserve(&window_registry, 10);
+ }
+
+ array_push(&window_registry, (uint8_t*)&window);
+}
+
+void _platform_unregister_window(platform_window* window) {
+ array_remove_by(&window_registry, (uint8_t*)&window);
+}
+
+void _switch_render_method(bool use_gpu)
+{
+ set_render_driver(use_gpu ? DRIVER_GL : DRIVER_CPU);
+
+ for (s32 i = 0; i < window_registry.length; i++) {
+ platform_window* w = *(platform_window**)array_at(&window_registry, i);
+ platform_setup_backbuffer(w);
+ }
+ platform_setup_renderer();
+ _assets_switch_render_method();
+}
+
+void platform_handle_events()
+{
+ __last_stamp = platform_get_time(TIME_FULL, TIME_NS);
+
+ bool _use_gpu = settings_get_number_or_default("USE_GPU", 1);
+
+ // USE_GPU setting changed..
+ if (current_render_driver() != (_use_gpu ? DRIVER_GL : DRIVER_CPU)) {
+ _switch_render_method(_use_gpu);
+ }
+
+ bool redraw_all = false;
+
+ if (assets_do_post_process())
+ redraw_all = true;
+
+ for (s32 i = 0; i < window_registry.length; i++) {
+ platform_window* w = *(platform_window**)array_at(&window_registry, i);
+
+ _global_keyboard = w->keyboard;
+ _global_mouse = w->mouse;
+ _global_camera = w->camera;
+
+ if (redraw_all) w->do_draw = true;
+
+ _platform_handle_events_for_window(w);
+
+ if (w->do_draw) {
+
+ platform_window_make_current(w);
+
+ u64 update_start = platform_get_time(TIME_FULL, TIME_NS);
+
+ platform_set_cursor(w, CURSOR_DEFAULT);
+ renderer->render_clear(w, rgb(255,255,255));
+ _camera_apply_transformations(w, &_global_camera);
+ renderer->render_reset_scissor();
+
+ w->update_func(w);
+ if (i == 0) update_render_notifications();
+
+ // Update delta.
+ {
+ u64 current_stamp = platform_get_time(TIME_FULL, TIME_NS);
+ u64 diff = current_stamp - update_start;
+ float diff_ms = diff / 1000000000.0f;
+ update_delta = diff_ms;
+ }
+
+ if (current_render_driver() == DRIVER_GL) IMP_glFinish();
+ platform_window_swap_buffers(w);
+ }
+
+ w->keyboard = _global_keyboard;
+ w->mouse = _global_mouse;
+ w->camera = _global_camera;
+
+ if (!w->is_open) {
+ platform_destroy_window(w);
+ }
+ }
+
+#if 1
+ {
+ u64 current_stamp = platform_get_time(TIME_FULL, TIME_NS);
+ u64 diff = current_stamp - __last_stamp;
+ float diff_ms = diff / 1000000000.0f;
+ frame_delta = diff_ms;
+ }
+
+ #if 0
+ if (diff_ms < TARGET_FRAMERATE)
+ {
+ double time_to_wait = (TARGET_FRAMERATE) - diff_ms;
+ // printf("sleeping for %f, fps: %f\n", time_to_wait, 1000.0 / (double)diff_ms);
+ thread_sleep(time_to_wait*1000);
+ }
+ #endif
+#endif
+} \ No newline at end of file