I have no strong opinion about changing the behavior, I'm just goofing around trying to understand how everything works and looking for
got-yas.
I brought this up because in my experience the toughest to track down problems are those that are in pieces of code that you "know" to be correct. My example was trivial, but take another where the divisor is coming from a global that was calculated with say "&-", instead of "&1-" and the offending code is triggered by a monster stepping on a pressure plate and the person seeing the problem is a player...it might take awhile for the designer to figure out what's causing the seemingly random crash. Additionally many programmers don't seem to know (or think about) the fact that integer division and mods by zero generate hardware exceptions, so that is an additional barrier to designers with limited programming experience.
The trace might or might not (almost always not) be helpful since the engine routine PrintTrace doesn't explicitly
flush the stream (which is a good thing IMHO) at each call. The runtime does not flush open streams on unhandled exceptions, so up to a buffer's worth of data (4K by default in VC) is lost (not written to the file) on unhandled exceptions, so the info in the trace virtually insured to be missing a fair amount of data if the program crashes. For my example above, no DSA tracing makes it's way into the file.
A possible patch for division is (and likewise for &%):
Code: Select all
// current version
i32 v = pdsaDbank->stack.pop();
i32 w = pdsaDbank->stack.pop();
pdsaDbank->stack.push(w/v);
Code: Select all
// patched version
i32 v = pdsaDbank->stack.pop();
i32 w = pdsaDbank->stack.pop();
if (v != 0)
pdsaDbank->stack.push(w/v);
else
die(someNumber, "divide-by-zero");
While I'm babbling, another minor potential
got-ya relates to the bit-shift instructions. The various CPU vendors implement shifts by more than 31 bits in two ways:
x >> (y & 31) or x >> (min(y,31))
Which could cause dungeons behave differently on desktop Windows vs. CE builds. (Intel uses the first BTW).
So, I'd suggest the following patch (and likewise for &RSHIFT):
Code: Select all
i32 v = pdsaDbank->stack.pop();
i32 w = pdsaDbank->stack.pop();
pdsaDbank->stack.push( (v>=0)?(w<<(v&31)):(w>>((-v)&31)));
This would make all versions behave exactly the same (the current desktop behavior) and the compiler will remove the unneeded mask on CPUs that use the first convention.
Again, I have no strong feeling about either of these potential issues, but removing barriers for people with little programming experience is never a bad thing.