chiark / gitweb /
Initial revision
[ssr] / StraySrc / Sculptrix / sculptrix / s / border
1 ;
2 ; border.s
3 ;
4 ; Plots borders given an icon block and a definition of the border shape
5 ;
6 ; © 1995-1998 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 ;----- Standard header ------------------------------------------------------
28
29                 GET     libs:header
30                 GET     libs:swis
31
32                 GET     libs:stream
33
34 ;----- External dependencies ------------------------------------------------
35
36                 GET     sh.colours
37                 GET     sh.wSpace
38
39                 GET     sh.messages
40
41 ;----- The idea -------------------------------------------------------------
42 ;
43 ; We store the border shapes as commands in blocks, and then read them out
44 ; when plotting needs to be done.
45 ;
46 ; The commands are very simple, and are one byte wide each.  Some commands
47 ; have arguments which are stored in the following byte or word.  Whole
48 ; word arguments are preceded by padding to a word boundary.  It ends up
49 ; looking a bit like a simple `machine code'.
50
51 ;----- Main code ------------------------------------------------------------
52
53                 AREA    |Module$$Code|,CODE,READONLY
54
55 ; --- border_plot ---
56 ;
57 ; On entry:     R0 == pointer to border defintion
58 ;               R1 == pointer to icon block
59 ;               R2,R3 == window origin position
60 ;               R4 == pointer to colour table
61 ;               R5 == group box title width (optional)
62 ;               R6 == group box title address (optional)
63 ;
64 ; On exit:      May return an error
65 ;
66 ; Use:          Plots a border using the border definition.
67
68                 EXPORT  border_plot
69 border_plot     ROUT
70
71                 STMFD   R13!,{R0-R11,R14}       ;Save lots of registers
72
73                 ; --- Set up some environment ---
74
75                 MOV     R10,R0                  ;Point at the border routine
76
77                 ADR     R14,sculpt_vduVars      ;Point to the VDU variables
78                 LDMIA   R14,{R7-R9}             ;Load these for the rule rtns
79
80                 LDMIA   R1,{R4-R6,R14}          ;Load the icon position
81
82                 SUB     R0,R7,#1                ;Turn this into a bitmask
83                 BIC     R4,R4,R0                ;Mask the x coordinates
84                 BIC     R6,R6,R0                ;To avoid nasty problems
85                 SUB     R0,R8,#1                ;Turn this into a bitmask
86                 BIC     R5,R5,R0                ;Mask the y coordinates
87                 BIC     R14,R14,R0              ;To avoid nasty problems
88
89                 ADD     R4,R4,R2                ;Convert to screen coords
90                 ADD     R5,R5,R3                ;Convert to screen coords
91                 ADD     R6,R6,R2                ;Convert to screen coords
92                 ADD     R14,R14,R3              ;Convert to screen coords
93
94                 STMFD   R13!,{R4-R6,R14}        ;These are initial reg values
95                 MOV     R11,R13                 ;Remember this position
96
97                 ; --- Now start executing ---
98
99 border__main    LDRB    R14,[R10],#1            ;Load the next instruction
100                 AND     R0,R14,#3               ;Fetch immediate op bits
101                 BIC     R14,R14,#3              ;Clear them from the byte
102                 CMP     R14,#(%10-%00)          ;Is instruction known?
103                 ADDCC   PC,PC,R14               ;Yes -- dispatch it then
104                 B       %10border_plot          ;If unknown, report error
105
106 00              B       border__ret             ;End the routine
107                 B       border__iLoad           ;Load a value from the icon
108                 B       border__load            ;Load a stored value
109                 B       border__ldCtr           ;Load a centrepoint
110                 B       border__op              ;Do an op on the value
111                 B       border__store           ;Store value in output blk
112                 B       border__stdCol          ;Standard colour selection
113                 B       border__colour          ;Other colour ops
114                 B       border__plot            ;Plot a rule
115                 B       border__skipTtl         ;Skip over the group title
116                 B       border__plotGrp         ;Plot a group box
117                 B       border__call            ;Call a subroutine
118
119 10border_plot   ADRL    R0,msg_errBadOpcode     ;Point to the error message
120                 ADD     R13,R11,#16+4           ;Restore the stack pointer
121                 LDMFD   R13!,{R1-R11,R14}       ;Restore registers
122                 ORRS    PC,R14,#V_flag          ;And return the error
123
124                 ; --- border__ret ---
125
126 border__ret     CMP     R13,R11                 ;Are we at top level?
127                 LDMCCFD R13!,{R10}              ;No -- restore our IP
128                 BCC     border__main            ;And continue
129
130                 ADD     R13,R11,#16             ;Restore stack pointer
131                 LDMFD   R13!,{R0-R11,R14}       ;Restore registers
132                 BICS    PC,R14,#V_flag          ;And return with glad tidings
133
134                 ; --- border__iLoad ---
135
136 border__iLoad   LDR     R6,[R1,R0,LSL #2]       ;Load the requested value
137 border__round   TST     R0,#1                   ;Is this a y-coordinate?
138                 ADDEQ   R6,R6,R2                ;No -- adjust by x origin
139                 ADDNE   R6,R6,R3                ;Yes -- adjust by y origin
140                 SUBEQ   R14,R7,#1               ;No -- get x width
141                 SUBNE   R14,R8,#1               ;Yes -- get y width
142                 BIC     R6,R6,R14               ;Round the value nicely
143                 B       border__main            ;And get next instruction
144
145                 ; --- border__load ---
146
147 border__load    LDR     R6,[R11,R0,LSL #2]      ;Load the requested value
148                 B       border__main            ;And get the next instruction
149
150                 ; --- border__ldCtr ---
151
152 border__ldCtr   ADD     R14,R1,R0,LSL #2        ;Find the correct bit
153                 LDMIA   R14,{R5,R6,R14}         ;Load three values
154                 ADD     R6,R5,R14               ;Add the two together
155                 MOV     R6,R6,ASR #1            ;Divide by two
156                 B       border__round           ;Now round the value to pixel
157
158                 ; --- border__op ---
159
160 border__op      LDRB    R14,[R10],#1            ;Load the next byte out
161                 TST     R0,#1                   ;Which op is it?
162                 ADDEQ   R6,R6,R14               ;Add -- do the add then
163                 SUBNE   R6,R6,R14               ;Sub -- do that
164                 B       border__main            ;And skip off merrily
165
166                 ; --- border__store ---
167
168 border__store   STR     R6,[R11,R0,LSL #2]      ;Store it (can't trash stk)
169                 B       border__main            ;And return to loop
170
171                 ; --- border__stdCol ---
172
173 border__stdCol  TST     R0,#2                   ;Doing complicated things?
174                 BNE     %f00                    ;Yes -- skip forwards then
175                 LDR     R14,[R11,#16 + 4*4]     ;Load the colour table addr
176                 LDRB    R0,[R14,R0]             ;Load the colour out
177                 SWI     XWimp_SetColour         ;Do the set
178                 B       border__main            ;And loop back round
179
180 00              LDR     R14,[R11,#16 + 4*4]     ;Load the colour table addr
181                 BIC     R14,R14,#&03            ;Clear non-alignedness
182                 STR     R14,[R11,#16 + 4*4]     ;Store the address back
183                 B       border__main            ;And return to caller
184
185                 ; --- border__colour ---
186
187 border__colour  CMP     R0,#0                   ;Is this set-from-icon?
188                 BEQ     %f00                    ;Yes -- do this
189                 CMP     R0,#1                   ;Do we indirect this?
190                 LDRB    R0,[R10],#1             ;Load the argument byte
191                 LDREQB  R0,[R12,R0]             ;Load the colour out
192                 SWI     XWimp_SetColour         ;Set the colour
193                 B       border__main            ;And loop back for more
194
195 00              BL      colours_read            ;Read the colours out
196                 MOV     R4,R0,LSR #4            ;Extract background colour
197                 AND     R0,R0,#&F               ;Extract foreground colour
198                 LDR     R14,[R1,#16]            ;Load the icon flags, please
199                 TST     R14,#&00400000          ;Is icon /really/ shaded?
200                 ANDNE   R0,R0,#2                ;Yes -- shade in simple way
201                 SWI     XWimp_SetColour         ;Set the colour, please
202                 ORR     R0,R4,#&80              ;Get the background colour
203                 SWI     XWimp_SetColour         ;Set the colour, please
204                 B       border__main            ;And continue
205
206                 ; --- border__plot ---
207
208 border__plot    ADD     R10,R10,#4+3            ;Word align instruction ptr
209                 BIC     R10,R10,#3              ;And advance past the branch
210                 STMFD   R13!,{R1-R3,R6}         ;Store useful values
211                 LDMIA   R11,{R3-R6}             ;Load the coordinates
212                 MOV     R14,PC                  ;Set up return address
213                 SUB     PC,R10,#4               ;Call the branch instr
214                 LDMFD   R13!,{R1-R3,R6}         ;Restore the registers
215                 B       border__main            ;And rejoin the loop
216
217                 ; --- border__skipTtl ---
218
219 border__skipTtl LDR     R14,[R11,#16 + 4*5]     ;Load the title width
220                 ADD     R6,R6,R14               ;Add this on nicely
221                 SUB     R14,R7,#1               ;Get x bitmask
222                 BIC     R6,R6,R14               ;To be nice
223                 B       border__main            ;Go forth and execute
224
225                 ; --- border__plotGrp ---
226
227 border__plotGrp LDMIA   R11,{R4-R6,R14}         ;Load the coordinates
228
229                 SUB     R4,R4,R2                ;Make them window relative
230                 SUB     R5,R5,R3                ;Keep doing this a bit
231                 SUB     R6,R6,R2
232                 SUB     R14,R14,R3
233
234                 SUB     R13,R13,#32             ;Make space for the block
235                 STMIA   R13,{R4-R6,R14}         ;Store all them away
236                 ADD     R10,R10,#4+3            ;Word align instruction ptr
237                 BIC     R10,R10,#3              ;And skip past flags word
238
239                 LDR     R4,[R10,#-4]            ;Load the flags word
240                 LDR     R5,[R1,#16]             ;Load the original flags
241                 BIC     R4,R4,#&0F400000        ;Clear the static flags
242                 AND     R5,R5,#&0F400000        ;And mask the real flags
243                 ORR     R4,R4,R5                ;Combine them nicely
244
245                 LDR     R5,[R11,#16 + 4*6]      ;Get the title
246                 MOV     R6,#-1                  ;No validation string
247                 MOV     R14,#1                  ;A random buffer length
248                 ADD     R0,R13,#16              ;Find a space nicely
249                 STMIA   R0,{R4-R6,R14}          ;Save the icon data
250                 MOV     R1,R13                  ;Point to this block
251                 SWI     XWimp_PlotIcon          ;Do the icon plotting
252                 ADD     R13,R13,#32             ;Restore the stack pointer
253                 LDR     R1,[R11,#16 + 4*1]      ;Reload the icon pointer
254                 B       border__main            ;Done that
255
256                 ; --- border__call ---
257
258 border__call    ADD     R10,R10,#4+3            ;Word align instruction ptr
259                 BIC     R10,R10,#3              ;And advance past the branch
260                 TST     R0,#1                   ;Do we save the old one?
261                 STMNEFD R13!,{R10}              ;Yes -- save old IP on stack
262                 LDR     R14,[R10,#-4]           ;Load the branch offset
263                 ADD     R10,R10,R14             ;Find the new routine
264                 B       border__main            ;Continue executing subrt
265
266                 LTORG
267
268 ;----- Command codes --------------------------------------------------------
269 ;
270 ; We try to organise these in a way which makes it easy to decode.  The
271 ; bottom two bits end up as an immediate operand in most cases, allowing us
272 ; to select entries in the icon bounding box easily.
273
274                 ^       -4
275
276                 #       4
277 bCmd_ret        EQU     {VAR}                   ;End border operation
278
279                 #       4
280 bCmd_ldix0      EQU     {VAR}+0                 ;Fetch X0 of the icon
281 bCmd_ldiy0      EQU     {VAR}+1                 ;Fetch Y0 of the icon
282 bCmd_ldix1      EQU     {VAR}+2                 ;Fetch X1 of the icon
283 bCmd_ldiy1      EQU     {VAR}+3                 ;Fetch Y1 of the icon
284
285                 #       4
286 bCmd_ldx0       EQU     {VAR}+0                 ;Fetch last stored X0
287 bCmd_ldy0       EQU     {VAR}+1                 ;Fetch last stored Y0
288 bCmd_ldx1       EQU     {VAR}+2                 ;Fetch last stored X1
289 bCmd_ldy1       EQU     {VAR}+3                 ;Fetch last stored Y1
290
291                 #       4
292 bCmd_ldhc       EQU     {VAR}+0                 ;Fetch horizontal centre
293 bCmd_ldvc       EQU     {VAR}+1                 ;Fetch vertical centre
294
295                 #       4
296 bCmd_add        EQU     {VAR}+0                 ;Add next byte
297 bCmd_sub        EQU     {VAR}+1                 ;Subtract next byte
298
299                 #       4
300 bCmd_stx0       EQU     {VAR}+0                 ;Store as the X0 parameter
301 bCmd_sty0       EQU     {VAR}+1                 ;Store as the Y0 parameter
302 bCmd_stx1       EQU     {VAR}+2                 ;Store as the X1 parameter
303 bCmd_sty1       EQU     {VAR}+3                 ;Store as the Y1 parameter
304
305                 #       4
306 bCmd_dark       EQU     {VAR}+0                 ;Use the current `dark' col
307 bCmd_light      EQU     {VAR}+1                 ;Use the current `light' col
308 bCmd_raw        EQU     {VAR}+2                 ;Switch to uninverted colours
309
310                 #       4
311 bCmd_icon       EQU     {VAR}+0                 ;Set colours from icon
312 bCmd_indCol     EQU     {VAR}+1                 ;Indirected colour
313 bCmd_litCol     EQU     {VAR}+2                 ;Literal colour
314
315                 #       4
316 bCmd_plot       EQU     {VAR}+0                 ;Plot a rule (arg == branch)
317
318                 #       4
319 bCmd_skpt       EQU     {VAR}+0                 ;Skip past the `title'
320
321                 #       4
322 bCmd_group      EQU     {VAR}+0                 ;Plot a group box
323
324                 #       4
325 bCmd_jmp        EQU     {VAR}+0                 ;Jump to a routine
326 bCmd_call       EQU     {VAR}+1                 ;Call subroutine
327
328 ;----- That's all, folks ----------------------------------------------------
329
330                 END