Banner
Views: 236,284,809
Time: 2013-05-22 12:31:38 PM
15 users online: AlCaPwN, Daniel08, Darkdlp02, o Dotsarecool, LadiesMan_217, MaxodeX, o MVS, Pokeymeister80, Schieber1234, Sokobansolver, tgamer08, TheRobju, tylersuperwiigamer, WeegeeBen, WhiteYoshiEgg - Guests: 38 - Bots: 18Users: 22,858 (1,272 active)
Latest: FUNKY kong ending
Tip: The multiple midpoints patch can also be used to move a level's normal midpoint.
Official Hex/ASM/Etc. Help Thread
Forum Index - SMW Hacking - General SMW Hacking Help - ASM & Related Topics - Official Hex/ASM/Etc. Help Thread
Pages: « 1 ... 102 103 104 105 106 ... 319 320 »
That works perfectly! Thanks a lot, Kaijyuu!

EDIT: Another question... Is it possible to move the coin counter to a different place in the status bar just for one level? Well, of course it's possible, but how can I do that? Do I have to manually store the content of $0DBF to another place, or is there another way to do that?
Last edited on 2009-07-15 09:53:58 AM by WhiteYoshiEgg.
This is from the helpful diagrams topic in the data repository forum.



Through level asm, or a sprite or something, you can manipulate what the status bar shows on the fly. If you can determine what should be in the status bar, put it there through this. Ex:

Code
LDA #$FE ;Number for a blank tile STA $0F13 ;10s digit of coin counter overwritten





Now, for a question of my own. I want to look at what code the intro level (C5) uses that's unique to itself. Specifically, I want to know why message boxes on that level indiscriminately send you to the overworld. Not necessarily asking for an address to change for this, but how to find that address through a debugger or something.
Well, normally it's the "display level message #1" sprite that does it, I think, but the CTRL-F9 changes that somehow, you could maybe compare before and after maybe? Alternatively, it might be related to the "replace overworld loading with intro level" ram address.

Looking through Carol's sprites didn't help at finding how to make Mario enter a level, does anyone know anything at all that could help?
I'm having problems with this ASM, It's must redirect the standing still pose of Mario, works fine but It has a glitch, you collect coins but they will be not written in the coin counter, what's wrong?

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Custom standing still pose
; By: Maxx, Pseudonym, Azure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

lorom ;\ ROM is LoRom
header ;/ and has a header

org $8DC4 ;\ Hack NMI
JSL Code ;/ routine

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Definitions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

!Code_Location = $128000 ;| Location of the main code

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Main Code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org !Code_Location

Code:

LDA $7B
BNE Return
LDA $13E0
BNE Return
LDA #$03
STA $13E0
Return: RTL
Last edited on 2009-07-15 03:46:42 PM by Dual Performance.
I'm trying to make a block that activates an endless P-switch effect when touched. Where are the RAM values that handle blue and silver P-switch activation? I can't seem to find it.
Last edited on 2009-07-15 04:36:01 PM by Hailstorm.
You mean these?

Originally posted by RAM Map
$7E:14AD - Blue POW Timer
$7E:14AE - Silver POW Timer
Oh, those. So, I suppose there isn't anyway to get them to last endlessly...
You could make the block set an unused RAM adress and use LevelASM to set the pow timer to a certain number if the RAM adress is set. That way, it will last forever*.

*Forever = until you reset the RAM adress.
Originally posted by MrCheeze
Well, normally it's the "display level message #1" sprite that does it, I think, but the CTRL-F9 changes that somehow, you could maybe compare before and after maybe? Alternatively, it might be related to the "replace overworld loading with intro level" ram address.

Looking through Carol's sprites didn't help at finding how to make Mario enter a level, does anyone know anything at all that could help?

That sprite simply displays a message and resets a few ram addresses. It doesn't actually handle warping you to the overworld.

Any text box, be it from hitting a message box to talking to an NPC sprite will send you to the overworld. I want to stop this.


As for your question, this could help you possibly:
Originally posted by RAM map
7E:0EF7 1 byte Misc. If negative and Mario is on a level tile, Mario will enter it directly.

By "negative" I assume they mean it's a signed integer, and as such 80-FF would be negative.
It's possible to define addresses relatively, isn't it? What I mean is, if I did something like this:

FreeRAM = $7F8200

Address1 = FreeRAM+0
Address2 = FreeRAM+1
Address3 = FreeRAM+2
Address4 = FreeRAM+3 etc.

or even:

FreeRAM = $7F8200

Table1 = FreeRAM+0
Table2 = FreeRAM+12
Table3 = FreeRAM+24
Table4 = FreeRAM+36 etc.

then that would work, right? Address1 would be defined as $7F8200, Address2 as $7F8201, Address3 as $7F8202, etc., and Table1 would be defined as $7F8200, Table2 would be defined as $7F820C, Table3 as $7F8218, etc. Right?

If those are correct, then I have to ask two add-on questions:

1) Does this work with minus as well as plus? Could I, for example, start at $7F8227 and define Address1 as Address-0, Address2 as FreeRAM-1, etc.?

2) Do the numbers after the + (or -) have to be in decimal? Would +$C or +$0C work as well as +12?
Last edited on 2009-07-15 08:19:48 PM by imamelia.
I'm not sure if I understood exactly what you're asking, but if I did...

What you're describing is the very definition of a table.

With snes ASM, I've only ever seen them using the registers, like so:
Code
LDA RAM_ADDRESS,x

I don't think you can use arbitrary numbers like #$04 to determine it directly. So you'd probably have to push a register and use it like so:
Code
PHX LDX #$04 LDA RAM_ADDRESS,x PLX

That would loading the ram address + 4.

Now, if you want tables of tables that's beyond my expertise. I imagine it's possible though.

And for your last question, no you can't really use negative numbers as far as I know. I'm not sure why you'd want to anyway.
Dual Performance:
I can point out two problems. The main one is that you forgot to restore the hacked code which was replaced by the JSL. The JSL overwrote this part of code:

LDA #$02
STA $420B

You must put it back in your own custom code, I'd say at the beginning.

Secondly, put a NOP after the JSL Code because the code you're hijacking is 5 bytes where as a JSL is 4 bytes, so we need to get rid of that extra byte by NOP'ing it out.

@Hailstorm: There isn't unless you use a loop ;)

LDA $14AD
CMP #$80
BNE Max
RTL
Max:
LDA #$FF
STA $14AD
RTL

I tested this and it works. There is no limit on the (blue) POW timer.
Last edited on 2009-07-15 11:31:15 PM by Nesquik Bunny.
Originally posted by imamelia
It's possible to define addresses relatively, isn't it? What I mean is, if I did something like this:

FreeRAM = $7F8200

Address1 = FreeRAM+0
Address2 = FreeRAM+1
Address3 = FreeRAM+2
Address4 = FreeRAM+3 etc.


Yes, this is possible if your assembler knows how to add numbers like this. I know not whether "Address1 = FreeRAM+3" is valid in any assembler, but I have used plus + in both wla-65816 and xkas v0.12.

Originally posted by Kaijyuu
I'm not sure if I understood exactly what you're asking, but if I did... I don't think you can use arbitrary numbers like #$04 to determine it directly. So you'd probably have to push a register and use it like so:
Code
PHX LDX #$04 LDA RAM_ADDRESS,x PLX

That would loading the ram address + 4.


Kaijyuu programmed the SNES to calculate RAM_ADDRESS + 4. I guess that imamelia wants the assembler to calculate RAM_ADDRESS + 4, and insert the sum into the machine code, so that the SNES does not need to do the calculation or use the X register.

When my assembler was wla-65816, I defined two direct-page locations called <header_buffer and <header_pathname. Each location holds a 24-bit long address. So I loaded the bank bytes to <header_buffer + 2 and to <header_pathname + 2:

Code
;; This code uses 16-bit accumulator. ;; Store 24-bit address of label cpio to <header_buffer. ;; Store 24-bit address of label result_name to <header_pathname. ;; lda #cpio ;; load 16-bit cpio sta <header_buffer ;; store it lda #result_name ;; load 16-bit result_name sta <header_pathname ;; store it sep #$20 ;; 8-bit accumulator lda #:cpio ;; load bank of cpio sta <header_buffer + 2 ;; store it lda #:result_name ;; load bank of result_name sta <header_pathname + 2 ;; store it rep #$20 ;; 16-bit accumulator


When my assembler was xkas v0.12, I defined a location called RAM_Lstate that holds eight bytes. To zero the bytes, I used addition:

Code
define RAM_Lstate "$7fa002" // 8 bytes // already have 16-bit A lda.w #0 sta.l {RAM_Lstate} // set state to zero sta.l {RAM_Lstate} + 2 sta.l {RAM_Lstate} + 4 sta.l {RAM_Lstate} + 6


I know that xkas v0.06 can do addition, but only in certain places, and there must be no spaces around the plus sign. I know not whether snescom can do addition.

Originally posted by imamelia
1) Does this work with minus as well as plus? Could I, for example, start at $7F8227 and define Address1 as Address-0, Address2 as FreeRAM-1, etc.?

2) Do the numbers after the + (or -) have to be in decimal? Would +$C or +$0C work as well as +12?


Yes, the assemblers that do + plus can also do - minus. Also, $C or $0C would probably work, if the assembler uses $ for hexadecimal; assemblers tend to allow both decimal and hexadecimal. If the assembler uses % for binary, then %1100 or %00001100 would also work.
Well, this is my very first attempt at ASM... and as expected it went kapoosh.
LDA $19
BEQ MoveMario
LDA $19
CMP #$01
BEQ MoveMarioSlow
LDA $19
CMP #$02
BEQ MoveMarioSlower
LDA $19
CMP #$03
BEQ MoveMarioSlowest
RTS
MoveMario:
LDA $7E
CLC
ADC #$08
STA $7E
RTS
MoveMarioSlow:
LDA $7E
CLC
ADC #$04
STA $7E
RTS
MoveMarioSlower:
LDA $7E
CLC
ADC #$03
STA $7E
RTS
MoveMarioSlowest:
LDA $7E
CLC
ADC #$02
STA $7E
RTS

It's supposed to move Mario fast if he's small, but slower if he's big/has powerup. Can someone tell me what's wrong and how to fix /improve it?
Apparently, you're modifying RAM address $7E, not $7B. $7B is horizontal movement and $7D is vertical movement. Also, That code would work every frame Mario touches it, and that makes the speed rise a lot more than you'd expect... What is the version of blocktool you're using? If You use Blocktool Deluxe, you need to define the offesets in the asm file (refer to Custom Blocks for examples of that) and use RTLs instead of RTS. What are the offsets of your block? That might have something to do with it.
Last edited on 2009-07-16 07:16:27 PM by scepile.
I would like to take an existing (custom) sprite and increase the number of hits it takes to kill it (essentially making an incredibly simple custom boss)

How would I go about doing this?

(This is my first venture into the magical world of ASM)
Last edited on 2009-07-16 07:47:43 PM by NamelessProtagonist.
Asterisk, that's not bad for your first try at ASM. But there are a few ways you can optimise your code and there's also a bug:

When you're comparing a RAM Address with a bunch of values, you don't need to load them again.

LDA $19
BEQ MoveMario
LDA $19 ; irrelevant
CMP #$01
BEQ MoveMarioSlow

Can be

LDA $19
BEQ MoveMario
CMP #$01
BEQ MoveMarioSlow

Secondly, rather than just adding each value separately, you can use a table:

LDY $19 ; powerup -> Y
LDA $7B ; if going
BPL Left ; left ..
CLC
ADC Spd,y ; add speed
BRA StoreSpd

Left:
SEC ; subtract
SBC Spd,y
StoreSpd:
STA $7B
RTS

Spd:
db $00,$01,$02,$02
; 00 01 02 03 ($19)

When going left, the speed is negative (#$80-#$FF) and #$80 is the fastest. That's why you need to subtract the values instead of adding them when going left.

@NamelessProtagonist:
It isn't really a good idea to start modding sprites when you just started learning ASM. I suggest you start off by creating simple blocks and then move onto sprites/patches when you feel you can easily make them. But anyway, here is what you need to do:

In the INIT routine of the sprite, you set a specific # of hitpoints to any unused sprite misc. address in the sprite.

Check for Mario upward contact (if you can jump on the sprite, that is), and if it's positive, decrement that sprite misc. address by 1 (or by how much health you want it to lose per hit). Once that address is zero, kill the sprite.


Nevermind, Kaijyuu posted a much better and detailed explanation below.
Last edited on 2009-07-17 12:34:07 AM by Nesquik Bunny.
@Nameless

If you want to learn ASM starting with coding sprites, I really don't suggest you start by modifying existing ones. There's a lot of code in them you likely won't understand unless it's heavily commented, and that can cause unnecessary headache.
I'd start with sprite tool's tutorials and work your way up to a working sprite.

Nevertheless, to answer your question:
Depends what kind of sprite it is. If it's something real simple that dies in one hit (like a shelless koopa), the easiest way to do so would be to cheak if it's dead at the end of it's routine, and bring it back to life if it's hitpoints (which you have newly defined) are not at 0.
Note that this would be significantly harder with something that already takes multiple hits to kill (such as a Rex) or acts weird when hit (such as a SMW goomba).

First off, let's make a new subroutine to keep things organized.
Code
START_SPRITE_CODE JSR SUB_GFX ; draw sprite gfx JSR MY_NEW_SUBROUTINE ; this is where we jump to our new routine to determine hit points. Name it whatever you like LDA $14C8,x ; \ if sprite status != 8... CMP #$08 ; } ... not (killed with spin jump [4] or star[2]) BNE RETURN ; / ... return LDA $9D ; \ if sprites locked... BNE RETURN ; / ... return

You'll see something like this in most sprites. You need to put "JSR MY_NEW_SUBROUTINE" before the lines of code shown below it here.
JSR = Jump To Subroutine. This is a command to make the game read code from any arbitrary point in your sprite's asm file, and in fact the game.


Now, somewhere where there's blank space in your sprite's asm file you'll want to put this:
Code
MY_NEW_SUBROUTINE ;this is the label you typed before for your subroutine's name LDA $14C8,x ;Loads your sprite's status value to the accumulator (A) CMP #$02 ;Compares it to a possible state. #$02 is the falling off screen type of killed, like something getting hit with a shell BEQ IS_HIT ; Branches if equal. Branch = go to. Unlike a JSR, this means we jump to another piece of code and don't come back unless we use another Branch command. Branches have a limited range of 128 bytes of code (I think...), while JSR has unlimited range. LDA $14C8,x ; #$03 = Squished. Also, the ",x" you see is how we reference a sprite's data. x is a variable. We're adding x to 14C8 to determine which byte of ram stores this particular sprite's data. CMP #$03 BEQ IS_HIT LDA $14C8,x CMP #$04 ; #$04 = Spinjumped. BEQ IS_HIT RTS ; ReTurn from Subroutine. Makes us leave this subroutine and go back to where we initially came from IS_HIT ;This is the label we go to if one of the previous conditions is true LDA #$08 ; #$08 is the sprite's state for "normal." STA $14C8,x ; STA = STore A. This writes whatever is in A to the piece of ram that holds the sprite's state RTS ; Return to subroutine

Your sprite is now immortal from normal death. (There's a couple more death states... check here: http://www.smwcentral.net/?p=thread&id=11960. Search for sprite status table near the end of the first post)
But what about hit points?

Near the top of the screen you'll see a routine with the first line being "dcb INIT". This is the initialization routine that runs only once on sprite creation.
NOTE: For the purposes of compatibility, I'm going to show you a method to store hitpoints that only allows 1 sprite of this type to be on the screen at once. I do not know if the custom sprite you're editing uses one of the misc sprite tables.

First, find an empty spot of RAM in the ram map. One off the top of my head: $7EC202

In the initialization routine, do this:

Code
dcb "INIT" ;Other pieces of code may be here. Do not edit LDA #$03 ;Your sprite's total hitpoints. Place whatever you like STA $7EC202 RTL ; RTL is like RTS, but they cannot be used interchangably. Explaining it is beyond the scope of this, so look it up if you're interested

Great. Now we have a piece of ram storing your sprite's hitpoints. But it's not used yet!

Go back to your custom routine.
Code
IS_HIT ;This is the label we go to if one of the previous conditions is true LDA $7EC202 ; Load your sprite's hitpoints CMP #$00 ; Compare them to 0 BEQ DEATH ; If equal, it is dead! LDA $7EC202 ; Let's decrement the total hitpoints if it's not 0 yet CLC ; "clear carry" The carry flag is part of the accumulator (A). This is to avoid possible bugs. Don't worry too much about it. SBC #$01 ; "SuBtract from Carry" This subtracts the number from A. STA $7EC202 ; Store the new hitpoint number to the RAM LDA #$08 ; #$08 is the sprite's state for "normal." STA $14C8,x ; STA = STore A. This writes whatever is in A to the piece of ram that holds the sprite's state DEATH ; Branches here if it's dead, skipping the lines of code that revive it RTS ; Return to subroutin


Ta-da. Done.
Last edited on 2009-07-16 11:47:46 PM by Kaijyuu.
Wow... this is quite a bit more difficult than I thought it would be... even so, I'm not giving up yet...

The sprite I'm trying to edit is the Giant Goomba one. I'm trying to make the Red Goomba and Blue Goomba from Paper Mario... The Blue one would take two hits to kill and the red one three. They would be fought together (I suppose I would have to use different empty RAM addresses for each one...)

Somehow Mario passes right through the sprite, takes damage, and nothing happens to it.

Also, if I throw a shell at him it hits him several times, giving a couple extra lives, but not killing it.

I think I'm going to restart... probably going to try to read some of the original code first incase something there conflicts with what I added...

Edit: Well, I redid it and this time he still dies in one hit for some reason, and the thing that happened when I toss a shell at it still happens. Still playing around with it...
Last edited on 2009-07-17 08:32:32 AM by NamelessProtagonist.
Upload your .asm on the file bin and I'll look at it.
Last edited on 2009-07-17 09:41:13 AM by Kaijyuu.
Pages: « 1 ... 102 103 104 105 106 ... 319 320 »
Forum Index - SMW Hacking - General SMW Hacking Help - ASM & Related Topics - Official Hex/ASM/Etc. Help Thread

The purpose of this site is not to distribute copyrighted material, but to honor one of our favourite games.

Copyright © 2005 - 2013 - SMW Central
Legal Information - Link To Us


Total queries: 27

Menu