aboutsummaryrefslogtreecommitdiff
path: root/tools/compile_assets/tiled.odin
diff options
context:
space:
mode:
authoriamcheeseman <[hidden email]>2026-01-17 18:19:57 -0500
committeriamcheeseman <[hidden email]>2026-01-17 18:19:57 -0500
commitdb10e319cc2201924815b2d8c9a4c2d21c2bfbb6 (patch)
tree17c7d1b0e485dc07161cbdca80ae2239fd6146c5 /tools/compile_assets/tiled.odin
parenteee06361048e34f6ca21348e8776636da95ef3f8 (diff)
Verlet ropes :)
Diffstat (limited to 'tools/compile_assets/tiled.odin')
-rw-r--r--tools/compile_assets/tiled.odin211
1 files changed, 139 insertions, 72 deletions
diff --git a/tools/compile_assets/tiled.odin b/tools/compile_assets/tiled.odin
index 196cb49..5c2862c 100644
--- a/tools/compile_assets/tiled.odin
+++ b/tools/compile_assets/tiled.odin
@@ -450,6 +450,142 @@ load_json_tileset :: proc(path: string) {
gids.last = u32(len(tiles))
}
+Properties :: map[string]union{
+ bool,
+ int,
+ string,
+ f32,
+}
+
+
+load_properties :: proc(into: ^Properties, obj: Json_Object, base_dir: string) {
+ for property in obj.properties {
+ value := property.value
+ if strings.compare(property.type, "file") == 0 {
+ rel, err := filepath.join(
+ {base_dir, value.(string)},
+ context.temp_allocator,
+ )
+ assert(err == nil)
+ value = rel
+ }
+ into[property.name] = value
+ }
+}
+
+load_json_object :: proc(
+ room_path: string,
+ tiled_to_real_gid: map[i32]u32,
+ parallax: [2]f32,
+ obj: Json_Object,
+) -> string {
+ cwd, cwd_err := os.get_working_directory(context.temp_allocator)
+ assert(cwd_err == nil)
+
+ room_dir, room_dir_err := filepath.rel(
+ cwd,
+ filepath.dir(room_path, context.temp_allocator),
+ context.temp_allocator,
+ )
+ assert(room_dir_err == nil)
+
+ pos: [2]f32
+ size: [2]f32
+ tile_id: Maybe(u32)
+ obj_type := obj.type if obj.type != "" else "prop"
+ type_name := strings.to_ada_case(obj_type)
+
+ properties: Properties
+ defer delete(properties)
+
+ if obj.template != "" {
+ rel, err := filepath.join(
+ {room_dir, obj.template},
+ context.temp_allocator,
+ )
+ assert(err == nil)
+
+ template_dir := filepath.dir(rel, context.temp_allocator)
+
+ json_text, read_err := os.read_entire_file(rel, context.temp_allocator)
+ if read_err != nil {
+ die("Could not load template %v (%v)", rel, read_err)
+ }
+
+ template: Json_Object_Template
+ unmarshal_err := json.unmarshal(
+ json_text,
+ &template,
+ allocator = context.temp_allocator,
+ )
+
+ tobj := template.object
+
+ if obj.type == "" && tobj.type != "" {
+ delete(type_name)
+ obj_type := tobj.type if tobj.type != "" else "prop"
+ type_name = strings.to_ada_case(obj_type)
+ }
+
+ pos = {f32(tobj.x), f32(tobj.y)}
+ size = {f32(tobj.width), f32(tobj.height)}
+
+ load_properties(&properties, tobj, template_dir)
+
+ if tobj.gid != 0 {
+ flip_flags := (tobj.gid & 0x80000000) >> 28
+
+ if flip_flags & 0b1000 != 0 {
+ size.x *= -1
+ }
+ if flip_flags & 0b0100 != 0 {
+ size.y *= -1
+ }
+
+ tiled_id := (tobj.gid << 4) >> 4
+
+ tile_id = tiled_to_real_gid[i32(tiled_id)]
+ }
+ }
+
+ pos = [2]f32{f32(obj.x), f32(obj.y)}
+ size = [2]f32{f32(obj.width), f32(obj.height)}
+
+ load_properties(&properties, obj, room_dir)
+
+ if obj.gid != 0 {
+ flip_flags := (obj.gid & 0x80000000) >> 28
+
+ if flip_flags & 0b1000 != 0 {
+ size.x *= -1
+ }
+ if flip_flags & 0b0100 != 0 {
+ size.y *= -1
+ }
+
+ tiled_id := (obj.gid << 4) >> 4
+
+ tile_id = tiled_to_real_gid[i32(tiled_id)]
+ }
+
+ // `object_type_names` now owns `type_name`; freed in main
+ if type_name in object_type_names {
+ key, _ := delete_key(&object_type_names, type_name)
+ delete(key)
+ }
+ object_type_names[type_name] = {}
+
+ return fmt.tprintf(
+ "{{type = .%v, tile_id = %v, pos = %w, size = %w, parallax = %w, properties = %w}}",
+ type_name,
+ tile_id,
+ pos,
+ size,
+ parallax,
+ properties,
+ )
+}
+
load_json_room :: proc(path: string, file: ^os.File) {
json_text, read_err := os.read_entire_file(file, context.temp_allocator)
if read_err != nil {
@@ -526,79 +662,10 @@ load_json_room :: proc(path: string, file: ^os.File) {
parallax := [2]f32{f32(layer.parallaxx), f32(layer.parallaxy)}
for obj in layer.objects {
- obj_type := obj.type if obj.type != "" else "prop"
- type_name := strings.to_ada_case(obj_type)
-
- // `object_type_names` now owns `type_name`; freed in main
- if type_name in object_type_names {
- key, _ := delete_key(&object_type_names, type_name)
- delete(key)
- }
- object_type_names[type_name] = {}
-
- pos := [2]f32{f32(obj.x), f32(obj.y)}
- size := [2]f32{f32(obj.width), f32(obj.height)}
-
- properties: map[string]union{
- bool,
- int,
- string,
- f32,
- }
- defer delete(properties)
-
- cwd, cwd_err := os.get_working_directory(context.temp_allocator)
- assert(cwd_err == nil)
- room_dir, room_dir_err := filepath.rel(
- cwd,
- filepath.dir(path, context.temp_allocator),
- context.temp_allocator,
- )
- assert(room_dir_err == nil)
-
- for property in obj.properties {
- value := property.value
- if strings.compare(property.type, "file") == 0 {
- rel, err := filepath.join(
- {room_dir, value.(string)},
- context.temp_allocator,
- )
- assert(err == nil)
- value = rel
- }
- properties[property.name] = value
- }
-
- tile_id: Maybe(u32) = nil
- if obj.gid != 0 {
- flip_flags := (obj.gid & 0x80000000) >> 28
-
- if flip_flags & 0b1000 != 0 {
- size.x *= -1
- }
- if flip_flags & 0b0100 != 0 {
- size.y *= -1
- }
-
- tiled_id := (obj.gid << 4) >> 4
-
- fmt.printfln("%032b %v %v %032b %x", obj.gid, obj.gid, tiled_id, flip_flags, flip_flags)
-
- tile_id = tiled_to_real_gid[i32(tiled_id)]
- // tile_id = u32(obj.gid)
- }
-
- line := fmt.tprintf(
- "{{type = .%v, tile_id = %v, pos = %w, size = %w, parallax = %w, properties = %w}}",
- type_name,
- tile_id,
- pos,
- size,
- parallax,
- properties,
+ append(
+ &objects,
+ load_json_object(path, tiled_to_real_gid, parallax, obj),
)
-
- append(&objects, line)
}
case:
fmt.eprintfln("WARNING: Unsupported tile layer type '%v'", layer.type)