JPEG support and other fixes from Nick Clark
[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 B %10draw__renderObject ;Type 14 is not defined
269 B %10draw__renderObject ;Type 15 is not defined
270 B draw__renderJPEG ;Render a JPEG
271
272 10 B draw__next ;Ignore unknown objects
273
274 LTORG
275
276 ; --- draw__next ---
277 ;
278 ; On entry: R7 == pointer to a draw object
279 ;
280 ; On exit: R7 == pointer to next draw object
281 ; R0 corrupted
282 ;
283 ; Use: Moves the current pointer on to the next object
284
285 draw__next ROUT
286
287 LDR R0,[R7,#4] ;Load the object size
288 ADD R7,R7,R0 ;Advance the object pointer
289 MOVS PC,R14 ;Return to caller
290
291 LTORG
292
293 ; --- draw__clip ---
294 ;
295 ; On entry: R7 == pointer to a draw object
296 ; R9 == pointer to current clipping rectangle
297 ;
298 ; On exit: R0-R6 corrupted
299 ; CS if the object appears within the clipping rectangle,
300 ; CC if it doesn't
301 ;
302 ; Use: Determines if a draw object needs rendering in the current
303 ; redraw job.
304
305 draw__clip STMFD R13!,{R7} ;Save a register
306 ADD R7,R7,#8 ;Point to the bounding box
307 LDMIA R7,{R4-R7} ;Load the box from it
308 LDMIA R9,{R0-R3} ;And load the clipping box
309 CMP R0,R6 ;Make sure the rectangles...
310 CMPLE R1,R7 ;... overlap
311 CMPLE R4,R2
312 CMPLE R5,R3
313 LDMFD R13!,{R7} ;Restore the R7 I saved
314 ORRLES PC,R14,#C_flag ;If it is within, set C
315 BICGTS PC,R14,#C_flag ;Otherwise clear C on exit
316
317 LTORG
318
319 ; --- draw__setTextSize ---
320 ;
321 ; On entry: R0 == x size in pixels
322 ; R1 == y size in pixels
323 ;
324 ; On exit: --
325 ;
326 ; Use: Sets the VDU 5 text size.
327
328 draw__setTextSize ROUT
329
330 STMFD R13!,{R0-R2,R14} ;Save a load of registers
331 MOV R1,R1,LSL #16 ;Shift up the y sizes
332 ORR R1,R1,R0 ;Add in the x sizes
333 MOV R0,#23 ;Build initial VDU sequence
334 ORR R0,R0,#17<<8 ;Add in more chars
335 ORR R0,R0,#7<<16
336 ORR R0,R0,#2<<24
337 MOV R2,#0 ;Wrap up the sequence nicely
338 STMFD R13!,{R0-R2} ;Save it on the stack
339 MOV R0,R13 ;Point to the sequence
340 MOV R1,#10 ;Get the sequence size in R1
341 SWI OS_WriteN ;Write it to the VDU stream
342 MOV R14,#4 ;Now set the spacing up
343 STRB R14,[R13,#3] ;Save it in the stream
344 MOV R0,R13 ;Point to the sequence
345 MOV R1,#10 ;Get the sequence size in R1
346 SWI OS_WriteN ;Write it to the VDU stream
347 ADD R13,R13,#12 ;Restore the stack pointer
348 LDMFD R13!,{R0-R2,PC}^ ;Return to caller
349
350 LTORG
351
352 ; --- draw__resetTextSize ---
353 ;
354 ; On entry: --
355 ;
356 ; On exit: --
357 ;
358 ; Use: Makes the text size nice again after doing all sorts of
359 ; horrid things to it for the sake of plotting text in the
360 ; system font.
361
362 draw__resetTextSize ROUT
363
364 STMFD R13!,{R0,R1,R14} ;Save some registers
365 BL screen_getInfo ;Read the screen information
366 LDMIA R0,{R0,R1} ;Load the eigen factors
367 MOV R14,#16 ;Normal width 16 OS units
368 MOV R0,R14,LSR R0 ;Scale it into pixels
369 MOV R14,#32 ;Normal height 32 OS units
370 MOV R1,R14,LSR R1 ;Scale it into pixels
371 BL draw__setTextSize ;Set the pixel size nicely
372 LDMFD R13!,{R0,R1,PC}^ ;And return to caller
373
374 LTORG
375
376 ;----- Object handlers ------------------------------------------------------
377 ;
378 ; All of these have the same entry and exit conditions as draw__renderObject.
379
380 ; --- draw__readFontTable ---
381
382 draw__readFontTable ROUT
383
384 LDR R1,[R7,#4] ;Find the object size
385 ADD R1,R7,R1 ;Convert to object end
386 ADD R0,R7,#8 ;Find start of font data
387
388 ; --- Read an entry from the table ---
389
390 00 CMP R0,R1 ;Have we finished yet?
391 BGE draw__next ;Yes -- return to caller
392 LDRB R2,[R0],#1 ;Get the internal font handle
393 CMP R2,#0 ;Is this a null one?
394 BEQ draw__next ;Yes -- that's it then
395
396 STR R0,[R12,R2,LSL #2] ;Save the name pointer away
397 10 LDRB R2,[R0],#1 ;Get a font name character
398 CMP R2,#0 ;Is this the end of the name?
399 BNE %10draw__readFontTable ;No -- go round again then
400
401 B %00draw__readFontTable ;Read the next font name
402
403 LTORG
404
405 ; --- draw__renderText ---
406
407 draw__renderText ROUT
408
409 STMFD R13!,{R14} ;Save the link temporarily
410 BL draw__clip ;Do we have to render it?
411 LDMFD R13!,{R14} ;Restore the link again
412 BCC draw__next ;No -- then return
413
414 ; --- Make sure the text isn't invisible ---
415
416 LDR R0,[R7,#24] ;Load the foreground colour
417 CMP R0,#-1 ;Is it transparent?
418 MOVEQS PC,R14 ;Yes -- do nothing then
419 ADD R6,R7,#24 ;Point to the object data
420
421 ; --- Find the font name ---
422
423 LDR R5,[R6,#8] ;Load internal font handle
424 CMP R5,#0 ;Is the handle 0?
425 BEQ draw__renderSystemText ;Yes -- use the system font
426 LDR R5,[R12,R5,LSL #2] ;Load the font name pointer
427 CMP R5,#0 ;Is it defined?
428 BEQ draw__renderSystemText ;No -- use the system font
429
430 ; --- Work out the text size I need ---
431
432 STMFD R13!,{R14} ;Save the link again
433 ADD R2,R6,#12 ;Point to the text sizes
434 LDR R4,[R10,#0] ;Load the scale factor
435 LDMIA R2,{R2,R3} ;Load x and y sizes
436 MOV R4,R4,LSR #8 ;Scale it down a little
437 MUL R2,R4,R2 ;Scale up the x size
438 MUL R3,R4,R3 ;And scale up the y size
439 MOV R4,#5 ;So div10 rounds to nearest
440 ADD R2,R4,R2,LSR #10 ;Scale values down further
441 ADD R3,R4,R3,LSR #10 ;Both the x and the y
442 MOV R0,R2 ;Get the x size
443 BL div10 ;Convert to points
444 MOV R2,R0 ;Move back into position
445 MOV R0,R3 ;Get the y size
446 BL div10 ;Convert to points
447 MOV R3,R0 ;Move back into position
448 LDMFD R13!,{R14} ;Restore the link again
449
450 ; --- Get a font handle ---
451
452 MOV R1,R5 ;Get the font name pointer
453 MOV R4,#0 ;Default scaling, please
454 MOV R5,#0 ;On x and y axes
455 SWI XFont_FindFont ;Try to get a font handle
456 BVS draw__renderSystemText ;Couldn't -- use system font
457
458 ; --- Set the right colours ---
459
460 LDR R1,[R6,#4] ;Load the background colour
461 LDR R2,[R6,#0] ;Load the foreground colour
462 MOV R3,#14 ;Antialias lots and lots
463 SWI ColourTrans_SetFontColours
464
465 ; --- Work out where to paint the text ---
466
467 ADD R3,R6,#20 ;Point to the coordinates
468 LDR R5,[R10,#0] ;Load the scale factor out
469 LDMIA R3,{R3,R4} ;Load the coordinates out
470 MOV R5,R5,LSR #8 ;Scale it down a little
471 MUL R3,R5,R3 ;Multiply up the x position
472 MUL R4,R5,R4 ;Multiply up the y position
473 MOV R3,R3,ASR #16 ;Scale down the x position
474 MOV R4,R4,ASR #16 ;Scale down the y position
475 ADD R1,R10,#16 ;Point to the plot offset
476 LDMIA R1,{R1,R2} ;Load the offsets out
477 ADD R3,R3,R1,ASR #8 ;Add it on (convert to OS)
478 ADD R4,R4,R2,ASR #8 ;Convert the y coordinate too
479
480 ; --- Paint the actual text then ---
481
482 ADD R1,R6,#28 ;Point to the text string
483 MOV R2,#&10 ;Coordinates are in OS units
484 SWI Font_Paint ;Paint the text on the screen
485
486 ; --- Tidy everything up then ---
487
488 SWI Font_LoseFont ;Lose the font handle now
489 B draw__next ;Find next draw object
490
491 LTORG
492
493 ; --- draw__renderSystemText ---
494 ;
495 ; Notes: This routine is entered with R6 set up as pointer to the
496 ; specific object data, and havng made sure that the text
497 ; actually does have to be rendered.
498
499 draw__renderSystemText ROUT
500
501 ; --- Set up the plotting colour ---
502
503 STMFD R13!,{R14} ;Save the link register
504 LDR R0,[R6,#0] ;Load the foreground colour
505 MOV R3,#0 ;Don't bother dithering it
506 MOV R4,#0 ;And set normal GCOL action
507 SWI ColourTrans_SetGCOL ;Set up the colour
508
509 ; --- Set up the text size ---
510
511 BL screen_getInfo ;Get things about the screen
512 LDMIA R0,{R2,R3} ;Load the eigen factors
513 ADD R14,R6,#12 ;Point to the size arguments
514 LDR R4,[R10,#0] ;Load the scale factor
515 LDMIA R14,{R0,R1} ;Load the text sizes out
516 MOV R4,R4,LSR #8 ;Shift it down a little
517 MUL R0,R4,R0 ;Multiply x size up
518 MUL R1,R4,R1 ;Multiply y size up too
519 MOV R0,R0,LSR #16 ;Scale x size down more
520 MOV R0,R0,LSR R2 ;And divide by pixel size
521 MOV R1,R1,LSR #16 ;Scale y size down more
522 MOV R1,R1,LSR R3 ;And divide by pixel size
523 BL draw__setTextSize ;Set the VDU 5 text size
524 MOV R3,R1,LSL R3 ;Multply y size up a bit
525
526 ; --- Move to the right place ---
527
528 ADD R14,R6,#20 ;Point to the position data
529 LDMIA R14,{R1,R2} ;Load the text positions
530 MUL R1,R4,R1 ;Scale up the x position
531 MUL R2,R4,R2 ;Scale up the y position
532 MOV R1,R1,ASR #16 ;Scale down the x pos
533 MOV R2,R2,ASR #16 ;Scale down the y pos
534 SUB R3,R3,R3,LSR #3 ;Find 7/8 of character height
535 ADD R2,R2,R3 ;Find top of text line
536 ADD R14,R10,#16 ;Find render offsets nicely
537 LDMIA R14,{R3,R4} ;Load the offsets out
538 ADD R1,R1,R3,ASR #8 ;Add them and convert to OS
539 ADD R2,R2,R4,ASR #8 ;Both the x and the y please
540 MOV R0,#4 ;Move cursor absolute
541 SWI OS_Plot ;Move graphics cursor nicely
542
543 ; --- Plot the text and go home ---
544
545 ADD R0,R6,#28 ;Point to the text string
546 SWI OS_Write0 ;Plot it on the screen
547 LDMFD R13!,{R14} ;Unstack the link register
548 B draw__next ;And move to the next object
549
550 LTORG
551
552 ; --- draw__renderPath ---
553
554 draw__renderPath ROUT
555
556 STMFD R13!,{R14} ;Save the link temporarily
557 BL draw__clip ;Do we have to render it?
558 LDMCCFD R13!,{R14} ;Restore the link again
559 BCC draw__next ;No -- then return
560
561 LDR R6,[R7,#36] ;Load the path style word
562 TST R6,#&80 ;Is there a dot-dash pattern?
563 ADDEQ R5,R7,#40 ;No -- find path data then
564 LDRNE R5,[R7,#44] ;Yes -- load dot-dash length
565 ADDNE R5,R7,R5,LSL #2 ;Add this to object start
566 ADDNE R5,R5,#48 ;And add fixed part of dash
567
568 ; --- Handle the filled in bit ---
569
570 LDR R0,[R7,#24] ;Load the fill colour
571 CMP R0,#-1 ;Is it transparent?
572 BEQ %50draw__renderPath ;Yes -- just draw outline
573
574 ; --- Render a filled path ---
575
576 MOV R3,#&100 ;Try and dither the fill
577 MOV R4,#0 ;Set normal GCOL action
578 SWI ColourTrans_SetGCOL ;Set the colour up
579
580 MOV R0,#&c80000 ;The basic flatness is 200
581 LDR R1,[R10,#0] ;Load the scale factor
582 BL div_round ;Divide to get the flatness
583 MOV R3,R0 ;Get flatness in R3 nicely
584
585 AND R1,R6,#&40 ;Get the path winding rule
586 MOV R1,R1,LSR #5 ;Shift it down into place
587 ORR R1,R1,#&30 ;And add in other fill bits
588 MOV R0,R5 ;Point to path specification
589 MOV R2,R10 ;Point to transform matrix
590 SWI Draw_Fill ;And render the filled path
591
592 ; --- Now handle an outline ---
593
594 50 LDR R0,[R7,#28] ;Load the outline colour
595 CMP R0,#-1 ;Is it transparent?
596 BEQ %90draw__renderPath ;Yes -- wrap everything up
597
598 ; --- Render a path outline ---
599
600 MOV R3,#&100 ;Try and dither the outline
601 MOV R4,#0 ;Set normal GCOL action
602 SWI ColourTrans_SetGCOL ;Set the colour up
603
604 ; --- Build the cap and join block ---
605 ;
606 ; Note that in fact the end cap and start cap specs are
607 ; reversed. This is a result of Acorn stupidity, bad
608 ; documentation, or both. We sit back and laugh as
609 ; WimpExtension gets it wrong.
610
611 AND R0,R6,#&03 ;Get the join style style
612 AND R4,R6,#&30 ;Get the start cap style
613 ORR R0,R0,R4,LSL #12 ;Move that into byte 2
614 AND R4,R6,#&0C ;Get the end cap style
615 ORR R0,R0,R4,LSL #6 ;Move that into byte 1
616
617 MOV R1,#&A0000 ;Mitre limit is 10.0
618
619 AND R2,R6,#&00FF0000 ;Get triangle cap width
620 MOV R2,R2,LSR #12 ;Move it into position
621 AND R4,R6,#&FF000000 ;Get triangle cap height
622 ORR R2,R2,R4,LSR #4 ;Move that into position
623
624 MOV R3,R2 ;End triangle == start one
625
626 STMFD R13!,{R0-R3} ;Save cap and join spec
627
628 ; --- Finally, plot the path ---
629
630 MOV R0,#&c80000 ;The basic flatness is 200
631 LDR R1,[R10,#0] ;Load the scale factor
632 BL div_round ;Divide to get the flatness
633 MOV R3,R0 ;Get flatness in R3 nicely
634 MOV R0,R5 ;Point to the path spec
635 MOV R1,#&38 ;A set fill style, please
636 MOV R2,R10 ;Point to transform matrix
637 LDR R4,[R7,#32] ;Load the line width
638 MOV R5,R13 ;Point to join and cap block
639 TST R6,#&80 ;Is there a dash pattern?
640 MOVEQ R6,#0 ;No -- don't plot one then
641 ADDNE R6,R7,#40 ;Yes -- find the data
642 SWI Draw_Stroke ;Plot the path outline
643 ADD R13,R13,#16 ;Recover used stack space
644
645 ; --- Wrap it all up nicely ---
646
647 90 LDMFD R13!,{R14} ;Restore the link again
648 B draw__next ;Find the next draw object
649
650 LTORG
651
652 ; --- draw__renderSprite ---
653
654 draw__renderSprite ROUT
655
656 ; --- Make sure I have to render it ---
657
658 STMFD R13!,{R14} ;Save the link temporarily
659 BL draw__clip ;Do we have to render it?
660 LDMCCFD R13!,{R14} ;Restore the link again
661 BCC draw__next ;No -- then return
662
663 ; --- Get a colour translation table for it ---
664
665 ADD R0,R7,#24 ;Point to the sprite def
666 MOV R1,R11 ;Put table in scratchpad
667 BL sprite_getTable ;Find a translation table
668
669 ; --- Work out the correct scaling ---
670
671 MOV R0,#40+512 ;Read sprite info
672 ;Sprite is pointed at
673 MOV R1,#&1000 ;Don't care about sprite area
674 ADD R2,R7,#24 ;Point to sprite block
675 SWI OS_SpriteOp ;Read the sprite info
676 BL screen_getInfo ;Read some screen info
677 LDMIA R0,{R0,R1} ;Load the eigen factors
678 MOV R5,R4,LSL R1 ;Scale the y value into R5
679 MOV R4,R3,LSL R0 ;Scale the x value into R4
680
681 ADD R0,R7,#8 ;Point to sprite bounding box
682 LDMIA R0,{R0-R3} ;Load the values out
683 SUB R2,R2,R0 ;Get sprite width in R2
684 SUB R3,R3,R1 ;Get sprite height in R3
685 LDR R14,[R10,#0] ;Load the scale factor
686 MOV R2,R2,LSR #8 ;Scale the dimensions down
687 MOV R3,R3,LSR #8 ;In both directions
688 MUL R2,R14,R2 ;Scale the x size
689 MUL R3,R14,R3 ;And the y size
690 MOV R2,R2,LSR #16 ;And scale the value down
691 MOV R3,R3,LSR #16 ;Both directions again
692 STMFD R13!,{R2-R5,R7} ;Save the resulting zoom blk
693 ;Save R7 -- we need to use it
694
695 MOV R14,R14,LSR #8 ;Shift scale factor down
696 MUL R3,R14,R0 ;Scale the x position
697 MUL R4,R14,R1 ;And the y position
698 MOV R3,R3,ASR #16 ;Scale down the resulting pos
699 MOV R4,R4,ASR #16 ;In both directions
700 ADD R0,R10,#16 ;Find the transform offsets
701 LDMIA R0,{R0,R1} ;Load them from the block
702 ADD R3,R3,R0,ASR #8 ;Add the x offset on
703 ADD R4,R4,R1,ASR #8 ;Add the y offset on too
704
705 ; --- Now plot the sprite in the right place ---
706
707 MOV R0,#52+512 ;Plot sprite scaled, please
708 MOV R1,#&1000 ;A dummy sprite area
709 ADD R2,R7,#24 ;Point to the sprite def
710 MOV R5,#8 ;Plot with mask, please
711 MOV R6,R13 ;Point to my zoom block
712 MOV R7,R11 ;Point to my translate table
713 SWI OS_SpriteOp ;Plot the sprite
714 ADD R13,R13,#16 ;Recover the zoom block
715 LDMFD R13!,{R7, R14} ;Unstack R7 and link register
716 B draw__next ;And render the next object
717
718 LTORG
719
720 ; --- draw__renderGroup ---
721
722 draw__renderGroup ROUT
723
724 STMFD R13!,{R14} ;Save the link temporarily
725 BL draw__clip ;Do we have to render it?
726 LDMFD R13!,{R14} ;Restore the link again
727 BCC draw__next ;No -- then return
728
729 ADD R7,R7,#36 ;Render the objects in there
730 MOVS PC,R14 ;I've mangled the object ptr
731
732 LTORG
733
734 ; --- draw__renderTagged ---
735
736 draw__renderTagged ROUT
737
738 STMFD R13!,{R14} ;Save the link temporarily
739 BL draw__clip ;Do we have to render it?
740 LDMCCFD R13!,{R14} ;Restore the link again
741 BCC draw__next ;No -- then return
742
743 STMFD R13!,{R7,R8} ;Save the object pointer
744 ;SA optimised, looks crazy:
745 LDR R8,[R7,#32] ;Get the object size
746 ADD R7,R7,#28 ;Point to the enclosed object
747 ADD R8,R7,R8 ;Point past the object
748 BL draw__doRender ;Render the object
749 LDMFD R13!,{R7,R8,R14} ;Restore registers
750 B draw__next ;And move to the next object
751
752 LTORG
753
754 ; --- draw__renderTransformedText ---
755
756 draw__renderTransformedText ROUT
757
758 STMFD R13!,{R14} ;Save the link temporarily
759 BL draw__clip ;Do we have to render it?
760 BLCS rov_version ;Get the current OS version
761 CMPCS R0,#300 ;Is it RISC OS 3 yet?
762 LDMFD R13!,{R14} ;Restore the link again
763 BCC draw__next ;No -- then return
764
765 ; --- Make sure the text isn't invisible ---
766
767 LDR R0,[R7,#24] ;Load the foreground colour
768 CMP R0,#-1 ;Is it transparent?
769 MOVEQS PC,R14 ;Yes -- do nothing then
770 ADD R6,R7,#24 ;Point to the object data
771
772 ; --- Find the font name ---
773
774 LDR R5,[R6,#36] ;Load internal font handle
775 CMP R5,#0 ;Is the handle 0?
776 BEQ %90draw__renderTransformedText
777 LDR R5,[R12,R5,LSL #2] ;Load the font name pointer
778 CMP R5,#0 ;Is it defined?
779 BEQ %90draw__renderTransformedText
780
781 ; --- Work out the text size I need ---
782
783 STMFD R13!,{R14} ;Save the link again
784 ADD R2,R6,#40 ;Point to the text sizes
785 LDR R4,[R10,#0] ;Load the scale factor
786 LDMIA R2,{R2,R3} ;Load x and y sizes
787 MOV R4,R4,LSR #8 ;Scale it down a little
788 MUL R2,R4,R2 ;Scale up the x size
789 MUL R3,R4,R3 ;And scale up the y size
790 MOV R4,#5 ;So div10 rounds to nearest
791 ADD R2,R4,R2,LSR #10 ;Scale values down further
792 ADD R3,R4,R3,LSR #10 ;Both the x and the y
793 MOV R0,R2 ;Get the x size
794 BL div10 ;Convert to points
795 MOV R2,R0 ;Move back into position
796 MOV R0,R3 ;Get the y size
797 BL div10 ;Convert to points
798 MOV R3,R0 ;Move back into position
799 LDMFD R13!,{R14} ;Restore the link again
800
801 ; --- Get a font handle ---
802
803 MOV R1,R5 ;Get the font name pointer
804 MOV R4,#0 ;Default scaling, please
805 MOV R5,#0 ;On x and y axes
806 SWI XFont_FindFont ;Try to get a font handle
807 BVS %90draw__renderTransformedText
808
809 ; --- Set the right colours ---
810
811 LDR R1,[R6,#32] ;Load the background colour
812 LDR R2,[R6,#28] ;Load the foreground colour
813 MOV R3,#14 ;Antialias lots and lots
814 SWI ColourTrans_SetFontColours
815
816 ; --- Work out where to paint the text ---
817
818 ADD R3,R6,#48 ;Point to the coordinates
819 LDR R5,[R10,#0] ;Load the scale factor out
820 LDMIA R3,{R3,R4} ;Load the coordinates out
821 MOV R5,R5,LSR #8 ;Scale it down a little
822 MUL R3,R5,R3 ;Multiply up the x position
823 MUL R4,R5,R4 ;Multiply up the y position
824 MOV R3,R3,ASR #16 ;Scale down the x position
825 MOV R4,R4,ASR #16 ;Scale down the y position
826 ADD R1,R10,#16 ;Point to the plot offset
827 LDMIA R1,{R1,R2} ;Load the offsets out
828 ADD R3,R3,R1,ASR #8 ;Add it on (convert to OS)
829 ADD R4,R4,R2,ASR #8 ;Convert the y coordinate too
830
831 ; --- Scale position to millipoints ---
832 ;
833 ; Multiply by 500 (very quickly)
834
835 ADD R3,R3,R3,LSL #2 ;Multiply R3 by 5 (*5)
836 ADD R3,R3,R3,LSL #2 ;Multiply R3 by 5 (*25)
837 MOV R3,R3,LSL #4 ;Multiply R3 by 16 (*400)
838
839 ADD R4,R4,R4,LSL #2 ;Multiply R3 by 5 (*5)
840 ADD R4,R4,R4,LSL #2 ;Multiply R3 by 5 (*25)
841 MOV R4,R4,LSL #4 ;Multiply R3 by 16 (*400)
842
843 ; --- Paint the actual text then ---
844
845 LDR R2,[R6,#24] ;Load the special magic flags
846 ADD R1,R6,#56 ;Point to the text string
847 MOV R2,R2,LSL #9 ;Shift flags into position
848 ORR R2,R2,#&40 ;Specify transform matrix
849 STMFD R13!,{R0} ;Save the font handle
850 SWI XFont_Paint ;Paint the text on the screen
851 LDMFD R13!,{R0} ;Restore the font handle
852
853 ; --- Tidy everything up then ---
854
855 SWI Font_LoseFont ;Lose the font handle now
856 90 B draw__next ;Find next draw object
857
858 LTORG
859
860 ; --- draw__renderTransformedSprite ----
861
862 draw__renderTransformedSprite ROUT
863
864 ; --- Make sure I have to render it ---
865
866 STMFD R13!,{R14} ;Save the link temporarily
867 BL draw__clip ;Do we have to render it?
868 BLCS rov_version ;Get the current OS version
869 CMPCS R0,#300 ;Is it RISC OS 3 yet?
870 LDMCCFD R13!,{R14} ;Restore the link again
871 BCC draw__next ;No -- then return
872
873 ; --- Get a colour translation table for it ---
874
875 ADD R0,R7,#48 ;Point to the sprite def
876 MOV R1,R11 ;Put table in scratchpad
877 BL sprite_getTable ;Find a translation table
878
879 ; --- Build the transformation matrix ---
880
881 ADD R14,R7,#24 ;Find the transform matrix
882 LDR R6,[R10,#0] ;Load the scale factor
883 LDMIA R14,{R0-R5} ;Load all the bits I need
884 MOV R6,R6,LSR #8 ;Shift scale factor down
885 MOV R0,R0,ASR #8 ;Also shift down sprite scale
886 MOV R1,R1,ASR #8 ;Also shift down sprite scale
887 MOV R2,R2,ASR #8 ;Also shift down sprite scale
888 MOV R3,R3,ASR #8 ;Also shift down sprite scale
889 MUL R0,R6,R0 ;Apply scale to sprite matrix
890 MUL R1,R6,R1 ;Apply scale to sprite matrix
891 MUL R2,R6,R2 ;Apply scale to sprite matrix
892 MUL R3,R6,R3 ;Apply scale to sprite matrix
893 STMFD R13!,{R7} ;Save R7 -- we need to use it
894 SUB R13,R13,#24 ;Make space for matrix
895 STMIA R13,{R0-R3} ;Save transform on stack
896 ADD R14,R10,#16 ;Point to my offsets
897 LDMIA R14,{R0,R1} ;Load the offsets out
898 MUL R4,R6,R4 ;Scale the sprite x offset
899 MUL R5,R6,R5 ;Scale the sprite y offset
900 ADD R4,R0,R4,ASR #8 ;Add on to original offset
901 ADD R5,R1,R5,ASR #8 ;Add on to original offset
902 ADD R14,R13,#16 ;Point to bit of matrix
903 STMIA R14,{R4,R5} ;Save these in the matrix
904
905 ; --- Now plot the sprite in the right place ---
906
907 MOV R0,#512+56 ;Plot sprite scaled, please
908 ;Tell it I have a sprite ptr
909 MOV R1,#&1000 ;A dummy sprite area
910 ADD R2,R7,#48 ;Point to the sprite def
911 MOV R3,#0 ;R6 points to a matrix
912 MOV R4,#0 ;No source rectangle thing
913 MOV R5,#8 ;Plot with mask, please
914 MOV R6,R13 ;Point to my matrix
915 MOV R7,R11 ;Point to my translate table
916 SWI OS_SpriteOp ;Plot the sprite
917 ADD R13,R13,#24 ;Recover the matrix block
918 LDMFD R13!,{R7,R14} ;Unstack R7 and link register
919 B draw__next ;And render the next object
920
921 ; --- draw__renderJPEG ----
922
923 draw__renderJPEG ROUT
924
925 ; --- Make sure I have to render it ---
926
927 STMFD R13!,{R14} ;Save the link temporarily
928 BL draw__clip ;Do we have to render it?
929 BLCS rov_version ;Get the current OS version
930 CMPCS R0,#360 ;Is it RISC OS 3.60 yet?
931 LDMCCFD R13!,{R14} ;Restore the link again
932 BCC draw__next ;No -- then return
933
934 ; --- Build the transformation matrix ---
935
936 ADD R14,R7,#40 ;Find the transform matrix
937 LDR R6,[R10,#0] ;Load the scale factor
938 LDMIA R14,{R0-R5} ;Load all the bits I need
939 MOV R6,R6,LSR #8 ;Shift scale factor down
940 MOV R0,R0,ASR #8 ;Also shift down JPEG scale
941 MOV R1,R1,ASR #8 ;Also shift down JPEG scale
942 MOV R2,R2,ASR #8 ;Also shift down JPEG scale
943 MOV R3,R3,ASR #8 ;Also shift down JPEG scale
944 MUL R0,R6,R0 ;Apply scale to JPEG matrix
945 MUL R1,R6,R1 ;Apply scale to JPEG matrix
946 MUL R2,R6,R2 ;Apply scale to JPEG matrix
947 MUL R3,R6,R3 ;Apply scale to JPEG matrix
948 SUB R13,R13,#24 ;Make space for matrix
949 STMIA R13,{R0-R3} ;Save transform on stack
950 ADD R14,R10,#16 ;Point to my offsets
951 LDMIA R14,{R0,R1} ;Load the offsets out
952 MUL R4,R6,R4 ;Scale the JPEG x offset
953 MUL R5,R6,R5 ;Scale the JPEG y offset
954 ADD R4,R0,R4,ASR #8 ;Add on to original offset
955 ADD R5,R1,R5,ASR #8 ;Add on to original offset
956 ADD R14,R13,#16 ;Point to bit of matrix
957 STMIA R14,{R4,R5} ;Save these in the matrix
958
959 ; --- Now plot the JPEG in the right place ---
960
961 ADD R0,R7,#68 ;Point to the JPEG def
962 MOV R1,#2 ;R2 points to a matrix, dither
963 MOV R2,R13 ;Point to my matrix
964 LDR R3,[R0,#-4] ;Load length of JPEG
965 SWI JPEG_PlotTransformed ;Plot the JPEG
966 ADD R13,R13,#24 ;Recover the matrix block
967 LDMFD R13!,{R14} ;Unstack the link register
968 B draw__next ;And render the next object
969
970 LTORG
971
972 ;----- That's all, folks ----------------------------------------------------
973
974 END