summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE19
-rw-r--r--example/example.c6
-rw-r--r--example/tset.tsj556
-rw-r--r--example/tsj2c.h28
-rw-r--r--go.mod3
-rw-r--r--main.go192
6 files changed, 804 insertions, 0 deletions
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 <stdio.h>
+
+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),
+ }
+}