; Copyright 1996 Acorn Computers Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; ; s.Backdrop ; ; Handles backdrop window and sprite. [ defaultbackdrop ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; CheckLCD ; ; If supporting an LCD use a patterned default backdrop which shimmers less ; CheckLCD Push "r0-r3,lr" LDR r0,backdrop_options TST r0,#bd_OptionActive ; do nothing if there is already a backdrop Pull "r0-r3,pc",NE MOV r0,#1 SWI XOS_ReadSysInfo CMP r1,#5 ; check for LCD Pull "r0-r3,pc",NE ADR r2,LCDbackdroptile ; allocate memory for file name (so *Backdrop works) BL strlen MOV r0,#ModHandReason_Claim SWI XOS_Module Pull "r0-r3,pc",VS STR r2,backdrop_path ; copy path name MOV r1,r2 ADR r0,LCDbackdroptile BL Copy_r0r1 MOV r0,#bd_OptionTiled :OR: bd_OptionRecache STR r0,backdrop_options LDR r0,poll_word ORR r0,r0,#PollWordReason_Recache STR r0,poll_word Pull "r0-r3,pc" LCDbackdroptile DCB "Pinboard:LCDTile",0 ALIGN ] ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; MakeCompactModeWord ; ; Formulate a word that expresses bpp, eigen, palette all in one ; ; Out : r0 = compact word ; r2 = sprite mode descriptor MakeCompactModeWord Push "r1, lr" MOV r0, #OsByte_CursorCharacterAndMode SWI XOS_Byte Pull "r1, pc",VS CMP r2, #256 ; Old style mode number limit MOVCC r0, r2 ; Numbered modes are unique Pull "r1, pc",CC SUB sp, sp, #20*4 MOV r1, sp SWI XWimp_ReadPalette MOV r0, #0 ; Checksum MOV r14, #20 ; Index 10 SUBS r14, r14, #1 LDRB r1, [sp, r14, LSL #2] ADD r0, r0, r1 BNE %BT10 ADD sp, sp, #20*4 ; Mix into &Fxybcccc LDRB r14, [r2, #12] ; Pixel depth ORR r0, r0, r14, LSL #16 LDRB r14, YEig ORR r0, r0, r14, LSL #20 LDRB r14, XEig ORR r0, r0, r14, LSL #24 ORR r0, r0, #&F0000000 ; Make sure a 1bpp EX0 EY0 mode can't be mistaken ; for old style mode 0 CLRV Pull "r1, pc" ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; [Int_]ModeChange ; ; The mode has changed, recalculate bounds and tiles ; Int_ModeChange Push "lr" ModeChange Debug bd,"Mode Change" [ truncate_filenames BL read_font_widths ] BL read_mode_variables LDR r0,backdrop_handle STR r0,[r1],#4 ADR r2,bounding_box LDMIA r2,{r2,r3,r4,r5} ADD r4,r4,#100 ADD r5,r5,#100 STMIA r1,{r2,r3,r4,r5} SWI XWimp_SetExtent Pull "PC",VS Debug bd,"Extent set." BL set_icon_bar_height [ useECFforLCD BL setupECF ] ; new extent set, now open the window. ADR r1,dataarea LDR r0,icon_bar_height STR r0 ,[r1,#8] ; Don't cover icon bar MOV r6,#-2 ADD r0,r1,#20 STMIA r0,{r4,r5,r6} SWI XWimp_OpenWindow Pull "PC",VS Debug bd,"Opened window" MOV r0,#-1 ; Current mode MOV r1,#VduExt_XWindLimit SWI XOS_ReadModeVariable MOVVC r3,r2 MOVVC r1,#VduExt_XEigFactor SWIVC XOS_ReadModeVariable MOVVC r3,r3,ASL r2 STRVC r3,Screen_x1 STRVC r2,XEig MOVVC r1,#VduExt_YWindLimit SWIVC XOS_ReadModeVariable MOVVC r3,r2 MOVVC r1,#VduExt_YEigFactor SWIVC XOS_ReadModeVariable MOVVC r3,r3,ASL r2 STRVC r3,Screen_y1 STRVC r2,YEig Pull "PC",VS LDR r0,backdrop_options TST r0,#bd_OptionActive [ defaultbackdrop BNE %FT01 BL CheckLCD ; if no backdrop then check for LCD Pull "PC" 01 ] TSTNE r0,#bd_OptionRecache Pull "PC",EQ TST r0, #bd_OptionJPEG BNE %FT03 02 BL MakeCompactModeWord LDR r14, CachedBackdropMode TEQ r0, r14 DebugIf NE, bd,"BackdropMode changed",r0,r14 LDREQ r0, CachedBackdrop_x1 LDREQ r14, Screen_x1 TEQEQ r0, r14 LDREQ r0, CachedBackdrop_y1 LDREQ r14, Screen_y1 TEQEQ r0, r14 DebugIf NE, bd,"Backdrop mode changed, recacheing sprite" 03 BLNE CacheBackdropSprite Pull "PC" FontChanged [ truncate_filenames BL read_font_widths ] LDR R0,backdrop_handle [ {FALSE} SUB R0,R0,#1 LDR R0,[R0,#168] ; num icons, NUM_ICONS | SUB SP,SP,#128 Push "R0" MOV R1,SP ORR R1,R1,#1 ; don't want icons SWI XWimp_GetWindowInfo LDR R0,[SP,#88] ADD SP,SP,#132 ] MOV R1,#0 STR R0,All_PB_Icons TEQ R0,R1 Pull "PC",EQ fontchanged_loop LDR R0,backdrop_handle SUB SP,SP,#32 Push "R0,R1" MOV R1,SP SWI XWimp_GetIconState BVS fontchanged_end LDR R0,[sp,#24] ; flags ADD R1,sp,#28 ; text TST R0,#if_text BEQ fontchanged_next TST R0,#if_indirected LDRNE R1,[R1] MOV R0,#1 MOVNE R2,#0 MOVEQ R2,#12 SWI XWimp_TextOp ADD R14,sp,#8 LDMIA R14,{R2-R5} SUB R14,R4,R2 CMP R14,R0 ADDLT R4,R2,R0 ; x1 = x0+width LDMIA sp,{R0-R1} ; not ! (!) SWI XWimp_ResizeIcon BVS fontchanged_end fontchanged_next ADD SP,SP,#40 ADD R1,R1,#1 LDR R0,All_PB_Icons TEQ R0,R1 Pull "PC",EQ B fontchanged_loop fontchanged_end ADD SP,SP,#40 CLRV Pull "PC" [ :LNOT: ursulawimp ; No palette utility PaletteChange Debug bd,"Palette change" LDR r0,backdrop_options TST r0,#bd_OptionActive TSTNE r0,#bd_OptionRecache Pull "PC",EQ BL CacheBackdropSprite Pull "PC" ] ;--------------------------------------------------------------- ; CacheBackdropSprite ; ; Cache backdrop sprite for current mode ; ; In : ; [backdrop_path] name of sprite file. ; ; Out: ; Sprite cached for current mode. ; ; This must always be entered when we are the current task ! CacheBackdropSprite ROUT Push "LR" LDR r0,backdrop_path CMP r0,#0 [ technicolour_text BGT %FT01 LDR r0,backdrop_handle MOV r1,#0 MOV r2,#0 MOV r3,#&8000 MOV r4,#&8000 SWI XWimp_ForceRedraw Pull "PC" 01 | Pull "PC",LE ] SWI XHourglass_On BL Int_CacheBackdropSprite BVS %FT01 [ debugspr MOV r0,#&20C MOV r1,#&8000 ADR r2,savedspritepath SWI XOS_SpriteOp B %FT20 savedspritepath DCB "scsi::4.$.tmp.sprites.pbsaved" ALIGN 20 ] SWI XHourglass_Off LDR r0,backdrop_handle MOV r1,#0 MOV r2,#0 MOV r3,#&8000 MOV r4,#&8000 SWI XWimp_ForceRedraw LDRVC r0,backdrop_options ORRVC r0,r0,#bd_OptionActive STRVC r0,backdrop_options Pull "PC",VC 01 Push "r0" ; If failed, free any used memory, SWI XHourglass_Off MOV r0,#0 ; and mark as inactive. MOV r1,#-1 SWI XWimp_SlotSize LDR r0,backdrop_options BIC r0,r0,#bd_OptionActive STR r0,backdrop_options Pull "r0" SETV Pull "PC" Int_CacheBackdropSprite ROUT Push "LR" ; First check that the file still exists and is still a sprite file. MOV r0,#OSFile_ReadWithTypeNoPath LDR r1,backdrop_path SWI XOS_File Pull "PC",VS CMP r0,#1 MOVNE r2,r0 MOVNE r0,#OSFile_MakeError SWINE XOS_File Pull "PC",VS ADD r4,r4,#4 STR r4,file_size ; JPEG backdrop support LDR r14,=&C85 CMP r6,r14 BNE %FT01 BL Int_CacheJPEG Pull "PC" 01 LDR r14,=&FF9 CMP r6,r14 ADRNEL r0,ErrorBlock_Pinboard_NotASprite LDRNE r4,backdrop_path BLNE msgtrans_errorlookup Pull "PC",VS ; It still exists ! ; See how much memory we need to store it ... LDR r0,backdrop_options BIC r0, r0, #bd_OptionJPEG STR r0, backdrop_options TST r0,#bd_OptionScaled ; Scaled ? BEQ %FT01 ; Sprite is scaled, get screen size (r4 = width, r5 = height) MOV r0,#-1 ; Use current mode MOV r1,#VduExt_XWindLimit ; Screen width in pixels SWI XOS_ReadModeVariable ADDVC r4,r2,#1 STRVC r4,scale_x1 MOVVC r1,#VduExt_YWindLimit ; Screen height in pixels SWIVC XOS_ReadModeVariable ADDVC r5,r2,#1 STRVC r5,scale_y1 Pull "PC",VS B %FT10 ; Go allocate memory etc. 01 ; We are not going to scale it so find out how big it will be in the current mode. MOV r0,#open_read :OR: open_nopath :OR: open_mustopen :OR: open_nodir LDR r1,backdrop_path SWI XOS_Find ; Open for reading. Pull "PC",VS MOV r1,r0 MOV r0,#OSGBPB_ReadFromGiven ; Read bytes from file ADR r2,dataarea MOV r3,#?saFirst MOV r4,#saFirst - 4 ; Sprite files are sprite areas with saEnd missing SWI XOS_GBPB BVS %FT05 LDR r0,dataarea SUB r4,r0,#4 Debug bd,"Offset to sprite is ",r4 MOV r0,#OSGBPB_ReadFromGiven ADR r2,dataarea MOV r3,#SpriteCBsize SWI XOS_GBPB ; Read sprite header BVC %FT06 05 Push "r0" ; Preserve original error MOV r0,#0 SWI XOS_Find ADDVS sp,sp,#4 Pull "r0",VC SETV Pull "PC" LTORG 06 MOV r0,#0 SWI XOS_Find ADR r2,dataarea LDR r0,[r2,#spMode] Debug bd,"Sprite mode is ",r0 LDR r5,[r2,#spHeight] ; Get height of sprite ADD r5,r5,#1 Debug bd,"Sprite height is ",r5 LDR r4,[r2,#spWidth] ; Get width in words MOV r4,r4,LSL #5 ; Max width in bits LDR r3,[r2,#spRBit] ; Get last bit used Debug bd,"Last bit = ",r3 ADD r4,r4,r3 ; Adjust width LDR r3,[r2,#spLBit] ; Get first bit used Debug bd,"First bit = ",r3 SUB r4,r4,r3 ; Adjust width ADD r4,r4,#1 ; Real width in bits MOV r1,#VduExt_Log2BPP ; get log2bpp for sprites mode SWI XOS_ReadModeVariable Pull "PC",VS MOV r4,r4,LSR r2 ; width in pixels Debug bd,"Sprite width is ",r4 MOV r1,#VduExt_YEigFactor ; Get YEig for sprite's mode SWI XOS_ReadModeVariable Pull "PC",VS MOV r5,r5, ASL r2 ; Height in OS units in sprites mode MOV r1,#VduExt_XEigFactor ; Get XEig for sprite's mode SWI XOS_ReadModeVariable Pull "PC",VS MOV r4,r4, ASL r2 ; Width in OS units in sprites mode ; Now convert back to pixels for current mode LDR r2, YEig MOVS r5,r5, LSR r2 ; Height in pixels MOVEQ r5,#1 ; Must be minimum of 1 pixel MOV r2,r5, LSL r2 ; Height in OS units in current mode STR r2,scale_y1 Debug bd,"Height in OS units is ",r2 LDR r2, XEig MOVS r4,r4, LSR r2 ; Width in pixels MOVEQ r4,#1 ; Must be minimum of 1 pixel MOV r2,r4, LSL r2 ; Width in OS units in current mode STR r2,scale_x1 Debug bd,"Width in OS units is ",r4 10 MOV r0,#-1 MOV r1,#VduExt_Log2BPP SWI XOS_ReadModeVariable ; Get Log2BPP for current mode MOV r3,r4,ASL r2 ; Width in bits ADD r3,r3,#7 MOV r3,r3,LSR #3 ; Width in bytes ADD r3,r3,#3 BIC r3,r3,#3 ; rounded up to nearest word MUL r2,r3,r5 ; r2 = size in bytes Debug bd,"Destination sprite width = ",r4 Debug bd,"Destination sprite height = ",r5 Debug bd,"Sprite size would be ",r2 ADD r2,r2,#&100 STR r2,slot_size ; Amount for actual sprite. ; Now get size of sprite in file LDR r0,file_size ADD r2,r2,r0 STR r2,tmp_slot_size ; Now get the memory we need. MOV r3,r2 MOV r0,r2 MOV r1,#-1 Debug bd,"Slot size required is ",r0 SWI XWimp_SlotSize MOVVS r0,#0 Debug bd,"actual Slot size is ",r0 CMP r3,r0 BLS got_memory LDR r0,backdrop_handle MOV r1,#0 MOV r2,#0 MOV r3,#&8000 MOV r4,#&8000 SWI XWimp_ForceRedraw ADRL r0,ErrorBlock_Pinboard_NoRoom BL msgtrans_errorlookup ; V set on exit Pull "PC" got_memory Debug bd,"Got memory, loading file" LDR r14,backdrop_options ORR r14,r14,#bd_OptionActive STR r14,backdrop_options ; mark as active to stop memory from being stolen! MOV r0,#OSFile_LoadNoPath LDR r1,backdrop_path MOV r2,#&8000 LDR r3,slot_size ADD r2,r2,r3 ; Address to load file. LDR r14,file_size STR r14,[r2],#4 Push "r2,r4,r5" MOV r3,#0 ; Load at given address SWI XOS_File Pull "r2,r4,r5" [ {FALSE} LDRVS r14,backdrop_options BICVS r14,r14,#bd_OptionActive STRVS r14,backdrop_options ] BVC LoadedOK Push R0 LDR r0,backdrop_handle MOV r1,#0 MOV r2,#0 MOV r3,#&8000 MOV r4,#&8000 SWI XWimp_ForceRedraw Pull R0 SETV Pull "PC" LoadedOK Debug bd,"File loaded." SUB r1,r2,#4 ; Pointer to sprite area LDR r2,[r1,#8] ADD r2,r2,r1 ; Pointer to sprite Push "r1,r2" MOV r1,#&8000 LDR r2,slot_size STR r2,[r1] MOV r2,#&10 STR r2,[r1,#8] LDR r0,=&100 + SpriteReason_ClearSprites SWI XOS_SpriteOp Debug bd,"Sprite area initialised" BLVC MakeCompactModeWord ADDVS sp,sp,#8 Pull "PC",VS MOV r6, r2 ; For SpriteReason_CreateSprite STR r0,CachedBackdropMode Debug bd,"BackdropMode is brought to you by the number ",r0 LDR r0,Screen_x1 LDR r1,Screen_y1 STR r0,CachedBackdrop_x1 STR r1,CachedBackdrop_y1 LDR r0,=&100 + SpriteReason_CreateSprite MOV r1,#&8000 ADRL r2,BackdropSpriteName ; Create new sprite in current mode MOV r3,#0 ; No palette Debug bd,"Xsize Ysize",r4,r5 SWI XOS_SpriteOp ADDVS sp,sp,#8 Pull "PC",VS Debug bd,"Created new sprite X x Y",r4,r5 ; Now plot old sprite into new one: Pull "r1,r2" ; Get old sprite pointer and area MOV r9,r1 MOV r10,r2 LDR R0,[R2,#spImage] LDR LR,[R2,#spTrans] CMP R0,R2 MOVGT R0,LR ; min(spImage,spMask) = offset to sprite data CMP R0,#spPalette ; does the sprite have a palette? BGT %FT01 ; Yup - so decode it properly Push "R2" LDR R0,[R2,#spMode] MOV R1,#VduExt_Log2BPP SWI XOS_ReadModeVariable ; attempt to read the Log2BPP CMP R2,#3 ; 8BPP or greater? Pull "R2",GE BGE %FT01 ADR R1,default_palette LDR R2,=&45555254 ; "TRUE" SWI XWimp_ReadPalette Pull "R2" ; restore R2 after reading the Wimp's palette Pull "PC",VS ; and then restore PC if it errors B %FT10 ; assuming that the sprite does have a palette or is 256 colours ; we now call ColourTrans to perform the conversion into our nicely ; specified buffer. 01 MOV R0,R9 ; R0 -> sprite area to be used MOV R1,R10 ; R1 -> sprite within the sprite area MOV R5,#1:SHL:0 ; R5 = control flag for ColourTrans (bit 0 =1 => R1 -> sprite) ; assuming that R0,R1 contain meaningful values, if R0 >256 then R5 should ; be setup to contain flags for the sprite conversion. ASSERT (colourtrans_end -colourtrans) >=1024 10 MOV R2,#-1 MOV R3,#-1 ; R2,R3 =-1 converting to current mode / palette ADR R4,colourtrans ; R4 -> buffer to fill with PixTrans information ORR R5,R5,#16 ; and ask for a wide table SWI XColourTrans_SelectTable Pull "PC",VS ; return if it errored (V set => R0 -> error block) ADR r6,ScaleFactors MOV r0,#0 STR r0,[r6,#0] ; x0 (y1 x1 y1 x1) STR r0,[r6,#20] ; y0 STR r0,[r6,#24] ; x0 STR r0,[r6,#28] ; y0 LDR r0,backdrop_options TST r0,#bd_OptionScaled BEQ %FT01 ; Scaled sprite, x1,y1 are screen x1,y1 LDR r2, XEig ; Get XEig LDR r0,scale_x1 MOV r0,r0,ASL r2 MOV r0,r0,ASL #8 STR r0,[r6,#8] STR r0,[r6,#16] Debug bd,"x1 = ",r0 LDR r2, YEig ; Get YEig LDR r0,scale_y1 MOV r0,r0,ASL r2 MOV r0,r0,ASL #8 STR r0,[r6,#4] STR r0,[r6,#12] Debug bd,"y1 = ",r0 LDR r0,icon_bar_height MOV r0,r0,LSL #8 STR r0,[r6,#20] STR r0,[r6,#28] B %FT10 01 ; Not a scaled sprite: LDR r0,scale_x1 MOV r0,r0,ASL #8 ; passed in 1/256th of an OS unit STR r0,[r6,#8] STR r0,[r6,#16] LDR r0,scale_y1 MOV r0,r0,ASL #8 ; passed in 1/256th of an OS unit STR r0,[r6,#4] STR r0,[r6,#12] 10 Debug bd,"Scale factors set." LDR r0,=&200 + SpriteReason_SwitchOutputToSprite MOV r1,#&8000 ; -> Sprite area ADD r2,r1,#16 ; -> Sprite MOV r3,#0 ; No save area. SWI XOS_SpriteOp BVS %FT99 ; If error, switch output to screen. Debug bd,"Output switched to sprite" LDR r0, background_colour MOV r3, #128 MOV r4, #0 SWI ColourTrans_SetGCOL SWI XOS_WriteI+16 MOV r0,#&200 + SpriteReason_PutSpriteTransformed MOV r1,r9 MOV r2,r10 MOV r3,#1 ; Dest = coords. MOV r5,#8 ; GCOL action ADD r5,r5,#32 ; wide table ADR r6,ScaleFactors ; Dest. coords. ADR r7,dataarea ; Pixel translation table. SWI XOS_SpriteOp [ debugbd BVS %FT99 ] Debug bd,"Sprite scaled." 99 LDR r0,=&200 + SpriteReason_SwitchOutputToSprite MOV r2,#0 MOV r3,#1 SWI XOS_SpriteOp ; Switch output back to screen. Pull "PC",VS Debug bd,"Output directed back to screen" ; Release any unwanted memory LDR r0,slot_size MOV r1,#-1 SWI XWimp_SlotSize Pull "PC",VS ; Now calculate where it would be plotted. LDR r0,backdrop_options TST r0,#bd_OptionScaled MOVNE r0,#0 STRNE r0,Sprite_x STRNE r0,Sprite_y ; For scaled sprites plot at 0,0 Pull "PC",NE TST r0,#bd_OptionTiled Pull "PC",NE ; For tiled sprites, compute at redraw time. MOV r0,#-1 ; Current mode MOV r1,#VduExt_XWindLimit ; Screen width in pixels SWI XOS_ReadModeVariable ADDVC r4,r2,#1 LDRVC r2,XEig ; XEig MOVVC r4,r4,ASL r2 ; Screen width in OS Units MOVVC r1,#VduExt_YWindLimit ; Screen height in pixels SWIVC XOS_ReadModeVariable ADDVC r5,r2,#1 LDRVC r2,YEig ; YEig MOVVC r5,r5,ASL r2 ; Screen height in OS Units Pull "PC",VS LDR r1,icon_bar_height SUB r5,r5,r1 LDR r0,scale_x1 SUBS r0,r4,r0 MOV r0,r0,ASR #1 STR r0,Sprite_x LDR r0,scale_y1 SUBS r0,r5,r0 MOV r0,r0,ASR #1 ADD r0,r0,r1 STR r0,Sprite_y Pull "PC" ClearBackdrop Push "r0-r4,lr" Debug pi,"ClearBackdrop" LDR r14,backdrop_options BIC r14,r14,#bd_OptionActive STR r14,backdrop_options LDR r0,backdrop_handle MOV r1,#0 MOV r2,#0 MOV r3,#&80000 MOV r4,#&80000 SWI XWimp_ForceRedraw LDR r2,backdrop_path TEQ r2,#0 MOVNE r0,#ModHandReason_Free SWINE XOS_Module MOV r1,#0 STR r1,backdrop_path MOVVC r0,#0 MOVVC r1,#-1 SWIVC XWimp_SlotSize Pull "r0-r4,pc" BackdropSpriteName DCB "Backdrop",0 ALIGN MakeErrorBlock Pinboard_NoRoom ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Int_CacheJPEG ; ; Caches a JPEG image used for backdrop ; ; In : r4 = file length (from OS_File call) Int_CacheJPEG Entry LDR r0, backdrop_options ORR r0, r0, #bd_OptionJPEG ORR r0, r0, #bd_OptionRecache STR r0, backdrop_options ; Get memory STR r4, slot_size MOV r3, r4 ADD r0, r4, #32 ; Add 32 to file size for luck (or SpriteExtend bug!) CMP r0, #&6000 ; if less than 24k, MOVLT r0, #&6000 ; make it 24k (SpriteExtend bug) MOV r1, #-1 SWI XWimp_SlotSize MOVVS r0, #0 CMP r0, r3 BCS %FT20 ; Couldn't get the memory LDR r0,backdrop_handle MOV r1,#0 MOV r2,#0 MOV r3,#&8000 MOV r4,#&8000 SWI XWimp_ForceRedraw ADRL r0,ErrorBlock_Pinboard_NoRoom BL msgtrans_errorlookup ; V set on exit Pull "PC" 20 ; Load JPEG MOV r0, #16 LDR r1, backdrop_path MOV r2, #&8000 MOV r3, #0 SWI OS_File ; Get width and height MOV r0, #1 MOV r1, #&8000 LDR r2, slot_size SWI XJPEG_Info MOV r4, r2 MOV r5, r3 ; Read YEig and calculate height in OS units LDR r2, YEig MOV r2,r5, LSL r2 STR r2,scale_y1 ; Read XEig and calculate width in OS units LDR r2, XEig MOV r2,r4, LSL r2 STR r2,scale_x1 ; Are we scaling? ADR r6, ScaleFactors LDR r0, backdrop_options TST r0, #bd_OptionScaled BEQ %FT50 ; Image is being scaled to fit screen ; Set up scale factors LDR r2, Screen_x1 ADD r2, r2, #4 STR r2, [r6] LDR r2, Screen_y1 LDR r0, icon_bar_height SUB r2, r2, r0 ADD r2, r2, #4 STR r2, [r6, #4] LDR r0, scale_x1 STR r0, [r6, #8] LDR r0, scale_y1 STR r0, [r6, #12] ; Set up position MOV r0, #0 STR r0, Sprite_x LDR r0, icon_bar_height STR r0, Sprite_y B %FT60 50 ; Image centred, so scale 1:1 MOV r0, #1 STR r0, [r6] STR r0, [r6, #4] STR r0, [r6, #8] STR r0, [r6, #12] ; Setup x position LDR r0, Screen_x1 LDR r1, scale_x1 SUBS r2, r0, r1 MOVS r3, r2, ASR #1 STR r3, Sprite_x ; Setup y position LDR r0, Screen_y1 LDR r1, scale_y1 LDR r4, icon_bar_height SUB r0, r0, r4 SUBS r2, r0, r1 MOVS r3, r2, ASR #1 ADD r3, r3, r4 STR r3, Sprite_y 60 EXIT LNK Icons.s