ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
tiles_load.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
38/****************************************************************************
39 * CODE SECTION
40 ****************************************************************************/
41
49/* <usermanual>
50@keyword LOAD TILES
51
52@english
53
54The ''LOAD TILES'' command allows you to load an image and to convert it into
55multiple ''TILE'', that is a format that will be converted into a way that can be efficiently drawn
56on the screen using the tiles. The second parameter is the mode to use to convert
57the given data (by default, it is equal to current mode)
58
59The command support a set of modern image format, like JPEG baseline & progressive,
60PNG 1/2/4/8/16-bit-per-channel, TGA, BMP (non-1bpp, non-RLE), PSD
61(composited view only, no extra channels, 8/16 bit-per-channel),
62GIF, HDR (radiance rgbE format), PIC (Softimage PIC) and PNM (PPM and PGM
63binary only) The image will be converted into a way that can be
64efficiently drawn on the screen.
65
66Since it is possible to load only one file of the same
67type at a time, it is necessary to be able to indicate an "alias" with
68which to exceed this limit. In this regard, there is also
69the ''AS'' syntax, which allows you to load the same file several
70times but with different names.
71
72A series of flags, separated by spaces, can be added at loading time
73to modify the behavior of ugBASIC.
74
75The ''FLIP X'' flag allows you to flip the image horizontally,
76before translating it into the native format. The same is true for the
77''FLIP Y'' command, which instead inverts the image vertically.
78There is also the ''FLIP XY'' (or ''FLIP YX'') parameter to act,
79simultaneously, on both directions.
80
81The ''COMPRESSED'' flag allows you to compress the image, if
82possible. Compression is a space-saving mechanism, in which the
83native data of the image is represented in a more compact form,
84which ugBASIC will be able to quickly convert into graphics at
85the appropriate time.
86
87The ''ROLL X'' flag allows you to SHIFT the (entire) image horizontally,
88for the entire size of a frame, in order to generate intermediate
89frames. The very same for ''ROLL Y'' command, which does the same
90vertically. There is also the ''ROLL XY'' (or ''ROLL YX'') parameter to act,
91simultaneously, on both directions.
92
93@italian
94
95Il comando ''LOAD TILES'' consente di caricare un'immagine e convertirla in
96una ''TILE''. Il secondo parametro è la modalità da utilizzare per convertire
97i dati forniti (per impostazione predefinita, è uguale alla modalità corrente)
98
99Il comando supporta un set di formati immagine moderni, come JPEG baseline e progressivo,
100PNG 1/2/4/8/16 bit per canale, TGA, BMP (non 1bpp, non RLE), PSD
101(solo vista composita, nessun canale extra, 8/16 bit per canale),
102GIF, HDR (formato radiance rgbE), PIC (Softimage PIC) e PNM (solo PPM e PGM
103binary). L'immagine verrà convertita in un modo che può essere
104disegnata in modo efficiente sullo schermo.
105
106Poiché è possibile caricare un solo file dello stesso
107tipo alla volta, è necessario poter indicare un "alias" con
108il quale superare questo limite. A questo proposito, esiste anche
109la sintassi ''AS'', che consente di caricare più volte lo stesso
110file ma con nomi diversi.
111
112Una serie di flag, separati da spazi, possono essere aggiunti in fase di caricamento
113per modificare il comportamento di ugBASIC.
114
115Il flag ''FLIP X'' consente di capovolgere l'immagine orizzontalmente,
116prima di tradurla nel formato nativo. Lo stesso vale per il
117comando ''FLIP Y'', che invece inverte l'immagine verticalmente.
118Esiste anche il parametro ''FLIP XY'' (o ''FLIP YX'') per agire,
119contemporaneamente, su entrambe le direzioni.
120
121Il flag ''ROLL X'' consente di spostare l'intera immagine in orizzontale,
122per l'intera dimensione di un frame, per generare i fotogrammi intercalari.
123Lo stesso per il flag ''ROLL Y'', che fa lo stesso verticalmente, e
124''ROLL XY '' (o ''ROLL YX'') per agire, contemporaneamente, su entrambe le
125 direzioni.
126
127Il flag ''COMPRESSED'' consente di comprimere l'immagine, se
128possibile. La compressione è un meccanismo di risparmio di spazio, in cui i dati nativi dell'immagine sono rappresentati in una forma più compatta, che
129ugBASIC sarà in grado di convertire rapidamente in grafica al momento opportuno.
130
131L'immagine può essere caricata come immagine trasparente (se l'immagine originale
132non ha trasparenza) utilizzando la parola chiave ''TRANSPARENCY'',
133seguita da un parametro opzionale che rappresenta il colore
134da considerare come trasparente.
135
136L'immagine può essere caricata come immagine trasparente (se l'immagine originale non ha trasparenza) usando la parola chiave ''OPACITY'',
137seguita da un parametro opzionale che rappresenta il colore
138da considerare come pavimentazione.
139
140L'immagine può essere caricata direttamente nella memoria di espansione
141usando la parola chiave BANKED. Il numero rappresenta
142il residente condiviso da usare come target per questa immagine.
143Per alcuni target questa è l'impostazione predefinita. Se vuoi,
144puoi spostare l'immagine nella memoria residente
145usando la parola chiave ''UNBANKED''.
146
147Infine, se non è previsto che l'immagine cambi durante il gioco, può essere contrassegnata
148con l'attributo ''READONLY'': in questo caso, l'immagine verrà archiviata
149nella memoria di sola lettura, se disponibile.
150
151@syntax = LOAD TILE( filename [AS alias][,mode] ) [fl]
152@syntax fl : [FLIP X] [FLIP Y] [FLIP XY] [FLIP YX]
153@syntax fl : [ROLL X] [ROLL Y] [ROLL XY] [ROLL YX]
154
155@example starship = LOAD TILES("starship.png")
156@example starship2 = LOAD TILES("starship.png" AS "starship2")
157@example alienAt11 = LOAD TILES("alien.jpg",11)
158@example alien2 = LOAD TILES("alien.jpg" AS "alien2",11)
159
160@alias TILES LOAD
161@alias FONT LOAD
162</usermanual> */
163
164/* <usermanual>
165@keyword TILES LOAD
166@alias LOAD TILES
167@alias FONT LOAD
168</usermanual> */
169
170/* <usermanual>
171@keyword FONT LOAD
172@alias LOAD TILES
173@alias TILES LOAD
174</usermanual> */
175
176Variable * tiles_load( Environment * _environment, char * _filename, int _flags, char * _tileset, int _index ) {
177
178 Variable * tileset = NULL;
179
180 if ( _tileset ) {
181 tileset = variable_retrieve( _environment, _tileset );
182 if ( tileset->type != VT_TILESET ) {
184 }
185 if ( ! _environment->tilesets[tileset->value] ) {
187 }
188 }
189
190 if ( _environment->tenLinerRulesEnforced ) {
191 CRITICAL_10_LINE_RULES_ENFORCED( "LOAD TILES");
192 }
193
194 if ( _environment->sandbox ) {
195 CRITICAL_SANDBOX_ENFORCED( "LOAD TILES");
196 }
197
198 int width = 0;
199 int height = 0;
200 int depth = 0;
201
202 // printf( "Allocating tiles (%s)\n", _filename );
203
204 char * lookedFilename = resource_load_asserts( _environment, _filename );
205
206 adiline2("LTS:%s:%s", _filename, lookedFilename );
207
208 unsigned char* source = stbi_load(lookedFilename, &width, &height, &depth, 0);
209
210 if ( !source ) {
212 }
213
214 if ( width % 8 ) {
216 }
217
218 if ( height % 8 ) {
220 }
221
222 if( _flags & FLAG_FLIP_X ) {
223 source = image_flip_x( _environment, source, width, height, depth );
224 }
225 if( _flags & FLAG_FLIP_Y ) {
226 source = image_flip_y( _environment, source, width, height, depth );
227 }
228
229 TileDescriptors * descriptors;
230
231 if ( tileset ) {
232 descriptors = _environment->tilesets[tileset->value];
233 } else {
234 if ( ! _environment->descriptors ) {
235 font_descriptors_init( _environment, 0 );
236 if ( _environment->fontConfig.optimized ) {
237 int count = (width/8)*(height/8);
238 if ( count < (_index+1) ) {
239 count = (_index+1);
240 }
241 _environment->descriptors->count = count;
242 _environment->descriptors->first = 0;
243 _environment->descriptors->firstFree = _environment->descriptors->first;
244 _environment->descriptors->lastFree = 255;
245 }
246 } else {
247 if ( _environment->descriptors->count < (_index+1) ) {
248 _environment->descriptors->count = (_index+1);
249 }
250 }
251 descriptors = _environment->descriptors;
252 }
253
254 Variable * index = variable_temporary( _environment, VT_TILES, "(tile index)" );
255
256 int x, y;
257
258 int firstTile = _index;
259
260 int z = 0, a = 1;
261
262 if ( _flags & FLAG_ROLL_X ) {
263 a = a * width;
264 source = image_enlarge_right( _environment, source, width, height, 8 );
265 width += 8;
266 }
267
268 if ( _flags & FLAG_ROLL_Y ) {
269 a = a * height;
270 source = image_enlarge_bottom( _environment, source, width, height, 8 );
271 height += 8;
272 }
273
274 for( z=0; z<a; ++z ) {
275 for (y=0; y<(height>>3);++y) {
276 for (x=0; x<(width>>3);++x) {
277 // Variable * realImage = image_converter( _environment, source, width, height, depth, x*8, y*8, 8, 8, BITMAP_MODE_DEFAULT, 0, _flags );
278
279 unsigned char * realSource = source + (y*8) * width * depth + (x*8) * depth;
280
281 unsigned char fontData[8];
282 memset( fontData, 0, 8 );
283
284 for( int yy = 0; yy < 8; ++yy ) {
285 for( int xx = 0; xx < 8; ++xx ) {
286
287 RGBi rgb;
288
289 // Take the color of the pixel
290 rgb.red = *realSource;
291 rgb.green = *(realSource + 1);
292 rgb.blue = *(realSource + 2);
293 if ( depth > 3 ) {
294 rgb.alpha = *(realSource + 3);
295 } else {
296 rgb.alpha = 255;
297 }
298 if ( rgb.alpha == 0 ) {
299 rgb.red = 0;
300 rgb.green = 0;
301 rgb.blue = 0;
302 }
303
304 // Calculate the offset starting from the tile surface area
305 // and the bit to set.
306 int offset = yy;
307 int bitmask = 1 << ( 7 - (xx & 0x7) );
308
309 if ( ( rgb.alpha < 255 ) || ( rgb.red + rgb.green + rgb.blue ) == 0 ) {
310 *( fontData + offset ) &= ~bitmask;
311 } else {
312 *( fontData + offset ) |= bitmask;
313 }
314
315 realSource += depth;
316
317 }
318
319 realSource += ( width - 8 ) * depth;
320
321 }
322
323 if ( _index == -1 ) {
324 int tile = tile_allocate( descriptors, fontData );
325
326 if ( firstTile == -1 ) {
327 firstTile = tile;
328 }
329
330 if ( tile == -1 ) {
332 }
333
334 _index = -1;
335
336 } else {
337 memcpy( descriptors->data[_index].data, fontData, 8 );
338 descriptors->descriptor[_index] = calculate_tile_descriptor( &descriptors->data[_index] );
339 ++_index;
340 }
341
342 // variable_delete( _environment, realImage->name );
343
344 }
345 }
346 if ( _flags & FLAG_ROLL_X ) {
347 source = image_roll_x_right( _environment, source, width, height );
348 }
349 if ( _flags & FLAG_ROLL_Y ) {
350 source = image_roll_y_down( _environment, source, width, height );
351 }
352 }
353
354 if ( a > 1 ) {
355 if ( ( ( width >> 3 ) * ( height >> 3 ) * a ) > 0xffff ) {
357 }
358
359 offsetting_size_count( _environment, ( width >> 3 ) * ( height >> 3 ), a );
360 index->originalWidth = width;
361 index->originalHeight = height;
362 index->originalDepth = depth;
363 }
364
365 cpu_store_32bit( _environment, index->realName,
366 firstTile |
367 ( ( width >> 3 ) << 8 ) |
368 ( ( height >> 3 ) << 16 ) |
369 ( a << 24 ) |
370 ( _flags & FLAG_ROLL_Y ? (1<<31) : (0) ) |
371 ( _flags & FLAG_ROLL_X ? (1<<30) : (0) )
372 );
373
375
376 // printf( "Last tile = %d\n", descriptors->firstFree );
377
378 // if ( ( descriptors->firstFree % TILES_PADDING ) ) {
379 // printf( "Padding with %d ", TILES_PADDING-( _environment->descriptors->firstFree % TILES_PADDING ) );
380 // descriptors->firstFree += TILES_PADDING-( _environment->descriptors->firstFree % TILES_PADDING );
381 // printf( "Last tile = %d\n", descriptors->firstFree );
382 // }
383
384 return index;
385
386}
void cpu_store_32bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 32 bit
Definition 6309.c:2540
Variable * variable_retrieve(Environment *_environment, char *_name)
int tile_allocate(TileDescriptors *_tiles, char *_data)
char * image_roll_y_down(Environment *_environment, char *_source, int _width, int _height)
char * image_flip_y(Environment *_environment, char *_source, int _width, int _height, int _depth)
TileDescriptor * calculate_tile_descriptor(TileData *_tileData)
char * image_roll_x_right(Environment *_environment, char *_source, int _width, int _height)
char * image_flip_x(Environment *_environment, char *_source, int _width, int _height, int _depth)
char * image_enlarge_right(Environment *_environment, char *_source, int _width, int _height, int _delta)
char * resource_load_asserts(Environment *_environment, char *_filename)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
Offsetting * offsetting_size_count(Environment *_environment, int _size, int _count)
void font_descriptors_init(Environment *_environment, int _embedded_present)
char * image_enlarge_bottom(Environment *_environment, char *_source, int _width, int _height, int _delta)
int offset
Definition _optimizer.c:681
STBIDEF void stbi_image_free(void *retval_from_stbi_load)
STBIDEF stbi_uc * stbi_load(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels)
TileDescriptors * tilesets[MAX_TILESETS]
Definition ugbc.h:2949
int sandbox
Definition ugbc.h:2990
int tenLinerRulesEnforced
Definition ugbc.h:2985
FontConfig fontConfig
Definition ugbc.h:2415
TileDescriptors * descriptors
Definition ugbc.h:2939
int optimized
Definition ugbc.h:2064
unsigned char red
Definition ugbc.h:433
unsigned char green
Definition ugbc.h:434
unsigned char blue
Definition ugbc.h:435
unsigned char alpha
Definition ugbc.h:436
char data[8]
Definition ugbc.h:2141
TileData data[512]
Definition ugbc.h:2153
TileDescriptor * descriptor[512]
Definition ugbc.h:2152
int originalHeight
Definition ugbc.h:1148
int originalDepth
Definition ugbc.h:1151
VariableType type
Definition ugbc.h:988
int originalWidth
Definition ugbc.h:1145
int value
Definition ugbc.h:1025
char * realName
Definition ugbc.h:982
Variable * tiles_load(Environment *_environment, char *_filename, int _flags, char *_tileset, int _index)
Emit code for LOAD TILE(...).
Definition tiles_load.c:176
#define CRITICAL_10_LINE_RULES_ENFORCED(v)
Definition ugbc.h:3550
struct _RGBi RGBi
Structure to store color components (red, green and blue).
#define CRITICAL_CANNOT_ALLOCATE_MORE_TILE()
Definition ugbc.h:3556
struct _TileDescriptors TileDescriptors
#define FLAG_ROLL_Y
Definition ugbc.h:4557
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
#define FLAG_FLIP_X
Definition ugbc.h:4553
@ VT_TILES
Definition ugbc.h:507
@ VT_TILESET
Definition ugbc.h:510
#define CRITICAL_TILE_LOAD_UNKNOWN_FORMAT(f)
Definition ugbc.h:3558
#define CRITICAL_SANDBOX_ENFORCED(v)
Definition ugbc.h:3687
#define CRITICAL_TILE_LOAD_ON_NON_TILESET(t)
Definition ugbc.h:3561
#define CRITICAL_TILE_INVALID_HEIGHT(h)
Definition ugbc.h:3560
#define FLAG_FLIP_Y
Definition ugbc.h:4554
#define CRITICAL_TILES_LOAD_IMAGE_TOO_BIG(v)
Definition ugbc.h:3664
#define CRITICAL_TILE_INVALID_WIDTH(w)
Definition ugbc.h:3559
#define adiline2(s, a, b)
Definition ugbc.h:4192
#define FLAG_ROLL_X
Definition ugbc.h:4555