lib/gamnit: intro the asteronit example
[nit.git] / lib / gamnit / examples / asteronits / src / texture_atlas_parser.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Tool to parse XML texture atlas and generated Nit code to access subtextures
16 module texture_atlas_parser
17
18 import dom
19 import gen_nit
20 import opts
21
22 # Command line options
23 var opts = new OptionContext
24 var opt_name = new OptionString("Name of the module to generate", "--name", "-n")
25 var opt_dir = new OptionString("Folder where to write the generated module", "--dir")
26 opts.add_option(opt_name, opt_dir)
27 opts.parse
28 var rest = opts.rest
29
30 if opts.errors.not_empty then
31 print_error opts.errors
32 exit 1
33 end
34
35 if rest.is_empty then
36 print_error "Error: Expected the path to the XML file as argument"
37 exit 2
38 end
39
40 # Prepare to read XML file and gather the attributes
41 var xml_file = rest.first
42 var attributes = new Array[String]
43
44 # Insert the first attribute, to load the root texture
45 var png_file = "images" / xml_file.basename("xml") + "png"
46 attributes.add """
47 var root_texture = new Texture("{{{png_file}}}")"""
48
49 # Read XML file
50 var content = xml_file.to_path.read_all
51 var xml = content.to_xml
52 if xml isa XMLError then
53 print_error "RSS Parse Error: {xml.message}:{xml.location or else "null"}"
54 exit 3
55 end
56
57 var items = xml["TextureAtlas"].first.children
58 for item in items do if item isa XMLOnelinerTag then
59 var x = null
60 var y = null
61 var width = null
62 var height = null
63 var name = null
64 for attr in item.attributes do if attr isa XMLStringAttr then
65 if attr.name == "x" then
66 x = attr.value.to_i
67 else if attr.name == "y" then
68 y = attr.value.to_i
69 else if attr.name == "width" then
70 width = attr.value.to_i
71 else if attr.name == "height" then
72 height = attr.value.to_i
73 else if attr.name == "name" then
74 name = attr.value
75 end
76 end
77
78 if x != null and y != null and width != null and height != null and name != null then
79 name = name.strip_extension(".png").to_snake_case
80
81 var coords = "{x}, {y}, {width}, {height}"
82 attributes.add """
83 var {{{name}}}: Texture = root_texture.subtexture({{{coords}}})"""
84 else
85 print_error "Error on {item}"
86 end
87 end
88
89 var module_name = opt_name.value
90 if module_name == null then module_name = "spritesheet"
91 var class_name = module_name.capitalized.to_camel_case
92
93 # Generate Nit code
94 var nit_module = new NitModule(module_name)
95 nit_module.header = """
96 # This file is generated by texture_atlas_parser
97 """
98
99 nit_module.content.add """
100 import gamnit::display
101 import gamnit::textures
102
103 class {{{class_name}}}
104 """
105
106 for a in attributes do nit_module.content.add a
107
108 nit_module.content.add """
109 end"""
110
111 var dir = opt_dir.value
112 if dir != null then
113 var out_path = dir / module_name + ".nit"
114 nit_module.write_to_file out_path
115 else
116 printn nit_module.write_to_string
117 end