; ; vString.s ; ; Parses validation strings for Sculptrix ; ; © 1995-1998 Straylight ; ;----- Licensing note ------------------------------------------------------- ; ; This file is part of Straylight's Sculptrix. ; ; Sculptrix is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2, or (at your option) ; any later version. ; ; Sculptrix is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with Sculptrix. If not, write to the Free Software Foundation, ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;----- Standard header ------------------------------------------------------ GET libs:header GET libs:swis GET libs:stream ;----- External dependencies ------------------------------------------------ GET sh.wSpace ;----- Main code ------------------------------------------------------------ AREA |Module$$Code|,CODE,READONLY ; --- vString_read --- ; ; On entry: R1 == pointer to an icon block ; ; On exit: CS if there's a border, and ; R0 == border info word ; R4 == pointer to `inverted' flag byte ; else CC and ; R0, R4 preserved ; ; Use: Reads an icon's validation string, and extracts relevant ; information. The border info word contains what sort of ; graphics we have to plot around the icon, and any special ; options thrown in. A string (for group borders etc.) is ; copied into the misc buffer if one was found. ; ; The syntax of a Sculptrix validation string is as follows: ; ; `xb'[][`,'] ; ; The is a letter which determines what sort of border ; is to be drawn. The modify the style of the border ; slightly. Note that if the is uppercase, then the ; border is inverted. The is only required for group ; boxes (type `g'). An unknown causes the icon to be ; ignored. Unknown are ignored. If no text is ; specified, a null string is assumed by default. Spaces ; are allowed in various sensible places. EXPORT vString_read vString_read ROUT STMFD R13!,{R0-R4,R14} ;Save some registers ; --- Find the validation string first --- MOV R2,#0 ;First call, this is 00 MOV R0,#'x' ;Find the validation string BL vString_find ;Try to find the string BCC %90vString_read ;Can't find a Sculptrix cmd LDRB R14,[R2,#1] ;Load the subcommand code [ :LNOT::DEF:only_new_commands SUB R4,R14,#'0' ;Convert to a digit CMP R4,#10 ;Is this recognised? BCC %50vString_read ;Yes -- deal with it ] ORR R14,R14,#&20 ;Make the command lowercase [ :LNOT::DEF:only_new_commands CMP R14,#'g' ;Is it a group command? BEQ %60vString_read ;Yes -- deal with it ] CMP R14,#'s' ;Is it a text+sprite? BEQ %70vString_read ;Yes -- deal with that too CMP R14,#'b' ;Is it the main `b' command? BNE %b00 ;No -- loop back for more ; --- Handle the new `xb' command --- MOV R14,#0 ;Initially terminate string STRB R14,sculpt_misc ;To avoid nasty problems ADD R2,R2,#2 ;Skip past the command chars 00 LDRB R3,[R2],#1 ;Load a byte from the string CMP R3,#&20 ;Is it a space character? BEQ %b00 ;Yes -- keep looking then CMP R3,#';' ;End of the command? CMPNE R3,#&1F ;Of of the whole string? BLS %90vString_read ;End of string -- abort now ORR R0,R3,#&20 ;Make the char lowercase ADR R1,vString__cnvTbl ;Point to the table BL vString__lookup ;Look up letter in the table BCC %90vString_read ;Not found -- give up then MOV R4,R0 ;Get the command code TST R3,#&20 ;Is the command uppercase? EOREQ R4,R4,#vsFlag_invert ;Yes -- invert the border SUB R3,R2,#1 ;Remember this offset ; --- Now read in the flags --- ADR R1,vString__flags ;Point to the flags table 00 LDRB R14,[R2],#1 ;Load a byte from the string CMP R14,#&20 ;Is it a space character? BEQ %b00 ;Yes -- keep looking then CMP R14,#';' ;End of the command? CMPNE R14,#&1F ;Of of the whole string? BLS %f05 ;End of string -- return CMP R14,#',' ;Is it a comma? BEQ %f00 ;Yes -- handle the text then ORR R0,R14,#&20 ;Make character lowercase BL vString__lookup ;Do the lookup EORCS R4,R4,R0 ;And merge in the flag B %b00 ;Keep going until done ; --- Copy the text over and exit --- 00 BL vString__copy ;Copy the text over, please B %80vString_read ;Now return this to caller ; --- Deal with an empty string --- 05 AND R14,R4,#&0000FF00 ;Extract the type code CMP R14,#vsCode_group ;Is this a group box? MOVEQ R4,#vsBrd_ridge+vsFlag_fade+vsFlag_invert LDREQ R14,sculpt_flags ;Load the flags word TSTEQ R14,#scFlag_acorn ;Acorn style group box? BICEQ R4,R4,#vsFlag_invert ;No -- don't invert it then B %80vString_read ;Now return this to caller ; --- Conversion tables --- vString__cnvTbl DCD 'a',vsBrd_action + vsFlag_slab DCD 'd',vsBrd_default + vsFlag_slab DCD 'i',vsBrd_action + vsFlag_invert DCD 'p',vsBrd_action + vsFlag_invert + vsFlag_fade DCD 'r',vsBrd_ridge DCD 'c',vsBrd_ridge + vsFlag_invert DCD 'w',vsBrd_write DCD 'o',vsBrd_offset DCD 'g',vsCode_group DCD -1 vString__flags DCD 'f',vsFlag_fade DCD 'i',vsFlag_invert DCD -1 ; --- Handle old-style `x' command --- [ :LNOT::DEF:only_new_commands 50vString_read MOV R3,R2 ;Remember this position ADR R14,vString__oldTbl ;Point to the table LDR R4,[R14,R4,LSL #2] ;Load the appropriate word CMP R4,#-1 ;Is there a zero there? BEQ %90vString_read ;Yes -- give up then LDRB R14,[R3,#0] ;Load the `X' character TST R14,#&20 ;Is it uppercase? EOREQ R4,R4,#vsFlag_invert ;Yes -- invert the icon B %80vString_read ;Now return this to caller vString__oldTbl DCD vsCode_simple + vsBrd_action + vsFlag_slab DCD vsCode_simple + vsBrd_ridge DCD vsCode_simple + vsBrd_default + vsFlag_slab DCD vsCode_simple + vsBrd_offset DCD vsCode_simple + vsBrd_action DCD -1 ;Group box title -- withdrawn DCD -1 ;Group box title -- withdrawn DCD vsCode_simple + vsBrd_write DCD vsCode_simple + vsBrd_action + vsFlag_fade DCD -1 ] ; --- Handle old-style `xg' command --- [ :LNOT::DEF:only_new_commands 60vString_read ADD R3,R2,#1 ;Point to the `G' ADD R2,R2,#3 ;Skip onto the text MOV R4,#vsCode_group ;Get a group title word BL vString__copy ;Copy the text over, please B %80vString_read ;Now return this to caller ] ; --- Handle `xs' text+sprite command --- 70vString_read ADD R3,R2,#1 ;Point to the `S' ADD R2,R2,#2 ;Skip onto the text MOV R4,#vsCode_tns ;Get the mystic word BL vString__copy ;Copy the text over, please B %80vString_read ;Now return this to caller ; --- Return values to caller --- 80vString_read STR R4,[R13,#4*0] ;Store the information word STR R3,[R13,#4*4] ;And the invert flag address LDMFD R13!,{R0-R4,R14} ;Restore registers ORRS PC,R14,#C_flag ;And return with C set 90vString_read LDMFD R13!,{R0-R4,R14} ;Restore registers BICS PC,R14,#C_flag ;And return with C clear LTORG ; --- vString__copy --- ; ; On entry: R0 == border type code ; R2 == pointer to tail of validation string ; ; On exit: R2 moved on ; ; Use: Copies the tail of the validation string into the misc ; buffer, transforming escape sequences correctly. vString__copy ROUT STMFD R13!,{R0,R14} ;Save some registers ADR R0,sculpt_misc ;Point to the buffer 00 LDRB R14,[R2],#1 ;Load the next byte out CMP R14,#';' ;Is this the end? CMPNE R14,#&1F ;Check for end of string BLS %f00 ;Yes -- skip onwards then CMP R14,#'\' ;Is this an escape? STRNEB R14,[R0],#1 ;Nothing special -- store BNE %b00 ;And loop back round LDRB R14,[R2],#1 ;Load the next byte out CMP R14,#&20 ;Check for end of string STRCSB R14,[R0],#1 ;Nothing special -- store BCS %b00 ;And loop back round 00 MOV R14,#0 ;Zero terminate the string STRB R14,[R0],#1 ;Store in the buffer LDMFD R13!,{R0,PC}^ ;Return when done LTORG ; --- vString__lookup --- ; ; On entry: R0 == word to look for ; R1 == pointer to table ; ; On exit: CS if found, and ; R0 == word from table ; else CC and ; R0 corrupted ; ; Use: Looks a word in a table, and returns the corresponding other ; word. vString__lookup ROUT STMFD R13!,{R1,R14} ;Save some registers 00 LDR R14,[R1],#8 ;Load the next word CMP R14,#-1 ;Is this the end? CMPNE R14,R0 ;Do these match? BNE %b00 ;Neither -- go back then CMP R14,R0 ;Which one was it? LDREQ R0,[R1,#-4] ;Match -- load previous word LDMFD R13!,{R1,R14} ;Restore registers ORREQS PC,R14,#C_flag ;Return C set if found BICNES PC,R14,#C_flag ;Return C clear if not LTORG ; --- vString_find --- ; ; On entry: R0 == character to find in block (not case-sensitive) ; R1 == pointer to icon block ; R2 == old pointer to search from, or 0 ; ; On exit: R0 == character forced to lower case ; CS if found, and ; R2 points to command string ; else CC and ; R2 corrupted ; ; Use: Tries to find a validation string command in the given ; icon block. EXPORT vString_find vString_find ROUT BIC R14,R14,#C_flag ;Assume we won't find it STMFD R13!,{R3,R14} ;Preserve for later use ; --- Ensure the icon is text and indirected --- LDR R3,[R1,#16] ;Get flags word TST R3,#1<<23 ;Is it deleted? MOVEQ R14,#&100 ;Can't put 101 in one instr ORREQ R14,R14,#&01 ;Check indirect and text ANDEQ R3,R3,R14 ;Mask the bits off CMPEQ R3,R14 ;Were they both set? LDMNEFD R13!,{R3,PC}^ ;No -- return huffily ; --- Find the validation string --- LDR R3,[R1,#24] ;Get pointer to valid string CMP R3,#-1 ;Is it empty? LDMEQFD R13!,{R3,PC}^ ;No -- return huffily ; --- Start from the right index --- ORR R0,R0,#&20 ;Make valid char lower case CMP R2,#0 ;Is it the start? ADDNE R2,R2,#1 ;No -- miss out one char BNE %30vString_find ;And skip this command MOV R2,R3 ;Start at the beginning ; --- Check the first char of a validation string --- 10vString_find LDRB R14,[R2],#1 ;Get a byte from string ORR R3,R14,#&20 ;Make lower case CMP R3,R0 ;Is it a match? SUBEQ R2,R2,#1 ;Point back to character LDMEQFD R13!,{R3,R14} ;And return ORREQS PC,R14,#C_flag ;Set C on exit for this MOV R3,#0 ;Not an excaped character ; --- Skip ahead to the next validation string --- 20vString_find CMP R14,#' ' ;Is it a control char? LDMCCFD R13!,{R3,PC}^ ;Yes -- return CMP R3,#1 ;Are we escaping? MOVEQ R3,#0 ;Yes -- done that now BEQ %30vString_find ;So skip this bit CMP R14,#';' ;Is it a semicolon? BEQ %10vString_find ;Yes -- try a new command CMP R14,#'\' ;Is it a backslash? MOVEQ R3,#1 ;Yes -- escape next char 30vString_find LDRB R14,[R2],#1 ;Get another character B %20vString_find ;And try again LTORG ;----- Border codes and flags ----------------------------------------------- ^ 0 vsCode_simple # &0100 ;A simple border vsCode_group # &0100 ;A group box border vsCode_tns # &0100 ;Text+sprite icon ^ 0 vsBrd_action # 1 ;Standard action button vsBrd_default # 1 ;Default action button vsBrd_ridge # 1 ;A ridge type border vsBrd_write # 1 ;A writable border vsBrd_offset # 1 ;Offset pressed-in border vsFlag_invert EQU (1<<31) ;Icon border is inverted vsFlag_fade EQU (1<<30) ;Icon border is faded vsFlag_slab EQU (1<<29) ;Icon may be slabbed ;----- That's all, folks ---------------------------------------------------- END