Initial revision
[ssr] / StraySrc / Libraries / Sapphire / s / draw
1 ;
2 ; draw.s
3 ;
4 ; Renders DrawFiles (MDW)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29 GET libs:header
30 GET libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34 GET sapphire:divide
35 GET sapphire:mem
36 GET sapphire:msgs
37 GET sapphire:roVersion
38 GET sapphire:sapphire
39 GET sapphire:screen
40 GET sapphire:sprite
41
42 ;----- Main code ------------------------------------------------------------
43
44 AREA |Sapphire$$Code|,CODE,READONLY
45
46 ; --- Register allocation ---
47 ;
48 ; R12 == pointer to font array
49 ; R10 == pointer to transform matrix
50 ; R9 == pointer to clipping block (in Draw units)
51 ; R8 == pointer to end of objects to render
52 ; R7 == pointer to start of current object
53
54 ; --- draw_render ---
55 ;
56 ; On entry: R0 == scale to plot drawfile (16.16 form)
57 ; R1 == pointer to a redraw block
58 ; R2 == pointer to drawfile in memory
59 ; R3 == size of drawfile block
60 ;
61 ; On exit: --
62 ;
63 ; Use: Renders a DrawFile in a window. Objects which aren't
64 ; recognised are not rendered. The objects which are handled
65 ; are as follows:
66 ;
67 ; * Font table objects
68 ; * Text objects (in fonts, or in system font)
69 ; * Draw path objects, filled and unfilled, including
70 ; dotted outlines
71 ; * Group objects
72 ; * Tagged objects
73 ; * Sprite objects, rendered as well as we can make it
74 ; * Transformed text, only on RISC OS 3
75 ; * Transformed sprite, only on RISC OS 3
76
77 EXPORT draw_render
78 draw_render ROUT
79
80 STMFD R13!,{R0-R12,R14} ;Save a load of registers
81
82 ; --- Set up the transformation matrix ---
83
84 LDR R4,[R1,#4] ;Load minimum x coord
85 ADD R14,R1,#16 ;Point to maximum y coord
86 LDMIA R14,{R5-R7} ;Load y coord and scroll pos
87 SUB R4,R4,R6 ;Work out x origin position
88 SUB R5,R5,R7 ;And the y origin position
89
90 SUB R13,R13,#24 ;Make way for the transform
91 MOV R10,R13 ;Point to it nicely
92 MOV R14,R13 ;Point to it for filling
93 MOV R6,R0 ;Set up x scale from user
94 MOV R7,#0 ;Don't do fancy x transforms
95 MOV R8,#0 ;Don't do fancy y transforms
96 MOV R9,R0 ;And scale y from user
97 STMIA R14!,{R6-R9} ;Save this in the block
98 MOV R6,R4,LSL #8 ;Convert offset to draw units
99 MOV R7,R5,LSL #8 ;And convert y offset too
100 STMIA R14,{R6,R7} ;Save these in the matrix too
101
102 ; --- Set up the adjusted clipping block too ---
103
104 SUB R13,R13,#16 ;Make way for a clipping blk
105 ADD R14,R1,#28 ;Point to original block
106 LDMIA R14,{R6-R9} ;Load the clipping coords
107 SUB R6,R6,R4 ;Convert these to window...
108 SUB R7,R7,R5 ;... coordinates for easy...
109 SUB R8,R8,R4 ;... clipping
110 SUB R9,R9,R5
111 MOV R4,R0 ;Get the scale factor safe
112
113 ; --- Now we have to divide by the scale factor ---
114
115 MOV R12,#&18000 ;A useful constant (1 1/2)
116 RSB R0,R12,R6,LSL #16 ;Take minimum x position
117 MOV R1,R4,LSR #8 ;And the scale factor
118 BL divide ;Do the division
119 MOV R6,R0 ;Take the result away nicely
120
121 RSB R0,R12,R7,LSL #16 ;Take minimum y position
122 MOV R1,R4,LSR #8 ;And the scale factor
123 BL divide ;Do the division
124 MOV R7,R0 ;Take the result away nicely
125
126 ADD R0,R12,R8,LSL #16 ;Take maximum x position
127 MOV R1,R4,LSR #8 ;And the scale factor
128 ADD R0,R0,R1 ;Make it round upwards
129 BL divide ;Do the division
130 MOV R8,R0 ;Take the result away nicely
131
132 ADD R0,R12,R9,LSL #16 ;Take maximum y position
133 MOV R1,R4,LSR #8 ;And the scale factor
134 ADD R0,R0,R1 ;Make it round upwards
135 BL divide ;Do the division
136 MOV R9,R0 ;Take the result away nicely
137
138 STMIA R13,{R6-R9} ;Save the modified values
139 MOV R9,R13 ;Point to the coords block
140
141 ; --- Set up start and end values ---
142
143 MOV R7,R2 ;Get start address to render
144 ADD R8,R7,R3 ;And calculate end address
145 MOV R0,R7 ;Point to the drawfile
146 BL draw_checkValid ;Make sure the drawfile's OK
147 BVS %10draw_render ;If not don't draw it
148 ADD R7,R7,#40 ;Point to renderable part
149
150 ; --- And finally initialise the font array ---
151
152 SUB R13,R13,#1024 ;The font array is *big*
153 MOV R12,R13 ;Point to it
154 MOV R0,R12 ;Point to font array
155 MOV R1,#1024 ;Get its size
156 MOV R2,#0 ;We're going to fill it
157 BL mem_set ;So make it all zeroes
158
159 ; --- Do the main rendering and tidy up ---
160
161 BL draw__doRender ;And do the main job
162 10draw_render ADD R13,R10,#24 ;Reclaim all the stack
163 BL draw__resetTextSize ;Make the text size sensible
164 LDMFD R13!,{R0-R12,PC}^ ;Return to caller now
165
166 ; --- draw_checkValid ---
167 ;
168 ; On entry: R0 == pointer to start of drawfile
169 ;
170 ; On exit: May return an error
171 ;
172 ; Use: Checks whether a drawfile is basically sound. This checking
173 ; isn't compulsory, and just checks the initial word and the
174 ; format version number -- nothing very exciting.
175
176 EXPORT draw_checkValid
177 draw_checkValid ROUT
178
179 BIC R14,R14,#V_flag ;Assume everything's OK
180 STMFD R13!,{R1,R14} ;Save a register away
181 LDR R14,draw__drawMagic ;Load the magic word out
182 LDR R1,[R0,#0] ;Load the first word out
183 CMP R14,R1 ;Do they match perfectly?
184 BNE %90draw_checkValid ;No -- then return error
185 LDR R14,[R0,#4] ;Load major format version
186 CMP R14,#201 ;Is it old enough for me?
187 LDMLEFD R13!,{R1,PC}^ ;Return to caller if OK
188
189 ; --- Version number is wrong ---
190
191 ADR R0,draw__tooNew ;Point to the error message
192 B %95draw_checkValid ;And handle the error
193
194 draw__drawMagic DCB "Draw"
195
196 draw__tooNew DCD 1
197 DCB "drawTOONEW",0
198
199 ; --- It isn't a drawfile ---
200
201 90 ADR R0,draw__badFile ;Point to the error message
202 95 BL msgs_error ;Translate the error
203 LDMFD R13!,{R1,R14} ;Unstack some registers
204 ORRS PC,R14,#V_flag ;And return the error
205
206 draw__badFile DCD 1
207 DCB "drawBADFILE",0
208
209 LTORG
210
211 ; --- draw__doRender ---
212 ;
213 ; On entry: R7 == pointer to object to start rendering
214 ; R8 == pointer to first object not to render
215 ; R9 == pointer to coordinate clipping block
216 ; R10 == pointer to transformation matrix
217 ; R12 == pointer to font array
218 ;
219 ; On exit: R7 points past last object rendered
220 ; R0-R6 may be corrupted
221 ;
222 ; Use: Renders a group of objects.
223
224 draw__doRender ROUT
225
226 STMFD R13!,{R14} ;Save a register
227 00 CMP R7,R8 ;Is there anything to do?
228 BLLT draw__renderObject ;Yes -- render an object
229 BLT %00draw__doRender ;And go round again
230 LDMFD R13!,{PC}^ ;Return to caller
231
232 LTORG
233
234 ; --- draw__renderObject ---
235 ;
236 ; On entry: R7 == pointer to object to render
237 ; R8 == pointer to first object not to render
238 ; R9 == pointer to coordinate clipping block
239 ; R10 == pointer to transformation matrix
240 ; R12 == pointer to font array
241 ;
242 ; On exit: R7 == pointer to next object to render
243 ; R0-R6 may be corrupted
244 ;
245 ; Use: The main object rendering dispatch routine.
246
247 draw__renderObject ROUT
248
249 LDR R0,[R7,#0] ;Get the object's type
250 CMP R0,#(%10-%00)/4 ;Is it in range of my table?
251 ADDLO PC,PC,R0,LSL #2 ;Yes -- dispatch it then
252 B %10draw__renderObject ;Out of range -- ignore it
253
254 00 B draw__readFontTable ;Font table object
255 B draw__renderText ;Render a text string
256 B draw__renderPath ;Render a standard draw path
257 B %10draw__renderObject ;Type 3 is not defined
258 B %10draw__renderObject ;Type 4 is not defined
259 B draw__renderSprite ;Render a sprite
260 B draw__renderGroup ;Handle a group of objects
261 B draw__renderTagged ;Render a tagged object
262 B %10draw__renderObject ;Type 8 is not defined
263 B %10draw__renderObject ;Text area is too difficult
264 B %10draw__renderObject ;Text column is too difficult
265 B %10draw__renderObject ;Options are not renderable
266 B draw__renderTransformedText ;Render rotated text
267 B draw__renderTransformedSprite ;Render rotated sprite
268
269 10 B draw__next ;Ignore unknown objects
270
271 LTORG
272
273 ; --- draw__next ---
274 ;
275 ; On entry: R7 == pointer to a draw object
276 ;
277 ; On exit: R7 == pointer to next draw object
278 ; R0 corrupted
279 ;
280 ; Use: Moves the current pointer on to the next object
281
282 draw__next ROUT
283
284 LDR R0,[R7,#4] ;Load the object size
285 ADD R7,R7,R0 ;Advance the object pointer
286 MOVS PC,R14 ;Return to caller
287
288 LTORG
289
290 ; --- draw__clip ---
291 ;
292 ; On entry: R7 == pointer to a draw object
293 ; R9 == pointer to current clipping rectangle
294 ;
295 ; On exit: R0-R6 corrupted
296 ; CS if the object appears within the clipping rectangle,
297 ; CC if it doesn't
298 ;
299 ; Use: Determines if a draw object needs rendering in the current
300 ; redraw job.
301
302 draw__clip STMFD R13!,{R7} ;Save a register
303 ADD R7,R7,#8 ;Point to the bounding box
304 LDMIA R7,{R4-R7} ;Load the box from it
305 LDMIA R9,{R0-R3} ;And load the clipping box
306 CMP R0,R6 ;Make sure the rectangles...
307 CMPLE R1,R7 ;... overlap
308 CMPLE R4,R2
309 CMPLE R5,R3
310 LDMFD R13!,{R7} ;Restore the R7 I saved
311 ORRLES PC,R14,#C_flag ;If it is within, set C
312 BICGTS PC,R14,#C_flag ;Otherwise clear C on exit
313
314 LTORG
315
316 ; --- draw__setTextSize ---
317 ;
318 ; On entry: R0 == x size in pixels
319 ; R1 == y size in pixels
320 ;
321 ; On exit: --
322 ;
323 ; Use: Sets the VDU 5 text size.
324
325 draw__setTextSize ROUT
326
327 STMFD R13!,{R0-R2,R14} ;Save a load of registers
328 MOV R1,R1,LSL #16 ;Shift up the y sizes
329 ORR R1,R1,R0 ;Add in the x sizes
330 MOV R0,#23 ;Build initial VDU sequence
331 ORR R0,R0,#17<<8 ;Add in more chars
332 ORR R0,R0,#7<<16
333 ORR R0,R0,#2<<24
334 MOV R2,#0 ;Wrap up the sequence nicely
335 STMFD R13!,{R0-R2} ;Save it on the stack
336 MOV R0,R13 ;Point to the sequence
337 MOV R1,#10 ;Get the sequence size in R1
338 SWI OS_WriteN ;Write it to the VDU stream
339 MOV R14,#4 ;Now set the spacing up
340 STRB R14,[R13,#3] ;Save it in the stream
341 MOV R0,R13 ;Point to the sequence
342 MOV R1,#10 ;Get the sequence size in R1
343 SWI OS_WriteN ;Write it to the VDU stream
344 ADD R13,R13,#12 ;Restore the stack pointer
345 LDMFD R13!,{R0-R2,PC}^ ;Return to caller
346
347 LTORG
348
349 ; --- draw__resetTextSize ---
350 ;
351 ; On entry: --
352 ;
353 ; On exit: --
354 ;
355 ; Use: Makes the text size nice again after doing all sorts of
356 ; horrid things to it for the sake of plotting text in the
357 ; system font.
358
359 draw__resetTextSize ROUT
360
361 STMFD R13!,{R0,R1,R14} ;Save some registers
362 BL screen_getInfo ;Read the screen information
363 LDMIA R0,{R0,R1} ;Load the eigen factors
364 MOV R14,#16 ;Normal width 16 OS units
365 MOV R0,R14,LSR R0 ;Scale it into pixels
366 MOV R14,#32 ;Normal height 32 OS units
367 MOV R1,R14,LSR R1 ;Scale it into pixels
368 BL draw__setTextSize ;Set the pixel size nicely
369 LDMFD R13!,{R0,R1,PC}^ ;And return to caller
370
371 LTORG
372
373 ;----- Object handlers ------------------------------------------------------
374 ;
375 ; All of these have the same entry and exit conditions as draw__renderObject.
376
377 ; --- draw__readFontTable ---
378
379 draw__readFontTable ROUT
380
381 LDR R1,[R7,#4] ;Find the object size
382 ADD R1,R7,R1 ;Convert to object end
383 ADD R0,R7,#8 ;Find start of font data
384
385 ; --- Read an entry from the table ---
386
387 00 CMP R0,R1 ;Have we finished yet?
388 BGE draw__next ;Yes -- return to caller
389 LDRB R2,[R0],#1 ;Get the internal font handle
390 CMP R2,#0 ;Is this a null one?
391 BEQ draw__next ;Yes -- that's it then
392
393 STR R0,[R12,R2,LSL #2] ;Save the name pointer away
394 10 LDRB R2,[R0],#1 ;Get a font name character
395 CMP R2,#0 ;Is this the end of the name?
396 BNE %10draw__readFontTable ;No -- go round again then
397
398 B %00draw__readFontTable ;Read the next font name
399
400 LTORG
401
402 ; --- draw__renderText ---
403
404 draw__renderText ROUT
405
406 STMFD R13!,{R14} ;Save the link temporarily
407 BL draw__clip ;Do we have to render it?
408 LDMFD R13!,{R14} ;Restore the link again
409 BCC draw__next ;No -- then return
410
411 ; --- Make sure the text isn't invisible ---
412
413 ADD R6,R7,#24 ;Point to the object data
414 LDR R0,[R6,#0] ;Load the foreground colour
415 CMP R0,#-1 ;Is it transparent?
416 MOVEQS PC,R14 ;Yes -- do nothing then
417
418 ; --- Find the font name ---
419
420 LDR R5,[R6,#8] ;Load internal font handle
421 CMP R5,#0 ;Is the handle 0?
422 BEQ draw__renderSystemText ;Yes -- use the system font
423 LDR R5,[R12,R5,LSL #2] ;Load the font name pointer
424 CMP R5,#0 ;Is it defined?
425 BEQ draw__renderSystemText ;No -- use the system font
426
427 ; --- Work out the text size I need ---
428
429 STMFD R13!,{R14} ;Save the link again
430 ADD R2,R6,#12 ;Point to the text sizes
431 LDMIA R2,{R2,R3} ;Load x and y sizes
432 LDR R4,[R10,#0] ;Load the scale factor
433 MOV R4,R4,LSR #8 ;Scale it down a little
434 MUL R2,R4,R2 ;Scale up the x size
435 MUL R3,R4,R3 ;And scale up the y size
436 MOV R4,#5 ;So div10 rounds to nearest
437 ADD R2,R4,R2,LSR #10 ;Scale values down further
438 ADD R3,R4,R3,LSR #10 ;Both the x and the y
439 MOV R0,R2 ;Get the x size
440 BL div10 ;Convert to points
441 MOV R2,R0 ;Move back into position
442 MOV R0,R3 ;Get the y size
443 BL div10 ;Convert to points
444 MOV R3,R0 ;Move back into position
445 LDMFD R13!,{R14} ;Restore the link again
446
447 ; --- Get a font handle ---
448
449 MOV R1,R5 ;Get the font name pointer
450 MOV R4,#0 ;Default scaling, please
451 MOV R5,#0 ;On x and y axes
452 SWI XFont_FindFont ;Try to get a font handle
453 BVS draw__renderSystemText ;Couldn't -- use system font
454
455 ; --- Set the right colours ---
456
457 LDR R1,[R6,#4] ;Load the background colour
458 LDR R2,[R6,#0] ;Load the foreground colour
459 MOV R3,#14 ;Antialias lots and lots
460 SWI ColourTrans_SetFontColours
461
462 ; --- Work out where to paint the text ---
463
464 ADD R3,R6,#20 ;Point to the coordinates
465 LDMIA R3,{R3,R4} ;Load the coordinates out
466 LDR R5,[R10,#0] ;Load the scale factor out
467 MOV R5,R5,LSR #8 ;Scale it down a little
468 MUL R3,R5,R3 ;Multiply up the x position
469 MUL R4,R5,R4 ;Multiply up the y position
470 MOV R3,R3,ASR #16 ;Scale down the x position
471 MOV R4,R4,ASR #16 ;Scale down the y position
472 ADD R1,R10,#16 ;Point to the plot offset
473 LDMIA R1,{R1,R2} ;Load the offsets out
474 ADD R3,R3,R1,ASR #8 ;Add it on (convert to OS)
475 ADD R4,R4,R2,ASR #8 ;Convert the y coordinate too
476
477 ; --- Paint the actual text then ---
478
479 ADD R1,R6,#28 ;Point to the text string
480 MOV R2,#&10 ;Coordinates are in OS units
481 SWI Font_Paint ;Paint the text on the screen
482
483 ; --- Tidy everything up then ---
484
485 SWI Font_LoseFont ;Lose the font handle now
486 B draw__next ;Find next draw object
487
488 LTORG
489
490 ; --- draw__renderSystemText ---
491 ;
492 ; Notes: This routine is entered with R6 set up as pointer to the
493 ; specific object data, and havng made sure that the text
494 ; actually does have to be rendered.
495
496 draw__renderSystemText ROUT
497
498 ; --- Set up the plotting colour ---
499
500 STMFD R13!,{R14} ;Save the link register
501 LDR R0,[R6,#0] ;Load the foreground colour
502 MOV R3,#0 ;Don't bother dithering it
503 MOV R4,#0 ;And set normal GCOL action
504 SWI ColourTrans_SetGCOL ;Set up the colour
505
506 ; --- Set up the text size ---
507
508 BL screen_getInfo ;Get things about the screen
509 LDMIA R0,{R2,R3} ;Load the eigen factors
510 ADD R14,R6,#12 ;Point to the size arguments
511 LDMIA R14,{R0,R1} ;Load the text sizes out
512 LDR R4,[R10,#0] ;Load the scale factor
513 MOV R4,R4,LSR #8 ;Shift it down a little
514 MUL R0,R4,R0 ;Multiply x size up
515 MUL R1,R4,R1 ;Multiply y size up too
516 MOV R0,R0,LSR #16 ;Scale x size down more
517 MOV R0,R0,LSR R2 ;And divide by pixel size
518 MOV R1,R1,LSR #16 ;Scale y size down more
519 MOV R1,R1,LSR R3 ;And divide by pixel size
520 BL draw__setTextSize ;Set the VDU 5 text size
521 MOV R3,R1,LSL R3 ;Multply y size up a bit
522
523 ; --- Move to the right place ---
524
525 ADD R14,R6,#20 ;Point to the position data
526 LDMIA R14,{R1,R2} ;Load the text positions
527 MUL R1,R4,R1 ;Scale up the x position
528 MUL R2,R4,R2 ;Scale up the y position
529 MOV R1,R1,ASR #16 ;Scale down the x pos
530 MOV R2,R2,ASR #16 ;Scale down the y pos
531 SUB R3,R3,R3,LSR #3 ;Find 7/8 of character height
532 ADD R2,R2,R3 ;Find top of text line
533 ADD R14,R10,#16 ;Find render offsets nicely
534 LDMIA R14,{R3,R4} ;Load the offsets out
535 ADD R1,R1,R3,ASR #8 ;Add them and convert to OS
536 ADD R2,R2,R4,ASR #8 ;Both the x and the y please
537 MOV R0,#4 ;Move cursor absolute
538 SWI OS_Plot ;Move graphics cursor nicely
539
540 ; --- Plot the text and go home ---
541
542 ADD R0,R6,#28 ;Point to the text string
543 SWI OS_Write0 ;Plot it on the screen
544 LDMFD R13!,{R14} ;Unstack the link register
545 B draw__next ;And move to the next object
546
547 LTORG
548
549 ; --- draw__renderPath ---
550
551 draw__renderPath ROUT
552
553 STMFD R13!,{R14} ;Save the link temporarily
554 BL draw__clip ;Do we have to render it?
555 LDMCCFD R13!,{R14} ;Restore the link again
556 BCC draw__next ;No -- then return
557
558 LDR R6,[R7,#36] ;Load the path style word
559 TST R6,#&80 ;Is there a dot-dash pattern?
560 ADDEQ R5,R7,#40 ;No -- find path data then
561 LDRNE R5,[R7,#44] ;Yes -- load dot-dash length
562 ADDNE R5,R7,R5,LSL #2 ;Add this to object start
563 ADDNE R5,R5,#48 ;And add fixed part of dash
564
565 ; --- Handle the filled in bit ---
566
567 LDR R0,[R7,#24] ;Load the fill colour
568 CMP R0,#-1 ;Is it transparent?
569 BEQ %50draw__renderPath ;Yes -- just draw outline
570
571 ; --- Render a filled path ---
572
573 MOV R3,#&100 ;Try and dither the fill
574 MOV R4,#0 ;Set normal GCOL action
575 SWI ColourTrans_SetGCOL ;Set the colour up
576
577 MOV R0,#&c80000 ;The basic flatness is 200
578 LDR R1,[R10,#0] ;Load the scale factor
579 BL div_round ;Divide to get the flatness
580 MOV R3,R0 ;Get flatness in R3 nicely
581
582 AND R1,R6,#&40 ;Get the path winding rule
583 MOV R1,R1,LSR #5 ;Shift it down into place
584 ORR R1,R1,#&30 ;And add in other fill bits
585 MOV R0,R5 ;Point to path specification
586 MOV R2,R10 ;Point to transform matrix
587 SWI Draw_Fill ;And render the filled path
588
589 ; --- Now handle an outline ---
590
591 50 LDR R0,[R7,#28] ;Load the outline colour
592 CMP R0,#-1 ;Is it transparent?
593 BEQ %90draw__renderPath ;Yes -- wrap everything up
594
595 ; --- Render a path outline ---
596
597 MOV R3,#&100 ;Try and dither the outline
598 MOV R4,#0 ;Set normal GCOL action
599 SWI ColourTrans_SetGCOL ;Set the colour up
600
601 ; --- Build the cap and join block ---
602 ;
603 ; Note that in fact the end cap and start cap specs are
604 ; reversed. This is a result of Acorn stupidity, bad
605 ; documentation, or both. We sit back and laugh as
606 ; WimpExtension gets it wrong.
607
608 AND R0,R6,#&03 ;Get the join style style
609 AND R4,R6,#&30 ;Get the start cap style
610 ORR R0,R0,R4,LSL #12 ;Move that into byte 2
611 AND R4,R6,#&0C ;Get the end cap style
612 ORR R0,R0,R4,LSL #6 ;Move that into byte 1
613
614 MOV R1,#&A0000 ;Mitre limit is 10.0
615
616 AND R2,R6,#&00FF0000 ;Get triangle cap width
617 MOV R2,R2,LSR #12 ;Move it into position
618 AND R4,R6,#&FF000000 ;Get triangle cap height
619 ORR R2,R2,R4,LSR #4 ;Move that into position
620
621 MOV R3,R2 ;End triangle == start one
622
623 STMFD R13!,{R0-R3} ;Save cap and join spec
624
625 ; --- Finally, plot the path ---
626
627 MOV R0,#&c80000 ;The basic flatness is 200
628 LDR R1,[R10,#0] ;Load the scale factor
629 BL div_round ;Divide to get the flatness
630 MOV R3,R0 ;Get flatness in R3 nicely
631 MOV R0,R5 ;Point to the path spec
632 MOV R1,#&38 ;A set fill style, please
633 MOV R2,R10 ;Point to transform matrix
634 LDR R4,[R7,#32] ;Load the line width
635 MOV R5,R13 ;Point to join and cap block
636 TST R6,#&80 ;Is there a dash pattern?
637 MOVEQ R6,#0 ;No -- don't plot one then
638 ADDNE R6,R7,#40 ;Yes -- find the data
639 SWI Draw_Stroke ;Plot the path outline
640 ADD R13,R13,#16 ;Recover used stack space
641
642 ; --- Wrap it all up nicely ---
643
644 90 LDMFD R13!,{R14} ;Restore the link again
645 B draw__next ;Find the next draw object
646
647 LTORG
648
649 ; --- draw__renderSprite ---
650
651 draw__renderSprite ROUT
652
653 ; --- Make sure I have to render it ---
654
655 STMFD R13!,{R14} ;Save the link temporarily
656 BL draw__clip ;Do we have to render it?
657 LDMCCFD R13!,{R14} ;Restore the link again
658 BCC draw__next ;No -- then return
659
660 ; --- Get a colour translation table for it ---
661
662 ADD R0,R7,#24 ;Point to the sprite def
663 MOV R1,R11 ;Put table in scratchpad
664 BL sprite_getTable ;Find a translation table
665
666 ; --- Work out the correct scaling ---
667
668 MOV R0,#40 ;Read sprite info
669 ADD R0,R0,#512 ;Sprite is pointed at
670 MOV R1,#&1000 ;Don't care about sprite area
671 ADD R2,R7,#24 ;Point to sprite block
672 SWI OS_SpriteOp ;Read the sprite info
673 BL screen_getInfo ;Read some screen info
674 LDMIA R0,{R0,R1} ;Load the eigen factors
675 MOV R5,R4,LSL R1 ;Scale the y value into R5
676 MOV R4,R3,LSL R0 ;Scale the x value into R4
677
678 ADD R0,R7,#8 ;Point to sprite bounding box
679 LDMIA R0,{R0-R3} ;Load the values out
680 SUB R2,R2,R0 ;Get sprite width in R2
681 SUB R3,R3,R1 ;Get sprite height in R3
682 MOV R2,R2,LSR #8 ;Scale the dimensions down
683 MOV R3,R3,LSR #8 ;In both directions
684 LDR R14,[R10,#0] ;Load the scale factor
685 MUL R2,R14,R2 ;Scale the x size
686 MUL R3,R14,R3 ;And the y size
687 MOV R2,R2,LSR #16 ;And scale the value down
688 MOV R3,R3,LSR #16 ;Both directions again
689 STMFD R13!,{R2-R5} ;Save the resulting zoom blk
690
691 MOV R14,R14,LSR #8 ;Shift scale factor down
692 MUL R3,R14,R0 ;Scale the x position
693 MUL R4,R14,R1 ;And the y position
694 MOV R3,R3,ASR #16 ;Scale down the resulting pos
695 MOV R4,R4,ASR #16 ;In both directions
696 ADD R0,R10,#16 ;Find the transform offsets
697 LDMIA R0,{R0,R1} ;Load them from the block
698 ADD R3,R3,R0,ASR #8 ;Add the x offset on
699 ADD R4,R4,R1,ASR #8 ;Add the y offset on too
700
701 ; --- Now plot the sprite in the right place ---
702
703 STMFD R13!,{R7} ;Save R7 -- we need to use it
704 MOV R0,#52 ;Plot sprite scaled, please
705 ADD R0,R0,#512 ;Tell it I have a sprite ptr
706 MOV R1,#&1000 ;A dummy sprite area
707 ADD R2,R7,#24 ;Point to the sprite def
708 MOV R5,#8 ;Plot with mask, please
709 ADD R6,R13,#4 ;Point to my zoom block
710 MOV R7,R11 ;Point to my translate table
711 SWI OS_SpriteOp ;Plot the sprite
712 LDMFD R13!,{R7} ;Unstack R7 again
713 ADD R13,R13,#16 ;Recover the zoom block
714 LDMFD R13!,{R14} ;Unstack the link register
715 B draw__next ;And render the next object
716
717 LTORG
718
719 ; --- draw__renderGroup ---
720
721 draw__renderGroup ROUT
722
723 STMFD R13!,{R14} ;Save the link temporarily
724 BL draw__clip ;Do we have to render it?
725 LDMFD R13!,{R14} ;Restore the link again
726 BCC draw__next ;No -- then return
727
728 ADD R7,R7,#36 ;Render the objects in there
729 MOVS PC,R14 ;I've mangled the object ptr
730
731 LTORG
732
733 ; --- draw__renderTagged ---
734
735 draw__renderTagged ROUT
736
737 STMFD R13!,{R14} ;Save the link temporarily
738 BL draw__clip ;Do we have to render it?
739 LDMCCFD R13!,{R14} ;Restore the link again
740 BCC draw__next ;No -- then return
741
742 STMFD R13!,{R7,R8} ;Save the object pointer
743 ADD R7,R7,#28 ;Point to the enclosed object
744 LDR R8,[R7,#4] ;Get the object size
745 ADD R8,R7,R8 ;Point past the object
746 BL draw__doRender ;Render the object
747 LDMFD R13!,{R7,R8,R14} ;Restore registers
748 B draw__next ;And move to the next object
749
750 LTORG
751
752 ; --- draw__renderTransformedText ---
753
754 draw__renderTransformedText ROUT
755
756 STMFD R13!,{R14} ;Save the link temporarily
757 BL draw__clip ;Do we have to render it?
758 BLCS rov_version ;Get the current OS version
759 CMPCS R0,#300 ;Is it RISC OS 3 yet?
760 LDMFD R13!,{R14} ;Restore the link again
761 BCC draw__next ;No -- then return
762
763 ; --- Make sure the text isn't invisible ---
764
765 ADD R6,R7,#24 ;Point to the object data
766 LDR R0,[R6,#0] ;Load the foreground colour
767 CMP R0,#-1 ;Is it transparent?
768 MOVEQS PC,R14 ;Yes -- do nothing then
769
770 ; --- Find the font name ---
771
772 LDR R5,[R6,#36] ;Load internal font handle
773 CMP R5,#0 ;Is the handle 0?
774 BEQ %90draw__renderTransformedText
775 LDR R5,[R12,R5,LSL #2] ;Load the font name pointer
776 CMP R5,#0 ;Is it defined?
777 BEQ %90draw__renderTransformedText
778
779 ; --- Work out the text size I need ---
780
781 STMFD R13!,{R14} ;Save the link again
782 ADD R2,R6,#40 ;Point to the text sizes
783 LDMIA R2,{R2,R3} ;Load x and y sizes
784 LDR R4,[R10,#0] ;Load the scale factor
785 MOV R4,R4,LSR #8 ;Scale it down a little
786 MUL R2,R4,R2 ;Scale up the x size
787 MUL R3,R4,R3 ;And scale up the y size
788 MOV R4,#5 ;So div10 rounds to nearest
789 ADD R2,R4,R2,LSR #10 ;Scale values down further
790 ADD R3,R4,R3,LSR #10 ;Both the x and the y
791 MOV R0,R2 ;Get the x size
792 BL div10 ;Convert to points
793 MOV R2,R0 ;Move back into position
794 MOV R0,R3 ;Get the y size
795 BL div10 ;Convert to points
796 MOV R3,R0 ;Move back into position
797 LDMFD R13!,{R14} ;Restore the link again
798
799 ; --- Get a font handle ---
800
801 MOV R1,R5 ;Get the font name pointer
802 MOV R4,#0 ;Default scaling, please
803 MOV R5,#0 ;On x and y axes
804 SWI XFont_FindFont ;Try to get a font handle
805 BVS %90draw__renderTransformedText
806
807 ; --- Set the right colours ---
808
809 LDR R1,[R6,#32] ;Load the background colour
810 LDR R2,[R6,#28] ;Load the foreground colour
811 MOV R3,#14 ;Antialias lots and lots
812 SWI ColourTrans_SetFontColours
813
814 ; --- Work out where to paint the text ---
815
816 ADD R3,R6,#48 ;Point to the coordinates
817 LDMIA R3,{R3,R4} ;Load the coordinates out
818 LDR R5,[R10,#0] ;Load the scale factor out
819 MOV R5,R5,LSR #8 ;Scale it down a little
820 MUL R3,R5,R3 ;Multiply up the x position
821 MUL R4,R5,R4 ;Multiply up the y position
822 MOV R3,R3,ASR #16 ;Scale down the x position
823 MOV R4,R4,ASR #16 ;Scale down the y position
824 ADD R1,R10,#16 ;Point to the plot offset
825 LDMIA R1,{R1,R2} ;Load the offsets out
826 ADD R3,R3,R1,ASR #8 ;Add it on (convert to OS)
827 ADD R4,R4,R2,ASR #8 ;Convert the y coordinate too
828
829 ; --- Scale position to millipoints ---
830 ;
831 ; Multiply by 500 (very quickly)
832
833 ADD R3,R3,R3,LSL #2 ;Multiply R3 by 5 (*5)
834 ADD R3,R3,R3,LSL #2 ;Multiply R3 by 5 (*25)
835 MOV R3,R3,LSL #4 ;Multiply R3 by 16 (*400)
836
837 ADD R4,R4,R4,LSL #2 ;Multiply R3 by 5 (*5)
838 ADD R4,R4,R4,LSL #2 ;Multiply R3 by 5 (*25)
839 MOV R4,R4,LSL #4 ;Multiply R3 by 16 (*400)
840
841 ; --- Paint the actual text then ---
842
843 ADD R1,R6,#56 ;Point to the text string
844 LDR R2,[R6,#24] ;Load the special magic flags
845 MOV R2,R2,LSL #9 ;Shift flags into position
846 ORR R2,R2,#&40 ;Specify transform matrix
847 STMFD R13!,{R0} ;Save the font handle
848 SWI XFont_Paint ;Paint the text on the screen
849 LDMFD R13!,{R0} ;Restore the font handle
850
851 ; --- Tidy everything up then ---
852
853 SWI Font_LoseFont ;Lose the font handle now
854 90 B draw__next ;Find next draw object
855
856 LTORG
857
858 ; --- draw__renderTransformedSprite ----
859
860 draw__renderTransformedSprite ROUT
861
862 ; --- Make sure I have to render it ---
863
864 STMFD R13!,{R14} ;Save the link temporarily
865 BL draw__clip ;Do we have to render it?
866 BLCS rov_version ;Get the current OS version
867 CMPCS R0,#300 ;Is it RISC OS 3 yet?
868 LDMCCFD R13!,{R14} ;Restore the link again
869 BCC draw__next ;No -- then return
870
871 ; --- Get a colour translation table for it ---
872
873 ADD R0,R7,#48 ;Point to the sprite def
874 MOV R1,R11 ;Put table in scratchpad
875 BL sprite_getTable ;Find a translation table
876
877 ; --- Build the transformation matrix ---
878
879 ADD R14,R7,#24 ;Find the transform matrix
880 LDMIA R14,{R0-R5} ;Load all the bits I need
881 LDR R6,[R10,#0] ;Load the scale factor
882 MOV R6,R6,LSR #8 ;Shift scale factor down
883 MOV R0,R0,ASR #8 ;Also shift down sprite scale
884 MOV R1,R1,ASR #8 ;Also shift down sprite scale
885 MOV R2,R2,ASR #8 ;Also shift down sprite scale
886 MOV R3,R3,ASR #8 ;Also shift down sprite scale
887 MUL R0,R6,R0 ;Apply scale to sprite matrix
888 MUL R1,R6,R1 ;Apply scale to sprite matrix
889 MUL R2,R6,R2 ;Apply scale to sprite matrix
890 MUL R3,R6,R3 ;Apply scale to sprite matrix
891 SUB R13,R13,#24 ;Make space for matrix
892 STMIA R13,{R0-R3} ;Save transform on stack
893 ADD R14,R10,#16 ;Point to my offsets
894 LDMIA R14,{R0,R1} ;Load the offsets out
895 MUL R4,R6,R4 ;Scale the sprite x offset
896 MUL R5,R6,R5 ;Scale the sprite y offset
897 ADD R4,R0,R4,ASR #8 ;Add on to original offset
898 ADD R5,R1,R5,ASR #8 ;Add on to original offset
899 ADD R14,R13,#16 ;Point to bit of matrix
900 STMIA R14,{R4,R5} ;Save these in the matrix
901
902 ; --- Now plot the sprite in the right place ---
903
904 STMFD R13!,{R7} ;Save R7 -- we need to use it
905 MOV R0,#56 ;Plot sprite scaled, please
906 ADD R0,R0,#512 ;Tell it I have a sprite ptr
907 MOV R1,#&1000 ;A dummy sprite area
908 ADD R2,R7,#48 ;Point to the sprite def
909 MOV R3,#0 ;R6 points to a matrix
910 MOV R4,#0 ;No source rectangle thing
911 MOV R5,#8 ;Plot with mask, please
912 ADD R6,R13,#4 ;Point to my matrix
913 MOV R7,R11 ;Point to my translate table
914 SWI OS_SpriteOp ;Plot the sprite
915 LDMFD R13!,{R7} ;Unstack R7 again
916 ADD R13,R13,#24 ;Recover the matrix block
917 LDMFD R13!,{R14} ;Unstack the link register
918 B draw__next ;And render the next object
919
920 LTORG
921
922 ;----- That's all, folks ----------------------------------------------------
923
924 END