chiark / gitweb /
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