diff options
author | Willem Jan Palenstijn | 2013-01-24 23:16:33 +0100 |
---|---|---|
committer | Willem Jan Palenstijn | 2013-01-25 00:57:50 +0100 |
commit | f5e43484a0cf91c048e37049f838c835d2da052c (patch) | |
tree | cf28b00638bffb233cab41e7f25b58dcdd28a1be | |
parent | 5691a40380653af1d76fcdd30d1ec2f5996abf11 (diff) | |
download | scummvm-rg350-f5e43484a0cf91c048e37049f838c835d2da052c.tar.gz scummvm-rg350-f5e43484a0cf91c048e37049f838c835d2da052c.tar.bz2 scummvm-rg350-f5e43484a0cf91c048e37049f838c835d2da052c.zip |
SCI: Fix kReadNumber sign/hex behaviour
Negative numbers now work, and hex overflow is handled like SSCI.
Thanks to waltervn for testing.
-rw-r--r-- | engines/sci/engine/kstring.cpp | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index 82206508e8..65e139e1ee 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -155,30 +155,47 @@ reg_t kReadNumber(EngineState *s, int argc, reg_t *argv) { source++; /* Skip whitespace */ int16 result = 0; + int16 sign = 1; + if (*source == '-') { + sign = -1; + source++; + } if (*source == '$') { // Hexadecimal input - result = (int16)strtol(source + 1, NULL, 16); + source++; + char c; + while ((c = *source++) != 0) { + int16 x = 0; + if ((c >= '0') && (c <= '9')) + x = c - '0'; + else if ((c >= 'a') && (c <= 'f')) + x = c - 'a' + 10; + else if ((c >= 'A') && (c <= 'F')) + x = c - 'A' + 10; + else + // Stop if we encounter anything other than a digit (like atoi) + break; + result *= 16; + result += x; + } } else { // Decimal input. We can not use strtol/atoi in here, because while // Sierra used atoi, it was a non standard compliant atoi, that didn't // do clipping. In SQ4 we get the door code in here and that's even // larger than uint32! - if (*source == '-') { - // FIXME: Setting result to -1 does _not_ negate the output. - result = -1; - source++; - } - while (*source) { - if ((*source < '0') || (*source > '9')) + char c; + while ((c = *source++) != 0) { + if ((c < '0') || (c > '9')) // Stop if we encounter anything other than a digit (like atoi) break; result *= 10; - result += *source - 0x30; - source++; + result += c - '0'; } } + result *= sign; + return make_reg(0, result); } |