ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
tileset_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 TILESET (storage)
53
54@english
55The ''TILESET'' command, inserted inside a ''BEGIN STORAGE'' - ''ENDSTORAGE'' block,
56allows you to define the content of the mass storage element as a tileset. 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 ''TILESET'', inserita all'interno di un blocco ''BEGIN STORAGE'' -
63''ENDSTORAGE'', permette di definire il contenuto dell'elemento di memorizzazione
64di massa come "tileset". 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 TILESET source [AS dest]
69
70@example TILESET "tiles.tsx" AS "tiles"
71
72@target all
73</usermanual> */
74Variable * tileset_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_IMAGES, 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 TsxTileset * tileset = tsx_load( lookedFilename );
87
88 final->originalTileset = tileset;
89
90 if ( !tileset ) {
92 }
93
94 if ( !tileset->image ) {
96 }
97
99 int i,di,x=0,y=0,z=0;
100 int bufferSize = 0;
101
102 TsxImage * tsxImage = tileset->image;
103
104 char * filename = strdup( _source_name );
105 char * filenameWithPath = malloc( 1024 );
106 memset( filenameWithPath, 0, 1024 );
107 char * separator = strrchr( filename, '/' );
108 if ( separator ) {
109 *(separator+1) = 0;
110 strcopy( filenameWithPath, filename );
111 }
112 strcat( filenameWithPath, tsxImage->source );
113
114 AtlasDescriptor * atlasDescriptor = atlas_descriptor_create( _environment, filenameWithPath, _flags, tileset->margin, tileset->margin, tileset->tilewidth, tileset->tileheight, tileset->spacing, tileset->spacing );
115
116 ImageDescriptor * frame = atlasDescriptor->frames;
117 for( int i=0; i<atlasDescriptor->count; ++i ) {
118 result[i] = image_converter( _environment, frame->data, frame->width, frame->height, frame->depth, 0, 0, tileset->tilewidth, tileset->tileheight, _mode, _transparent_color, _flags );
119 bufferSize += result[i]->size;
120 frame = frame->next;
121 }
122
123 bufferSize += 3;
124
125 char * buffer = malloc( bufferSize );
126 char * ptr = buffer;
127 ptr[0] = atlasDescriptor->count;
128 ptr[1] = ( tileset->tilewidth & 0xff );
129 ptr[2] = ( tileset->tilewidth >> 8 ) & 0xff;
130
131 if ( ( result[0]->size * atlasDescriptor->count ) > 0xffff ) {
133 }
134
135 final->offsettingFrames = offsetting_size_count( _environment, result[0]->size, atlasDescriptor->count );
136 offsetting_add_variable_reference( _environment, final->offsettingFrames, final, 0 );
137
138 ptr += 3;
139 for(int i=0; i<atlasDescriptor->count; ++i ) {
140 memcpy( ptr, result[i]->valueBuffer, result[i]->size );
141 ptr += result[i]->size;
142 }
143 variable_store_buffer( _environment, final->name, buffer, bufferSize, 0 );
144 final->originalBitmap = atlasDescriptor->image->data;
145 final->originalWidth = atlasDescriptor->image->width;
146 final->originalHeight = atlasDescriptor->image->height;
147 final->originalDepth = atlasDescriptor->image->depth;
148 final->originalColors = atlasDescriptor->image->colorsCount;
149 memcpy( final->originalPalette, atlasDescriptor->image->colors, MAX_PALETTE * sizeof( RGBi ) );
150 final->frameWidth = tileset->tilewidth;
151 final->frameHeight = tileset->tileheight;
152 final->firstGid = tileset->firstgid;
153 final->frameSize = result[0]->size;
154 final->frameCount = atlasDescriptor->count;
155
156 for(int i=0; i<atlasDescriptor->count; ++i ) {
157 variable_temporary_remove( _environment, result[i]->name );
158 }
159
160 // stbi_image_free(source);
161
162 if ( ( _flags & FLAG_COMPRESSED ) && !_environment->compressionForbidden ) {
163
164 // Try to compress the result of image conversion.
165 // This means that the buffer will be compressed using MSC1
166 // algorithm, up to 32 frequent sequences. The original size of
167 // the buffer will be considered as "uncompressed" size.
168 MSC1Compressor * compressor = msc1_create( 32 );
169 final->uncompressedSize = final->size;
170 MemoryBlock * output = msc1_compress( compressor, final->valueBuffer, final->uncompressedSize, &final->size );
171
172 int temporary;
173 MemoryBlock * outputCheck = msc1_uncompress( compressor, output, final->size, &temporary );
174 if ( memcmp( outputCheck, final->valueBuffer, final->uncompressedSize ) != 0 ) {
175 CRITICAL_COMPRESSION_FAILED(_source_name);
176 }
177 msc1_free( compressor );
178 // printf( "%s: %d bytes -> %d bytes\n", _filename, final->uncompressedSize, final->size );
179 // If the compressed memory is greater than the original
180 // size, we discard the compression and we will continue as
181 // usual.
182 if ( final->uncompressedSize < final->size ) {
183 final->size = final->uncompressedSize;
184 final->uncompressedSize = 0;
185 free( output );
186 }
187 // Otherwise, we can safely replace the original data
188 // buffer with the compressed one.
189 else {
190 free( final->valueBuffer );
191 final->valueBuffer = output;
192 }
193 final->residentAssigned = 1;
194 _environment->maxExpansionBankSize[1] = BANK_SIZE;
195
196 }
197
198 _environment->currentFileStorage->size = final->size;
199 _environment->currentFileStorage->content = final->valueBuffer;
200
201 return final;
202
203}
void variable_temporary_remove(Environment *_environment, char *_name)
char * resource_load_asserts(Environment *_environment, char *_filename)
void offsetting_add_variable_reference(Environment *_environment, Offsetting *_first, Variable *_var, int _sequence)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
Offsetting * offsetting_size_count(Environment *_environment, int _size, int _count)
Variable * variable_store_buffer(Environment *_environment, char *_destination, unsigned char *_buffer, int _size, int _at)
int size
Definition _optimizer.c:678
char * name
Definition _optimizer.c:672
Variable * image_converter(Environment *_environment, char *_data, int _width, int _height, int _depth, int _offset_x, int _offset_y, int _frame_width, int _frame_height, int _mode, int _transparent_color, int _flags)
#define BANK_SIZE
Definition atari.h:146
AtlasDescriptor * atlas_descriptor_create(Environment *_environment, char *_filename, int _flags, int _image_origin_x, int _image_origin_y, int _frame_width, int _frame_height, int _frame_offset_x, int _frame_offset_y)
void file_storage(Environment *_environment, char *_source_name, char *_target_name, FileStorageFormat _format, VariableType _type)
Emit code for FILE ... AS ....
MSC1Compressor * msc1_create(int _maximum_repeated_sequences)
Definition msc1.c:300
void msc1_free(MSC1Compressor *_msc1)
Definition msc1.c:740
MemoryBlock * msc1_uncompress(MSC1Compressor *_msc1, MemoryBlock *_input, int _size, int *_output_size)
Definition msc1.c:746
MemoryBlock * msc1_compress(MSC1Compressor *_msc1, MemoryBlock *_input, int _size, int *_output_size)
Definition msc1.c:381
unsigned char MemoryBlock
Definition msc1.h:90
struct _MSC1Compressor MSC1Compressor
struct _ImageDescriptor * frames
Definition ugbc.h:939
struct _ImageDescriptor * image
Definition ugbc.h:925
int compressionForbidden
Definition ugbc.h:3169
int maxExpansionBankSize[MAX_RESIDENT_SHAREDS]
Definition ugbc.h:3010
FileStorage * currentFileStorage
Definition ugbc.h:2536
int size
Definition ugbc.h:204
char * content
Definition ugbc.h:210
int colorsCount
Definition ugbc.h:918
RGBi * colors
Definition ugbc.h:917
char * data
Definition ugbc.h:911
struct _ImageDescriptor * next
Definition ugbc.h:919
char * source
Definition tsx.h:40
int spacing
Definition tsx.h:68
struct _TsxImage * image
Definition tsx.h:70
int margin
Definition tsx.h:67
int tilewidth
Definition tsx.h:62
int firstgid
Definition tsx.h:66
int tileheight
Definition tsx.h:63
int size
Definition ugbc.h:1077
Variable * tileset_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 TILESERT(...).
TsxTileset * tsx_load(char *_filename)
Definition tsx.c:47
struct _TsxTileset TsxTileset
struct _TsxImage TsxImage
void * malloc(YYSIZE_T)
void free(void *)
#define FLAG_COMPRESSED
Definition ugbc.h:4570
struct _ImageDescriptor ImageDescriptor
struct _RGBi RGBi
Structure to store color components (red, green and blue).
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
@ FSF_BINARY
Definition ugbc.h:251
#define CRITICAL_TILESET_LOAD_IMAGE_TOO_BIG(v)
Definition ugbc.h:3665
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_IMAGES
Definition ugbc.h:495
struct _AtlasDescriptor AtlasDescriptor
#define CRITICAL_TILESET_LOAD_MISSING_IMAGE(v)
Definition ugbc.h:3632
#define MAX_PALETTE
Definition ugbc.h:568
#define CRITICAL_COMPRESSION_FAILED(v)
Definition ugbc.h:3768
#define CRITICAL_TILESET_LOAD_UNKNOWN_FORMAT(v)
Definition ugbc.h:3631
char * strcopy(char *_dest, char *_source)