diff --git a/src/app.c b/src/app.c index f9ef1d36..b9c1315c 100644 --- a/src/app.c +++ b/src/app.c @@ -126,7 +126,7 @@ void app_register_exit_callback(app_exit_callback_func *func) * Entry point * ========================== */ -void app_entry_point(void) +void app_entry_point(struct string args_str) { struct temp_arena scratch = scratch_begin_no_conflict(); @@ -163,6 +163,7 @@ void app_entry_point(void) logf_info("Start of logs"); arena_temp_end(temp); } + logf_info("App started with args: \"%F\"", FMT_STR(args_str)); /* Create window */ struct sys_window window = sys_window_alloc(); @@ -223,7 +224,7 @@ void app_entry_point(void) struct sound_startup_receipt sound_sr = sound_startup(&work_sr, &asset_cache_sr, &resource_sr); struct draw_startup_receipt draw_sr = draw_startup(&renderer_sr, &font_sr); struct phys_startup_receipt phys_sr = phys_startup(); - struct user_startup_receipt user_sr = user_startup(&work_sr, &renderer_sr, &font_sr, &sprite_sr, &draw_sr, &asset_cache_sr, &sound_sr, &mixer_sr, &phys_sr, &host_sr, &window); + struct user_startup_receipt user_sr = user_startup(&work_sr, &renderer_sr, &font_sr, &sprite_sr, &draw_sr, &asset_cache_sr, &sound_sr, &mixer_sr, &phys_sr, &host_sr, args_str, &window); struct playback_startup_receipt playback_sr = playback_startup(&mixer_sr); (UNUSED)user_sr; diff --git a/src/app.h b/src/app.h index 8a74aae6..881e1483 100644 --- a/src/app.h +++ b/src/app.h @@ -22,7 +22,7 @@ struct string app_write_path_cat(struct arena *arena, struct string filename); /* Register a function that will be called when the application exits */ void app_register_exit_callback(app_exit_callback_func *func); -void app_entry_point(void); +void app_entry_point(struct string args); void app_exit(void); diff --git a/src/host.c b/src/host.c index 6cb545a8..3a9ad55d 100644 --- a/src/host.c +++ b/src/host.c @@ -1021,6 +1021,7 @@ INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(host_receiver_thread_entry_point, arg) socks.socks = &host->sock; socks.count = 1; + /* FIXME: Shutdown signal */ volatile b32 run = true; while (run) { struct sock *sock = sock_wait_for_available_read(socks, NULL, F32_INFINITY); diff --git a/src/renderer_d3d11.c b/src/renderer_d3d11.c index 77405a9b..6ac1ac11 100644 --- a/src/renderer_d3d11.c +++ b/src/renderer_d3d11.c @@ -199,7 +199,7 @@ INTERNAL void process_shader_compilation_error(ID3DBlob *error_blob) struct string error_prefix = string_copy(scratch.arena, LIT("Failed to compile shader:\n")); if (error_blob) { char *compile_error_cstr = (char *)ID3D10Blob_GetBufferPointer(error_blob); - struct string error_msg = string_cat(scratch.arena, error_prefix, string_from_cstr(compile_error_cstr)); + struct string error_msg = string_cat(scratch.arena, error_prefix, string_from_cstr_no_limit(compile_error_cstr)); sys_panic(error_msg); } scratch_end(scratch); @@ -241,7 +241,7 @@ INTERNAL void shader_init(struct dx11_shader *shader, enum shader_kind kind) struct temp_arena scratch = scratch_begin_no_conflict(); const struct dx11_shader_desc *shader_desc = &G.shader_info[kind]; - struct string name = string_from_cstr(shader_desc->name_cstr); + struct string name = string_from_cstr_no_limit(shader_desc->name_cstr); shader->kind = kind; shader->vertex_size = shader_desc->vertex_size; diff --git a/src/string.c b/src/string.c index 9a844b48..2ea09625 100644 --- a/src/string.c +++ b/src/string.c @@ -642,12 +642,10 @@ struct string32 string32_from_string(struct arena *arena, struct string str8) } /* ========================== * - * Legacy strings + * C narrow strings * ========================== */ -/* C narrow strings */ - -u64 cstr_len(char *cstr) +u64 cstr_len_no_limit(char *cstr) { char *end = cstr; if (cstr) { @@ -658,7 +656,7 @@ u64 cstr_len(char *cstr) return end - cstr; } -u64 cstr_len_limit(char *cstr, u64 limit) +u64 cstr_len(char *cstr, u64 limit) { char *end = cstr; if (cstr) { @@ -691,31 +689,50 @@ char *cstr_buff_from_string(struct string dest_buff, struct string src) return (char *)dest_buff.text; } -struct string string_from_cstr(char *cstr) +struct string string_from_cstr_no_limit(char *cstr) { - u64 len = cstr_len(cstr); + u64 len = cstr_len_no_limit(cstr); return (struct string) { .len = len, .text = (u8 *)cstr }; } -struct string string_from_cstr_limit(char *cstr, u64 limit) +struct string string_from_cstr(char *cstr, u64 limit) { - u64 len = cstr_len_limit(cstr, limit); + u64 len = cstr_len(cstr, limit); return (struct string) { .text = (u8 *)cstr, .len = len }; } -/* C wide strings */ +/* ========================== * + * C wide strings + * ========================== */ -u64 wstr_len(wchar_t *wstr) +u64 wstr_len_no_limit(wchar_t *wstr) { wchar_t *end = wstr; - while (*end) { - ++end; + if (end) { + while (*end) { + ++end; + } + } + return end - wstr; +} + +u64 wstr_len(wchar_t *wstr, u64 limit) +{ + wchar_t *end = wstr; + if (wstr) { + for (u64 i = 0; i < limit; ++i) { + if (*end) { + ++end; + } else { + break; + } + } } return end - wstr; } @@ -734,17 +751,33 @@ wchar_t *wstr_from_string16(struct arena *arena, struct string16 src) return (wchar_t *)text; } -struct string string_from_wstr(struct arena *arena, wchar_t *wstr) +struct string string_from_wstr_no_limit(struct arena *arena, wchar_t *wstr) { - struct string16 str16 = string16_from_wstr(wstr); + struct string16 str16 = string16_from_wstr_no_limit(wstr); return string_from_string16(arena, str16); } -struct string16 string16_from_wstr(wchar_t *wstr) +struct string string_from_wstr(struct arena *arena, wchar_t *wstr, u64 limit) { - u64 len = wstr_len(wstr); + struct string16 str16 = string16_from_wstr(wstr, limit); + return string_from_string16(arena, str16); +} + +struct string16 string16_from_wstr_no_limit(wchar_t *wstr) +{ + u64 len = wstr_len_no_limit(wstr); return (struct string16) { .len = len, .text = (u16 *)wstr }; } + +struct string16 string16_from_wstr(wchar_t *wstr, u64 limit) +{ + u64 len = wstr_len(wstr, limit); + return (struct string16) + { + .len = len, + .text = (u16 *)wstr + }; +} diff --git a/src/string.h b/src/string.h index db1a7a66..8dfaa7ef 100644 --- a/src/string.h +++ b/src/string.h @@ -110,17 +110,20 @@ struct string32 string32_from_string(struct arena *arena, struct string str8); * Legacy strings * ========================== */ -u64 cstr_len(char *cstr); -u64 cstr_len_limit(char *cstr, u64 limit); +u64 cstr_len_no_limit(char *cstr); +u64 cstr_len(char *cstr, u64 limit); char *cstr_from_string(struct arena *arena, struct string src); char *cstr_buff_from_string(struct string dest_buff, struct string src); -struct string string_from_cstr(char *cstr); -struct string string_from_cstr_limit(char *cstr, u64 limit); +struct string string_from_cstr_no_limit(char *cstr); +struct string string_from_cstr(char *cstr, u64 limit); -u64 wstr_len(wchar_t *wstr); +u64 wstr_len_no_limit(wchar_t *wstr); +u64 wstr_len(wchar_t *wstr, u64 limit); wchar_t *wstr_from_string(struct arena *arena, struct string src); wchar_t *wstr_from_string16(struct arena *arena, struct string16 src); -struct string string_from_wstr(struct arena *arena, wchar_t *wstr); -struct string16 string16_from_wstr(wchar_t *wstr); +struct string string_from_wstr_no_limit(struct arena *arena, wchar_t *wstr); +struct string string_from_wstr(struct arena *arena, wchar_t *wstr, u64 limit); +struct string16 string16_from_wstr_no_limit(wchar_t *wstr); +struct string16 string16_from_wstr(wchar_t *wstr, u64 limit); #endif diff --git a/src/sys_win32.c b/src/sys_win32.c index 094e3504..6651e86e 100644 --- a/src/sys_win32.c +++ b/src/sys_win32.c @@ -105,6 +105,8 @@ GLOBAL struct { DWORD thread_tls_index; u32 main_thread_id; + wchar_t cmdline_args_wstr[8192]; + /* Panic */ struct atomic_i32 panicking; wchar_t panic_wstr[4096]; @@ -639,7 +641,7 @@ b32 sys_file_filter_next(struct arena *arena, struct sys_file_filter *filter) } if (found) { - struct string file_name = string_from_wstr(arena, find_file_data.cFileName); + struct string file_name = string_from_wstr_no_limit(arena, find_file_data.cFileName); if (string_eq(file_name, LIT(".")) || string_eq(file_name, LIT(".."))) { /* Skip initial '.' and '..' matches */ found = sys_file_filter_next(arena, filter); @@ -961,7 +963,7 @@ INTERNAL void win32_update_window_from_settings(struct win32_window *window, str { struct temp_arena scratch = scratch_begin_no_conflict(); - wchar_t *title_wstr = wstr_from_string(scratch.arena, string_from_cstr(settings->title)); + wchar_t *title_wstr = wstr_from_string(scratch.arena, string_from_cstr_no_limit(settings->title)); SetWindowTextW(hwnd, title_wstr); scratch_end(scratch); } @@ -1678,7 +1680,7 @@ INTERNAL DWORD WINAPI win32_thread_proc(LPVOID vt) win32_thread_set_tls(&tls); /* Set thread name */ - struct string thread_name = string_from_cstr(t->thread_name_cstr); + struct string thread_name = string_from_cstr_no_limit(t->thread_name_cstr); if (thread_name.len > 0) { /* FIXME: Don't use scratch arena here, to avoid scratch TLS being initialized for threads that don't need them otherwise */ struct temp_arena scratch = scratch_begin_no_conflict(); @@ -1833,7 +1835,7 @@ struct string sys_get_clipboard_text(struct arena *arena) HANDLE handle = GetClipboardData(CF_UNICODETEXT); if (handle) { u16 *src_wstr = (u16 *)GlobalLock(handle); - res = string_from_string16(arena, string16_from_wstr(src_wstr)); + res = string_from_string16(arena, string16_from_wstr_no_limit(src_wstr)); GlobalUnlock(handle); } CloseClipboard(); @@ -2018,19 +2020,26 @@ void sys_sleep(f64 seconds) * Entry point * ========================== */ -INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(app_thread_entry_point, arg) +INTERNAL SYS_THREAD_ENTRY_POINT_FUNC_DEF(win32_app_thread_entry_point, arg) { (UNUSED)arg; - app_entry_point(); + struct temp_arena scratch = scratch_begin_no_conflict(); + struct string cmdline_args = string_from_wstr(scratch.arena, G.cmdline_args_wstr, ARRAY_COUNT(G.cmdline_args_wstr)); + app_entry_point(cmdline_args); + scratch_end(scratch); } -int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, _In_ LPWSTR command_line, _In_ int show_code) +int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, _In_ LPWSTR cmdline_wstr, _In_ int show_code) { (UNUSED)instance; (UNUSED)prev_instance; - (UNUSED)command_line; + (UNUSED)cmdline_wstr; (UNUSED)show_code; + u64 cmdline_len = wstr_len(cmdline_wstr, ARRAY_COUNT(G.cmdline_args_wstr) - 1); + MEMCPY(G.cmdline_args_wstr, cmdline_wstr, cmdline_len * sizeof(*cmdline_wstr)); + G.cmdline_args_wstr[cmdline_len] = 0; + const wchar_t *error_msg = NULL; /* ========================== * @@ -2134,7 +2143,7 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, /* Call app thread and wait for return */ { /* Start app thread */ - struct sys_thread app_thread = sys_thread_alloc(&app_thread_entry_point, NULL, LIT("[P9] App thread")); + struct sys_thread app_thread = sys_thread_alloc(&win32_app_thread_entry_point, NULL, LIT("[P9] App thread")); /* Get app thread handle */ HANDLE app_thread_handle = 0; diff --git a/src/tar.c b/src/tar.c index 6e6c1d15..fa012650 100644 --- a/src/tar.c +++ b/src/tar.c @@ -111,7 +111,7 @@ struct tar_archive tar_parse(struct arena *arena, struct string data, struct str continue; } - struct string file_name_cstr = string_from_cstr((char *)header.file_name); + struct string file_name_cstr = string_from_cstr_no_limit((char *)header.file_name); if (file_name_cstr.len >= 2) { /* Chop off './' prefix */ file_name_cstr.len -= 2; diff --git a/src/user.c b/src/user.c index 7edbcde6..2d46364c 100644 --- a/src/user.c +++ b/src/user.c @@ -50,6 +50,7 @@ GLOBAL struct { struct sys_window *window; struct sim_ctx *sim_ctx; struct host *host; + struct string connect_address_str; /* Usage stats */ i64 last_second_reset_ns; @@ -153,6 +154,7 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, struct mixer_startup_receipt *mixer_sr, struct phys_startup_receipt *phys_sr, struct host_startup_receipt *host_sr, + struct string connect_address_str, struct sys_window *window) { (UNUSED)work_sr; @@ -183,7 +185,12 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, G.window = window; sys_window_register_event_callback(G.window, &window_event_callback); - G.sim_ctx = sim_ctx_alloc(sprite_sr, phys_sr, host_sr, 12345); + if (connect_address_str.len == 0) { + G.sim_ctx = sim_ctx_alloc(sprite_sr, phys_sr, host_sr, 12345); + G.connect_address_str = LIT("127.0.0.1:12345"); + } else { + G.connect_address_str = string_copy(&G.arena, connect_address_str); + } G.debug_draw = true; @@ -634,7 +641,7 @@ INTERNAL void user_update(void) static f64 last_try_connect = 0; f64 now = SECONDS_FROM_NS(sys_time_ns()); if (last_try_connect == 0 || (now - last_try_connect) > 0.1) { - struct sock_address connect_addr = sock_address_from_string(LIT("127.0.0.1:12345")); + struct sock_address connect_addr = sock_address_from_string(G.connect_address_str); host_queue_connect_to_address(G.host, connect_addr); last_try_connect = now; } @@ -687,12 +694,12 @@ INTERNAL void user_update(void) } if (event->kind == SYS_EVENT_KIND_BUTTON_UP) { - #if DEVELOPER +#if DEVELOPER /* Escape quit */ if (event->button == SYS_BTN_ESC) { app_exit(); } - #endif +#endif } /* Update mouse pos */ @@ -707,15 +714,15 @@ INTERNAL void user_update(void) enum user_bind_kind bind = g_binds[button]; if (bind) { b32 pressed = event->kind == SYS_EVENT_KIND_BUTTON_DOWN; - #if 0 +#if 0 b32 out_of_bounds = button >= SYS_BTN_M1 && button <= SYS_BTN_M5 && (G.ui_cursor.x < 0 || G.ui_cursor.y < 0 || G.ui_cursor.x > G.ui_size.x || G.ui_cursor.y > G.ui_size.y); - #else +#else b32 out_of_bounds = false; - #endif +#endif G.bind_states[bind].is_held = pressed && !out_of_bounds; if (pressed) { if (!out_of_bounds) { @@ -1112,7 +1119,7 @@ INTERNAL void user_update(void) draw_arrow_line(G.ui_cmd_buffer, start, end, 3, 10, RGBA_32_F(1, 1, 1, 0.5)); } - #if 0 +#if 0 /* Draw slices */ if (!sprite_tag_is_nil(ent->sprite)) { struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, sprite); @@ -1153,7 +1160,7 @@ INTERNAL void user_update(void) } } } - #endif +#endif /* Draw collider */ if (sim_ent_has_prop(ent, SIM_ENT_PROP_PHYSICAL_DYNAMIC)) { @@ -1182,14 +1189,14 @@ INTERNAL void user_update(void) end = xform_mul_v2(G.world_to_ui_xf, end); draw_line(G.ui_cmd_buffer, start, end, thickness, color); } - #if 0 +#if 0 /* Draw support point at focus dir */ { struct v2 p = collider_support_point(&collider, xf, ent->control.focus); p = xform_mul_v2(G.world_to_ui_xf, p); draw_circle(G.ui_cmd_buffer, p, 3, COLOR_RED, 10); } - #endif +#endif } /* Draw contact constraint */ @@ -1200,19 +1207,15 @@ INTERNAL void user_update(void) (UNUSED)e0; (UNUSED)e1; - #if 1 +#if 1 +#if DEVELOPER /* Draw contact points */ { f32 radius = 5; for (u32 i = 0; i < data->num_points; ++i) { struct phys_contact_point point = data->points[i]; - #if 0 - struct v2 p0 = xform_mul_v2(e0_xf, contact.point_local_e0); - struct v2 p1 = xform_mul_v2(e1_xf, contact.point_local_e1); - struct v2 point = v2_add(p0, v2_mul(v2_sub(p1, p0), 0.5f)); - #else struct v2 dbg_pt = point.dbg_pt; - #endif + /* Draw point */ { //u32 color = contact.persisted ? RGBA_32_F(1, 1, 0, 0.50) : RGBA_32_F(1, 0, 0, 0.50); @@ -1231,7 +1234,7 @@ INTERNAL void user_update(void) struct v2 end = xform_mul_v2(G.world_to_ui_xf, v2_add(dbg_pt, v2_mul(v2_norm(data->normal), len))); draw_arrow_line(G.ui_cmd_buffer, start, end, arrow_thickness, arrow_height, color); } - #if 0 +#if 0 /* Draw contact info */ { struct font *disp_font = font_load_async(LIT("res/fonts/fixedsys.ttf"), 12.0f); @@ -1262,13 +1265,14 @@ INTERNAL void user_update(void) draw_text(G.ui_cmd_buffer, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_ui_xf, dbg_pt)), V2(0, offset_px)), text); } } - #endif +#endif } } +#endif } /* Draw collision debug */ - #if COLLIDER_DEBUG +#if COLLIDER_DEBUG if (sim_ent_has_prop(ent, SIM_ENT_PROP_COLLISION_DEBUG)) { struct phys_collision_debug *data = &ent->collision_debug_data; struct collider_collision_points_result collider_res = data->res; @@ -1280,7 +1284,7 @@ INTERNAL void user_update(void) (UNUSED)e1_collider; /* Draw closest points */ - #if 0 +#if 0 { f32 radius = 4; u32 color = RGBA_32_F(1, 1, 0, 0.5); @@ -1289,7 +1293,7 @@ INTERNAL void user_update(void) draw_circle(G.ui_cmd_buffer, a, radius, color, 10); draw_circle(G.ui_cmd_buffer, b, radius, color, 10); } - #endif +#endif /* Draw clipping */ { @@ -1329,11 +1333,11 @@ INTERNAL void user_update(void) } } - #if COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI +#if COLLIDER_DEBUG_DETAILED_DRAW_MENKOWSKI struct xform e0_xf = data->xf0; struct xform e1_xf = data->xf1; - #if 0 +#if 0 /* Only draw points with large separation */ b32 should_draw = false; for (u32 i = 0; i < data->num_points; ++i) { @@ -1342,12 +1346,12 @@ INTERNAL void user_update(void) break; } } - #else +#else b32 should_draw = true; - #endif +#endif if (should_draw) { - #if 0 +#if 0 /* Test info */ { struct font *disp_font = font_load_async(LIT("res/fonts/fixedsys.ttf"), 12.0f); @@ -1369,7 +1373,7 @@ INTERNAL void user_update(void) draw_text(G.ui_cmd_buffer, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_ui_xf, V2(0, 0))), V2(0, offset_px)), text); } } - #endif +#endif /* Draw menkowski */ { @@ -1454,10 +1458,10 @@ INTERNAL void user_update(void) } } } - #endif +#endif } - #endif - #endif +#endif +#endif /* Draw hierarchy */ if (sim_ent_has_prop(parent, SIM_ENT_PROP_ACTIVE) && !parent->is_root) { diff --git a/src/user.h b/src/user.h index 6163c4b7..69240f22 100644 --- a/src/user.h +++ b/src/user.h @@ -60,6 +60,7 @@ struct user_startup_receipt user_startup(struct work_startup_receipt *work_sr, struct mixer_startup_receipt *mixer_sr, struct phys_startup_receipt *phys_sr, struct host_startup_receipt *host_sr, + struct string connect_address_str, struct sys_window *window); #endif