Posts for p4plus2


Experienced Forum User
Joined: 12/29/2011
Posts: 13
Samsara wrote:
I'm assuming that's a joke as well, but as for my actual reasoning: I, nor anyone else, can conceivably prove that this run does reach the ending within the entire lifetime of humanity, the Earth, and potentially the universe itself. We can't accept it without verification that it is a complete movie, and since it's impossible to verify... Yeah, it can't be accepted. GEG ends input 40 seconds earlier too if you wanna go into pedantic semantics
Is this a challenge :P? Because I think very well could prove this TAS eventually completes.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
Sorry, but I think I communicated something poorly, so let me try again. Those BRKs are not actually BRKs as SNES9x claims, rather they are valid instructions residing in the controller registers. OAM still does n ot directly change the game mode, it is the controllers. This time the game mode is set to #$18 and then $13C6 is set to #$08 which is the "roll credits" cutscene. That BRK analysis would have been true if they were real BRKs and not a glitch in the emulator. I still have questions to the legitimacy though. Many SNES documents I read said registers can not be executed ever, others said read based registers can be executed. Additionally, more than two controllers are used requiring a multitap or similar device. However, multitaps require a "BIOS" (term used loosely as manual small drivers are possible) to be correctly read. I do need to do more research, and even more important I will try and get in contact with somebody that has a flashcart to test some ideas. Sorry for any confusion. If anybody needs clarification or has further questions, just let me know I'll do my best. I do still believe this glitch is possible, but not in the currently used method.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
Personman wrote:
No one (I don't think?) wants to eliminate the longer runs. The idea is to have the "less-glitched" runs be the ones that get a special category, while the absolute fastest run is labeled any%. After all, the name does imply at any percent of the game's objectives may be completed before reaching the end state. So we can have a "beats Bowser" run and a "beats Ganondorf" run or whatever. The default, any% category should go to the absolute fastest run.
This, I can support. I think this sounds like a much better alternative.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
asteron wrote:
No one is calling the other run non-glitched. This one is labeled "glitched" (in quotes) because it is dominated by a glitch that evades pretty much all of the game objectives. The glitch in this run is similar to a buffer overrun exploit I believe in which you are manipulating executable code as if it was data. This tends to be among the most extreme of glitches and is not employed in the other run.
Totally false. This glitch changes one value on the stack, but it is by no means an overflow. The stack is altered from spitting out a sprite with index #$FF, so when "sta $00e4,y" is executed ($01f203)it stores to $01E3. As linked in the original post, I have documented how this glitch works very thoroughly here: http://99.10.160.182/glitch.asm My point was, "extreme" glitches are still glitches. How does one arbitrarily decide what is "extreme"? Just because a glitch requires more planning makes it "extreme"? Or is it by how the game reacts to the glitch? or is it by how the glitch interacts as a software level? Or by how hard it is to pull off? Glitches are glitches, there is no magical way to classify them on magnitude.
While the "glitched" label is old, I think it is fine to use. It is there as a kind of warning to the viewer that this run will be using glitches to "complete" the game in an unusual manner that evades major game objectives. A casual viewer may not consider the game to be "beaten" as much as it has been "broken".
I am not saying a warning shouldn't exist, I am saying that this "glitch" does not need a special category. Any% is any% and an ending was achieved via glitches. So, the warning in tags in justified, but saying it needs a special category because of the style of glitch is ridiculous. See above about judging the magnitude of a glitch.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
Really what define "RAM corruption"? I seriously do not consider this to be "RAM corruption". Most glitches in SMW involve manipulating RAM on some level, so where do you draw the line? Code can execute in RAM and does so in SMW every frame($7F8000 in RAM is the OAM clear routine that sets sprites off screen), so that is a poor argument as well. It is additionally unfair to call this a glitched run and a "regular" any% non-glitched. All SMW TASes I am aware of abuse glitches, even if it is simply using alternating frames to gain extra speed. And I am pretty sure the definition of a glitch is malfunction, which this certainly is.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
SmashManiac wrote:
Wow, very nice and precise explanation p4plus2! Impressive, I like that! So basically, beating SMW normally eventually causes the game to reach game mode 29 and stay on it until reset. If somehow we would have jumped directly to game mode 29 from game mode 14 however, it would have looked as if the game simply hanged while playing instead of a win, but by passing through game mode 27 beforehand, then we get the ending screen, which is the latest output feedback of the ending sequence. Also, if I understand the code you posted correctly (correct me if I'm wrong), passing through game mode 26 simply allows a smoother transition, since the game would otherwise need to overflow the brightness value during game mode 28 to reach game mode 29. Considering this, even though reaching game mode 29 is the final win state of SMW, since there is no win output feedback that far in the code, the best test in my opinion to determine a win is to check if the program counter equals $00963D, or in other words if the game is about to execute the code associated with game mode 27. As for those that feel that the correct win test should be at the earliest point of the ending sequence rather than the latest, well that point would be the exact moment when Bowser is defeated, not the Thank You screen. Therefore, both versions of this run would need to be rejected, since adding the 3 frames would merely be a compromise that satisfies nobody except on a purely subjective level.
Pretty much spot on. The only additions I hate to make to that is that the "smoother transition" enables F-Blank which is required to not have glitched graphics from writing to VRAM outside of a blank. But those will be temporary effects, so game mode #$27 is still a fair judgment on whether or not to call it a victory.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
DarkKobold wrote:
Derakon wrote:
p4plus2 wrote:
How do you define the "machine thinking you won"? As far as the SNES cares it just executes opcodes, there is no real hardware "win state". That said, there are software level win states, and I believe that once a software level "winning" routine has been triggered, that would qualify as winning.?
So, if I found a "write to save memory" glitch and set the win bit, then you'd accept that the game was completed, even if I was in the middle of a level at the time?
This is why I prefer the credits version - it doesn't just display a splash screen, it plays the level victory fanfare, and actually executes an ending. With this one, the splash screen just appears, and the music keeps going. I'd like to know if you can still actually move Mario during this (watching x/y values).
WARNING: Huge technical post ahead. No you can not move Mario. The game no longer is in a level, it it has changed its mode of processing entirely. In this glitch the game mode is changed to #$26 (as I explained like three times now). But let me bring the actual code into this now: First lets talk about how SMW actually processes its game loop. There is a small infinite loop that basically checks if NMI has run, and once it has it will run a routine called "RunGameMode". So lets take a look at the game loop:
GameLoop:
        LDA $10                       ;$00806B        |\ Main wait loop
        BEQ GameLoop                  ;$00806D        | | $10 is set in NMI to $00
        CLI                           ;$00806F        | | Enable interrupts
        INC $13                       ;$008070        | | Increment frame counter
        JSR RunGameMode               ;$008072        | | Run the game
        STZ $10                       ;$008075        | | Clear $10
        BRA GameLoop                  ;$008077        |/ Back to the wait loop
As you can see, the game simply runs in an infinite loop. So the real important thing to us is what happens in the different game modes. So lets take a look at the routine next.
RunGameMode:
	LDA.w $0100                   ;$009322        | Load the current game mode
	JSL ExecutePtr                ;$009325        | Call the execute pointer routine
Simple enough, So what does this mean? It means there are a series of pointers that control game execution. So here are the important game mode pointers to us, I have snipped non-important ones.
*snip*
dw InLevelGameMode                    ; 14 - In level
*snip*
dw CODE_009F6F                        ; 26 - Fade to the end
dw CODE_00963D                        ; 27 - load the end 
dw CODE_009F7C                        ; 28 - Fade in to the end
dw Return00968D                       ; 29 - END (last game mode in SMW)
In game mode 14 is when you are controlling Mario and the level is executing as normal. The code for game mode 14 is huge, I won't torture you with that unless you want to see the code for it. Game mode 26 is the code there the game will fade out to enter F-Blank (brightness of 00 with the negative bit set) in preparation for game mode #$27 to upload graphics.
CODE_009F4C:
        LDA.w $0DAE                   ;$009F4C        |\ Calculate the current brightness step
        CLC                           ;$009F4F        | |
        ADC.w DATA_009F2F,Y           ;$009F50        | |
        STA.w $0DAE                   ;$009F53        |/ Store the current brightness ($2100 mirror)
        CMP.w DATA_009F33,Y           ;$009F56        |\ If the brightness has not reached the desired brightness
        BNE CODE_009F66               ;$009F59        |/
        INC.w $0100                   ;$009F5B        | Increment the game mode (putting you at game mode #$27)
        LDA.w $0DAF                   ;$009F5E        |\ Flip the Mosaic/Fade direction
        EOR.b #$01                    ;$009F61        | |
        STA.w $0DAF                   ;$009F63        |/
CODE_009F66:
        LDA.b #$03                    ;$009F66        |\ Copy the mosaic mirror to the mosaic register
        ORA.w $0DB0                   ;$009F68        | |
        STA.w $2106                   ;$009F6B        |/
Return009F6E:
        RTS                           ;$009F6E        | Done with game mode 26

CODE_009F6F:
        DEC.w $0DB1                   ;$009F6F        |\ Keep the current game mode active
        BPL Return009F6E              ;$009F72        | |
        JSR KeepModeActive            ;$009F74        |/
CODE_009F77:
        LDY.w $0DAF                   ;$009F77        |\ Load the current Mosaic/Fade direction
        BRA CODE_009F4C               ;$009F7A        |/ Branch to an earlier portion of code
Game mode #$27 is where the actual graphics are uploaded. This game mode simply prepares the screen in F-Blank.
CODE_00963D:
        JSR CODE_0085FA               ;$00963D        | Turns off IO and does some DMA
        JSR Clear_1A_13D3             ;$009640        | Clean RAM $131A to $13D3
        JSR SetUpScreen               ;$009643        | Do some screen setup
        JSR CODE_00955E               ;$009646        | Upload the layer graphics to VRAM
        LDA.b #$19                    ;$009649        |\ Set some screen properties(such as palette settings)
        STA.w $192B                   ;$00964B        | |
        LDA.b #$03                    ;$00964E        | |
        STA.w $192F                   ;$009650        | |
        LDA.b #$03                    ;$009653        | |
        STA.w $1930                   ;$009655        |/
        JSR UploadSpriteGFX           ;$009658        |\ Upload the palette and graphics
        JSR LoadPalette               ;$00965B        |/
        LDX.b #$0B                    ;$00965E        | Load the loop index
CODE_009660:                          
        LDA.w TheEndPalettes,X        ;$009660        |\ Do some palette corrections
        STA.w $08A7,X                 ;$009663        | |
        LDA.w DATA_00B71A,X           ;$009666        | |
        STA.w $08C7,X                 ;$009669        | |
        LDA.w DATA_00B726,X           ;$00966C        | |
        STA.w $08E7,X                 ;$00966F        | |
        DEX                           ;$009672        | |
        BPL CODE_009660               ;$009673        |/
        JSR CODE_00922F               ;$009675        | DMA the palettes to CGRAM (they were in mirrors before)
        LDA.b #$D5                    ;$009678        |\ Set and load a layer three image (THE END text)
        STA $12                       ;$00967A        | |
        JSR LoadScrnImage             ;$00967C        |/ 
        JSL CODE_0CAADF               ;$00967F        | Copy some sprites to OAM (the characters)
        JSR CODE_008494               ;$009683        | Run the OAM size table routine
        LDX.b #$14                    ;$009686        |\ Useless loads, probably old leftover code
        LDY.b #$00                    ;$009688        |/
        JMP CODE_009622               ;$00968A        | Jump ahead
                                      
CODE_009622:                          
        JSR KeepModeActive            ;$009622        | Keep the game mode active(unused since there is no $0DB1 check)
        LDA.b #$09                    ;$009625        |\ Set the background mode
        STA $3E                       ;$009627        |/
        JMP CODE_0093EA               ;$009629        | Jump ahead
                                      
CODE_0093EA:                          
        LDA.b #$01                    ;$0093EA        |\ Set to the cutscene mode
        STA.w $0D9B                   ;$0093EC        |/
        LDA.b #$20                    ;$0093EF        |\ Update some screen settings
        JSR ScreenSettings            ;$0093F1        |/
        INC.w $0100                   ;$0093F4        | Increment the game mode
        LDA.b #$81                    ;$0093F7        |\ Renable NMI
        STA.w $4200                   ;$0093F9        |/
        RTS                           ;$0093FC        | Done with game mdoe #$27
Game mode #$28 is a small game mode that shares most of the code with #$26. This game mode is responsible for doing the fade-in effect.
CODE_009F7C:
        DEC.w $0DB1                   ;$009F7C        |\ Check if the game mode should be kept active
        BPL Return009F6E              ;$009F7F        |/
        LDA.b #$08                    ;$009F81        |\ Set the number of frames to delay the fade-in steps
        JSR CODE_009F2B               ;$009F83        |/
        BRA CODE_009F77               ;$009F86        | Run the fade code from game mode #$26 (opposite direction)
And lastly, game mode #$29. The simplest one of them all.
Return00968D:
	RTS
Thats it. The game just simply returns. It has nothing more to do. For all intents and purposes, the game is done with execution. Hopefully this helps clarify what a "winning" state in SMW is.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
SmashManiac wrote:
Unfortunately, in the context of a friendly competition, there needs to be a clear goal that everyone can agree upon. So then, when do you beat the game? When the machine thinks that you've won, when you feel that you've won, or when the original game design says that you've won? For somebody like me that has studied game theory, the only reasonable answer is when the machine thinks that you've won, because it is easily definable and observable, while the other choices are open to interpretation and subjectivity.
How do you define the "machine thinking you won"? As far as the SNES cares it just executes opcodes, there is no real hardware "win state". That said, there are software level win states, and I believe that once a software level "winning" routine has been triggered, that would qualify as winning.♦
Experienced Forum User
Joined: 12/29/2011
Posts: 13
ALAKTORN wrote:
I don’t even know what that means, which is why I abstained from voting
In SMW the current game mode is RAM addres $0100. #$14 for example is the "in level" game mode. In this glitch the game mode is changed prematurely to #$26 which tell the game that the player has one and to display "THE END"*. *Actually #$26 is a fade out, #$27 is load "THE END" graphics, #$28 is the fade in, and lastly #$29 is simply an RTS meaning the game basically enters an infinite loop. At the end of each of these game mode the game mode is incremented, just as it is in a regular SMW run. The final game mode in a normal run is #$29 as is here.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
feos wrote:
I can't hack a game, but one can add Mario's position to the heads up display, so that the tester would see if he is in correct place.
If you can see the position, the correct position that means you can no longer do the glitch already. That means you have to precalculate the speed and know how fast you are going then hope you are fast enough to spit on the exact frame required. It is possible, just extraordinarily hard.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
feos wrote:
When FinalFighter discovered his Rockman's glitch (DelayStageClear), he made a hack that allowed to test this glitch with higher possibility, and it was tested on console via Power Pak. Is it possible to invent something like that to check the possibility itslef on console? http://tasvideos.org/forum/viewtopic.php?p=228835#228835
Given the RAM used, it would be tricky, but doable. You would need to override OAM and the RNG in order to give a reasonable shot of doing this on console. Even doing that, this glitch depends on you being at an exact position on the screen which doesn't help. If you take a look at the document I made about this glitch, you can see why it WILL work on console. If this didn't work on console, we are doing something fundamentally wrong in emulation as most of the opcodes involved are basic and nothing involving SNES registers. So to recap: 1) Override OAM 2) Override the RNG 3) Hope you get the exact position on brown platform 4) Make sure yoshi has a null sprite If you do all of that you could feasibly do this on console easier. Get one part wrong, and you will probably just crash the game. The reason this glitch requires brown platforms(which I never explained in the document) is because the brown platforms preform some tricks to hide mario then recall the his display and handling routines. They do this to avoid the "jitter" effect which would have happened trying to snap mario to a single location. You can find a brown platform disassembly here: http://99.10.160.182/evil.asm I never finished commenting it, but the important part is the call to JSL $00E2BD before the storing of #$FF to $78(that JSL is called in the RTS just before the storing of #$FF). This all happens at CODE_01CA6E. If you really want to try and make a hack I will see if I can toss something together. But as I said, I have already tested pieces of this on an SNES and conceptually it all works. Its just a matter of getting all components perfect which I could never do on console. EDIT: Here is a link to my document so you don't have to go to the first post, http://99.10.160.182/glitch.asm
Experienced Forum User
Joined: 12/29/2011
Posts: 13
The RNG is reset every time you enter a level. This is in order to help keep objects which use the RNG consistent each time the level is entered. Because the SMW RNG doesn't use user input or any other variable source as entropy, it will always take the same number of iterations to get a desired result. However, being off by a single frame WILL cause it to fail. This glitch is very sensitive, but not impossible. The contents of RAM is extremely hard, but not impossible as well. Especially if there were a bot involved. In theory the same input will result in the same RAM values. The only exception would be uninitialized RAM which this glitch does not use. If this is attempted on console, there are a million ways to go wrong and only a few hundred to get it right at best.
Experienced Forum User
Joined: 12/29/2011
Posts: 13
Sonikkustar wrote:
I'm a little skeptical to vote on this because it looks like this glitch is caused by inaccurate emulation. I'll vote once there is more concrete evidence that this is a legitimate glitch.
While I was unable to fully replicate the glitch on console, I have been able to test each component and it IS possible in theory on console. Additionally, having debugged this glitch and seeing the ASM involved, there is no reason why this would be from inaccurate emulation. If you actually read the technical document that Masterjun included, you would know this glitch works by changing the game mode (RAM address $0100) by manipulating the stack, RNG, and OAM mirrors. I can confirm with an extremely high degree of certainty this is not an emulator specific glitch.