ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
tilemap_storage.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 "../../ugbc.h"
37#include "../../libs/msc1.h"
38#include "../../libs/tsx.h"
39
40/****************************************************************************
41 * CODE SECTION
42 ****************************************************************************/
43
51/* <usermanual>
52@keyword TILEMAP (storage)
53
54@english
55The ''TILEMAP'' command, inserted inside a ''BEGIN STORAGE'' - ''ENDSTORAGE'' block,
56allows you to define the content of the mass storage element as a tilemap. The basic
57syntax requires indicating the name of the ''source'' file that will be converted
58and inserted into the medium. If you don't want to use the same name, you can indicate
59an alias (''AS target'').
60
61@italian
62Il comando ''TILEMAP'', inserita all'interno di un blocco ''BEGIN STORAGE'' -
63''ENDSTORAGE'', permette di definire il contenuto dell'elemento di memorizzazione
64di massa come "tilemap". La sintassi di base prevede di indicare il nome del file
65sorgente che sarà convertito e inserito nel supporto. Se non si vuole utilizzare
66lo stesso nome, è possibile indicare un alias (''AS target'').
67
68@syntax TILEMAP source [AS target]
69
70@example TILEMAP "dungeon.tmx" AS "dungeon"
71
72@target all
73</usermanual> */
74Variable * tilemap_storage( Environment * _environment, char * _source_name, char * _target_name, int _mode, int _flags, int _transparent_color, int _background_color, int _bank_expansion ) {
75
76 file_storage( _environment, _source_name, _target_name, FSF_BINARY, 0 );
77
78 Variable * final = variable_temporary( _environment, VT_TILEMAP, 0 );
79
80 int width = 0;
81 int height = 0;
82 int depth = 0;
83
84 char * lookedFilename = resource_load_asserts( _environment, _source_name );
85
86 TmxMap * tilemap = tmx_load( lookedFilename );
87
88 final->originalTilemap = tilemap;
89
90 if ( !tilemap ) {
92 }
93
94 if ( !tilemap->layers ) {
96 }
97
98 if ( !tilemap->tilesets ) {
100 }
101
102 TsxTileset * tileset = tilemap->tilesets;
103
104 if ( !tileset->source ) {
105 CRITICAL_TILEMAP_SOURCE_MISSING( _source_name );
106 }
107
108 // while( tileset ) {
109 if ( final->tileset ) {
111 }
112 char * tilesetFileName = strdup( lookedFilename );
113 char * tilesetFileNameWithPath = malloc( MAX_TEMPORARY_STORAGE );
114 memset( tilesetFileNameWithPath, 0, MAX_TEMPORARY_STORAGE );
115 char * separator = strrchr( tilesetFileName, '/' );
116 if ( separator ) {
117 *(separator+1) = 0;
118 strcopy( tilesetFileNameWithPath, tilesetFileName );
119 }
120 strcat( tilesetFileNameWithPath, tileset->source );
121 lookedFilename = resource_load_asserts( _environment, tilesetFileNameWithPath );
122 Variable * tilesetVar = tileset_load( _environment, lookedFilename, NULL, _mode, _flags, _transparent_color, _background_color, _bank_expansion );
123 tilesetVar->firstGid = tileset->firstgid;
124 // tileset = tileset->next;
125 // }
126
127 char * tilesetData = tilesetVar->valueBuffer;
128 int tilesetSize = tilesetVar->size;
129
130 TmxLayer * layer = tilemap->layers;
131
132 while( layer ) {
133 // if ( final->valueBuffer ) {
134 // CRITICAL_TILEMAP_LOAD_ONLY_ONE_LAYER( _filename );
135 // }
136 int size = layer->width * layer->height;
137 char * mapData = NULL;
138 if ( final->valueBuffer ) {
139 if ( final->size != size ) {
141 }
142 mapData = realloc( final->valueBuffer, final->size + size );
143 final->valueBuffer = mapData;
144 mapData += final->size;
145 } else {
146 mapData = malloc( size );
147 final->valueBuffer = mapData;
148 }
149 memset( mapData, 0, size );
150 for(int i=0; i<size; ++i ) {
151 if ( layer->data[i] >= tilesetVar->firstGid ) {
152 mapData[i] = ((unsigned char)layer->data[i]) - (tilesetVar->firstGid);
153 } else {
154 mapData[i] = 0xff;
155 }
156 }
157 final->size += size;
158 final->mapWidth = layer->width;
159 final->mapHeight = layer->height;
160 ++final->mapLayers;
161 layer = layer->next;
162 }
163
164 char * tilemapData = final->valueBuffer;
165 int tilemapSize = final->size;
166
167 int screenWidthAsTilesConst = ( _environment->screenWidth / tilesetVar->frameWidth );
168 int screenHeightAsTilesConst = ( _environment->screenHeight / tilesetVar->frameHeight );
169 int deltaFrameConst = final->mapWidth > screenWidthAsTilesConst ? ( final->mapWidth - screenWidthAsTilesConst ) : 0;
170 int sizeConst = final->mapWidth * final->mapHeight;
171 int deltaFrameScreenConst = sizeConst - ( final->mapWidth * screenHeightAsTilesConst );
172 int mapWidth = final->mapWidth;
173 int frameWidth = tilesetVar->frameWidth;
174 int frameHeight = tilesetVar->frameHeight;
175 int mapLayers = final->mapLayers;
176 int frameSize = tilesetVar->frameSize;
177
178 // +-----+---+---------------------------------------+
179 // | 0 | 2 | Offset to tileset |
180 // +-----+---+---------------------------------------+
181 // | +2 | 1 | Screen width as tiles |
182 // +-----+---+---------------------------------------+
183 // | +3 | 1 | Screen height as tiles |
184 // +-----+---+---------------------------------------+
185 // | +4 | 1 | Delta frame |
186 // +-----+---+---------------------------------------+
187 // | +5 | 2 | Size (w x h) |
188 // +-----+---+---------------------------------------+
189 // | +7 | 2 | Delta Frame Screen |
190 // +-----+---+---------------------------------------+
191 // | +9 | 1 | Map width |
192 // +-----+---+---------------------------------------+
193 // | +10 | 1 | Frame width |
194 // +-----+---+---------------------------------------+
195 // | +11 | 1 | Frame height |
196 // +-----+---+---------------------------------------+
197 // | +12 | 1 | Map layers |
198 // +-----+---+---------------------------------------+
199 // | +13 | 2 | Frame size |
200 // +-----+---+---------------------------------------+
201 // | +15 | |
202 // +-----+-------------------------------------------+
203 //
204 // 1) TILEMAP
205 // 2) TILESET
206
207 int size = tilesetSize + tilemapSize + 15;
208 char * data = malloc( tilesetSize + tilemapSize + 15 );
209
210#ifdef CPU_BIG_ENDIAN
211 data[1] = ( tilemapSize & 0xff );
212 data[0] = ( ( tilemapSize >> 8 ) & 0xff );
213#else
214 data[0] = ( tilemapSize & 0xff );
215 data[1] = ( ( tilemapSize >> 8 ) & 0xff );
216#endif
217
218 // printf( " tilemapSize = %d (%4.4x)\n", tilemapSize, tilemapSize );
219
220 data[2] = ( screenWidthAsTilesConst & 0xff );
221
222 // printf( " screenWidthAsTilesConst = %d (%2.2x)\n", screenWidthAsTilesConst, screenWidthAsTilesConst );
223
224 data[3] = ( screenHeightAsTilesConst & 0xff );
225
226 // printf( " screenHeightAsTilesConst = %d (%2.2x)\n", screenHeightAsTilesConst, screenHeightAsTilesConst );
227
228 data[4] = ( deltaFrameConst & 0xff );
229
230 // printf( " deltaFrameConst = %d (%2.2x)\n", deltaFrameConst, deltaFrameConst );
231
232#ifdef CPU_BIG_ENDIAN
233 data[6] = ( sizeConst & 0xff );
234 data[5] = ( ( sizeConst >> 8 ) & 0xff );
235#else
236 data[5] = ( sizeConst & 0xff );
237 data[6] = ( ( sizeConst >> 8 ) & 0xff );
238#endif
239
240 // printf( " sizeConst = %d (%2.2x)\n", sizeConst, sizeConst );
241
242#ifdef CPU_BIG_ENDIAN
243 data[8] = ( deltaFrameScreenConst & 0xff );
244 data[7] = ( ( deltaFrameScreenConst >> 8 ) & 0xff );
245#else
246 data[7] = ( deltaFrameScreenConst & 0xff );
247 data[8] = ( ( deltaFrameScreenConst >> 8 ) & 0xff );
248#endif
249
250 // printf( " deltaFrameScreenConst = %d (%2.2x)\n", deltaFrameScreenConst, deltaFrameScreenConst );
251
252 data[9] = ( mapWidth & 0xff );
253
254 // printf( " mapWidth = %d (%2.2x)\n", mapWidth, mapWidth );
255
256 data[10] = ( frameWidth & 0xff );
257
258 // printf( " frameWidth = %d (%2.2x)\n", frameWidth, frameWidth );
259
260 data[11] = ( frameHeight & 0xff );
261
262 // printf( " frameHeight = %d (%2.2x)\n", frameHeight, frameHeight );
263
264 data[12] = ( mapLayers & 0xff );
265
266 // printf( " mapLayers = %d (%2.2x)\n", mapLayers, mapLayers );
267
268#ifdef CPU_BIG_ENDIAN
269 data[14] = ( frameSize & 0xff );
270 data[13] = ( ( frameSize >> 8 ) & 0xff );
271#else
272 data[13] = ( frameSize & 0xff );
273 data[14] = ( ( frameSize >> 8 ) & 0xff );
274#endif
275
276 // printf( " frameSize = %d (%4.4x)\n", frameSize, frameSize );
277
278 memcpy( &data[15], tilemapData, tilemapSize );
279 memcpy( &data[15+tilemapSize], tilesetData, tilesetSize );
280
281 _environment->currentFileStorage->size = size;
282 _environment->currentFileStorage->content = data;
283
284 // printf( "size tileset = %d\n", tilesetSize );
285
286 // printf( "size total = %d\n", size );
287
288 variable_temporary_remove( _environment, tilesetVar->name );
289
290 return final;
291
292}
void variable_temporary_remove(Environment *_environment, char *_name)
char * resource_load_asserts(Environment *_environment, char *_filename)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
int size
Definition _optimizer.c:678
void file_storage(Environment *_environment, char *_source_name, char *_target_name, FileStorageFormat _format, VariableType _type)
Emit code for FILE ... AS ....
FileStorage * currentFileStorage
Definition ugbc.h:2536
int screenHeight
Definition ugbc.h:2860
int screenWidth
Definition ugbc.h:2855
int size
Definition ugbc.h:204
char * content
Definition ugbc.h:210
int width
Definition tmx.h:62
struct _TmxLayer * next
Definition tmx.h:67
int * data
Definition tmx.h:65
int height
Definition tmx.h:63
struct _TsxTileset * tilesets
Definition tmx.h:85
struct _TmxLayer * layers
Definition tmx.h:87
int firstgid
Definition tsx.h:66
char * source
Definition tsx.h:61
unsigned char * valueBuffer
Definition ugbc.h:1061
int firstGid
Definition ugbc.h:1166
int size
Definition ugbc.h:1077
char * name
Definition ugbc.h:979
int frameSize
Definition ugbc.h:1134
int frameWidth
Definition ugbc.h:1162
int frameHeight
Definition ugbc.h:1164
Variable * tilemap_storage(Environment *_environment, char *_source_name, char *_target_name, int _mode, int _flags, int _transparent_color, int _background_color, int _bank_expansion)
Emit code for LOAD TILEMAP(...).
Variable * tileset_load(Environment *_environment, char *_filename, char *_alias, int _mode, int _flags, int _transparent_color, int _background_color, int _bank_expansion)
Emit code for LOAD TILESERT(...).
TmxMap * tmx_load(char *_filename)
Definition tmx.c:48
struct _TmxMap TmxMap
struct _TmxLayer TmxLayer
struct _TsxTileset TsxTileset
void * malloc(YYSIZE_T)
#define CRITICAL_TILEMAP_LOAD_ONLY_ONE_TILESET(v)
Definition ugbc.h:3641
#define CRITICAL_TILEMAP_LOAD_UNKNOWN_FORMAT(v)
Definition ugbc.h:3638
#define CRITICAL_TILEMAP_LOAD_ONLY_SAME_SIZE_LAYER(v)
Definition ugbc.h:3653
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
@ FSF_BINARY
Definition ugbc.h:251
#define CRITICAL_TILEMAP_SOURCE_MISSING(v)
Definition ugbc.h:3705
struct _Variable Variable
Structure of a single variable.
#define CRITICAL_TILEMAP_LOAD_MISSING_TILESET(v)
Definition ugbc.h:3640
struct _Environment Environment
Structure of compilation environment.
@ VT_TILEMAP
Definition ugbc.h:525
#define CRITICAL_TILEMAP_LOAD_MISSING_LAYER(v)
Definition ugbc.h:3639
char * strcopy(char *_dest, char *_source)