4 ; Draws pretty 3D boxes
9 ;----- Licensing note -------------------------------------------------------
11 ; This file is part of Straylight's Sculptrix.
13 ; Sculptrix is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
18 ; Sculptrix is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sculptrix. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 ;----- Change history -------------------------------------------------------
31 ; 1.00 MDW Initial version written
33 ; 1.01 MDW Added support for group boxes
34 ; Fixed validation string parser -- will now search
35 ; all `X' commands instead of just the first one
37 ; 1.02 MDW Fixed problem with multiple unslab ops in one poll
39 ; 1.03 MDW Stopped excessive redrawing in group box rendering
41 ; 1.04 MDW Done strange things to make text+sprite icons nice
42 ; Any contortions required are due solely to TMA.
44 ; 1.05 MDW Filled in group box types 0 and 2 (ridge'n'plinth)
46 ; 1.06 MDW Allowed user-changing of the 3D colours and things
47 ; Also included different colours for shaded borders
49 ; 1.07 MDW Fixed bug in Sculptrix_SlabIcon, which corrupted R0
50 ; on exit. Nothing has been affected by this, but we
51 ; may as well get it right.
53 ; 1.08 MDW Made colour change before toggling slab on slab ops
54 ; Integrated colour change with toggle slab, now
55 ; box_toggle does all Sculptrix_DoSlab needs to, so
56 ; renamed box_toggle as swi_doslab. Module therefore
59 ; 1.09 TMA Added type 7 border -- a writable type with its own
60 ; black border. Less flickery than a Wimp type,
61 ; however, the border is always 4 OS units.
63 ; MDW Fixed writable border being black when it gets shaded
65 ; 1.10 MDW Made writable border read colours from icon, and fill
66 ; the whole icon with the background colour, rather
67 ; than just the outside. Basically, rewrote the
68 ; border 7 rendering code.
70 ; 1.11 MDW Fixed Sculptrix_SetSpriteArea bug -- I `found' my
71 ; workspace twice. Ooops.
72 ; MDW Changed to use new Acorn-allocated SWI chunk number
74 ; 1.12 MDW Improved shaded-icon checking to avoid branch.
75 ; Added 10cs delay to unslab with window open in line
76 ; with STASIS requirements.
78 ; 1.13 MDW Fixed bug in mitre start position -- inserted RSB
79 ; to make it go in the right direction.
81 ; 1.14 MDW Removed filling in groupbox type 0 to allow dbx
82 ; controls to be within group boxes.
84 ; 1.15 MDW Modified rendering of `xs' icons to match new STEEL
85 ; and Sapphire icon shading habits. Added a 256-byte
86 ; static buffer for group titles, to avoid dynamic
87 ; allocation in mid-redraw, Changed lots of signed
88 ; compares to unsigned, which removes some redundancy.
89 ; Fixed text+sprite handling to look in Wimp area
90 ; if not in user area. Added messages support. Added
91 ; border type 8 for partitions that fade properly
92 ; (suggested by Alex Thoukydides).
94 ;----- Standard header ------------------------------------------------------
102 ;----- PLOT code numbers ----------------------------------------------------
115 ;----- VDU variable numbers -------------------------------------------------
120 ;----- Module header --------------------------------------------------------
122 AREA |!!!Module$$Header|,CODE,READONLY
124 DCD 0 ;Module start code
125 DCD s_init ;Initialisation
126 DCD s_die ;Finalisation
127 DCD s_service ;Service call
128 DCD s_title ;Module title string
129 DCD s_help ;Module help string
130 DCD s_command ;Command table
131 DCD &4A2C0 ;SWI chunk (temporary)
132 DCD s_swic ;SWI handling
133 DCD s_swin ;SWI names table
134 DCD 0 ;SWI names code
136 ;----- Module strings -------------------------------------------------------
138 s_title DCB "Sculptrix",0
140 ;----- SWI name table -------------------------------------------------------
142 s_swin DCB "Sculptrix",0
151 DCB "SetSpriteArea",0
157 ;----- Command table --------------------------------------------------------
159 s_command DCB "Sculptrix_Colours",0
165 DCB "Sculptrix_GroupType",0
173 ;----- Initialisation and finalisation --------------------------------------
177 STMFD R13!,{R14} ;Stack link register nicely
179 ; --- Get some workspace ---
181 MOV R0,#6 ;Allocate workspace
182 MOV R3,#s_wsize ;Make it *this* big
183 SWI XOS_Module ;Get me memory
184 LDMVSFD R13!,{PC} ;Return if it barfed
185 STR R2,[R12] ;Stash the workspace pointer
186 MOV R12,R2 ;Move the pointer across
188 ; --- Set initial values ---
190 BL vdu_set ;Set up the graphics vars
191 MOV R0,#0 ;Initial flags setting
192 STR R0,s_flags ;Store in the flags word
193 MOV R0,#1 ;Start using WIMP area
194 STR R0,s_sarea ;Store in sprite area word
195 MOV R0,#&0400 ;Default colours
196 ORR R0,R0,R0,LSL #16 ;Propagate to top half
197 MOV R1,#&0200 ;Default colours
198 ORR R1,R1,R1,LSL #16 ;Propagate to top half
204 ; --- I think that's it ---
206 LDMFD R13!,{PC}^ ;Return to caller happy
213 MOV R11,R12 ;Keep the private word ptr
214 LDR R12,[R12] ;Find my workspace
216 ; --- Free my workspace ---
218 MOV R0,#7 ;Free RMA space
219 MOV R2,R12 ;Point to workspace
220 SWI XOS_Module ;Try to free the memory
221 MOV R0,#0 ;Gonna zero the private word
222 STR R0,[R11] ;Then zero it
223 LDMFD R13!,{R11,PC}^ ;A happy bunny
227 ;----- Service call handling ------------------------------------------------
231 CMP R1,#&46 ;Is it a mode change?
232 MOVNES PC,R14 ;No -- return
234 LDR R12,[R12] ;Get my workspaxe
235 B vdu_set ;Set up the VDU variables
238 ;----- Command handlers -----------------------------------------------------
240 ; --- Sculptrix_Colours ---
244 STMFD R13!,{R1-R5,R14} ;Save some registers
245 LDR R12,[R12] ;Locate my workspace pointer
247 ; --- If no argument, use the default ---
249 CMP R1,#0 ;Is there an argument?
250 ADREQ R0,cmd__defCol ;No -- point to default
252 ; --- Read normal 3D colours ---
254 LDRB R2,[R0],#1 ;Get the first digit
255 BL %50cmd_colours ;Convert to binary
256 MOV R3,R2,LSL #8 ;Look after it
257 LDRB R2,[R0],#1 ;Get the next digit
258 BL %50cmd_colours ;Convert to binary
259 ORR R3,R3,R2 ;Mix into the word nicely
260 ORR R3,R3,R3,LSL #16 ;Propagate to upper half
262 ; --- Read shaded 3D colours ---
264 LDRB R2,[R0],#1 ;Get the first digit
265 BL %50cmd_colours ;Convert to binary
266 MOV R4,R2,LSL #8 ;Look after it
267 LDRB R2,[R0],#1 ;Get the next digit
268 BL %50cmd_colours ;Convert to binary
269 ORR R4,R4,R2 ;Mix into the word nicely
270 ORR R4,R4,R4,LSL #16 ;Propagate to upper half
272 ; --- Read the other colours ---
274 LDRB R2,[R0],#1 ;Get a digit
275 BL %50cmd_colours ;Convert to binary
276 MOV R5,R2,LSL #8 ;Look after it
277 LDRB R2,[R0],#1 ;Get a digit
278 BL %50cmd_colours ;Convert to binary
279 ORR R5,R5,R2 ;Look after it
281 ; --- Now store these away nicely ---
283 ADR R1,s_colours ;Point to base address
284 STMIA R1,{R3-R5} ;Store them in workspace
285 LDMFD R13!,{R1-R5,PC}^ ;Return to caller
287 ; --- Convert R2 to binary ---
289 50cmd_colours SUBS R2,R2,#'0' ;Convert a digit
290 CMP R2,#10 ;Is this bigger than 9?
291 SUBCS R2,R2,#7 ;Yes -- convert from upper
292 CMP R2,#16 ;Still out of range?
293 SUBCS R2,R2,#&20 ;Yes -- must have been lower
294 CMP R2,#16 ;Still out of range?
295 BCS %51cmd_colours ;Yes -- that's an error
296 MOVS PC,R14 ;Return to caller
298 51cmd_colours ADRL R0,msg_errBadHex ;Point to error message
299 LDMFD R13!,{R1-R5,R14} ;Unstack the registers
300 ORRS PC,R14,#V_flag ;Return to caller
302 cmd__defCol DCB "4020CE",0
306 ; --- Sculptrix_GroupType ---
310 LDRB R0,[R0] ;Get the digit
311 LDR R12,[R12] ;Find my workspace
312 LDR R1,s_flags ;Load my flags word
313 BIC R1,R1,#s_CHANNEL :OR: s_FAINTCHAN
314 CMP R0,#'1' ;Is it a deep channel?
315 ORREQ R1,R1,#s_CHANNEL
316 CMP R0,#'2' ;Is it a shallow channel?
317 ORREQ R1,R1,#s_CHANNEL :OR: s_FAINTCHAN
323 ;----- SWI names and numbers etc --------------------------------------------
327 LDR R12,[R12] ;Get my workspace neatly
328 CMP R11,#(%01s_swic-%00s_swic)/4 ;Check SWI is in range
329 ADDCC PC,PC,R11,LSL #2 ;Go to correct branch instr
330 B %01s_swic ;Branch to complain thing
332 00s_swic B swi_redraw
343 01s_swic ADRL R0,msg_errBadSwi ;Point to error message
344 ORRS PC,R14,#V_flag ;Return with an error
348 ;----- SWI handling ---------------------------------------------------------
350 ; --- Sculptrix_RedrawWindow ---
352 ; R1 == pointer to redraw block
356 STMFD R13!,{R0-R11,R14} ;Stack registers
358 ; --- Find the window origin ---
360 MOV R11,R1 ;Keep the pointer nicely
361 BL box_readRectangle ;Find everything about rdrw
363 ; --- Now go through the icons ---
365 SUB R13,R13,#40 ;Make way for an icon block
366 MOV R1,R13 ;Point to the block
367 LDR R0,[R11,#0] ;Get the window handle
368 MOV R2,#0 ;Start at icon 0
369 STMIA R1,{R0,R2} ;Store them in the block
371 ; --- Main loop -- go through each icon and plot ---
373 00swi_redraw SWI XWimp_GetIconState ;Read info into block
374 ADDVS R13,R13,#44 ;Error -- reclaim stack space
375 LDMVSFD R13!,{R1-R11,PC} ;And return to caller
376 LDR R0,[R1,#24] ;Get the flags word
377 CMP R0,#1<<23 ;Is it only deleted?
378 ADDEQ R13,R13,#40 ;Yes -- reclaim stack space
379 LDMEQFD R13!,{R0-R11,PC}^ ;And return to caller
381 ; --- Find out whether the icon is visible ---
383 ADD R0,R1,#8 ;Point to coords block
384 LDMIA R0,{R0,R2-R4} ;Load the icon coordinates
389 BGT %01swi_redraw ;Not visible -- skip it
391 ADD R0,R1,#8 ;Point to icon block
394 ; --- Ho-hum. Now do the next one ---
396 01swi_redraw LDR R0,[R1,#4] ;Get the icon handle
397 ADD R0,R0,#1 ;Bump it up a little
398 STR R0,[R1,#4] ;Store it back again
399 B %00swi_redraw ;And go round for another
403 ; --- Sculptrix_DoSlab ---
405 ; On entry: R0 == window handle
407 ; R2 == colour to slab to
409 ; On exit: R2 == old colour of icon, or -1 if icon couldn't be slabbed
413 STMFD R13!,{R0-R11,R14} ;Stack registers
414 MOV R9,R2 ;Look after the colour
415 MOV R2,#-1 ;Store -1 in stacked R2
416 STR R2,[R13,#8] ;Return no colour currently
418 ; --- Find out if we need to do anything ---
420 SUB R13,R13,#44 ;Make way for an icon def
421 STMIA R13,{R0,R1} ;Store icon handle and stuff
422 MOV R1,R13 ;Point to icon block
423 SWI XWimp_GetIconState ;Get the icon information
424 ADDVS R13,R13,#48 ;If it failed, reclaim stack
425 LDMVSFD R13!,{R1-R11,PC} ;And return the error
427 MOV R3,#0 ;Start from the beginning
428 90swi_doslab ADD R0,R1,#8 ;Point to actual icon def
429 MOV R2,#'X' ;Get the validation command
430 BL box_findValid ;Find the validation string
431 CMP R2,#0 ;Did it work?
432 ADDEQ R13,R13,#44 ;No -- reclaim used stack
433 LDMEQFD R13!,{R0-R11,PC}^ ;And return to caller
435 ; --- Get the border type -- only 0 and 2 slab ---
437 LDRB R0,[R2,#1] ;Get the border type number
438 CMP R0,#'0' ;Is it a normal action type?
439 CMPNE R0,#'2' ;Or a default action type?
440 MOVNE R3,R2 ;No -- point to this place
441 BNE %90swi_doslab ;And loop back
443 ; --- It's a worthwhile icon ---
445 LDMIA R1,{R0,R1} ;Load window and icon handles
446 MOV R8,R2 ;Look after this pointer
447 MOV R2,R9 ;Get the colour wanted
448 BL box_setcolour ;Set the colour properly
449 STR R2,[R13,#44+8] ;Store it nicely away again
450 MOV R1,R13 ;Point at the block again
452 ; --- Update the border ---
454 LDRB R0,[R8,#0] ;Get the border command
455 EOR R0,R0,#&20 ;Toggle its case
456 STRB R0,[R8,#0] ;Store it back again
458 LDR R3,[R1,#24] ;Load the icon flags
459 EOR R3,R3,#&005F0000 ;Toggle ESG and shaded bit
460 TST R3,#1<<22 ;Is the icon shaded?
461 TSTNE R3,#&001F0000 ;No -- test the ESG bits
462 ADRNE R11,s_colours ;No -- use normal colours
463 ADREQ R11,s_shadeCols ;Yes -- use shaded colours
465 TST R0,#&20 ;Is it set now?
466 ADDEQ R11,R11,#1 ;No -- use offset colours
468 ADD R0,R1,#8 ;Point to icon def again
469 LDMIA R0,{R3-R6} ;Get icon coords
470 SUB R3,R3,#4 ;Make space for border around
474 STMIB R1,{R3-R6} ;That's now our update block
475 SWI XWimp_UpdateWindow ;Try and update it then
476 BVS %01swi_doslab ;If it failed skip this bit
477 CMP R0,#0 ;Is there anything to do?
478 BEQ %01swi_doslab ;No -- skip it too
480 ADD R2,R1,#16 ;Point to y1
481 LDMIA R2,{R8-R10} ;Get coordinates from block
482 SUB R10,R8,R10 ;Get y origin position
483 LDR R8,[R2,#-12] ;Get x0 value from block
484 SUB R9,R8,R9 ;Get x origin position
486 ADD R3,R3,#4 ;Point back to the icon block
495 00swi_doslab ; --- Draw box (inline copy) ---
497 ; We only draw the inner slabbed bit -- the rest doesn't
498 ; change even in the default type.
501 STMIA R2,{R3-R6} ;Store adjusted coords away
517 ; --- Get another rectangle ---
519 SWI XWimp_GetRectangle
520 CMP R0,#0 ;Have we anything to do?
521 BNE %00swi_doslab ;Yes -- do it then, dummy
523 01swi_doslab ADD R13,R13,#44
524 LDMFD R13!,{R0-R11,PC}^
528 ; --- Sculptrix_SlabIcon ---
530 ; On entry: R0 == window handle
532 ; R2 == pointer to 4 word slab descriptor to be filled in
537 STMFD R13!,{R0-R2,R10,R14} ;Keep link register safe
539 ; --- Fill in the caller's descriptor block ---
541 MOV R10,R2 ;Keep the pointer safe
542 STMIA R10,{R0,R1} ;Stash the icon info away
543 SWI XOS_ReadMonotonicTime ;Read the current time
544 CMP R1,#0 ;Are mouse buttons pressed?
545 ADDEQ R0,R0,#5 ;No -- then bump time on 5
546 STR R0,[R10,#12] ;Store in the descriptor
548 ; --- Slab the border in or out ---
550 LDR R0,[R10,#0] ;Reload window handle
551 LDRB R2,s_slabcol ;Get the slab colour nicely
552 BL swi_doslab ;Do the slabbing operation
553 LDMVSFD R13!,{R0-R2,R10,PC} ;If it failed, return error
555 SUB R13,R13,#20 ;Space for a pointer block
556 MOV R1,R13 ;Point to the block
557 SWI XWimp_GetPointerInfo ;Read current mouse state
558 LDR R1,[R13,#8] ;Load the button state
559 ADD R13,R13,#20 ;Restore the stack pointer
560 CMP R1,#0 ;Are there buttons pressed?
561 ORREQ R2,R2,#256 ;Yes -- set a flag bit then
562 STR R2,[R10,#8] ;Store the old icon colour
564 ; --- Say to pause on unslabs in flags ---
566 LDR R14,s_flags ;Get the flags word
567 BIC R14,R14,#s_UNSLAB ;Clear unslab bit
568 STR R14,s_flags ;Store flags word back
570 ; --- Return to caller ---
572 LDMFD R13!,{R0-R2,R10,PC}^ ;Return to caller
576 ; --- Sculptrix_UnslabIcon ---
578 ; On entry: R2 == pointer to descriptor filled in by Sculptrix_SlabIcon
583 STMFD R13!,{R0-R2,R10,R14} ;Stack my registers
585 ; --- Find out if we need to do any slabbing ---
587 LDR R14,[R2,#8] ;Get the icon colour
588 CMP R14,#-1 ;Is it nonslabbed?
589 LDMEQFD R13!,{R0-R2,R10,PC}^
591 ; --- Do we unslab quickly? ---
593 MOV R10,R2 ;Look after slab block
594 SUB R13,R13,#36 ;To read the window state
595 LDR R0,s_flags ;Get the flags word
596 TST R0,#s_UNSLAB ;Is the unslab bit set?
597 BNE %03swi_unslab ;Yes -- skip past the wait
599 ; --- Wait the requisite quantity of time ---
601 LDR R0,[R10,#0] ;Get the window handle
602 MOV R1,R13 ;Point to the block
603 STR R0,[R1,#0] ;Store in the block
604 SWI XWimp_GetWindowState ;Get info about the window
605 BVS %01swi_unslab ;It must have been deleted
607 LDR R0,[R1,#32] ;Get the window flags
608 TST R0,#1<<16 ;Is the window open?
609 BEQ %01swi_unslab ;And just wait the time out
611 ; --- Wait for the mouse to be released ---
613 LDR R14,[R10,#8] ;Load colour and flags bits
614 TST R14,#256 ;Is the `no mouse' bit set?
615 BNE %01swi_unslab ;And do the wait operation
617 00swi_unslab SWI XOS_Mouse ;Read mouse information
618 CMP R2,#0 ;Are the buttons released?
619 BNE %00swi_unslab ;No -- keep waiting
620 B %03swi_unslab ;Do the actual unslab
622 ; --- Wait for the timer to elapse ---
624 01swi_unslab LDR R1,[R10,#12] ;Load the slab time
625 ADD R1,R1,#10 ;Work out unslab time
626 02swi_unslab SWI XOS_ReadMonotonicTime ;Get the current time
627 CMP R1,R0 ;How do they compare?
628 BPL %02swi_unslab ;Too low -- go round again
630 ; --- Actually unslab the icon ---
632 03swi_unslab ADD R13,R13,#36 ;Reclaim the stack space
633 LDMIA R10,{R0-R2} ;Get window, icon and colour
634 AND R2,R2,#255 ;Clear flags bits etc.
635 BL swi_doslab ;Unslab the icon
637 ; --- Remember we've done this now ---
639 LDR R0,s_flags ;Get the flags word again
640 ORR R0,R0,#s_UNSLAB ;Set the unslab bit
641 STR R0,s_flags ;Store the flags word away
643 ; --- Return to caller ---
645 LDMFD R13!,{R0-R2,R10,PC}^ ;Return to caller
649 ; --- Sculptrix_BoundingBox ---
651 ; On entry: R1 == pointer to an icon block
652 ; On exit: R0 == 0 if there was no border
653 ; block updated to reflect border width
657 STMFD R13!,{R1-R6,R14} ;Stash registers
658 MOV R3,#0 ;Start from the beginning
659 00swi_bbox MOV R0,R1 ;Point to block
660 MOV R2,#'X' ;The correct magic command
661 BL box_findValid ;Find the validation string
662 CMP R2,#0 ;Was it not there?
663 MOVEQ R0,#0 ;Mark as nonpresent
664 LDMEQFD R13!,{R1-R6,PC}^ ;Then return
665 LDRB R0,[R2,#1] ;Get the border type
666 CMP R0,#'g' ;It could be a group box
667 CMPNE R0,#'G' ;Try both cases
668 BEQ %02swi_bbox ;If so, be clever
670 SUBS R0,R0,#'0' ;Turn into a number
671 CMP R0,#6 ;Is it type 6?
672 BEQ %01swi_bbox ;Yes -- be clever
673 CMP R0,#9 ;Is it too big?
674 MOVCS R3,R2 ;Not there if too high
675 BCS %00swi_bbox ;So try for another one
676 LDMIA R1,{R3-R6} ;Load the bounding box regs
677 ADR R2,box_borders ;Get the border size table
678 LDRB R0,[R2,R0] ;Load the border width
683 STMIA R1,{R3-R6} ;Store the sizes back
684 LDMFD R13!,{R1-R6,PC}^ ;Return happy
686 01swi_bbox LDMIA R1,{R3-R6} ;Load the bounding box regs
691 LDMFD R13!,{R1-R6,PC}^ ;Return happy
693 02swi_bbox LDMIA R1,{R3-R6} ;Load the bounding box regs
700 LDMFD R13!,{R1-R6,PC}^ ;Return happy
702 box_borders DCB 4,8,12,8,4,4,0,12,4
706 ; --- Sculptrix_PlotIcon ---
708 ; On entry: R0 == pointer to icon block
709 ; R1 == pointer to redraw block
713 STMFD R13!,{R0-R11,R14} ;Stash loads of registers
714 LDMIA R0,{R0,R2-R8} ;Load the icon coordinates
715 STMFD R13!,{R0,R2-R8} ;Store them on the stack
716 BL box_readRectangle ;Get the graphics window size
717 MOV R0,R13 ;Point to the icon block
718 BL box_ploticon ;Plot the icon
719 ADD R13,R13,#32 ;Reclaim the space
720 LDMFD R13!,{R0-R11,PC}^ ;Return to caller
724 ; --- Sculptrix_PlotGroup ---
726 ; On entry: R0 == pointer to icon block
727 ; R1 == pointer to redraw block
729 ; R3 == pointer to title string
733 STMFD R13!,{R0-R11,R14} ;Stash loads of registers
734 LDMIA R0,{R0,R4-R10} ;Load the icon coordinates
735 STMFD R13!,{R0,R4-R10} ;Store them on the stack
736 BL box_readRectangle ;Get the graphics window size
737 MOV R0,R13 ;Point to the icon block
738 MOV R1,R2 ;Get border type number
739 MOV R2,R3 ;Get pointer to group string
740 BL box_dogroup ;Plot the icon
741 ADD R13,R13,#32 ;Reclaim the space
742 LDMFD R13!,{R0-R11,PC}^ ;Return to caller
746 ; --- Sculptrix_SetSpriteArea ---
748 ; On entry: R0 == pointer to sprite area to use
752 STR R0,s_sarea ;Save it as sprite area ptr
753 MOVS PC,R14 ;Return to caller
755 ; --- Sculptrix_UpdateIcon ---
757 ; On entry: R0 == window handle
758 ; R1 == icon handle to update
762 STMFD R13!,{R0-R4,R14} ;Save some registers
763 SUB R13,R13,#84 ;For icon and redraw blocks
764 STMIA R13,{R0,R1} ;Save the bits at the bottom
765 MOV R1,R13 ;Point to the icon block
766 SWI XWimp_GetIconState ;Find the icon's bits out
767 BVS %99swi_update ;If it failed, go ahead
768 ADD R2,R13,#40 ;Point to the redraw block
769 LDR R0,[R13,#0] ;Get the window handle again
770 STR R0,[R2,#0] ;Store window handle at base
771 ADD R0,R1,#8 ;Point to icon coordinates
772 LDMIA R0,{R0,R1,R3,R14} ;Load the coordinates
773 SUB R0,R0,#16 ;Include the border nicely
777 STMIB R2,{R0,R1,R3,R14} ;Save them out again
778 MOV R1,R2 ;Point to this block
779 SWI XWimp_UpdateWindow ;Start the window redraw
780 BVS %99swi_update ;If it failed, go ahead
782 00swi_update CMP R0,#0 ;Is this the end yet?
783 BEQ %80swi_update ;Yes -- finish up nicely
784 ADD R0,R13,#8 ;Point to the icon block
785 BL swi_ploticon ;Plot the icon on the screen
786 SWI XWimp_GetRectangle ;Get the next redraw rect
787 B %00swi_update ;And draw that one too
789 80swi_update ADD R13,R13,#84 ;Reclaim all that stack
790 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
792 99swi_update ADD R13,R13,#88 ;Reclaim stack + R0
793 LDMFD R13!,{R1-R4,PC} ;Return with V still set
797 ; --- Scultrix_SlabColour ---
801 ; On exit: R2 == standard slabbing-in colour
803 swi_slabcol LDRB R2,s_slabcol
806 ;----- Icon box redrawing ---------------------------------------------------
808 ; --- box_readRectangle ---
810 ; On entry: R1 == pointer to a Wimp redraw block
811 ; On exit: R1 corrupted
812 ; R5-R8 == adjusted, window-relative mouse rectangle
813 ; R9,R10 == screen coords of window origin
815 box_readRectangle ROUT
817 CMP R1,#0 ;Is there a redraw block?
818 MOVEQ R9,#0 ;Yes -- don't translate box
820 MOVEQS PC,R14 ;And return
821 ADD R1,R1,#16 ;Point to y1
822 LDMIA R1,{R8-R10} ;Get coordinates from block
823 SUB R10,R8,R10 ;Get y origin position
824 LDR R8,[R1,#-12] ;Get x0 value from block
825 SUB R9,R8,R9 ;Get x origin position
827 ; --- Mangle the graphics rectangle ---
829 ADD R1,R1,#12 ;Point to the graphics window
830 LDMIA R1,{R5-R8} ;Load the window posn
831 SUB R5,R5,R9 ;Convert to window coords
836 SUB R5,R5,#16 ;Add a little bit of leeway
845 ; --- box_ploticon ---
847 ; On entry: R0 == pointer to an icon block (writable)
848 ; R5-R10 == as set by box_readRectangle
849 ; On exit: R2-R4,R11 corrupted
854 00box_ploticon STMFD R13!,{R14}
855 MOV R2,#'X' ;Find X commands in valid
856 BL box_findValid ;Is it there?
857 LDMFD R13!,{R14} ;Get return address back
859 MOVEQS PC,R14 ;No -- return to caller
861 ; --- If the border has a capital letter, invert ---
863 ; Also, choose the right colours for shaded boxes
865 LDR R11,[R0,#16] ;Get the icon flags word
866 EOR R11,R11,#&005F0000 ;Toggle ESG and shaded bits
867 TST R11,#1<<22 ;Is the icon shaded?
868 TSTNE R11,#&001F0000 ;Or is ESG all set?
869 ADRNE R11,s_colours ;No -- use normal colours
870 ADREQ R11,s_shadeCols ;Yes -- use shaded colours
872 LDRB R4,[R2,#0] ;Get the command letter
873 TST R4,#&20 ;Is it upper case?
874 ADDEQ R11,R11,#1 ;Yes -- use offset colours
876 ; --- Get the render type, and handle as required ---
878 LDRB R3,[R2,#1] ;Get the border type number
879 ORR R4,R3,#&20 ;Convert to lower case
881 CMP R4,#'g' ;Is it a group box type?
882 BEQ box_plotgroup ;Yes -- plot a group box
884 CMP R4,#'s' ;Is it a gadget text/sprite?
885 BEQ box_plottns ;Yes -- plot cunningly
887 ; --- Dispatch normal group border numbers ---
889 SUB R3,R3,#'0' ;Convert to a digit
890 CMP R3,#(%02box_ploticon-%01box_ploticon)/4
891 ADDCC PC,PC,R3,LSL #2 ;Go to branch table
892 B %03box_ploticon ;Not found -- try next valid
894 01box_ploticon B brd0 ;Standard plinth
895 B brd1 ;Group ridge/channel
896 B brd2 ;Default action button
897 B brd3 ;Writable wide border
898 B brd0 ;Nonslabbing standard plinth
899 B brd5 ;Plinth with ridge intersect
900 B brd6 ;Channel terminators
901 B brd7 ;Writable with black border
902 B brd8 ;Like 4, only different
905 03box_ploticon MOV R3,R2 ;Point to that command
906 B %00box_ploticon ;And find the next string
910 ; --- box_setcolour ---
912 ; On entry: R0 == window handle
914 ; R2 == colour to set
915 ; On exit: R2 == old colour of icon
919 STMFD R13!,{R0,R1,R3-R5,R14} ;Stack registers
920 MOV R5,R2 ;Keep the colour safe
921 SUB R13,R13,#40 ;Make way for icon block
922 STMIA R13,{R0,R1} ;Set up icon block
923 MOV R1,R13 ;Point to block
924 SWI XWimp_GetIconState ;Get info about icon
925 ADDVS R13,R13,#44 ;If it failed, reset stack
926 LDMVSFD R13!,{R1,R3-R5,PC} ;And return the error
928 ; --- Check for fonts ---
930 LDR R0,[R1,#24] ;Get icon flags word
931 TST R0,#1<<6 ;Check anti-aliased bit
932 BEQ %00box_setcolour ;Reset -- do it normally
933 ADD R0,R1,#8 ;Point to icon definition
934 MOV R2,#'F' ;Find F validation string
935 MOV R3,#0 ;Start from the beginning
936 BL box_findValid ;Find it
937 CMP R2,#0 ;Was it not there?
938 ADDEQ R13,R13,#40 ;No -- reset stack ptr
939 LDMEQFD R13!,{R0,R1,R3-R5,PC}^ ;We did all we could
940 ADR R0,box_hexdigits ;Point to hex digits table
941 LDRB R0,[R0,R5] ;Get the right digit
942 LDRB R5,[R2,#1] ;Get the old colour
943 STRB R0,[R2,#1] ;Store in validation string
944 SUB R2,R5,#'0' ;Turn into a digit
945 CMP R2,#10 ;Is it a hex digit?
946 SUBCS R2,R2,#7 ;Yes -- get the number
947 CMP R2,#16 ;Is it still too big?
948 SUBCS R2,R2,#&20 ;It must have been lower case
950 ; --- Prod the icon into redrawing ---
952 MOV R0,#0 ;Don't set either flags mask
953 STR R0,[R1,#8] ;Set XOR mask
954 STR R0,[R1,#12] ;Set BIC mask
955 SWI XWimp_SetIconState ;Give the icon a little prod
956 ADDVC R13,R13,#40 ;It worked fine
957 LDMVCFD R13!,{R0,R1,R3-R5,PC}^ ;So return happily
958 ADD R13,R13,#44 ;If it failed, reset stack
959 LDMFD R13!,{R1,R3-R5,PC} ;And return the error
961 ; --- Just set the colours in the time-honoured way ---
963 00box_setcolour MOV R2,#&F ;Only want 4 bits
964 AND R2,R2,R0,LSR #28 ;Get old colour in R2
965 MOV R0,R5,LSL #28 ;Shift colour into position
966 STR R0,[R1,#8] ;This is our XOR mask
967 MOV R0,#&F0000000 ;Only change the colour
968 STR R0,[R1,#12] ;This is our BIC mask
969 SWI XWimp_SetIconState ;Give the icon a little prod
970 ADDVC R13,R13,#40 ;It worked fine
971 LDMVCFD R13!,{R0,R1,R3-R5,PC}^ ;So return happily
972 ADD R13,R13,#44 ;If it failed, reset stack
973 LDMFD R13!,{R1,R3-R5,PC} ;And return the error
975 box_hexdigits DCB "0123456789ABCDEF",0
979 ;----- Messing with validation strings --------------------------------------
981 ; --- box_findValid ---
983 ; On entry: R0 == pointer to icon block
984 ; R2 == character to find in block (not case-sensitive)
985 ; R3 == old pointer to search from, or 0
986 ; On exit: R3,R4 corrupted
987 ; R2 points to command string if found, or 0
991 STMFD R13!,{R3} ;Preserve for later use
993 ; --- Ensure the icon is text and indirected ---
995 LDR R3,[R0,#16] ;Get flags word
996 TST R3,#1<<23 ;Is it deleted?
997 MOVEQ R4,#&100 ;Can't put 101 in one instr
998 ORREQ R4,R4,#&01 ;Check indirect and text
999 ANDEQ R3,R3,R4 ;Mask the bits off
1000 CMPEQ R3,R4 ;Were they both set?
1001 MOVNE R2,#0 ;Couldn't find it
1003 MOVNES PC,R14 ;No -- return huffily
1005 ; --- Find the validation string ---
1007 LDR R3,[R0,#24] ;Get pointer to valid string
1008 CMP R3,#-1 ;Is it empty?
1009 MOVEQ R2,#0 ;Yes -- not found
1013 ; --- Start from the right index ---
1015 ORR R2,R2,#&20 ;Make valid char lower case
1016 LDMFD R13!,{R4} ;Get search index
1017 STMFD R13!,{R14} ;Need another register
1018 CMP R4,#0 ;Is it the start?
1019 MOVNE R3,R4 ;No -- start from old pos
1020 BNE %02box_findValid ;And skip this command
1022 ; --- Check the first char of a validation string ---
1024 00box_findValid LDRB R14,[R3],#1 ;Get a byte from string
1025 ORR R4,R14,#&20 ;Make lower case
1026 CMP R4,R2 ;Is it a match?
1027 SUBEQ R2,R3,#1 ;Point back to character
1028 LDMEQFD R13!,{PC}^ ;And return
1029 MOV R4,#0 ;Not an excaped character
1031 ; --- Skip ahead to the next validation string ---
1033 01box_findValid CMP R14,#' ' ;Is it a control char?
1034 MOVCC R2,#0 ;Yes -- not found
1035 LDMCCFD R13!,{PC}^ ;And return
1036 CMP R4,#1 ;Are we escaping?
1037 MOVEQ R4,#0 ;Yes -- done that now
1038 BEQ %02box_findValid ;So skip this bit
1039 CMP R14,#';' ;Is it a semicolon?
1040 BEQ %00box_findValid ;Yes -- try a new command
1041 CMP R14,#'\' ;Is it a backslash?
1042 MOVEQ R4,#1 ;Yes -- escape next char
1043 02box_findValid LDRB R14,[R3],#1 ;Get another character
1044 B %01box_findValid ;And try again
1048 ;----- Plot text+sprite icons -----------------------------------------------
1050 ; --- box_plottns ---
1052 ; On entry: R0 == pointer to an icon block (writable)
1053 ; R2 == pointer to the validation string command
1054 ; R5-R10 == set up by box_readRectangle
1058 STMFD R13!,{R0-R4,R14} ;Stack some registers
1060 ; --- Now copy the sprite name into the buffer ---
1062 LDR R0,[R13,#0] ;Find the icon pointer
1063 MOV R2,#'s' ;Find the sprite name
1064 MOV R3,#0 ;Search from the beginning
1065 BL box_findValid ;Find the string
1066 CMP R2,#0 ;Did it find anything?
1067 BEQ %99box_plottns ;No -- nothing to do then
1069 ; --- Copy the sprite name into the buffer ---
1071 ADR R0,s_buffer ;Point to my buffer
1072 ADD R2,R2,#1 ;Point to first sprite char
1073 00box_plottns LDRB R14,[R2],#1 ;Get the character
1074 CMP R14,#';' ;Is it the string end?
1075 CMPNE R14,#',' ;Or the sprite name end?
1076 CMPNE R14,#&1F ;Or the validation string end
1077 MOVLS R14,#0 ;Yes -- null terminate
1078 STRB R14,[R0],#1 ;Store in the buffer
1079 BHI %00box_plottns ;No -- loop round again
1081 ; --- Now read the sprite information ---
1083 STMFD R13!,{R5,R6} ;Save some registers
1084 MOV R0,#40 ;Read sprite information
1085 LDR R1,s_sarea ;Find the user's sprite area
1086 ADR R2,s_buffer ;Point to the block
1087 CMP R1,#1 ;Is it the wimp area
1088 BEQ %f05 ;Yes -- skip on then
1089 ORR R0,R0,#&100 ;No -- say user sprite area
1090 SWI XOS_SpriteOp ;So try to cope with that
1091 BVC %f06 ;If OK skip onwards
1093 05 MOV R0,#40 ;Read sprite information
1094 ADR R2,s_buffer ;Point to the block
1097 06 MOV R0,R6 ;Get the sprite's mode number
1098 LDMFD R13!,{R5,R6} ;Unstack the registers
1099 BVS %99box_plottns ;No sprite, no text
1101 ; --- Find the width of the sprite, then ---
1103 MOV R1,#4 ;Read XEigFactor
1104 SWI XOS_ReadModeVariable ;Read the value then
1105 BVS %99box_plottns ;No sprite mode, no text
1106 MOV R4,R3,LSL R2 ;Get sprite width in OS units
1108 ; --- Plot the icon to avoid strangeness ---
1110 LDR R1,[R13,#0] ;Get the icon block pointer
1111 SWI XWimp_PlotIcon ;Plot the icon onto screen
1113 ; --- Copy the text string into the buffer ---
1115 LDR R2,[R13,#8] ;Find the validation string
1116 ADD R0,R2,#2 ;Point to the text string
1117 ADR R1,s_buffer ;Point to the buffer start
1119 10box_plottns LDRB R14,[R0],#1 ;Get a byte from the string
1120 CMP R14,#'\' ;Is it an escape?
1121 BEQ %11box_plottns ;Yes -- handle it specially
1122 CMP R14,#';' ;Or the next command?
1123 CMPNE R14,#&1F ;Is it a control character
1124 MOVLS R14,#0 ;Yes -- store a null byte
1125 STRB R14,[R1],#1 ;Store the character away
1126 BHI %10box_plottns ;No -- loop round again
1127 B %12box_plottns ;Yes -- branch away
1129 11box_plottns LDRB R14,[R0],#1 ;Get the escaped byte
1130 CMP R14,#32 ;Is it a control character?
1131 MOVCC R14,#0 ;Yes -- store a real term
1132 STRB R14,[R1],#1 ;Store the character away
1133 BCS %10box_plottns ;And get another one
1135 ; --- Now plot the text part ---
1137 12box_plottns MOV R0,#8 ;Get the current font handle
1138 SWI XWimp_ReadSysInfo ;Go and do that then
1139 MOVVS R0,#0 ;If failed, assume system
1140 CMP R0,#0 ;Is there a magic font?
1141 LDR R1,[R13,#0] ;Find the icon block again
1142 LDR R0,[R1,#16] ;Find the icon flags word
1143 MOV R14,#&FF000000 ;Mask for the old flags
1144 ORRNE R14,R14,#&00400000 ;If antialiased, copy shade
1145 LDR R2,=&00000111 ;Magic flags for text part
1146 AND R0,R0,R14 ;Keep original colours
1147 ORR R0,R0,R2 ;Mix 'n' match the icon flags
1148 STR R0,[R1,#16] ;Store that back again
1149 LDR R0,[R1,#0] ;Get left icon edge
1150 ADD R0,R0,R4 ;Offset by the right amount
1151 STR R0,[R1,#0] ;Store it back again
1152 ADR R14,s_buffer ;Find the buffer pointer
1153 STR R14,[R1,#20] ;Point to the text string
1154 MOV R0,#-1 ;No validation string pliz
1155 STR R0,[R1,#24] ;Store it in the buffer
1156 SWI XWimp_PlotIcon ;And stick it on the screen
1158 ; --- Tidy up and leave ---
1160 99box_plottns LDMFD R13!,{R0-R4,PC}^ ;Return to caller if OK
1164 ;----- Plot group boxes -----------------------------------------------------
1166 ; --- box_plotgroup ---
1168 ; On entry: R0 == pointer to an icon block (writable)
1169 ; R2 == pointer to the validation string command
1170 ; R5-R10 == set up by box_readRectangle
1174 STMFD R13!,{R0-R2,R14} ;Stack some registers
1176 ; --- Copy the string into the buffer ---
1178 LDR R2,[R13,#8] ;Find the validation string
1179 ADD R0,R2,#3 ;Point to the text string
1180 ADR R1,s_buffer ;Point to the buffer start
1182 00box_plotgroup LDRB R14,[R0],#1 ;Get a byte from the string
1183 CMP R14,#'\' ;Is it an escape?
1184 BEQ %01box_plotgroup ;Yes -- handle it specially
1185 CMP R14,#';' ;Or the next command?
1186 CMPNE R14,#&1F ;Is it a control character
1187 MOVLS R14,#0 ;Yes -- terminate string
1188 STRB R14,[R1],#1 ;Store the character away
1189 BHI %00box_plotgroup ;No -- loop round again
1190 B %02box_plotgroup ;Yes -- branch away
1192 01box_plotgroup LDRB R14,[R0],#1 ;Get the escaped byte
1193 CMP R14,#32 ;Is it a control character?
1194 MOVCC R14,#0 ;Yes -- store a real term
1195 STRB R14,[R1],#1 ;Store the character away
1196 BCS %00box_plotgroup ;And get another one
1198 ; --- Now plot the group border ---
1200 02box_plotgroup LDR R0,[R13,#0] ;Get the icon block pointer
1201 LDRB R1,[R2,#2] ;Get the border type
1202 SUB R1,R1,#'0' ;Convert to an integer
1203 ADR R2,s_buffer ;Point to the string
1204 BL box_dogroup ;Handle the actual plotting
1206 ; --- Tidy up and leave ---
1208 03box_plotgroup LDMFD R13!,{R0-R2,PC}^ ;Return to caller if OK
1212 ; --- box_dogroup ---
1214 ; On entry: R0 == pointer to coordinates box
1215 ; R1 == group border type number
1216 ; R2 == pointer to group title string
1220 STMFD R13!,{R11,R14} ;Store registers
1221 LDR R14,s_flags ;Get the flags word
1222 TST R14,#s_CHANNEL ;Does the user want channels?
1223 EORNE R1,R1,#1 ;Yes -- toggle channelness
1224 ADR R14,%02box_dogroup
1225 CMP R1,#(%02box_dogroup-%01box_dogroup)/4
1226 ADDCC PC,PC,R1,LSL #2 ;Go to branch table
1227 LDMFD R13!,{R11,PC}^ ;Return to caller
1229 01box_dogroup B grp0 ;Standard ridge and plinth
1230 B grp1 ;Acorn channel and gap
1231 B grp2 ;Standard ridge and plinth
1232 B grp3 ;Acorn channel and gap
1234 02box_dogroup LDMFD R13!,{R11,PC} ;Return to caller
1236 ;----- Drawing group borders ------------------------------------------------
1238 ; --- grp_titleicon ---
1240 ; On entry: R0 == pointer to icon coordinates to bodge
1241 ; R1 == left gap for icon title
1242 ; R2 == pointer to title string
1243 ; On exit: R0 == pointer to adjusted box
1247 STMFD R13!,{R0-R5,R14} ;Stash registers away nicely
1249 ; --- Work out the length of the string ---
1251 MOV R5,#0 ;Nothing counted yet
1252 00grp_titleicon LDRB R14,[R2,R5] ;Get the next character
1253 CMP R14,#32 ;Is it a control char?
1254 ADD R5,R5,#1 ;If not, bump the length
1255 BCS %00grp_titleicon ;And loop round again
1257 MOV R0,#8 ;Read the Wimp font handle
1258 SWI XWimp_ReadSysInfo ;Try and find it
1259 MOVVS R5,R5,LSL #4 ;Multiply by 16
1260 BVS %01grp_titleicon ;If not supported, ignore
1261 CMP R0,#0 ;Is there a font used?
1262 MOVEQ R5,R5,LSL #4 ;Multiply by 16
1263 BEQ %01grp_titleicon ;If not, skip ahead a bit
1265 ; --- Work out the width of the string ---
1267 MOV R1,#1000 ;Just something big
1268 MOV R2,#1000 ;Something else big :-)
1269 SWI XFont_Converttopoints ;Convert them to millipts
1270 SWI XFont_SetFont ;Set this as the current font
1271 MOV R3,R2 ;Move these coords now
1273 LDR R1,[R13,#8] ;Find the string pointer
1274 MOV R4,#-1 ;Don't split the string
1275 SWI XFont_StringWidth ;Find the width of the string
1276 MOV R1,R2 ;Move the coords back again
1278 SWI XFont_ConverttoOS ;Convert back to OS units
1279 ADD R5,R1,#16 ;Get the string width
1281 ; --- Now bodge the icon block ---
1283 01grp_titleicon LDMIA R13,{R0,R1} ;Get block ptr and offset
1284 LDMIA R0,{R2,R3,R4,R14} ;Get the icon coords
1285 ADD R2,R2,R1 ;Offset the left side
1286 SUB R3,R14,#20 ;Find bottom of group box
1287 ADD R4,R2,R5 ;Add on the string width
1288 ADD R14,R14,#28 ;Find the top of the icon
1289 STMIA R0,{R2,R3,R4,R14} ;Store the modified coords
1291 ; --- Bodge the rest of the icon ---
1293 LDR R2,[R13,#8] ;Find the string pointer
1294 STR R2,[R0,#20] ;Store this as data
1295 MOV R2,#-1 ;No validation string
1296 STR R2,[R0,#24] ;Store this away too
1297 MOV R2,#1 ;It doesn't care about this
1298 STR R2,[R0,#28] ;Store this as the length
1299 LDR R2,=&17000139 ;Icon flags word
1300 STR R2,[R0,#16] ;Store this as icon flags
1302 LDMFD R13!,{R0-R5,PC}^ ;Return to caller
1304 ; --- grp_fillBorder ---
1306 ; On entry: R5-R8 == box coordinates (!)
1307 ; R9,R10 == window origin coordinates on the screen
1309 ; Removed in version 1.14
1315 STMFD R13!,{R0-R4,R14} ;Save some registers
1316 MOV R0,#1 ;Grey background
1317 SWI XWimp_SetColour ;Set up the background
1318 MOV R0,#4 ;Move absolute
1319 ADD R1,R5,R9 ;Translate left hand side
1320 ADD R2,R6,R10 ;Translate bottom edge
1321 SWI XOS_Plot ;Move there
1322 MOV R0,#101 ;Filled rectangle, absolute
1323 ADD R1,R7,R9 ;Translate right hand side
1324 ADD R2,R8,R10 ;Translate top edge
1325 LDMIA R12,{R3,R4} ;Get the pixel sizes
1326 SUB R1,R1,R3 ;Chop a bit off the right
1327 SUB R2,R2,R4 ;Chop a bit off the top
1328 SWI XOS_Plot ;Fill in the background
1329 LDMFD R13!,{R0-R4,PC}^ ;Restore the registers
1336 grp0 STMFD R13!,{R1-R8,R14} ;Stash registers
1338 LDMIA R0,{R5-R8} ;Get the border coordinates
1339 STMFD R13!,{R5-R8} ;Save them on the stack
1340 MOV R3,R0 ;Keep this pointer safe
1341 ; BL grp_fillBorder ;Don't fill in 1.14
1343 ; --- Translate the icon block ---
1345 MOV R1,#16 ;Small offset here
1346 BL grp_titleicon ;Find the icon position
1348 ; --- Now display the main border ---
1350 LDMIA R0,{R5-R8} ;Save this position
1351 MOV R0,R13 ;Point to border position
1352 MOV R1,R3 ;Point to title position
1353 ADR R11,s_colours ;Point to colour table
1354 BL gborder ;Plot the group border
1356 ; --- Now display the main title border ---
1358 STMIA R3,{R5-R8} ;Restore saved position
1359 MOV R0,R3 ;Point to the position
1360 BL brd5 ;Plot the top plinth
1361 STMIA R0,{R5-R8} ;Restore that again
1362 MOV R1,R0 ;Point to the icon block
1363 SWI XWimp_PlotIcon ;Now plot the icon on top
1364 ADD R13,R13,#16 ;Restore stack pointer
1365 LDMFD R13!,{R1-R8,PC} ;Return to caller
1369 grp1 STMFD R13!,{R1-R8,R14} ;Stash registers
1371 LDMIA R0,{R5-R8} ;Get the border coordinates
1372 STMFD R13!,{R5-R8} ;Save them on the stack
1373 MOV R3,R0 ;Keep this pointer safe
1375 ; --- Translate the icon block ---
1377 MOV R1,#16 ;Small offset here
1378 BL grp_titleicon ;Find the icon position
1380 ; --- Now display the main border ---
1382 LDMIA R0,{R5-R8} ;Save this position
1383 MOV R0,R13 ;Point to border position
1384 MOV R1,R3 ;Point to title position
1385 LDR R11,s_flags ;Get the flags word
1386 TST R11,#s_FAINTCHAN ;Is it meant to be faint
1387 ADREQ R11,s_colours+1 ;Point to colour table
1388 ADRNE R11,s_shadeCols+1
1389 BL gborder ;Plot the group border
1391 ; --- Now display the main title border ---
1393 STMIA R3,{R5-R8} ;Restore saved position
1394 MOV R0,R3 ;Point to the position
1395 BL brd6 ;Plot the top thingy
1396 STMIA R0,{R5-R8} ;Restore that again
1397 MOV R1,R0 ;Point to the icon block
1399 ; --- Stop the top bit from being filled ---
1402 BIC R0,R0,#(1<<5) ;Clear filled flag
1405 SWI XWimp_PlotIcon ;Now plot the icon on top
1406 ADD R13,R13,#16 ;Restore stack pointer
1407 LDMFD R13!,{R1-R8,PC} ;Return to caller
1411 grp2 STMFD R13!,{R1-R8,R14} ;Stash registers
1413 LDMIA R0,{R5-R8} ;Get the border coordinates
1414 STMFD R13!,{R5-R8} ;Save them on the stack
1415 MOV R3,R0 ;Keep this pointer safe
1416 ; BL grp_fillBorder ;Don't fill in 1.14
1418 ; --- Translate the icon block ---
1420 MOV R1,#32 ;Large offset here
1421 BL grp_titleicon ;Find the icon position
1423 ; --- Now display the main border ---
1425 LDMIA R0,{R5-R8} ;Save this position
1426 MOV R0,R13 ;Point to border position
1427 MOV R1,R3 ;Point to title position
1428 ADR R11,s_colours ;Point to colour table
1429 BL gborder ;Plot the group border
1431 ; --- Now display the main title border ---
1433 STMIA R3,{R5-R8} ;Restore saved position
1434 MOV R0,R3 ;Point to the position
1435 BL brd5 ;Plot the top plinth
1436 STMIA R0,{R5-R8} ;Restore that again
1437 MOV R1,R0 ;Point to the icon block
1438 SWI XWimp_PlotIcon ;Now plot the icon on top
1439 ADD R13,R13,#16 ;Restore stack pointer
1440 LDMFD R13!,{R1-R8,PC} ;Return to caller
1444 grp3 STMFD R13!,{R1-R8,R14} ;Stash registers
1446 LDMIA R0,{R5-R8} ;Get the border coordinates
1447 STMFD R13!,{R5-R8} ;Save them on the stack
1448 MOV R3,R0 ;Keep this pointer safe
1450 ; --- Translate the icon block ---
1452 MOV R1,#32 ;Small offset here
1453 BL grp_titleicon ;Find the icon position
1455 ; --- Now display the main border ---
1457 LDMIA R0,{R5-R8} ;Save this position
1458 MOV R0,R13 ;Point to border position
1459 MOV R1,R3 ;Point to title position
1460 LDR R11,s_flags ;Get the flags word
1461 TST R11,#s_FAINTCHAN ;Is it meant to be faint
1462 ADREQ R11,s_colours+1 ;Point to colour table
1463 ADRNE R11,s_shadeCols+1
1464 BL gborder ;Plot the group border
1466 ; --- Now display the main title border ---
1468 STMIA R3,{R5-R8} ;Restore saved position
1469 MOV R0,R3 ;Point to the position
1470 BL brd6 ;Plot the top thingy
1471 STMIA R0,{R5-R8} ;Restore that again
1472 MOV R1,R0 ;Point to the icon block
1474 ; --- Stop the top bit from being filled ---
1477 BIC R0,R0,#(1<<5) ;Clear filled flag
1480 SWI XWimp_PlotIcon ;Now plot the icon on top
1481 ADD R13,R13,#16 ;Restore stack pointer
1482 LDMFD R13!,{R1-R8,PC} ;Return to caller
1486 ; On entry: R0 == pointer to icon coordinates block (writable)
1487 ; R1 == pointer to title icon coordinate
1488 ; R9 == x coord of window origin on screen
1489 ; R10 == y coord of window origin on screen
1491 ; Plots a group border such that it doesn't overlap the title icon at all.
1495 STMFD R13!,{R0-R5,R8,R14} ;Stack registers away
1496 MOV R8,R1 ;Keep this pointer safe
1498 ; --- Now convert all the boxes to screen coords ---
1500 LDMIA R0,{R1-R4} ;Get the straight box
1502 STMIA R0,{R1-R4} ;Write it back nicely
1504 SUB R1,R1,#4 ;Now expand it a little
1508 STMFD R13!,{R1-R4} ;Stash them on the stack
1510 LDMIA R8,{R1-R4} ;Get the title position
1513 STMFD R13!,{R1-R4} ;Save them on the stack too
1515 ; --- Now render all the parts except for the top ---
1536 ; --- Now fix up the top coordinates ---
1538 LDR R0,[R13,#8] ;Get right side of title box
1539 ADD R0,R0,#8 ;Move it clear of the group
1540 LDR R5,[R1,#0] ;Get the old left hand side
1541 STR R0,[R1,#0] ;Store as left side here
1542 STR R0,[R13,#16] ;And left side for other one
1544 ; --- Now render the left top sides ---
1553 ; --- Now get the right top sides ---
1555 STR R5,[R1,#0] ;Store it back again
1556 SUB R5,R5,#4 ;Fiddle for outer border
1557 STR R5,[R13,#16] ;Save in outer border block
1559 LDR R0,[R13,#0] ;Get right hand side of this
1560 SUB R0,R0,#4 ;Move it over a little
1561 STR R0,[R1,#8] ;Store as rightside here
1562 STR R0,[R13,#24] ;And right side for other one
1564 ; --- Now render the right top sides ---
1573 ; --- Return -- it's all over ---
1575 ADD R13,R13,#32 ;Restore the stack pointer
1577 LDMFD R13!,{R0-R5,R8,PC}^ ;Return to caller
1581 ;----- Draw the border types ------------------------------------------------
1583 ; All entry: R0 == pointer to icon coordinates block (writable)
1584 ; R9 == x coord of window origin on screen
1585 ; R10 == y coord of window origin on screen
1593 TST R14,#s_FAINTCHAN
1595 ADRNE R11,s_shadeCols
1603 STMFD R13!,{R0-R4,R14} ;Stack registers away
1604 LDMIA R0,{R1-R4} ;Load the coordinates
1607 MOV R1,R0 ;Keep pointer to box
1609 ; --- Draw bits of the border ---
1625 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1633 STMFD R13!,{R0-R4,R14} ;Stack registers away
1634 SUB R13,R13,#16 ;Make space for another blk
1635 LDMIA R0,{R1-R4} ;Load the coordinates
1643 MOV R1,R0 ;Keep pointer to box
1645 ; --- Draw bits of the border ---
1669 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1677 STMFD R13!,{R0-R4,R14} ;Stack registers away
1678 LDMIA R0,{R1-R4} ;Load the coordinates
1691 MOV R1,R0 ;Keep pointer to box
1693 ; --- Draw inside border ---
1709 ; --- Draw rim around the middle ---
1711 ; It's overkill, but I'll use the calls below for this
1721 ; --- Draw surrounding border ---
1723 BIC R11,R11,#1 ;Round pointer downwards
1739 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1746 STMFD R13!,{R0-R4,R14} ;Stack registers away
1747 LDMIA R0,{R1-R4} ;Load the coordinates
1750 MOV R1,R0 ;Save this away
1752 ; --- Fill in the inside section to overwrite marbling ---
1768 MOV R1,R0 ;Keep pointer to box
1770 ; --- Draw bits of the border ---
1786 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1794 STMFD R13!,{R0-R4,R14} ;Stack registers away
1795 LDMIA R0,{R1-R4} ;Load the coordinates
1798 SUB R14,R4,R2 ;Get height of box
1799 ADD R2,R2,R14,LSR #1 ;Centre R2 in box
1800 SUB R4,R2,#4 ;Move thing to right place
1801 ADD R2,R2,#4 ;And copy across
1802 SUB R3,R1,#4 ;Set up the nick width
1803 STMFD R13!,{R1-R4} ;Stash them on the stack
1804 MOV R1,R0 ;Keep pointer to box
1806 ; --- Draw bits of the border ---
1831 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1839 STMFD R13!,{R0-R4,R14} ;Stack registers away
1840 LDMIA R0,{R1-R4} ;Load the coordinates
1843 SUB R14,R4,R2 ;Get height of box
1844 ADD R2,R2,R14,LSR #1 ;Centre R2 in box
1845 MOV R4,R2 ;Move thing to right place
1846 SUB R3,R1,#4 ;Set up the nick width
1847 STMFD R13!,{R1-R4} ;Stash them on the stack
1848 MOV R1,R0 ;Keep pointer to box
1850 ; --- Draw bits of the border ---
1873 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1881 STMFD R13!,{R0-R10,R14} ;Stack registers away
1882 LDMIA R0,{R1-R4} ;Load the coordinates
1885 MOV R10,R0 ;Save this away
1886 LDR R9,[R10,#16] ;Load the icon's flags
1888 ; --- Find out about the icon's colours ---
1890 TST R9,#1<<6 ;Is it anti-aliased?
1891 BEQ %10brd7 ;No -- skip this bit out then
1893 BIC R9,R9,#&ff000000 ;Clear out the font handle
1894 MOV R2,#'F' ;Find font validation strings
1895 MOV R3,#0 ;Start from the beginning
1896 BL box_findValid ;Find the colour command
1897 CMP R2,#0 ;Was it not there at all?
1898 ORREQ R9,R9,#&07000000 ;No -- use default colours
1899 BEQ %10brd7 ;And skip to the end
1901 LDRB R0,[R2,#1] ;Load a byte from the string
1902 SUB R0,R0,#'0' ;Turn it into a number
1903 CMP R0,#10 ;Is it a letter, not a digit?
1904 SUBCS R0,R0,#7 ;Yes -- compensate for that
1905 CMP R0,#16 ;Is it lowercase?
1906 SUBCS R0,R0,#&20 ;Yes -- deal with that case
1908 LDRB R1,[R2,#2] ;Load the next byte too
1909 SUB R1,R1,#'0' ;Turn it into a number
1910 CMP R1,#10 ;Is it a letter, not a digit?
1911 SUBCS R1,R1,#7 ;Yes -- compensate for that
1912 CMP R1,#16 ;Is it lowercase?
1913 SUBCS R1,R1,#&20 ;Yes -- deal with that case
1915 ORR R9,R9,R0,LSL #28 ;Fit the background colour in
1916 ORR R9,R9,R1,LSL #24 ;And the foreground colour
1918 ; --- First plot the whole background ---
1920 10brd7 ADR R14,s_dx ;Point to the pixel sizes
1921 LDMIA R14,{R7,R8} ;Load them out nicely
1922 LDMFD R13!,{R3-R6} ;Load the coordinates out
1924 TST R9,#1<<5 ;Is the icon filled?
1925 BEQ %20brd7 ;No -- skip this bit out
1927 MOV R0,R9,LSR #28 ;Get the background colour
1928 AND R0,R0,#&f ;Clear all the other bits
1929 SWI XWimp_SetColour ;Set the bit's colour
1931 MOV R0,#plot_MOVE+plot_ABSOLUTE
1934 ADD R1,R1,R7 ;Don't overlap the border
1936 SWI XOS_Plot ;Move to the bottom left
1938 MOV R0,#plot_RECTFILL+plot_ABSOLUTE+plot_FORE
1943 SWI XOS_Plot ;Fill in the background
1945 ; --- Plot the foreground border now ---
1947 20brd7 MOV R0,R9,LSR #24 ;Get the foreground colour
1948 AND R0,R0,#&f ;Clear all the other bits
1949 SWI XWimp_SetColour ;Set the bit's colour
1951 MOV R0,#plot_MOVE+plot_ABSOLUTE
1954 SWI XOS_Plot ;Move to the bottom left
1956 MOV R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1960 SWI XOS_Plot ;Plot the left hand side
1962 MOV R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1967 SWI XOS_Plot ;Plot the top edge
1969 MOV R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1973 SWI XOS_Plot ;Plot the right hand side
1975 MOV R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1978 SWI XOS_Plot ;Plot the bottom edge
1980 ; --- Now plot a writable border (type 3) ---
1982 LDMIA R10,{R0-R3} ;Load the coordinates
1983 SUB R0,R0,#4 ;Modify for the extra border
1989 LDMFD R13!,{R0-R10,R14} ;Restore all the registers
1990 B brd3 ;And plot the writable border
1995 ;----- Mangle coordinates for the mode --------------------------------------
1997 ; --- box_convert ---
1999 ; Converts box given in R1-R4 by translating to screen coords and rounding
2000 ; down to pixel boundaries
2004 STMFD R13!,{R0,R14} ;Stash registers
2006 ; --- Convert to screen coordinates ---
2013 ; --- Round off to whole pixel sizes ---
2025 ;----- Set up the VDU variables in the buffer -------------------------------
2031 STMFD R13!,{R0-R3,R14} ;Stack some registers
2032 ADR R0,vdu_wanted ;Which ones do we want?
2033 ADR R1,s_dx ;Where do we want them?
2034 SWI XOS_ReadVduVariables ;Read the values
2035 LDMIA R1,{R0,R2} ;Read their values into regs
2036 CMP R2,#2 ;Is this a high-pixel mode?
2037 MOVEQ R3,#2 ;Yes -- use a default value
2039 MOVNE R3,R3,LSR R2 ;No -- divide up border
2042 MOV R0,R14,LSL R0 ;Convert these to pixel sizes
2044 STMIA R1,{R0,R2,R3} ;Store back in workspace
2045 LDMFD R13!,{R0-R3,PC}^ ;Return to caller
2047 vdu_wanted DCD vdu_XEIG
2053 ;----- Plot primitives ------------------------------------------------------
2057 ; Plots a vertical strip in the current foreground colour on the left of an
2060 ; On entry: R0 == pointer to the icon bounding box
2064 STMFD R13!,{R0-R3,R14} ;Keep the stack pointer busy
2065 MOV R3,R0 ;Keep the pointer safe
2066 LDMIA R3!,{R1,R2} ;Get the bottom left coord
2067 SUB R1,R1,#4 ;Make way for the border
2068 SUB R2,R2,#4 ;Make way for the border
2069 MOV R0,#plot_MOVE+plot_ABSOLUTE
2070 SWI XOS_Plot ;Move to first corner
2071 LDR R1,s_dx ;Get the pixel width
2072 RSB R1,R1,#4 ;Trim the width a little
2073 LDR R3,[R3,#4] ;Get the top coordinate
2074 SUB R2,R3,R2 ;Find the height of the strip
2075 LDR R3,s_dy ;Get the y pixel size
2076 SUB R2,R2,R3 ;And add that in too
2077 ADD R2,R2,#4 ;And add the border width
2078 MOV R0,#plot_RECTFILL+plot_FORE+plot_RELATIVE
2079 SWI XOS_Plot ;Plot the rectangle
2080 LDMFD R13!,{R0-R3,PC}^ ;Return to caller
2084 ; --- prim_right ---
2086 ; Plots a vertical strip in the current foreground colour on the right of an
2089 ; On entry: R0 == pointer to the icon bounding box
2093 STMFD R13!,{R0-R3,R14} ;Keep the stack pointer busy
2094 ADD R3,R0,#16 ;Point to the top of the box
2095 LDMDB R3!,{R1,R2} ;Get the top right coord
2096 LDR R0,s_dy ;Get the y pixel size
2098 ADD R2,R2,#4 ;Make way for the border
2099 MOV R0,#plot_MOVE+plot_ABSOLUTE
2100 SWI XOS_Plot ;Move to first corner
2101 LDR R1,s_dx ;Get the pixel width
2102 RSB R1,R1,#4 ;Trim the width a little
2103 LDR R3,[R3,#-4] ;Get the bottom coordinate
2104 SUB R2,R3,R2 ;Find the height of the strip
2105 SUB R2,R2,#4 ;And add the border width
2106 MOV R0,#plot_RECTFILL+plot_FORE+plot_RELATIVE
2107 SWI XOS_Plot ;Plot the rectangle
2108 LDMFD R13!,{R0-R3,PC}^ ;Return to caller
2112 ; --- prim_bottom ---
2114 ; Plots a horizontal strip in the current foreground colour along the bottom
2115 ; of an icon, with a little jagged bit on the left hand side.
2117 ; On entry: R0 == pointer to icon block
2122 STMFD R13!,{R0-R2,R7-R11,R14} ;Keep stack pointer moving
2124 ; --- Load the variables we need ---
2126 LDMIA R0,{R9-R11} ;Get useful coordinates out
2127 LDR R1,s_dx ;Get x pixel width
2128 LDR R8,s_dy ;Get y pixel width
2129 LDR R2,s_start ;Get start X offset
2131 ; --- Initialise variables for first loop ---
2133 SUB R9,R9,R2 ;Shift x0 back a little
2134 SUB R11,R11,R1 ;Shift x1 past icon edge
2135 SUB R2,R10,R8 ;Move y below the icon
2136 ADD R11,R11,#4 ;And make space for border
2137 RSB R7,R8,#4 ;Loop stops when R7==0
2139 ; --- Draw a line (loop body) ---
2141 00prim_bottom MOV R0,#plot_MOVE+plot_ABSOLUTE
2143 SWI XOS_Plot ;Move to the left of the line
2144 MOV R0,#plot_LINE+plot_FORE+plot_ABSOLUTE
2146 SWI XOS_Plot ;Draw the line
2148 ; --- Check if we've done (loop termination) ---
2150 SUBS R7,R7,R8 ;Decrement the counter
2151 LDMLTFD R13!,{R0-R2,R7-R11,PC}^ ;Return to caller
2153 ; --- Update coordinates (loop update) ---
2155 SUB R9,R9,R8 ;Move x coordinate back a bit
2156 SUB R2,R2,R8 ;Move y coordinate down a bit
2157 B %00prim_bottom ;And do it all again
2163 ; Plots a horizontal strip in the current foreground colour along the top
2164 ; of an icon, with a little jagged bit on the right hand side.
2166 ; On entry: R0 == pointer to icon block
2171 STMFD R13!,{R0-R2,R7-R11,R14} ;Keep stack pointer moving
2173 ; --- Load the variables we need ---
2175 LDMIA R0,{R8-R11} ;Get useful coordinates out
2176 MOV R9,R8 ;Don't want y0
2177 LDR R1,s_dx ;Get x pixel width
2178 LDR R8,s_dy ;Get y pixel width
2179 LDR R2,s_start ;Get start X offset
2181 ; --- Initialise variables for first loop ---
2183 SUB R9,R9,#4 ;Make space for border
2184 SUB R10,R10,R1 ;Shift x1 past icon edge
2185 ADD R10,R10,R2 ;And add on the little bitty
2186 MOV R2,R11 ;Move y above the icon
2187 RSB R7,R8,#4 ;Loop stops when R7==0
2189 ; --- Draw a line (loop body) ---
2191 00prim_top MOV R0,#plot_MOVE+plot_ABSOLUTE
2193 SWI XOS_Plot ;Move to the left of the line
2194 MOV R0,#plot_LINE+plot_FORE+plot_ABSOLUTE
2196 SWI XOS_Plot ;Draw the line
2198 ; --- Check if we've done (loop termination) ---
2200 SUBS R7,R7,R8 ;Decrement the counter
2201 LDMLTFD R13!,{R0-R2,R7-R11,PC}^ ;Return to caller
2203 ; --- Update coordinates (loop update) ---
2205 ADD R10,R10,R8 ;Move x coordinate on a bit
2206 ADD R2,R2,R8 ;Move y coordinate up a bit
2207 B %00prim_top ;And do it all again
2211 ;----- Workspace layout -----------------------------------------------------
2217 ; --- Graphics variables ---
2219 s_dx # 4 ;Horizontal pixel size (OS)
2220 s_dy # 4 ;Vertical pixel size (OS)
2221 s_start # 4 ;Offset into corner for plot
2223 ; --- Various other things ---
2225 s_flags # 4 ;Various Sculptix flags
2226 s_sarea # 4 ;The sprite area in tns icons
2230 s_colours # 4 ;Colours for the 3D bits
2231 s_shadeCols # 4 ;Colours for shaded 3D boxes
2232 s_slabcol # 1 ;Slabbing in colour
2233 s_rimcol # 1 ;Inner rim colour for type 2
2234 # 2 ;Padding to align
2236 ; --- Misc buffers ---
2238 s_buffer # 256 ;A big buffer for things
2242 s_UNSLAB EQU (1<<0) ;We've unslabbed this poll
2243 s_CHANNEL EQU (1<<1) ;Use channels, not ridges
2244 s_FAINTCHAN EQU (1<<2) ;Draw channel boxes faintly
2246 s_wsize EQU s_wend-s_wstart
2248 ;----- That's all, folks ----------------------------------------------------