Submission #9011: IgorOliveira666's SNES Super Mario World "arbitrary code execution, glitchfest" in 42:49.44

Super Nintendo Entertainment System
arbitrary code execution, glitchfest
(Submitted: arbitrary code execution)
(Submitted: Super Mario World.smc USA)
BizHawk 2.9.1
154420
60.0988138974405
26882
PowerOn
Submitted by IgorOliveira666 on 4/13/2024 1:07 AM
Submission Comments
Look at me here again, destroying Super Mario World once again :)

Game Objectives ⭐

  • Emulator used: BizHawk 2.9.1
  • Allow Left+Right / Up+Down
  • Core subBSNESv115+
  • Abuses programming errors
  • Heavy glitch abuse
  • Corrupts memory
  • Take hit and use death to show funny things

About The Run ⭐

This TAS is a glitchfest that uses arbitrary code execution. I don't know which branch would be better between "glitchfest" or "arbitrary code execution", so I chose the second one, taking into consideration that this is not a "normal" glitchfest. The ideal would be "glitchfest with arbitrary code execution", but it's a bit long.
The process until writing the code is the same as Masterjun. It's all explained here. I just did some cool stuff before writing the code instead of going straight to eating the chuck :)

About The Code ⭐

Briefly, I wrote code in the game's subroutine ($7F8000) that allowed me, through controls 1 and 5, to change some addresses in the game's memory whenever I wanted. The code is as follows:
Pressing L on controller 1 = increments slot 7 sprite ID ($A5)
Pressing R on controller 1 = increments slot 6 sprite ID ($A6)
Pressing L on controller 5 = increments the item box ($0DC2)
Pressing R on controller 5 = changes Mario's powerup ($19)
Note: The code was written to use control 2, however, BizHawk 2.9.1 has 8 controls and, I believe, for this reason the buttons ended up being on control 5.
Note 2: I was unable to use the L/R of controller 5 with Luigi to change the powerup and item box because, I believe, there was a conflict since controller 5 is used to control Luigi. Therefore, playing with Luigi, I could only increase slots 6 and 7 and I was unable to use the benefits of having all the powerups and items in the item box.
The code is this:
LDA $18
AND #$10     ;|check if R (controller 1) is pressed
BNE ace1
LDA $18
AND #$20     ;|check if L (controller 1) is pressed
BNE ace2
LDA $0DA9
AND #$18     ;|check if L (controller 2) is pressed
BNE ace3
LDA $0DA9
AND #$20     ;|check if L (controller 2) is pressed
BNE ace4
LDA $0019
CMP #$04
BEQ powerup
RTL
ace1:
INC $00A4     ;|increment $A4 if $18 equals 10
RTL
ace2:
INC $00A5    ;|increment $A5 if $18 equals 20
RTL
ace3:
INC $0019    ;|increment $19 if $0DA9 equals 18
RTL
ace4:
INC $0DC2    ;|increment $0DC2 if $0DA9 equals 20
RTL
powerup:
STZ $0019    ;|stores 0 in $19 if the value is >4
RTL
Now the code in hexadecimal:
A5 18 29 10 D0 1C A5 18
29 20 D0 1A AD A9 0D 29
18 D0 17 AD A9 0D 29 20
D0 14 AD 19 00 C9 04 F0
11 6B EE A4 00 6B EE A5 
00 6B EE 19 00 6B EE C2
0D 6B 9C 19 00 6B
So basically I wrote this hex code at address $7F8182 through the inputs. It is not possible to write to $7F directly from the inputs due to the lack of bytes in the controls.
Because of this, I was forced to write a different code in $0A85 (a rarely used place in memory) just to be able to write the desired code in $7F8182. The code written in $0A85 was code that wrote the desired code in $7F8182. In short, I wrote the code in $0A85, made the game read this code and return to the main routine. After that, the desired code is automatically written to $7F8182. If you look at the memory at $0A85 at the time of the crash, you will see the code being written.
I'm not going to leave the code that was written in $0A85 here because it's a huge code. And maybe there are much easier and faster ways to write a code in $7F8182, but I didn't care about that, since this is a glitchfest and time has no relevance.
I won't leave the inputs here either, because, after all, there are more than 300 lines of inputs and I don't think anyone is interested, right? :)

More About The Code ⭐

Along with the code written in $7F8182, I also changed other addresses during the crash, they are:
  • $1F11, $1F17, $1F19 and $1F1A = All about Mario's Position on the map
  • $1F12, $1F1B, $1F1C, $1F1D and $1F1E = All about Luigi's Position on the map
  • $19C7 = Pipe exit at YI2
In other words, during the crash, in addition to writing code in the subroutine, I also changed the position on the map of Luigi and Mario and the exit of the blue pipe in YI2. You will obviously notice this in the video hehe.

Level by Level Comments? ⭐

Oh man, I don't think I need to comment level by level here, right? So much happened on the levels that it's difficult to explain. If anyone understands anything, feel free to explain it to me. 🥴
But basically, after writing the code, I was able to use it at all levels. You will see very strange things happening, random sprites coming out of the item box, Mario changing powerups out of nowhere, sprites transforming into other sprites and so on... Maybe someday I'll explain level by level, but I'm too lazy today :|

Special Thanks ⭐

  • Noise de Gole for helping me with ACE and for the code ideas (the code for changing sprite IDs is his idea).
  • Bruno Valads for helping me with extremely useful scripts.
  • Masterjun for the fabulous explanation in your submission that helped me write the codes and inputs.
  • You for watching :)

feos: Claiming for judging.
feos: Great work as always!
We historically label ACE playarounds/glitchfests as just ACE, so this movie's current branch is fine. And we already have a non-ACE glitchfest, which I don't think should be obsoleted by this run. Because as I've said before, we want to encourage more creativity, which means we need to show that through out judging decisions about co-existing branches. Inclusivity invites creativity, and in the end we will have more cool movies. When some Alternative branches start looking way too similar, we can obsolete some.

Spikestuff: Processing...
Last Edited by Spikestuff on 5/29/2024 1:19 AM
Page History Latest diff List referrers