Initial revision
[ssr] / StraySrc / Sculptrix / sculptrix / s / vString
1 ;
2 ; vString.s
3 ;
4 ; Parses validation strings for Sculptrix
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.wSpace
37
38 ;----- Main code ------------------------------------------------------------
39
40 AREA |Module$$Code|,CODE,READONLY
41
42 ; --- vString_read ---
43 ;
44 ; On entry: R1 == pointer to an icon block
45 ;
46 ; On exit: CS if there's a border, and
47 ; R0 == border info word
48 ; R4 == pointer to `inverted' flag byte
49 ; else CC and
50 ; R0, R4 preserved
51 ;
52 ; Use: Reads an icon's validation string, and extracts relevant
53 ; information. The border info word contains what sort of
54 ; graphics we have to plot around the icon, and any special
55 ; options thrown in. A string (for group borders etc.) is
56 ; copied into the misc buffer if one was found.
57 ;
58 ; The syntax of a Sculptrix validation string is as follows:
59 ;
60 ; `xb'<type>[<flags>][`,'<text>]
61 ;
62 ; The <type> is a letter which determines what sort of border
63 ; is to be drawn. The <flags> modify the style of the border
64 ; slightly. Note that if the <type> is uppercase, then the
65 ; border is inverted. The <text> is only required for group
66 ; boxes (type `g'). An unknown <type> causes the icon to be
67 ; ignored. Unknown <flags> are ignored. If no text is
68 ; specified, a null string is assumed by default. Spaces
69 ; are allowed in various sensible places.
70
71 EXPORT vString_read
72 vString_read ROUT
73
74 STMFD R13!,{R0-R4,R14} ;Save some registers
75
76 ; --- Find the validation string first ---
77
78 MOV R2,#0 ;First call, this is
79 00 MOV R0,#'x' ;Find the validation string
80 BL vString_find ;Try to find the string
81 BCC %90vString_read ;Can't find a Sculptrix cmd
82 LDRB R14,[R2,#1] ;Load the subcommand code
83
84 [ :LNOT::DEF:only_new_commands
85 SUB R4,R14,#'0' ;Convert to a digit
86 CMP R4,#10 ;Is this recognised?
87 BCC %50vString_read ;Yes -- deal with it
88 ]
89
90 ORR R14,R14,#&20 ;Make the command lowercase
91
92 [ :LNOT::DEF:only_new_commands
93 CMP R14,#'g' ;Is it a group command?
94 BEQ %60vString_read ;Yes -- deal with it
95 ]
96
97 CMP R14,#'s' ;Is it a text+sprite?
98 BEQ %70vString_read ;Yes -- deal with that too
99
100 CMP R14,#'b' ;Is it the main `b' command?
101 BNE %b00 ;No -- loop back for more
102
103 ; --- Handle the new `xb' command ---
104
105 MOV R14,#0 ;Initially terminate string
106 STRB R14,sculpt_misc ;To avoid nasty problems
107 ADD R2,R2,#2 ;Skip past the command chars
108
109 00 LDRB R3,[R2],#1 ;Load a byte from the string
110 CMP R3,#&20 ;Is it a space character?
111 BEQ %b00 ;Yes -- keep looking then
112 CMP R3,#';' ;End of the command?
113 CMPNE R3,#&1F ;Of of the whole string?
114 BLS %90vString_read ;End of string -- abort now
115
116 ORR R0,R3,#&20 ;Make the char lowercase
117 ADR R1,vString__cnvTbl ;Point to the table
118 BL vString__lookup ;Look up letter in the table
119 BCC %90vString_read ;Not found -- give up then
120 MOV R4,R0 ;Get the command code
121
122 TST R3,#&20 ;Is the command uppercase?
123 EOREQ R4,R4,#vsFlag_invert ;Yes -- invert the border
124 SUB R3,R2,#1 ;Remember this offset
125
126 ; --- Now read in the flags ---
127
128 ADR R1,vString__flags ;Point to the flags table
129
130 00 LDRB R14,[R2],#1 ;Load a byte from the string
131 CMP R14,#&20 ;Is it a space character?
132 BEQ %b00 ;Yes -- keep looking then
133 CMP R14,#';' ;End of the command?
134 CMPNE R14,#&1F ;Of of the whole string?
135 BLS %f05 ;End of string -- return
136 CMP R14,#',' ;Is it a comma?
137 BEQ %f00 ;Yes -- handle the text then
138
139 ORR R0,R14,#&20 ;Make character lowercase
140 BL vString__lookup ;Do the lookup
141 EORCS R4,R4,R0 ;And merge in the flag
142 B %b00 ;Keep going until done
143
144 ; --- Copy the text over and exit ---
145
146 00 BL vString__copy ;Copy the text over, please
147 B %80vString_read ;Now return this to caller
148
149 ; --- Deal with an empty string ---
150
151 05 AND R14,R4,#&0000FF00 ;Extract the type code
152 CMP R14,#vsCode_group ;Is this a group box?
153 MOVEQ R4,#vsBrd_ridge+vsFlag_fade+vsFlag_invert
154 LDREQ R14,sculpt_flags ;Load the flags word
155 TSTEQ R14,#scFlag_acorn ;Acorn style group box?
156 BICEQ R4,R4,#vsFlag_invert ;No -- don't invert it then
157 B %80vString_read ;Now return this to caller
158
159 ; --- Conversion tables ---
160
161 vString__cnvTbl DCD 'a',vsBrd_action + vsFlag_slab
162 DCD 'd',vsBrd_default + vsFlag_slab
163 DCD 'i',vsBrd_action + vsFlag_invert
164 DCD 'p',vsBrd_action + vsFlag_invert + vsFlag_fade
165 DCD 'r',vsBrd_ridge
166 DCD 'c',vsBrd_ridge + vsFlag_invert
167 DCD 'w',vsBrd_write
168 DCD 'o',vsBrd_offset
169 DCD 'g',vsCode_group
170 DCD -1
171
172 vString__flags DCD 'f',vsFlag_fade
173 DCD 'i',vsFlag_invert
174 DCD -1
175
176 ; --- Handle old-style `x<digit>' command ---
177
178 [ :LNOT::DEF:only_new_commands
179
180 50vString_read MOV R3,R2 ;Remember this position
181 ADR R14,vString__oldTbl ;Point to the table
182 LDR R4,[R14,R4,LSL #2] ;Load the appropriate word
183 CMP R4,#-1 ;Is there a zero there?
184 BEQ %90vString_read ;Yes -- give up then
185 LDRB R14,[R3,#0] ;Load the `X' character
186 TST R14,#&20 ;Is it uppercase?
187 EOREQ R4,R4,#vsFlag_invert ;Yes -- invert the icon
188 B %80vString_read ;Now return this to caller
189
190 vString__oldTbl DCD vsCode_simple + vsBrd_action + vsFlag_slab
191 DCD vsCode_simple + vsBrd_ridge
192 DCD vsCode_simple + vsBrd_default + vsFlag_slab
193 DCD vsCode_simple + vsBrd_offset
194 DCD vsCode_simple + vsBrd_action
195 DCD -1 ;Group box title -- withdrawn
196 DCD -1 ;Group box title -- withdrawn
197 DCD vsCode_simple + vsBrd_write
198 DCD vsCode_simple + vsBrd_action + vsFlag_fade
199 DCD -1
200
201 ]
202
203 ; --- Handle old-style `xg' command ---
204
205 [ :LNOT::DEF:only_new_commands
206
207 60vString_read ADD R3,R2,#1 ;Point to the `G'
208 ADD R2,R2,#3 ;Skip onto the text
209 MOV R4,#vsCode_group ;Get a group title word
210 BL vString__copy ;Copy the text over, please
211 B %80vString_read ;Now return this to caller
212
213 ]
214
215 ; --- Handle `xs' text+sprite command ---
216
217 70vString_read ADD R3,R2,#1 ;Point to the `S'
218 ADD R2,R2,#2 ;Skip onto the text
219 MOV R4,#vsCode_tns ;Get the mystic word
220 BL vString__copy ;Copy the text over, please
221 B %80vString_read ;Now return this to caller
222
223 ; --- Return values to caller ---
224
225 80vString_read STR R4,[R13,#4*0] ;Store the information word
226 STR R3,[R13,#4*4] ;And the invert flag address
227 LDMFD R13!,{R0-R4,R14} ;Restore registers
228 ORRS PC,R14,#C_flag ;And return with C set
229
230 90vString_read LDMFD R13!,{R0-R4,R14} ;Restore registers
231 BICS PC,R14,#C_flag ;And return with C clear
232
233 LTORG
234
235 ; --- vString__copy ---
236 ;
237 ; On entry: R0 == border type code
238 ; R2 == pointer to tail of validation string
239 ;
240 ; On exit: R2 moved on
241 ;
242 ; Use: Copies the tail of the validation string into the misc
243 ; buffer, transforming escape sequences correctly.
244
245 vString__copy ROUT
246
247 STMFD R13!,{R0,R14} ;Save some registers
248 ADR R0,sculpt_misc ;Point to the buffer
249
250 00 LDRB R14,[R2],#1 ;Load the next byte out
251 CMP R14,#';' ;Is this the end?
252 CMPNE R14,#&1F ;Check for end of string
253 BLS %f00 ;Yes -- skip onwards then
254
255 CMP R14,#'\' ;Is this an escape?
256 STRNEB R14,[R0],#1 ;Nothing special -- store
257 BNE %b00 ;And loop back round
258
259 LDRB R14,[R2],#1 ;Load the next byte out
260 CMP R14,#&20 ;Check for end of string
261 STRCSB R14,[R0],#1 ;Nothing special -- store
262 BCS %b00 ;And loop back round
263
264 00 MOV R14,#0 ;Zero terminate the string
265 STRB R14,[R0],#1 ;Store in the buffer
266 LDMFD R13!,{R0,PC}^ ;Return when done
267
268 LTORG
269
270 ; --- vString__lookup ---
271 ;
272 ; On entry: R0 == word to look for
273 ; R1 == pointer to table
274 ;
275 ; On exit: CS if found, and
276 ; R0 == word from table
277 ; else CC and
278 ; R0 corrupted
279 ;
280 ; Use: Looks a word in a table, and returns the corresponding other
281 ; word.
282
283 vString__lookup ROUT
284
285 STMFD R13!,{R1,R14} ;Save some registers
286 00 LDR R14,[R1],#8 ;Load the next word
287 CMP R14,#-1 ;Is this the end?
288 CMPNE R14,R0 ;Do these match?
289 BNE %b00 ;Neither -- go back then
290 CMP R14,R0 ;Which one was it?
291 LDREQ R0,[R1,#-4] ;Match -- load previous word
292 LDMFD R13!,{R1,R14} ;Restore registers
293 ORREQS PC,R14,#C_flag ;Return C set if found
294 BICNES PC,R14,#C_flag ;Return C clear if not
295
296 LTORG
297
298 ; --- vString_find ---
299 ;
300 ; On entry: R0 == character to find in block (not case-sensitive)
301 ; R1 == pointer to icon block
302 ; R2 == old pointer to search from, or 0
303 ;
304 ; On exit: R0 == character forced to lower case
305 ; CS if found, and
306 ; R2 points to command string
307 ; else CC and
308 ; R2 corrupted
309 ;
310 ; Use: Tries to find a validation string command in the given
311 ; icon block.
312
313 EXPORT vString_find
314 vString_find ROUT
315
316 BIC R14,R14,#C_flag ;Assume we won't find it
317 STMFD R13!,{R3,R14} ;Preserve for later use
318
319 ; --- Ensure the icon is text and indirected ---
320
321 LDR R3,[R1,#16] ;Get flags word
322 TST R3,#1<<23 ;Is it deleted?
323 MOVEQ R14,#&100 ;Can't put 101 in one instr
324 ORREQ R14,R14,#&01 ;Check indirect and text
325 ANDEQ R3,R3,R14 ;Mask the bits off
326 CMPEQ R3,R14 ;Were they both set?
327 LDMNEFD R13!,{R3,PC}^ ;No -- return huffily
328
329 ; --- Find the validation string ---
330
331 LDR R3,[R1,#24] ;Get pointer to valid string
332 CMP R3,#-1 ;Is it empty?
333 LDMEQFD R13!,{R3,PC}^ ;No -- return huffily
334
335 ; --- Start from the right index ---
336
337 ORR R0,R0,#&20 ;Make valid char lower case
338 CMP R2,#0 ;Is it the start?
339 ADDNE R2,R2,#1 ;No -- miss out one char
340 BNE %30vString_find ;And skip this command
341 MOV R2,R3 ;Start at the beginning
342
343 ; --- Check the first char of a validation string ---
344
345 10vString_find LDRB R14,[R2],#1 ;Get a byte from string
346 ORR R3,R14,#&20 ;Make lower case
347 CMP R3,R0 ;Is it a match?
348 SUBEQ R2,R2,#1 ;Point back to character
349 LDMEQFD R13!,{R3,R14} ;And return
350 ORREQS PC,R14,#C_flag ;Set C on exit for this
351 MOV R3,#0 ;Not an excaped character
352
353 ; --- Skip ahead to the next validation string ---
354
355 20vString_find CMP R14,#' ' ;Is it a control char?
356 LDMCCFD R13!,{R3,PC}^ ;Yes -- return
357 CMP R3,#1 ;Are we escaping?
358 MOVEQ R3,#0 ;Yes -- done that now
359 BEQ %30vString_find ;So skip this bit
360 CMP R14,#';' ;Is it a semicolon?
361 BEQ %10vString_find ;Yes -- try a new command
362 CMP R14,#'\' ;Is it a backslash?
363 MOVEQ R3,#1 ;Yes -- escape next char
364 30vString_find LDRB R14,[R2],#1 ;Get another character
365 B %20vString_find ;And try again
366
367 LTORG
368
369 ;----- Border codes and flags -----------------------------------------------
370
371 ^ 0
372 vsCode_simple # &0100 ;A simple border
373 vsCode_group # &0100 ;A group box border
374 vsCode_tns # &0100 ;Text+sprite icon
375
376 ^ 0
377 vsBrd_action # 1 ;Standard action button
378 vsBrd_default # 1 ;Default action button
379 vsBrd_ridge # 1 ;A ridge type border
380 vsBrd_write # 1 ;A writable border
381 vsBrd_offset # 1 ;Offset pressed-in border
382
383 vsFlag_invert EQU (1<<31) ;Icon border is inverted
384 vsFlag_fade EQU (1<<30) ;Icon border is faded
385 vsFlag_slab EQU (1<<29) ;Icon may be slabbed
386
387 ;----- That's all, folks ----------------------------------------------------
388
389 END