Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
1 user currently in Super Mario World hacking: labmaster | 3 guests
Acmlm's Board - I2 Archive - Super Mario World hacking - Ran into another ASM wall | |
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
User Post
Kailieann

Koopa
Level: 11

Posts: 35/106
EXP: 5320
For next: 665

Since: 10-09-05

Since last post: 2 hours
Last activity: 2 hours
Posted on 10-14-05 05:24 AM Link | Quote
Okay, this time I was trying to make a block that would respond to certain buttons being pressed.

Most of the button input is handled by 7E0015 (as some of you already know), using the following values (or combinations thereof)

01 Right
02 Left
04 Down
08 Up
10 Start
20 Select
40 Y
80 B

For my test block, I was trying to get it to respond to the combination of Right+B (81). But the problem is that I wanted it to respond to that combination regardless of any other buttons that might be pressed (seeing as I very rarely take my thumb off the Y button, myself).

So instead of CMP, I went with BIT, and got... nothing.
Again, for testing, the result I was aiming for was to set Mario's coins to 99. But, of course, it didn't, because it did nothing.

So. What did I screw up this time?

AD 15 00 24 81 D0 01 60 A9 63 8D BF 0D 60

LDA $0015 ; Load 7E0015 to accumulator
BIT #$81 ; AND 81, set z-flag if bits are shared
BNE #$1 ; Skip 1 instruction if z-flag not set
RTS ; Return
LDA #$63 ; Load 63 to accumulator
STA $0DBF ; Store accumulator to 7EBF0D
RTS ; Return

I'll admit, I've never been good with bitwise operators, and I've still only been learning ASM for less than a week, but at least I'm trying.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 7674/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 10-14-05 05:42 AM Link | Quote
Try AND in place of BIT.
Kailieann

Koopa
Level: 11

Posts: 36/106
EXP: 5320
For next: 665

Since: 10-09-05

Since last post: 2 hours
Last activity: 2 hours
Posted on 10-14-05 06:05 AM Link | Quote
ohhkay....
it worked...
but only from the right side of the block, and not the left.
And also regardless of whether or not B is pressed.


(edited by Kailieann on 10-15-05 01:55 AM)
(edited by Kailieann on 10-15-05 01:57 AM)
Sukasa

Boomboom
Error 349857348734534: The system experienced an error.
Level: 57

Posts: 1910/1981
EXP: 1446921
For next: 39007

Since: 02-06-05
From: *Shrug*

Since last post: 6 days
Last activity: 1 day
Posted on 10-14-05 07:41 AM Link | Quote
After the AND #$81, add in a CMP #$81. That should do the trick.
Kailieann

Koopa
Level: 11

Posts: 39/106
EXP: 5320
For next: 665

Since: 10-09-05

Since last post: 2 hours
Last activity: 2 hours
Posted on 10-14-05 07:54 AM Link | Quote
Nope.
Still only works on the right side of the block, works if I press left or right (should only be right+B), and ignores B completely.


(edited by Kailieann on 10-15-05 01:55 AM)
(edited by Kailieann on 10-15-05 01:56 AM)
BMF98567
BLACK HAS BUILT A SILLY DICE-MAZE!
GO!

Current list of BURNING FURY >8( recipients:
- Yiffy Kitten (x2)
- Xkeeper
Level: 53

Posts: 1201/1261
EXP: 1094149
For next: 62970

Since: 03-15-04
From: Blobaria
Special Move: Rising Meatloaf Backhand Combo

Since last post: 21 hours
Last activity: 1 hour
Posted on 10-14-05 04:15 PM Link | Quote
OK, first off, you need to know that SMW actually uses two RAM addresses for its button flags: $15 and $17 ($16 and $18 store the same flags, but for only one frame). $17 holds the status of the L, R, A, and X buttons on the SNES controller:



The problem with SMW is that, for some reason, it doesn't differentiate between A and B + A. B = 80 00, A = 80 80, and B + A = 80 80 (normally A = 00 80). Basically, this means that unless you require the player to press NOTHING but B + Right (LDA $15, XBA, LDA $17, REP #$20, CMP #$8100), both A and B are going to trigger it.

Anyway, if you don't mind either A or B triggering the code, then it should look like so:

A5 17 29 81 C9 81 D0 05 A9 63 8D BF 0D 60

LDA $17 ; load controller flags
AND #$81 ; isolate right and A/B flags
CMP #$81 ; are right and A/B both pressed?
BNE #$05 ; if not, branch to end
LDA #$63 ; load 99 coins
STA $0DBF ; store to coin counter
RTS ; end

(notice I eliminated the redundant RTS by branching to the end of the routine...not required, just good form)

That SHOULD work just fine. I don't know why it would only activate on the right side of the block...did you double-check your offsets in Block Tool? (Above, Below, and Sides should all be set to zero)
Kailieann

Koopa
Level: 11

Posts: 41/106
EXP: 5320
For next: 665

Since: 10-09-05

Since last post: 2 hours
Last activity: 2 hours
Posted on 10-14-05 06:19 PM Link | Quote
I did actually know about $17, but since it doesn't do anything when the d-pad or the B button is pressed, I ignored it and stuck with $15 (though I did know about the A/B thing, I just overlooked it).

Incidentally, as far as I can tell, $0DA2, $0DAA, $0DA4, and $0DAC also store controller input, though DA2 and DAA don't do the A/B thing. Maybe I should try using one of them instead.

As for Blocktool, I had Above and Below set to -1, because I only wanted it to work from the sides.

At any rate, the second one you provided seems to work (now I just have to figure out how to put in the actual code I wanted..), though I'm not sure I want the option of A being in there (I'll try one of the DAx offsets later).
The XBA one crashed the game for some reason.
It should be A5 15 EB A5 17 C2 20 CD 81 00 F0 05 A9 63 8D BF 0D 60, yes?
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 7698/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 10-14-05 06:29 PM Link | Quote
I'm pretty sure the game was designed to be as NES-like internally as possible. If you look at the controller map, the first byte is the same as an NES's would be, and then the second distinguishes between A/B or X/Y and tells whether L and/or R are pressed.

Those 0DAx addresses are certainly interesting. If that doesn't work, it may be necessary to hack the controller routine to store more detailed information elsewhere.
Kailieann

Koopa
Level: 11

Posts: 48/106
EXP: 5320
For next: 665

Since: 10-09-05

Since last post: 2 hours
Last activity: 2 hours
Posted on 10-15-05 10:49 AM Link | Quote
Okay. I've tried again, this time incrementing the coin counter so I can get a clearer picture of what's going on.

And, again, it doesn't work on the left side, and it completely ignores the B button.
But at least now I know it only works while I'm holding right.

What I have now is this:
AD xx xx 35 81 C5 81 ?? 07 AD BF 0D 1A 8D BF 0D 60

with xxxx being either 1500, A20D, or AA0D, and ?? being either D0 or F0 since I still can't keep my branch statements straight.

For reference:

LDA $xxxx ; Load one of the control addresses to the accumulator
AND #$81 ; Checks to see if Right+B is pressed
CMP #$81 ; Sets z-flag if Right+B is pressed
BNE/BEQ #$07 ; Skips the next 7 instructions
LDA $BF0D ; Load Coins to the accumulator
INC ; Increase accumulator by 1
STA $BF0D ; Store accumulator to Coins
RTS ; Exit

And blocktool offsets:
Below/Above/Sides: 0
Spr UD/SprLR/Cape/Fireball/Reloc: -1

Map16 Number 512 (0x200), behavior: 130

As far as I know, this should work. But it doesn't.
Can anyone see anything I'm missing? Can someone test to see if they get the same results?
And can someone please find out what the hell is making it not work from the left side of the blocks, because that is just mind-boggling.

I tried putting a cement block (130) above and to the right of the blocks in question, and for some reason nothing happens when I'm right up against it, either.
The only thing I can figure is that somehow block 130 (and all blocks that act like it) somehow block scripts when you're right against their left edge.

Which makes absolutely no sense, but then neither does anything else about this.


(edited by Kailieann on 10-15-05 01:49 AM)
(edited by Kailieann on 10-15-05 02:05 AM)
BMF98567
BLACK HAS BUILT A SILLY DICE-MAZE!
GO!

Current list of BURNING FURY >8( recipients:
- Yiffy Kitten (x2)
- Xkeeper
Level: 53

Posts: 1204/1261
EXP: 1094149
For next: 62970

Since: 03-15-04
From: Blobaria
Special Move: Rising Meatloaf Backhand Combo

Since last post: 21 hours
Last activity: 1 hour
Posted on 10-15-05 05:11 PM Link | Quote
Whoooooooa there...you're getting some of your opcodes mixed up. It's no wonder the code isn't working right.

First example:

A5 15 EB A5 17 C2 20 CD 81 00 F0 05 A9 63 8D BF 0D 60

The snippet of code I provided wasn't complete, it was just an example (I didn't think you'd actually use it ). C2 20 puts the accumulator (A) into 16-bit mode, so it can work with two bytes at once (it can hold two regardless of what mode it's in, but you have to use XBA to swap the high and low bytes). The problem here is that you're not setting it back to 8-bit mode afterwards, so the CPU reads the following opcodes wrong and eventually crashes. You need to stick an E2 20 (SEP #$20) after the CMP to fix this. Also, you've got the wrong CMP opcode there, and your operand is reversed (00 81, not 81 00; $17 is the low byte, and $15 is the high byte, due to the XBA byte swap). CD is "CMP Absolute," which compares A to the address specified in the operand. You want C9, "CMP Immediate," which compares A to the value in the operand. You should probably read up on the different addressing modes used in 6502/65c816 ASM (Absolute, Indirect, Implied, etc.) before you go much further.

You've also got the wrong conditional branch there. F0 (BEQ) will branch if A == #$8100--this means the code is skipped when the correct buttons are pressed! Change that to a D0 (BNE), so it branches if A != #$8100.

So, the proper code would be:

A5 15 EB A5 17 C2 20 C9 00 81 E2 20 D0 05 A9 63 8D BF 0D 60

Remember, though, this particular code will work ONLY if the player is pressing nothing but A/B + Right.

Second example:

AD xx xx 35 81 C5 81 ?? 07 AD BF 0D 1A 8D BF 0D 60

Again, you're using the wrong opcodes (right function, wrong addressing mode). 35 81 should be 29 81, and C5 81 should be C9 81. ?? 07 should be D0 07 (you want to branch if A is NOT equal to #$81). The corrected code:

AD xx xx 29 81 C9 81 D0 07 AD BF 0D 1A 8D BF 0D 60

Also, keep in mind that since you're reading the "button held" flags, the coin counter is going to increment once per frame as long as the buttons are held (but maybe that's what you want?).

Overall, you're doing awesome so far. Just read up on those addressing modes like I told you, and you'll be an ASM guru in no time.


(edited by BMF98567 on 10-15-05 08:22 AM)
Kailieann

Koopa
Level: 11

Posts: 50/106
EXP: 5320
For next: 665

Since: 10-09-05

Since last post: 2 hours
Last activity: 2 hours
Posted on 10-15-05 08:02 PM Link | Quote
It would be helpful if information about things like the addressing modes were in, say for example, one of the stickies. Or the help file from Glyph's sticky.

Then again, most of the stickies are so bogged down with extra posts that I can't get through most of them anyways.

It works now, though I assume you'd already guessed that. Clearly incrementing the coins every frame isn't what I had in mind (like I said, the coins were only to test the rest of the code), though I find it extremely interesting that doing so can make the coin counter go past 99 all the way up to P5. I guess the whole 1-up thing doesn't actually have anything to do with the number of coins you have.

-----

Okay, anyone know of a way to check and see if a button was just pressed, rather than being held?

I tried out the following script using 7E0016 to see if I could increment the coins every time down was pressed, but nothing happened.

AD 16 00 29 04 C9 04 D0 07 AD BF 0D 1A 8D BF 0D 60

LDA $1600 ; Load 1-frame control data to accumulator
AND #$04 ; Check to see if down is pressed
CMP #$04 ; Set z-flag if down is pressed
BNE #$07 ; Skip to end if z-flag is not set
LDA $BF0D ; Load coins to accumulator
INC ; Increase accumulator by 1
STA $BF0D ; Store accumulator to coins
RTS ; End

Thoughts, anyone?


(edited by Kailieann on 10-15-05 01:51 PM)
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 7745/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 10-16-05 02:59 AM Link | Quote
When you get a coin, the game checks if you have 100 and if so, gives you a 1up and sets the counter back to 0. I think calling $05B34A will give you a coin and handle the 1up stuff, but I've never tried it.
Add to favorites | "RSS" Feed | Next newer thread | Next older thread
Acmlm's Board - I2 Archive - Super Mario World hacking - Ran into another ASM wall | |


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 0.017 seconds.