seymour.shabow wrote:
> Hey, remember all that discussion that went back and forth over the
> years about the "meteor bonus multiplier bug"? (Which I did fix but
> also with other added things).
OK, to refresh everyone's memory as to what the bug is and what causes
it....
If you have all rockets lit on the outlanes, AND you have a lot of other
scoring things going on (usually related to a spinner hit since that
keeps repeating) you can overload the thread engine in the game, such
that the 'collect all rockets' thread (which unnecessarily gives a sound
effect and scores for each rocket instead of just scoring it at
once...i.e. there are delays built into the thread which turn out to
cause the error.).
Once the collect all rockets thread is running AND the thread starts
that collects the bonus in the outhole, you will get a zero inserted
into the bonus multiplier.... which will count down 255x (if you wait
long enough). It's not infinite, and has nothing to do with the speed
of the game. Its simply because the collect all rockets thread isn't
finished when the collect bonus thread starts.... and the error is
because the multiplier in the collect bonus thread is stored in the same
memory location that the collect all rockets thread uses as well. 2
threads that were never intended to run at the same time using the same
memory location is sure to cause errors.
It's more likely to happen the more rockets you have (since that extends
out the collect all rockets thread execution) and with the spinner as it
keeps adding another thread onto the execution (the spinner thread is
exceptionally long as it has almost 2k (that's 25% of the entire
codebase!) dedicated to seeing which lamps are lit, what multiplier you
have, and moving those lamps around.) This is extremely sloppy in
stern's thread language and really could be changed to inline assembly
to save TONS of space. If I needed more romspace I'd probably do just that.
The fixes?
My (ultimately working) fix was to repurpose one of the audits that's
used to track replay levels 2 and 3 and use those locations instead to
store the variables in the collect all rockets thread.
Stern's fix from way back when was to utilize the lower part of the
stack to do the same thing. I don't think that way is 100% safe (they
didn't use the BOTTOM of the stack - they used somewhere in the middle)
- but it's probably safe enough. Put enough extra threads in play
though and you'd probably clobber it.
There were a lot of red herrings in duplicating the error, and until I
disassembled the original code 100% and commented it all didn't even
realize the duplicate memory location until I laid them out next to each
other.
Some failed fixes along the way....
check the multiplier during bonus countdown and if it ever became 0x, or
something else invalid, just make it 2x. That's not fair... you lose
multiplier because the game screwed up. This did work but was sloppy,
unfair, and reactive. This came about from not understanding the entire
codebase!
add a delay to the outhole thread running/starting so that other threads
had a chance to finish. I think this would have worked but it drove me
NUTS when the ball drains and just sits there for 3-4 seconds.
Several more failed stratagems where checking the spinner and collect
all rockets threads all of which lasted about 5 minutes in the machine
before I rejected them.
What pointed me in the right direction was when I didn't take the
spinner into account AT ALL in getting the bug to activate. I got a ton
of other switches going first and then I collected all rockets and STILL
got the bug.... so I knew it was in the collect rockets thread. Once I
could ignore the 2k long spinner code.... a lot easier to spot it.