SMB1 + SMB2J SRAM Plus (FDS hack)

A place where you can keep others updated about your NES-related projects through screenshots, videos or information in general.

Moderator: Moderators

Post Reply
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by tepples »

"I'm all about that BA55, 'bout that BA55, no treble"

That should work at first glance. Is there anything substantial in this patch that doesn't move, so that it can be assured not to work if patched on top of some random FDS side?
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

tepples wrote:"I'm all about that BA55, 'bout that BA55, no treble"

That should work at first glance. Is there anything substantial in this patch that doesn't move, so that it can be assured not to work if patched on top of some random FDS side?

Everything in ROM should be different as I assembled with ASM6 and just about every routine is different since I fixed all the glitches. So I would assume so. If anything comes up let me know and we can work on a different type of patch. --ShaneM
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

I want to hear your all's thoughts on this:

Hit the Axe and Keep It There

Do you all think that's a glitch or not? Would you all like it fixed? I seem to have overlooked this one when fixing glitches as it still occurs. The routine is found in "ChkFootMTile:" in doppleganer's disassembly and has to do with the CMP check with RAM $03 (what's loaded into A; block buffer) against the CMP #$C6 (axe BG tile ID).

So, who would like to see this fixed? Is it really a glitch? Thoughts or opinions? --ShaneM, the Master of ASM
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by tepples »

From a game designer's point of view: I think if Mario already burned Bowser to death, the axe should stay visible no matter the angle at which Mario touches it. This makes the rule consistent: hide the axe if and only if the bridge is collapsing.
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

tepples wrote:From a game designer's point of view: I think if Mario already burned Bowser to death, the axe should stay visible no matter the angle at which Mario touches it. This makes the rule consistent: hide the axe if and only if the bridge is collapsing.

Thank you for your input. I've interpreted your post as "this is an oversight on the developer's part". So, I will sum it up to "this is a glitch".

This has now been fixed. But slightly different from tepple's suggested fix. I've made it to always disappear because the code that jumps to it either loads RAM $03 (left foot metatile) or $00 (right foot metatile) to the CMP #$C6 for the axe tile. Going too far right caused the current ID to get cleared from the block buffer. Since either $00 or $03 is used and this is the main routine for all collision in the game (a stupid place to put axe tile code) I couldn't push A onto the stack to be loaded after this since PHA only stores immediate values (even found at RAM addresses). I couldn't use register X for a CPX routine after the CMP #$C6 if the Z flag was set (hence it didn't branch) and Y is also being used too. What I did was a data fix for this. I changed all scroll stops from $5D for castle levels to $4D. Surprisingly, it is absolutely not noticeable but rather it fixes this glitch from occurring. I've fixed it in SMB2J so far and will change it in SMB1, soon. I am also still working on the manual to improve it, too. So for now, here's SMB The Lost Levels RC4. --ShaneM, the Master of ASM

Fixed:
Hit the Axe and Keep It There
Attachments
Super Mario Bros. 2 - The Lost Levels with SRAM (Japan)_002.png
Super Mario Bros. 2 - The Lost Levels with SRAM (Japan)_002.png (3.33 KiB) Viewed 6473 times
Last edited by ShaneM on Sun Nov 01, 2015 11:00 am, edited 1 time in total.
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

You know what I just realized? The SNES version of Super Mario Bros.: The Lost Levels actually fixes the Axe by doing EXACTLY what I did by shorting the scroll stops! o_0
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

I'm getting ready to release the new SMB1 build fix. I want some opinions: How many of you would like to see the original SMB1 GFX for the SMB1 portion? How many prefer the Lost Levels tiles? --ShaneM
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

Still haven't heard what people want me to do with SMB1. But, I've corrected all 'Engrish' found on SMB2J and will release it soon. Text fixed includes the World 9 intro screen, as well as Game Over screen for World 9. Another text corrected is the poem on 8-4 to make it slightly more poetic and logical, as well as make use of another beta tile that I discovered. The beta tile is from ANNSMB (All Night Nippon) and can be found in the FCEUX PPU viewer as tiles $FB-$FE. One is a heart, two are Japanese and one is an exclamation point. I've added the heart from ANNSMB into the SMB2J Princess poem as sort of a border. I will release this soon; work on improving the manual has begun! --ShaneM, the Master of ASM

EDIT: For those wondering how I got the 'heart' beta tile to fit from ANNSMB into SMB2J, I've replaced the "J" tile with it since "J" is never used.
Attachments
Super Mario Bros. 2 - The Lost Levels with SRAM (Japan)_003.png
Super Mario Bros. 2 - The Lost Levels with SRAM (Japan)_003.png (4.25 KiB) Viewed 6346 times
User avatar
Hamtaro126
Posts: 818
Joined: Thu Jan 19, 2006 5:08 pm

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by Hamtaro126 »

In your current script, as well from the original version:

Code: Select all

HURRAH TO (two spaces) [Player Name]
The two spaces needs to be changed to only one space, essential if correcting errors!

EDIT: I agree, SMB1 can still use most of it's original graphics, and it will still be fun,

- move the title screen to the PRG instead of CHR (of which you already did that),
- remove off the sprite graphic associated with sprite 0 (as IRQ is used instead),
- Remove one of the duplicate tiles for the stem of the Piranha Plants,
- Remove the semi-duplicate tiles for the top of bricks, as SMAS SMB1 uses the same character as the bottom,
- OPTIONAL: If score sprites does not matter, remove the sprites only (Scoring can still be used if you need it!)
- PROTIP: The second coin sprite can be flipped like in SMB3 by adding a bit of code to flip the second frame, using 3 CHR tiles instead of 4.

and now you got a bit more CHR to use

A SUGGESTION: Maybe making Princess Peach and the Ending Door different colors for use in your SMB2J and SMB1, Just replace Peach's Attribute to the one used in-game as Green, but make it so that the door is not green and uses a colorset of $08,$28,$18 (Wood-like colors) and when Peach appears, the palette turns to the following colors: $25,$36,$08 (pink, skin, brown)
AKA SmilyMZX/AtariHacker.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by tepples »

Hamtaro126 wrote:- Remove the semi-duplicate tiles for the top of bricks, as SMAS SMB1 uses the same character as the bottom,
But then there'd be no contrast for the brick in front of the "castle wall" repeating tiles near the end of 8-3. SMAS doesn't need it because it removes the repeating tiles in favor of a parallax background.
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

Hamtaro126 wrote:In your current script, as well from the original version:

Code: Select all

HURRAH TO (two spaces) [Player Name]
The two spaces needs to be changed to only one space, essential if correcting errors!

EDIT: I agree, SMB1 can still use most of it's original graphics, and it will still be fun,

- move the title screen to the PRG instead of CHR (of which you already did that),
- remove off the sprite graphic associated with sprite 0 (as IRQ is used instead),
- Remove one of the duplicate tiles for the stem of the Piranha Plants,
- Remove the semi-duplicate tiles for the top of bricks, as SMAS SMB1 uses the same character as the bottom,
- OPTIONAL: If score sprites does not matter, remove the sprites only (Scoring can still be used if you need it!)
- PROTIP: The second coin sprite can be flipped like in SMB3 by adding a bit of code to flip the second frame, using 3 CHR tiles instead of 4.

and now you got a bit more CHR to use

A SUGGESTION: Maybe making Princess Peach and the Ending Door different colors for use in your SMB2J and SMB1, Just replace Peach's Attribute to the one used in-game as Green, but make it so that the door is not green and uses a colorset of $08,$28,$18 (Wood-like colors) and when Peach appears, the palette turns to the following colors: $25,$36,$08 (pink, skin, brown)
I'll try to go in order, here.

1) The two spaces within the poem on 8-4/D-4 for player's name was intentional on Nintendo's part for symmetry. Look at the end of the sentence lines, see how they match and go in pattern? Removing that space would break symmetry. (ie "saved" on line 2 and "Luigi" on line 3)

2) Thanks for the SMB1 opinion; it will be weighed in.

3) "remove off the sprite graphic associated with sprite 0 (as IRQ is used instead)" - SMB2J does not use Sprite 0 for the undercoin anymore. Since SMB1 is a hack of that, it's not used anyway.

4) "Remove one of the duplicate tiles for the stem of the Piranha Plants" - Why? Then the Piranha Plant will look odd...

5) "Remove the semi-duplicate tiles for the top of bricks, as SMAS SMB1 uses the same character as the bottom" - What tepples said.

6) "The second coin sprite can be flipped like in SMB3 by adding a bit of code to flip the second frame, using 3 CHR tiles instead of 4." - I would need more CHR RAM to create animated sprites. Now, if you've ever hacked SMB2J on the FDS, you'd know that this is next to impossible to do.

7) "A SUGGESTION..." - We'll see.
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

Right now I'm trying to rip some code from the EU version of SMB1 to improve TLL. The SNES version actually make the same changes to the EU TLL. Turns out not all their changes were necessary. So far, I've ripped the vertical collision fix for underwater blocks from that version, except it I coded myself a little differently. New build coming soon. I will make more comparisons and some to the SMAS EU, too. For now, here is the Nintendo-original EU fix for minusing vertical gravity when bumping underwater blocks vs. my fix from scratch.

Really, this is not a glitch that they fixed more or less a customization. Commentary notes are mine and so is the "watertype" label. If you borrow my method, credit me.

Code: Select all

;original NTSC/Japan
NYSpd:
       lda #$01               ;set player's vertical speed to nullify
       sta Player_Y_Speed     ;jump or swim

Code: Select all

;original Nintendo EU SMB1
NYSpd:
       ldy #$01                ;set player's vertical speed to nullify (one by default)
       lda AreaType           ;are we in a water type level?
       bne watertype         ;if not, then branch
       dey                        ;otherwise set Y as #$00 to impose gravity
watertype:      
       sty Player_Y_Speed   ;store either #$01 or #$00 depending on terrain type

Code: Select all

;the ShaneM way
NYSpd:
       ldy #$00                ;set player's vertical speed to nullify (zero by default)
       lda AreaType           ;are we in a water type level?
       beq watertype         ;if so, then branch
       iny                        ;otherwise set Y as #$01 to set gravity
watertype:      
       sty Player_Y_Speed   ;store either #$01 or #$00 depending on terrain type
I plan on releasing the next RC on Tuesday as well as an updated manual. --ShaneM, the Master of ASM
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

Okay, I'm puzzled. Thoughts?

I'm a little confused about this EU's change, though I understand what the code is doing. Below is the code and I was hoping to get your all's weigh in on what you think. After it, I give my info on what the code does (I give the routine "ChkForPlayerInjury" that branches right before it as well):

Code: Select all

ChkForPlayerInjury:
          lda Player_Y_Speed     ;check player's vertical speed
          bmi ChkInj             ;perform procedure below if player moving upwards
          bne EnemyStomped       ;or not at all, and branch elsewhere if moving downwards
ChkInj:
.ifdef Japan
          lda Enemy_ID,x         ;branch if enemy object < $07
          cmp #Bloober           ;(Goomba, Buzzy Beetle, Green/Red Koopa and Hammer Bro will branch)
          bcc ChkETmrs           ;to check stomp/invincible timers and enemy facing direction
          lda Player_Y_Position  ;otherwise load player's vertical position
          clc                    
          adc #$0c               ;and add 12 pixels to player's vertical position
.else
          lda #FlyCheepCheepFrenzy   ;#$14 gets loaded into A
          ldy Enemy_ID,x         ;branch if enemy object is not FlyCheepCheepFrenzy
          cpy #$14                         
          bne +                  ;branch to Player_Y_Position
          lda #Bloober	         ;load #$07 into A
+         adc Player_Y_Position  ;RAM $ce, add carry player's vertical position to A
.endif          
          cmp Enemy_Y_Position,x ;compare modified player's position to enemy's position
          bcc EnemyStomped       ;branch if player's position above (less than) enemy's
ChkETmrs: lda StompTimer      ;check stomp timer
          bne EnemyStomped       ;branch if set
My thoughts: I think this code is only branched to if the player is vertically moving upward or standing still; moving downward vertically causes the BNE to branch in "ChkForPlayerInjury". "Player_Y_Speed" (RAM $9F) will be a signed value if the player is going up and unsigned if going down (so MSB or d7 WILL be set if this branch occurs). Now, if the player is indeed going up, we branch to "ChkInj", the routine in question. What the NTSC seems to do is branch to check various timers if dealing with enemies such as Goombas etc. or anything less than Blooper (#$07) as I labeled above. If the enemy in A plus X offset is #$07 or greater it will thus not branch because the Carry is set. Next, we load A with what's loaded at RAM $CE, or Player_Y_Position. (The player's Y is stored as #$B0 when on the ground at the lowest playable part of the level, decrementing from that value as the player is vertically inclined/stomps on an enemy.) $CF plus X offset is where the Enemy_Y_Position is stored and is #$08 greater than the player's when on flat ground. So, for example, a Goomba (RAM $16,x will load an #$06 in Memory) on flat ground will have a #$B8 loaded into RAM $CF plus X whereas the protagonist will have #$B0 in that occurrence stored at RAM $CE.

So anyway, if the enemy object in Memory plus X is #$07 or greater, Carry will be set so we will clear Carry and add #$0C to A (which is loading the player's current Y position). So A will thus have whatever that value is plus #$0c added to it for the upcoming comparison with RAM $CF plus X register (in layman's terms, the enemy which is loaded for the comparison since 6 enemies can be loaded at once). At the end of the .endif conditional statement above, we now move onto comparing the current value in A with the enemy offset. If the player's Y is at all above (being less than) the enemy's, we thus branch to the enemy being stomped "EnemyStomped" (and the timer flag at RAM $0791 will be set to branch; from there it checks for certain enemies such Spinys or other 'untouchable' enemies and branches accordingly to injure player or else award player certain pts.). If Carry is set, then we move on to check various timers and branch accordingly to injure player/turn enemies around etc. For enemies that are not Lakitu, Cheeps or the likes, we skip all of this. That makes sense, logically.

What the EU does: It appears to use the Y register for the check, but loads A with #$14 by default. Y register is loaded with the value stored at RAM $1E plus X register. The next thing we do is compare register Y with #$14 (or Cheep-Cheep frenzy enemy) and any other enemy which is NOT Cheep-Cheep frenzy will thus branch and we clear the Z flag. If it is the Cheep-Cheep, d6 will be set and thus skip the branch. If it is Cheep, then we now load A with #$07 rather than the previously loaded #$14. (So A will either be loaded with #$14 or #$07 depending on the current enemy plus X register and whether we previously branched or not we will end up with at the "adc Player_Y_Position") Next, we are at "adc Player_Y_Position", instead of A being loaded with this value we ADC with it instead, but Carry will be cleared here so we need not CLC. Neither will Carry be set with what's at RAM $CE. From there we move onto the linear code with the CMP,X. If the player's Y is at all above (being less than) the enemy's, we thus branch to the enemy being stomped "EnemyStomped" (and the timer flag at RAM $0791 will be set to branch; from there it checks for certain enemies such Spinys or other 'untouchable' enemies and branches accordingly to injure player or else award player certain pts.).

So my question is, what's the point of changing this in the EU? Obviously all enemies are now checked instead of those that are #$07 or greater. And we add either load A with #$07 or #$14 rather than the ADC #$0C like NTSC does. It singles out flying Cheep-Cheep and gives them #$07, but why? What kind of fix is this?

EDIT: Oh, forgot to mention, I had to comment on everything on the code myself since doppleganger didn't really go into detail. I will submit a better commented version to RHDN when I'm done. Really want to hear thoughts on this code, though, as I'm perplexed. --ShaneM, the Master of ASM
Last edited by ShaneM on Sun Jan 18, 2015 7:41 pm, edited 1 time in total.
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

I think I have an idea of what this fix is for. It's some sort of fix for if the player collides with the Cheep-Cheep at a weird angle. It corrects collision to "stomp" on the enemy rather than taking damage when collision is made while the player is jumping. (This fix implies that the player is jumping thereby having a signed integer at RAM $9F to do this check.) I'm going to try and figure out why the check was made to add #$14 for other enemies (though it's inverted in the EU and we ADC Player_Y_Position instead of loading A with the value). Point is, I want to see why that was done differently in EU to include enemies that are #$06 or less into the comparison (thereby making the label "ChkETmrs:" completely useless in the EU build).
User avatar
ShaneM
Posts: 353
Joined: Wed Apr 04, 2012 4:15 pm
Location: United States of America (USA)
Contact:

Re: SMB1 + SMB2J SRAM Plus (FDS hack)

Post by ShaneM »

ShaneM wrote:I think I have an idea of what this fix is for. It's some sort of fix for if the player collides with the Cheep-Cheep at a weird angle. It corrects collision to "stomp" on the enemy rather than taking damage when collision is made while the player is jumping. (This fix implies that the player is jumping thereby having a signed integer at RAM $9F to do this check.) I'm going to try and figure out why the check was made to add #$14 for other enemies (though it's inverted in the EU and we ADC Player_Y_Position instead of loading A with the value). Point is, I want to see why that was done differently in EU to include enemies that are #$06 or less into the comparison (thereby making the label "ChkETmrs:" completely useless in the EU build).

Okay. I now have a perfect understanding of what this EU difference does. I will get into more detail tomorrow when I get up and after I get some free time. In a nutshell, this really doesn't fix any glitch. Rather, if corrects an oversight on the NTSC programmer's part. It is customization, as well as optimization. It has to do with a very specific jump slightly over an enemy, so close to the head that it should be counted as a "stomp" in the NTSC but counts as a player injury if the enemy is #$06 or less. I tried changing the code and specifically testing with an enemy that sets Carry (Lakitu) to verify. The EU separates Cheep-Cheep frenzies from this because on the account of diagonal enemy jumping on their part since their bounding box data is different. I will incorporate this into my SMB2J build; it only takes 1 additional byte and I found an opportunity to optimize code in "KillPlayer" to earn two free bytes. --ShaneM, the Master of ASM
Post Reply