; ; draw.s ; ; Renders DrawFiles (MDW) ; ; © 1994-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Sapphire library. ; ; Sapphire is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2, or (at your option) ; any later version. ; ; Sapphire is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with Sapphire. If not, write to the Free Software Foundation, ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;----- Standard header ------------------------------------------------------ GET libs:header GET libs:swis ;----- External dependencies ------------------------------------------------ GET sapphire:divide GET sapphire:mem GET sapphire:msgs GET sapphire:roVersion GET sapphire:sapphire GET sapphire:screen GET sapphire:sprite ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ; --- Register allocation --- ; ; R12 == pointer to font array ; R10 == pointer to transform matrix ; R9 == pointer to clipping block (in Draw units) ; R8 == pointer to end of objects to render ; R7 == pointer to start of current object ; --- draw_render --- ; ; On entry: R0 == scale to plot drawfile (16.16 form) ; R1 == pointer to a redraw block ; R2 == pointer to drawfile in memory ; R3 == size of drawfile block ; ; On exit: -- ; ; Use: Renders a DrawFile in a window. Objects which aren't ; recognised are not rendered. The objects which are handled ; are as follows: ; ; * Font table objects ; * Text objects (in fonts, or in system font) ; * Draw path objects, filled and unfilled, including ; dotted outlines ; * Group objects ; * Tagged objects ; * Sprite objects, rendered as well as we can make it ; * Transformed text, only on RISC OS 3 ; * Transformed sprite, only on RISC OS 3 EXPORT draw_render draw_render ROUT STMFD R13!,{R0-R12,R14} ;Save a load of registers ; --- Set up the transformation matrix --- LDR R4,[R1,#4] ;Load minimum x coord ADD R14,R1,#16 ;Point to maximum y coord LDMIA R14,{R5-R7} ;Load y coord and scroll pos SUB R4,R4,R6 ;Work out x origin position SUB R5,R5,R7 ;And the y origin position SUB R13,R13,#24 ;Make way for the transform MOV R10,R13 ;Point to it nicely MOV R14,R13 ;Point to it for filling MOV R6,R0 ;Set up x scale from user MOV R7,#0 ;Don't do fancy x transforms MOV R8,#0 ;Don't do fancy y transforms MOV R9,R0 ;And scale y from user STMIA R14!,{R6-R9} ;Save this in the block MOV R6,R4,LSL #8 ;Convert offset to draw units MOV R7,R5,LSL #8 ;And convert y offset too STMIA R14,{R6,R7} ;Save these in the matrix too ; --- Set up the adjusted clipping block too --- SUB R13,R13,#16 ;Make way for a clipping blk ADD R14,R1,#28 ;Point to original block LDMIA R14,{R6-R9} ;Load the clipping coords SUB R6,R6,R4 ;Convert these to window... SUB R7,R7,R5 ;... coordinates for easy... SUB R8,R8,R4 ;... clipping SUB R9,R9,R5 MOV R4,R0 ;Get the scale factor safe ; --- Now we have to divide by the scale factor --- MOV R12,#&18000 ;A useful constant (1 1/2) RSB R0,R12,R6,LSL #16 ;Take minimum x position MOV R1,R4,LSR #8 ;And the scale factor BL divide ;Do the division MOV R6,R0 ;Take the result away nicely RSB R0,R12,R7,LSL #16 ;Take minimum y position MOV R1,R4,LSR #8 ;And the scale factor BL divide ;Do the division MOV R7,R0 ;Take the result away nicely ADD R0,R12,R8,LSL #16 ;Take maximum x position MOV R1,R4,LSR #8 ;And the scale factor ADD R0,R0,R1 ;Make it round upwards BL divide ;Do the division MOV R8,R0 ;Take the result away nicely ADD R0,R12,R9,LSL #16 ;Take maximum y position MOV R1,R4,LSR #8 ;And the scale factor ADD R0,R0,R1 ;Make it round upwards BL divide ;Do the division MOV R9,R0 ;Take the result away nicely STMIA R13,{R6-R9} ;Save the modified values MOV R9,R13 ;Point to the coords block ; --- Set up start and end values --- MOV R7,R2 ;Get start address to render ADD R8,R7,R3 ;And calculate end address MOV R0,R7 ;Point to the drawfile BL draw_checkValid ;Make sure the drawfile's OK BVS %10draw_render ;If not don't draw it ADD R7,R7,#40 ;Point to renderable part ; --- And finally initialise the font array --- SUB R13,R13,#1024 ;The font array is *big* MOV R12,R13 ;Point to it MOV R0,R12 ;Point to font array MOV R1,#1024 ;Get its size MOV R2,#0 ;We're going to fill it BL mem_set ;So make it all zeroes ; --- Do the main rendering and tidy up --- BL draw__doRender ;And do the main job 10draw_render ADD R13,R10,#24 ;Reclaim all the stack BL draw__resetTextSize ;Make the text size sensible LDMFD R13!,{R0-R12,PC}^ ;Return to caller now ; --- draw_checkValid --- ; ; On entry: R0 == pointer to start of drawfile ; ; On exit: May return an error ; ; Use: Checks whether a drawfile is basically sound. This checking ; isn't compulsory, and just checks the initial word and the ; format version number -- nothing very exciting. EXPORT draw_checkValid draw_checkValid ROUT BIC R14,R14,#V_flag ;Assume everything's OK STMFD R13!,{R1,R14} ;Save a register away LDR R14,draw__drawMagic ;Load the magic word out LDR R1,[R0,#0] ;Load the first word out CMP R14,R1 ;Do they match perfectly? BNE %90draw_checkValid ;No -- then return error LDR R14,[R0,#4] ;Load major format version CMP R14,#201 ;Is it old enough for me? LDMLEFD R13!,{R1,PC}^ ;Return to caller if OK ; --- Version number is wrong --- ADR R0,draw__tooNew ;Point to the error message B %95draw_checkValid ;And handle the error draw__drawMagic DCB "Draw" draw__tooNew DCD 1 DCB "drawTOONEW",0 ; --- It isn't a drawfile --- 90 ADR R0,draw__badFile ;Point to the error message 95 BL msgs_error ;Translate the error LDMFD R13!,{R1,R14} ;Unstack some registers ORRS PC,R14,#V_flag ;And return the error draw__badFile DCD 1 DCB "drawBADFILE",0 LTORG ; --- draw__doRender --- ; ; On entry: R7 == pointer to object to start rendering ; R8 == pointer to first object not to render ; R9 == pointer to coordinate clipping block ; R10 == pointer to transformation matrix ; R12 == pointer to font array ; ; On exit: R7 points past last object rendered ; R0-R6 may be corrupted ; ; Use: Renders a group of objects. draw__doRender ROUT STMFD R13!,{R14} ;Save a register 00 CMP R7,R8 ;Is there anything to do? BLLT draw__renderObject ;Yes -- render an object BLT %00draw__doRender ;And go round again LDMFD R13!,{PC}^ ;Return to caller LTORG ; --- draw__renderObject --- ; ; On entry: R7 == pointer to object to render ; R8 == pointer to first object not to render ; R9 == pointer to coordinate clipping block ; R10 == pointer to transformation matrix ; R12 == pointer to font array ; ; On exit: R7 == pointer to next object to render ; R0-R6 may be corrupted ; ; Use: The main object rendering dispatch routine. draw__renderObject ROUT LDR R0,[R7,#0] ;Get the object's type CMP R0,#(%10-%00)/4 ;Is it in range of my table? ADDLO PC,PC,R0,LSL #2 ;Yes -- dispatch it then B %10draw__renderObject ;Out of range -- ignore it 00 B draw__readFontTable ;Font table object B draw__renderText ;Render a text string B draw__renderPath ;Render a standard draw path B %10draw__renderObject ;Type 3 is not defined B %10draw__renderObject ;Type 4 is not defined B draw__renderSprite ;Render a sprite B draw__renderGroup ;Handle a group of objects B draw__renderTagged ;Render a tagged object B %10draw__renderObject ;Type 8 is not defined B %10draw__renderObject ;Text area is too difficult B %10draw__renderObject ;Text column is too difficult B %10draw__renderObject ;Options are not renderable B draw__renderTransformedText ;Render rotated text B draw__renderTransformedSprite ;Render rotated sprite 10 B draw__next ;Ignore unknown objects LTORG ; --- draw__next --- ; ; On entry: R7 == pointer to a draw object ; ; On exit: R7 == pointer to next draw object ; R0 corrupted ; ; Use: Moves the current pointer on to the next object draw__next ROUT LDR R0,[R7,#4] ;Load the object size ADD R7,R7,R0 ;Advance the object pointer MOVS PC,R14 ;Return to caller LTORG ; --- draw__clip --- ; ; On entry: R7 == pointer to a draw object ; R9 == pointer to current clipping rectangle ; ; On exit: R0-R6 corrupted ; CS if the object appears within the clipping rectangle, ; CC if it doesn't ; ; Use: Determines if a draw object needs rendering in the current ; redraw job. draw__clip STMFD R13!,{R7} ;Save a register ADD R7,R7,#8 ;Point to the bounding box LDMIA R7,{R4-R7} ;Load the box from it LDMIA R9,{R0-R3} ;And load the clipping box CMP R0,R6 ;Make sure the rectangles... CMPLE R1,R7 ;... overlap CMPLE R4,R2 CMPLE R5,R3 LDMFD R13!,{R7} ;Restore the R7 I saved ORRLES PC,R14,#C_flag ;If it is within, set C BICGTS PC,R14,#C_flag ;Otherwise clear C on exit LTORG ; --- draw__setTextSize --- ; ; On entry: R0 == x size in pixels ; R1 == y size in pixels ; ; On exit: -- ; ; Use: Sets the VDU 5 text size. draw__setTextSize ROUT STMFD R13!,{R0-R2,R14} ;Save a load of registers MOV R1,R1,LSL #16 ;Shift up the y sizes ORR R1,R1,R0 ;Add in the x sizes MOV R0,#23 ;Build initial VDU sequence ORR R0,R0,#17<<8 ;Add in more chars ORR R0,R0,#7<<16 ORR R0,R0,#2<<24 MOV R2,#0 ;Wrap up the sequence nicely STMFD R13!,{R0-R2} ;Save it on the stack MOV R0,R13 ;Point to the sequence MOV R1,#10 ;Get the sequence size in R1 SWI OS_WriteN ;Write it to the VDU stream MOV R14,#4 ;Now set the spacing up STRB R14,[R13,#3] ;Save it in the stream MOV R0,R13 ;Point to the sequence MOV R1,#10 ;Get the sequence size in R1 SWI OS_WriteN ;Write it to the VDU stream ADD R13,R13,#12 ;Restore the stack pointer LDMFD R13!,{R0-R2,PC}^ ;Return to caller LTORG ; --- draw__resetTextSize --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Makes the text size nice again after doing all sorts of ; horrid things to it for the sake of plotting text in the ; system font. draw__resetTextSize ROUT STMFD R13!,{R0,R1,R14} ;Save some registers BL screen_getInfo ;Read the screen information LDMIA R0,{R0,R1} ;Load the eigen factors MOV R14,#16 ;Normal width 16 OS units MOV R0,R14,LSR R0 ;Scale it into pixels MOV R14,#32 ;Normal height 32 OS units MOV R1,R14,LSR R1 ;Scale it into pixels BL draw__setTextSize ;Set the pixel size nicely LDMFD R13!,{R0,R1,PC}^ ;And return to caller LTORG ;----- Object handlers ------------------------------------------------------ ; ; All of these have the same entry and exit conditions as draw__renderObject. ; --- draw__readFontTable --- draw__readFontTable ROUT LDR R1,[R7,#4] ;Find the object size ADD R1,R7,R1 ;Convert to object end ADD R0,R7,#8 ;Find start of font data ; --- Read an entry from the table --- 00 CMP R0,R1 ;Have we finished yet? BGE draw__next ;Yes -- return to caller LDRB R2,[R0],#1 ;Get the internal font handle CMP R2,#0 ;Is this a null one? BEQ draw__next ;Yes -- that's it then STR R0,[R12,R2,LSL #2] ;Save the name pointer away 10 LDRB R2,[R0],#1 ;Get a font name character CMP R2,#0 ;Is this the end of the name? BNE %10draw__readFontTable ;No -- go round again then B %00draw__readFontTable ;Read the next font name LTORG ; --- draw__renderText --- draw__renderText ROUT STMFD R13!,{R14} ;Save the link temporarily BL draw__clip ;Do we have to render it? LDMFD R13!,{R14} ;Restore the link again BCC draw__next ;No -- then return ; --- Make sure the text isn't invisible --- ADD R6,R7,#24 ;Point to the object data LDR R0,[R6,#0] ;Load the foreground colour CMP R0,#-1 ;Is it transparent? MOVEQS PC,R14 ;Yes -- do nothing then ; --- Find the font name --- LDR R5,[R6,#8] ;Load internal font handle CMP R5,#0 ;Is the handle 0? BEQ draw__renderSystemText ;Yes -- use the system font LDR R5,[R12,R5,LSL #2] ;Load the font name pointer CMP R5,#0 ;Is it defined? BEQ draw__renderSystemText ;No -- use the system font ; --- Work out the text size I need --- STMFD R13!,{R14} ;Save the link again ADD R2,R6,#12 ;Point to the text sizes LDMIA R2,{R2,R3} ;Load x and y sizes LDR R4,[R10,#0] ;Load the scale factor MOV R4,R4,LSR #8 ;Scale it down a little MUL R2,R4,R2 ;Scale up the x size MUL R3,R4,R3 ;And scale up the y size MOV R4,#5 ;So div10 rounds to nearest ADD R2,R4,R2,LSR #10 ;Scale values down further ADD R3,R4,R3,LSR #10 ;Both the x and the y MOV R0,R2 ;Get the x size BL div10 ;Convert to points MOV R2,R0 ;Move back into position MOV R0,R3 ;Get the y size BL div10 ;Convert to points MOV R3,R0 ;Move back into position LDMFD R13!,{R14} ;Restore the link again ; --- Get a font handle --- MOV R1,R5 ;Get the font name pointer MOV R4,#0 ;Default scaling, please MOV R5,#0 ;On x and y axes SWI XFont_FindFont ;Try to get a font handle BVS draw__renderSystemText ;Couldn't -- use system font ; --- Set the right colours --- LDR R1,[R6,#4] ;Load the background colour LDR R2,[R6,#0] ;Load the foreground colour MOV R3,#14 ;Antialias lots and lots SWI ColourTrans_SetFontColours ; --- Work out where to paint the text --- ADD R3,R6,#20 ;Point to the coordinates LDMIA R3,{R3,R4} ;Load the coordinates out LDR R5,[R10,#0] ;Load the scale factor out MOV R5,R5,LSR #8 ;Scale it down a little MUL R3,R5,R3 ;Multiply up the x position MUL R4,R5,R4 ;Multiply up the y position MOV R3,R3,ASR #16 ;Scale down the x position MOV R4,R4,ASR #16 ;Scale down the y position ADD R1,R10,#16 ;Point to the plot offset LDMIA R1,{R1,R2} ;Load the offsets out ADD R3,R3,R1,ASR #8 ;Add it on (convert to OS) ADD R4,R4,R2,ASR #8 ;Convert the y coordinate too ; --- Paint the actual text then --- ADD R1,R6,#28 ;Point to the text string MOV R2,#&10 ;Coordinates are in OS units SWI Font_Paint ;Paint the text on the screen ; --- Tidy everything up then --- SWI Font_LoseFont ;Lose the font handle now B draw__next ;Find next draw object LTORG ; --- draw__renderSystemText --- ; ; Notes: This routine is entered with R6 set up as pointer to the ; specific object data, and havng made sure that the text ; actually does have to be rendered. draw__renderSystemText ROUT ; --- Set up the plotting colour --- STMFD R13!,{R14} ;Save the link register LDR R0,[R6,#0] ;Load the foreground colour MOV R3,#0 ;Don't bother dithering it MOV R4,#0 ;And set normal GCOL action SWI ColourTrans_SetGCOL ;Set up the colour ; --- Set up the text size --- BL screen_getInfo ;Get things about the screen LDMIA R0,{R2,R3} ;Load the eigen factors ADD R14,R6,#12 ;Point to the size arguments LDMIA R14,{R0,R1} ;Load the text sizes out LDR R4,[R10,#0] ;Load the scale factor MOV R4,R4,LSR #8 ;Shift it down a little MUL R0,R4,R0 ;Multiply x size up MUL R1,R4,R1 ;Multiply y size up too MOV R0,R0,LSR #16 ;Scale x size down more MOV R0,R0,LSR R2 ;And divide by pixel size MOV R1,R1,LSR #16 ;Scale y size down more MOV R1,R1,LSR R3 ;And divide by pixel size BL draw__setTextSize ;Set the VDU 5 text size MOV R3,R1,LSL R3 ;Multply y size up a bit ; --- Move to the right place --- ADD R14,R6,#20 ;Point to the position data LDMIA R14,{R1,R2} ;Load the text positions MUL R1,R4,R1 ;Scale up the x position MUL R2,R4,R2 ;Scale up the y position MOV R1,R1,ASR #16 ;Scale down the x pos MOV R2,R2,ASR #16 ;Scale down the y pos SUB R3,R3,R3,LSR #3 ;Find 7/8 of character height ADD R2,R2,R3 ;Find top of text line ADD R14,R10,#16 ;Find render offsets nicely LDMIA R14,{R3,R4} ;Load the offsets out ADD R1,R1,R3,ASR #8 ;Add them and convert to OS ADD R2,R2,R4,ASR #8 ;Both the x and the y please MOV R0,#4 ;Move cursor absolute SWI OS_Plot ;Move graphics cursor nicely ; --- Plot the text and go home --- ADD R0,R6,#28 ;Point to the text string SWI OS_Write0 ;Plot it on the screen LDMFD R13!,{R14} ;Unstack the link register B draw__next ;And move to the next object LTORG ; --- draw__renderPath --- draw__renderPath ROUT STMFD R13!,{R14} ;Save the link temporarily BL draw__clip ;Do we have to render it? LDMCCFD R13!,{R14} ;Restore the link again BCC draw__next ;No -- then return LDR R6,[R7,#36] ;Load the path style word TST R6,#&80 ;Is there a dot-dash pattern? ADDEQ R5,R7,#40 ;No -- find path data then LDRNE R5,[R7,#44] ;Yes -- load dot-dash length ADDNE R5,R7,R5,LSL #2 ;Add this to object start ADDNE R5,R5,#48 ;And add fixed part of dash ; --- Handle the filled in bit --- LDR R0,[R7,#24] ;Load the fill colour CMP R0,#-1 ;Is it transparent? BEQ %50draw__renderPath ;Yes -- just draw outline ; --- Render a filled path --- MOV R3,#&100 ;Try and dither the fill MOV R4,#0 ;Set normal GCOL action SWI ColourTrans_SetGCOL ;Set the colour up MOV R0,#&c80000 ;The basic flatness is 200 LDR R1,[R10,#0] ;Load the scale factor BL div_round ;Divide to get the flatness MOV R3,R0 ;Get flatness in R3 nicely AND R1,R6,#&40 ;Get the path winding rule MOV R1,R1,LSR #5 ;Shift it down into place ORR R1,R1,#&30 ;And add in other fill bits MOV R0,R5 ;Point to path specification MOV R2,R10 ;Point to transform matrix SWI Draw_Fill ;And render the filled path ; --- Now handle an outline --- 50 LDR R0,[R7,#28] ;Load the outline colour CMP R0,#-1 ;Is it transparent? BEQ %90draw__renderPath ;Yes -- wrap everything up ; --- Render a path outline --- MOV R3,#&100 ;Try and dither the outline MOV R4,#0 ;Set normal GCOL action SWI ColourTrans_SetGCOL ;Set the colour up ; --- Build the cap and join block --- ; ; Note that in fact the end cap and start cap specs are ; reversed. This is a result of Acorn stupidity, bad ; documentation, or both. We sit back and laugh as ; WimpExtension gets it wrong. AND R0,R6,#&03 ;Get the join style style AND R4,R6,#&30 ;Get the start cap style ORR R0,R0,R4,LSL #12 ;Move that into byte 2 AND R4,R6,#&0C ;Get the end cap style ORR R0,R0,R4,LSL #6 ;Move that into byte 1 MOV R1,#&A0000 ;Mitre limit is 10.0 AND R2,R6,#&00FF0000 ;Get triangle cap width MOV R2,R2,LSR #12 ;Move it into position AND R4,R6,#&FF000000 ;Get triangle cap height ORR R2,R2,R4,LSR #4 ;Move that into position MOV R3,R2 ;End triangle == start one STMFD R13!,{R0-R3} ;Save cap and join spec ; --- Finally, plot the path --- MOV R0,#&c80000 ;The basic flatness is 200 LDR R1,[R10,#0] ;Load the scale factor BL div_round ;Divide to get the flatness MOV R3,R0 ;Get flatness in R3 nicely MOV R0,R5 ;Point to the path spec MOV R1,#&38 ;A set fill style, please MOV R2,R10 ;Point to transform matrix LDR R4,[R7,#32] ;Load the line width MOV R5,R13 ;Point to join and cap block TST R6,#&80 ;Is there a dash pattern? MOVEQ R6,#0 ;No -- don't plot one then ADDNE R6,R7,#40 ;Yes -- find the data SWI Draw_Stroke ;Plot the path outline ADD R13,R13,#16 ;Recover used stack space ; --- Wrap it all up nicely --- 90 LDMFD R13!,{R14} ;Restore the link again B draw__next ;Find the next draw object LTORG ; --- draw__renderSprite --- draw__renderSprite ROUT ; --- Make sure I have to render it --- STMFD R13!,{R14} ;Save the link temporarily BL draw__clip ;Do we have to render it? LDMCCFD R13!,{R14} ;Restore the link again BCC draw__next ;No -- then return ; --- Get a colour translation table for it --- ADD R0,R7,#24 ;Point to the sprite def MOV R1,R11 ;Put table in scratchpad BL sprite_getTable ;Find a translation table ; --- Work out the correct scaling --- MOV R0,#40 ;Read sprite info ADD R0,R0,#512 ;Sprite is pointed at MOV R1,#&1000 ;Don't care about sprite area ADD R2,R7,#24 ;Point to sprite block SWI OS_SpriteOp ;Read the sprite info BL screen_getInfo ;Read some screen info LDMIA R0,{R0,R1} ;Load the eigen factors MOV R5,R4,LSL R1 ;Scale the y value into R5 MOV R4,R3,LSL R0 ;Scale the x value into R4 ADD R0,R7,#8 ;Point to sprite bounding box LDMIA R0,{R0-R3} ;Load the values out SUB R2,R2,R0 ;Get sprite width in R2 SUB R3,R3,R1 ;Get sprite height in R3 MOV R2,R2,LSR #8 ;Scale the dimensions down MOV R3,R3,LSR #8 ;In both directions LDR R14,[R10,#0] ;Load the scale factor MUL R2,R14,R2 ;Scale the x size MUL R3,R14,R3 ;And the y size MOV R2,R2,LSR #16 ;And scale the value down MOV R3,R3,LSR #16 ;Both directions again STMFD R13!,{R2-R5} ;Save the resulting zoom blk MOV R14,R14,LSR #8 ;Shift scale factor down MUL R3,R14,R0 ;Scale the x position MUL R4,R14,R1 ;And the y position MOV R3,R3,ASR #16 ;Scale down the resulting pos MOV R4,R4,ASR #16 ;In both directions ADD R0,R10,#16 ;Find the transform offsets LDMIA R0,{R0,R1} ;Load them from the block ADD R3,R3,R0,ASR #8 ;Add the x offset on ADD R4,R4,R1,ASR #8 ;Add the y offset on too ; --- Now plot the sprite in the right place --- STMFD R13!,{R7} ;Save R7 -- we need to use it MOV R0,#52 ;Plot sprite scaled, please ADD R0,R0,#512 ;Tell it I have a sprite ptr MOV R1,#&1000 ;A dummy sprite area ADD R2,R7,#24 ;Point to the sprite def MOV R5,#8 ;Plot with mask, please ADD R6,R13,#4 ;Point to my zoom block MOV R7,R11 ;Point to my translate table SWI OS_SpriteOp ;Plot the sprite LDMFD R13!,{R7} ;Unstack R7 again ADD R13,R13,#16 ;Recover the zoom block LDMFD R13!,{R14} ;Unstack the link register B draw__next ;And render the next object LTORG ; --- draw__renderGroup --- draw__renderGroup ROUT STMFD R13!,{R14} ;Save the link temporarily BL draw__clip ;Do we have to render it? LDMFD R13!,{R14} ;Restore the link again BCC draw__next ;No -- then return ADD R7,R7,#36 ;Render the objects in there MOVS PC,R14 ;I've mangled the object ptr LTORG ; --- draw__renderTagged --- draw__renderTagged ROUT STMFD R13!,{R14} ;Save the link temporarily BL draw__clip ;Do we have to render it? LDMCCFD R13!,{R14} ;Restore the link again BCC draw__next ;No -- then return STMFD R13!,{R7,R8} ;Save the object pointer ADD R7,R7,#28 ;Point to the enclosed object LDR R8,[R7,#4] ;Get the object size ADD R8,R7,R8 ;Point past the object BL draw__doRender ;Render the object LDMFD R13!,{R7,R8,R14} ;Restore registers B draw__next ;And move to the next object LTORG ; --- draw__renderTransformedText --- draw__renderTransformedText ROUT STMFD R13!,{R14} ;Save the link temporarily BL draw__clip ;Do we have to render it? BLCS rov_version ;Get the current OS version CMPCS R0,#300 ;Is it RISC OS 3 yet? LDMFD R13!,{R14} ;Restore the link again BCC draw__next ;No -- then return ; --- Make sure the text isn't invisible --- ADD R6,R7,#24 ;Point to the object data LDR R0,[R6,#0] ;Load the foreground colour CMP R0,#-1 ;Is it transparent? MOVEQS PC,R14 ;Yes -- do nothing then ; --- Find the font name --- LDR R5,[R6,#36] ;Load internal font handle CMP R5,#0 ;Is the handle 0? BEQ %90draw__renderTransformedText LDR R5,[R12,R5,LSL #2] ;Load the font name pointer CMP R5,#0 ;Is it defined? BEQ %90draw__renderTransformedText ; --- Work out the text size I need --- STMFD R13!,{R14} ;Save the link again ADD R2,R6,#40 ;Point to the text sizes LDMIA R2,{R2,R3} ;Load x and y sizes LDR R4,[R10,#0] ;Load the scale factor MOV R4,R4,LSR #8 ;Scale it down a little MUL R2,R4,R2 ;Scale up the x size MUL R3,R4,R3 ;And scale up the y size MOV R4,#5 ;So div10 rounds to nearest ADD R2,R4,R2,LSR #10 ;Scale values down further ADD R3,R4,R3,LSR #10 ;Both the x and the y MOV R0,R2 ;Get the x size BL div10 ;Convert to points MOV R2,R0 ;Move back into position MOV R0,R3 ;Get the y size BL div10 ;Convert to points MOV R3,R0 ;Move back into position LDMFD R13!,{R14} ;Restore the link again ; --- Get a font handle --- MOV R1,R5 ;Get the font name pointer MOV R4,#0 ;Default scaling, please MOV R5,#0 ;On x and y axes SWI XFont_FindFont ;Try to get a font handle BVS %90draw__renderTransformedText ; --- Set the right colours --- LDR R1,[R6,#32] ;Load the background colour LDR R2,[R6,#28] ;Load the foreground colour MOV R3,#14 ;Antialias lots and lots SWI ColourTrans_SetFontColours ; --- Work out where to paint the text --- ADD R3,R6,#48 ;Point to the coordinates LDMIA R3,{R3,R4} ;Load the coordinates out LDR R5,[R10,#0] ;Load the scale factor out MOV R5,R5,LSR #8 ;Scale it down a little MUL R3,R5,R3 ;Multiply up the x position MUL R4,R5,R4 ;Multiply up the y position MOV R3,R3,ASR #16 ;Scale down the x position MOV R4,R4,ASR #16 ;Scale down the y position ADD R1,R10,#16 ;Point to the plot offset LDMIA R1,{R1,R2} ;Load the offsets out ADD R3,R3,R1,ASR #8 ;Add it on (convert to OS) ADD R4,R4,R2,ASR #8 ;Convert the y coordinate too ; --- Scale position to millipoints --- ; ; Multiply by 500 (very quickly) ADD R3,R3,R3,LSL #2 ;Multiply R3 by 5 (*5) ADD R3,R3,R3,LSL #2 ;Multiply R3 by 5 (*25) MOV R3,R3,LSL #4 ;Multiply R3 by 16 (*400) ADD R4,R4,R4,LSL #2 ;Multiply R3 by 5 (*5) ADD R4,R4,R4,LSL #2 ;Multiply R3 by 5 (*25) MOV R4,R4,LSL #4 ;Multiply R3 by 16 (*400) ; --- Paint the actual text then --- ADD R1,R6,#56 ;Point to the text string LDR R2,[R6,#24] ;Load the special magic flags MOV R2,R2,LSL #9 ;Shift flags into position ORR R2,R2,#&40 ;Specify transform matrix STMFD R13!,{R0} ;Save the font handle SWI XFont_Paint ;Paint the text on the screen LDMFD R13!,{R0} ;Restore the font handle ; --- Tidy everything up then --- SWI Font_LoseFont ;Lose the font handle now 90 B draw__next ;Find next draw object LTORG ; --- draw__renderTransformedSprite ---- draw__renderTransformedSprite ROUT ; --- Make sure I have to render it --- STMFD R13!,{R14} ;Save the link temporarily BL draw__clip ;Do we have to render it? BLCS rov_version ;Get the current OS version CMPCS R0,#300 ;Is it RISC OS 3 yet? LDMCCFD R13!,{R14} ;Restore the link again BCC draw__next ;No -- then return ; --- Get a colour translation table for it --- ADD R0,R7,#48 ;Point to the sprite def MOV R1,R11 ;Put table in scratchpad BL sprite_getTable ;Find a translation table ; --- Build the transformation matrix --- ADD R14,R7,#24 ;Find the transform matrix LDMIA R14,{R0-R5} ;Load all the bits I need LDR R6,[R10,#0] ;Load the scale factor MOV R6,R6,LSR #8 ;Shift scale factor down MOV R0,R0,ASR #8 ;Also shift down sprite scale MOV R1,R1,ASR #8 ;Also shift down sprite scale MOV R2,R2,ASR #8 ;Also shift down sprite scale MOV R3,R3,ASR #8 ;Also shift down sprite scale MUL R0,R6,R0 ;Apply scale to sprite matrix MUL R1,R6,R1 ;Apply scale to sprite matrix MUL R2,R6,R2 ;Apply scale to sprite matrix MUL R3,R6,R3 ;Apply scale to sprite matrix SUB R13,R13,#24 ;Make space for matrix STMIA R13,{R0-R3} ;Save transform on stack ADD R14,R10,#16 ;Point to my offsets LDMIA R14,{R0,R1} ;Load the offsets out MUL R4,R6,R4 ;Scale the sprite x offset MUL R5,R6,R5 ;Scale the sprite y offset ADD R4,R0,R4,ASR #8 ;Add on to original offset ADD R5,R1,R5,ASR #8 ;Add on to original offset ADD R14,R13,#16 ;Point to bit of matrix STMIA R14,{R4,R5} ;Save these in the matrix ; --- Now plot the sprite in the right place --- STMFD R13!,{R7} ;Save R7 -- we need to use it MOV R0,#56 ;Plot sprite scaled, please ADD R0,R0,#512 ;Tell it I have a sprite ptr MOV R1,#&1000 ;A dummy sprite area ADD R2,R7,#48 ;Point to the sprite def MOV R3,#0 ;R6 points to a matrix MOV R4,#0 ;No source rectangle thing MOV R5,#8 ;Plot with mask, please ADD R6,R13,#4 ;Point to my matrix MOV R7,R11 ;Point to my translate table SWI OS_SpriteOp ;Plot the sprite LDMFD R13!,{R7} ;Unstack R7 again ADD R13,R13,#24 ;Recover the matrix block LDMFD R13!,{R14} ;Unstack the link register B draw__next ;And render the next object LTORG ;----- That's all, folks ---------------------------------------------------- END