From 2fb85a3cdc3b957ff2e3b9b00cc0a6287a5af0b5 Mon Sep 17 00:00:00 2001 From: kdx Date: Tue, 4 Apr 2023 09:00:57 +0200 Subject: initial commit & done --- LICENSE | 19 ++ example/example.c | 6 + example/tset.tsj | 556 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ example/tsj2c.h | 28 +++ go.mod | 3 + main.go | 192 +++++++++++++++++++ 6 files changed, 804 insertions(+) create mode 100644 LICENSE create mode 100644 example/example.c create mode 100644 example/tset.tsj create mode 100644 example/tsj2c.h create mode 100644 go.mod create mode 100644 main.go diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a32c30c --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2023 kdx + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/example/example.c b/example/example.c new file mode 100644 index 0000000..7373335 --- /dev/null +++ b/example/example.c @@ -0,0 +1,6 @@ +#include "tset.h" +#include + +int +main(void) { +} diff --git a/example/tset.tsj b/example/tset.tsj new file mode 100644 index 0000000..7862ba9 --- /dev/null +++ b/example/tset.tsj @@ -0,0 +1,556 @@ +{ "columns":16, + "image":"..\/res\/tset.png", + "imageheight":512, + "imagewidth":256, + "margin":0, + "name":"tset", + "objectalignment":"center", + "spacing":0, + "tilecount":512, + "tiledversion":"1.10.0", + "tileheight":16, + "tiles":[ + { + "id":0, + "type":"solid" + }, + { + "id":1, + "type":"solid" + }, + { + "id":2, + "type":"solid" + }, + { + "id":3, + "type":"solid" + }, + { + "id":4, + "type":"solid" + }, + { + "id":5, + "type":"solid" + }, + { + "id":16, + "type":"solid" + }, + { + "id":17, + "type":"solid" + }, + { + "id":18, + "type":"solid" + }, + { + "id":19, + "type":"solid" + }, + { + "id":20, + "type":"solid" + }, + { + "id":21, + "type":"solid" + }, + { + "id":32, + "type":"solid" + }, + { + "id":33, + "type":"solid" + }, + { + "id":34, + "type":"solid" + }, + { + "id":35, + "type":"solid" + }, + { + "id":36, + "type":"solid" + }, + { + "id":37, + "type":"solid" + }, + { + "id":48, + "type":"solid" + }, + { + "id":49, + "type":"solid" + }, + { + "id":50, + "type":"solid" + }, + { + "id":51, + "type":"solid" + }, + { + "id":52, + "type":"solid" + }, + { + "id":53, + "type":"solid" + }, + { + "id":64, + "type":"solid" + }, + { + "id":65, + "type":"solid" + }, + { + "id":66, + "type":"solid" + }, + { + "id":67, + "type":"solid" + }, + { + "id":68, + "type":"solid" + }, + { + "id":69, + "type":"solid" + }, + { + "id":80, + "type":"solid" + }, + { + "id":81, + "type":"solid" + }, + { + "id":82, + "type":"solid" + }, + { + "id":83, + "probability":0.5, + "type":"solid" + }, + { + "id":84, + "type":"solid" + }, + { + "id":85, + "type":"solid" + }, + { + "id":96, + "type":"solid" + }, + { + "id":97, + "type":"solid" + }, + { + "id":98, + "type":"solid" + }, + { + "id":99, + "type":"solid" + }, + { + "id":100, + "type":"solid" + }, + { + "id":101, + "type":"solid" + }, + { + "id":112, + "type":"solid" + }, + { + "id":113, + "type":"solid" + }, + { + "id":114, + "type":"solid" + }, + { + "id":115, + "type":"solid" + }, + { + "id":116, + "type":"solid" + }, + { + "id":117, + "type":"solid" + }, + { + "id":128, + "type":"solid" + }, + { + "id":129, + "type":"solid" + }, + { + "id":130, + "type":"solid" + }, + { + "id":131, + "type":"solid" + }, + { + "id":132, + "type":"solid" + }, + { + "id":133, + "type":"solid" + }, + { + "id":134, + "type":"spike" + }, + { + "id":135, + "type":"spike" + }, + { + "id":136, + "type":"spike" + }, + { + "id":137, + "type":"spike" + }, + { + "id":138, + "type":"spike" + }, + { + "id":144, + "type":"solid" + }, + { + "id":145, + "type":"solid" + }, + { + "id":146, + "type":"solid" + }, + { + "id":147, + "type":"solid" + }, + { + "id":148, + "type":"solid" + }, + { + "id":149, + "type":"solid" + }, + { + "id":150, + "type":"spike" + }, + { + "id":151, + "type":"spike" + }, + { + "id":152, + "type":"spike" + }, + { + "id":153, + "type":"spike" + }, + { + "id":154, + "type":"spike" + }, + { + "id":160, + "type":"solid" + }, + { + "id":161, + "type":"solid" + }, + { + "id":162, + "type":"solid" + }, + { + "id":163, + "type":"solid" + }, + { + "id":164, + "type":"solid" + }, + { + "id":165, + "type":"solid" + }, + { + "id":166, + "type":"spike" + }, + { + "id":167, + "type":"spike" + }, + { + "id":168, + "type":"spike" + }, + { + "id":169, + "type":"spike" + }, + { + "id":170, + "type":"spike" + }, + { + "id":176, + "type":"solid" + }, + { + "id":177, + "type":"solid" + }, + { + "id":178, + "type":"solid" + }, + { + "id":179, + "type":"solid" + }, + { + "id":180, + "type":"solid" + }, + { + "id":181, + "type":"solid" + }, + { + "id":182, + "type":"spike" + }, + { + "id":183, + "type":"spike" + }, + { + "id":184, + "type":"spike" + }, + { + "id":185, + "type":"spike" + }, + { + "id":186, + "type":"spike" + }, + { + "id":192, + "type":"solid" + }, + { + "id":193, + "type":"solid" + }, + { + "id":194, + "type":"solid" + }, + { + "id":195, + "type":"solid" + }, + { + "id":196, + "type":"solid" + }, + { + "id":197, + "type":"solid" + }, + { + "id":198, + "type":"spike" + }, + { + "id":199, + "type":"spike" + }, + { + "id":200, + "type":"spike" + }, + { + "id":201, + "type":"spike" + }, + { + "id":202, + "type":"spike" + }, + { + "id":208, + "type":"solid" + }, + { + "id":209, + "type":"solid" + }, + { + "id":210, + "type":"solid" + }, + { + "id":211, + "type":"solid" + }, + { + "id":212, + "type":"solid" + }, + { + "id":213, + "type":"solid" + }, + { + "id":224, + "type":"solid" + }, + { + "id":225, + "type":"solid" + }, + { + "id":226, + "type":"solid" + }, + { + "id":227, + "type":"solid" + }, + { + "id":228, + "type":"solid" + }, + { + "id":229, + "type":"solid" + }, + { + "id":240, + "type":"solid" + }, + { + "id":241, + "type":"solid" + }, + { + "id":242, + "type":"solid" + }, + { + "id":243, + "type":"solid" + }, + { + "id":244, + "type":"solid" + }, + { + "id":245, + "type":"solid" + }, + { + "animation":[ + { + "duration":700, + "tileid":344 + }, + { + "duration":700, + "tileid":345 + }], + "id":344 + }, + { + "animation":[ + { + "duration":700, + "tileid":345 + }, + { + "duration":700, + "tileid":344 + }], + "id":345 + }, + { + "animation":[ + { + "duration":700, + "tileid":359 + }, + { + "duration":700, + "tileid":360 + }], + "id":359 + }, + { + "animation":[ + { + "duration":700, + "tileid":360 + }, + { + "duration":700, + "tileid":359 + }], + "id":360 + }], + "tilewidth":16, + "transformations": + { + "hflip":true, + "preferuntransformed":false, + "rotate":false, + "vflip":true + }, + "type":"tileset", + "version":"1.10" +} \ No newline at end of file diff --git a/example/tsj2c.h b/example/tsj2c.h new file mode 100644 index 0000000..df71e98 --- /dev/null +++ b/example/tsj2c.h @@ -0,0 +1,28 @@ +#pragma once + +typedef struct { + double duration; + double tileid; +} Tsj2cFrame; + +typedef struct { + unsigned int id; + const char *type; + double probability; + const int numframes; + const Tsj2cFrame *frames; +} Tsj2cTile; + +typedef struct { + const char *name; + const char *path; + unsigned int imagewidth; + unsigned int imageheight; + unsigned int tilewidth; + unsigned int tileheight; + unsigned int margin; + unsigned int columns; + unsigned int tilecount; + unsigned int numtiles; + const Tsj2cTile *tiles; +} Tsj2cSet; diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..6e7a848 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module kdx.re/cgit/tsj2c + +go 1.18 diff --git a/main.go b/main.go new file mode 100644 index 0000000..abde00f --- /dev/null +++ b/main.go @@ -0,0 +1,192 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "math" + "os" +) + +type Root struct { + Path string + Name string + NName string + ImageWidth float64 + ImageHeight float64 + TileWidth float64 + TileHeight float64 + Margin float64 + Columns float64 + TileCount float64 + Tiles []Tile +} + +type Tile struct { + Id float64 + Type string + Probability float64 + Frames []Frame +} + +type Frame struct { + Duration float64 + TileId float64 +} + +func main() { + out := "#include \"tsj2c.h\"\n" + names := []string{} + for i := 1; i < len(os.Args); i++ { + result, err := process(os.Args[i]) + if err != nil { + panic(err) + } + out += fmt.Sprint(result) + names = append(names, result.Name) + } + out += "const Tsj2cSet *tsj2c_sets[]={" + for i := 0; i < len(names); i++ { + out += "&" + names[i] + "," + } + out += "0};\n" + fmt.Print(out) +} + +func process(path string) (Root, error) { + content, err := ioutil.ReadFile(path) + if err != nil { + panic(err) + } + + var data map[string]interface{} + err = json.Unmarshal(content, &data) + if err != nil { + panic(err) + } + + var root = Root{ + Path: path, + Name: "", + NName: data["name"].(string), + ImageWidth: data["imagewidth"].(float64), + ImageHeight: data["imageheight"].(float64), + TileWidth: data["tilewidth"].(float64), + TileHeight: data["tileheight"].(float64), + Margin: data["margin"].(float64), + Columns: data["columns"].(float64), + TileCount: data["tilecount"].(float64), + Tiles: []Tile{}, + } + for i := 0; i < len(root.Path); i++ { + chr := root.Path[i] + if (chr >= '0' && chr <= '9') || (chr >= 'A' && chr <= 'Z') || + (chr >= 'a' && chr <= 'z') { + root.Name += string(chr) + } else { + root.Name += "_" + } + } + + tiles := data["tiles"].([]interface{}) + for i := 0; i < len(tiles); i++ { + root.Tiles = append(root.Tiles, NewTile(tiles[i].(map[string]interface{}))) + } + return root, nil +} + +func (this Root) String() string { + out := "static const Tsj2cSet " + this.Name + "={" + out += "\"" + this.NName + "\"," + out += "\"" + this.Path + "\"," + out += fmt.Sprint(this.ImageWidth) + "," + out += fmt.Sprint(this.ImageHeight) + "," + out += fmt.Sprint(this.TileWidth) + "," + out += fmt.Sprint(this.TileHeight) + "," + out += fmt.Sprint(this.Margin) + "," + out += fmt.Sprint(this.Columns) + "," + out += fmt.Sprint(this.TileCount) + "," + out += fmt.Sprint(len(this.Tiles)) + "," + + out += "(const Tsj2cTile[]){" + for i := 0; i < len(this.Tiles); i++ { + out += this.Tiles[i].String() + "," + } + out += "}" + + out += "};\n" + return out +} + +func (this Tile) String() string { + out := "{" + out += fmt.Sprint(this.Id) + "," + if this.Type != "" { + out += "\"" + this.Type + "\"," + } else { + out += "0," + } + if math.IsNaN(this.Probability) { + out += "1," + } else { + out += fmt.Sprint(this.Probability) + "," + } + + out += fmt.Sprint(len(this.Frames)) + "," + if len(this.Frames) > 0 { + out += "(const Tsj2cFrame[]){" + for i := 0; i < len(this.Frames); i++ { + if i > 0 { + out += "," + } + out += this.Frames[i].String() + } + out += "}" + } else { + out += "0" + } + + out += "}" + return out +} + +func (this Frame) String() string { + out := "{" + out += fmt.Sprint(this.Duration) + "," + out += fmt.Sprint(this.TileId) + out += "}" + return out +} + +func NewTile(jtile map[string]interface{}) Tile { + tile := Tile{ + Id: jtile["id"].(float64), + Type: "", + Probability: math.NaN(), + Frames: []Frame{}, + } + v, ok := jtile["type"] + if ok { + tile.Type = v.(string) + } + v, ok = jtile["probability"] + if ok { + tile.Probability = v.(float64) + } + v, ok = jtile["animation"] + if ok { + frames := v.([]interface{}) + for i := 0; i < len(frames); i++ { + frame := frames[i].(map[string]interface{}) + tile.Frames = append(tile.Frames, NewFrame(frame)) + } + } + return tile +} + +func NewFrame(src map[string]interface{}) Frame { + return Frame{ + Duration: src["duration"].(float64), + TileId: src["tileid"].(float64), + } +} -- cgit v1.2.3