ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
draw.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
51/* <usermanual>
52@keyword DRAW (instruction)
53
54The ''DRAW'' command allows you to draw line segments and rectangles
55on the screen, forming one of the basic building blocks for creating
56simple graphics. This command can be used to draw coordinate axes
57and data points, to create characters, environments, and objects,
58to draw windows, buttons, and other interface elements.
59
60It starts drawing from the coordinates ''(x1, y1)''
61to arrive at the coordinates ''(x2, y2)'', using the color ''c''.
62The start or the final coordinates can be omitted: in this case, ugBASIC
63will draw, respectively, starting from the last drawn position and
64arriving at the last drawn position. If the color is omitted, the
65last color selected with the ''INK'' or ''PEN'' command will be used.
66
67The ''DRAW'' command offers several additional options to customize
68the drawing. After the color, that is optinal, you can put the letter
69''B'' to draw a rectangle. The letters ''BF'' means that the
70rectangle must be filled, too. Finally, the default line style is normally
71"complete" but a 16 bit bitmask can be set with the ''SET LINE'' command.
72You can also select the ''mode'' that can be ''PSET'' or ''PRESET''. If
73''PSET'' is used the line is drawn in the current foreground colour.
74If ''PRESET'', the line is drawn in the background colour.
75
76The accuracy of the drawings is limited by the resolution of the screen,
77and drawing many lines can slow down the program, especially on 8-bit computers.
78
79@italian
80
81Il comando ''DRAW'' consente di disegnare segmenti di linea e rettangoli
82sullo schermo, formando uno degli elementi di base per la creazione di
83semplici elementi grafici. Questo comando può essere utilizzato per disegnare
84assi di coordinate e punti dati, per creare personaggi, ambienti e oggetti,
85per disegnare finestre, pulsanti e altri elementi dell'interfaccia.
86
87Inizia a disegnare dalle coordinate ''(x1, y1)'' per arrivare alle coordinate
88''(x2, y2)'', utilizzando il colore ''c''. Le coordinate di partenza o di
89arrivo possono essere omesse: in questo caso, ugBASIC disegnerà,
90rispettivamente, partendo dall'ultima posizione disegnata e arrivando
91all'ultima posizione disegnata. Se il colore viene omesso,
92verrà utilizzato l'ultimo colore selezionato con il comando
93''INK'' o ''PEN''.
94
95Il comando ''DRAW'' offre diverse opzioni aggiuntive per personalizzare
96il disegno. Dopo il colore, che è facoltativo, puoi mettere la lettera
97''B'' per disegnare un rettangolo. Le lettere ''BF'' indicano che anche
98il rettangolo deve essere riempito. Infine, lo stile di linea predefinito
99è normalmente "completo", ma è possibile impostare una maschera di bit
100a 16 bit con il comando ''SET LINE''.
101
102È anche possibile selezionare la ''mode'' che può essere ''PSET''
103o ''PRESET''. Se si utilizza ''PSET'', la linea viene disegnata nel
104colore di primo piano corrente. Se ''PRESET'', la linea viene disegnata
105nel colore di sfondo.
106
107La precisione dei disegni è limitata dalla risoluzione dello schermo
108e disegnare molte linee può rallentare il programma, specialmente
109su computer a 8 bit.
110
111@syntax DRAW (x1,y1)-(x2,y2),c[,B[F]]
112@syntax DRAW (x1,y1)-(x2,y2),c[,[mode]][,B[F]]
113@syntax DRAW [x1], [y1] TO x2, y2[, c]
114@syntax DRAW TO [y2],[y2][,c]
115
116@usedInExample graphics_color_01.bas
117@usedInExample graphics_lines_01.bas
118@usedInExample graphics_shapes_01.bas
119@usedInExample graphics_shapes_02.bas
120@usedInExample graphics_shapes_03.bas
121
122@alias LINE
123@seeAlso BAR
124@seeAlso BOX
125@seeAlso SET LINE
126
127@target all
128</usermanual> */
129
130/* <usermanual>
131@keyword LINE
132
133@english
134
135@italian
136
137@syntax LINE [x1], [y1] TO x2, y2[, c]
138@syntax LINE TO x2, y2[, c]
139@syntax LINE (x1,y1) - (x2,y2)[,mode]
140
141@example LINE 10,10 TO 100,100,WHITE
142@example LINE TO 100,100
143
144@usedInExample graphics_color_01.bas
145@usedInExample graphics_lines_01.bas
146@usedInExample graphics_shapes_01.bas
147@usedInExample graphics_shapes_02.bas
148@usedInExample graphics_shapes_03.bas
149
150@alias DRAW (instruction)
151
152</usermanual> */
153void draw( Environment * _environment, char * _x0, char * _y0, char * _x1, char * _y1, char * _c, int _preserve_color ) {
154
156
157 Variable * x0 = variable_define( _environment, "draw__x0", VT_POSITION, 0 );
158 Variable * y0 = variable_define( _environment, "draw__y0", VT_POSITION, 0 );
159 Variable * x1 = variable_define( _environment, "draw__x1", VT_POSITION, 0 );
160 Variable * y1 = variable_define( _environment, "draw__y1", VT_POSITION, 0 );
161 Variable * c = variable_define( _environment, "draw__c", VT_COLOR, 0 );
162
163 Variable * pattern = variable_retrieve( _environment, "LINE" );
164 Variable * bit = variable_temporary( _environment, VT_BYTE, "(bit)" );
165 Variable * fraction = variable_temporary( _environment, VT_POSITION, "(fraction)");
166 Variable * x = variable_temporary( _environment, VT_POSITION, "(x)" );
167 Variable * y = variable_temporary( _environment, VT_POSITION, "(y)" );
168
169 Variable * dx = variable_temporary( _environment, VT_POSITION, "(dx)");
170 Variable * dy = variable_temporary( _environment, VT_POSITION, "(dy)");
171 Variable * dx2 = variable_temporary( _environment, VT_POSITION, "(dx2)");
172 Variable * dy2 = variable_temporary( _environment, VT_POSITION, "(dy2)");
173
174 Variable * stepx = variable_temporary( _environment, VT_POSITION, "(stepx)");
175 Variable * stepy = variable_temporary( _environment, VT_POSITION, "(stepy)");
176
177 variable_store( _environment, bit->name, 0 );
178
179 variable_move( _environment, x0->name, x->name );
180 variable_move( _environment, y0->name, y->name );
181
182 variable_move( _environment, variable_sub( _environment, x1->name, x0->name )->name, dx->name );
183
184 variable_move( _environment, variable_sub( _environment, y1->name, y0->name )->name, dy->name );
185
186 if_then( _environment, variable_less_than_const( _environment, dy->name, 0, 0 )->name );
187 variable_move( _environment, variable_complement_const( _environment, dy->name, 0 )->name, dy->name );
188 variable_store( _environment, stepy->name, -1 );
189 else_if_then_label( _environment );
190 else_if_then( _environment, NULL );
191 variable_store( _environment, stepy->name, 1 );
192 end_if_then( _environment );
193 if_then( _environment, variable_less_than_const( _environment, dx->name, 0, 0 )->name );
194 variable_move( _environment, variable_complement_const( _environment, dx->name, 0 )->name, dx->name );
195 variable_store( _environment, stepx->name, -1 );
196 else_if_then_label( _environment );
197 else_if_then( _environment, NULL );
198 variable_store( _environment, stepx->name, 1 );
199 end_if_then( _environment );
200 variable_move_naked( _environment, dy->name, dy2->name );
201 dy2 = variable_sl_const( _environment, dy2->name, 1 );
202 variable_move_naked( _environment, dx->name, dx2->name );
203 dx2 = variable_sl_const( _environment, dx2->name, 1 );
204 if ( _environment->lineNeeded ) {
205 if_then( _environment, variable_bit( _environment, pattern->name, bit->name )->name );
206 }
207 plot( _environment, x->name, y->name, c->name, _preserve_color );
208 if ( _environment->lineNeeded ) {
209 end_if_then( _environment );
210 }
211 variable_increment( _environment, bit->name );
212 if_then( _environment, variable_compare_const( _environment, bit->name, 16 )->name );
213 variable_store( _environment, bit->name, 0 );
214 end_if_then( _environment );
215 if_then( _environment, variable_greater_than( _environment, dx2->name, dy2->name, 0 )->name );
216 variable_move( _environment, variable_sub( _environment, dy2->name, dx->name)->name, fraction->name);
217 begin_while( _environment );
218 begin_while_condition( _environment, variable_compare_not( _environment, x->name, x1->name )->name );
219 variable_move( _environment, variable_add( _environment, x->name, stepx->name )->name, x->name );
220 if_then( _environment, variable_greater_than_const( _environment, fraction->name, 0, 1 )->name );
221 variable_move( _environment, variable_add( _environment, y->name, stepy->name )->name, y->name );
222 variable_move( _environment, variable_sub( _environment, fraction->name, dx2->name )->name, fraction->name );
223 end_if_then( _environment );
224 variable_move( _environment, variable_add( _environment, fraction->name, dy2->name )->name, fraction->name );
225 if ( _environment->lineNeeded ) {
226 if_then( _environment, variable_bit( _environment, pattern->name, bit->name )->name );
227 }
228 plot( _environment, x->name, y->name, c->name, _preserve_color );
229 if ( _environment->lineNeeded ) {
230 end_if_then( _environment );
231 variable_increment( _environment, bit->name );
232 if_then( _environment, variable_compare_const( _environment, bit->name, 16 )->name );
233 variable_store( _environment, bit->name, 0 );
234 end_if_then( _environment );
235 }
236 end_while( _environment );
237 else_if_then_label( _environment );
238 else_if_then( _environment, NULL );
239 variable_move( _environment, variable_sub( _environment, dx2->name, dy->name)->name, fraction->name);
240 begin_while( _environment );
241 begin_while_condition( _environment, variable_compare_not( _environment, y->name, y1->name )->name );
242 if_then( _environment, variable_greater_than_const( _environment, fraction->name, 0, 1 )->name );
243 variable_move( _environment, variable_add( _environment, x->name, stepx->name )->name, x->name );
244 variable_move( _environment, variable_sub( _environment, fraction->name, dy2->name )->name, fraction->name );
245 end_if_then( _environment );
246 variable_move( _environment, variable_add( _environment, y->name, stepy->name )->name, y->name );
247 variable_move( _environment, variable_add( _environment, fraction->name, dx2->name )->name, fraction->name );
248 if ( _environment->lineNeeded ) {
249 if_then( _environment, variable_bit( _environment, pattern->name, bit->name )->name );
250 }
251 plot( _environment, x->name, y->name, c->name, _preserve_color );
252 if ( _environment->lineNeeded ) {
253 end_if_then( _environment );
254 }
255 variable_increment( _environment, bit->name );
256 if_then( _environment, variable_compare_const( _environment, bit->name, 16 )->name );
257 variable_store( _environment, bit->name, 0 );
258 end_if_then( _environment );
259 end_while( _environment );
260 end_if_then( _environment );
261
262 cpu_return( _environment );
263
264 deploy_end( draw );
265
266 Variable * x0 = variable_retrieve_or_define( _environment, _x0, VT_POSITION, 0 );
267 Variable * y0 = variable_retrieve_or_define( _environment, _y0, VT_POSITION, 0 );
268 Variable * x1 = variable_retrieve_or_define( _environment, _x1, VT_POSITION, 0 );
269 Variable * y1 = variable_retrieve_or_define( _environment, _y1, VT_POSITION, 0 );
270 Variable * c = NULL;
271 if ( _c ) {
272 c = variable_retrieve_or_define( _environment, _c, VT_COLOR, 0 );
273 }
274
275 Variable * dx0 = variable_retrieve( _environment, "draw__x0" );
276 Variable * dy0 = variable_retrieve( _environment, "draw__y0" );
277 Variable * dx1 = variable_retrieve( _environment, "draw__x1" );
278 Variable * dy1 = variable_retrieve( _environment, "draw__y1" );
279 Variable * dc = variable_retrieve( _environment, "draw__c" );
280
281 variable_move( _environment, x0->name, dx0->name );
282 variable_move( _environment, y0->name, dy0->name );
283 variable_move( _environment, x1->name, dx1->name );
284 variable_move( _environment, y1->name, dy1->name );
285
286 if ( c ) {
287 variable_move( _environment, c->name, dc->name );
288 } else {
289 variable_move( _environment, "PEN", dc->name );
290 }
291
292 cpu_call( _environment, "lib_draw");
293
294}
void cpu_call(Environment *_environment, char *_label)
Definition 6309.c:3755
void cpu_return(Environment *_environment)
Definition 6309.c:4030
Variable * variable_add(Environment *_environment, char *_source, char *_destination)
Add two variable and return the sum of them.
Variable * variable_retrieve(Environment *_environment, char *_name)
Variable * variable_less_than_const(Environment *_environment, char *_source, int _destination, int _equal)
Variable * variable_retrieve_or_define(Environment *_environment, char *_name, VariableType _type, int _value)
Variable * variable_greater_than(Environment *_environment, char *_source, char *_destination, int _equal)
Compare two variable and return the result of comparation.
Variable * variable_move(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable by converting it.
Variable * variable_move_naked(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable without conversion.
void variable_increment(Environment *_environment, char *_source)
Increment a variable by one.
Variable * variable_compare_not(Environment *_environment, char *_source, char *_destination)
Compare two variable and return the result of comparation.
Variable * variable_define(Environment *_environment, char *_name, VariableType _type, int _value)
Define a variable for the program.
Variable * variable_sl_const(Environment *_environment, char *_destination, int _steps)
Variable * variable_sub(Environment *_environment, char *_source, char *_dest)
Make a differenze between two variable and return the difference of them.
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
Variable * variable_store(Environment *_environment, char *_destination, unsigned int _value)
Store a direct value to a variable.
Variable * variable_greater_than_const(Environment *_environment, char *_source, int _destination, int _equal)
Variable * variable_complement_const(Environment *_environment, char *_source, int _value)
Calculate the complement of a variable.
Variable * variable_compare_const(Environment *_environment, char *_source, int _destination)
Compare two variable and return the result of comparation.
Variable * variable_bit(Environment *_environment, char *_value, char *_position)
Emit code for HAS BIT / BIT(...).
void plot(Environment *_environment, char *_x, char *_y, char *_c, int _preserve_color)
Definition plot.c:46
void draw(Environment *_environment, char *_x0, char *_y0, char *_x1, char *_y1, char *_c, int _preserve_color)
Emit ASM code to implement DRAW command.
Definition draw.c:153
void else_if_then_label(Environment *_environment)
Emit ASM code for ... ELSE [IF] ....
void else_if_then(Environment *_environment, char *_expression)
Emit ASM code for ... ELSE [IF] ....
void end_if_then(Environment *_environment)
Emit ASM code for ENDIF.
Definition end_if_then.c:50
void if_then(Environment *_environment, char *_expression)
Emit ASM code for IF ... THEN ....
Definition if_then.c:123
#define bit(ticks, adrmode)
Definition sidreloc.c:579
int lineNeeded
Definition ugbc.h:2559
char * name
Definition ugbc.h:979
#define deploy_end(s)
Definition ugbc.h:4365
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_POSITION
Definition ugbc.h:468
@ VT_BYTE
Definition ugbc.h:450
@ VT_COLOR
Definition ugbc.h:471
#define deploy_begin(s)
Definition ugbc.h:4356
void begin_while_condition(Environment *_environment, char *_expression)
Definition while.c:99
void begin_while(Environment *_environment)
Emit ASM code for WHILE ....
Definition while.c:83
void end_while(Environment *_environment)
Emit ASM code for ... WEND.
Definition while.c:127