Initial revision
[ssr] / StraySrc / Sculptrix / old-vsn / s / sculptrix
1 ;
2 ; sculptrix.s
3 ;
4 ; Draws pretty 3D boxes
5 ;
6 ; © 1994 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sculptrix.
12 ;
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)
16 ; any later version.
17 ;
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.
22 ;
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.
26
27 ;----- Change history -------------------------------------------------------
28 ;
29 ; Version By Change
30 ; ~~~~~~~ ~~ ~~~~~~
31 ; 1.00 MDW Initial version written
32 ;
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
36 ;
37 ; 1.02 MDW Fixed problem with multiple unslab ops in one poll
38 ;
39 ; 1.03 MDW Stopped excessive redrawing in group box rendering
40 ;
41 ; 1.04 MDW Done strange things to make text+sprite icons nice
42 ; Any contortions required are due solely to TMA.
43 ;
44 ; 1.05 MDW Filled in group box types 0 and 2 (ridge'n'plinth)
45 ;
46 ; 1.06 MDW Allowed user-changing of the 3D colours and things
47 ; Also included different colours for shaded borders
48 ;
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.
52 ;
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
57 ; slightly smaller!
58 ;
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.
62 ;
63 ; MDW Fixed writable border being black when it gets shaded
64 ;
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.
69 ;
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
73 ;
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.
77 ;
78 ; 1.13 MDW Fixed bug in mitre start position -- inserted RSB
79 ; to make it go in the right direction.
80 ;
81 ; 1.14 MDW Removed filling in groupbox type 0 to allow dbx
82 ; controls to be within group boxes.
83 ;
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).
93
94 ;----- Standard header ------------------------------------------------------
95
96 GET libs:header
97 GET libs:swis
98
99 GET sh.messages
100 IMPORT s_help
101
102 ;----- PLOT code numbers ----------------------------------------------------
103
104 plot_MOVE EQU 0
105 plot_FORE EQU 1
106 plot_INVERSE EQU 2
107 plot_BACK EQU 3
108
109 plot_RELATIVE EQU 0
110 plot_ABSOLUTE EQU 4
111
112 plot_RECTFILL EQU 96
113 plot_LINE EQU 0
114
115 ;----- VDU variable numbers -------------------------------------------------
116
117 vdu_XEIG EQU 4
118 vdu_YEIG EQU 5
119
120 ;----- Module header --------------------------------------------------------
121
122 AREA |!!!Module$$Header|,CODE,READONLY
123
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
135
136 ;----- Module strings -------------------------------------------------------
137
138 s_title DCB "Sculptrix",0
139
140 ;----- SWI name table -------------------------------------------------------
141
142 s_swin DCB "Sculptrix",0
143
144 DCB "RedrawWindow",0
145 DCB "DoSlab",0
146 DCB "SlabIcon",0
147 DCB "UnslabIcon",0
148 DCB "BoundingBox",0
149 DCB "PlotIcon",0
150 DCB "PlotGroupBox",0
151 DCB "SetSpriteArea",0
152 DCB "UpdateIcon",0
153 DCB "SlabColour",0
154
155 DCB 0
156
157 ;----- Command table --------------------------------------------------------
158
159 s_command DCB "Sculptrix_Colours",0
160 DCD cmd_colours
161 DCB 0,0,1,0
162 DCD synt_colours
163 DCD help_colours
164
165 DCB "Sculptrix_GroupType",0
166 DCD cmd_group
167 DCB 1,0,1,0
168 DCD synt_group
169 DCD help_group
170
171 DCD 0
172
173 ;----- Initialisation and finalisation --------------------------------------
174
175 s_init ROUT
176
177 STMFD R13!,{R14} ;Stack link register nicely
178
179 ; --- Get some workspace ---
180
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
187
188 ; --- Set initial values ---
189
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
199 MOV R2,#&0C00
200 ORR R2,R2,#&000E
201 ADR R3,s_colours
202 STMIA R3,{R0-R2}
203
204 ; --- I think that's it ---
205
206 LDMFD R13!,{PC}^ ;Return to caller happy
207
208 LTORG
209
210 s_die ROUT
211
212 STMFD R13!,{R11,R14}
213 MOV R11,R12 ;Keep the private word ptr
214 LDR R12,[R12] ;Find my workspace
215
216 ; --- Free my workspace ---
217
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
224
225 LTORG
226
227 ;----- Service call handling ------------------------------------------------
228
229 s_service ROUT
230
231 CMP R1,#&46 ;Is it a mode change?
232 MOVNES PC,R14 ;No -- return
233
234 LDR R12,[R12] ;Get my workspaxe
235 B vdu_set ;Set up the VDU variables
236
237
238 ;----- Command handlers -----------------------------------------------------
239
240 ; --- Sculptrix_Colours ---
241
242 cmd_colours ROUT
243
244 STMFD R13!,{R1-R5,R14} ;Save some registers
245 LDR R12,[R12] ;Locate my workspace pointer
246
247 ; --- If no argument, use the default ---
248
249 CMP R1,#0 ;Is there an argument?
250 ADREQ R0,cmd__defCol ;No -- point to default
251
252 ; --- Read normal 3D colours ---
253
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
261
262 ; --- Read shaded 3D colours ---
263
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
271
272 ; --- Read the other colours ---
273
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
280
281 ; --- Now store these away nicely ---
282
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
286
287 ; --- Convert R2 to binary ---
288
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
297
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
301
302 cmd__defCol DCB "4020CE",0
303
304 LTORG
305
306 ; --- Sculptrix_GroupType ---
307
308 cmd_group ROUT
309
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
318 STR R1,s_flags
319 MOVS PC,R14
320
321 LTORG
322
323 ;----- SWI names and numbers etc --------------------------------------------
324
325 s_swic ROUT
326
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
331
332 00s_swic B swi_redraw
333 B swi_doslab
334 B swi_slab
335 B swi_unslab
336 B swi_bbox
337 B swi_ploticon
338 B swi_plotgroup
339 B swi_spritearea
340 B swi_update
341 B swi_slabcol
342
343 01s_swic ADRL R0,msg_errBadSwi ;Point to error message
344 ORRS PC,R14,#V_flag ;Return with an error
345
346 LTORG
347
348 ;----- SWI handling ---------------------------------------------------------
349
350 ; --- Sculptrix_RedrawWindow ---
351 ;
352 ; R1 == pointer to redraw block
353
354 swi_redraw ROUT
355
356 STMFD R13!,{R0-R11,R14} ;Stack registers
357
358 ; --- Find the window origin ---
359
360 MOV R11,R1 ;Keep the pointer nicely
361 BL box_readRectangle ;Find everything about rdrw
362
363 ; --- Now go through the icons ---
364
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
370
371 ; --- Main loop -- go through each icon and plot ---
372
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
380
381 ; --- Find out whether the icon is visible ---
382
383 ADD R0,R1,#8 ;Point to coords block
384 LDMIA R0,{R0,R2-R4} ;Load the icon coordinates
385 CMP R0,R7
386 CMPLE R2,R8
387 CMPLE R5,R3
388 CMPLE R6,R4
389 BGT %01swi_redraw ;Not visible -- skip it
390
391 ADD R0,R1,#8 ;Point to icon block
392 BL box_ploticon
393
394 ; --- Ho-hum. Now do the next one ---
395
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
400
401 LTORG
402
403 ; --- Sculptrix_DoSlab ---
404 ;
405 ; On entry: R0 == window handle
406 ; R1 == icon number
407 ; R2 == colour to slab to
408 ;
409 ; On exit: R2 == old colour of icon, or -1 if icon couldn't be slabbed
410
411 swi_doslab ROUT
412
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
417
418 ; --- Find out if we need to do anything ---
419
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
426
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
434
435 ; --- Get the border type -- only 0 and 2 slab ---
436
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
442
443 ; --- It's a worthwhile icon ---
444
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
451
452 ; --- Update the border ---
453
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
457
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
464
465 TST R0,#&20 ;Is it set now?
466 ADDEQ R11,R11,#1 ;No -- use offset colours
467
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
471 SUB R4,R4,#4
472 ADD R5,R5,#4
473 ADD R6,R6,#4
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
479
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
485
486 ADD R3,R3,#4 ;Point back to the icon block
487 ADD R3,R3,R9
488 ADD R4,R4,#4
489 ADD R4,R4,R10
490 SUB R5,R5,#4
491 ADD R5,R5,R9
492 SUB R6,R6,#4
493 ADD R6,R6,R10
494
495 00swi_doslab ; --- Draw box (inline copy) ---
496 ;
497 ; We only draw the inner slabbed bit -- the rest doesn't
498 ; change even in the default type.
499
500 ADD R2,R1,#4
501 STMIA R2,{R3-R6} ;Store adjusted coords away
502
503 LDRB R0,[R11,#0]
504 SWI XWimp_SetColour
505 MOV R0,R2
506 BL prim_left
507 LDRB R0,[R11,#1]
508 SWI XWimp_SetColour
509 MOV R0,R2
510 BL prim_right
511 BL prim_bottom
512 LDRB R0,[R11,#0]
513 SWI XWimp_SetColour
514 MOV R0,R2
515 BL prim_top
516
517 ; --- Get another rectangle ---
518
519 SWI XWimp_GetRectangle
520 CMP R0,#0 ;Have we anything to do?
521 BNE %00swi_doslab ;Yes -- do it then, dummy
522
523 01swi_doslab ADD R13,R13,#44
524 LDMFD R13!,{R0-R11,PC}^
525
526 LTORG
527
528 ; --- Sculptrix_SlabIcon ---
529 ;
530 ; On entry: R0 == window handle
531 ; R1 == icon handle
532 ; R2 == pointer to 4 word slab descriptor to be filled in
533 ; On exit: --
534
535 swi_slab ROUT
536
537 STMFD R13!,{R0-R2,R10,R14} ;Keep link register safe
538
539 ; --- Fill in the caller's descriptor block ---
540
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
547
548 ; --- Slab the border in or out ---
549
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
554
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
563
564 ; --- Say to pause on unslabs in flags ---
565
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
569
570 ; --- Return to caller ---
571
572 LDMFD R13!,{R0-R2,R10,PC}^ ;Return to caller
573
574 LTORG
575
576 ; --- Sculptrix_UnslabIcon ---
577 ;
578 ; On entry: R2 == pointer to descriptor filled in by Sculptrix_SlabIcon
579 ; On exit: --
580
581 swi_unslab ROUT
582
583 STMFD R13!,{R0-R2,R10,R14} ;Stack my registers
584
585 ; --- Find out if we need to do any slabbing ---
586
587 LDR R14,[R2,#8] ;Get the icon colour
588 CMP R14,#-1 ;Is it nonslabbed?
589 LDMEQFD R13!,{R0-R2,R10,PC}^
590
591 ; --- Do we unslab quickly? ---
592
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
598
599 ; --- Wait the requisite quantity of time ---
600
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
606
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
610
611 ; --- Wait for the mouse to be released ---
612
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
616
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
621
622 ; --- Wait for the timer to elapse ---
623
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
629
630 ; --- Actually unslab the icon ---
631
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
636
637 ; --- Remember we've done this now ---
638
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
642
643 ; --- Return to caller ---
644
645 LDMFD R13!,{R0-R2,R10,PC}^ ;Return to caller
646
647 LTORG
648
649 ; --- Sculptrix_BoundingBox ---
650 ;
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
654
655 swi_bbox ROUT
656
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
669
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
679 SUB R3,R3,R0
680 SUB R4,R4,R0
681 ADD R5,R5,R0
682 ADD R6,R6,R0
683 STMIA R1,{R3-R6} ;Store the sizes back
684 LDMFD R13!,{R1-R6,PC}^ ;Return happy
685
686 01swi_bbox LDMIA R1,{R3-R6} ;Load the bounding box regs
687 SUB R3,R3,#4
688 ADD R5,R5,#4
689 STMIA R1,{R3-R6}
690 MOV R0,#1
691 LDMFD R13!,{R1-R6,PC}^ ;Return happy
692
693 02swi_bbox LDMIA R1,{R3-R6} ;Load the bounding box regs
694 SUB R3,R3,#8
695 SUB R4,R4,#8
696 ADD R5,R5,#8
697 ADD R6,R6,#32
698 STMIA R1,{R3-R6}
699 MOV R0,#1
700 LDMFD R13!,{R1-R6,PC}^ ;Return happy
701
702 box_borders DCB 4,8,12,8,4,4,0,12,4
703
704 ROUT
705
706 ; --- Sculptrix_PlotIcon ---
707 ;
708 ; On entry: R0 == pointer to icon block
709 ; R1 == pointer to redraw block
710
711 swi_ploticon ROUT
712
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
721
722 LTORG
723
724 ; --- Sculptrix_PlotGroup ---
725 ;
726 ; On entry: R0 == pointer to icon block
727 ; R1 == pointer to redraw block
728 ; R2 == border type
729 ; R3 == pointer to title string
730
731 swi_plotgroup ROUT
732
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
743
744 LTORG
745
746 ; --- Sculptrix_SetSpriteArea ---
747 ;
748 ; On entry: R0 == pointer to sprite area to use
749
750 swi_spritearea ROUT
751
752 STR R0,s_sarea ;Save it as sprite area ptr
753 MOVS PC,R14 ;Return to caller
754
755 ; --- Sculptrix_UpdateIcon ---
756 ;
757 ; On entry: R0 == window handle
758 ; R1 == icon handle to update
759
760 swi_update ROUT
761
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
774 SUB R1,R1,#16
775 ADD R3,R3,#16
776 ADD R14,R14,#16
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
781
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
788
789 80swi_update ADD R13,R13,#84 ;Reclaim all that stack
790 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
791
792 99swi_update ADD R13,R13,#88 ;Reclaim stack + R0
793 LDMFD R13!,{R1-R4,PC} ;Return with V still set
794
795 LTORG
796
797 ; --- Scultrix_SlabColour ---
798 ;
799 ; On entry: --
800 ;
801 ; On exit: R2 == standard slabbing-in colour
802
803 swi_slabcol LDRB R2,s_slabcol
804 MOVS PC,R14
805
806 ;----- Icon box redrawing ---------------------------------------------------
807
808 ; --- box_readRectangle ---
809 ;
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
814
815 box_readRectangle ROUT
816
817 CMP R1,#0 ;Is there a redraw block?
818 MOVEQ R9,#0 ;Yes -- don't translate box
819 MOVEQ R10,#0
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
826
827 ; --- Mangle the graphics rectangle ---
828
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
832 SUB R6,R6,R10
833 SUB R7,R7,R9
834 SUB R8,R8,R10
835
836 SUB R5,R5,#16 ;Add a little bit of leeway
837 SUB R6,R6,#32
838 ADD R7,R7,#16
839 ADD R8,R8,#16
840
841 MOVS PC,R14
842
843 LTORG
844
845 ; --- box_ploticon ---
846 ;
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
850
851 box_ploticon ROUT
852
853 MOV R3,#0
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
858 CMP R2,#0 ;Check
859 MOVEQS PC,R14 ;No -- return to caller
860
861 ; --- If the border has a capital letter, invert ---
862 ;
863 ; Also, choose the right colours for shaded boxes
864
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
871
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
875
876 ; --- Get the render type, and handle as required ---
877
878 LDRB R3,[R2,#1] ;Get the border type number
879 ORR R4,R3,#&20 ;Convert to lower case
880
881 CMP R4,#'g' ;Is it a group box type?
882 BEQ box_plotgroup ;Yes -- plot a group box
883
884 CMP R4,#'s' ;Is it a gadget text/sprite?
885 BEQ box_plottns ;Yes -- plot cunningly
886
887 ; --- Dispatch normal group border numbers ---
888
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
893
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
903 02box_ploticon
904
905 03box_ploticon MOV R3,R2 ;Point to that command
906 B %00box_ploticon ;And find the next string
907
908 LTORG
909
910 ; --- box_setcolour ---
911 ;
912 ; On entry: R0 == window handle
913 ; R1 == icon handle
914 ; R2 == colour to set
915 ; On exit: R2 == old colour of icon
916
917 box_setcolour ROUT
918
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
927
928 ; --- Check for fonts ---
929
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
949
950 ; --- Prod the icon into redrawing ---
951
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
960
961 ; --- Just set the colours in the time-honoured way ---
962
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
974
975 box_hexdigits DCB "0123456789ABCDEF",0
976
977 LTORG
978
979 ;----- Messing with validation strings --------------------------------------
980
981 ; --- box_findValid ---
982 ;
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
988
989 box_findValid ROUT
990
991 STMFD R13!,{R3} ;Preserve for later use
992
993 ; --- Ensure the icon is text and indirected ---
994
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
1002 ADDNE R13,R13,#4
1003 MOVNES PC,R14 ;No -- return huffily
1004
1005 ; --- Find the validation string ---
1006
1007 LDR R3,[R0,#24] ;Get pointer to valid string
1008 CMP R3,#-1 ;Is it empty?
1009 MOVEQ R2,#0 ;Yes -- not found
1010 ADDEQ R13,R13,#4
1011 MOVEQS PC,R14
1012
1013 ; --- Start from the right index ---
1014
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
1021
1022 ; --- Check the first char of a validation string ---
1023
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
1030
1031 ; --- Skip ahead to the next validation string ---
1032
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
1045
1046 LTORG
1047
1048 ;----- Plot text+sprite icons -----------------------------------------------
1049
1050 ; --- box_plottns ---
1051 ;
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
1055
1056 box_plottns ROUT
1057
1058 STMFD R13!,{R0-R4,R14} ;Stack some registers
1059
1060 ; --- Now copy the sprite name into the buffer ---
1061
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
1068
1069 ; --- Copy the sprite name into the buffer ---
1070
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
1080
1081 ; --- Now read the sprite information ---
1082
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
1092
1093 05 MOV R0,#40 ;Read sprite information
1094 ADR R2,s_buffer ;Point to the block
1095 SWI XWimp_SpriteOp
1096
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
1100
1101 ; --- Find the width of the sprite, then ---
1102
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
1107
1108 ; --- Plot the icon to avoid strangeness ---
1109
1110 LDR R1,[R13,#0] ;Get the icon block pointer
1111 SWI XWimp_PlotIcon ;Plot the icon onto screen
1112
1113 ; --- Copy the text string into the buffer ---
1114
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
1118
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
1128
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
1134
1135 ; --- Now plot the text part ---
1136
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
1157
1158 ; --- Tidy up and leave ---
1159
1160 99box_plottns LDMFD R13!,{R0-R4,PC}^ ;Return to caller if OK
1161
1162 LTORG
1163
1164 ;----- Plot group boxes -----------------------------------------------------
1165
1166 ; --- box_plotgroup ---
1167 ;
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
1171
1172 box_plotgroup ROUT
1173
1174 STMFD R13!,{R0-R2,R14} ;Stack some registers
1175
1176 ; --- Copy the string into the buffer ---
1177
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
1181
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
1191
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
1197
1198 ; --- Now plot the group border ---
1199
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
1205
1206 ; --- Tidy up and leave ---
1207
1208 03box_plotgroup LDMFD R13!,{R0-R2,PC}^ ;Return to caller if OK
1209
1210 LTORG
1211
1212 ; --- box_dogroup ---
1213 ;
1214 ; On entry: R0 == pointer to coordinates box
1215 ; R1 == group border type number
1216 ; R2 == pointer to group title string
1217
1218 box_dogroup ROUT
1219
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
1228
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
1233
1234 02box_dogroup LDMFD R13!,{R11,PC} ;Return to caller
1235
1236 ;----- Drawing group borders ------------------------------------------------
1237
1238 ; --- grp_titleicon ---
1239 ;
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
1244
1245 grp_titleicon ROUT
1246
1247 STMFD R13!,{R0-R5,R14} ;Stash registers away nicely
1248
1249 ; --- Work out the length of the string ---
1250
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
1256
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
1264
1265 ; --- Work out the width of the string ---
1266
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
1272 MOV R2,R1
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
1277 MOV R2,R3
1278 SWI XFont_ConverttoOS ;Convert back to OS units
1279 ADD R5,R1,#16 ;Get the string width
1280
1281 ; --- Now bodge the icon block ---
1282
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
1290
1291 ; --- Bodge the rest of the icon ---
1292
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
1301
1302 LDMFD R13!,{R0-R5,PC}^ ;Return to caller
1303
1304 ; --- grp_fillBorder ---
1305 ;
1306 ; On entry: R5-R8 == box coordinates (!)
1307 ; R9,R10 == window origin coordinates on the screen
1308 ;
1309 ; Removed in version 1.14
1310
1311 [ {FALSE}
1312
1313 grp_fillBorder ROUT
1314
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
1330
1331 LTORG
1332 ]
1333
1334 ; --- grp 0 ---
1335
1336 grp0 STMFD R13!,{R1-R8,R14} ;Stash registers
1337
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
1342
1343 ; --- Translate the icon block ---
1344
1345 MOV R1,#16 ;Small offset here
1346 BL grp_titleicon ;Find the icon position
1347
1348 ; --- Now display the main border ---
1349
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
1355
1356 ; --- Now display the main title border ---
1357
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
1366
1367 ; --- grp 1 ---
1368
1369 grp1 STMFD R13!,{R1-R8,R14} ;Stash registers
1370
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
1374
1375 ; --- Translate the icon block ---
1376
1377 MOV R1,#16 ;Small offset here
1378 BL grp_titleicon ;Find the icon position
1379
1380 ; --- Now display the main border ---
1381
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
1390
1391 ; --- Now display the main title border ---
1392
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
1398
1399 ; --- Stop the top bit from being filled ---
1400
1401 LDR R0,[R1,#16]
1402 BIC R0,R0,#(1<<5) ;Clear filled flag
1403 STR R0,[R1,#16]
1404
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
1408
1409 ; --- grp 2 ---
1410
1411 grp2 STMFD R13!,{R1-R8,R14} ;Stash registers
1412
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
1417
1418 ; --- Translate the icon block ---
1419
1420 MOV R1,#32 ;Large offset here
1421 BL grp_titleicon ;Find the icon position
1422
1423 ; --- Now display the main border ---
1424
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
1430
1431 ; --- Now display the main title border ---
1432
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
1441
1442 ; --- grp 3 ---
1443
1444 grp3 STMFD R13!,{R1-R8,R14} ;Stash registers
1445
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
1449
1450 ; --- Translate the icon block ---
1451
1452 MOV R1,#32 ;Small offset here
1453 BL grp_titleicon ;Find the icon position
1454
1455 ; --- Now display the main border ---
1456
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
1465
1466 ; --- Now display the main title border ---
1467
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
1473
1474 ; --- Stop the top bit from being filled ---
1475
1476 LDR R0,[R1,#16]
1477 BIC R0,R0,#(1<<5) ;Clear filled flag
1478 STR R0,[R1,#16]
1479
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
1483
1484 ; --- gborder ---
1485 ;
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
1490 ;
1491 ; Plots a group border such that it doesn't overlap the title icon at all.
1492
1493 gborder ROUT
1494
1495 STMFD R13!,{R0-R5,R8,R14} ;Stack registers away
1496 MOV R8,R1 ;Keep this pointer safe
1497
1498 ; --- Now convert all the boxes to screen coords ---
1499
1500 LDMIA R0,{R1-R4} ;Get the straight box
1501 BL box_convert
1502 STMIA R0,{R1-R4} ;Write it back nicely
1503
1504 SUB R1,R1,#4 ;Now expand it a little
1505 SUB R2,R2,#4
1506 ADD R3,R3,#4
1507 ADD R4,R4,#4
1508 STMFD R13!,{R1-R4} ;Stash them on the stack
1509
1510 LDMIA R8,{R1-R4} ;Get the title position
1511 BL box_convert
1512
1513 STMFD R13!,{R1-R4} ;Save them on the stack too
1514
1515 ; --- Now render all the parts except for the top ---
1516
1517 MOV R1,R0
1518 LDRB R0,[R11,#0]
1519 SWI XWimp_SetColour
1520 ADD R0,R13,#16
1521 BL prim_left
1522 MOV R0,R1
1523 BL prim_right
1524 LDRB R0,[R11,#1]
1525 SWI XWimp_SetColour
1526 ADD R0,R13,#16
1527 BL prim_right
1528 BL prim_bottom
1529 MOV R0,R1
1530 BL prim_left
1531 LDRB R0,[R11,#0]
1532 SWI XWimp_SetColour
1533 MOV R0,R1
1534 BL prim_bottom
1535
1536 ; --- Now fix up the top coordinates ---
1537
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
1543
1544 ; --- Now render the left top sides ---
1545
1546 ADD R0,R13,#16
1547 BL prim_top
1548 LDRB R0,[R11,#1]
1549 SWI XWimp_SetColour
1550 MOV R0,R1
1551 BL prim_top
1552
1553 ; --- Now get the right top sides ---
1554
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
1558
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
1563
1564 ; --- Now render the right top sides ---
1565
1566 MOV R0,R1
1567 BL prim_top
1568 LDRB R0,[R11,#0]
1569 SWI XWimp_SetColour
1570 ADD R0,R13,#16
1571 BL prim_top
1572
1573 ; --- Return -- it's all over ---
1574
1575 ADD R13,R13,#32 ;Restore the stack pointer
1576
1577 LDMFD R13!,{R0-R5,R8,PC}^ ;Return to caller
1578
1579 LTORG
1580
1581 ;----- Draw the border types ------------------------------------------------
1582 ;
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
1586
1587 ; --- brd8 ---
1588
1589 brd8 ROUT
1590
1591 STMFD R13!,{R14}
1592 LDR R14,s_flags
1593 TST R14,#s_FAINTCHAN
1594 ANDNE R14,R11,#3
1595 ADRNE R11,s_shadeCols
1596 ADDNE R11,R11,R14
1597 LDMFD R13!,{R14}
1598
1599 ; --- brd0 ---
1600
1601 brd0 ROUT
1602
1603 STMFD R13!,{R0-R4,R14} ;Stack registers away
1604 LDMIA R0,{R1-R4} ;Load the coordinates
1605 BL box_convert
1606 STMIA R0,{R1-R4}
1607 MOV R1,R0 ;Keep pointer to box
1608
1609 ; --- Draw bits of the border ---
1610
1611 LDRB R0,[R11,#0]
1612 SWI XWimp_SetColour
1613 MOV R0,R1
1614 BL prim_left
1615 LDRB R0,[R11,#1]
1616 SWI XWimp_SetColour
1617 MOV R0,R1
1618 BL prim_right
1619 BL prim_bottom
1620 LDRB R0,[R11,#0]
1621 SWI XWimp_SetColour
1622 MOV R0,R1
1623 BL prim_top
1624
1625 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1626
1627 LTORG
1628
1629 ; --- brd1 ---
1630
1631 brd1 ROUT
1632
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
1636 BL box_convert
1637 STMIA R0,{R1-R4}
1638 SUB R1,R1,#4
1639 SUB R2,R2,#4
1640 ADD R3,R3,#4
1641 ADD R4,R4,#4
1642 STMIA R13,{R1-R4}
1643 MOV R1,R0 ;Keep pointer to box
1644
1645 ; --- Draw bits of the border ---
1646
1647 LDRB R0,[R11,#0]
1648 SWI XWimp_SetColour
1649 MOV R0,R13
1650 BL prim_left
1651 MOV R0,R1
1652 BL prim_right
1653 LDRB R0,[R11,#1]
1654 SWI XWimp_SetColour
1655 MOV R0,R13
1656 BL prim_right
1657 BL prim_bottom
1658 MOV R0,R1
1659 BL prim_left
1660 BL prim_top
1661 LDRB R0,[R11,#0]
1662 SWI XWimp_SetColour
1663 MOV R0,R13
1664 BL prim_top
1665 MOV R0,R1
1666 BL prim_bottom
1667
1668 ADD R13,R13,#16
1669 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1670
1671 LTORG
1672
1673 ; --- brd2 ---
1674
1675 brd2 ROUT
1676
1677 STMFD R13!,{R0-R4,R14} ;Stack registers away
1678 LDMIA R0,{R1-R4} ;Load the coordinates
1679 BL box_convert
1680 STMIA R0,{R1-R4}
1681 SUB R1,R1,#4
1682 SUB R2,R2,#4
1683 ADD R3,R3,#4
1684 ADD R4,R4,#4
1685 STMFD R13!,{R1-R4}
1686 SUB R1,R1,#4
1687 SUB R2,R2,#4
1688 ADD R3,R3,#4
1689 ADD R4,R4,#4
1690 STMFD R13!,{R1-R4}
1691 MOV R1,R0 ;Keep pointer to box
1692
1693 ; --- Draw inside border ---
1694
1695 LDRB R0,[R11,#0]
1696 SWI XWimp_SetColour
1697 MOV R0,R1
1698 BL prim_left
1699 LDRB R0,[R11,#1]
1700 SWI XWimp_SetColour
1701 MOV R0,R1
1702 BL prim_right
1703 BL prim_bottom
1704 LDRB R0,[R11,#0]
1705 SWI XWimp_SetColour
1706 MOV R0,R1
1707 BL prim_top
1708
1709 ; --- Draw rim around the middle ---
1710 ;
1711 ; It's overkill, but I'll use the calls below for this
1712
1713 LDR R0,s_rimcol
1714 SWI XWimp_SetColour
1715 ADD R0,R13,#16
1716 BL prim_left
1717 BL prim_right
1718 BL prim_top
1719 BL prim_bottom
1720
1721 ; --- Draw surrounding border ---
1722
1723 BIC R11,R11,#1 ;Round pointer downwards
1724 LDR R0,[R11,#1]
1725 SWI XWimp_SetColour
1726 MOV R0,R13
1727 BL prim_left
1728 LDR R0,[R11,#0]
1729 SWI XWimp_SetColour
1730 MOV R0,R13
1731 BL prim_right
1732 BL prim_bottom
1733 LDR R0,[R11,#1]
1734 SWI XWimp_SetColour
1735 MOV R0,R13
1736 BL prim_top
1737
1738 ADD R13,R13,#32
1739 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1740
1741 LTORG
1742 ; --- brd3 ---
1743
1744 brd3 ROUT
1745
1746 STMFD R13!,{R0-R4,R14} ;Stack registers away
1747 LDMIA R0,{R1-R4} ;Load the coordinates
1748 BL box_convert
1749 STMIA R0,{R1-R4}
1750 MOV R1,R0 ;Save this away
1751
1752 ; --- Fill in the inside section to overwrite marbling ---
1753
1754 MOV R0,#1
1755 SWI XWimp_SetColour
1756 MOV R0,R1
1757 BL prim_left
1758 BL prim_right
1759 BL prim_bottom
1760 BL prim_top
1761
1762 LDMIA R0,{R1-R4}
1763 SUB R1,R1,#4
1764 SUB R2,R2,#4
1765 ADD R3,R3,#4
1766 ADD R4,R4,#4
1767 STMIA R0,{R1-R4}
1768 MOV R1,R0 ;Keep pointer to box
1769
1770 ; --- Draw bits of the border ---
1771
1772 LDRB R0,[R11,#1]
1773 SWI XWimp_SetColour
1774 MOV R0,R1
1775 BL prim_left
1776 LDRB R0,[R11,#0]
1777 SWI XWimp_SetColour
1778 MOV R0,R1
1779 BL prim_right
1780 BL prim_bottom
1781 LDRB R0,[R11,#1]
1782 SWI XWimp_SetColour
1783 MOV R0,R1
1784 BL prim_top
1785
1786 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1787
1788 LTORG
1789
1790 ; --- brd5 ---
1791
1792 brd5 ROUT
1793
1794 STMFD R13!,{R0-R4,R14} ;Stack registers away
1795 LDMIA R0,{R1-R4} ;Load the coordinates
1796 BL box_convert
1797 STMIA R0,{R1-R4}
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
1805
1806 ; --- Draw bits of the border ---
1807
1808 LDRB R0,[R11,#0]
1809 SWI XWimp_SetColour
1810 MOV R0,R1
1811 BL prim_left
1812 LDRB R0,[R11,#1]
1813 SWI XWimp_SetColour
1814 MOV R0,R1
1815 BL prim_right
1816 BL prim_bottom
1817 MOV R0,R13
1818 BL prim_top
1819 LDRB R0,[R11,#0]
1820 SWI XWimp_SetColour
1821 MOV R0,R1
1822 BL prim_top
1823 LDMIA R1,{R1-R3}
1824 LDR R2,[R13,#4]
1825 ADD R1,R3,#4
1826 STMIA R13,{R1-R3}
1827 MOV R0,R13
1828 BL prim_bottom
1829
1830 ADD R13,R13,#16
1831 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1832
1833 LTORG
1834
1835 ; --- brd6 ---
1836
1837 brd6 ROUT
1838
1839 STMFD R13!,{R0-R4,R14} ;Stack registers away
1840 LDMIA R0,{R1-R4} ;Load the coordinates
1841 BL box_convert
1842 STMIA R0,{R1-R4}
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
1849
1850 ; --- Draw bits of the border ---
1851
1852 LDRB R0,[R11,#1]
1853 SWI XWimp_SetColour
1854 MOV R0,R13
1855 BL prim_left
1856 LDRB R0,[R11,#0]
1857 SWI XWimp_SetColour
1858 MOV R0,R13
1859 BL prim_top
1860
1861 LDMIA R1,{R1-R3}
1862 LDR R2,[R13,#4]
1863 ADD R1,R3,#4
1864 STMIA R13,{R1-R3}
1865
1866 BL prim_right
1867 LDRB R0,[R11,#1]
1868 SWI XWimp_SetColour
1869 MOV R0,R13
1870 BL prim_bottom
1871
1872 ADD R13,R13,#16
1873 LDMFD R13!,{R0-R4,PC}^ ;Return to caller
1874
1875 LTORG
1876
1877 ; --- brd7 ---
1878
1879 brd7 ROUT
1880
1881 STMFD R13!,{R0-R10,R14} ;Stack registers away
1882 LDMIA R0,{R1-R4} ;Load the coordinates
1883 BL box_convert
1884 STMFD R13!,{R1-R4}
1885 MOV R10,R0 ;Save this away
1886 LDR R9,[R10,#16] ;Load the icon's flags
1887
1888 ; --- Find out about the icon's colours ---
1889
1890 TST R9,#1<<6 ;Is it anti-aliased?
1891 BEQ %10brd7 ;No -- skip this bit out then
1892
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
1900
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
1907
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
1914
1915 ORR R9,R9,R0,LSL #28 ;Fit the background colour in
1916 ORR R9,R9,R1,LSL #24 ;And the foreground colour
1917
1918 ; --- First plot the whole background ---
1919
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
1923
1924 TST R9,#1<<5 ;Is the icon filled?
1925 BEQ %20brd7 ;No -- skip this bit out
1926
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
1930
1931 MOV R0,#plot_MOVE+plot_ABSOLUTE
1932 SUB R1,R3,#4
1933 SUB R2,R4,#4
1934 ADD R1,R1,R7 ;Don't overlap the border
1935 ADD R2,R2,R8
1936 SWI XOS_Plot ;Move to the bottom left
1937
1938 MOV R0,#plot_RECTFILL+plot_ABSOLUTE+plot_FORE
1939 ADD R1,R5,#4
1940 ADD R2,R6,#4
1941 SUB R1,R1,R7,LSL #1
1942 SUB R2,R2,R8,LSL #1
1943 SWI XOS_Plot ;Fill in the background
1944
1945 ; --- Plot the foreground border now ---
1946
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
1950
1951 MOV R0,#plot_MOVE+plot_ABSOLUTE
1952 SUB R1,R3,#4
1953 SUB R2,R4,#4
1954 SWI XOS_Plot ;Move to the bottom left
1955
1956 MOV R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1957 ADD R1,R5,#4
1958 SUB R1,R1,R7
1959 SUB R2,R4,#4
1960 SWI XOS_Plot ;Plot the left hand side
1961
1962 MOV R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1963 ADD R1,R5,#4
1964 SUB R1,R1,R7
1965 ADD R2,R6,#4
1966 SUB R2,R2,R8
1967 SWI XOS_Plot ;Plot the top edge
1968
1969 MOV R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1970 SUB R1,R3,#4
1971 ADD R2,R6,#4
1972 SUB R2,R2,R8
1973 SWI XOS_Plot ;Plot the right hand side
1974
1975 MOV R0,#plot_LINE+plot_ABSOLUTE+plot_FORE
1976 SUB R1,R3,#4
1977 SUB R2,R4,#4
1978 SWI XOS_Plot ;Plot the bottom edge
1979
1980 ; --- Now plot a writable border (type 3) ---
1981
1982 LDMIA R10,{R0-R3} ;Load the coordinates
1983 SUB R0,R0,#4 ;Modify for the extra border
1984 SUB R1,R1,#4
1985 ADD R2,R2,#4
1986 ADD R3,R3,#4
1987 STMIA R10,{R0-R3}
1988
1989 LDMFD R13!,{R0-R10,R14} ;Restore all the registers
1990 B brd3 ;And plot the writable border
1991
1992 LTORG
1993
1994
1995 ;----- Mangle coordinates for the mode --------------------------------------
1996
1997 ; --- box_convert ---
1998 ;
1999 ; Converts box given in R1-R4 by translating to screen coords and rounding
2000 ; down to pixel boundaries
2001
2002 box_convert ROUT
2003
2004 STMFD R13!,{R0,R14} ;Stash registers
2005
2006 ; --- Convert to screen coordinates ---
2007
2008 ADD R1,R1,R9
2009 ADD R2,R2,R10
2010 ADD R3,R3,R9
2011 ADD R4,R4,R10
2012
2013 ; --- Round off to whole pixel sizes ---
2014
2015 LDR R0,s_dx
2016 LDR R14,s_dy
2017 SUB R0,R0,#1
2018 SUB R14,R14,#1
2019 BIC R1,R1,R0
2020 BIC R2,R2,R14
2021 BIC R3,R3,R0
2022 BIC R4,R4,R14
2023 LDMFD R13!,{R0,PC}
2024
2025 ;----- Set up the VDU variables in the buffer -------------------------------
2026
2027 ; --- vdu_set ---
2028
2029 vdu_set ROUT
2030
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
2038 MOVNE R3,#4
2039 MOVNE R3,R3,LSR R2 ;No -- divide up border
2040 RSBNE R3,R3,#4
2041 MOV R14,#1
2042 MOV R0,R14,LSL R0 ;Convert these to pixel sizes
2043 MOV R2,R14,LSL R2
2044 STMIA R1,{R0,R2,R3} ;Store back in workspace
2045 LDMFD R13!,{R0-R3,PC}^ ;Return to caller
2046
2047 vdu_wanted DCD vdu_XEIG
2048 DCD vdu_YEIG
2049 DCD -1
2050
2051 LTORG
2052
2053 ;----- Plot primitives ------------------------------------------------------
2054
2055 ; --- prim_left ---
2056 ;
2057 ; Plots a vertical strip in the current foreground colour on the left of an
2058 ; icon box.
2059 ;
2060 ; On entry: R0 == pointer to the icon bounding box
2061
2062 prim_left ROUT
2063
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
2081
2082 LTORG
2083
2084 ; --- prim_right ---
2085 ;
2086 ; Plots a vertical strip in the current foreground colour on the right of an
2087 ; icon box.
2088 ;
2089 ; On entry: R0 == pointer to the icon bounding box
2090
2091 prim_right ROUT
2092
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
2097 SUB R2,R2,R0
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
2109
2110 LTORG
2111
2112 ; --- prim_bottom ---
2113 ;
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.
2116 ;
2117 ; On entry: R0 == pointer to icon block
2118
2119
2120 prim_bottom ROUT
2121
2122 STMFD R13!,{R0-R2,R7-R11,R14} ;Keep stack pointer moving
2123
2124 ; --- Load the variables we need ---
2125
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
2130
2131 ; --- Initialise variables for first loop ---
2132
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
2138
2139 ; --- Draw a line (loop body) ---
2140
2141 00prim_bottom MOV R0,#plot_MOVE+plot_ABSOLUTE
2142 MOV R1,R9
2143 SWI XOS_Plot ;Move to the left of the line
2144 MOV R0,#plot_LINE+plot_FORE+plot_ABSOLUTE
2145 MOV R1,R11
2146 SWI XOS_Plot ;Draw the line
2147
2148 ; --- Check if we've done (loop termination) ---
2149
2150 SUBS R7,R7,R8 ;Decrement the counter
2151 LDMLTFD R13!,{R0-R2,R7-R11,PC}^ ;Return to caller
2152
2153 ; --- Update coordinates (loop update) ---
2154
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
2158
2159 LTORG
2160
2161 ; --- prim_top ---
2162 ;
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.
2165 ;
2166 ; On entry: R0 == pointer to icon block
2167
2168
2169 prim_top ROUT
2170
2171 STMFD R13!,{R0-R2,R7-R11,R14} ;Keep stack pointer moving
2172
2173 ; --- Load the variables we need ---
2174
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
2180
2181 ; --- Initialise variables for first loop ---
2182
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
2188
2189 ; --- Draw a line (loop body) ---
2190
2191 00prim_top MOV R0,#plot_MOVE+plot_ABSOLUTE
2192 MOV R1,R9
2193 SWI XOS_Plot ;Move to the left of the line
2194 MOV R0,#plot_LINE+plot_FORE+plot_ABSOLUTE
2195 MOV R1,R10
2196 SWI XOS_Plot ;Draw the line
2197
2198 ; --- Check if we've done (loop termination) ---
2199
2200 SUBS R7,R7,R8 ;Decrement the counter
2201 LDMLTFD R13!,{R0-R2,R7-R11,PC}^ ;Return to caller
2202
2203 ; --- Update coordinates (loop update) ---
2204
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
2208
2209 LTORG
2210
2211 ;----- Workspace layout -----------------------------------------------------
2212
2213 ^ 0,R12
2214
2215 s_wstart # 0
2216
2217 ; --- Graphics variables ---
2218
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
2222
2223 ; --- Various other things ---
2224
2225 s_flags # 4 ;Various Sculptix flags
2226 s_sarea # 4 ;The sprite area in tns icons
2227
2228 ; --- Colours ---
2229
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
2235
2236 ; --- Misc buffers ---
2237
2238 s_buffer # 256 ;A big buffer for things
2239
2240 s_wend # 0
2241
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
2245
2246 s_wsize EQU s_wend-s_wstart
2247
2248 ;----- That's all, folks ----------------------------------------------------
2249
2250 END