; ; tspr.s ; ; Toolsprite hacking for things like border sizes (TMA) ; ; © 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:screen GET sapphire:wimp ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ; --- tspr_getSprAddr --- ; ; On entry: -- ; ; On exit: R0 == pointer to tool sprites, or 0 if none ; ; Use: Returns a pointer to the toolsprites. If the user is using ; RISC OS 2, or there are no toolsprites defined, then ; 0 is returned. EXPORT tspr_getSprAddr tspr_getSprAddr ROUT STMFD R13!,{R1,R2,R14} ;Stack some registers BL wimp_version ;Get the wimp version number CMP R0,#300 ;Are we using RISC OS 2? MOVLT R0,#0 ;Yes -- no sprites then BLT %90tspr_getSprAddr ;...and return SWIEQ Wimp_BaseOfSprites ;We want this for 3.00 MOVEQ R0,R1 ;...RAM resident part please BEQ %90tspr_getSprAddr ;...and return MOV R1,#94 ;We need to test with 350... ADD R1,R1,#256 ;...so create the number CMP R0,R1 ;Is version < 3.50? BLT %10 ;Yes -- deal with it then ; --- We are using RISC OS 3.50 or higher --- MOV R0,#9 ;Read toolsprite control blk SWI Wimp_ReadSysInfo ;Find it then B %90tspr_getSprAddr ;And return ; --- We are using RISC OS 3.01 - 3.49 --- 10 ADR R1,tspr__versionList ;Point to the version list 20 LDR R2,[R1],#4 ;Load the version number CMP R0,R2 ;Is it the one we want? BLT %90tspr_getSprAddr ;It isn't in list -- return BEQ %30tspr_getSprAddr ;It is -- deal with it CMP R2,#-1 ;Are we at the end? MOVEQ R0,#0 ;Yes -- no sprite then BEQ %90tspr_getSprAddr ;...return ADD R1,R1,#4 ;Skip past address field B %20tspr_getSprAddr ;And keep searching ; --- We have located the version number --- 30 STMFD R13!,{R3-R5} ;Stack some more registers LDR R14,[R1] ;Get the address offset MOV R0,#18 ;Look-up module name ADR R1,tspr__moduleName ;Point to the module name SWI OS_Module ;Get information then LDR R0,[R4,R14] ;Get the toolsprite address SUB R0,R0,#4 ;Correct it nicely LDMFD R13!,{R3-R5} ;Get registers back ; --- Return to caller --- 90 LDMFD R13!,{R1,R2,PC}^ ;Unstack registers and return tspr__moduleName DCB "WindowManager",0 ALIGN tspr__versionList DCD 316,1676 DCD 322,1708 DCD -1 LTORG ; --- tspr_borderWidths --- ; ; On entry: -- ; ; On exit: R0 == title bar height ; R1 == vertical scroll bar width ; R2 == horizontal scroll bar height ; ; Use: Return the width of window tools by looking at the ; sprites associated with them, rather than creating ; a temporary window. EXPORT tspr_borderWidths tspr_borderWidths ROUT STMFD R13!,{R3-R10,R14} ;Stack some registers ; --- Find out about the current mode --- BL screen_getInfo ;Get some screen information MOV R7,#0 ;Flags word so far LDR R9,[R0,#screen_xEig] ;Get the xEig Factor LDR R10,[R0,#screen_yEig] ;and the yEig Factor CMP R9,#1 ;Are we in a high... CMPEQ R10,#1 ;...resolution mode? ORREQ R7,R7,#1 ;Yes -- remember this LDR R1,[R0,#screen_bpp] ;Get the bpp CMP R1,#1 ;Monochrome mode? ORREQ R7,R7,#2 ;Yes -- remember this too ; --- Are we using tool sprites? --- BL tspr_getSprAddr ;Find the address of sprites CMP R0,#0 ;Are there any? BEQ %80tspr_borderWidths ;No -- get RISC OS 2 defaults MOV R8,R0 ;Put sprite block in R8 ; --- Use sprites to get the border widths --- ; ; First, find out about the title bar ADR R3,tspr__titleName ;Point to title bar sprite ^ BL %50tspr_borderWidths ;Get sprite information MOV R0,R4 ;The returned height BVC %20tspr_borderWidths ;All OK -- now vertical TST R7,#1 ;Are we in a high res mode? MOVNE R0,#42 ;Yes -- use this height MOVEQ R0,#44 ;No -- use this height ; --- Now the vertical scroll bar --- 20 ADR R3,tspr__vertName ;Point to vert bar sprite ^ BL %50tspr_borderWidths ;Get sprite information MOVVC R1,R3 ;The returned height MOVVS R1,#42 ;The default width ; --- Finally the horizontal scroll bar height --- 30 ADR R3,tspr__horzName ;Point to horz bar sprite ^ BL %50tspr_borderWidths ;Get sprite information MOV R2,R4 ;The returned height BVC %90tspr_borderWidths ;All OK -- now return TST R7,#1 ;Are we in a high res mode? MOVNE R2,#42 ;Yes -- use this height MOVEQ R2,#44 ;No -- use this height B %90tspr_borderWidths ;Return to caller ; --- Find out about the given sprite --- 50 BIC R14,R14,#V_flag ;No error yet STMFD R13!,{R0-R2,R14} ;Preserve these values MOV R14,R3 ;Remember this pointer LDR R2,[R3,R7,LSL#2] ;Actually point to the name MOV R1,R8 ;The sprite block MOV R0,#256+40 ;Read sprite information SWI XOS_SpriteOp ;Read info LDRVS R2,[R14] ;Error -- get default name MOVVS R0,#256+40 ;...read sprite information SWIVS XOS_SpriteOp ;...try again MOVVC R3,R3,LSL R9 ;Calculate width in OS units MOVVC R4,R4,LSL R10 ;Calculate height in OS units LDMFD R13!,{R0-R2,R14} ;Get registers back ORRVSS PC,R14,#V_flag ;Return with error BICVCS PC,R14,#V_flag ;Or maybe without ; --- Use RISC OS 2 defaults --- 80 MOV R1,#42 ;This is width in all modes TST R7,#1 ;Are we in a high res mode? MOVNE R0,#42 ;Yes -- use this height MOVEQ R0,#44 ;No -- use this height MOV R2,R0 ;This height is the same ; --- Return to the caller --- 90 LDMFD R13!,{R3-R10,PC}^ ;Return tspr__titleName DCD tbarlcap DCD tbarlcap22 DCD tbarlcap0 DCD tbarlcap23 tspr__vertName DCD vwellbcap DCD vwellbcap22 DCD vwellbcap0 DCD vwellbcap23 tspr__horzName DCD hwelllcap DCD hwelllcap22 DCD hwelllcap0 DCD hwelllcap23 tbarlcap DCB "tbarlcap",0 tbarlcap22 DCB "tbarlcap22",0 tbarlcap0 DCB "tbarlcap0",0 tbarlcap23 DCB "tbarlcap23",0 vwellbcap DCB "vwellbcap",0 vwellbcap22 DCB "vwellbcap22",0 vwellbcap0 DCB "vwellbcap0",0 vwellbcap23 DCB "vwellbcap23",0 hwelllcap DCB "hwelllcap",0 hwelllcap22 DCB "hwelllcap22",0 hwelllcap0 DCB "hwelllcap0",0 hwelllcap23 DCB "hwelllcap23",0 LTORG ; --- tspr_adjustBox --- ; ; On entry: R1 == pointer to Wimp_OpenWindow block to modify ; ; On exit: Block updated in place ; ; Use: Updates the open block to ensure that the window is opened ; on the screen. EXPORT tspr_adjustBox tspr_adjustBox ROUT ; --- Find out which gadgets the window has --- STMFD R13!,{R0-R11,R14} ;Save a job load of regs SUB R13,R13,#36 ;Space for a window state LDR R0,[R1,#0] ;Load the caller's handle STR R0,[R13,#0] ;Save it in my block MOV R1,R13 ;Point to my state block SWI Wimp_GetWindowState ;Find the window information LDR R3,[R13,#32] ;Load the window flags out ADD R13,R13,#36 ;Reclaim the stack space ; --- Now mangle the window block --- BL tspr_borderWidths ;Get the border widths LDR R4,[R13,#4] ;Load his pointer back again LDMIB R4,{R5-R8} ;Load the coordinates out TST R3,#&0f000000 ;Is there a top-row gadget? ADDNE R8,R8,R0 ;Yes -- add title bar height TST R3,#&10000000 ;Is there a vert. scrollbar? ADDNE R7,R7,R1 ;Yes -- add scrollbar width TST R3,#&40000000 ;Is there a horiz. one? SUBNE R6,R6,R2 ;Yes -- sub scrollbar height ; --- Get the screen dimensions --- BL screen_getInfo ;Find the screen information MOV R11,R0 ;Remember this block's pos ADD R0,R0,#screen_width ;Find the screen width LDMIA R0,{R9,R10} ;Load width and height ; --- Now load the original coords again --- LDMIB R4,{R0-R3} ;Load the coordinates out ; --- Mangle the x coordinates first --- SUB R14,R7,R5 ;Get the window width CMP R14,R9 ;Is this wider than screen? SUBGT R0,R0,R5 ;Yes -- fit it exactly then SUBGT R2,R7,R2 ;And fit right edge to screen SUBGT R2,R9,R2 SUBS R14,R7,R9 ;Is the right edge on? SUBGT R2,R2,R14 ;No -- shift it back on then SUBGT R0,R0,R14 ;Ensure the width is constant SUBS R14,R5,#0 ;Is the left edge on? SUBLT R0,R0,R14 ;No -- shift it back on SUBLT R2,R2,R14 ;Ensure constant width again ; --- Now mangle the y coordinates --- SUBS R14,R8,R6 ;Get the window height CMP R14,R10 ;Is this higher than screen? SUBGT R1,R1,R6 ;Yes -- fit it exactly then SUBGT R3,R8,R3 ;And fit top edge to screen SUBGT R3,R10,R3 SUBS R14,R8,R10 ;Is the top edge on? SUBGT R3,R3,R14 ;No -- shift it back on then SUBGT R1,R1,R14 ;Ensure height is constant LDR R14,[R11,#screen_dy] ;Get screen dy value SUBS R14,R6,R14 ;Is the bottom edge on? SUBLT R1,R1,R14 ;No -- shift it back on SUBLT R3,R3,R14 ;Ensure constant height again ; --- Store it back and return --- STMIB R4,{R0-R3} ;Store coordinates back again LDMFD R13!,{R0-R11,PC}^ ;Return to caller LTORG ;----- That's all, folks ---------------------------------------------------- END