added logging system; added texture to items
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 22 Feb 2022 02:54:56 +0000 (20:54 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 22 Feb 2022 02:54:56 +0000 (20:54 -0600)
13 files changed:
run_tree/assets/images/beer-1.png [new file with mode: 0644]
run_tree/scenes/default.items
run_tree/scenes/quick_save.scene
src/build.onyx
src/entity/items.onyx
src/entity/manager.onyx
src/entity/player.onyx
src/entity/store.onyx
src/game.onyx
src/gfx/texture.onyx
src/main.onyx
src/utils/asset_loader.onyx
src/utils/logger.onyx [new file with mode: 0644]

diff --git a/run_tree/assets/images/beer-1.png b/run_tree/assets/images/beer-1.png
new file mode 100644 (file)
index 0000000..72a5ce1
Binary files /dev/null and b/run_tree/assets/images/beer-1.png differ
index f9d6bf488d3f9d3e8d3f8f325b64afbfd0abd1f2..99408993faee53282bdfe56b714a8bd0b0fef2e8 100644 (file)
@@ -1,5 +1,6 @@
 :beer
 name="Beer"
+texture_path="./assets/images/beer-1.png"
 weight=12.34
 
 
index 17de2c490f8e49e8c890b5e408de0f5d5de4bdc8..dfd385540cc4344a4cc46234cb4fd552b6da81e0 100644 (file)
@@ -1,11 +1,27 @@
+:Wall
+entity.id = 10
+entity.flags = 2
+entity.pos.x = 178.0000
+entity.pos.y = 312.0000
+entity.size.x = 355.0000
+entity.size.y = 28.0000
+
+:Wall
+entity.id = 11
+entity.flags = 2
+entity.pos.x = 447.0000
+entity.pos.y = 165.0000
+entity.size.x = 31.0000
+entity.size.y = 328.0000
+
 :Player
-entity.id = 1
+entity.id = 12
 entity.flags = 2
-entity.pos.x = 891.5230
-entity.pos.y = 279.3731
+entity.pos.x = 237.4579
+entity.pos.y = 133.2012
 entity.size.x = 32.0000
 entity.size.y = 32.0000
-holding = 4
+holding = 0
 controls.up = 87
 controls.down = 83
 controls.left = 65
@@ -13,92 +29,26 @@ controls.right = 68
 controls.interact = 70
 controls.pick_up = 71
 color.r = 1.0000
-color.g = 0.0000
+color.g = 1.0000
 color.b = 1.0000
 color.a = 1.0000
-facing = 3
-
-:Player
-entity.id = 2
-entity.flags = 2
-entity.pos.x = 328.9612
-entity.pos.y = 309.7936
-entity.size.x = 32.0000
-entity.size.y = 32.0000
-holding = 0
-controls.up = 265
-controls.down = 264
-controls.left = 263
-controls.right = 262
-controls.interact = 44
-controls.pick_up = 46
-color.r = 1.0000
-color.g = 0.0000
-color.b = 0.0000
-color.a = 1.0000
 facing = 4
 
 :Door
-entity.id = 3
+entity.id = 13
 entity.flags = 7
-entity.pos.x = 290.0374
-entity.pos.y = 211.0090
-entity.size.x = 370.0000
-entity.size.y = 24.0000
-target_openness = 0.8000
-
-:Item_Entity
-entity.id = 4
-entity.flags = 0
-entity.pos.x = 891.5230
-entity.pos.y = 259.3731
-entity.size.x = 10.0000
-entity.size.y = 8.0000
-color.r = 1.0000
-color.g = 0.0000
-color.b = 1.0000
-color.a = 1.0000
+entity.pos.x = 353.0000
+entity.pos.y = 312.0000
+entity.size.x = 156.0000
+entity.size.y = 30.0000
+target_openness = 0.0000
 
 :Item_Entity
-entity.id = 5
+entity.id = 14
 entity.flags = 4
-entity.pos.x = 167.6909
-entity.pos.y = 283.5205
-entity.size.x = 13.0000
-entity.size.y = 10.0000
-color.r = 1.0000
-color.g = 0.0000
-color.b = 1.0000
-color.a = 1.0000
-
-:Wall
-entity.id = 6
-entity.flags = 2
-entity.pos.x = 501.0000
-entity.pos.y = 291.0000
-entity.size.x = 62.0000
-entity.size.y = 180.0000
-
-:Wall
-entity.id = 7
-entity.flags = 2
-entity.pos.x = 275.0000
-entity.pos.y = 391.0000
-entity.size.x = 461.0000
-entity.size.y = 34.0000
-
-:Wall
-entity.id = 8
-entity.flags = 2
-entity.pos.x = 74.0000
-entity.pos.y = 313.0000
-entity.size.x = 65.0000
-entity.size.y = 222.0000
+entity.pos.x = 269.4578
+entity.pos.y = 133.2012
+entity.size.x = 24.0000
+entity.size.y = 24.0000
+item = "beer"
 
-:Wall
-entity.id = 9
-entity.flags = 2
-entity.pos.x = 686.0000
-entity.pos.y = 302.0000
-entity.size.x = 50.0000
-entity.size.y = 363.0000
index c88630770cfd025b1f3f5dbe1382876c34ecdc19..cea7606defe4280f94030babfaa4a1ea7388e6e7 100644 (file)
@@ -33,6 +33,7 @@ DEBUG :: false
 #load "utils/any_utils"
 #load "utils/asset_loader"
 #load "utils/input"
+#load "utils/logger"
 #load "utils/vecmath"
 
 #load "stb_image"
index e6c5b504929c6dc19cd4737e1338a145197ccbdc..750a103143a5323f5ae4c24d41df65d79dad7d4d 100644 (file)
@@ -6,7 +6,8 @@ Item :: struct {
     name: str;
     weight := 10.0f;
 
-    color := Color.{ 1, 1, 0 };
+    color        := Color.{ 1, 1, 0 };
+    texture_path : str;
 }
 
 Item_Store :: struct {
@@ -14,6 +15,7 @@ Item_Store :: struct {
     items: Map(str, ^Item);
 
     load_items_from_file :: item_store_load_items_from_file;
+    get_item             :: item_store_get_item;
 }
 
 item_store_make :: () -> Item_Store {
@@ -29,7 +31,7 @@ item_store_load_items_from_file :: (use this: ^Item_Store, path: str) {
 
     err, input_file := os.open(path, .Read);
     if err != .None {
-        printf("Failed to open file: {}\n", path);
+        debug_log(.Error, "Failed to open file: {}", path);
         return;
     }
     defer os.close(^input_file);
@@ -51,8 +53,7 @@ item_store_load_items_from_file :: (use this: ^Item_Store, path: str) {
                     |> string.strip_whitespace();
 
             if items->has(item_id) {
-                printf("Duplicate definition for item with id '{}', on line: {}.\n", item_id);
-                return;
+                debug_log(.Warning, "Duplicate definition for item with id '{}', on line: {}.", item_id);
             }
 
             item_id = string.alloc_copy(item_id, allocator=item_allocator);
@@ -71,44 +72,50 @@ item_store_load_items_from_file :: (use this: ^Item_Store, path: str) {
 
         member := get_any_for_member(ptr_to_any(current_item), var_name);
         if member.data == null {
-            printf("'{}' is not a valid member of Item on line {}.\n", var_name, line_number);
+            debug_log(.Warning, "'{}' is not a valid member of Item on line {}.", var_name, line_number);
             continue;
         }
 
         if !conv.parse_any(member.data, member.type, line) {
-            printf("Unable to parse '{}' for type '{}' on line {}.\n", line, member.type, line_number);
+            debug_log(.Warning, "Unable to parse '{}' for type '{}' on line {}.", line, member.type, line_number);
             continue;
         }
     }
 }
 
+item_store_get_item :: (use this: ^Item_Store, id: str) -> ^Item {
+    return items[id];
+}
 
 Item_Entity :: struct {
     use entity: Entity;
 
     [Editor_Custom_Field.{render_item_picker}]
     item: str;
-    color: Color;
 
     init_data :: struct {
         pos   := Vector2.{0, 0};
-        color := Color.{1, 0, 1, 1};
     }
 
     init :: (use this: ^Item_Entity, data: init_data) {
         this.pos   = data.pos;
         this.size  = .{16, 16};
-        this.color = data.color;
         this.flags |= .Carryable;
     }
 
     get_rect :: Entity.get_rect
 
     draw :: (use this: ^Item_Entity) {
-        immediate_set_color(this.color);
+        item_data := item_store->get_item(item);
+        immediate_set_color(item_data.color);
 
         r := this->get_rect();
-        immediate_rectangle(r.x, r.y, r.w, r.h);
+        texture, loaded := texture_lookup(item_data.texture_path);
+        if !loaded {
+            immediate_rectangle(r.x, r.y, r.w, r.h);
+        } else {
+            immediate_image(^texture, r.x, r.y, r.w, r.h);            
+        }
     }
 }
 
index 6a157d0b107b87d638ae10210546a80091dd906d..e11bad36853ce8b086f9fc213a57383a84f0e605 100644 (file)
@@ -118,11 +118,11 @@ entity_manager_register :: (use this: ^Entity_Manager, $entity_type: type_expr)
         @CompilerFeatures // Maybe there should be data stored in the Type_Info_Struct about
         // the functions/methods that are defined in the structs scope. I don't know if that
         // would be worthwhile or if it would just be bulking up the type info data.
-        #if #defined(entity_type.destroy)  { info.destroy  = entity_type.destroy;  if DEBUG do printf("{} has '{}'.\n", entity_type, "destroy"); }
-        #if #defined(entity_type.update)   { info.update   = entity_type.update;   if DEBUG do printf("{} has '{}'.\n", entity_type, "update"); }
-        #if #defined(entity_type.draw)     { info.draw     = entity_type.draw;     if DEBUG do printf("{} has '{}'.\n", entity_type, "draw"); }
-        #if #defined(entity_type.get_rect) { info.get_rect = entity_type.get_rect; if DEBUG do printf("{} has '{}'.\n", entity_type, "get_rect"); }
-        #if #defined(entity_type.interact) { info.interact = entity_type.interact; if DEBUG do printf("{} has '{}'.\n", entity_type, "interact"); }
+        #if #defined(entity_type.destroy)  { info.destroy  = entity_type.destroy;  if DEBUG do debug_log(.Debug, "{} has '{}'.", entity_type, "destroy"); }
+        #if #defined(entity_type.update)   { info.update   = entity_type.update;   if DEBUG do debug_log(.Debug, "{} has '{}'.", entity_type, "update"); }
+        #if #defined(entity_type.draw)     { info.draw     = entity_type.draw;     if DEBUG do debug_log(.Debug, "{} has '{}'.", entity_type, "draw"); }
+        #if #defined(entity_type.get_rect) { info.get_rect = entity_type.get_rect; if DEBUG do debug_log(.Debug, "{} has '{}'.", entity_type, "get_rect"); }
+        #if #defined(entity_type.interact) { info.interact = entity_type.interact; if DEBUG do debug_log(.Debug, "{} has '{}'.", entity_type, "interact"); }
 
         entity_types[entity_type] = info;
     }
index 850ef5b3e2c404c1ee583d4b99ed047a14f25928..560669f2a9da3a929e6a88243c2153dbd53ad40f 100644 (file)
@@ -244,8 +244,6 @@ Door :: struct {
     }
 
     interact :: (use this: ^Door, interactor: ^Entity) {
-        printf("The door at {} was interacted with by a {}!\n", pos, interactor.type);
-
         // Doors only open if interacted with by a player
         if_entity_is(interactor, Player) {
             target_openness = 0.8f - target_openness;
index 810604dc81f1bb26f2bdf1acb152cc2baee2fb58..85c0ee72c260edc5c242af8d11e014b7269f6ee5 100644 (file)
@@ -56,10 +56,16 @@ entity_manager_save_to_file :: (use this: ^Entity_Manager, filename: str) {
                     io.write(dest, output);
                 }
 
-                case #default {
-                    msg := conv.format(output_buffer, "Unhandled output case: {}\n", it.type);
-                    // assert(false, msg);
-                    printf("ERROR: {}\n", msg);
+                case #default do switch it.type {
+                    case str {
+                        output := conv.format_va(output_buffer, "{} = {\"}\n", .[.{^name, str}, member_any]);
+                        io.write(dest, output);
+                    }
+
+                    case #default {
+                        msg := conv.format(output_buffer, "Unhandled output case: {}\n", it.type);
+                        debug_log(.Error, msg);
+                    }
                 }
             }
         }
@@ -69,7 +75,7 @@ entity_manager_save_to_file :: (use this: ^Entity_Manager, filename: str) {
 entity_manager_load_from_file :: (use this: ^Entity_Manager, filename: str) {
     err, input_file := os.open(filename, .Read);
     if err != .None {
-        printf("Failed to open file: {}\n", filename);
+        debug_log(.Error, "Failed to open file: {}", filename);
         return;
     }
     defer os.close(^input_file);
@@ -106,7 +112,7 @@ entity_manager_load_from_file :: (use this: ^Entity_Manager, filename: str) {
             }
 
             if entity_info == null {
-                printf("Unknown entity kind '{}' on line {}.\n", entity_kind, line_number);
+                debug_log(.Error, "Unknown entity kind '{}' on line {}.", entity_kind, line_number);
                 current_entity = null;
                 continue;
             }
@@ -125,12 +131,12 @@ entity_manager_load_from_file :: (use this: ^Entity_Manager, filename: str) {
         member := get_any_for_member(any.{current_entity, current_entity.type}, var_name);
         if member.data == null {
             entity_info := cast(^Type_Info_Struct) get_type_info(current_entity.type);
-            printf("'{}' is not a valid member of '{}' on line {}.\n", var_name, entity_info.name, line_number);
+            debug_log(.Warning, "'{}' is not a valid member of '{}' on line {}.", var_name, entity_info.name, line_number);
             continue;
         }
 
         if !conv.parse_any(member.data, member.type, line) {
-            printf("Unable to parse '{}' for type '{}' on line {}.\n", line, member.type, line_number);
+            debug_log(.Warning, "Unable to parse '{}' for type '{}' on line {}.", line, member.type, line_number);
             continue;
         }
     }
index 36e28a50b20667477602184542c2d61554755abc..97613ebb7814ea9a0967e577d5bdec6ed57624f7 100644 (file)
@@ -10,13 +10,12 @@ scene: Entity_Manager;
 item_store: Item_Store;
 
 game_init :: () {
-    // player_texture = texture_make(#cstr "./assets/images/player.png");
+    // player_texture = texture_lookup(#cstr "./assets/images/player.png");
 
     // This process of queueing the asset bucket should
     // be made automatic somehow...
     queue_assets(^player_assets);
 
-
     load_assets();
 
     scene = entity_manager_create();
@@ -30,21 +29,25 @@ game_init :: () {
     item_store->load_items_from_file("scenes/default.items");
 
     #if DEBUG {
-        println("Registered Entity types:");
+        debug_log(.Debug, "Registered Entity types:");
         for scene.entity_types.entries {
             info := cast(^type_info.Type_Info_Struct) type_info.get_type_info(it.key);
-            printf("    {}\n", info.name);
+            debug_log(.Debug, "    {}", info.name);
         }
     }
 }
 
+#local quick_save_file := "scenes/quick_save.scene";
+
 game_update :: (dt: f32) {
     if is_key_just_up(GLFW_KEY_F8) {
-        scene->save_to_file("scenes/quick_save.scene");
+        debug_log(.Info, "Saving to '{}'.", quick_save_file);
+        scene->save_to_file(quick_save_file);
     }
 
     if is_key_just_up(GLFW_KEY_F9) {
-        scene->load_from_file("scenes/quick_save.scene");
+        debug_log(.Info, "Loading from '{}'.", quick_save_file);
+        scene->load_from_file(quick_save_file);
     }
 
     if editor_shown() {
index b5c14279d2710133c05aa5f5d8cf536d8194d8ad..8586b4099ed21fa00a962eb11589b0f8ed9567bb 100644 (file)
@@ -12,14 +12,18 @@ Texture :: struct {
     filename: str;
 }
 
-texture_make :: #match {}
-#match texture_make (filename: str) -> (Texture, bool) {
+texture_lookup :: #match {}
+#match texture_lookup (filename: str) -> (Texture, bool) {
+    if texture_cache->has(filename) {
+        return texture_cache[filename], true;
+    }
+    
     buffer: [512] u8;
     memory.copy(~~ buffer, filename.data, math.min(filename.count, 511));
-    return texture_make(cast(cstr) buffer);
+    return texture_lookup(cast(cstr) buffer);
 }
 
-#match texture_make (path: cstr) -> (Texture, bool) {
+#match texture_lookup (path: cstr) -> (Texture, bool) {
     filename := string.from_cstr(path);
     if texture_cache->has(filename) {
         return texture_cache[filename], true;
index 0b5088f2fccda13bb0b1a27961d764d8f7b45dd7..12cdd27aee90660d6fc4e8a2647a6a4ad7414359 100644 (file)
@@ -56,7 +56,7 @@ update :: (dt: f32) {
 }
 
 draw :: () {
-    immediate_clear(.{0.1, 0.1, 0.1});
+    immediate_clear(.{0.15, 0.15, 0.2});
     defer ui_end_frame();
     defer input_post_update();
     defer {
@@ -144,7 +144,7 @@ create_window :: () => {
 
 main :: (args) => {
     if !glfwInit() {
-        println("Failed to initialize GLFW");
+        debug_log(.Critical, "Failed to initialize GLFW!");
         os.exit(1);
     }
 
index 15a0b1752fe4e8b4dc1105ae12489803eb8055de..c4ecea664060e6ec890b03b9b96af1670d017382 100644 (file)
@@ -43,18 +43,18 @@ load_assets :: () {
 
                 if path_tag != null {
                     path := *cast(^str) path_tag.data;
-                    if texture, success := texture_make(path); success {
+                    if texture, success := texture_lookup(path); success {
                         *out_texture = texture;
                     } else {
-                        printf("[ERROR] Failed to load texture '{}' for asset queued here: {}:{},{}.\n", path, location.file, location.line, location.column);
+                        debug_log(.Error, "Failed to load texture '{}' for asset queued here: {}:{},{}.\n", path, location.file, location.line, location.column);
                     }
                 } else {
-                    printf("[ERROR] Texture path not found for texture asset load here: {}:{},{}.\n", location.file, location.line, location.column);
+                    debug_log(.Error, "Texture path not found for texture asset load here: {}:{},{}.\n", location.file, location.line, location.column);
                 }
             }
 
             case #default {
-                printf("[WARN]  Asset loader does not know how to load a '{}'.\n", type);
+                debug_log(.Warning, "Asset loader does not know how to load a '{}'.\n", type);
             }
         }
     }
diff --git a/src/utils/logger.onyx b/src/utils/logger.onyx
new file mode 100644 (file)
index 0000000..529ddee
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// This may become an in-game or external file logger in the future,
+// but for now this is just for logging to the command line.
+
+use package core
+
+Log_Level :: enum {
+    Debug;
+    Info;
+    Warning;
+    Error;
+    Critical;
+}
+
+debug_log :: (level: Log_Level, format: str, args: ..any) {
+    debug_log_va(level, format, ~~args);
+}
+
+debug_log_va :: (level: Log_Level, format: str, args: [] any) {
+    buf: [2048] u8;
+    output := conv.format_va(buf, format, args);
+    printf("[{}] {}\n", level_string(level), output);
+}
+
+#local level_string :: (level: Log_Level) => {
+    switch level {
+        case .Debug    do return "DEBUG";
+        case .Info     do return "INFO ";
+        case .Warning  do return "WARN ";
+        case .Error    do return "ERROR";
+        case .Critical do return "CRIT ";
+    }
+
+    return "     ";
+}