Yes, this was great, amazing work with this run!
I had to add two extra frames of inputs to make sure Samus wasn't traveling upwards when the shot is fired, and then five more frames for the inputs for triggering the ending. Normally it should have been three frames only for those inputs, but for some reason the game decided to only run the code that updates beams every other frame this time, so I had to insert two blank frames.
Here's the final lsnes movie file:
http://tas.speedga.me/Super%20Metroid%20Glitch%25.lsmv
I couldn't find a way to modify the rerecord count though, so for now it will show only 1 rerecord.
Joined: 10/30/2011
Posts: 146
Location: Auckland, New Zealand
OMG great work guys, I really enjoyed all these new total control TASes being made recently. It's the uppermost level of awesomeness for me to watch =D
Joined: 4/17/2010
Posts: 11495
Location: Lake Chargoggagoggmanchauggagoggchaubunagungamaugg
1 month 10 days later...
You guys are fast!
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
W E L P
http://www.twitch.tv/tewtal/c/3971198
Thanks to Total, x-ray OoB and space/time beam are now equally strong glitches.
This makes low% glitched 1 % lower and might lead to an improvement for any% glitched no GT code
(I also think this officially makes x-ray OoB a 'memory corruption' glitch, so 'any% no memory corruption' succintly bans both and so on)
Okay, that's interesting. How does it work? Go OOB, navigate blindly to the room behind Mother Brain's room, use the X-Ray scope to reset your position, walk to ship, fly away?
Pyrel - an open-source rewrite of the Angband roguelike game in Python.
I should add that this glitch using X-Ray OOB is something Kejardon found 9 years ago that someone mentioned to me and I did some research on.
I haven't done any debugging or anything yet on this but the effects of it is that when you go down a few screens OOB, X-Ray will start overflowing memory and start overwriting all kinds of thing in RAM. The amount overwritten seems to be affected by the Y-position, so the further down you go, the more gets overwritten.
There's some other quirks as well that needs to be researched with it, like it will write different patterns depending on which way to X-ray. Also holding up for a while will also affect the data it writes.
How does it make glitched low% lower than it is if you still need X-ray, maybe you mean for regular speedrunners?
Anyway, really cool glitch. I wonder if there's another spot you can get off screen far enough quickly.
Wow, fantastic Total! PJBoy and I were discussing whether OOB could be sufficient to jump to the ending, or even execute arbitrary code, but the route we thought of was to try to exploit glitched door transitions, and the whole setup seemed pretty unlikely. The X-ray method seems really promising!
Edit: I looked at what happens when using the X-ray OOB:
$91/C505 08 PHP
$91/C506 C2 30 REP #$30
$91/C508 A5 18 LDA $18
$91/C50A 3A DEC A
$91/C50B 0A ASL A
$91/C50C A8 TAY
$91/C50D A5 12 LDA $12
$91/C50F C9 40 00 CMP #$0040
$91/C512 D0 07 BNE $07 [$C51B] down
$91/C514 A9 00 FF LDA #$FF00
$91/C517 97 00 STA [$00],y
$91/C519 80 05 BRA $05 [$C520] down
$91/C51B A9 00 FF LDA #$FF00
$91/C51E 97 00 STA [$00],y
$91/C520 88 DEY
$91/C521 88 DEY
$91/C522 B7 00 LDA [$00],y
$91/C524 C9 FF 00 CMP #$00FF
$91/C527 F0 09 BEQ $09 [$C532] down
$91/C529 A9 FF 00 LDA #$00FF
$91/C52C 97 00 STA [$00],y
$91/C52E 88 DEY
$91/C52F 88 DEY
$91/C530 10 F0 BPL $F0 [$C522] up
$91/C532 A5 18 LDA $18
$91/C534 0A ASL A
$91/C535 A8 TAY
$91/C536 B7 00 LDA [$00],y
$91/C538 C9 FF 00 CMP #$00FF
$91/C53B F0 0C BEQ $0C [$C549] down
$91/C53D A9 FF 00 LDA #$00FF
$91/C540 97 00 STA [$00],y
$91/C542 C8 INY
$91/C543 C8 INY
$91/C544 C0 CC 01 CPY #$01CC
$91/C547 30 ED BMI $ED [$C536] up
$91/C549 28 PLP
$91/C54A 60 RTS
At this point, $0 = 7e9800 = base and $18 = samusY-screenY-10 = yoff, so this should be equivalent to the pseudo-code
Assuming no 00ff values are encountered, this will overwrite [base+(yoff-1)<<1:base] backwards and [base+yoff<<1:base+1cc] forwards. We cannot affect anything below base, I.e. below 7e9800. But there are some interesting things above there, such as the event bit array, which is what total used. We are very limited as to which values will be written. It's either 00ff or ff00, but that is enough to set any event bit we want. On the other hand, this leaves very little potential for arbitrary code execution: It's hard to do anything useful with only ff00 or 00ff.
Well if it turns out to be possible to use this to beat the recent ACE run for speed it would still be possible to find something cool to do with that run as a starting point so as to not let all the work to make ACE possible (and also getting there) go to waste over a run that would unfortunately (great discovery aside) probably be a lot less interesting to watch.
There might be some hope for this for arbitrary code execution actually.
I found yesterday that if you hold up to X-Ray up, it will start shifting in bytes that's certainly not 00FF or FF00. They seem to be the same every time so it could be data from ROM but I'm not sure, it was late so didn't have time to research much more.
I did manage to use it to trigger something funny though. By standing at the exactly right pixel I got it to set both the escape sequence trigger and also reset the gamestate so when loading a save the intro plays.
http://www.twitch.tv/tewtal/c/3980860
Doing this will also delete your missiles and make your item percent one percent lower, so doing this would result in 5% if you do it with 6% :)
Getting back to the intro after saving has been a known side effect of resetting the game state for a long time afaik, but having the escape sequence being triggered already when you land is just brilliant :P As well as doing any of that without the glitched beams of course.
I'm unsure if it should be considered to be lower than 6%, considering that you still collect 6 items and if you go purely by the percentage that the game shows you could have it be 0% with ACE.
I'm currently investigating the Yapping Maw shinespark glitch:
Link to video
It crashes the game, and as we all know, crashes often lead to arbitrary code execution, and this glitch only depends on the speed booster (and a yapping maw). Tracking down the full mechanism of this glitch is complicated, but a rough sketch is that $a60 contains a pointer to code to run depending on Samus' pose. When moving normally it has the value e913, but while shinesparking it has the value e90e. When yapping maws releases Samus, it sets this value to e913 (moving normally) even if she is shinesparking. This messes up the handling of the speed echoes that are supposed to circle around Samus when she hits a wall. A mirror of Samus' pose in $a28 is supposed to contain ffff when she stops sparking, but due to this error, it contains her actual pose, which further down the line causes ffff to be written to $aae. Which finally leads to this:
90d346 lda #$000f A:ffff X:0080 Y:0004 S:1ff4 D:0000 DB:90 NvmxdizC V: 56
90d349 sta $0a68 [900a68] A:000f X:0080 Y:0004 S:1ff4 D:0000 DB:90 nvmxdizC V: 56
90d34c lda $0aaf [900aaf] A:000f X:0080 Y:0004 S:1ff4 D:0000 DB:90 nvmxdizC V: 56
90d34f and #$00ff A:90ff X:0080 Y:0004 S:1ff4 D:0000 DB:90 NvmxdizC V: 56
90d352 asl a A:00ff X:0080 Y:0004 S:1ff4 D:0000 DB:90 nvmxdizC V: 56
90d353 tax A:01fe X:0080 Y:0004 S:1ff4 D:0000 DB:90 nvmxdizc V: 56
Things are sensible up to this point, where we perform the jump
jsr *$d37d[($aaf&ff)<<1].
We jump far into a region of the rom which is filled with ffffffff, which we execute
until we wrap around into RAM. $d37d is ROM, so what's going wrong must be
$aaf, which is documented as an index used for shinespark echoes.
This value is ff here, but is not set in this file. Should compare with normal shinespark
90d354 jsr ($d37d,x) [90d57b] A:01fe X:01fe Y:0004 S:1ff4 D:0000 DB:90 nvmxdizc V: 56
90fead sbc $ffffff,x [0001fd] A:01fe X:01fe Y:0004 S:1ff2 D:0000 DB:90 nvmxdizc V: 56
...
90fffd sbc $d3ffff,x [d401fd] A:01fd X:01fe Y:0004 S:1ff2 D:0000 DB:90 nvmxdizC V: 59
900001 sta $0000,x [9001fe] A:01fd X:01fe Y:0004 S:1ff2 D:0000 DB:90 nvmxdizC V: 59
900002 brk #$00 A:01fd X:01fe Y:0004 S:1ff1 D:0000 DB:90 nvmxdizC V: 59
900003 brk #$04 A:01fd X:01fe Y:0004 S:1ff0 D:0000 DB:90 nvmxdizC V: 59
900004 tsb $b5 [0000b5] A:01fd X:01fe Y:0004 S:1ff1 D:0000 DB:90 NvmxdizC V: 59
900006 bra $ff88 [8fff88] A:01fd X:01fe Y:0004 S:1ff1 D:0000 DB:90 NvmxdizC V: 59
900009 brk #$98 A:cc1b X:01fe Y:0004 S:1ff1 D:0000 DB:90 NvmxdizC V: 59
90000c brk #$53 A:001b X:01fe Y:0004 S:1ff1 D:0000 DB:90 nvmxdizC V: 59
90000d eor ($00,s),y [909094] A:0036 X:01fe Y:0004 S:1ff1 D:0000 DB:90 nvmxdizc V: 59
90000e brk #$27 A:0036 X:0036 Y:0004 S:1ff1 D:0000 DB:90 nvmxdizc V: 59
We enter oam here, and survive for a surprising amount of time
9004a9 beq $04ab [9004ab] A:0036 X:0036 Y:0004 S:1fef D:0000 DB:90 nvmxdizc V: 59
...
Ok, this brk is real. The others must be fake somehow. Amazingly, we get all
the way to 4f1 here, which is in oam I believe. So with lots of luck, one could
manipulate oam to jump somewhere better.
9004f1 brk #$0e A:9dd3 X:0037 Y:007e S:1ff7 D:0000 DB:90 NvmXdizC V: 60
008573 jml $808573 [808573] A:9dd3 X:0037 Y:007e S:1ff3 D:0000 DB:90 NvmXdIzC V: 60
The upshot of all this is that the Yapping Maw shinespark glitch ends up executing RAM as code, and while we have less control than with the charged space-time beam, it makes it into the powerful but tricky OAM region of memory, which is the same one I used for my original game-ending demonstration video.
So I think this is pretty pomising, and certainly worth more investigation. If it could be made to work, one could make a TAS that makes a beeline for the speed booster, and then heads for the closest yapping maw.
Edit: Total and I have investigated this now. It seems like snes9x does not emulate this correctly. In lsnes it seems like this inevitably leads to a BRK soon after it starts executing RAM. Too bad.
Edit2: It seems like the lava/sand shinespark crash is practically the same as the yapping maw glitch, including the same wrap-around to RAM, and the same method of avoidting the glitch (holding a button). So that's another promising method that didn't work out. Though, the current approach is already fully workable, we just hoped one could go faster.
Joined: 3/25/2006
Posts: 850
Location: stuck in Pandora's box HELLPP!!!
How did you get that $91C505 routine to execute? Some reverse engineering tells me that routine can only be executed by the Eye enemy (the thing that shines light at you after getting morph ball), and even then, I'm not sure if it's ever executed under normal circumstances
Joined: 4/17/2010
Posts: 11495
Location: Lake Chargoggagoggmanchauggagoggchaubunagungamaugg
Looks like lsnes really needs some symbolic debugging/tracing.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
PJBoy: It jumps there from $91beb2. I just used x-ray quite normally (while being oob). The code leading there did not seem particularly glitchy. That eye enemy uses a similar effect to the x-ray scope, so it wouldn't be odd for them to share some could, would it? Here is <a>a trace</a> of the execution leading up to it. It starts from just after we return from interrupt, which released the code from a long waiting cycle.
Looks like this route might make for a faster x-ray glitch route, and less boring, too: http://www.twitch.tv/twocat/c/3988333
Also it's a 5% completion of the game.