began work on an in game editor
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 30 Jan 2022 23:54:17 +0000 (17:54 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 30 Jan 2022 23:54:17 +0000 (17:54 -0600)
src/build.onyx
src/entity/editor.onyx [new file with mode: 0644]
src/entity/manager.onyx
src/gfx/font.onyx
src/main.onyx
src/utils/vecmath.onyx

index 990b1f5387006f24c2276e105ca61f2520c5df3a..f80a96d27b4c78af51eeebe0ba146a2f38bbb29c 100644 (file)
@@ -15,6 +15,7 @@ DEBUG :: false
 
 #load "main"
 
+#load "entity/editor"
 #load "entity/manager"
 #load "entity/player"
 
diff --git a/src/entity/editor.onyx b/src/entity/editor.onyx
new file mode 100644 (file)
index 0000000..73d1b8e
--- /dev/null
@@ -0,0 +1,98 @@
+
+use package core
+use package opengles
+use package glfw3
+
+editor_shown := false;
+
+editor_init :: () {
+    editor_font = font_lookup(.{"./assets/fonts/calibri.ttf", 18});
+    selected_entity_id = Entity_Nothing;
+}
+
+editor_toggle :: () {
+    editor_shown = !editor_shown;
+    selected_entity_id = Entity_Nothing;
+    dragging = false;
+}
+
+editor_update :: (dt: f32) {
+    mx, my := mouse_get_position();
+    mouse_pos := Vector2.{ ~~mx, ~~my };
+
+    if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) {
+        selected_entity_id = Entity_Nothing;
+        for entity_manager.entities {
+            get_rect := entity_manager.entity_types[it.type].get_rect;
+            if get_rect == null_proc do continue;
+
+            if get_rect(it) |> Rect.contains(mouse_pos) {
+                selected_entity_id = it.id;
+                break;
+            }
+        }
+
+        dragging = selected_entity_id != Entity_Nothing;
+    }
+
+    if !is_button_down(GLFW_MOUSE_BUTTON_LEFT) {
+        dragging = false;        
+    }
+
+    // This will be replaced by a "tool" system
+    if dragging && selected_entity_id != Entity_Nothing {
+        dmx, dmy := mouse_get_delta();
+        selected_entity := entity_manager->get(selected_entity_id);
+        selected_entity.pos += Vector2.{~~dmx, ~~dmy};
+    }
+}
+
+editor_draw :: () {
+    entity_manager->draw();
+    immediate_flush();
+
+    if selected_entity_id != Entity_Nothing {
+        selected_entity := entity_manager->get(selected_entity_id);
+        get_rect := entity_manager.entity_types[selected_entity.type].get_rect;
+
+        r := get_rect(selected_entity);
+        immediate_set_color(.{1,1,0,0.5});
+        immediate_rectangle(r.x-2, r.y-2, r.w+4, r.h+4);
+        immediate_rectangle(r.x, r.y, r.w, r.h);
+    }
+
+    immediate_set_color(.{0.5, 0.5, 0.5, 0.7});
+
+    x0 := cast(f32) window_width * 0.25;
+    x1 := cast(f32) window_width * 0.75;
+    y0 := cast(f32) window_height * 0.25;
+    y1 := cast(f32) window_height * 0.75;
+
+    immediate_rectangle(x0, y0, x1 - x0, y1 - y0);
+
+    font_set_color(.{1,1,1});
+    y0 += 20;
+    font_print(editor_font, x0, y0, "Registered Entity types:");
+    y0 += 20;
+    for entity_manager.entity_types.entries {
+        defer y0 += 20;
+        info := cast(^type_info.Type_Info_Struct) type_info.get_type_info(it.key);
+        font_print(editor_font, x0, y0, "    {}\n", info.name);
+    }
+
+    if selected_entity_id != Entity_Nothing {
+        selected_entity := entity_manager->get(selected_entity_id);
+
+        switch_entity(selected_entity) {
+            entity_case(Player) { font_print(editor_font, x0, y0, "{*}", object); }
+            case #default { font_print(editor_font, x0, y0, "{*}", selected_entity); }
+        }
+    }
+}
+
+#local {
+    editor_font: Font;
+
+    selected_entity_id: Entity_ID;
+    dragging := false;
+}
index 02753c158384d7fe500cfc90313d790d32b51137..34e9c1522a59eaa2ffce32d3d557a7b06529960f 100644 (file)
@@ -72,7 +72,7 @@ entity_manager_create :: () -> Entity_Manager {
 entity_manager_register :: (use this: ^Entity_Manager, $entity_type: type_expr) where IsEntity(^entity_type) {
     if !entity_types->has(entity_type) {
 
-        { // Validate that the entity_type does not have any pointers.
+        #if DEBUG { // Validate that the entity_type does not have any pointers.
             use type_info;
 
             info := cast (^Type_Info_Struct) get_type_info(entity_type);
@@ -215,7 +215,7 @@ switch_entity :: macro (entity: ^Entity, body: Code) {
 
 entity_case :: macro (type: type_expr, body: Code) {
     case type {
-        object := cast(^type) it;
+        object := cast(^type) entity;
         #insert body;
     }
 }
index dd78b0446823be0416825c055ebe97755eb4ca15..06599da200b7d57b1936cc592a9e84005f001667 100644 (file)
@@ -121,6 +121,13 @@ font_print :: (font: Font, x, y: f32, format: str, va: ..any) {
 }
 
 font_draw :: (font: Font, x, y: f32, msg: str) {
+    // If this is being used in conjunction with the immediate
+    // rendering system, make sure the immediate objects are flushed
+    // before trying to render over them.
+    #if #defined(immediate_flush) {
+        immediate_flush();
+    }
+
     quads: ^stbtt_aligned_quad = alloc.from_stack(msg.count * sizeof stbtt_aligned_quad);
     quad_num := 0;
 
index 96510c0e5ec94771a38a16330ee183ea91bfe1b5..e4d55db44a5064e897dd1b32980287bd158fd9c5 100644 (file)
@@ -32,6 +32,7 @@ init :: () {
     shaders_init();
     fonts_init();
     immediate_init();
+    editor_init();
 
     glfwGetWindowSize(window, ^window_width, ^window_height);
     glViewport(0, 0, window_width, window_height);
@@ -59,7 +60,6 @@ init :: () {
     entity_manager->make(Item, .{ pos=.{ 275, 250 }, color=.{0,1,0} });
     entity_manager->make(Item, .{ pos=.{ 300, 250 }, color=.{0,0,1} });
     
-
     #if DEBUG {
         println("Registered Entity types:");
         for entity_manager.entity_types.entries {
@@ -78,15 +78,45 @@ update :: (dt: f32) {
         return;
     }
 
+    if is_key_just_up(GLFW_KEY_F7) {
+        editor_toggle();
+    }
+
+    if editor_shown {
+        editor_update(dt);
+        return;
+    }
+
     entity_manager->update(dt);
 }
 
 draw :: () {
     immediate_clear(.{0.1, 0.1, 0.1});
+    defer {
+        immediate_flush();
+        
+        #if DEBUG {
+            font_set_color(.{1,0,0});
+            font_print(debug_font, 0, 16, "FPS: {}", game_fps);
+            font_print(debug_font, 0, 32, "HEAP: {b16}", alloc.heap.get_watermark());
+            font_print(debug_font, 0, 48, "FREE: {}KB", alloc.heap.get_freed_size() / 1024);
+
+            version_buf : [32] u8;
+            version_str := conv.format(version_buf, "Version: {}.{}", runtime.vars.MAJOR_VERSION, runtime.vars.MINOR_VERSION);
+            font_print(debug_font, ~~window_width - font_get_width(debug_font, version_str), 16, version_str);
+        }
+
+        glfwSwapBuffers(window);
+    }
 
     update_world_matrix();
     update_model_matrix(.{0,0});
 
+    if editor_shown {
+        editor_draw();
+        return;
+    }
+
     entity_manager->draw();
 
     #if false {
@@ -94,21 +124,6 @@ draw :: () {
         immediate_set_color(.{1,1,1});
         immediate_rectangle(~~mx, ~~my, 10, 10);
     }
-
-    immediate_flush();
-
-    #if DEBUG {
-        font_set_color(.{1,0,0});
-        font_print(debug_font, 0, 16, "FPS: {}", game_fps);
-        font_print(debug_font, 0, 32, "HEAP: {b16}", alloc.heap.get_watermark());
-        font_print(debug_font, 0, 48, "FREE: {}KB", alloc.heap.get_freed_size() / 1024);
-
-        version_buf : [32] u8;
-        version_str := conv.format(version_buf, "Version: {}.{}", runtime.vars.MAJOR_VERSION, runtime.vars.MINOR_VERSION);
-        font_print(debug_font, ~~window_width - font_get_width(debug_font, version_str), 16, version_str);
-    }
-
-    glfwSwapBuffers(window);
 }
 
 #local {
index 70700edd659d71f489de68b120a951db9cb73c0f..32b24f1252dc4c3b604035bd090894be6e001655 100644 (file)
@@ -83,4 +83,9 @@ Rect :: struct {
             && r1.y <= r2.y + r2.h
             && r1.y + r1.h >= r2.y;
     }
+
+    contains :: (r: Rect, p: Vector2) -> bool {
+        return r.x <= p.x && r.x + r.w >= p.x
+            && r.y <= p.y && r.y + r.h >= p.y;
+    }
 }