Files
hello/tiled_parser.odin
2026-08-21 19:48:16 +05:00

140 lines
3.4 KiB
Odin

package main
import "base:runtime"
import "core:encoding/json"
import "core:fmt"
import "core:os"
Map_File :: struct {
compression_level: int `json:"compressionlevel"`,
height: int `json:"height"`,
infinite: bool `json:"infinite"`,
layers: []Layer `json:"layers"`,
next_layer_id: int `json:"nextlayerid"`,
next_object_id: int `json:"nextobjectid"`,
orientation: string `json:"orientation"`,
render_order: string `json:"renderorder"`,
tiled_version: string `json:"tiledversion"`,
tile_height: int `json:"tileheight"`,
tile_sets: []Tileset `json:"tilesets"`,
tile_width: int `json:"tilewidth"`,
type: string `json:"type"`,
version: string `json:"version"`,
width: int `json:"width"`,
}
Layer :: struct {
data: []int `json:"data"`,
height: int `json:"height"`,
id: int `json:"id"`,
name: string `json:"name"`,
opacity: f32 `json:"opacity"`,
type: string `json:"type"`,
visible: bool `json:"visible"`,
width: int `json:"width"`,
x: int `json:"x"`,
y: int `json:"y"`,
}
Tileset :: struct {
first_gid: int `json:"firstgid"`,
source: string `json:"source"`,
}
Map_Load_Error_Type :: enum {
None,
Err_Loading_File,
Err_Unmarshal,
}
Map_Load_Error :: struct {
type: Map_Load_Error_Type,
msg: string,
}
Map :: struct {
width: i32,
height: i32,
layers: []Layer_Data,
}
Layer_Data :: struct {
data: [][]i32,
}
load_map :: proc(
path: string,
allocator: runtime.Allocator,
) -> (
map_out: Map,
err: Map_Load_Error,
) {
context.allocator = allocator
cfg_data, os_err := os.read_entire_file(path, context.allocator)
if os_err != os.General_Error.None {
return {}, Map_Load_Error{type = .Err_Loading_File, msg = fmt.aprintf("Error reading file: %v (%v)", path, os_err)}
}
unm_map: Map_File
unm_err := json.unmarshal(cfg_data, &unm_map)
if unm_err != nil {
return {}, Map_Load_Error{type = .Err_Unmarshal, msg = fmt.aprintf("Error unmarshalling file: %v (%v)\nOnly Tiled version 1.11.2 is supported", path, unm_err)}
}
assert(!unm_map.infinite, "Infinite maps are not supported")
assert(
unm_map.orientation == "orthogonal",
"Only orthogonal maps are supported",
)
assert(
unm_map.render_order == "right-down",
"Only right-down maps are supported",
)
assert(
unm_map.tile_height == 16 && unm_map.tile_width == 16,
"Only 16x16 tiles are supported",
)
if len(unm_map.layers) == 0 {
return {}, Map_Load_Error{type = .Err_Unmarshal, msg = fmt.aprintf("No layers found in file: %v", path)}
}
if len(unm_map.tile_sets) == 0 {
return {}, Map_Load_Error{type = .Err_Unmarshal, msg = fmt.aprintf("No tilesets found in file: %v", path)}
}
for layer in unm_map.layers {
assert(
layer.type == "tilelayer",
"Only layers with type 'tilelayer' are supported",
)
}
map_out.width = i32(unm_map.width)
map_out.height = i32(unm_map.height)
map_out.layers = make([]Layer_Data, len(unm_map.layers))
for &out, li in map_out.layers {
src := unm_map.layers[li]
out.data = make([][]i32, src.height)
for row in 0 ..< src.height {
out.data[row] = make([]i32, src.width)
for col in 0 ..< src.width {
out.data[row][col] = i32(src.data[row * src.width + col])
}
}
}
// for layer in unm_map.layers {
// for tile, tile_id in layer.data {
// map_out.data[tile_id / layer.width][tile_id % layer.width] = i32(
// tile,
// )
// }
// }
return
}