ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
msprite_init.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"
36
37/****************************************************************************
38 * CODE SECTION
39 ****************************************************************************/
40
41#if defined(__c64__) || defined(__c64reu__) || defined(__c128__)
42
49/* <usermanual>
50@keyword MSPRITE (function)
51
52@english
53
54This statement allows you to define a multiplexed sprite. These objects are
55managed entirely by ugBASIC, and using ''SPRITE'' as usual. A multiplexed
56sprite is a composition of composite sprite where each element of the
57composition is done by using a virtual sprite that, in turns, use a
58real (hardware) sprite.
59
60sprites where images are cropped, the size of a multiplexed sprite is taken
61directly from the image data, and it is rounded to the underlying hardware
62size (so a 32x32 monochromatic image as above will be converted into 4
63hardware sprites of 24x21 pixels). So, if the hardware sprites cannot
64be resized, a part of the area inside these sprites is wasted, and
65that you need more than one sprite to represent a large image.
66
67The maximum of eight hardware sprites therefore imposes a strict limit
68to the number of such objects you can display on a horizontal line.
69The total width of the objects must not exceed:
7024*8=192 pixels (for monochrome sprites)
7116*4=96 pixels (for two colors sprites)
7216*2=48 pixels (for four colors sprites)
7316*1=24 pixels (for eight colors sprites)
74
75If you try to ignore this limitation, you won't get an error message,
76but your multiplexed sprite will not be displayed on the screen. So
77it's vital to ensure that the above restriction is respected.
78
79The function accepts the ''name'' of a graphic resource, among those previously
80loaded. This must correspond to a single image: therefore it can be an image
81or a frame of an ''ATLAS'' or a ''SEQUENCE''. The system, in a completely
82automatic way, will convert the resource into graphic data compatible with the
83sprite format.
84
85The command accepts a series of parameters, which can be added after the
86name of the graphic resource. The ''EXPAND VERTICAL'' parameter allows you
87to double the vertical dimensions, making each pixel occupy two or more
88vertical pixels. On the other hand, the ''COMPRESS VERTICAL'' command allows
89you to restore the original dimensions. The ''EXPAND HORIZONTAL'' parameter
90allows you to double the vertical dimensions, making each pixel occupy
91two or more vertical pixels. On the other hand, the ''COMPRESS HORIZONTAL''
92command allows you to restore the original dimensions. Finally, it is possible
93to indicate one of the colors in the palette as "transparent", and therefore
94that it does not need to generate a hardware sprite. This can be useful where
95the graphic resource does not use the color black, which is the standard color
96to characterize the background. Due to the isomorphic nature of the language,
97not all flags are usable, or have an effect, on all targets that support sprites.
98
99The function provides additional syntax, valid for redefining a sprite already
100defined. The purpose of such syntax is to modify the graphic information inherent
101to a sprite already defined previously, thus being able to dynamically replace the
102appearance of the sprite. In this case, it is necessary to provide a reference to
103the previously defined sprite (''previous''), and ensure that the graphic
104characteristics (such as the number of colors) are identical.
105
106An additional syntax allows you to "duplicate" a sprite, thus sharing its
107graphic resources. Simply pass the reference to a previous MSPRITE to define
108it.
109
110@italian
111
112@syntax = MSPRITE ( name flags )
113@syntax = MSPRITE ( name, previous flags )
114@syntax = MSPRITE ( msprite )
115
116@example spaceshift = MSPRITE( LOAD IMAGE( "spaceship.png" ) IGNORE COLOR GREEN )
117@example alien = MSPRITE( LOAD IMAGE( "alien1.png" ) )
118@example alien = MSPRITE( LOAD IMAGE( "alien2.png" ), alien )
119
120@seeAlso CSPRITE
121@seeAlso SPRITE
122
123@target c64
124@target c128
125@target c64reu
126</usermanual> */
127
128Variable * msprite_init( Environment * _environment, char * _image, char * _sprite, int _flags ) {
129
130 if ( _environment->deployed.sprite ) {
132 }
133
134 Variable * index;
135 Variable * startIndex;
136 Variable * spriteCount;
137 Variable * result = variable_temporary( _environment, VT_MSPRITE, "(sprite index)" );
138
139 index = variable_temporary( _environment, VT_MSPRITE, "(sprite index)" );
140 spriteCount = variable_retrieve( _environment, "SPRITECOUNT" );
141 startIndex = variable_temporary( _environment, VT_MSPRITE, "(sprite index)" );
142
143 if ( _sprite ) {
144 Variable * original = variable_retrieve_or_define( _environment, _sprite, VT_MSPRITE, 0 );
145 cpu_move_8bit( _environment, original->realName, startIndex->realName );
146 cpu_move_8bit( _environment, original->realName, result->realName );
147 } else {
148 cpu_move_8bit( _environment, spriteCount->realName, startIndex->realName );
149 cpu_move_8bit( _environment, spriteCount->realName, result->realName );
150 }
151
152 Variable * image = variable_retrieve( _environment, _image );
153
154 // +---+------------- width in sprites (00 = 1, 01 = 2, 10 = 3, 11 = 4)
155 // | | +---+----- height in sprites (00 = 1, 01 = 2, 10 = 3, 11 = 4)
156 // | | | |
157 // +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
158 // | M | c | c | c | x | x | y | y | | n | n | n | n | n | n | n | n |
159 // +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
160 // +-+---+---+---------------------+ +-------------------------------+
161 // | | | | (VT_MSPRITE+1) (VT_MSPRITE+0)
162 // | | | |
163 // | +---+---+-- number of colors
164 // +-------------- multicolor (0 = no / 1 = yes) [UNUSED]
165
166 int y_slots = 1 + ( (image->originalHeight-1) / 21 );
167 int x_slots = 0;
168 // if ( _flags & SPRITE_FLAG_MULTICOLOR) {
169 // x_slots = ( (image->originalWidth-1) / 12 ) + 1;
170 // } else {
171 x_slots = ( (image->originalWidth-1) / 24 ) + 1;
172 // }
173
174 int colorTransparency = COLOR_BLACK;
175
176 if ( _flags & SPRITE_FLAG_TRANSPARENCY_COLOR ) {
177 colorTransparency = _flags & 0x000f;
178 }
179
180 RGBi palette[MAX_PALETTE];
181 int colorUsed = vic2_palette_extract( _environment, image->originalBitmap, image->originalWidth, image->originalHeight, image->originalDepth, _flags, &palette[0] );
182
183 int c_slots = 0;
184 for (int i=0; i<colorUsed; ++i ) {
185 if ( palette[i].index == colorTransparency ) continue;
186 ++c_slots;
187 for (int y=0; y<y_slots; ++y ) {
188 for (int x=0; x<x_slots; ++x ) {
189
190 cpu_move_8bit( _environment, startIndex->realName, index->realName );
191 Variable * realImage = sprite_converter( _environment, image->originalBitmap, image->originalWidth, image->originalHeight, image->originalDepth, &palette[i], _flags, x, y );
192 vic2_sprite_data_from( _environment, index->name, realImage->name );
193
194 // if ( _flags & SPRITE_FLAG_MULTICOLOR) {
195 // sprite_multicolor_var( _environment, index->name );
196 // outline1("LDA %s", address_displacement( _environment, index->realName, "1" ) );
197 // outline0("ORA #%10000000" )
198 // outline1("STA %s", address_displacement( _environment, index->realName, "1" ) );
199 // } else {
200 // sprite_monocolor_var( _environment, index->name );
201 // outline1("LDA %s", address_displacement( _environment, index->realName, "1" ) );
202 // outline0("AND #%01111111" )
203 // outline1("STA %s", address_displacement( _environment, index->realName, "1" ) );
204 // }
205
206 // if ( _flags & SPRITE_FLAG_EXPAND_HORIZONTAL ) {
207 // sprite_expand_horizontal_var( _environment, index->name );
208 // } else {
209 // sprite_compress_horizontal_var( _environment, index->name );
210 // }
211
212 // if ( _flags & SPRITE_FLAG_EXPAND_VERTICAL ) {
213 // sprite_expand_vertical_var( _environment, index->name );
214 // } else {
215 // sprite_expand_vertical_var( _environment, index->name );
216 // }
217
218 if ( ! _sprite ) {
219 cpu_inc( _environment, spriteCount->realName );
220 }
221 cpu_inc( _environment, startIndex->realName );
222 cpu_inc( _environment, index->realName );
223 }
224 }
225 }
226
227 // +---+------------- width in sprites (00 = 1, 01 = 2, 10 = 3, 11 = 4)
228 // | | +---+----- height in sprites (00 = 1, 01 = 2, 10 = 3, 11 = 4)
229 // | | | |
230 // +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
231 // | M | c | c | c | x | x | y | y | | n | n | n | n | n | n | n | n |
232 // +---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
233 // +-+---+---+---------------------+ +-------------------------------+
234 // | | | | (VT_MSPRITE+1) (VT_MSPRITE+0)
235 // | | | |
236 // | +---+---+-- number of colors
237 // +-------------- multicolor (0 = no / 1 = yes) [unused]
238
239 outline1("LDA #$%2.2x", ( (y_slots-1) & 0x03 ) | ( ( (x_slots-1) & 0x03 ) << 2 ) | ( ( (c_slots-1) & 0x07 ) << 4 ) | ( ( _flags & SPRITE_FLAG_MULTICOLOR ) ? 0x80 : 0x00) );
240 outline1("STA %s", address_displacement( _environment, result->realName, "1" ) );
241
242 return result;
243
244}
245
246#endif
void cpu_inc(Environment *_environment, char *_variable)
Definition 6309.c:4555
void cpu_move_8bit(Environment *_environment, char *_source, char *_destination)
CPU 6309: emit code to move 8 bit
Definition 6309.c:743
#define COLOR_BLACK
Definition 6847.h:36
Variable * variable_retrieve(Environment *_environment, char *_name)
Variable * variable_retrieve_or_define(Environment *_environment, char *_name, VariableType _type, int _value)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
char * address_displacement(Environment *_environment, char *_address, char *_displacement)
Variable * msprite_init(Environment *_environment, char *_image, char *_sprite, int _flags)
Emit code for SPRITE(...).
Variable * sprite_converter(Environment *_environment, char *_data, int _width, int _height, int _depth, RGBi *_color, int _flags, int _slot_x, int _slot_y)
int sprite
Definition ugbc.h:1726
Deployed deployed
Definition ugbc.h:2921
char * originalBitmap
Definition ugbc.h:1142
int originalHeight
Definition ugbc.h:1148
int originalDepth
Definition ugbc.h:1151
char * name
Definition ugbc.h:979
int originalWidth
Definition ugbc.h:1145
char * realName
Definition ugbc.h:982
struct _RGBi RGBi
Structure to store color components (red, green and blue).
#define SPRITE_FLAG_TRANSPARENCY_COLOR
Definition ugbc.h:4565
struct _Variable Variable
Structure of a single variable.
#define SPRITE_FLAG_MULTICOLOR
Definition ugbc.h:4559
struct _Environment Environment
Structure of compilation environment.
@ VT_MSPRITE
Definition ugbc.h:531
#define MAX_PALETTE
Definition ugbc.h:568
#define CRITICAL_CANNOT_MIX_SPRITES_MSPRITES()
Definition ugbc.h:3739
#define outline1(s, a)
Definition ugbc.h:4253
int vic2_palette_extract(Environment *_environment, char *_data, int _width, int _height, int _depth, int _flags, RGBi *_palette)
Definition vic2.c:4374
void vic2_sprite_data_from(Environment *_environment, char *_sprite, char *_image)
Definition vic2.c:1511