read method
Implementation
@override
void read() async {
Z.inInterrupt = true;
Z.printBuffer();
final operands = visitOperandsVar(4, true);
final storeTo = readb();
if (operands.length > 2) {
//TODO implement aread optional args
log.warning('implement aread optional args');
throw GameException(
"Sorry :( This interpreter doesn't yet support a required feature of this game.");
}
int maxBytes = mem.loadb(operands[0].value!);
int textBuffer = operands[0].value! + 2;
int? maxWords;
int parseBuffer;
// if (operands.length > 2) {
maxWords = mem.loadb(operands[1].value!);
parseBuffer = operands[1].value! + 1;
// }
void processLine(String line) async {
line = line.trim().toLowerCase();
Z.mostRecentInput = line;
var charCount = mem.loadb(textBuffer - 1);
if (charCount > 0) {
//continuation of previous input
maxBytes -= charCount;
}
if (line.length > maxBytes - 1) {
line = line.substring(0, maxBytes - 2);
log.warning("Truncated line in v5 read(): $line");
}
var tbTotalAddr = textBuffer - 1;
//write the total to the textBuffer (adjust if continuation)
mem.storeb(tbTotalAddr,
line.length + charCount > 0 ? line.length + charCount : 0);
var zChars = ZSCII.toZCharList(line);
//adjust if continuation
textBuffer += charCount > 0 ? charCount : 0;
//store the zscii chars in text buffer
for (final c in zChars) {
mem.storeb(textBuffer++, c);
}
var tokens = Z.engine.mem.dictionary.tokenize(line);
log.fine("got tokens $tokens in v5 read()");
if (maxWords == null) {
log.fine("z5 read() maxWords == null");
//second parameter was not passed, so
// we are not going to write to the parse
// buffer (etude.z5 does .. )
writeVariable(storeTo, 10);
return;
}
//Debugger.verbose(' (tokenized: $tokens)');
var parsed = Z.engine.mem.dictionary.parse(tokens, line);
//Debugger.debug('$parsed');
var maxParseBufferBytes = (4 * maxWords) + 2;
var i = 0;
for (final p in parsed) {
i++;
if (i > maxParseBufferBytes) break;
mem.storeb(parseBuffer++, p);
}
// must return 13 v5+
writeVariable(storeTo, 13);
}
final result = await Z.sendIO({"command": ioCommands.read});
Z.inInterrupt = false;
if (result == '/!') {
Z.inBreak = true;
Debugger.debugStartAddr = programCounter- 1;
Z.callAsync(Debugger.startBreak);
} else {
processLine(result);
Z.callAsync(Z.runIt);
}
}