! ---------------------------------------------------------------------------- !
! StringMaker.h by Roger Firth (
[email protected])
!
! 1.0 Jul 2002
! Original version.
!
! ---------------------------------------------------------------------------- !
! Installation: add the line:
!
! Include "StringMaker";
!
! near the start of your game file.
!
! ---------------------------------------------------------------------------- !
!
! The routine StringToChars(s,a) unpacks a string S into an array of
! characters A, in which the first word (A-->0) holds the length of the
! string, and the remaining bytes (A->2, A->3, ...) hold the characters.
! You can also create such an array using output stream 3 (see section 42
! of the DM4):
!
! @output_stream 3 A;
! print ... ;
! @output_stream -3;
!
! The routine CharsToString(a,s) reverses the process. Here A is an array
! of characters in the format created by StringToChars(), and S is an
! array of words into which the packed string is written. Note that this
! array will be in the Z-machine's low memory (only the compiler can write
! into the high memory region) and so therefore you cannot use
! print (string) S to output the string that you have made; instead, use
! print (address) S to print it.
!
! For example:
!
! Array AAA --> 100; ! reserve 100 words for a character array
! Array SSS --> 100; ! and the same for the string.
!
! StringToChars("This is^a short string", AAA);
! AAA->13 = 'm'; ! overwrite "short" with "small"
! AAA->14 = 'a';
! AAA->15 = AAA->16 = 'l';
! AAA->24 = '.'; ! add a full stop on the end
! AAA-->0 = AAA-->0 + 1;
! CharsToString(AAA, SSS);
! print (address) SSS, "^";
!
! produces:
!
! This is
! a small string.
System_file;
Array alphaTable ->
'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z'
'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z'
' ' '^' '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '.' ',' '!' '?' '_' '#' 039 '"' '/' '\' '-' ':' '(' ')';
Global sCount = 0; ! current word in string
Global zCount = 0; ! current Z-char within word
[ StringToChars s a; ! unpack a string into an array of ZSCII characters
(s).print_to_array(a);
return a-->0;
];
[ CharsToString a s ! pack ZSCII characters into a Z-character string
t i;
t = $0034-->0; if (t == 0) t = alphaTable; ! address of alphabet table
sCount = zCount = 0;
for (i=0 : i<(a-->0) : i++)
ZSCIItoZchar(a->(i+2), s, t); ! convert all ZSCII to Z-chars
switch (zCount) { ! fix up last word of string
1: s-->sCount = s-->sCount | $80A5; ! - two pad characters
2: s-->sCount = s-->sCount | $8005; ! - one pad character
0: sCount--;
s-->sCount = s-->sCount | $8000; ! - no pad characters
default: "StringMaker BUG1";
}
return sCount;
];
[ ZSCIItoZchar c s t ! convert 10-bit ZSCII char to 5-bit Z-character(s)
i;
if (c == 32) { ! space
Zchar(0, s); return;
}
if (c == 13) { ! newline
Zchar(5, s); Zchar(7, s); return;
}
for (i=0 : i<78 : i++) if (c == t->i)
switch (i/26) { ! found in alpha table
0: Zchar(6+i, s); ! - A0 (lower case)
return;
1: Zchar(4, s); Zchar(6+i%26, s); ! - A1 (upper case)
return;
2: Zchar(5, s); Zchar(6+i%26, s); ! - A2 (punctuation)
return;
default: "StringMaker BUG2";
}
Zchar(5, s); Zchar(6, s); ! not found in alpha table
Zchar(c/$20, s); Zchar(c&$1F, s);
];
[ Zchar c s; ! pack a Z-character into the string being built
switch (zCount++) {
0: s-->sCount = c * $400;
1: s-->sCount = s-->sCount + c * $20;
2: s-->sCount = s-->sCount + c; sCount++; zCount = 0;
default: "StringMaker BUG3";
}
];
! ---------------------------------------------------------------------------- !