diff --git a/build_file.c b/build_file.c index 30b85c7..0f53b5e 100644 --- a/build_file.c +++ b/build_file.c @@ -41,7 +41,7 @@ int main(int argc, char **argv) { ok = os_systemf( "cl ../src/core_test/core_test_entry.c -Fe:core_test.exe -Fd:core_test.pdb" " -I ../src" - " /Zi /FC /nologo /Oi" + " /Zi /FC /nologo /Oi /O2" " /WX /W3 /wd4200 /diagnostics:column" " /link /incremental:no" ); diff --git a/package/index.html b/package/index.html index b324d59..daa7a63 100644 --- a/package/index.html +++ b/package/index.html @@ -104,6 +104,9 @@ const mem = new memory_t(new WebAssembly['Memory']({ initial: 2000, maximum: 655 ctx2d.fillStyle = `rgba(${r}, ${g}, ${b}, ${a})`; ctx2d.fill(); }, + wasm_clear: () => { + ctx2d.clearRect(0, 0, canvas.width, canvas.height); + }, wasm_set_clip: (x, y, w, h) => { ctx2d.restore(); ctx2d.save(); @@ -115,6 +118,11 @@ const mem = new memory_t(new WebAssembly['Memory']({ initial: 2000, maximum: 655 return parseFloat(mem.read_cstr(str, len)); }, wasm_trap: () => { throw new Error() }, + wasm_alert: (str, len) => { + const string = mem.read_cstr(str,len); + console.log(string); + alert(string); + }, }; const program = await WebAssembly['instantiate'](binary, { "env": wasm_imports }); diff --git a/src/app/app_wasm.c b/src/app/app_wasm.c index 944f992..c24b951 100644 --- a/src/app/app_wasm.c +++ b/src/app/app_wasm.c @@ -2,8 +2,11 @@ #define fn_wasm_export __attribute__((visibility("default"))) #define fn_wasm_import +fn_wasm_import void wasm_alert(isize ptr, i32 len); fn_wasm_import f64 wasm_parse_float(isize str, i32 len); fn_wasm_import void wasm_write_to_console(isize str, i32 len); + +fn_wasm_import void wasm_clear(); fn_wasm_import void wasm_draw_text(isize str, i32 len, f64 x, f64 y, isize font_str, i32 font_len, i32 font_size, f32 r, f32 g, f32 b, f32 a); fn_wasm_import void wasm_draw_rect(f64 x, f64 y, f64 w, f64 h, f32 r, f32 g, f32 b, f32 a); fn_wasm_import f64 wasm_measure_text(isize str, i32 len, isize font_str, i32 font_len, i32 font_size); @@ -27,13 +30,16 @@ glb f64 wasm_last_time = 0; fn void app_update(ma_arena_t *perm_arena, app_event_t *events, i32 event_count); +fn void alert(s8_t string) { + wasm_alert((isize)string.str, (i32)string.len); +} fn void puts(const char *string) { wasm_write_to_console((isize)string, (i32)str_len((char *)string)); } fn double strtod(const char *str, char **end_unused) { - assertf(end_unused == NULL, "second parameter should be null!!"); + assert(end_unused == NULL); return wasm_parse_float((isize)str, str_len((char *)str)); } @@ -183,14 +189,17 @@ fn_wasm_export void wasm_key_up(char *key, b32 ctrl, b32 shift, b32 alt, b32 met fn_wasm_export void wasm_update(f64 time, f64 width, f64 height, f64 dpr) { f64 delta_time = (time - wasm_last_time); + v2f32_t window_size = (v2f32_t){width / dpr, height / dpr}; for (i32 i = 0; i < wasm_events.len; i += 1) { wasm_events.data[i].dpr = dpr; - wasm_events.data[i].window_size = (v2f32_t){width / dpr, height / dpr}; + wasm_events.data[i].window_size = window_size; wasm_events.data[i].time = time; wasm_events.data[i].delta_time = delta_time; } wasm_dpr = dpr; + wasm_clear(); + draw_rect(r2f64(0, 0, window_size.x, window_size.y), white_color_global); app_update(&wasm_perm_arena, wasm_events.data, wasm_events.len); wasm_events.len = 0; @@ -199,12 +208,24 @@ fn_wasm_export void wasm_update(f64 time, f64 width, f64 height, f64 dpr) { } fn_wasm_export void wasm_init(void) { - isize page_size = kib(64); - isize page_count = __builtin_wasm_memory_size(0); - u8 *memory = (u8 *)&__heap_base; - usize memory_size = page_count * (page_size) - (isize)memory; - wasm_perm_arena.data = memory; - wasm_perm_arena.commit = wasm_perm_arena.reserve = memory_size; + { + isize page_size = kib(64); + isize page_count = __builtin_wasm_memory_size(0); + u8 *memory = (u8 *)&__heap_base; + usize memory_size = page_count * (page_size) - (isize)memory; + wasm_perm_arena.data = memory; + wasm_perm_arena.commit = wasm_perm_arena.reserve = memory_size; + + // init core + { + ma_push_arena_ex(&wasm_perm_arena, &core_desc.scratch[0], mib(1)); + ma_push_arena_ex(&wasm_perm_arena, &core_desc.scratch[1], kib(256)); + ma_push_arena_ex(&wasm_perm_arena, &core_desc.scratch[2], kib(64)); + } + + debugf("on_init, __builtin_wasm_memory_size(0) = %d(%d)", page_count, memory_size); + } + wasm_input_text_arena = ma_push_arena(&wasm_perm_arena, kib(1)); - debugf("on_init, __builtin_wasm_memory_size(0) = %d(%d)", page_count, memory_size); + } \ No newline at end of file diff --git a/src/core/core.c b/src/core/core.c index 6283de3..c742fec 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -18,8 +18,9 @@ #endif #if PLATFORM_WASM -double strtod(const char *str, char **end_unused); -void puts(const char *str); +fn double strtod(const char *str, char **end_unused); +fn void puts(const char *str); +fn void alert(s8_t string); #endif #if PLATFORM_CL diff --git a/src/core/core_arena.c b/src/core/core_arena.c index cebd62e..a230244 100644 --- a/src/core/core_arena.c +++ b/src/core/core_arena.c @@ -83,6 +83,7 @@ fn void *ma_push_size_ex(ma_arena_t *arena, usize size) { } } if (new_len > arena->commit) { + invalid_codepath; return NULL; } } @@ -98,12 +99,16 @@ fn void *ma_push_size(ma_arena_t *arena, usize size) { return result; } -fn ma_arena_t *ma_push_arena(ma_arena_t *allocator, usize size) { - ma_arena_t *result = ma_push_type(allocator, ma_arena_t); +fn void ma_push_arena_ex(ma_arena_t *allocator, ma_arena_t *result, usize size) { result->data = (u8 *)ma_push_size(allocator, size); result->reserve = size; result->commit = size; result->align = ma_default_alignment; +} + +fn ma_arena_t *ma_push_arena(ma_arena_t *allocator, usize size) { + ma_arena_t *result = ma_push_type(allocator, ma_arena_t); + ma_push_arena_ex(allocator, result, size); return result; } @@ -151,7 +156,7 @@ fn ma_temp_t ma_begin_scratch_ex(ma_arena_t **conflicts, int conflict_count) { } } - assertf(unoccupied, "Failed to get free scratch memory, this is a fatal error, this shouldnt happen"); + assert(unoccupied); // failed to get free scratch memory, this is a fatal error, this shouldnt happen ma_temp_t result = ma_begin_temp(unoccupied); return result; } diff --git a/src/core/core_arena.h b/src/core/core_arena.h index bdd2227..f60faeb 100644 --- a/src/core/core_arena.h +++ b/src/core/core_arena.h @@ -26,9 +26,10 @@ fn void ma_destroy(ma_arena_t *arena); // // push -fn void *ma_push_size_ex(ma_arena_t *arena, usize size); fn void *ma_push_size(ma_arena_t *arena, usize size); +fn void *ma_push_size_ex(ma_arena_t *arena, usize size); fn ma_arena_t *ma_push_arena(ma_arena_t *allocator, usize size); +fn void ma_push_arena_ex(ma_arena_t *allocator, ma_arena_t *result, usize size); #define ma_push_type(arena, Type) (Type *)ma_push_size((arena), sizeof(Type)) #define ma_push_array(arena, Type, count) (Type *)ma_push_size((arena), sizeof(Type) * (count)) diff --git a/src/core/core_defines.h b/src/core/core_defines.h index 05db35e..82ef22f 100644 --- a/src/core/core_defines.h +++ b/src/core/core_defines.h @@ -46,6 +46,7 @@ typedef double f64; #ifndef offsetof #define offsetof(st, m) ((usize)&(((st *)0)->m)) #endif +#define expect(x) if (!(x)) #define kib(x) (1024ULL * (x##ULL)) #define mib(x) (1024ULL * kib(x)) diff --git a/src/core/core_intrin.c b/src/core/core_intrin.c index c554f98..c59cbdf 100644 --- a/src/core/core_intrin.c +++ b/src/core/core_intrin.c @@ -87,16 +87,6 @@ fn f64 f64_from_s8(s8_t string) { return result; } -fn void core_print_message(s8_t string) { - ma_temp_t scratch = ma_begin_scratch(); - s8_t copy = s8_printf(scratch.arena, "%S\n", string); -#if PLATFORM_WINDOWS - OutputDebugStringA(copy.str); -#endif - puts(copy.str); - ma_end_scratch(scratch); -} - fn date_t date_now(void) { date_t result = {0}; #if PLATFORM_WASM @@ -121,4 +111,4 @@ fn date_t date_now(void) { result.year = lt->tm_year; #endif return result; -} \ No newline at end of file +} diff --git a/src/core/core_intrin.h b/src/core/core_intrin.h index 6fcb752..f6be258 100644 --- a/src/core/core_intrin.h +++ b/src/core/core_intrin.h @@ -35,6 +35,6 @@ THREAD_LOCAL core_desc_t core_desc = { .log = { .break_on_fatal = true, .log_proc = default_log_proc, - .flags = log_flag_all, + .flags = 0, } }; diff --git a/src/core/core_log.c b/src/core/core_log.c index 8e6dbd8..9590f99 100644 --- a/src/core/core_log.c +++ b/src/core/core_log.c @@ -1,11 +1,11 @@ -fn s8_t log_level_str(log_level_t level) { +fn char *log_level_str(log_level_t level) { switch(level) { - case log_level_debug: return s8_lit("DEBUG"); - case log_level_info: return s8_lit("INFO"); - case log_level_warning: return s8_lit("WARN"); - case log_level_error: return s8_lit("ERROR"); - case log_level_fatal: return s8_lit("FATAL"); - default: return s8_lit("INVALID"); + case log_level_debug: return "DEBUG"; + case log_level_info: return "INFO"; + case log_level_warning: return "WARN"; + case log_level_error: return "ERROR"; + case log_level_fatal: return "FATAL"; + default: return "INVALID"; } } @@ -20,6 +20,17 @@ fn void log_basef(i32 module, log_level_t level, s8_t file_and_line, const char ma_end_scratch(scratch); } +fn void core_error_message(char *str) { +#if PLATFORM_WINDOWS + MessageBoxA(NULL, str, "fatal error", MB_OK); + fprintf(stderr, "%s", str); +#elif PLATFORM_WASM + alert(s8_from_char(str)); +#else + fprintf(stderr, "%s", str); +#endif +} + fn void default_log_proc(log_event_t ev) { ma_temp_t scratch = ma_begin_scratch(); sb8_t *sb = sb8_serial_begin(scratch.arena); @@ -27,7 +38,7 @@ fn void default_log_proc(log_event_t ev) { sb8_printf(sb, "[%d] ", ev.module); } if (core_desc.log.flags & log_flag_level) { - sb8_printf(sb, "%-5S ", log_level_str(ev.level)); + sb8_printf(sb, "%-5s ", log_level_str(ev.level)); } date_t date = {0}; { @@ -47,23 +58,25 @@ fn void default_log_proc(log_event_t ev) { sb8_printf(sb, "%-40S ", ev.file_and_line); } - sb8_printf(sb, " %S", ev.string); + sb8_printf(sb, " %S\n", ev.string); s8_t result = sb8_serial_end(sb); - core_print_message(result); - ma_end_scratch(scratch); - if (ev.level == log_level_fatal) { - if (core_desc.log.break_on_fatal) { -#if PLATFORM_WINDOWS - if (IsDebuggerPresent()) -#endif + if (ev.level != log_level_fatal) { + IF_PLATFORM_WINDOWS(OutputDebugStringA(result.str);) + puts(result.str); + } else { + core_error_message(result.str); + #if PLATFORM_WASM debug_break(); - } else { - SWITCH_PLATFORM_WINDOWS_WASM_ELSE( - ExitProcess(1), - debug_break(), - exit(1) - ); - } + #else + if (core_desc.log.break_on_fatal) { + debug_break(); + } else { + exit(1); + } + #endif } + + ma_end_scratch(scratch); } + diff --git a/src/core/core_log.h b/src/core/core_log.h index 6e1f0f9..a73e224 100644 --- a/src/core/core_log.h +++ b/src/core/core_log.h @@ -52,23 +52,27 @@ struct logger_t { b32 break_on_fatal; }; -fn void log_base(i32 module, log_level_t level, s8_t file_and_line, s8_t string); -fn void log_basef(i32 module, log_level_t level, s8_t file_and_line, const char *str, ...); -fn s8_t log_level_str(log_level_t level); - +/////////////////////////////// +// main api #define debugf(...) log_basef(module_null, log_level_debug, S8_FILE_AND_LINE, __VA_ARGS__) #define errorf(MODULE, ...) log_basef(MODULE, log_level_error, S8_FILE_AND_LINE, __VA_ARGS__) #define fatalf(...) (log_basef(module_null, log_level_fatal, S8_FILE_AND_LINE, __VA_ARGS__), 0) -#define assert(x) (!(x) && fatalf("condition doesn't hold: " #x)) -#define assertf(x, ...) (!(x) && fatalf("condition doesn't hold: " __VA_ARGS__)) - -#if PLATFORM_CL -#define debug__break() __debugbreak() +fn void core_error_message(char *str); +#define program_version "---" +#if PLATFORM_DEBUG_ASSERT +#define assert(x) (!(x) && (core_error_message(FILE_AND_LINE ": internal program error! assertion failed, program version: " program_version), debug_break())) #else -#define debug__break() __builtin_trap() +#define assert(x) (void)(x) #endif -#define debug_break() (debug__break(), 0) +#define not_implemented assert(!"not implemented!") +#define invalid_codepath assert(!"invalid code path!") + + + +fn void log_base(i32 module, log_level_t level, s8_t file_and_line, s8_t string); +fn void log_basef(i32 module, log_level_t level, s8_t file_and_line, const char *str, ...); + /* diff --git a/src/core/core_platform_defines.h b/src/core/core_platform_defines.h index c5d0128..fa41dca 100644 --- a/src/core/core_platform_defines.h +++ b/src/core/core_platform_defines.h @@ -64,6 +64,10 @@ #define PLATFORM_ADDRESS_SANITIZER 0 #endif +#ifndef PLATFORM_DEBUG_ASSERT +#define PLATFORM_DEBUG_ASSERT 1 +#endif + #if PLATFORM_WINDOWS #define SWITCH_PLATFORM_WINDOWS_WASM_ELSE(WINDOWS, WASM, ELSE) WINDOWS #elif PLATFORM_WASM @@ -72,7 +76,19 @@ #define SWITCH_PLATFORM_WINDOWS_WASM_ELSE(WINDOWS, WASM, ELSE) ELSE #endif - #if PLATFORM_CL #pragma warning(disable: 4116) #endif + +#if PLATFORM_CL +#define debug__break() __debugbreak() +#else +#define debug__break() __builtin_trap() +#endif +#define debug_break() (debug__break(), 0) + +#if PLATFORM_WINDOWS +#define IF_PLATFORM_WINDOWS(x) x +#else +#define IF_PLATFORM_WINDOWS(x) +#endif \ No newline at end of file diff --git a/src/core/core_string.c b/src/core/core_string.c index e4e8a21..fd3ca64 100644 --- a/src/core/core_string.c +++ b/src/core/core_string.c @@ -69,8 +69,8 @@ fn s8_t s8_from_char(char *string) { fn s16_t s16_from_s8(ma_arena_t *ma, s8_t string) { u16 *buffer = ma_push_array(ma, u16, string.len + 1); i64 len = wstr_from_str(buffer, string.len + 1, string.str, string.len); - assert(len < string.len); - return (s16_t){buffer,len}; + assert(len <= string.len); // @todo: verify + return (s16_t){buffer, len}; } fn s8_t s8_from_s16(ma_arena_t *ma, s16_t string) { @@ -78,18 +78,15 @@ fn s8_t s8_from_s16(ma_arena_t *ma, s16_t string) { char *buffer = ma_push_array(ma, char, buffer_size); i64 len = str_from_wstr(buffer, buffer_size, string.str, string.len); assert(len < buffer_size); - return (s8_t){buffer,len}; + return (s8_t){buffer, len}; } fn s8_t s8_copy(ma_arena_t *ma, s8_t string) { char *copy = (char *)ma_push_size(ma, sizeof(char) * (string.len + 1)); - if (copy) { - memory_copy(copy, string.str, string.len); - copy[string.len] = 0; - s8_t result = s8(copy, string.len); - return result; - } - return (s8_t){0}; + memory_copy(copy, string.str, string.len); + copy[string.len] = 0; + s8_t result = s8(copy, string.len); + return result; } s8_t s8_copy_char(ma_arena_t *ma, char *s) { @@ -207,8 +204,8 @@ s8_t s8_skip_past(s8_t string, s8_t a) { fn s8_t s8_slice(s8_t string, int64_t first_index, int64_t one_past_last_index) { if (one_past_last_index < 0) one_past_last_index = string.len + one_past_last_index + 1; if (first_index < 0) first_index = string.len + first_index; - assert(first_index < one_past_last_index && "s8_slice, first_index is bigger then one_past_last_index"); - assert(string.len > 0 && "Slicing string of length 0! Might be an error!"); + assert(first_index < one_past_last_index); + assert(string.len > 0); s8_t result = string; if (string.len > 0) { if (one_past_last_index > first_index) { @@ -476,10 +473,7 @@ fn u64 u64_from_s8(s8_t s, u64 base) { u64 acc = 0; for (i64 i = 0; i < s.len; i++) { u64 num = u64_from_hexchar(s.str[i]); - if (num >= base) { - fatalf("failed to convert string into number, didn't expect: %c", s.str[i]); - break; - } + assert(num < base); acc *= base; acc += num; } diff --git a/src/core/core_type_info.c b/src/core/core_type_info.c index 810b394..c52a2f3 100644 --- a/src/core/core_type_info.c +++ b/src/core/core_type_info.c @@ -368,7 +368,8 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t * lex_t *ident = parser_expect(par, lex_kind_ident); parser_expect(par, lex_kind_colon); - assert(s8_equal(ident->string, mem->name)); + + expect (s8_equal(ident->string, mem->name)) fatalf("expected identifier: %S, got instead %S", mem->name, ident->string); ti__deserial_data_ex(arena, par, mem_p, mem->type); parser_expect(par, lex_kind_comma); diff --git a/src/wasm_app/main.c b/src/wasm_app/main.c index 9acde2d..b639875 100644 --- a/src/wasm_app/main.c +++ b/src/wasm_app/main.c @@ -5,25 +5,24 @@ // #include "debug.c" // #include "ui2.c" -ma_arena_t *frame_arena; - +f64 delta_time; void app_update(ma_arena_t *perm_arena, app_event_t *events, i32 event_count) { - if (frame_arena == NULL) { - frame_arena = ma_push_arena(perm_arena, kib(32)); - } + if (event_count) delta_time = events[0].delta_time; + draw_textf(v2f64(0,0), "delta time: %f", delta_time); - f64 pos = 0.0; - f64 offset = get_font_height() + 8; - for (i32 i = 0; i < event_count; i += 1) { - s8_t string = ti_serial_data(frame_arena, events + i, app_event_t); - sb8_t split = s8_split(frame_arena, string, s8_lit("\n"), s8_split_none); + ma_scratch_scope(temp) { + f64 offset = get_font_height() + 8; + f64 pos = offset; + for (i32 i = 0; i < event_count; i += 1) { + s8_t string = ti_serial_data(temp.arena, events + i, app_event_t); + sb8_t split = s8_split(temp.arena, string, s8_lit("\n"), s8_split_none); - for (sb8_node_t *it = split.first; it; it = it->next) { - draw_text((v2f64_t){0, pos}, white_color_global, it->string); + for (sb8_node_t *it = split.first; it; it = it->next) { + draw_text((v2f64_t){0, pos}, black_color_global, it->string); - pos += offset; + pos += offset; + } } } - ma_set0(frame_arena); } diff --git a/todo.txt b/todo.txt index 086f289..086ff7e 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,7 @@ [ ] platform [ ] app [ ] wasm + [x] exit function: maybe using alert [ ] win32 [ ] hot reload / plugins [ ] linux @@ -13,7 +14,7 @@ [ ] revisit api [ ] core - [ ] revisit api + [x] revisit api [ ] s8_bin [ ] bin_write_begin - serialize binary data (sb8_bin_write?) bin_write_end