; ; tmsMain.s ; ; The Straylight Tearoff Menu Segment (TMA) ; ; © 1994 Straylight ; ;----- Don't forget to do these things -------------------------------------- ; ; Do a good checksum ;----- Standard header ------------------------------------------------------ GET libs:header GET libs:swis ;----- External Dependencies ------------------------------------------------ GET libs:tearSupt.sh.tearsupt GET sapphire:errorBox GET sapphire:help GET sapphire:idle GET sapphire:keyString GET sapphire:msgs GET sapphire:resspr GET sapphire:sapphire GET sapphire:screen GET sapphire:string GET sapphire:tspr GET sapphire:wimp GET sapphire:win ; --- Internal header files --- GET sapphire:_tms.tmsCreate GET sapphire:_tms.tmsGlobal GET sapphire:_tms.tmsGlue ;----- Main code ------------------------------------------------------------ AREA |Sapphire$$Code|,CODE,READONLY ; --- tms__closeMenu --- ; ; On entry: R2 == pointer to menu to close ; R10 == pointer to the menu we are currently over ; ; On exit: -- ; ; Use: Closes the menu structure pointed to, and destroys it EXPORT tms__closeMenu tms__closeMenu ROUT CMP R2,#0 ;Is there menu? MOVEQS PC,R14 ;No -- return STMFD R13!,{R0-R4,R14} ;Stack some registers LDR R14,tms__currDbox ;Get the current dbox CMP R14,R2 ;Is this what we are closing? BEQ %20tms__closeMenu ;Yes -- close it then LDR R0,[R2,#hPrevMenu] ;Get the previous menu CMP R0,#0 ;Is there one? BEQ %03tms__closeMenu ;No -- skip this bit then CMP R0,R10 ;Are we over previous menu? BLNE tms__deselect ;No -- deselect the item LDREQ R1,[R0,#hFlags] ;Yes -- get its flags BICEQ R1,R1,#hFlag__warned ;...clear the warned flag STREQ R1,[R0,#hFlags] ;...store flags back again MOV R0,#0 ;A NULL pointer ; --- Tell the previous menu that we have closed --- LDR R1,[R2,#hFromItem] ;Get the item we are from CMP R1,#0 ;Is there one? STRNE R0,[R1,#iSubMenu] ;Yes -- no submenu now ; --- Update some globals --- 03 STR R0,tms__prevLevel ;No previous level STR R0,tms__orgTearoff ;No originating tearoff ; --- Clear the previous field of torn menus --- LDR R1,tms__tornoffs ;Get the head of the list CMP R1,#0 ;Are we at the end? BEQ %05tms__closeMenu ;Yes -- jump 04 LDR R4,[R1,#hPrevMenu] ;Get the 'previous' field CMP R2,R4 ;Does it point to this menu? STREQ R0,[R1,#hPrevMenu] ;Yes -- make it NULL LDR R1,[R1,#hNextTorn] ;Get the next torn menu CMP R1,#0 ;Are we at the end? BNE %04tms__closeMenu ;No -- keep looking ; --- If we are closing the current transient, do this --- 05 LDR R0,tms__current ;Point to current transient CMP R0,R2 ;Are we closing it? BNE %09tms__closeMenu ;No -- jump ahead MOV R0,#0 ;Yes -- A NULL pointer STR R0,tms__current ;...no current any more BL tearSupport_closed ;Stop tearoffsupt sending ; --- If dbox came from this menu, do this --- LDR R0,tms__dboxPrev ;Get dbox parent CMP R0,R2 ;Are we closing it? MOVEQ R0,#0 ;Yes -- get a NULL word STREQ R0,tms__dboxPrev ;And store that as the parent ; --- Now close down the menu structure --- 09 LDR R3,tms__oldHandle ;Get the old handle 10 MOV R0,R2 ;Destroy this menu LDR R1,[R0,#hFlags] ;Get the flags word TST R1,#hFlag__torn ;Is the menu torn off? LDMNEFD R13!,{R0-R4,PC}^ ;Yes -- return LDR R2,[R0,#hSubMenu] ;Get the submenu pointer ; --- Inform the owner about deletion --- STMFD R13!,{R0-R2,R10,R12} ;Stack some registers ADD R0,R0,#hHandler ;Point to the handler LDMIA R0,{R2,R10,R12} ;Get values out MOV R0,#mEvent_deleted ;The menu has been deleted MOV R1,#0 ;No item in question CMP R2,#0 ;Sanity check MOV R14,PC ;Set up return address MOVNE PC,R2 ;Call the handler LDMFD R13!,{R0-R2,R10,R12} ;Get registers back ; --- Destroy the menu --- BL tms__destroy ;Destroy the menu CMP R0,R3 ;Were we over this menu? BLEQ tms__cleanUp ;Yes -- clean up then TST R1,#hFlag__warned ;Has there been a warning LDMEQFD R13!,{R0-R4,PC}^ ;No -- return CMP R2,#0 ;Is there a submenu? LDMEQFD R13!,{R0-R4,PC}^ ;No -- Return to caller TST R1,#hFlag__dbox ;Is this a dbox? BEQ %10tms__closeMenu ;No -- keep going then ; --- Its a window then --- 20 LDR R0,tms__dboxPrev ;Get the previous menu CMP R0,#0 ;Is there one? BEQ %25tms__closeMenu ;No -- skip this bit then CMP R0,R10 ;Are we over previous menu? BLNE tms__deselect ;No -- deselect the item LDREQ R1,[R0,#hFlags] ;Yes -- get its flags BICEQ R1,R1,#hFlag__warned ;...clear the warned flag STREQ R1,[R0,#hFlags] ;...store flags back again MOV R0,#0 ;A NULL pointer ; --- Tell the previous menu that we have closed --- LDR R1,tms__dboxPrev ;Get the item we are from CMP R1,#0 ;Is there one? STRNE R0,[R1,#iSubMenu] ;Yes -- no submenu now ; --- Now close the dialogue box --- 25 LDR R2,tms__currDbox ;Load the dbox handle STR R2,[R13,#-4]! ;Put handle on the stack MOV R1,R13 ;Point to it SWI Wimp_CloseWindow ;And close the window ADD R13,R13,#4 ;Reclaim my stack MOV R0,#0 ;No current dbox STR R0,tms__currDbox ;Make that clear LDR R1,tms__current ;Get the current transient CMP R1,#0 ;Is this what we are closing? STREQ R0,tms__current ;Yes -- no transient now then BLEQ tearSupport_closed ;Stop the messages please LDR R0,tms__flags ;Load the main flags ORR R0,R0,#tFlag__doFake ;Do a fake NULL event STR R0,tms__flags ;Store the flags back again LDMFD R13!,{R0-R4,PC}^ ;Return to caller LTORG ; --- tms__alarm1 --- ; ; On entry: -- ; ; On exit: -- ; ; Use: The first alarm to be called when waiting on an item. tms__alarm1 ROUT STMFD R13!,{R0-R2,R7,R8,R14} ;Stack registers nicley ; --- Set up the next alarm --- MOV R0,#161 ;Read the CMOS ram MOV R1,#23 ;Read the delay time SWI OS_Byte ;Read the delay then LDR R0,tms__flags ;Load the tms flags ORR R0,R0,#tFlag__nActive ;Menus are not active STR R0,tms__flags ;Save the new flags ADD R2,R2,R2,LSL #2 ;Multiply delay by 5 MOV R2,R2,LSL #1 ;And then by 2 SWI OS_ReadMonotonicTime ;Read the current time ADD R0,R0,R2 ;Set alarm for this time ADR R1,tms__alarm2 ;Call this handler ADR R2,tms__alarm1 ;Use this handle MOV R3,R12 ;And pass workspace in R12 BL idle_setAlarm ;Set the alarm ; --- Open the sub menu --- LDR R10,tms__alarmMenu ;Get the menu alarm is for LDR R0,[R10,#hHandle] ;Load the window handle STR R0,[R13,#-36]! ;Store in a block MOV R1,R13 ;Point to the block SWI Wimp_GetWindowState ;Get the window state LDR R7,tms__alarmItem ;Get the alarm item LDR R8,tms__itemBlock ;Get item block address BL tms__subMenu ;And open the menu ADD R13,R13,#36 ;Get the stack back LDMFD R13!,{R0-R2,R7,R8,PC}^ ;Return to caller LTORG ; --- tms__alarm2 --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Called as the second alarm, allowing selection of other ; items in the menu. tms__alarm2 ROUT STMFD R13!,{R14} ;Stack some registers LDR R14,tms__flags ;Load the tms flags BIC R14,R14,#tFlag__nActive ;Menus are not active STR R14,tms__flags ;Save the new flags LDMFD R13!,{PC}^ ;Return to caller ; --- tms__findItem --- ; ; On entry: R0 == x coordinate (menu relative) ; R1 == y coordinate (menu relative) ; R10 == pointer to the menu ; ; On exit: R8 == pointer to the item block ; R7 == pointer to the actual item tms__findItem ROUT STMFD R13!,{R0-R4,R14} ;Stack some registers MOV R2,#0 ;The y coordinate so far LDR R3,[R10,#hFlags] ;Get the menu flags TST R3,#hFlag__tearable ;Is there a tearoff bar? SUBNE R2,R2,#tms__barHeight ;Yes -- move y position down LDR R8,[R10,#hItems] ;Point to the items 00tms__findItem ADD R7,R8,#iHdrSize ;Point to the first item LDR R4,[R8,#iNumber] ;Get the item count 01tms__findItem CMP R1,R2 ;Compare y coordinates BGE %90tms__findItem ;If greater -- no item found SUB R2,R2,#44 ;The bottom of the item CMP R1,R2 ;Compare y coordinates BGE %10tms__findItem ;We've found it -- jump a bit LDR R3,[R7,#iFlags] ;Get the item flags TST R3,#iFlag__dotted ;Is there a dotted line? SUBNE R2,R2,#24 ;Subract that from y SUBS R4,R4,#1 ;Subtract the item count ADDNE R7,R7,#iItemSize ;If some left, point to them BNE %01tms__findItem ;...and try them LDR R8,[R8,#iItems] ;Point to the next batch CMP R8,#0 ;Are there any left BNE %00tms__findItem ;Yes -- check them B %90tms__findItem ;No -- return ; --- We have found the item --- 10tms__findItem LDR R1,[R8,#iDefinition] ;Point to packed definition LDR R0,[R8,#iNumber] ;Get the number of items SUBS R0,R0,R4 ;Get the index of item STR R0,tms__itemIndex ;Store this index value BEQ %15tms__findItem ;If we have found it -- jump 11tms__findItem LDR R2,[R1],#4 ;Get the item flags TST R2,#mFlag_indirect ;Is this item indirected? ADDNE R1,R1,#4 ;Yes -- skip the offset word BNE %13tms__findItem ;And skip past the loop ; --- Skip inline text string --- 12tms__findItem LDRB R14,[R1],#1 ;Get a message string byte CMP R14,#' ' ;Is it a terminator? BGE %12tms__findItem ;No -- get another one ADD R1,R1,#3 ;Add 3 BIC R1,R1,#3 ;And word align the pointer ; --- Skip over shortcut word --- 13tms__findItem TST R2,#mFlag_shortcut ;It there a shortcut? TSTEQ R2,#mFlag_iShortcut ;Even an indirected one? ADDNE R1,R1,#4 ;Yes -- skip over value ; --- Now skip other optional blocks --- SKPITEM R2,R1 ;Skip this item SUBS R0,R0,#1 ;Decrement my count BGT %11tms__findItem ;Keep trying if some left 15tms__findItem STR R1,tms__itemOver ;Store this pointer STR R8,tms__itemBlock ;And this one too LDMFD R13!,{R0-R4,PC}^ ;And return to caller ; --- The pointer wasn't over an item --- 90tms__findItem MOV R8,#0 ;No item block found MOV R7,#0 ;No item found either LDMFD R13!,{R0-R4,PC}^ ;Return now LTORG ; --- tms__updateItem --- ; ; On entry: R7 == pointer to the item to highlight ; R10 == pointer to the menu ; ; On exit: -- ; ; Use: Forces an update of the textual part of an item. EXPORT tms__updateItem tms__updateItem ROUT STMFD R13!,{R0-R4,R11,R14} ;Stack some registers SUB R13,R13,#44 ;Get a redraw block LDR R4,[R7,#iyCoord] ;Get the y coordinate LDR R11,[R7,#iFlags] ;Get the item flags LDR R0,[R10,#hHandle] ;Get the window handle MOV R1,#24 ;x0 LDR R3,[R10,#hTotWidth] ;Get the total width ADD R3,R3,#24 ;x1 SUB R2,R4,#44 ;y0 STMIA R13,{R0-R4} ;Fill in the block MOV R1,R13 ;Point to it SUB R13,R13,#32 ;Get another block SWI Wimp_UpdateWindow ;Start the redraw 00 CMP R0,#0 ;More to do? ADDEQ R13,R13,#(44+32) ;Get the stack back LDMEQFD R13!,{R0-R4,R11,PC}^ ;No -- return BL tms__redrawText ;Perform the redrawing BL tms__redrawSprite ;.,.,.,., BL tms__redrawKey ;... SWI Wimp_GetRectangle ;Get another rectangle B %00tms__updateItem ;And keep redrawing LTORG ; --- tms__highlight --- ; ; On entry: R2 == pointer to item to highlight ; R10 == pointer to the menu for these items ; ; On exit: -- ; ; Use: Highlights the item pointed to on entry tms__highlight ROUT STMFD R13!,{R0,R7,R14} ;Stack some registers LDR R0,[R10,#hSelected] ;Get the selected item CMP R2,R0 ;Are they the same STMEQFD R13!,{R0-R4,R7,PC}^ ;Yes -- return MOV R7,R2 ;Point to the item STR R7,[R10,#hSelected] ;This is now selected item LDR R0,[R7,#iFlags] ;Get the item flags TST R0,#iFlag__shaded ;Is the item shaded? BLEQ tms__updateItem ;No -- update it LDMFD R13!,{R0,R7,PC}^ ;And return LTORG ; --- tms__unHighlight --- ; ; On entry: R2 == pointer to item to un-highlight ; R10 == pointer to the menu for these items ; ; On exit: -- ; ; Use: un-highlights the item pointed to on entry tms__unHighlight ROUT STMFD R13!,{R0,R7,R14} ;Stack some registers LDR R0,[R10,#hSelected] ;Get the selected item CMP R2,R0 ;Are they the same? LDMNEFD R13!,{R0,R7,PC}^ ;No -- return MOV R7,R2 ;Point to the item MOV R0,#0 ;No selected item STR R0,[R10,#hSelected] ;Store the NULL pointer LDR R0,[R7,#iFlags] ;Get the item flags TST R0,#iFlag__shaded ;Is the item shaded? BLEQ tms__updateItem ;No -- update it LDMFD R13!,{R0,R7,PC}^ ;And return LTORG ; --- tms__deselect --- ; ; On entry: R0 == pointer to the menu ; ; On exit: -- ; ; Use: Deselects the highlighted item in the given menu tms__deselect ROUT STMFD R13!,{R2,R10,R14} ;Stack some registers LDR R2,[R0,#hSelected] ;Point to the selected item CMP R2,#0 ;Is there one? LDMEQFD R13!,{R2,R10,PC}^ ;No -- return then MOV R10,R0 ;We need menu in R10 BL tms__unHighlight ;Unhighlight it then LDR R14,[R0,#hFlags] ;Get the flags word BIC R14,R14,#hFlag__warned ;We are no longer warned STR R14,[R0,#hFlags] ;Store back modified flags LDMFD R13!,{R2,R10,PC}^ ;Return to caller LTORG ; --- tmsh__subWaiting --- ; ; On entry: -- ; ; On exit: CS if we're waiting for a submenu, CC otherwise ; ; Use: Informs transWin if a submenu is expected. EXPORT tmsh__subWaiting tmsh__subWaiting ROUT STMFD R13!,{R12,R14} ;Save some registers WSPACE tms__wSpace ;Load my workspace address LDR R14,tms__flags ;Load the flags word TST R14,#tFlag__subWait ;Are we waiting for a submenu LDMFD R13!,{R12,R14} ;Unstack the registers ORRNES PC,R14,#C_flag ;Yes -- return CS then BICEQS PC,R14,#C_flag ;No -- return CC then LTORG ; --- tmsh__openSub --- ; ; On entry: R0 == window handle to open ; ; On exit: -- ; ; Use: Opens the given window as a submenu from a tms menu. EXPORT tmsh__openSub tmsh__openSub ROUT STMFD R13!,{R0-R3,R12,R14} ;Save registers WSPACE tms__wSpace ;Load my workspace address STR R0,[R13,#-36]! ;Get a block LDR R1,tms__currItem ;Point to the current item STR R0,[R1,#iDbox] ;Store the window handle LDR R14,[R1,#iFlags] ;Load the flags word ORR R14,R14,#iFlag__dbox ;Say this is a dbox STR R14,[R1,#iFlags] ;Save the flags back STR R0,tms__currDbox ;Store it here too LDR R1,tms__orgTearoff ;Load the originating tearoff STR R0,[R1,#hDbox] ;Store the window handle LDR R14,[R1,#hFlags] ;Load the flags word ORR R14,R14,#hFlag__dbox ;Say this is a dbox STR R14,[R1,#hFlags] ;Save the flags back STR R0,[R1,#hSubMenu] ;Store as submenu STR R1,tms__dboxPrev ;This is menu dbox came from LDR R14,tms__current ;Load the current transient CMP R14,#0 ;Is there one? BLEQ wimp_taskHandle ;No -- get task handle BLEQ tearSupport_opened ;...start tearSupt then MOV R1,R13 ;Point to it SWI Wimp_GetWindowState ;Get the window state LDMIB R1,{R0-R3} ;Get the current coords SUB R2,R2,R0 ;Get the current width SUB R1,R3,R1 ;And its height ADR R0,tms__coords ;Get coords to open at LDMIA R0,{R0,R3} ;Load some coords then SUB R1,R3,R1 ;Calculate y0 coord ADD R2,R0,R2 ;And then x1 STMIB R13,{R0-R3} ;Store them back nicely MOV R0,#-1 ;Open at the front please STR R0,[R13,#28] ;Store this in the block MOV R1,R13 ;Point back to the block BL tspr_adjustBox ;Fit on screen properly SWI Wimp_OpenWindow ;Open the window ADD R13,R13,#36 ;Restore stack LDMFD R13!,{R0-R3,R12,PC}^ ;Return to caller LTORG ; --- tms__subMenu --- ; ; On entry: R1 == pointer to a window state for the menu ; R7 == pointer to the item ; R8 == pointer to item header block ; R10 == pointer to the menu ; R12 == workspace pointer ; ; On exit: -- ; ; Use: Opens the sub menu correctly for the given item. tms__subMenu ROUT STMFD R13!,{R0-R6,R14} ;Stack some registers ; --- Store the coords to open next menu --- LDR R4,[R1,#12] ;Get the x1 coordinate LDR R5,[R1,#16] ;...and y1 ADD R4,R4,#2 ;Correct x1 a bit LDR R6,[R7,#iyCoord] ;Get the y coord of item ADD R5,R5,R6 ;Calculate next y to open at LDR R6,[R1,#24] ;Don't forget scroll offset SUB R5,R5,R6 ;No siree ADR R6,tms__coords ;Point to the coords STMIA R6,{R4,R5} ;Store the coordinates ; --- Warn the user/open the menu if we need to --- LDR R6,[R10,#hFlags] ;Get the menu flags TST R6,#hFlag__warned ;Have we already been warned? BNE %35tms__subMenu ;Yes -- skip this bit ORR R6,R6,#hFlag__warned ;We have been now STR R6,[R10,#hFlags] ;Store back the flags LDR R4,[R7,#iSubMenu] ;Get the submenu ptr CMP R4,#0 ;Is there one? BLNE tms__locateMenu ;Yes -- try to find it CMP R4,#0 ;Has it been returned? BNE %37tms__subMenu ;Yes -- bring it back to us STR R6,[R10,#hFlags] ;Store the flags back TST R6,#hFlag__torn ;Is menu torn off? STRNE R10,tms__orgTearoff ;Yes -- remember this fact MOV R5,#0 ;A NULL pointer STR R5,[R10,#hSubMenu] ;No current sub menu STR R10,tms__prevLevel ;This is the previous menu LDR R4,tms__itemOver ;Get packed defn for item LDR R3,[R4],#4 ;Get the flags word TST R3,#mFlag_subWarn ;Do we require a warning? BNE %33tms__subMenu ;Yes -- deal with it TST R3,#mFlag_indirect ;Is this item indirected? ADDNE R4,R4,#4 ;Yes -- skip the offset word BNE %32tms__subMenu ;And skip past the loop ; --- Skip inline text string --- 31tms__subMenu LDRB R14,[R4],#1 ;Get a message string byte CMP R14,#' ' ;Is it a terminator? BGE %31tms__subMenu ;No -- get another one ADD R4,R4,#3 ;Add 3 BIC R4,R4,#3 ;And word align the pointer ; --- Now skip other optional blocks --- 32tms__subMenu TST R3,#mFlag_shortcut ;Is there a normal... TSTEQ R3,#mFlag_iShortcut ;...or indirected shortcut? ADDNE R4,R4,#4 ;Yes -- skip over it SKIP mFlag_shade,4,R3,R4 SKIP mFlag_iShade,4,R3,R4 SKIP mFlag_switch,4,R3,R4 SKIP mFlag_radio,8,R3,R4 SKIP mFlag_sprite,8,R3,R4 ; --- We are now pointing at submenu information --- LDR R0,[R4,#0] ;Point to packed definition LDR R1,[R4,#4] ;Point to the event handler LDR R2,[R8,#iR10] ;Use R10 from previous item LDR R3,[R8,#iR12] ;Use R12 from previous item BL tms__searchForMenu ;Does this menu exist? BCS %37tms__subMenu ;Yes -- get it back then BL tms_create ;Create the menu STR R0,[R7,#iSubMenu] ;Store this in item defn STR R7,[R0,#hFromItem] ;We came from this item B %40tms__subMenu ;Now deal with real clicks ; --- The user requires a submenu warning --- 33tms__subMenu LDR R0,[R7,#iFlags] ;Get the item flags TST R0,#iFlag__shaded ;Is the item shaded? TSTNE R0,#iFlag__noWarn ;And we don't want warning? BNE %40tms__subMenu ;Both -- return MOV R0,#mEvent_arrow ;Send this event type LDR R1,tms__itemIndex ;With this index STR R7,tms__currItem ;Save the current item STR R10,tms__orgTearoff ;The originating menu LDR R14,tms__flags ;Load my current flags ORR R14,R14,#tFlag__subWait ;We're waiting for a submenu STR R14,tms__flags ;Save the flags back STMFD R13!,{R10,R12} ;Save these registers ADD R3,R8,#iHandler ;Point to the handler LDMIA R3,{R3,R10,R12} ;Load the values ADDS R0,R0,#0 ;Clear the carry flag TEQ R3,#0 ;Sanity check MOV R14,PC ;Set up the return address MOVNE PC,R3 ;Call the handler LDMFD R13!,{R10,R12} ;Get my registers back LDR R14,tms__flags ;Load my current flags BIC R14,R14,#tFlag__subWait ;Stopped waiting for submenu STR R14,tms__flags ;Save the flags back ; --- Use must return with menu in R0, and carry set if ; menu is already open. STR R0,[R7,#iSubMenu] ;Store this in item defn TEQ R0,#0 ;Has user returned NULL? STRNE R7,[R0,#hFromItem] ;No -- we came from this item MOVCS R4,R0 ;If carry set... BCS %37tms__subMenu ;...reposition given menu B %40tms__subMenu ;Return to caller ; --- There has already been a warning --- 35tms__subMenu LDR R4,[R10,#hSubMenu] ;Get the submenu pointer CMP R4,#0 ;Is there one? BEQ %40tms__subMenu ;No -- return to caller LDR R14,[R7,#iFlags] ;Get the item flags TST R14,#iFlag__dbox ;Is this a dbox? BNE %40tms__subMenu ;Yes -- return to caller LDR R5,[R4,#hFlags] ;Get flags for sub menu TST R5,#hFlag__warned ;Does submenu have submenu? BEQ %36tms__subMenu ;No -- jump this bit LDR R2,[R4,#hSubMenu] ;Point to the submenu's sub BL tms__closeMenu ;Close it down MOV R0,R4 ;Point to the submenu BL tms__deselect ;Deselect highlighted item ; --- Reposition the sub menu --- 36tms__subMenu SUB R13,R13,#36 ;Get me a block LDR R5,[R4,#hHandle] ;Get the window handle STR R5,[R13,#0] ;Store it in the block MOV R1,R13 ;Point to the block SWI Wimp_GetWindowState ;Get the window state then LDR R5,[R13,#12] ;Get x1 LDR R1,[R13,#4] ;Get x0 SUB R5,R5,R1 ;Get the window width LDR R1,tms__coords ;Get the x position to open STR R1,[R13,#4] ;Store this in the block ADD R5,R5,R1 ;Get new x1 position STR R5,[R13,#12] ;Store this too LDR R5,[R13,#16] ;Get y1 LDR R1,[R13,#8] ;Get y0 SUB R5,R5,R1 ;Get the window height LDR R1,tms__coords+4 ;Get the y position to open LDR R3,[R4,#hFlags] ;Get the menu flags TST R3,#hFlag__tearable ;Is there a bar? ADDNE R1,R1,#tms__barHeight ;Yes -- add this on STR R1,[R13,#16] ;Store this in the block SUB R5,R1,R5 ;Get new y0 position STR R5,[R13,#8] ;Store this too MOV R1,#-1 ;Open in front STR R1,[R13,#28] ;Store this value too MOV R1,R13 ;Point to the block BL tspr_adjustBox ;Mangle to fit on screen SWI Wimp_OpenWindow ;Open the window ADD R13,R13,#36 ;Get my stack back B %40tms__subMenu ;Deal with real clicks ; --- We need to 'bring back' a torn off menu --- 37tms__subMenu MOV R5,R10 ;Remember R10 value MOV R10,R4 ;Point at found menu BL tms__unTearMenu ;Un-tear it BL tms__updateBar ;Update the tearoff bar MOV R10,R5 ;Get R10 value back STR R4,[R7,#iSubMenu] ;Store submenu pointer back STR R4,[R10,#hSubMenu] ;...in places good STR R10,[R4,#hPrevMenu] ;Store previous menu STR R7,[R4,#hFromItem] ;Item menu was from LDR R5,tms__current ;Get the current menu CMP R5,#0 ;Is there one? STREQ R4,tms__current ;No -- store this one then BLEQ wimp_taskHandle ;...get the task handle BLEQ tearSupport_opened ;...start tearoffsupt sending B %36tms__subMenu ;And reposition it 40tms__subMenu LDMFD R13!,{R0-R6,PC}^ ;Return to caller LTORG ; --- tms__buttons --- ; ; On entry: R1 == pointer to mousepointer info block ; R10 == pointer to the menu ; ; On exit: -- ; ; Use: Called when a button event is detected on a menu, or ; for NULL events (with button type 0) tms__buttons ROUT STMFD R13!,{R0-R9,R14} ;Stack some registers LDR R14,tms__flags ;Get the current flags TST R14,#tFlag__nActive ;Are we active? BNE %99tms__buttons ;No -- return ; --- First we deal with *any* button type --- MOV R9,R1 ;Keep a pointer to the block SUB R13,R13,#36 ;Get a small block MOV R1,R13 ;Point to the block LDR R2,[R10,#hHandle] ;Get the window handle STR R2,[R1,#0] ;Store the window handle SWI Wimp_GetWindowState ;Get the window state MOV R8,R1 ;Remember this pointer LDR R0,[R9,#0] ;Get the mouse x coord LDR R2,[R8,#20] ;Get the scroll x position LDR R3,[R8,#4] ;Get the x0 position ADD R0,R0,R2 ;Calculate workarea relative SUB R0,R0,R3 ;...x position LDR R1,[R9,#4] ;Get the mouse y coord LDR R2,[R8,#24] ;Get the scroll y position LDR R3,[R8,#16] ;Get the y1 position ADD R1,R1,R2 ;Calculate workarea relative SUB R1,R1,R3 ;...y position STMIA R9,{R0,R1} ;Store back updated positions LDR R6,tms__flags ;Get the flags BL tms__findItem ;Find the item we are over CMP R8,#0 ;Did we find an item BEQ %12tms__buttons ;No -- jump ahead a bit LDR R5,[R10,#hTotWidth] ;Get the width SUB R5,R5,#24 ;The right hand edge CMP R0,R5 ;Are we over it? ; --- Complex condition time --- ; ; The following code should only be executed if: ; we're over a sub menu arrow AND we were ; not over it before ; OR ; we are not over a submenu arrow at all AND the ; item isn't the alarm item BIC R6,R6,#tFlag__overArrow ;We are not over an arrow BLT %10tms__buttons ;We cannot be over an arrow LDR R5,tms__itemOver ;Get a pointer to the item LDR R5,[R5,#0] ;Get the item flags MVN R5,R5 ;Invert them! AND R5,R5,#mFlag_subMenu+mFlag_subWarn ; Keep these bits CMP R5,#mFlag_subMenu+mFlag_subWarn ;Is there no arrow? ; Here, EQ if we are not over an arrow, NE otherwise --- BEQ %10tms__buttons ;Jump if we're not over arrow ORR R6,R6,#tFlag__overArrow ;We are over an arrow STR R6,tms__flags ;Store the flags LDR R5,[R10,#hSelected] ;Get the selected item CMP R7,R5 ;Are they the same? BEQ %30tms__buttons ;Yes -- jump this section ; --- Well, the condition has been met at this point --- 10tms__buttons STR R6,tms__flags ;Store the flags LDR R0,tms__alarmItem ;Get item alarm is for CMP R0,R7 ;Are they the same? BEQ %30tms__buttons ;Yes -- jump this section LDR R0,tms__alarmItem ;Get item alarm is for CMP R0,R7 ;Are they the same? BEQ %30tms__buttons ;Yes -- jump this section ; LDR R6,[R10,#hFlags] ;Get the menu flags ; TST R6,#hFlag__tearable ;Is there a bar? ; BEQ %11tms__buttons ;No -- jump ahead ; CMP R1,#-tms__barHeight ;Is it in the bar ; BGE %12tms__buttons ;Yes -- jump past this bit ; --- Close the current RISCOS menu using tearoff support --- 11tms__buttons STMFD R13!,{R0-R1} ;Stack these now MOV R0,#1 ;Switch off SWI vectoring BL tearSupport_switch ;Yes siree bob matey MOV R1,#-1 ;No menu please Mr. Wimp SWI XWimp_CreateMenu ;La de dar do MOVVC R0,#0 ;Switch vectoring back on BLVC tearSupport_switch ;Please LDMFD R13!,{R0-R1} ;Get coords back back ; --- If the menu is torn off, then close transient --- LDR R5,[R10,#hFlags] ;Get the menu flags TST R5,#hFlag__torn ;Has menu been torn off? BEQ %12tms__buttons ;No -- skip ahead LDR R2,tms__current ;Point to current transient CMP R2,#0 ;Is there one? LDREQ R2,tms__currDbox ;No -- load dbox handle BL tms__closeMenu ;Close the menu B %13tms__buttons ;Skip the next bit ; --- If there is already a menu open from here, close it --- 12tms__buttons LDR R5,[R10,#hFlags] ;Get the menu flags TST R5,#hFlag__warned ;Has there been a warning? BEQ %13tms__buttons ;No -- skip ahead LDR R2,[R10,#hSubMenu] ;Get its submenu BL tms__closeMenu ;Close the submenu BIC R5,R5,#hFlag__dbox ;There is no dbox now STR R5,[R10,#hFlags] ;Store the flags back CMP R7,#0 ;Is there an item? LDRNE R6,[R7,#iFlags] ;Yes -- get the menu flags BICNE R6,R6,#iFlag__dbox ;...not a dbox STRNE R6,[R7,#iFlags] ;...store flags back again MOV R2,#0 ;A NULL pointer STR R2,[R10,#hSubMenu] ;No sub menu any more ; --- Cause a fake event if we just closed a dbox --- 13tms__buttons LDR R0,tms__flags ;Load the flags word TST R0,#tFlag__doFake ;Should we do a fake? BNE %90tms__buttons ;Yes -- return to caller ; --- Do the selecting/deselecting --- LDR R5,[R10,#hSelected] ;Get the selected item CMP R7,R5 ;Are they the same? BEQ %15tms__buttons ;Yes -- do nothing here CMP R5,#0 ;Is there a selected item BEQ %14tms__buttons ;No -- skipitty jump LDR R6,[R5,#iFlags] ;Get the flags for this item TST R6,#iFlag__shaded ;Is it shaded? BNE %14tms__buttons ;Yes -- skipitty jump MOV R2,R5 ;Unhighlight this item BL tms__unHighlight ;Unhighlight it then 14tms__buttons MOVS R2,R7 ;Point to the item BLNE tms__highlight ;Yes -- highlight the item STR R2,[R10,#hSelected] ;Store pointer to item ADRL R0,tms__alarm1 ;Remove alarms with this hnd BL idle_removeAllAlarms ;Do it then MOV R0,#-1 ;No alarm set STR R0,tms__alarmItem ;So say that ; --- Do we need to set an alarm? --- 15tms__buttons CMP R7,#0 ;Is there an item? BEQ %20tms__buttons ;No -- don't set an alarm LDR R6,[R7,#iFlags] ;Get the flags word TST R6,#iFlag__arrow ;Are we over an arrow? BEQ %20tms__buttons ;No -- don't set an alarm LDR R0,tms__alarmItem ;Get the current alarm item CMP R0,#-1 ;Is there one? BNE %20tms__buttons ;Yes -- skip ahead BL wimp_version ;Get the wimp version CMP R0,#300 ;Higher than RISC OS 2? BLT %20tms__buttons ;No -- don't do this then ; --- Check with the CMOS setting --- MOV R0,#161 ;Read CMOS MOV R1,#197 ;The wimp flags SWI XOS_Byte ;Read them then TST R2,#&80 ;Is the bit set? BEQ %20tms__buttons ;No -- don't do this then MOV R0,#161 ;Read CMOS MOV R1,#23 ;Read the delay time SWI XOS_Byte ;Read it then CMP R2,#0 ;Is there a sensible time? BEQ %20tms__buttons ;No -- don't do this then ; --- Right, set the alarm --- STR R10,tms__alarmMenu ;Alarm is for this menu STR R7,tms__alarmItem ;And for this item ADD R1,R2,R2,LSL #2 ;Multiply time by 5 MOV R1,R1,LSL #1 ;And then by 2 (10 in all) SWI OS_ReadMonotonicTime ;Read the current time ADD R0,R0,R1 ;Set alarm for this time ADRL R1,tms__alarm1 ;Point to handler function MOV R2,R0 ;Use that as the handle MOV R3,R12 ;Pass workspace in R12 BL idle_setAlarm ;And set the alarm ; --- Correct some 'variables' --- 20tms__buttons LDR R6,[R10,#hFlags] ;Get the menu flags BIC R6,R6,#hFlag__warned ;We haven't been warned BIC R6,R6,#hFlag__dbox ;And there is not a dbox STR R6,[R10,#hFlags] ;Store the flags back again CMP R7,#0 ;Is there an item? MOV R6,#0 ;A NULL pointer STR R6,tms__prevLevel ;No previous level STR R6,tms__orgTearoff ;No originating tearoff ; --- Well, that lots over, no where near finished though --- ; --- Are we over a sub menu arrow? --- 30tms__buttons CMP R7,#0 ;Is there an item? BEQ %40tms__buttons ;No -- deal with real clicks LDR R6,tms__flags ;Get the flags word TST R6,#tFlag__overArrow ;Are we over an arrow? BEQ %40tms__buttons ;No -- skip this bit ; --- The pointer is over an arrow --- MOV R1,R13 ;Point to the window state BL tms__subMenu ;Open the sub menu ; --- Deal with real buttons clicks --- 40tms__buttons LDR R2,[R9,#8] ;Get the button status CMP R2,#0 ;Was a button pressed? BEQ %90tms__buttons ;No -- return ; --- Was the click on the tearoff bar? --- LDR R0,tms__flags ;Get the flags word TST R2,#6 ;Select or menu pressed? ORRNE R0,R0,#tFlag__close ;Yes -- close the transient BICEQ R0,R0,#tFlag__close ;No -- keep it open STR R0,tms__flags ;Store the flags back LDMIA R9,{R0,R1} ;Get the coordiantes LDR R2,[R10,#hFlags] ;Get the menu flags TST R2,#hFlag__tearable ;Is there a bar? BEQ %50tms__buttons ;No -- branch ahead CMP R1,#-tms__barHeight ;Did we click in the bar? BLT %50tms__buttons ;No -- branch ahead CMP R1,#-4 ;The top of the icon BGT %90tms__buttons ;Not in icon -- return CMP R1,#-(tms__barHeight-4) ;The bottom level BLT %90tms__buttons ;Not in icon -- return TST R2,#hFlag__torn ;Has the menu been torn off BNE %45tms__buttons ;Yes -- deal with that ; --- Was the click in the tear icon? --- CMP R0,#4 ;The left hand side BLT %90tms__buttons ;Not in icon -- return CMP R0,#68 ;The right hand side BGT %90tms__buttons ;Not in icon -- return BL tms__tearMenu ;Tear the menu off B %90tms__buttons ;Return to caller ; --- The menu is torn off -- what did we click in? --- 45tms__buttons CMP R0,#4 ;The left hand side BLT %90tms__buttons ;Not in icon -- return CMP R0,#70 ;The right hand side BLLE tms__closeTornMenu ;Tear the menu off BLE %90tms__buttons ;Return to caller ; --- Was it in the fold icon --- 46tms__buttons LDR R2,[R10,#hTotWidth] ;The total menu width SUB R2,R2,#60 ;LHS of tear icon CMP R0,R2 ;Where did we click? BLT %90tms__buttons ;Not in it, that's for sure ADD R2,R2,#56 ;RHS of tear icon CMP R0,R2 ;Where did we click? BGT %90tms__buttons ;Not in it, that's for sure BL tms__foldMenu ;Fold the menu then B %90tms__buttons ;Return to caller ; --- The click was on an item --- 50tms__buttons CMP R7,#0 ;Is there an item here? BEQ %90tms__buttons ;No -- return LDR R0,[R7,#iFlags] ;Get the item flags TST R0,#iFlag__shaded ;Is the item shaded BNE %90tms__buttons ;Yes -- return then MOV R3,#3 ;Flash this many times MOV R0,#19 ;VSync 51tms__buttons SWI OS_Byte ;Wait for it SWI OS_Byte ;Wait for it again MOV R2,R7 ;Point to the item BL tms__unHighlight ;Unhighlight item SWI OS_Byte ;Wait for VSync SWI OS_Byte ;Wait for it again MOV R2,R7 ;Point to the item BL tms__highlight ;Highlight item SUBS R3,R3,#1 ;Decrement counter BNE %51tms__buttons ;Flash more times if needed ; --- Close the menu structure if we need to --- LDR R0,tms__flags ;Get the flags word TST R0,#tFlag__close ;Should I close the menu? LDRNE R2,tms__current ;Yes -- point to current menu BLNE tms__closeMenu ;...and close the transient ; --- Finally, report event to the user --- STMFD R13!,{R10,R12} ;Save these registers MOV R0,#mEvent_select ;Item has been selected LDR R1,tms__itemIndex ;The items index ADD R3,R8,#iHandler ;Point to the handler LDMIA R3,{R3,R10,R12} ;Load the values ADDS R0,R0,#0 ;Clear the carry flag TEQ R3,#0 ;Sanity check MOV R14,PC ;Set up the return address MOVNE PC,R3 ;Call the handler LDMFD R13!,{R10,R12} ;Get my registers back BL tms_recreate ;Recreate the existing menus ; --- Return to the user --- 90tms__buttons ADD R13,R13,#36 ;Reclaim my stack 99tms__buttons LDMFD R13!,{R0-R9,PC}^ ;And return to caller LTORG ; --- tms__cleanUp --- ; ; On entry: R0 == handle idle handler is called with (the menu) ; ; On exit: -- ; ; Use: Called to clean up the system when the pointer has left ; a menu. EXPORT tms__cleanUp tms__cleanUp ROUT STMFD R13!,{R0-R3,R14} ;Stack some registers MOV R2,R0 ;The R10 value ADRL R1,tms__idleHandler ;The routine that is called MOV R0,#0 ;How frequently it was called MOV R3,R12 ;The R12 value passed BL idle_removeHandler ;Remove the handler MOV R0,#0 ;No handler set up STR R0,tms__oldHandle ;Store that fact ADRL R0,tms__alarm1 ;Remove alarms with this hnd BL idle_removeAllAlarms ;Do it then MOV R0,#-1 ;No alarm set STR R0,tms__alarmItem ;So say that BL tms__alarm2 ;Allow item selection LDMFD R13!,{R0-R3,PC}^ ;Return to caller LTORG ; --- tms__updateBar --- ; ; On entry: R10 == pointer to the menu ; ; On exit: -- ; ; Use: Update the tearoff bar of the given menu tms__updateBar ROUT STMFD R13!,{R0-R4,R14} ;Stack some registers SUB R13,R13,#44 ;Get me a block LDR R0,[R10,#hHandle] ;Get the window handle MOV R1,#0 ;x0 LDR R3,[R10,#hTotWidth] ;Get the total width ADD R3,R3,#48 ;x1 MOV R2,#-tms__barHeight ;y0 MOV R4,#0 ;y1 STMIA R13,{R0-R4} ;Fill in the block MOV R1,R13 ;Point to it MOV R4,R2 ;The y coordinate SUB R13,R13,#32 ;Get another block SWI Wimp_UpdateWindow ;Start the redraw 00 CMP R0,#0 ;More to do? BEQ %10tms__updateBar ;No -- return BL tms__redrawBar ;Perform the redrawing SWI Wimp_GetRectangle ;Get another rectangle B %00tms__updateBar ;And keep redrawing 10 ADD R13,R13,#(44+32) ;Get the stack back LDMFD R13!,{R0-R4,PC}^ ;Return to caller LTORG ; --- tms__tearMenu --- ; ; On entry: R10 == pointer to menu to tear off ; ; On exit: -- ; ; Use: Called when the user clicks on the tear icon tms__tearMenu ROUT STMFD R13!,{R0-R2,R4,R14} ;Stack some registers LDR R0,[R10,#hFlags] ;Get the menu flags ORR R0,R0,#hFlag__torn ;The menu is now torn STR R0,[R10,#hFlags] ;Store back the flags LDR R0,[R10,#hPrevMenu] ;Get the previous menu CMP R0,#0 ;Is there one? BLNE tms__deselect ;Yes -- deselect it ; --- Start the drag operaton --- SUB R13,R13,#28 ;Get me a block LDR R0,[R10,#hHandle] ;Get the window handle MOV R1,#1 ;Drag window position STMIA R13,{R0,R1} ;Store them in the block MOV R1,R13 ;Point to the block SWI Wimp_DragBox ;Start the drag ADD R13,R13,#28 ;Get the stack back ; --- Alter the icons on the bar --- BL tms__updateBar ;Update the bar ; --- Add the menu to the list of torn menus --- 10tms__tearMenu LDR R0,tms__tornoffs ;Get the list head STR R0,[R10,#hNextTorn] ;Put pointer in menu header STR R10,tms__tornoffs ;Store this as the head LDR R0,tms__current ;Get the current transient CMP R0,R10 ;Are we tearing it? BNE %15tms__tearMenu ;No -- jump ahead MOV R0,#0 ;A NULL pointer STR R0,tms__current ;No current transient BL tearSupport_closed ;TearoffSupt_Closed ; --- Close the transient if we need to --- 15tms__tearMenu LDR R0,tms__flags ;Get the program flags TST R0,#tFlag__close ;Do we close transients? LDRNE R2,tms__current ;Point to current transient BLNE tms__closeMenu ;And close the transient ; --- Return to the caller --- LDMFD R13!,{R0-R2,R4,PC}^ ;Return to caller LTORG ; --- tms__unTearMenu --- ; ; On entry: R10 == pointer to menu to untear ; ; On exit: -- ; ; Use: 'Un-tears' the give menu. Note that the bar is NOT redrawn tms__unTearMenu ROUT STMFD R13!,{R0-R2,R14} ;Stack some registers LDR R0,tms__tornoffs ;Get the torn off list MOV R1,#0 ;The previous menu 00 CMP R0,R10 ;Is this the menu BEQ %10tms__unTearMenu ;Yes -- deal with it MOV R1,R0 ;This is now the previous LDR R0,[R0,#hNextTorn] ;Get the next in the list CMP R0,#0 ;Is there one? BNE %00tms__unTearMenu ;Yes -- deal with it ; --- Cant find it, werg! --- LDMFD R13!,{R0-R2,PC}^ ;Return to caller ; -- Right, we've found it now --- 10 LDR R2,[R0,#hNextTorn] ;Get the pointer to next CMP R1,#0 ;Is it the first in list? STREQ R2,tms__tornoffs ;Yes -- store next as head STRNE R2,[R1,#hNextTorn] ;No -- store in prev ptr LDR R0,[R10,#hFlags] ;Get the menu flags BIC R0,R0,#hFlag__torn ;We are not torn now STR R0,[R10,#hFlags] ;Store the flags back TST R0,#hFlag__warned ;Have we been warned? BEQ %15tms__unTearMenu ;No -- jump ahead LDR R2,[R10,#hSubMenu] ;Get the sub menu BL tms__closeMenu ;Close it MOV R0,R10 ;Point to my menu BL tms__deselect ;Deselect it ; --- Unfold the menu if we need to --- 15 LDR R0,[R10,#hFlags] ;Get the menu flags TST R0,#hFlag__folded ;Is the menu folded BLNE tms__foldMenu ;Yes -- unfold it LDMFD R13!,{R0-R2,PC}^ ;Return to caller LTORG ; --- tms__closeTornMenu --- ; ; On entry: R10 == pointer to torn off menu to close ; ; On exit: -- ; ; Use: Closes a torn off menu. tms__closeTornMenu ROUT STMFD R13!,{R0-R2,R14} ;Stack some registers BL tms__unTearMenu ;'Un-tear' the menu MOV R2,R10 ;Close this menu BL tms__closeMenu ;Now close the menu LDR R0,tms__flags ;Get the program flags TST R0,#tFlag__close ;Do we close transients? LDRNE R2,tms__current ;Point to current transient BLNE tms__closeMenu ;And close the transient ; --- Return to the caller --- LDMFD R13!,{R0-R2,PC}^ ;Return to caller LTORG ; --- tms__locateMenu --- ; ; On entry: R4 == pointer to menu to find ; ; On exit: R4 preserved if it exists, 0 otherwise ; ; Use: Attempt to find the given menu in the torn off ; list. It is returned in R4 if it is found tms__locateMenu ROUT STMFD R13!,{R14} ;Stack some registers LDR R14,tms__tornoffs ;Get the torn off list CMP R14,#0 ;Are there any BEQ %99tms__locateMenu ;No -- return failure 00 CMP R14,R4 ;Have we found it? LDMEQFD R13!,{PC}^ ;Yes -- return LDR R14,[R14,#hNextTorn] ;Get the next in the list CMP R14,#0 ;Is there one BNE %00tms__locateMenu ;Yes -- try it ; --- We didn't find it --- 99 MOV R4,#0 ;Return failure LDMFD R13!,{PC}^ ;Return to caller LTORG ; --- tms__searchForMenu --- ; ; On entry: R0 == pointer to packed definition ; R1 == pointer to event handler ; R2 == R10 value passed to handler ; R3 == R12 value passed to handler ; ; On exit: C set and R4 points to menu if found, C clear otherwise ; ; Use: Searches the tornoff menus for a menu with characteristics ; matching the search required tms__searchForMenu ROUT BIC R14,R14,#C_flag ;We haven't found it STMFD R13!,{R5-R7,R12,R14} ;Stack some registers WSPACE tms__wSpace ;Locate my workspace LDR R14,tms__tornoffs ;Get the torn off list CMP R14,#0 ;Are there any BEQ %99tms__searchForMenu ;No -- return failure 00 ADD R4,R14,#hHandler ;Point to useful values LDMIA R4,{R4-R7} ;Get them out CMP R0,R7 ;Packed definition the same? CMPEQ R1,R4 ;...and the handler? CMPEQ R2,R5 ;...and R10 value? CMPEQ R3,R6 ;...and R12 value? MOVEQ R4,R14 ;We've found it LDMEQFD R13!,{R5-R7,R12,R14} ;Get back registers ORREQS PC,R14,#C_flag ;And return happy LDR R14,[R14,#hNextTorn] ;Get the next in the list CMP R14,#0 ;Is there one BNE %00tms__searchForMenu ;Yes -- try it ; --- We didn't find it --- 99 MOV R4,#0 ;Return failure LDMFD R13!,{R5-R7,R12,PC}^ ;Return to caller LTORG ; --- tms_closeMenu --- ; ; On entry: R0 == pointer to menu definition ; R1 == pointer to event handler ; R2 == R10 value to look for ; R3 == R12 value to look for ; ; On exit: -- ; ; Use: Searches through the menus which have been torn off for a ; menu which matches the specifications given, and closes ; it if it is found. EXPORT tms_closeMenu tms_closeMenu ROUT STMFD R13!,{R4,R10,R12,R14} ;Stack registers WSPACE tms__wSpace ;Locate my workspace BL tms__searchForMenu ;Try to find the menu MOVCS R10,R4 ;Found it -- put in R10 BLCS tms__closeTornMenu ;And close it LDMFD R13!,{R4,R10,R12,PC}^ ;Return to caller LTORG ; --- tms_closeAll --- ; ; On entry: R0 == R10 value to search for ; ; On exit: -- ; ; Use: Closes all the torn off menus with the given r10 ; value. EXPORT tms_closeAll tms_closeAll ROUT STMFD R13!,{R10,R12,R14} ;Stack registers WSPACE tms__wSpace ;Locate my workspace LDR R10,tms__tornoffs ;Get the torn off list CMP R10,#0 ;Are there any BEQ %90tms_closeAll ;No -- return 00 LDR R14,[R10,#hR10] ;Get the R10 value CMP R0,R14 ;Is R10 value the same? BLEQ tms__closeTornMenu ;Yes -- close that menu LDR R10,[R10,#hNextTorn] ;Get the next in the list CMP R10,#0 ;Is there one BNE %00tms_closeAll ;Yes -- try it 90tms_closeAll LDMFD R13!,{R10,R12,PC}^ ;Return to caller LTORG ; --- tms__foldMenu --- ; ; On entry: R10 == pointer to menu to fold ; ; On exit: -- ; ; Use: Folds or unfolds the menu, as appropriate tms__foldMenu ROUT STMFD R13!,{R0-R5,R14} ;Stack some registers ; --- Get the window state --- SUB R13,R13,#88 ;Get me a block LDR R0,[R10,#hHandle] ;Get the window handle STR R0,[R13,#0] ;Store it in the block MOV R1,R13 ;Point to the block SWI Wimp_GetWindowState ;Get the window state ; --- First, close the current transient menu --- LDR R0,tms__flags ;Get the program flags TST R0,#tFlag__close ;Do we close transients? LDRNE R2,tms__current ;Point to current transient BLNE tms__closeMenu ;And close the transient LDR R0,[R10,#hFlags] ;Get the menu flags EOR R0,R0,#hFlag__folded ;Toggle the foldedness STR R0,[R10,#hFlags] ;Store back modified flags TST R0,#hFlag__folded ;Test that bit now BEQ %50tms__foldMenu ;No longer folded -- jump ; --- We must now fold up the menu --- TST R0,#hFlag__scrBar ;Is there a scroll bar? BEQ %25tms__foldMenu ;No -- do quick fold ADD R1,R10,#hHandle ;Point to the window handle SWI Wimp_CloseWindow ;Close the window SWI Wimp_DeleteWindow ;And then delete it LDR R0,[R10,#hHandle] ;The window handle ADRL R1,tms__eventHandler ;Point to the handler MOV R2,R10 ;The handle passed MOV R3,R12 ;Workspace passed in R3 BL win_removeEventHandler ;Remove the event handler LDR R1,tms__oldHandle ;Get the old handle CMP R0,R1 ;Are they the same? BLEQ tms__cleanUp ;Yes -- clean up a bit LDR R0,[R10,#hHeight] ;Get the menu height BL tms__createWindow ;Create the window MOVVS R1,#1 ;On error -- show 1 icon BLVS errorBox ;...display the error BVS %99tms__foldMenu ;...and return to caller ADRL R1,tms__eventHandler ;Point to the handler MOV R2,R10 ;The handle passed MOV R3,R12 ;Workspace passed in R3 BL win_eventHandler ;Remove the event handler MOV R1,R13 ;Point to window state STR R0,[R1,#0] ;Store in the block LDR R4,[R1,#16] ;Get y1 SUB R0,R4,#24 ;No -- y0-y1-actual height STR R0,[R1,#8] ;Store new y0 BL tspr_adjustBox ;Mangle to fit on the screen SWI Wimp_OpenWindow ;Open the window B %99tms__foldMenu ;Return to caller ; --- The menu has no scrollbar --- 25tms__foldMenu MOV R1,R13 ;Point to state LDR R0,[R1,#16] ;Get y1 SUB R0,R0,#24 ;New y0 value STR R0,[R1,#8] ;Store it in the block SWI Wimp_OpenWindow ;Open the window B %99tms__foldMenu ;And return ; --- The menu must be 'un-folded' --- 50tms__foldMenu BL screen_getInfo ;Get the screen information LDR R1,[R0,#screen_height] ;Get the screen height LDR R2,[R10,#hMaxHeight] ;Get the maximum menu height LDR R3,[R10,#hHeight] ;And the actual menu height ; --- We add a scroll bar if h>maxH or h+50>screen height --- CMP R2,#0 ;Is there a maximum height? BEQ %55tms__foldMenu ;No try next condition CMP R3,R2 ;Is height > maxHeight? BGT %60tms__foldMenu ;Yes -- unfold with scrll bar 55tms__foldMenu ADD R3,R3,#50 ;Add a little to the height CMP R3,R1 ;Compare to the screen height BLE %75tms__foldMenu ;Unfold without scroll bar ; --- Unfold with a scroll bar --- 60tms__foldMenu ADD R1,R10,#hHandle ;Point to the window handle SWI Wimp_CloseWindow ;Close the window SWI Wimp_DeleteWindow ;And then delete it LDR R0,[R10,#hHandle] ;The window handle ADRL R1,tms__eventHandler ;Point to the handler MOV R2,R10 ;The handle passed MOV R3,R12 ;Workspace passed in R3 BL win_removeEventHandler ;Remove the event handler LDR R1,tms__oldHandle ;Get the old handle CMP R0,R1 ;Are they the same? BLEQ tms__cleanUp ;Yes -- clean up a bit LDR R0,[R10,#hHeight] ;Get the menu height BL tms__createWindow ;Create the window MOVVS R1,#1 ;On error -- show 1 icon BLVS errorBox ;...display the error BVS %99tms__foldMenu ;...and return to caller ADRL R1,tms__eventHandler ;Point to the handler MOV R2,R10 ;The handle passed MOV R3,R12 ;Workspace passed in R3 BL win_eventHandler ;Remove the event handler MOV R1,R13 ;Point to window state STR R0,[R1,#0] ;Store in the block LDR R4,[R1,#16] ;Get y1 LDR R3,[R10,#hHeight] ;And actual height LDR R2,[R10,#hMaxHeight] ;Get the maximum height CMP R2,#0 ;Is there one? SUBNE R0,R4,R2 ;Yes -- y0=y1-maxHeight SUBEQ R0,R4,R3 ;No -- y0-y1-actual height STR R0,[R1,#8] ;Store new y0 BL tspr_adjustBox ;Mangle to fit on the screen MOV R14,#-1 ;To open at the front STR R14,[R1,#28] ;We alter the behind value SWI Wimp_OpenWindow ;Open the window B %99tms__foldMenu ;Return to caller ; --- We must unfold without a scroll bar --- 75tms__foldMenu MOV R1,R13 ;Point to state LDR R0,[R1,#16] ;Get y1 LDR R2,[R10,#hHeight] ;Get actual height SUB R0,R0,R2 ;New y0 value STR R0,[R1,#8] ;Store it in the block MOV R14,#-1 ;To open at the front STR R14,[R1,#28] ;We alter the behind value SWI Wimp_OpenWindow ;Open the window 99tms__foldMenu ADD R13,R13,#88 ;Get the block back LDMFD R13!,{R0-R5,PC}^ ;Return to caller ; --- tms__ensureWindowOK --- ; ; On entry: R1 == pointer to window state ; R10 == ponter to the menu ; ; On exit: -- ; ; Use: Called after a mode change, to make sure that the menu still ; fits on the screen, and to make appropriate changes ; if the font has changed, etc. tms__ensureWindowOK ROUT STMFD R13!,{R0-R4,R14} ;Stack some registers LDR R0,[R10,#hFlags] ;Get the menu flags TST R0,#hFlag__folded ;Is the menu folded BNE %98tms__ensureWindowOK ;Yes -- return BL screen_getInfo ;Get the screen info LDR R4,[R0,#screen_height] ;Get screen height LDR R3,[R10,#hHeight] ;Get menu height ADD R3,R3,#50 ;Add 50 for luck LDR R2,[R10,#hFlags] ;Get the menu flags ; --- Check to see if we should remove scroll bar --- TST R2,#hFlag__scrBar ;Is there a scroll bar BEQ %40tms__ensureWindowOK ;No -- jump ahead CMP R3,R4 ;Is actual < screen height? BGT %40tms__ensureWindowOK ;No -- jump ahead LDR R14,[R10,#hMaxHeight] ;Get max height CMP R14,#0 ;Is there one? BEQ %10tms__ensureWindowOK ;No -- remove scroll bar CMP R3,R14 ;Is actual < max height? BGT %40tms__ensureWindowOK ;No -- jump ahead ; --- Remove the scroll bar then --- 10 BL %80tms__ensureWindowOK ;Create a new window LDR R0,[R1,#8] ;Get y0 ADD R0,R0,R3 ;Calculate y1 STR R0,[R1,#16] ;Store it in the block SWI Wimp_OpenWindow ;Open the window B %99tms__ensureWindowOK ;And return to caller ; --- Check if we should add a scroll bar --- 40 TST R2,#hFlag__scrBar ;Is there a scroll bar BNE %98tms__ensureWindowOK ;Yes -- return CMP R3,R4 ;Is actual > screen height? BLT %98tms__ensureWindowOK ;No -- return ; --- Rebuild the window --- 50 BL %80tms__ensureWindowOK ;Create a new window LDR R0,[R1,#4] ;Get old x0 LDR R2,[R10,#hTotWidth] ;Get the menu width ADD R0,R0,R2 ;Calculate x1 STR R0,[R1,#12] ;Store it in the block SWI Wimp_OpenWindow ;Open the window BL tms__width ;Check the width B %99tms__ensureWindowOK ;And return to caller ; --- Create a new window --- 80 STMFD R13!,{R1-R3,R14} ;Save some registers ADD R1,R10,#hHandle ;Point to the window handle SWI Wimp_CloseWindow ;Close the window SWI Wimp_DeleteWindow ;And then delete it LDR R0,[R10,#hHandle] ;The window handle ADRL R1,tms__eventHandler ;Point to the handler MOV R2,R10 ;The handle passed MOV R3,R12 ;Workspace passed in R3 BL win_removeEventHandler ;Remove the event handler LDR R1,tms__oldHandle ;Get the old handle CMP R0,R1 ;Are they the same? BLEQ tms__cleanUp ;Yes -- clean up a bit LDR R0,[R10,#hHeight] ;Get the menu height BL tms__createWindow ;Create the window MOVVS R1,#1 ;On error -- show 1 icon BLVS errorBox ;...display the error BVS %99tms__ensureWindowOK ;...and return to caller ADRL R1,tms__eventHandler ;Point to the handler MOV R2,R10 ;The handle passed MOV R3,R12 ;Workspace passed in R3 BL win_eventHandler ;Remove the event handler LDMFD R13!,{R1-R3,R14} ;Get registers back STR R0,[R1,#0] ;Store in the block MOV R0,#-1 ;The behind value STR R0,[R1,#28] ;Store in the block MOVS PC,R14 ;Return to caller ; --- Return to caller --- 98 MOV R0,#-1 ;Open in front STR R0,[R1,#28] ;Store this fact SWI Wimp_OpenWindow ;Open the window LDR R14,tms__flags ;Get the main flags word TST R14,#tFlag__newFont ;Has the font changed? BL tms__width ;Yes -- check the width 99 LDMFD R13!,{R0-R4,PC}^ ;Return to caller LTORG ; --- tms__idleHandler --- ; ; On entry: R10 == pointer to menu ; ; On exit: -- ; ; Use: Called on NULL events. R10 points to the menu that the ; pointer is currently over tms__idleHandler ROUT STMFD R13!,{R1,R14} ;Stack some registers LDR R1,tms__flags ;Get the flags word TST R1,#tFlag__doFake ;Are we about to fake a NULL? LDMNEFD R13!,{R1,PC}^ ;Yes -- return then TST R1,#tFlag__faking ;Are we fakingone now? BNE %10tms__idleHandler ;Yes -- jump ahead then SUB R13,R13,#20 ;Get a block MOV R1,R13 ;Point to the block SWI Wimp_GetPointerInfo ;Get the pointer position MOV R14,#0 ;Clear the button state STR R14,[R1,#8] ;Put value in the bbits BL tms__buttons ;Call the buttons routine ADD R13,R13,#20 ;Get the stack back LDMFD R13!,{R1,PC}^ ;Return to caller ; --- Clear the 'faking' bit --- 10 BIC R1,R1,#tFlag__faking ;Clear the flag STR R1,tms__flags ;Store the new flags LDMFD R13!,{R1,PC}^ ;Return to caller LTORG ; --- tms__makeDashPattern --- ; ; On entry: -- ; ; On exit: -- ; ; Use: Programs the VDU dot pattern, for sheer prettiness. tms__makeDashPattern ROUT STMFD R13!,{R0-R2,R14} ;Stack some registers MOV R0,#163 ;General OS_Byte MOV R1,#242 ;242 is the only valid value MOV R2,#8 ;Repeat length SWI OS_Byte ;Set dash pattern length ADR R0,tms__dashPtn ;Point to the pattern spec MOV R1,#?tms__dashPtn ;Size of the string SWI OS_WriteN ;Write 'em all to VDU drivers LDMFD R13!,{R0-R2,PC}^ ;Return to caller tms__dashPtn DCB 23,6,&f0,&f0,&f0,&f0,&f0,&f0,&f0,&f0 LTORG ; --- tms__redrawTick --- ; ; On entry: R4 == the y coordinate ; R11 == item flags ; R13 == pointer to a block to use ; ; On exit: -- ; ; Use: Redraw the tick/splodge on the left hand side of a menu tms__redrawTick ROUT STMFD R13!,{R0-R3,R5,R14} ;Stack the link ADD R5,R13,#24 ;Point to the block MOV R0,#0 ;x0 MOV R2,#24 ;x1 SUB R1,R4,#44 ;y0 MOV R3,R4 ;y1 STMIA R5!,{R0-R3} ;Store this in the block LDR R0,=&07000038 ;Icon flags so far TST R11,#iFlag__ticked ;Is there a tick TSTEQ R11,#iFlag__radio ;Or a splodge? MOVEQ R1,#&20 ;Neither -- plot nothing BEQ %00tms__redrawTick ;And plot it TST R11,#iFlag__shaded ;Is the item shaded? ORRNE R0,R0,#&00400000 ;Yes -- shade icon TST R11,#iFlag__ticked ;Are we plotting a tick? MOVEQ R1,#&8F ;Nope -- must be a splodge BEQ %00tms__redrawTick ;And plot it LDR R1,tms__flags ;Get the flags word TST R1,#tFlag__riscos3 ;Is this RISC OS 3? BNE %01tms__redrawTick ;Yes -- jump a bit MOV R1,#&80 ;No -- plot a tick 00 ORR R0,R0,#1 ;Text icon STMIA R5,{R0,R1} ;Fill in the rest of block B %02tms__redrawTick ;And jump this bit ; --- Plot tick RISCOS 3 style --- 01 MOV R2,#1 ;Point R2 at it ORR R0,R0,#&100 ;Indirected icon ORR R0,R0,#&2 ;Sprite icon ADR R1,tms__sprTickName ;Point to the sprite name MOV R3,#2 ;The buffer length STMIA R5,{R0-R3} ;Fill in the rest of block 02 ADD R1,R13,#24 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon LDMFD R13!,{R0-R3,R5,PC}^ ;Return to caller LTORG tms__sprTickName DCB &80,0 EXPORT tms__wSpace tms__wSpace DCD 0 ; --- tms__redrawSprite --- ; ; On entry: R4 == the y coordinate ; R11 == item flags ; R13 == pointer to a block to use ; ; On exit: -- ; ; Use: Redraw the tick/splodge on the left hand side of a menu tms__redrawSprite ROUT STMFD R13!,{R0-R3,R5,R14} ;Stack the link ADD R5,R13,#24 ;Point to the block MOV R0,#24+8 ;x0 LDR R2,[R10,#hSprWidth] ;Get maximum sprite width ADD R2,R2,R0 ;Add on to get x1 SUB R1,R4,#44 ;y0 MOV R3,R4 ;y1 STMIA R5!,{R0-R3} ;Store this in the block LDR R0,=&07000112 ;Icon flags so far TST R11,#iFlag__sprite ;Is there a sprite? BICEQ R0,R0,#2 ;No -- plot no sprite then TST R11,#iFlag__shaded ;Is the item shaded? ORRNE R0,R0,#&00400000 ;Yes -- shade icon TST R11,#iFlag__halfSize ;Is it a small one? ORRNE R0,R0,#&00000800 ;Yes -- set the half-size bit STR R0,[R5],#4 ;Stash the flags away LDR R0,[R7,#iSprName] ;Find the sprite name string LDR R1,[R7,#iSprArea] ;Get the sprite area too MOV R2,#1 ;Not a number, it's a name STMIA R5!,{R0-R2} ;Stash the data away too 02 ADD R1,R13,#24 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon LDMFD R13!,{R0-R3,R5,PC}^ ;Return to caller LTORG ; --- tms__redrawText --- ; ; On entry: R4 == the y coordinate ; R7 == pointer to the icon ; R10 == the menu pointer ; R11 == item flags ; R13 == pointer to a block to use ; ; On exit: -- ; ; Use: Redraw the text part of the menu tms__redrawText ROUT STMFD R13!,{R0-R3,R14} ;Stack the link ADD R14,R13,#20 ;Point to the block ; --- Plot a dirty great bar across the item --- MOV R0,#24 ;x0 LDR R2,[R10,#hTotWidth] ;The menu width SUB R2,R2,#24 ;Calculate x1 SUB R1,R4,#44 ;y0 MOV R3,R4 ;y1 STMIA R14!,{R0-R3} ;Store this in the block LDR R0,=&07000030 ;Get some base flags TST R11,#iFlag__shaded ;Is the item shaded? ORRNE R0,R0,#&00400000 ;Yes -- set the shaded bitty LDREQ R2,[R10,#hSelected] ;Get the selected item CMPEQ R7,R2 ;Is it this item? EOREQ R0,R0,#&77000000 ;Yes -- invert it then STR R0,[R14],#4 ;Save these flags away ADD R1,R13,#20 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon ; --- Now plot the text transparently over this --- LDR R14,[R10,#hSprWidth] ;Load sprite column width ADD R14,R14,#24 ;Bump in a little STR R14,[R1,#0] ;Save as the x0 position LDR R0,=&07000131 ;The icon flags TST R11,#iFlag__shaded ;Is the item shaded? ORRNE R0,R0,#&00400000 ;Yes -- shade icon LDREQ R2,[R10,#hSelected] ;Get the selected item CMPEQ R7,R2 ;Is it this item? EOREQ R0,R0,#&77000000 ;No -- use these colours LDR R1,[R7,#iText] ;Point to the text MOV R2,#-1 ;No validation string MOV R3,#&ff ;Buffer length ADD R14,R13,#36 ;Point to the right bit STMIA R14,{R0-R3} ;Fill in the rest of block ADD R1,R13,#20 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon LDMFD R13!,{R0-R3,PC}^ ;Return to caller LTORG ; --- tms__redrawKey --- ; ; On entry: R4 == the y coordinate ; R7 == pointer to the icon ; R10 == the menu pointer ; R11 == item flags ; R13 == pointer to a block to use ; ; On exit: -- ; ; Use: Redraw the text part of the menu tms__redrawKey ROUT STMFD R13!,{R0-R3,R5,R11,R14} ;Stack the link ADD R5,R13,#28 ;Point to the block LDR R2,[R7,#iKeyCode] ;Get the string to print CMP R2,#-1 ;Is there one? BEQ %99tms__redrawKey ;No -- return LDR R2,[R10,#hTotWidth] ;The menu width LDR R0,[R10,#hKeyWidth] ;Get the shortcut width SUB R2,R2,#24 ;Calculate x1 SUB R0,R2,R0 ;And then x0 SUB R1,R4,#44 ;y0 MOV R3,R4 ;y1 STMIA R5!,{R0-R3} ;Store this in the block LDR R3,=&00000131 ;The icon flags TST R11,#iFlag__shaded ;Is the item shaded? ORRNE R3,R3,#&007400000 ;Yes -- shade icon BNE %00tms__redrawKey ;...forget this next bit LDR R2,[R10,#hSelected] ;Get the selected item CMP R7,R2 ;Is it this item? ORRNE R3,R3,#&07000000 ;No -- use these colours ORREQ R3,R3,#&70000000 ;Yep -- use these colours 00 LDR R0,[R7,#iKeyCode] ;Point to the text MOV R1,#1 ;Covert to a short string LDR R11,tms__R11 ;Get scratchpad address BL keyString ;Do the conversion MOV R1,R0 ;Put string in R1 MOV R0,R3 ;And flags in R0 MOV R2,#-1 ;No validation string MOV R3,#&ff ;Buffer length STMIA R5,{R0-R3} ;Fill in the rest of block ADD R1,R13,#28 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon 99 LDMFD R13!,{R0-R3,R5,R11,PC}^ ;Return to caller LTORG ; --- tms__redrawArrow --- ; ; On entry: R4 == the y coordinate ; R10 == pointer to the menu ; R11 == item flags ; R13 == pointer to a block to use ; ; On exit: -- ; ; Use: Redraw the arrow on the right hand side of a menu tms__redrawArrow ROUT TST R11,#iFlag__arrow ;Is there an arrow? MOVEQS PC,R14 ;No -- return STMFD R13!,{R0-R3,R5,R14} ;Stack the link ADD R5,R13,#24 ;Point to the block LDR R2,[R10,#hTotWidth] ;x1 SUB R0,R2,#24 ;x0 SUB R1,R4,#44 ;y0 MOV R3,R4 ;y1 STMIA R5!,{R0-R3} ;Store this in the block LDR R0,=&07000038 ;Icon flags so far TST R11,#iFlag__shaded ;Is the item shaded? ORRNE R0,R0,#&00400000 ;Yes -- shade icon LDR R1,tms__flags ;Get the flags word TST R1,#tFlag__riscos3 ;Is this RISC OS 3? BNE %01tms__redrawArrow ;Yes -- jump a bit MOV R1,#&89 ;No -- plot a tick ORR R0,R0,#1 ;Text icon STMIA R5,{R0,R1} ;Fill in the rest of block B %02tms__redrawArrow ;And jump this bit ; --- Plot tick RISCOS 3 style --- 01 MOV R2,#1 ;The WIMP area ORR R0,R0,#&100 ;Indirected icon ORR R0,R0,#&2 ;Sprite icon ADR R1,tms__sprArrowName ;Point to the sprite name MOV R3,#2 ;The buffer length STMIA R5,{R0-R3} ;Fill in the rest of block 02 ADD R1,R13,#24 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon LDMFD R13!,{R0-R3,R5,PC}^ ;Return to caller LTORG tms__sprArrowName DCB &89,0 ; --- tms__redrawBar --- ; ; On entry: R4 == the y coordinate ; R10 == the menu pointer ; R13 == pointer to a block to use ; ; On exit: -- ; ; Use: Redraw the tearoff bar in a menu. Notice that this is ; different to the steel version, which uses icons here tms__redrawBar ROUT STMFD R13!,{R0-R3,R5,R14} ;Stack the link ADD R5,R13,#24 ;Point to the block MOV R0,#0 ;x0 LDR R2,[R10,#hTotWidth] ;x1 MOV R1,R4 ;y0 MOV R3,#0 ;y1 STMIA R5!,{R0-R3} ;Store this in the block LDR R14,[R10,#hFlags] ;Get the menu flags LDR R0,=&07000031 ;The icon flags TST R14,#hFlag__global ;Is this a `global' menu? ORREQ R0,R0,#&30000000 ;No -- grey bar then ORRNE R0,R0,#&80000000 ;Yes -- blie bar then MOV R1,#0 ;No text STMIA R5,{R0-R1} ;Fill in the rest of block ADD R1,R13,#24 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon LDR R5,[R10,#hFlags] ;Get the menu flags TST R5,#hFlag__torn ;Has menu been torn? BNE %50tms__redrawBar ;Yes -- draw that bit ; --- Draw just the tear icon --- ADD R5,R13,#24 ;Point to the block MOV R0,#4 ;x0 MOV R2,#68 ;x1 MOV R1,#-20 ;y0 MOV R3,#-4 ;y1 STMIA R5!,{R0-R3} ;Store this in the block LDR R0,=&00000112 ;The icon flags MOV R1,R0 ;Hark -- R0 to be corrupted BL resspr_area ;Get the sprite area MOV R2,R0 ;Point R2 at it MOV R0,R1 ;Get flags back in R0 ADR R1,tms__sprTearName ;Point to the sprite name MOV R3,#5 ;The buffer length STMIA R5,{R0-R3} ;Fill in the rest of block ADD R1,R13,#24 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon LDMFD R13!,{R0-R3,R5,PC}^ ;Return to caller ; --- Plot the icons in a torn menu --- 50 ADD R5,R13,#24 ;Point to the block MOV R0,#4 ;x0 MOV R2,#70 ;x1 MOV R1,#-20 ;y0 MOV R3,#-4 ;y1 STMIA R5!,{R0-R3} ;Store this in the block LDR R0,=&00000112 ;The icon flags MOV R1,R0 ;Hark -- R0 to be corrupted BL resspr_area ;Get the sprite area MOV R2,R0 ;Point R2 at it MOV R0,R1 ;Get flags back in R0 ADR R1,tms__sprCloseName ;Point to the sprite name MOV R3,#6 ;The buffer length STMIA R5,{R0-R3} ;Fill in the rest of block ADD R1,R13,#24 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon ADD R5,R13,#24 ;Point to the block LDR R2,[R10,#hTotWidth] ;Get the width SUB R0,R2,#60 ;x0 SUB R2,R2,#4 ;x1 MOV R1,#-20 ;y0 MOV R3,#-4 ;y1 STMIA R5!,{R0-R3} ;Store this in the block LDR R0,=&00000112 ;The icon flags MOV R1,R0 ;Hark -- R0 to be corrupted BL resspr_area ;Get the sprite area MOV R2,R0 ;Point R2 at it MOV R0,R1 ;Get flags back in R0 ADR R1,tms__sprFoldName ;Point to the sprite name MOV R3,#6 ;The buffer length STMIA R5,{R0-R3} ;Fill in the rest of block ADD R1,R13,#24 ;Point to the block SWI Wimp_PlotIcon ;Plot the icon LDMFD R13!,{R0-R3,R5,PC}^ ;Return to caller LTORG tms__sprTearName DCB "tear",0 tms__sprCloseName DCB "close",0 tms__sprFoldName DCB "fold",0 ; --- tms__doRedraw --- ; ; On entry: R0 == flags: ; bit 0 == don't only plot queued items ; R1 == pointer to the redraw block ; ; On exit: -- ; ; Use: Actually redraws a menu, given the redraw block tms__doRedraw ROUT STMFD R13!,{R0-R11,R14} ;Stack some registers MOV R3,R0 ;Keep flags safe nicely ; --- Set up some pointers --- SUB R13,R13,#32 ;Get a nice block MOV R6,R1 ;Remember the redraw block LDR R5,[R10,#hFlags] ;Get the flags word MOV R4,#0 ;The y coordinate TST R5,#hFlag__tearable ;Is there a tearoff bar? SUBNE R4,R4,#tms__barHeight ;Yes -- Allow for it ; --- Draw the tearoff bar --- TSTNE R3,#1 ;Does it need redrawing? BLNE tms__redrawBar ;Yeap... ; --- Now deal with items --- LDR R9,[R10,#hItems] ;Point to the first item 00tms__doRedraw LDR R8,[R9,#iNumber] ;Get the number of items ADD R7,R9,#iHdrSize ;And point to the first item ; --- Now redraw each item --- 01tms__doRedraw LDR R11,[R7,#iFlags] ;Get the item flags TST R3,#1 ;Are we only doing queued? ORRNE R11,R11,#&FF000000 ;No -- pretend it wa queued ; --- Redraw the tick/splodge on the left --- TST R11,#iFlag__newTick ;Has the tick changed? BLNE tms__redrawTick ;Yes -- plot the tick thing ; --- Plot the main text part --- 09tms__doRedraw TST R11,#iFlag__newText ;Has the text changed? BLNE tms__redrawText ;Yes -- redraw the text bit ; --- Now the sprite, if there is one --- 08tms__doRedraw TST R11,#iFlag__newSpr ;Does sprite need rendering? BLNE tms__redrawSprite ;Yes -- render it then ; --- The keyboard shortcut --- TST R11,#iFlag__newKey ;Has shortcut changed? BLNE tms__redrawKey ;Yes -- redraw it then ; --- The arrow --- TST R11,#iFlag__newArrow ;Has the arrow changed? BLNE tms__redrawArrow ;Yes -- draw it then ; --- And finally, plot the dotted line --- TST R11,#iFlag__dotted ;Is there a dotted line here? BEQ %90tms__doRedraw ;No -- jump this code then MOV R0,#4 ;Move cursor LDR R1,[R6,#4] ;To r.box->x0 LDR R2,[R6,#16] ;r.box->y1 ADD R2,R2,R4 ;r.box->y1+y SUB R2,R2,#56 ;r.box->y1+y-(44+12) LDR R14,[R6,#24] ;Don't neglect scroll offset SUB R2,R2,R14 ;No way bob... SWI OS_Plot ;Do the move BL tms__makeDashPattern ;Program the dash pattern MOV R0,#7 ;Colour 7 SWI Wimp_SetColour ;Thus let it be MOV R0,#17 ;Dotted line -- both ends LDR R1,[R10,#hTotWidth] ;Get the width to draw MOV R2,#0 ;Relative y offset SWI OS_Plot ;Plot the line ; --- Alter the y coordinate --- 90tms__doRedraw TST R11,#iFlag__dotted ;Is there a dotted line SUBNE R4,R4,#68 ;Yes -- take into account SUBEQ R4,R4,#44 ;No -- just sub item height ; --- Do next item --- SUBS R8,R8,#1 ;Decrement item count ADDNE R7,R7,#iItemSize ;Point to the next item BNE %01tms__doRedraw ;...and redraw it LDR R9,[R9,#iItems] ;If at end -- point to next CMP R9,#0 ;Any more items? BNE %00tms__doRedraw ;Yes -- redraw them ADD R13,R13,#32 ;Get my block back LDMFD R13!,{R0-R11,PC}^ ;Return to caller LTORG ; --- tms__redraw --- ; ; On entry: R0 == event from wimp ; R1 == pointer to the wimp block ; R10 == pointer to the menu ; ; On exit: -- ; ; Use: Called to perform the redraw loop when redrawing a menu tms__redraw ROUT STMFD R13!,{R0,R1,R14} ;Stack some registers SWI Wimp_RedrawWindow ;Start the redraw 00tms__redraw CMP R0,#0 ;More to do? LDMEQFD R13!,{R0,R1,PC}^ ;No -- return MOV R0,#1 ;Redraw everything please BL tms__doRedraw ;Perform the redrawing SWI Wimp_GetRectangle ;Get another rectangle B %00tms__redraw ;And keep redrawing LTORG ; --- tms__update --- ; ; On entry: R0 == flags (as for doRedraw) ; R10 == pointer to the menu ; ; On exit: -- ; ; Use: Updates the entire menu. EXPORT tms__update tms__update ROUT STMFD R13!,{R0-R3,R14} ;Stack some registers LDR R14,[R10,#hHandle] ;Load the window handle STR R14,[R13,#-44]! ;Create a block MOV R0,#0 ;Minimum x coord LDR R1,[R10,#hHeight] ;Load out the height RSB R1,R1,#0 ;Minimum y coordinate LDR R2,[R10,#hTotWidth] ;Get the total width MOV R3,#0 ;Maximum y coordinate STMIB R13,{R0-R3} ;Store in the block MOV R1,R13 ;Point to the block SWI Wimp_UpdateWindow ;Start the redraw 00tms__update CMP R0,#0 ;More to do? ADDEQ R13,R13,#44 ;No -- get stack back LDMEQFD R13!,{R0-R3,PC}^ ;...and return LDR R0,[R13,#44] ;Load the caller's flags BL tms__doRedraw ;Perform the redrawing SWI Wimp_GetRectangle ;Get another rectangle B %00tms__update ;And keep redrawing LTORG ; --- tms__eventHandler --- ; ; On entry: R0 == event, as returned from Wimp_Poll ; R1 == pointer to the event block ; R10 == pointer to the menu ; ; On exit: -- ; ; Use: Deals with the event that has been sent to my window EXPORT tms__eventHandler tms__eventHandler ROUT ORR R14,R14,#C_flag ;Set carry flag on return CMP R0,#8 ;Is it a low-numbered event? ADDLE PC,PC,R0,LSL #2 ;Yes -- dispatch B %00tms__eventHandler ;No -- handle specially ; --- The event dispatch table --- BICS PC,R14,#C_flag ;Null events are ignored B tms__redraw ;Call this to redraw menu B %10tms__eventHandler ;Open unopened windows B %20tms__eventHandler ;Close unclosed windows B %30tms__eventHandler ;Pointer's left a window B %40tms__eventHandler ;Gone back inside again B tms__buttons ;Call the button handler BICS PC,R14,#C_flag ;Drag returned -- so what BICS PC,R14,#C_flag ;Key press ; --- Handle high-numbered events --- 00 CMP R0,#17 ;Is it a message? CMPNE R0,#18 ;Or another message? BICNES PC,R14,#C_flag ;No -- nothing we can do ; --- Deal with a help message --- STMFD R13!,{R0-R4,R14} ;Stack registers LDR R14,[R1,#16] ;Get the message number LDR R2,=&502 ;Load the constant number CMP R14,R2 ;Is it a help message LDMNEFD R13!,{R0-R3,R14} ;No -- load registers BICNES PC,R14,#C_flag ;...couldn't understand ; --- Find the item that we are over --- ADD R4,R1,#20 ;Point to the coordinates SUB R13,R13,#36 ;Get a small block MOV R1,R13 ;Point to the block LDR R2,[R10,#hHandle] ;Get the window handle STR R2,[R1,#0] ;Store the window handle SWI Wimp_GetWindowState ;Get the window state LDR R0,[R4,#0] ;Get the mouse x coord LDR R2,[R13,#20] ;Get the scroll x position LDR R3,[R13,#4] ;Get the x0 position ADD R0,R0,R2 ;Calculate workarea relative SUB R0,R0,R3 ;...x position LDR R1,[R4,#4] ;Get the mouse y coord LDR R2,[R13,#24] ;Get the scroll y position LDR R3,[R13,#16] ;Get the y1 position ADD R1,R1,R2 ;Calculate workarea relative SUB R1,R1,R3 ;...y position ADD R13,R13,#36 ;Get the block back STMFD R13!,{R0,R1} ;Stack the coordinates BL tms__findItem ;Find the associated icon CMP R8,#0 ;Were we over an item? BEQ %05tms__eventHandler ;No -- try the tearoff bar ; --- Send the help event to the users handler --- STMFD R13!,{R10,R12} ;Save these registers MOV R0,#mEvent_help ;Help on item required LDR R1,tms__itemIndex ;The items index LDR R2,tms__itemOver ;Point to packed item def. ADD R3,R8,#iHandler ;Point to the handler LDMIA R3,{R3,R10,R12} ;Load the values TEQ R3,#0 ;Sanity check MOV R14,PC ;Set up the return address MOVNE PC,R3 ;Call the handler LDMFD R13!,{R10,R12} ;Get my registers back ADD R13,R13,#8 ;Skip over the coordinates B %09tms__eventHandler ;And return ; --- Was the click on the tearoff bar? --- 05 LDR R0,tms__flags ;Get the flags word LDMFD R13!,{R0,R1} ;Get the coordiantes LDR R2,[R10,#hFlags] ;Get the menu flags TST R2,#hFlag__tearable ;Is there a bar? BEQ %09tms__eventHandler ;No -- branch ahead CMP R1,#-tms__barHeight ;Did we click in the bar? BLT %09tms__eventHandler ;No -- branch ahead CMP R1,#-4 ;The top of the icon BGT %09tms__eventHandler ;Not in icon -- return CMP R1,#-(tms__barHeight-4) ;The bottom level BLT %09tms__eventHandler ;Not in icon -- return TST R2,#hFlag__torn ;Has the menu been torn off BNE %06tms__eventHandler ;Yes -- deal with that ; --- Was the click in the tear icon? --- CMP R0,#4 ;The left hand side BLT %09tms__eventHandler ;Not in icon -- return CMP R0,#68 ;The right hand side BGT %09tms__eventHandler ;Not in icon -- return ADRL R0,tms__helpTear ;Point to the tear message BL msgs_lookup ;Look it up in messages file BL help_add ;And send it to help B %09tms__eventHandler ;Return to caller ; --- The menu is torn off -- what did we click in? --- 06 CMP R0,#4 ;The left hand side BLT %09tms__eventHandler ;Not in icon -- return CMP R0,#70 ;The right hand side ADRLEL R0,tms__helpClose ;Point to the close message BLLE msgs_lookup ;Look it up in messages file BLLE help_add ;And send it to help BLE %09tms__eventHandler ;Return to caller ; --- Was it in the fold icon --- 07 LDR R2,[R10,#hTotWidth] ;The total menu width SUB R2,R2,#60 ;LHS of tear icon CMP R0,R2 ;Where did we click? BLT %09tms__eventHandler ;Not in it, that's for sure ADD R2,R2,#56 ;RHS of tear icon CMP R0,R2 ;Where did we click? ADRLEL R0,tms__helpFold ;Point to the fold message BLLE msgs_lookup ;Look it up in messages file BLLE help_add ;And send it to help 09 LDMFD R13!,{R0-R4,R14} ;Load back registers ORRS PC,R14,#C_flag ;Return with carry set ; --- OpenWindow request --- 10 STMFD R13!,{R14} ;Stack some registers BL screen_justChangedMode ;Has there been a mode change SWICC Wimp_OpenWindow ;No -- open the window LDMCCFD R13!,{PC}^ ;...and return to caller STMFD R13!,{R0-R3} ;Stack some more registers BL tms__ensureWindowOK ;Ensure window is OK SUB R13,R13,#20 ;Get me a block MOV R1,R13 ;Point to it SWI Wimp_GetPointerInfo ;Get the pointer information LDR R0,[R1,#12] ;Get the window ptr is over LDR R1,[R10,#hHandle] ;And window handle of menu CMP R0,R1 ;Are they the same? BNE %15tms__eventHandler ;No -- return LDR R0,tms__oldHandle ;Get the idle handler handle CMP R0,#0 ;Is there one? BNE %15tms__eventHandler ;Yes -- return MOV R0,#0 ;Frequency -- quick please ADRL R1,tms__idleHandler ;Point to the handler MOV R2,R10 ;Pass menu in R10 MOV R3,R12 ;And workspace in R12 BL idle_handler ;Add in the handler STR R10,tms__oldHandle ;And store away new handle 15 ADD R13,R13,#20 ;Get the stack back LDMFD R13!,{R0-R3,PC}^ ;Return to caller ; --- CloseWindow request --- 20 SWI Wimp_CloseWindow ;Close the window MOVS PC,R14 ;And return ; --- Pointer leaving --- 30 STMFD R13!,{R0,R2,R10,R14} ;Stack some registers LDR R0,tms__oldHandle ;Is there an idle handle hnd CMP R0,#0 ;Is there one? LDMEQFD R13!,{R0,R2,R10,PC}^ ;No -- return BL tms__cleanUp ;Yes -- clean up a bit MOV R10,R0 ;Point to the menu LDR R2,[R10,#hFlags] ;Get the flags for the menu TST R2,#hFlag__warned ;Have we be warned? LDMNEFD R13!,{R0,R2,R10,PC}^ ;Yes -- return LDR R2,[R0,#hSelected] ;Point to the selected item CMP R2,#0 ;Is there one? BLNE tms__unHighlight ;Un-highlight the item LDMFD R13!,{R0,R2,R10,PC}^ ;And return to caller ; --- Pointer entering --- 40 STMFD R13!,{R0-R3,R14} ;Stack some registers LDR R0,tms__oldHandle ;Is there an idle handle hnd CMP R0,#0 ;Is there one? BLNE tms__cleanUp ;Yes -- clean up a bit MOV R0,#0 ;Frequency -- quick please ADRL R1,tms__idleHandler ;Point to the handler MOV R2,R10 ;Pass menu in R10 MOV R3,R12 ;And workspace in R12 BL idle_handler ;Add in the handler STR R2,tms__oldHandle ;We have an idle handler BL tms__alarm2 ;Allow item selection LDMFD R13!,{R0-R3,PC}^ ;And return to caller tms__helpTear DCB "TMST",0 tms__helpClose DCB "TMSC",0 tms__helpFold DCB "TMSF",0 LTORG ; --- tms_help --- ; ; On entry: R0 == pointer to base message tag ; R1 == index of menu item ; ; On exit: -- ; ; Use: Adds a string to the help message found by adding the menu ; item number to the base message tag. EXPORT tms_help tms_help ROUT CMP R1,#0 ;Is the menu item sane? MOVLTS PC,R14 ;No -- don't trust Tim STMFD R13!,{R0-R2,R14} ;Save some registers MOV R1,R0 ;Point to base message tag MOV R0,R11 ;Point to scratchpad BL str_cpy ;Add the string in there MOV R1,R0 ;Point to terminating null MOV R2,#25 ;Should be 25 bytes left over LDR R0,[R13,#4] ;Get his item number SWI OS_ConvertInteger4 ;Tack it on the end MOV R0,R11 ;Point to the message tag BL msgs_lookup ;Translate it nicely BL help_add ;Add it to the help string LDMFD R13!,{R0-R2,PC}^ ;Return to caller LTORG ;----- Workspace ------------------------------------------------------------ AREA |Sapphire$$LibData|,CODE,READONLY DCD tms__wSize ;Workspace size DCD tms__wSpace ;Workspace pointer DCD 0 ;Scratchpad size DCD tms_init ;Initialisation ;----- That's all, folks ---------------------------------------------------- END