; ; slab.s ; ; Icon slabbing for Sculptrix ; ; © 1995-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Sculptrix. ; ; Sculptrix 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. ; ; Sculptrix 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 Sculptrix. 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 GET libs:stream ;----- External dependencies ------------------------------------------------ GET sh.colours GET sh.plot GET sh.vString GET sh.wSpace ;----- Main code ------------------------------------------------------------ AREA |Module$$Code|,CODE,READONLY ; --- slab_doSlab --- ; ; On entry: R0 == window handle ; R1 == icon handle ; R2 == new background colour for icon ; ; On exit: R2 == old background colour, or -1 ; ; Use: Low-level slabbing operation. EXPORT slab_doSlab slab_doSlab ROUT STMFD R13!,{R0-R5,R14} ;Save some registers MOV R14,#-1 ;Nothing achieved yet STR R14,[R13,#8] ;Store as old colour ; --- Read the icon information --- SUB R13,R13,#84 ;Enough for a redraw block STMIA R13,{R0,R1} ;Store the window and icon MOV R1,R13 ;Point to this block SWI XWimp_GetIconState ;Read the icon information BVS %99slab_doSlab ;If that failed, return ADD R1,R13,#8 ;Point to the icon data BL vString_read ;Read the border information BCC %90slab_doSlab ;No border -- return now TST R0,#vsFlag_slab ;Is the border slabbable? BEQ %90slab_doSlab ;Not slabbable -- return BIC R5,R0,#&FF ;Clear to raw plinth ; --- Swap the colours over --- MOV R1,R13 ;Point to the full block BL colours_set ;Set the background colour STR R2,[R13,#84+8] ;Store this to return in R2 ; --- Now toggle the border --- LDRB R14,[R4,#0] ;Load the invert character EOR R14,R14,#&20 ;Change its case STRB R14,[R4,#0] ;Store the character back ADD R14,R13,#8 ;Point to the bounding box LDMIA R14,{R2-R4,R14} ;Load these values out SUB R2,R2,#4 ;Expand to allow for border SUB R3,R3,#4 ADD R4,R4,#4 ADD R14,R14,#4 LDR R0,[R13,#0] ;Load the window handle ADD R1,R13,#40 ;Point to the update block STMIA R1,{R0,R2-R4,R14} ;Store them back again SWI XWimp_UpdateWindow ;Start the update operation BVS %99slab_doSlab ;If that failed, return CMP R0,#0 ;Is there anything to do? BEQ %90slab_doSlab ;No -- do nothing then ; --- Read the window origin position --- LDR R2,[R1,#4] ;Load the x0 coordinate ADD R14,R1,#16 ;Find the others LDMIA R14,{R3,R4,R14} ;Load them from the block SUB R2,R2,R4 ;Find the x origin SUB R3,R3,R14 ;And find the y origin ; --- Do the update loop --- 00 EOR R0,R5,#vsFlag_invert ;Get the border type word ADD R1,R13,#8 ;Point to the icon data BL plot_border ;Go and plot the border ADDVC R1,R13,#40 ;Point to the update block SWIVC XWimp_GetRectangle ;Get another rectangle BVS %99slab_doSlab ;If that failed, return CMP R0,#0 ;Is that all there is? BNE %b00 ;No -- loop back then ; --- Tidy up and return --- 90slab_doSlab ADD R13,R13,#84 ;Restore the stack pointer LDMFD R13!,{R0-R5,R14} ;Restore registers BICS PC,R14,#V_flag ;And return without error 99slab_doSlab ADD R13,R13,#84+4 ;Restore the stack pointer LDMFD R13!,{R1-R5,R14} ;Restore registers except R0 ORRS PC,R14,#V_flag ;And return the error LTORG ; --- slab_slab --- ; ; On entry: R0 == window handle ; R1 == icon handle ; R2 == pointer to slab descriptor block ; ; On exit: -- ; ; Use: Slabs an icon in, and records information for unslabbing. EXPORT slab_slab slab_slab ROUT STMFD R13!,{R0-R3,R14} ;Save some registers ; --- Fill in the descriptor block --- MOV R3,R2 ;Remember this pointer STMIA R3,{R0,R1} ;Store them away SWI XOS_ReadMonotonicTime ;Read the time STR R0,[R3,#12] ;Store it in the block ; --- Do the slabness --- LDR R0,[R3,#0] ;Load the window handle LDR R2,sculpt_slab ;Get the slab colour BL slab_doSlab ;Do the slabbing op BVS %99slab_slab SUB R13,R13,#20 ;Allow some space for block MOV R1,R13 ;Point to the block SWI XWimp_GetPointerInfo ;Fetch the mouse status LDR R14,[R13,#8] ;Fetch the button state ADD R13,R13,#20 ;Restore the stack pointer CMP R14,#0 ;Are any buttons pressed? ORREQ R2,R2,#&100 ;No -- set a flag then STR R2,[R3,#8] ;Store in the descriptor ; --- Clear the `immediate unslab' flag --- LDR R14,sculpt_flags ;Load the flags word BIC R14,R14,#scFlag_unslab ;Clear the flag STR R14,sculpt_flags ;Store the flags back LDMFD R13!,{R0-R3,PC}^ ;Return when done 99 ADD R13,R13,#4 ;Don't restore R0 on exit LDMFD R13!,{R1-R3,R14} ;Restore other registers ORRS PC,R14,#V_flag ;And return with V set LTORG ; --- slab_unslab --- ; ; On entry: R2 == pointer to descriptor block ; ; On exit: -- ; ; Use: Unslabs an icon which was slabbed. EXPORT slab_unslab slab_unslab ROUT STMFD R13!,{R0-R4,R14} ;Save some registers MOV R4,R2 ;Move this somewhere nice ; --- Quick check to see if anything needs doing --- LDR R14,[R4,#8] ;Load the colour word CMP R14,#-1 ;Is this unset? BEQ %90slab_unslab ;Yes -- return then ; --- Do we do this quickly? --- LDR R14,sculpt_flags ;Load the flags word TST R14,#scFlag_unslab ;Have we recently unslabbed? BNE %50slab_unslab ;Yes -- skip the delay ORR R14,R14,#scFlag_unslab ;Set the flag now STR R14,sculpt_flags ;Save the flags back ; --- Work out how long to wait --- SUB R13,R13,#36 ;Make space for a block LDR R14,[R4,#0] ;Load the window handle STR R14,[R13,#0] ;Store in the block MOV R1,R13 ;Point to my block SWI XWimp_GetWindowState ;Read the window state MOVVS R14,#0 ;If failed, assume deleted LDRVC R14,[R13,#32] ;Else load the window flags ADD R13,R13,#36 ;Restore the stack pointer TST R14,#&00010000 ;Is the window open? BEQ %10slab_unslab ;Yes -- wait for timer then LDR R14,[R4,#8] ;Load the flags/colour word TST R14,#&100 ;Is the `no mouse' bit set? BNE %10slab_unslab ;Yes -- wait for timer then ; --- Check for the mouse then --- 00 SWI XOS_Mouse ;Read the mouse position CMP R2,#0 ;Are the buttons released? BNE %b00 ;No -- skip round B %50slab_unslab ;Now skip onwards for unslab ; --- Check for the timer --- 10slab_unslab LDR R1,[R4,#12] ;Load the targt time ADD R1,R1,#10 ;Allow a tenth of a second 00 SWI XOS_ReadMonotonicTime ;Read the current time CMP R0,R1 ;Have we waited long enough? BMI %b00 ;No -- loop back then ; --- Now we can unslab the icon --- 50slab_unslab LDMIA R4,{R0-R2} ;Load the information out AND R2,R2,#&FF ;Only use the colour bits BL slab_doSlab ;Do the unslabbing 90 LDMFD R13!,{R0-R4,PC}^ ;Return to caller when done 99 ADD R13,R13,#4 ;Don't restore R0 on exit LDMFD R13!,{R1-R4,R14} ;Restore registers ORRS PC,R14,#V_flag ;And return to caller LTORG ; --- slab_colour --- ; ; On entry: -- ; ; On exit: R2 == slab colour ; ; Use: Returns the current slabbing colour. EXPORT slab_colour slab_colour ROUT LDR R2,sculpt_slab ;Load the slabbing colour MOVS PC,R14 ;And return to caller LTORG ;----- That's all, folks ---------------------------------------------------- END