ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
draw_string.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/* <usermanual>
42@keyword DRAW (program)
43
44@english
45
46The ''DRAW'' command allows to draw on the SCREEN. The parameter is either a
47string constant, or a string variable, containing a set of the draw
48subcommands. Usually the first action of any drawing is to move
49to the start point.
50
51''M x,y'' means move to the coordinates given by ''x,y''.
52If you wanto to move to a point, it is usually a good idea to make a "blank" move,
53that is move without drawing or lifting the pencil off the paper.
54
55If you do not you may get unwanted lines on your drawing, you can use the letter ''B''.
56Any drawing instruction following the ''B'' will be a blank line. BMx,y means move to
57the ''x,y'' without drawing. Having decided the start point, you may now move up (U),
58down (D), right (R), or Left (L) by as many pixels as you like. The sequence
59U20R20D20L20 will cause drawing a square.
60
61Apart from vertical and horizontal lines you can also draw diagonal lines.
62These use the subcommands ''E'',''F'',''G'' and ''H'', for instance ''E12'' will draw a
63diagonal line, 12 points long, at 45 degrees from the vertical. All the angles
64are measured from the vertical as follows: ''E'' = 45 degrees, ''F'' = 135 degrees,
65''G'' = 225 degrees and ''H'' = 315 degrees. This allows diagonal lines to be drawn
66in any of 4 directions.
67
68We can change the color by using ''C''. The letter ''C'' is followed by a number from
690 to ''COLOR COUNT'', representing the code for one of the available colours.
70
71If the drawing is a bit small, we can scale it up with the ''S'' parameter.
72The ''S'' means scale, and allows a drawing, or parts of a drawing to be scaled
73up or down in units of 1/4 (0.25). So ''S1'' reduces the drawing to 1/4 scale,
74''S2'' to 2/4 (half) scale, ''S8'' to 8/4 (twice) scale, and so on.
75The default setting for scale is 4/4 (i.e. 1, the original size).
76
77Another option available is the angle parameter A. This allows us to rotate all
78or part of the drawing, as all lines after the A will be drawn with the
79displacement given by An, where n is a number between 0 and 3, as follows,
800 = 0 degrees, 1 = 90 degrees, 2 = 180 degrees, 3 = 270 degrees.
81
82Finally, the ''N'' command has the meaning of no update of drawing position. This is to
83draw a line as specified but do not use the end of the line as the new position.
84
85Note that if the Simons' BASIC compatibility option is active (via the ''OPTION DIALECT TSB''
86pragma), the string commands will use a different, i.e. language-compatible, command set.
87
88@italian
89
90Il comando ''DRAW'' consente di disegnare sullo schermo. Il parametro è una costante
91stringa o una variabile stringa contenente un insieme di sottocomandi. Di solito
92la prima azione di qualsiasi disegno è spostarsi al punto iniziale.
93
94''M x,y'' significa spostarsi verso le coordinate date da ''x,y''. Se ci si vuole spostare
95verso un punto, di solito è una buona idea fare una mossa senza scrivere, cioè
96muoversi senza disegnare o sollevare la matita dal foglio.
97
98In caso contrario si potrebbero ottenere linee indesiderate sullo schermo. Si può utilizzare
99la lettera ''B''. Qualsiasi istruzione di disegno che segue la ''B'' sarà priva di effetti
100di disegno. ''BMx,y'' significa spostarsi su ''x,y'' senza disegnare.
101
102Dopo aver deciso il punto iniziale, ci si può spostare in alto (''U''), in basso (''D''),
103a destra (''R'') o a sinistra (''L'') di quanti pixel si desidera. La sequenza
104U20R20D20L20 causerà il disegno di un quadrato.
105
106Oltre alle linee verticali e orizzontali puoi anche disegnare linee diagonali. Questi usano
107i sottocomandi ''E'',''F'',''G'' e ''H'', ad esempio ''E12'' disegnerà una linea diagonale,
108lunga 12 punti, a 45 gradi dal verticale. Tutti gli angoli sono misurati dalla verticale come
109segue: ''E'' = 45 gradi, ''F'' = 135 gradi, ''G'' = 225 gradi e ''H'' = 315 gradi.
110Ciò consente di tracciare linee diagonali in una qualsiasi delle 4 direzioni.
111
112E' possibile cambiare il colore usando ''C''. La lettera ''C'' è seguita da un numero da
113''0'' a ''COLOR COUNT'', che rappresenta il codice di uno dei colori disponibili.
114
115Se il disegno è troppo piccolo, si può ingrandirlo con il parametro ''S''. La ''S'' significa
116scala e consente di ingrandire o ridurre un disegno o parti di esso in unità di 1/4 (0,25).
117Quindi ''S1'' riduce il disegno a 1/4 di scala, ''S2'' a 2/4 (metà) scala, ''S8'' a 8/4
118(due volte) scala e così via. L'impostazione predefinita per la scala è 4/4 (ovvero 1,
119la dimensione originale).
120
121Un'altra opzione disponibile è il comando ''A''. Questo permette di ruotare tutto o parte
122del disegno, poiché tutte le linee dopo la ''A'' verranno disegnate con lo spostamento dato
123da ''An'', dove n è un numero compreso tra ''0'' e ''3'', come segue: 0 = 0 gradi,
1241 = 90 gradi, 2 = 180 gradi, 3 = 270 gradi.
125
126Infine il comando ''N'' ha il significato di nessun aggiornamento della posizione del disegno.
127Questo serve per tracciare una linea come specificato ma non utilizzare la fine della linea
128come nuova posizione.
129
130Da notare che, se l'opzione di compatibilità con il Simons' BASIC è attiva (per mezzo del
131pragma ''OPTION DIALECT TSB''), i comandi della stringa utilizzerà un set di comandi diverso,
132ovvero compatibile con quel linguaggio.
133
134@syntax DRAW instructions
135
136@example DRAW "BM0,0;R10;U10;L10;D10"
137
138@usedInExample graphics_draw_01.bas
139
140@target all
141</usermanual> */
142void draw_string( Environment * _environment, char * _string ) {
143
145
147
148 char drawStringLabel[MAX_TEMPORARY_STORAGE]; sprintf( drawStringLabel, "%sds", label );
149 char readParameterLabel[MAX_TEMPORARY_STORAGE]; sprintf( readParameterLabel, "%srp", label );
150 char readParameter2Label[MAX_TEMPORARY_STORAGE]; sprintf( readParameter2Label, "%srp2", label );
151 char readParameter3Label[MAX_TEMPORARY_STORAGE]; sprintf( readParameter3Label, "%srp3", label );
152
153 char moveCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( moveCommandLabel, "%smove", label );
154 char move2CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( move2CommandLabel, "%smove2", label );
155 char move3CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( move3CommandLabel, "%smove3", label );
156 char move4CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( move4CommandLabel, "%smove4", label );
157 char move5CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( move5CommandLabel, "%smove5", label );
158 char updownCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( updownCommandLabel, "%supdown", label );
159 char updown2CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( updown2CommandLabel, "%supdown2", label );
160 char upCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( upCommandLabel, "%sup", label );
161 char downCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( downCommandLabel, "%sdown", label );
162 char leftrightCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( leftrightCommandLabel, "%sleftright", label );
163 char leftright2CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( leftright2CommandLabel, "%sleftright2", label );
164 char leftCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( leftCommandLabel, "%sleft", label );
165 char rightCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( rightCommandLabel, "%sright", label );
166 char up2CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( up2CommandLabel, "%sup2", label );
167 char down2CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( down2CommandLabel, "%sdown2", label );
168 char left2CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( left2CommandLabel, "%sleft2", label );
169 char right2CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( right2CommandLabel, "%sright2", label );
170 char blankCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( blankCommandLabel, "%sblank", label );
171 char doneCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( doneCommandLabel, "%sdone", label );
172 char done2CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( done2CommandLabel, "%sdone2", label );
173 char drawCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( drawCommandLabel, "%sdraw", label );
174 char angleCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( angleCommandLabel, "%sangle", label );
175 char anglesCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( anglesCommandLabel, "%sangles", label );
176 char angles2CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( angles2CommandLabel, "%sangles2", label );
177 char angle45CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( angle45CommandLabel, "%sa45", label );
178 char angle135CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( angle135CommandLabel, "%sa135", label );
179 char angle225CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( angle225CommandLabel, "%sa225", label );
180 char angle315CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( angle315CommandLabel, "%sa315", label );
181 char colorCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( colorCommandLabel, "%scol", label );
182 char scaleCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( scaleCommandLabel, "%sscale", label );
183 char rotateCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( rotateCommandLabel, "%srotate", label );
184 char rotate0CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( rotate0CommandLabel, "%srotate0", label );
185 char rotate90CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( rotate90CommandLabel, "%srotate90", label );
186 char rotate180CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( rotate180CommandLabel, "%srotate180", label );
187 char rotate270CommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( rotate270CommandLabel, "%srotate270", label );
188 char noUpdateCommandLabel[MAX_TEMPORARY_STORAGE]; sprintf( noUpdateCommandLabel, "%snoupdate", label );
189
190 Variable * drawUCommandLetter = variable_retrieve( _environment, "DRAWUCOMMAND" );
191 Variable * drawDCommandLetter = variable_retrieve( _environment, "DRAWDCOMMAND" );
192 Variable * drawLCommandLetter = variable_retrieve( _environment, "DRAWLCOMMAND" );
193 Variable * drawRCommandLetter = variable_retrieve( _environment, "DRAWRCOMMAND" );
194 Variable * drawECommandLetter = variable_retrieve( _environment, "DRAWECOMMAND" );
195 Variable * drawFCommandLetter = variable_retrieve( _environment, "DRAWFCOMMAND" );
196 Variable * drawGCommandLetter = variable_retrieve( _environment, "DRAWGCOMMAND" );
197 Variable * drawHCommandLetter = variable_retrieve( _environment, "DRAWHCOMMAND" );
198
199 // Move to the start of routine
200 cpu_jump( _environment, drawStringLabel );
201
202 // ----------------------------[ SUBROUTINE: READ PARAMETER ]
203
204 // string -> (address, size)
205 Variable * address = variable_define( _environment, "drawstring__address", VT_ADDRESS, 0 );
206 Variable * size = variable_define( _environment, "drawstring__size", VT_BYTE, 0 );
207
208 // xxx, -> (paddress, psize)
209 Variable * paddress = variable_define( _environment, "drawstring__paddress", VT_ADDRESS, 0 );
210 Variable * psize = variable_define( _environment, "drawstring__psize", VT_BYTE, 0 );
211 Variable * digit = variable_define( _environment, "drawstring__digit", VT_BYTE, 0 );
212 Variable * parameter = variable_define( _environment, "drawstring__parameter", VT_POSITION, 0 );
213 Variable * eos = variable_define( _environment, "drawstring__eos", VT_BYTE, 0 );
214
215 cpu_label( _environment, readParameterLabel );
216
217 // Take current address as starting of parameter
218 cpu_move_16bit( _environment, address->realName, paddress->realName );
219
220 // The parameter starts with a zero length.
221 cpu_store_8bit( _environment, psize->realName, 0 );
222
223 // Let's retrieve the parameter. We know that the parameter should end
224 // with a ',' so we are looking for that character, or for the end
225 // of the original string, as well -- note that the end of the string
226 // means end of the parameter itself.
227 begin_do_loop( _environment );
228
229 // Exit if drawing string is ended
230 cpu_compare_and_branch_8bit_const( _environment, size->realName, 0, readParameter2Label, 1 );
231
232 // Exit from this loop if the letter is not a digit.
233 cpu_move_8bit_indirect2( _environment, address->realName, digit->realName );
234 cpu_greater_than_8bit_const( _environment, digit->realName, '9', eos->realName, 0, 0 );
235 cpu_compare_and_branch_8bit_const( _environment, eos->realName, 0xff, readParameter3Label, 1 );
236 cpu_less_than_8bit_const( _environment, digit->realName, '0', eos->realName, 0, 0 );
237 cpu_compare_and_branch_8bit_const( _environment, eos->realName, 0xff, readParameter3Label, 1 );
238 cpu_dec( _environment, size->realName );
239 cpu_inc_16bit( _environment, address->realName );
240
241 // Increment the length of the parameter, and move along the
242 // drawing commands string
243 cpu_inc( _environment, psize->realName );
244
245 end_do_loop( _environment );
246
247 cpu_label( _environment, readParameter3Label );
248 // cpu_dec_16bit( _environment, address->realName );
249 // cpu_inc( _environment, size->realName );
250 // If we arrived here, it means that we are able to read and decode
251 // the parameter as number.
252 cpu_label( _environment, readParameter2Label );
253 cpu_convert_string_into_16bit( _environment, paddress->realName, psize->realName, parameter->realName );
254
255 cpu_return( _environment );
256
257 // ------------------------------------ STARTING ROUTINE
258 cpu_label( _environment, drawStringLabel );
259
260 // String with the drawing commands,
261 Variable * string = variable_define( _environment, "drawstring__string", VT_DSTRING, 0 );
262
263 // Letter with command
264 Variable * command = variable_define( _environment, "drawstring__command", VT_BYTE, 0 );
265
266 // Next coordinates to move to.
267 Variable * x = variable_define( _environment, "drawstring__x", VT_POSITION, 0 );
268 Variable * y = variable_define( _environment, "drawstring__y", VT_POSITION, 0 );
269
270 // Next delta coordinates.
271 Variable * dx = variable_define( _environment, "drawstring__dx", VT_POSITION, 0 );
272 Variable * dy = variable_define( _environment, "drawstring__dy", VT_POSITION, 0 );
273
274 // Next delta coordinates scaled
275 Variable * ds = variable_define( _environment, "drawstring__ds", VT_POSITION, 0 );
276
277 // Scale.
278 Variable * scale = variable_retrieve( _environment, "DRAWSCALE" );
279
280 // Angle
281 Variable * angle = variable_retrieve( _environment, "DRAWANGLE" );
282
283 // Is blank required?
284 Variable * blank = variable_define( _environment, "drawstring__blank", VT_BYTE, 0 );
285
286 // Position has not to be updated?
287 Variable * noUpdate = variable_define( _environment, "drawstring__noupdate", VT_BYTE, 0 );
288
289 // Color to be used
290 Variable * c = variable_define( _environment, "drawstring__c", VT_COLOR, 0 );
291
292 // Retrieve the effective address of the string with the drawing commands.
293
294 variable_move( _environment, "PEN", c->name );
295
296 cpu_dsdescriptor( _environment, string->realName, address->realName, size->realName );
297
298 // ------------------------------------ FETCH AND DECODE LOOP
299 begin_do_loop( _environment );
300
301 // Starting with current position on x and y
302 variable_move( _environment, origin_resolution_relative_transform_x( _environment, NULL, 0 )->name, x->name );
303 variable_move( _environment, origin_resolution_relative_transform_y( _environment, NULL, 0 )->name, y->name );
304
305 // Are drawing commands ended? Exit fetch and decode loop.
306 cpu_compare_and_branch_8bit_const( _environment, size->realName, 0, label, 1 );
307
308 // Retrieve command letter.
309 cpu_move_8bit_indirect2( _environment, address->realName, command->realName );
310 cpu_dec( _environment, size->realName );
311 cpu_inc_16bit( _environment, address->realName );
312
313 // Is it 'M' ? -> MOVE
314 cpu_compare_and_branch_char_const( _environment, command->realName, 'M', moveCommandLabel, 1 );
315
316 // Is it 'L' ? -> LEFT
317 cpu_compare_and_branch_8bit( _environment, command->realName, drawLCommandLetter->realName, leftCommandLabel, 1 );
318
319 // Is it 'R' ? -> RIGHT
320 cpu_compare_and_branch_8bit( _environment, command->realName, drawRCommandLetter->realName, rightCommandLabel, 1 );
321
322 // Is it 'U' ? -> UP
323 cpu_compare_and_branch_8bit( _environment, command->realName, drawUCommandLetter->realName, upCommandLabel, 1 );
324
325 // Is it 'D' ? -> DOWN
326 cpu_compare_and_branch_8bit( _environment, command->realName, drawDCommandLetter->realName, downCommandLabel, 1 );
327
328 // Is it 'B' ? -> BLANK (next action)
329 cpu_compare_and_branch_char_const( _environment, command->realName, 'B', blankCommandLabel, 1 );
330
331 // Is it 'E' ? -> 45°
332 cpu_compare_and_branch_8bit( _environment, command->realName, drawECommandLetter->realName, angleCommandLabel, 1 );
333
334 // Is it 'F' ? -> 135°
335 cpu_compare_and_branch_8bit( _environment, command->realName, drawFCommandLetter->realName, angleCommandLabel, 1 );
336
337 // Is it 'G' ? -> 225°
338 cpu_compare_and_branch_8bit( _environment, command->realName, drawGCommandLetter->realName, angleCommandLabel, 1 );
339
340 // Is it 'H' ? -> 315°
341 cpu_compare_and_branch_8bit( _environment, command->realName, drawHCommandLetter->realName, angleCommandLabel, 1 );
342
343 // Is it 'C' ? -> change color
344 cpu_compare_and_branch_char_const( _environment, command->realName, 'C', colorCommandLabel, 1 );
345
346 // Is it 'S' ? -> scale
347 cpu_compare_and_branch_char_const( _environment, command->realName, 'S', scaleCommandLabel, 1 );
348
349 // Is it 'A' ? -> angle (rotate)
350 cpu_compare_and_branch_char_const( _environment, command->realName, 'A', rotateCommandLabel, 1 );
351
352 // Is it 'N' ? -> NO UPDATE (next action)
353 cpu_compare_and_branch_char_const( _environment, command->realName, 'N', noUpdateCommandLabel, 1 );
354
355 // No command was recognized: silently, move to the next character.
356 cpu_jump( _environment, doneCommandLabel );
357
358 // ----------------------------[ MOVE ]
359 cpu_label( _environment, moveCommandLabel );
360
361 cpu_call( _environment, readParameterLabel );
362
363 cpu_move_16bit( _environment, parameter->realName, x->realName );
364
365 cpu_inc_16bit( _environment, address->realName );
366
367 cpu_call( _environment, readParameterLabel );
368
369 cpu_move_16bit( _environment, parameter->realName, y->realName );
370
371 // // Now we have to transform (x,y) into the effective
372 // // reference system, based on ORIGIN and RESOLUTION keywords.
373 // variable_move( _environment, origin_resolution_relative_transform_x( _environment, x->name, 0 )->name, x->name );
374 // variable_move( _environment, origin_resolution_relative_transform_y( _environment, y->name, 0 )->name, y->name );
375
376 cpu_jump( _environment, drawCommandLabel );
377
378 // ----------------------------[ BLANK ]
379
380 // Enable blanking (only for the next move instruction)
381 cpu_label( _environment, blankCommandLabel );
382 cpu_store_8bit( _environment, blank->realName, 0xff );
383 cpu_jump( _environment, doneCommandLabel );
384
385 // ----------------------------[ NO UPDATE ]
386
387 // No update position (only for the next move instruction)
388 cpu_label( _environment, noUpdateCommandLabel );
389 cpu_store_8bit( _environment, noUpdate->realName, 0xff );
390 cpu_jump( _environment, doneCommandLabel );
391
392 // ----------------------------[ COLOR ]
393
394 // Change color
395 cpu_label( _environment, colorCommandLabel );
396 cpu_call( _environment, readParameterLabel );
397 variable_move( _environment, parameter->name, c->name );
398 cpu_jump( _environment, done2CommandLabel );
399
400 // ----------------------------[ SCALE ]
401
402 // Change scale
403 cpu_label( _environment, scaleCommandLabel );
404 cpu_call( _environment, readParameterLabel );
405 variable_move( _environment, parameter->name, scale->name );
406 cpu_jump( _environment, done2CommandLabel );
407
408 // ----------------------------[ ANGLE ]
409
410 // Change angle
411 cpu_label( _environment, rotateCommandLabel );
412 cpu_call( _environment, readParameterLabel );
413 variable_move( _environment, parameter->name, angle->name );
414 cpu_compare_and_branch_8bit_const( _environment, angle->realName, 0, rotate0CommandLabel, 1 );
415 cpu_compare_and_branch_8bit_const( _environment, angle->realName, 1, rotate90CommandLabel, 1 );
416 cpu_compare_and_branch_8bit_const( _environment, angle->realName, 2, rotate180CommandLabel, 1 );
417 cpu_compare_and_branch_8bit_const( _environment, angle->realName, 3, rotate270CommandLabel, 1 );
418
419 cpu_label( _environment, rotate0CommandLabel );
420 cpu_store_char( _environment, drawUCommandLetter->realName, 'U' );
421 cpu_store_char( _environment, drawDCommandLetter->realName, 'D' );
422 cpu_store_char( _environment, drawLCommandLetter->realName, 'L' );
423 cpu_store_char( _environment, drawRCommandLetter->realName, 'R' );
424 cpu_store_char( _environment, drawECommandLetter->realName, 'E' );
425 cpu_store_char( _environment, drawFCommandLetter->realName, 'F' );
426 cpu_store_char( _environment, drawGCommandLetter->realName, 'G' );
427 cpu_store_char( _environment, drawHCommandLetter->realName, 'H' );
428 cpu_jump( _environment, done2CommandLabel );
429
430 cpu_label( _environment, rotate90CommandLabel );
431 cpu_store_char( _environment, drawUCommandLetter->realName, 'L' );
432 cpu_store_char( _environment, drawDCommandLetter->realName, 'R' );
433 cpu_store_char( _environment, drawLCommandLetter->realName, 'D' );
434 cpu_store_char( _environment, drawRCommandLetter->realName, 'U' );
435 cpu_store_char( _environment, drawECommandLetter->realName, 'H' );
436 cpu_store_char( _environment, drawFCommandLetter->realName, 'E' );
437 cpu_store_char( _environment, drawGCommandLetter->realName, 'F' );
438 cpu_store_char( _environment, drawHCommandLetter->realName, 'G' );
439 cpu_jump( _environment, done2CommandLabel );
440
441 cpu_label( _environment, rotate180CommandLabel );
442 cpu_store_char( _environment, drawUCommandLetter->realName, 'D' );
443 cpu_store_char( _environment, drawDCommandLetter->realName, 'U' );
444 cpu_store_char( _environment, drawLCommandLetter->realName, 'R' );
445 cpu_store_char( _environment, drawRCommandLetter->realName, 'L' );
446 cpu_store_char( _environment, drawECommandLetter->realName, 'G' );
447 cpu_store_char( _environment, drawFCommandLetter->realName, 'H' );
448 cpu_store_char( _environment, drawGCommandLetter->realName, 'E' );
449 cpu_store_char( _environment, drawHCommandLetter->realName, 'F' );
450 cpu_jump( _environment, done2CommandLabel );
451
452 cpu_label( _environment, rotate270CommandLabel );
453 cpu_store_char( _environment, drawUCommandLetter->realName, 'R' );
454 cpu_store_char( _environment, drawDCommandLetter->realName, 'L' );
455 cpu_store_char( _environment, drawLCommandLetter->realName, 'U' );
456 cpu_store_char( _environment, drawRCommandLetter->realName, 'D' );
457 cpu_store_char( _environment, drawECommandLetter->realName, 'F' );
458 cpu_store_char( _environment, drawFCommandLetter->realName, 'G' );
459 cpu_store_char( _environment, drawGCommandLetter->realName, 'H' );
460 cpu_store_char( _environment, drawHCommandLetter->realName, 'E' );
461 cpu_jump( _environment, done2CommandLabel );
462
463 cpu_jump( _environment, done2CommandLabel );
464
465 // ----------------------------[ UP/DOWN ]
466 cpu_label( _environment, upCommandLabel );
467 cpu_label( _environment, downCommandLabel );
468
469 cpu_call( _environment, readParameterLabel );
470
471 // If we arrived here, it means that we are able to read and decode
472 // the parameter as (negative) dy.
473 cpu_label( _environment, up2CommandLabel );
474
475 cpu_compare_and_branch_8bit_const( _environment, psize->realName, 0, updownCommandLabel, 1 );
476 cpu_move_16bit( _environment, parameter->realName, dy->realName );
477 cpu_jump( _environment, updown2CommandLabel );
478 cpu_label( _environment, updownCommandLabel );
479 cpu_store_16bit( _environment, dy->realName, 1 );
480 cpu_jump( _environment, updown2CommandLabel );
481 cpu_label( _environment, updown2CommandLabel );
482
483 variable_move( _environment, origin_resolution_relative_transform_y( _environment, dy->name, 0 )->name, dy->name );
484
485 variable_move( _environment, variable_mul( _environment, dy->name, scale->name )->name, dy->name );
486 variable_move( _environment, variable_div2_const( _environment, dy->name, 4, NULL )->name, ds->name );
487
488 cpu_compare_and_branch_8bit( _environment, command->realName, drawDCommandLetter->realName, down2CommandLabel, 1 );
489
490 variable_move( _environment,
491 variable_sub( _environment, y->name,
492 ds->name
493 )->name,
494 y->name
495 );
496 cpu_jump( _environment, drawCommandLabel );
497
498 cpu_label( _environment, down2CommandLabel );
499 variable_move( _environment,
500 variable_add( _environment, y->name,
501 ds->name
502 )->name,
503 y->name
504 );
505 cpu_jump( _environment, drawCommandLabel );
506
507 // ----------------------------[ LEFT/RIGHT ]
508 cpu_label( _environment, leftCommandLabel );
509 cpu_label( _environment, rightCommandLabel );
510
511 cpu_call( _environment, readParameterLabel );
512
513 // If we arrived here, it means that we are able to read and decode
514 // the parameter as (negative) dx.
515 cpu_label( _environment, left2CommandLabel );
516 cpu_compare_and_branch_8bit_const( _environment, psize->realName, 0, leftrightCommandLabel, 1 );
517 cpu_move_16bit( _environment, parameter->realName, dx->realName );
518 cpu_jump( _environment, leftright2CommandLabel );
519 cpu_label( _environment, leftrightCommandLabel );
520 cpu_store_16bit( _environment, dx->realName, 1 );
521 cpu_jump( _environment, leftright2CommandLabel );
522 cpu_label( _environment, leftright2CommandLabel );
523
524 variable_move( _environment, origin_resolution_relative_transform_x( _environment, dx->name, 0 )->name, dx->name );
525
526 variable_move( _environment, variable_mul( _environment, dx->name, scale->name )->name, dx->name );
527 variable_move( _environment, variable_div2_const( _environment, dx->name, 4, NULL )->name, ds->name );
528
529 cpu_compare_and_branch_8bit( _environment, command->realName, drawRCommandLetter->realName, right2CommandLabel, 1 );
530
531 variable_move( _environment,
532 variable_sub( _environment, x->name,
533 ds->name
534 )->name,
535 x->name
536 );
537 cpu_jump( _environment, drawCommandLabel );
538
539 cpu_label( _environment, right2CommandLabel );
540 variable_move( _environment,
541 variable_add( _environment, x->name,
542 ds->name
543 )->name,
544 x->name
545 );
546 cpu_jump( _environment, drawCommandLabel );
547
548 // ----------------------------[ ANGLE 45, 135, 225, 315 ]
549
550 cpu_label( _environment, angleCommandLabel );
551
552 cpu_call( _environment, readParameterLabel );
553
554 cpu_compare_and_branch_8bit_const( _environment, psize->realName, 0, anglesCommandLabel, 1 );
555 cpu_move_16bit( _environment, parameter->realName, dx->realName );
556 cpu_jump( _environment, angles2CommandLabel );
557 cpu_label( _environment, anglesCommandLabel );
558 cpu_store_8bit( _environment, dx->realName, 1 );
559 cpu_jump( _environment, angles2CommandLabel );
560 cpu_label( _environment, angles2CommandLabel );
561
562 variable_move( _environment, origin_resolution_relative_transform_x( _environment, dx->name, 0 )->name, dx->name );
563
564 variable_move( _environment, variable_mul( _environment, dx->name, scale->name )->name, dx->name );
565 variable_move( _environment, variable_div2_const( _environment, dx->name, 4, NULL )->name, ds->name );
566
567 cpu_compare_and_branch_8bit( _environment, command->realName, drawECommandLetter->realName, angle45CommandLabel, 1 );
568
569 cpu_compare_and_branch_8bit( _environment, command->realName, drawFCommandLetter->realName, angle135CommandLabel, 1 );
570
571 cpu_compare_and_branch_8bit( _environment, command->realName, drawGCommandLetter->realName, angle225CommandLabel, 1 );
572
573 cpu_compare_and_branch_8bit( _environment, command->realName, drawHCommandLetter->realName, angle315CommandLabel, 1 );
574
575 cpu_label( _environment, angle45CommandLabel );
576 variable_move( _environment,
577 variable_add( _environment, x->name,
578 ds->name
579 )->name,
580 x->name
581 );
582 variable_move( _environment,
583 variable_sub( _environment, y->name,
584 ds->name
585 )->name,
586 y->name
587 );
588 cpu_jump( _environment, drawCommandLabel );
589
590 cpu_label( _environment, angle135CommandLabel );
591 variable_move( _environment,
592 variable_add( _environment, x->name,
593 ds->name
594 )->name,
595 x->name
596 );
597 variable_move( _environment,
598 variable_add( _environment, y->name,
599 ds->name
600 )->name,
601 y->name
602 );
603 cpu_jump( _environment, drawCommandLabel );
604
605 cpu_label( _environment, angle225CommandLabel );
606 variable_move( _environment,
607 variable_sub( _environment, x->name,
608 ds->name
609 )->name,
610 x->name
611 );
612 variable_move( _environment,
613 variable_add( _environment, y->name,
614 ds->name
615 )->name,
616 y->name
617 );
618 cpu_jump( _environment, drawCommandLabel );
619
620 cpu_label( _environment, angle315CommandLabel );
621 variable_move( _environment,
622 variable_sub( _environment, x->name,
623 ds->name
624 )->name,
625 x->name
626 );
627 variable_move( _environment,
628 variable_sub( _environment, y->name,
629 ds->name
630 )->name,
631 y->name
632 );
633 cpu_jump( _environment, drawCommandLabel );
634
635 // ----------------------------[ DRAW (or BLANK) ]
636 cpu_label( _environment, drawCommandLabel );
637
638 // If blank move has been requested, we avoid to draw anything.
639 cpu_compare_and_branch_8bit_const( _environment, blank->realName, 0xff, move5CommandLabel, 1 );
640
641 // Let's draw from the previous position to the current position.
642 draw( _environment,
643 origin_resolution_relative_transform_x( _environment, NULL, 0 )->name,
644 origin_resolution_relative_transform_y( _environment, NULL, 0 )->name,
645 x->name, y->name, c->name, 0 );
646
647 // Update current position (this is done also if nothing is drawn!)
648 cpu_label( _environment, move5CommandLabel );
649
650 // Avoid to not to draw again.
651 cpu_store_8bit( _environment, blank->realName, 0 );
652
653 // Avoid to update position if not requested
654 cpu_compare_and_branch_8bit_const( _environment, noUpdate->realName, 0xff, done2CommandLabel, 1 );
655 gr_locate( _environment, x->name, y->name );
656
657 // Move to the next character of the drawing commands string.
658 cpu_label( _environment, done2CommandLabel );
659 cpu_store_8bit( _environment, noUpdate->realName, 0 );
660 // cpu_inc( _environment, size->realName );
661 // cpu_dec_16bit( _environment, address->realName );
662 cpu_store_16bit( _environment, dx->realName, 0 );
663 cpu_store_16bit( _environment, dy->realName, 0 );
664 cpu_store_16bit( _environment, ds->realName, 0 );
665 cpu_jump( _environment, doneCommandLabel );
666
667 // Move to the next character of the drawing commands string.
668 cpu_label( _environment, doneCommandLabel );
669
670 end_do_loop( _environment );
671 // ------------------------------------ FETCH AND DECODE LOOP (end)
672
673 cpu_label( _environment, label );
674 cpu_return( _environment );
675
677
678 Variable * string = variable_retrieve( _environment, _string );
679
680 if ( ( string->type != VT_STRING ) && ( string->type != VT_DSTRING ) ) {
682 }
683
684 if( string->type == VT_STRING ) {
685 Variable * dstring = variable_temporary( _environment, VT_DSTRING, "(dstring)" );
686 cpu_dsdefine( _environment, string->realName, dstring->realName );
687 string = dstring;
688 }
689
690 Variable * parameter = variable_retrieve( _environment, "drawstring__string" );
691
692 variable_move( _environment, string->name, parameter->name );
693 cpu_call( _environment, "lib_draw_string");
694
695 if ( _environment->procedureName ) {
696 yield( _environment );
697 }
698
699}
void cpu_store_char(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 8 bit
Definition 6309.c:785
void cpu_store_16bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 16 bit
Definition 6309.c:1503
void cpu_inc(Environment *_environment, char *_variable)
Definition 6309.c:4555
void cpu_dsdefine(Environment *_environment, char *_string, char *_index)
Definition 6309.c:5884
void cpu_compare_and_branch_char_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
CPU 6309: emit code to compare two 8 bit values and jump if they are equal/different
Definition 6309.c:925
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_dec(Environment *_environment, char *_variable)
Definition 6309.c:4630
void cpu_greater_than_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 6309.c:999
void cpu_move_16bit(Environment *_environment, char *_source, char *_destination)
CPU 6309: emit code to move 16 bit
Definition 6309.c:1474
void cpu_call(Environment *_environment, char *_label)
Definition 6309.c:3755
void cpu_store_8bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 8 bit
Definition 6309.c:761
void cpu_jump(Environment *_environment, char *_label)
Definition 6309.c:3739
void cpu_less_than_8bit_const(Environment *_environment, char *_source, int _destination, char *_other, int _equal, int _signed)
Definition 6309.c:960
void cpu_return(Environment *_environment)
Definition 6309.c:4030
void cpu_move_8bit_indirect2(Environment *_environment, char *_value, char *_source)
Definition 6309.c:5294
void cpu_inc_16bit(Environment *_environment, char *_variable)
Definition 6309.c:4565
void cpu_compare_and_branch_8bit(Environment *_environment, char *_source, char *_destination, char *_label, int _positive)
Definition 6309.c:851
void cpu_convert_string_into_16bit(Environment *_environment, char *_string, char *_len, char *_value)
Definition 6309.c:5502
void cpu_dsdescriptor(Environment *_environment, char *_index, char *_address, char *_size)
Definition 6309.c:5977
void cpu_compare_and_branch_8bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
CPU 6309: emit code to compare two 8 bit values and jump if they are equal/different
Definition 6309.c:876
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 * origin_resolution_relative_transform_x(Environment *_environment, char *_x, int _is_relative)
Variable * variable_move(Environment *_environment, char *_source, char *_destination)
Store the value of a variable inside another variable by converting it.
Variable * variable_define(Environment *_environment, char *_name, VariableType _type, int _value)
Define a variable for the program.
Variable * variable_mul(Environment *_environment, char *_source, char *_destination)
Make a multiplication between two variable and return the product of them.
Variable * origin_resolution_relative_transform_y(Environment *_environment, char *_y, int _is_relative)
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_div2_const(Environment *_environment, char *_destination, int _bits, char *_remainder)
Subdivide by two a variable for various times and return the result.
int size
Definition _optimizer.c:678
char * name
Definition _optimizer.c:672
void begin_do_loop(Environment *_environment)
Emit ASM code for DO ....
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 draw_string(Environment *_environment, char *_string)
void end_do_loop(Environment *_environment)
Emit ASM code for ... LOOP.
Definition end_do_loop.c:49
void gr_locate(Environment *_environment, char *_x, char *_y)
Emit code for GR LOCATE command.
Definition gr.c:89
char * procedureName
Definition ugbc.h:2775
char * name
Definition ugbc.h:979
VariableType type
Definition ugbc.h:988
char * realName
Definition ugbc.h:982
#define deploy_end(s)
Definition ugbc.h:4365
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
#define CRITICAL_CANNOT_USE_DRAW_WITHOUT_STRING(t)
Definition ugbc.h:3683
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_POSITION
Definition ugbc.h:468
@ VT_STRING
Definition ugbc.h:474
@ VT_BYTE
Definition ugbc.h:450
@ VT_ADDRESS
Definition ugbc.h:465
@ VT_COLOR
Definition ugbc.h:471
@ VT_DSTRING
Definition ugbc.h:483
#define deploy_begin(s)
Definition ugbc.h:4356
#define MAKE_LABEL
Definition ugbc.h:3351
void yield(Environment *_environment)
Emit code for YIELD.
Definition yield.c:63