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 }