Language…
11 users online:  AmperSam, Dan2point5, fsvgm777, Gasterus155, JPhanto, kirsvantas, nonamelol1, reevebarusadar8, signature_steve, Sokobansolver, tOaO - Guests: 248 - Bots: 320
Users: 64,795 (2,377 active)
Latest user: mathew

Official Hex/ASM/Etc. Help Thread

  • Pages:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 418
  • 419
  • 420


Code
	LDA $15					
	AND #$01				
	BEQ Label_0000

This branches if bit 0 is set to 0, i.e. the button is not pressed. You want a BNE instead.

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
Thanks that worked.
What can I do to make a block "kill itself" after interacting with mario?
By killing itself I mean, to completely deactivate, stop working, do not interact again.

For you to get a clearer message of what I want: I have this one block that activates the One Shot trigger for ExAnimation. The problem is, it will loop the animation if I interact with the block again, and I want it to only animate once.

Here's the block:

Code
;This Block will activate a custom one shot trigger.
;Change the !Number defined below.
;Act Like whatever you want
;-----------------------
;by JackTheSpades

!Number = 0	;which trigger to use. Valid numbers are 0-1F

print "Enables the one shot trigger !Number "

db $42
JMP Code : JMP Code : JMP Code : JMP Skip : JMP Skip : JMP Skip : JMP Skip
JMP Code : JMP Code : JMP Code

!Add #= ($!Number&$18)>>$3
!Number #= $!Number-($!Number&$18)

Code:
	LDA $7FC0F8+!Add
	ORA #$01<<$!Number
	STA $7FC0F8+!Add
Skip:
	RTL


I thought of adding the code routine from Blockreator that changes the current block into another one, but I don't know where to place the code, or if it's okay to do that.
Yes you can use the change block routine. Just place it anywhere after Code and before skip.

Code
;prev code
Code:	LDA $7FC0F8+!Add
	ORA #$01<<$!Number
	STA $7FC0F8+!Add
	; here for example
Skip:	RTL


Note however that this only affects the current block. If you have more than one block as your trigger and want to trigger the whole thing only once even when touching other blocks then a better option would be to use a freeram flag:

Code
;prev code
!somefreeram = $60
Code:	LDA !somefreeram
	BNE Skip
	INC !somefreeram
	LDA $7FC0F8+!Add
	ORA #$01<<$!Number
	STA $7FC0F8+!Add
Skip:	RTL

this would only trigger the animation once then not again until you reenter the room (Or set !somefreeram to 0 some other way) even when touching other blocks that may trigger the same animation. If you want it on a per-block basis changing the block itself is the better option though
The freeram trick seems to work better for me! I'm using a barrier of blocks as a checkpoint to trigger the animation, so using the "kill block" routine didn't work as intended.

Thank you once again, Biob. #smw{T_T}
The other day I tried to make a perfect 48x32 sized SMB1 Bowser through copy-pasting code, and I was wondering of someone could help me fix the code involving it's tilemap mostly because I somehow managed to almost get it work:


(please ignore the deliberately glitched graphics)

When it's looking right, the tilemap is flipped incorrectly for some reason.



Also (not sure if this issue one is actually worth fixing), when it's throwing hammers, the hammer tile that shows on the original 32X32 sprite's back doesn't appear anymore. It also spawns them in a slighly different position when looking right (closer to the middle).

Here's the asm file for those interested.


THe tilemap issue is probably related to how you wrote your graphics routine. I assume you wrote your code so it assembles like this:

A B
C D

with X/Y offsets moving the tiles around. But when the boss is facing right, you probably still have the tiles assembled like that, instead of actually flipping the assembly to this:

B A
D C

So you end up with the individual tiles flipped but not the boss as a whole.


For the other issue, I'm not quite sure what you mean. The position thing at least sounds like just be an offset thing (you'll want to shift the spawn position of the hammers based on the sprite's direction).

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
Originally posted by Thomas
THe tilemap issue is probably related to how you wrote your graphics routine. I assume you wrote your code so it assembles like this:

A B
C D

with X/Y offsets moving the tiles around. But when the boss is facing right, you probably still have the tiles assembled like that, instead of actually flipping the assembly to this:

B A
D C

So you end up with the individual tiles flipped but not the boss as a whole.


For the other issue, I'm not quite sure what you mean. The position thing at least sounds like just be an offset thing (you'll want to shift the spawn position of the hammers based on the sprite's direction).


Just tried flipping the offsets for when it's facing right and now it works like a charm. It also happened to fix that other issue I had with the "spawn-other-sprite location", so...thanks!

The weird thing is, though, that the whole "hammer not appearing on bowser's back before throwing it" issue seems to come from this part of the code:

Code
                    PLX                     ; pull, X = sprite index             
                    LDY #$02                ; \ 02, because we didn't write to 460 yet
                    LDA #$05                ;  | A = number of tiles drawn - 1
                    JSL $01B7B3             ; / don't draw if offscreen
                    RTS                     ; return


It's used thrice; for the 48x32 Bowser, for when there's no hammer and for when the 16x16 hammer tile is meant to show, and for some reason the former seems to negate the latters when they're all present. Don't really mind that's the case to be honest(I'm happy the thing finally works properly now), but it's a shame I'll have to find a way to remove the routine without messing with the sprite. (and also that bowser has code that's filling space for no reason, I guess)


If you're running $01B7B3 multiple times in the same frame, then yeah, they'll probably overwrite each other. That routine pulls the OAM slot directly from $15EA, rather than whatever you were using the in code at the time, so calling it twice just overwrites the first call's tiles.

There's two ways you could handle this. One way is to optimize the code down to only a single call, with scratch RAM or a branch to determine the value for A. The other way would be to directly modify $15EA between calls (which you can safely do since it gets reset at the start of each frame).

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
Originally posted by Thomas
There's two ways you could handle this. One way is to optimize the code down to only a single call, with scratch RAM or a branch to determine the value for A. The other way would be to directly modify $15EA between calls (which you can safely do since it gets reset at the start of each frame).


I tried doing the first thing (at least I think that's what I did) and the tile started showing as it was meant to to. If it wasn't for one last detail, the sprite would be ready to go:



When moving the camera offscreen, the hammer tile also spawns at the other extreme for some seconds. If the code's commentary is anything to go by, it's already supossed to prevent that sort of thing of happening, which is really confusing me.

Here's the last version of the sprite. As long as you have LR scrolling, you shouldn't have any problems with it.
Okay I have a really dumb issue (again) and I can't seem to figure it out.

I want a levelasm code that will nuke ABXY. Simple to do right?

Code
$7E0015		1 byte		I/O
	
Controller data 1. Format: byetUDLR.
b = A or B; y = X or Y; e = select; t = Start; U = up; D = down; L = left, R = right.

I was trying to do this on my own, but I'm unable to.

I'm assuming byetUDLR must be converted from BIN to HEX (with byet changed to 0011) then stored in $15? Something like this:

Code
LDA #$3F	;0011 1111 = 3F
STA $15 

I inserted the above code as a block, the result is, when I'm above the block Mario is constantly pressing Down. The ABXY is still working.

The above was just a example to show you what I was doing, I'm aware that my idea of how the byetUDLR works is completely wrong. Can someone patiently explain to me how would this work?


--
As of the typing of this post I realized I shouldn't store anything to that address because it will work as if I gave that certain command to the I/O. Meaning, even if I get the right value to set ABXY as idle, it'd still work if I pressed them.
You can use TRB (test and reset bits) to disable certain buttons.

For example:
Code
LDA #%00001111 ; Load controller bits that should be disabled
TRB $15 ; Set these bits to 0


This would reset all the lower bits of $15 (UDLR) essentially disabling the buttons.

In case of disabling ABXY you'd want to load #%11000000 (Or #$C0) and then use TRB on $15 (And possibly $16,$17,$18 as well)

Code
LDA #%11000000 ; or #$C0
TRB $15 ; Disable currently held buttons
TRB $16 ; Disable first frame buttons
TRB $17 ; Disable A/X currently held buttons
TRB $18 ; Disable A/X first frame buttons


That address refers to what buttons are currently being pressed. A bit being 0 means the button is not pressed, while 1 means it is.

In order to force a button to always be in its 'not pressed' state, you would do something like this:

Code
LDA $15
AND #$3F	;[by]etUDLR
STA $15

If you're not super familiar with the AND opcode, it performs a bitwise AND:

Code
in : %xxxx xxxx
AND: %0011 1111  ; #$3F
out: %00xx xxxx



You'll probably also want to do the same for $16-$18, too. In that case, there's actually a faster way to do it:

Code
LDA #$C0
TRB $15
TRB $16
TRB $17
TRB $18

TRB is an interesting command that clears bits in an address using the value in A. So with that code, A has %11000000, so TRB will clear the highest two bits of the given address.

As an alternative, you could use TSB (which sets bits) on $0DAA-$0DAD.

e: dang

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
Okay, that seems to work just fine!Thank you, both. <3

I have a few questions on how this works though.

Originally posted by 65c816 Instructions
TRB - Test and Reset Bit

Tests the bit similarly to “AND”, and clears it, while affecting the flags.

So basically, the code tells the "by" to go back to zero (or its original state?) when it's checked as C0 (aka when pressing ABXY)?
Similarly to CMPing it then STZing maybe?


Could the same Opcode be used as, for example, if I wanted mario to stay small when eating a mushroom: LDA #$01 TRB $19 ?
It seems to work that way, besides the "growing" animation still playing. Is there a better way to approach that kind of operation, or is this the correct way?

Sorry for the silly questions, I just felt like asking since we're already here. Also, some things are easier to understand when explained directly, instead of reading in a compiled tutorial
Yes, when using TRB all bits currently set in A will be set to 0 in the address specified by the TRB (TRB $15)
All other bits will be left unchanged.

Quote
Could the same Opcode be used as, for example, if I wanted mario to stay small when eating a mushroom: LDA #$01 TRB $19

Not quite. This only works with mushroom and cape because of how it's set up:

00 (00000000) means no powerup
01 (00000001) means mushroom
02 (00000010) means cape
03 (00000011) means flower

Since doing [LDA #$01 : TRB $19] would always set bit 0 to 0, 00 becomes 00, 01 becomes 00, 02 becomes 02 but 03 becomes 02 because when the lowest bit of 03 (00000011) is set to 0 it becomes 00000010 which is 02
I tried making a sprite that teleports the player to a certain level when they get a score of at least 12000.

Code

Must've done something wrong because nothing happens once I get over 12000 points. Could someone point me in the right direction?
Are you sure, you mean by 12000 points the value in the status bar (if you haven't removed the right most zero from the status bar, that's it) or the absolute value (i.e. value on the status bar divided by 10)?
If the former than you have to change #$2EE0 to #$02EE #$04B0 (0x02EE is 750 in dec) (there also is the highest byte but since the score clears out and it is very unlikely to get more than 655350 points in a single level, doing that isn't required).
Got it to work per your suggestion, thanks.
Not really an ASM question, but I'm not sure where else to ask this.

What memory address does Lunar Magic 2.40+ use for its 8 additional overworld events? They won't fit in the table at $1F02 with SMW's usual event flags, so I'm guessing it's using some supposedly free RAM?

–=–=–=–=–=–=–
Advynia: a Yoshi's Island editor - Alyssa's Unlikely Trap demo 3


Not sure what you mean, since there's enough room in that table for all of the events. I only see up to event 0x77 in LM, and 15 * 8 = 120 = 0x78.

Professional frame-by-frame time wizard. YouTube - Twitter - SMW Glitch List - SMW Randomizer
  • Pages:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 418
  • 419
  • 420