ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
tmx.c
Go to the documentation of this file.
1/*****************************************************************************
2 * ugBASIC - an isomorphic BASIC language compiler for retrocomputers *
3 *****************************************************************************
4 * Copyright 2021-2026 Marco Spedaletti (asimov@mclink.it)
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *----------------------------------------------------------------------------
18 * Concesso in licenza secondo i termini della Licenza Apache, versione 2.0
19 * (la "Licenza"); è proibito usare questo file se non in conformità alla
20 * Licenza. Una copia della Licenza è disponibile all'indirizzo:
21 *
22 * http://www.apache.org/licenses/LICENSE-2.0
23 *
24 * Se non richiesto dalla legislazione vigente o concordato per iscritto,
25 * il software distribuito nei termini della Licenza è distribuito
26 * "COSÌ COM'È", SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o
27 * implicite. Consultare la Licenza per il testo specifico che regola le
28 * autorizzazioni e le limitazioni previste dalla medesima.
29 ****************************************************************************/
30
31/****************************************************************************
32 * INCLUDE SECTION
33 ****************************************************************************/
34
35#include "tsx.h"
36#include "tmx.h"
37
38#include <stdio.h>
39#include <string.h>
40#include <stdlib.h>
41#include <limits.h>
42#include <unistd.h>
43#include <libxml/parser.h>
44#include <libxml/tree.h>
45
46char * strcopy( char * _dest, const char * _source );
47
48TmxMap * tmx_load( char * _filename ) {
49
50 TmxMap * result = NULL;
51
52 xmlDocPtr doc;
53
54 doc = xmlReadFile( _filename, NULL, 0 );
55
56 if ( ! doc )
57 return result;
58
59 result = malloc( sizeof( TmxMap ) );
60 memset( result, 0, sizeof ( TmxMap ) );
61
62 xmlNode *root_element = NULL;
63 xmlNode *cur_node = NULL;
64
65 root_element = xmlDocGetRootElement(doc);
66
67 for (cur_node = root_element; cur_node; cur_node = cur_node->next) {
68 if (cur_node->type == XML_ELEMENT_NODE) {
69 if ( strcmp( cur_node->name, "map" ) == 0 ) {
70 struct _xmlAttr * properties = cur_node->properties;
71 while( properties ) {
72 if ( properties->type == XML_ATTRIBUTE_NODE ) {
73 xmlChar* value = xmlNodeListGetString(cur_node->doc, properties->children, 1);
74 if ( strcmp( properties->name, "version") == 0 ) {
75 result->version = strdup( value );
76 } else if ( strcmp( properties->name, "tiledVersion") == 0 ) {
77 result->tiledversion = strdup( value );
78 } else if ( strcmp( properties->name, "orientation") == 0 ) {
79 if ( strcmp( value, "orthogonal" ) == 0 ) {
81 } else if ( strcmp( value, "isometric" ) == 0 ) {
82 result->orientation = TMX_ISOMETRIC;
83 } else if ( strcmp( value, "staggered" ) == 0 ) {
84 result->orientation = TMX_STAGGERED;
85 } else if ( strcmp( value, "hexagonal" ) == 0 ) {
86 result->orientation = TMX_HEXAGONAL;
87 }
88 } else if ( strcmp( properties->name, "renderorder") == 0 ) {
89 if ( strcmp( value, "right-down" ) == 0 ) {
91 } else if ( strcmp( value, "right-up" ) == 0 ) {
92 result->orientation = TMX_RIGHT_UP;
93 } else if ( strcmp( value, "left-down" ) == 0 ) {
94 result->orientation = TMX_LEFT_DOWN;
95 } else if ( strcmp( value, "left-up" ) == 0 ) {
96 result->orientation = TMX_LEFT_UP;
97 }
98 } else if ( strcmp( properties->name, "width") == 0 ) {
99 result->width = atoi( value );
100 } else if ( strcmp( properties->name, "height") == 0 ) {
101 result->height = atoi( value );
102 } else if ( strcmp( properties->name, "tilewidth") == 0 ) {
103 result->tilewidth = atoi( value );
104 } else if ( strcmp( properties->name, "tileheight") == 0 ) {
105 result->tileheight = atoi( value );
106 } else if ( strcmp( properties->name, "infinite") == 0 ) {
107 result->infinite = atoi( value );
108 } else if ( strcmp( properties->name, "nextlayerid") == 0 ) {
109 result->nextlayerid = atoi( value );
110 } else if ( strcmp( properties->name, "nextobjectid") == 0 ) {
111 result->nextobjectid = atoi( value );
112 }
113 xmlFree(value);
114 }
115 properties = properties->next;
116 }
117
118 xmlNode * child = cur_node->children;
119 while( child ) {
120
121 if ( strcmp( child->name, "tileset" ) == 0 ) {
122
123 char * source;
124 int firstgid;
125
126 struct _xmlAttr * properties = child->properties;
127 while( properties ) {
128 if ( properties->type == XML_ATTRIBUTE_NODE ) {
129 xmlChar* value = xmlNodeListGetString(child->doc, properties->children, 1);
130 if ( strcmp( properties->name, "source") == 0 ) {
131 source = strdup( value );
132 } if ( strcmp( properties->name, "firstgid") == 0 ) {
133 firstgid = atoi( value );
134 }
135 xmlFree(value);
136 }
137 properties = properties->next;
138 }
139
140 if ( source ) {
141
142 char * filename = strdup( _filename );
143 char * filenameWithPath = malloc( 1024 );
144 memset( filenameWithPath, 0, 1024 );
145 char * separator = strrchr( filename, '/' );
146 if ( separator ) {
147 *(separator+1) = 0;
148 strcopy( filenameWithPath, filename );
149 }
150 strcat( filenameWithPath, source );
151
152 TsxTileset * tileset = tsx_load( filenameWithPath );
153
154 tileset->source = source;
155 tileset->firstgid = firstgid;
156
157 if ( ! result->tilesets ) {
158 result->tilesets = tileset;
159 } else {
160 TsxTileset * actual = result->tilesets;
161 while( actual->next ) {
162 actual = actual->next;
163 }
164 actual->next = tileset;
165 }
166
167 }
168
169 } else if ( strcmp( child->name, "layer" ) == 0 ) {
170
171 TmxLayer * layer = malloc( sizeof( TmxLayer ) );
172 memset( layer, 0, sizeof( TmxLayer ) );
173
174 struct _xmlAttr * properties = child->properties;
175 while( properties ) {
176 if ( properties->type == XML_ATTRIBUTE_NODE ) {
177 xmlChar* value = xmlNodeListGetString(child->doc, properties->children, 1);
178 if ( strcmp( properties->name, "name") == 0 ) {
179 layer->name = strdup( value );
180 } if ( strcmp( properties->name, "width") == 0 ) {
181 layer->width = atoi( value );
182 } if ( strcmp( properties->name, "height") == 0 ) {
183 layer->height = atoi( value );
184 } if ( strcmp( properties->name, "id") == 0 ) {
185 layer->id = atoi( value );
186 }
187 xmlFree(value);
188 }
189 properties = properties->next;
190 }
191
192 xmlNode * rechild = child->children;
193 while( rechild ) {
194
195 if ( strcmp( rechild->name, "data" ) == 0 ) {
196
197 layer->data = malloc( layer->width * layer->height * sizeof( int ) );
198 memset( layer->data, 0, layer->width * layer->height * sizeof( int ) );
199
200 char * content = (char*)xmlNodeGetContent( rechild->children );
201
202 int step = 0;
203
204 while( *content ) {
205
206 char valueString[32];
207 memset( valueString, 0, 32 );
208 int p=0, j=0;
209
210 while( *content ) {
211 char c = *content;
212 ++content;
213 if ( j == 0 ) {
214 if ( (c < '0') || (c > '9') ) {
215 continue;
216 }
217 j = 1;
218 } else {
219 if ( (c < '0') || (c > '9') ) {
220 break;
221 }
222 }
223 valueString[p] = c;
224 ++p;
225 }
226
227 int value = atoi( valueString );
228 layer->data[step] = value;
229 ++step;
230
231 }
232
233 }
234
235 rechild = rechild->next;
236
237 }
238
239 if ( ! result->layers ) {
240 result->layers = layer;
241 } else {
242 TmxLayer * actual = result->layers;
243 while( actual->next ) {
244 actual = actual->next;
245 }
246 actual->next = layer;
247 }
248
249 }
250
251 child = child->next;
252
253 }
254
255 }
256 }
257 }
258
259 xmlFreeDoc(doc);
260
261 return result;
262
263}
int width
Definition tmx.h:62
struct _TmxLayer * next
Definition tmx.h:67
char * name
Definition tmx.h:61
int id
Definition tmx.h:60
int * data
Definition tmx.h:65
int height
Definition tmx.h:63
int nextlayerid
Definition tmx.h:82
int width
Definition tmx.h:77
struct _TsxTileset * tilesets
Definition tmx.h:85
int infinite
Definition tmx.h:81
char * version
Definition tmx.h:73
char * tiledversion
Definition tmx.h:74
TmxOrientation orientation
Definition tmx.h:75
int height
Definition tmx.h:78
int tilewidth
Definition tmx.h:79
int nextobjectid
Definition tmx.h:83
struct _TmxLayer * layers
Definition tmx.h:87
int tileheight
Definition tmx.h:80
struct _TsxTileset * next
Definition tsx.h:74
int firstgid
Definition tsx.h:66
char * source
Definition tsx.h:61
TmxMap * tmx_load(char *_filename)
Definition tmx.c:48
char * strcopy(char *_dest, const char *_source)
struct _TmxMap TmxMap
struct _TmxLayer TmxLayer
@ TMX_HEXAGONAL
Definition tmx.h:45
@ TMX_ISOMETRIC
Definition tmx.h:43
@ TMX_ORTHOGONAL
Definition tmx.h:42
@ TMX_STAGGERED
Definition tmx.h:44
@ TMX_RIGHT_DOWN
Definition tmx.h:51
@ TMX_LEFT_DOWN
Definition tmx.h:53
@ TMX_LEFT_UP
Definition tmx.h:54
@ TMX_RIGHT_UP
Definition tmx.h:52
TsxTileset * tsx_load(char *_filename)
Definition tsx.c:47
struct _TsxTileset TsxTileset
void * malloc(YYSIZE_T)