diff options
| author | Aldrik Ramaekers <aldrikboy@gmail.com> | 2024-11-23 22:33:43 +0100 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrikboy@gmail.com> | 2024-11-23 22:33:43 +0100 |
| commit | b1e857cf1471d1871a9396696b22fa531da98249 (patch) | |
| tree | 3923008a8653057698cb339faf6dcfa92e18364b /project-base/src/platform_shared.c | |
| parent | 106bb7fcadf637cec883648916cc8d19529d6199 (diff) | |
add projbase to repo
Diffstat (limited to 'project-base/src/platform_shared.c')
| -rw-r--r-- | project-base/src/platform_shared.c | 364 |
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 |
