aboutsummaryrefslogtreecommitdiff
path: root/src/main.jai
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.jai')
-rw-r--r--src/main.jai207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/main.jai b/src/main.jai
new file mode 100644
index 0000000..897cfb7
--- /dev/null
+++ b/src/main.jai
@@ -0,0 +1,207 @@
+#import "Basic";
+#import "Window_Creation";
+Simp :: #import "Simp";
+Input :: #import "Input";
+Unicode :: #import "Unicode";
+
+#load "widget_interface.jai";
+#load "menu_app.jai";
+#load "apps/example_app.jai";
+#load "apps/maze_app.jai";
+#load "ui_panel.jai";
+#load "debug_overlay.jai";
+
+// Global reference to active app state
+active_app: *Widget_State;
+
+// The different apps available
+menu_state: Widget_State;
+example_state: Widget_State;
+maze_state: Widget_State;
+
+window: Window_Type;
+window_width : s32 = 1920;
+window_height : s32 = 1080;
+
+// silly
+FRAMES :: 32_768;
+frame_times : [FRAMES] float;
+frame_times_sum: float;
+frame_times_cursor: int;
+
+FONT_HEIGHT :: 32;
+
+switch_app :: (new_app: *Widget_State) {
+ active_app = new_app;
+}
+
+
+main :: () {
+ window = create_window(window_width, window_height, "Jai Sandbox");
+ Simp.set_render_target(window);
+ // Initialize all apps
+ init_menu_app(*menu_state);
+ init_example_widget(*example_state);
+ init_maze_app(*maze_state);
+
+ text_edit: [..] u8;
+ held_keys: String_Builder;
+
+ if menu_state.init then menu_state.init(*menu_state);
+ if example_state.init then example_state.init(*example_state);
+ if maze_state.init then maze_state.init(*maze_state);
+
+ the_font := (cast(*Menu_Data) menu_state.data).font;
+ active_app = *menu_state;
+
+ quit := false;
+ last_time := seconds_since_init();
+
+ sub_frames := false;
+
+ while !quit {
+ // FIXME lazy FPS cap
+ sleep_milliseconds(10);
+
+ Input.update_window_events();
+
+ for Input.get_window_resizes() {
+ Simp.update_window(it.window);
+ if it.window == window {
+
+ window_width = it.width;
+ window_height = it.height;
+ }
+ }
+
+ for Input.events_this_frame {
+ if it.type == {
+ case .QUIT;
+ quit = true;
+
+ case .KEYBOARD;
+ if it.key_pressed == 0 continue;
+
+ // If escape is pressed, toggle back to menu
+ if it.key_code == .ESCAPE {
+ if active_app != *menu_state {
+ switch_app(*menu_state);
+ } else {
+ quit = true; // Escape on menu quits
+ }
+ }
+
+ if it.key_pressed && it.key_code == .BACKSPACE {
+ // @FixMe this works fine for English characters since most of that character set
+ // is one-byte in UTF8, but will not work correctly for many other language characters.
+ if text_edit.count then pop(*text_edit);
+ }
+
+ case .TEXT_INPUT;
+ value := it.utf32;
+
+ str := Unicode.character_utf32_to_utf8(value);
+ for 0..str.count-1 {
+ array_add(*text_edit, str[it]);
+ }
+ free(str);
+ }
+ }
+
+ for Input.input_button_states {
+ if it & .DOWN {
+ if it_index >= 0x20 && it_index < 0x7F {
+ value: u8 = cast(u8) it_index;
+ str: string;
+ str.data = *value;
+ str.count = 1;
+ append(*held_keys, str);
+ } else {
+ print_to_builder(*held_keys, "% ", cast(Input.Key_Code) it_index);
+ }
+ }
+ }
+
+ held_keys_text := builder_to_string(*held_keys);
+ defer free(held_keys_text);
+
+ now := seconds_since_init();
+ dt := cast(float)(now - last_time);
+ last_time = now;
+
+ if sub_frames {
+ frame_times_sum -= frame_times[frame_times_cursor];
+ }
+ frame_times_sum += dt;
+ frame_times[frame_times_cursor] = dt;
+ frame_times_cursor += 1;
+
+ if frame_times_cursor >= FRAMES {
+ sub_frames = true;
+ frame_times_cursor = 0;
+ }
+
+ fps := 0.0;
+ if sub_frames {
+ fps = FRAMES / frame_times_sum;
+ } else {
+ fps = frame_times_cursor / frame_times_sum;
+ }
+
+ text_edit_text: string;
+ text_edit_text.data = text_edit.data;
+ text_edit_text.count = text_edit.count;
+
+ // Update active app
+ if active_app && active_app.update {
+ active_app.update(active_app, dt);
+ }
+
+ ui_occludes := ui_handle_input(active_app);
+ debug_add_value("UI occludes: %", ui_occludes);
+ active_app.handle_input(active_app, ui_occludes);
+
+ // Render active app
+ if active_app && active_app.render {
+ active_app.render(active_app);
+ }
+
+ mouse_x, mouse_y, _ := get_mouse_pointer_position(window, true);
+
+ // overlay
+ debug_add_value("FPS: %", fps);
+ debug_add_value("frame_times_sum: %", frame_times_sum);
+ debug_add_value("frame_times_cursor: %", frame_times_cursor);
+ debug_add_value("Window Size: %, %", window_width, window_height);
+ debug_add_value("Text Input: %", text_edit_text);
+ debug_add_value("Held keys: %", held_keys_text);
+ debug_add_value("mouse_pos: %, %", mouse_x, mouse_y);
+
+ // Set up debug overlay elements
+ render_debug_overlay(the_font);
+
+ // Render global UI panels (on top of active app)
+ ui_render(active_app);
+ clear_debug_overlay();
+
+ finish_frame();
+ }
+
+ if menu_state.shutdown then menu_state.shutdown(*menu_state);
+ if example_state.shutdown then example_state.shutdown(*example_state);
+}
+
+draw_text :: (font: *Simp.Dynamic_Font, color: Vector4, x: int, y: int, fmt: string, args: .. Any) {
+ assert(font != null);
+ builder: String_Builder;
+
+ print_to_builder(*builder, fmt, ..args);
+ text := builder_to_string(*builder);
+ defer free(text);
+
+ Simp.draw_text(font, x, y, text, color);
+}
+
+finish_frame :: () {
+ Simp.swap_buffers(window);
+}