Omnimaga

Calculator Community => Major Community Projects => Super Smash Bros. Open => Topic started by: Hayleia on September 30, 2014, 12:05:44 pm

Title: [Asm]How To make your own character
Post by: Hayleia on September 30, 2014, 12:05:44 pm
(Still in the works. You can start making your character but nothing guarantees that you'll never need to come back to what you've already written. Spriting doesn't have this kind of risk though. If you are really in an urge to make a character and can't wait for this to be done, you can also have a glance at Fox/Falco's source.)


Random Notes

I have no idea if Spasm can compile into appvars instead of compiling into programs so I actually compile as programs then convert into appvars. That's why I'll say "program" and "appvar" everywhere without distinction.

The Asm tutorial will probably take more time to write than the Axe tutorial since I have a character "done" in Axe but have yet to provide examples in Asm. At worst, read the Asm tutorial, then read the Axe tutorial, notice where the difference are, they are not many really (there's nothing high level in making characters and I don't even think there's anything high level in Axe anyway).


Notes to make your life easier

You can include the smashh.inc into your program. It only includes definitions, not code nor data so you can include it wherever you want in your program.
This will not only be a lot more readable for you to write "AirNull" than to write "%00000011" but this will also allow some specification changes (I hope that will never happen but we never know) because if you wrote "AirNull" everywhere, just change the include and the AirNull constant is changed everywhere while if you wrote "%00000011", you'll have to change them all "by hand".

I'd also advise you to use your own macros, like "#define Gravity 38" so that you can quickly change a constant everywhere in your program.


How do characters work, without details (you'll have details below)

Basically, they work with states. When your character is standing, doing nothing, it's in a state that we can call the "Standing state". It will leave this state when you press Jump for example, to go to the "Jumping state". Another example is the "Dashing State", that repeats itself (not entirely true) until you stop pressing the arrow key you pressed to start this state, or when you press Jump, etc.


The Header

This is necessary to have the game list your character and not list random appvars that don't have the right header.

The header starts with a one byte number, which for now is 1. This is actually not used for now, but in case specification changes happen (which I still hope will never happen), you'll have to put 2 here then 3, etc so that the program knows which specification your character is following.

You then need to put "SSBOCHAR",0. This is what the program uses to check if the appvar is a SSBO character or not.

The following two bytes are the size of the program.

Then, you put a 16x14 icon for the character selection menu (28 bytes).

You finish the header with the name of your character, obviously null-terminated.

For example if you are making Falco, here's what it should look like for now.
Code: [Select]
.org 0

.db 1
.db "SSBOCHAR",0
.dw HeaderEnd
.db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.db "Falco",0

HeaderEnd:


General Information

After the header, you need to put information about your character that SSBO will needs to get quick access to. In that order:
1 byte: gravity (not used anymore, can be recycled for something else)
1 byte: air speed
1 byte: traction
1 byte: max number of jumps (2 in general, 5 for Jigglypuff)
2 bytes: max horizontal speed (not used yet)

Then follow the adresses of states that the program will need to have quick access to. A counter example is the second frame of the Down Aerial. You only access that one after the first frame. That first frame however needs to be quickly accessed to when the player asks for a Down Aerial.
All of those adresses take two bytes.
Since for now you have not written any state and have the adress of none, just put the adress of the standing state everywhere, you'll change that as you go along.

Anyway, in that order:
Standing, Airing, Dashing, GroundJump, AirJump, Landing
AirNeutralSpecial, AirSideSpecial, AirDownSpecial, AirUpSpecial
GroundNeutralSpecial, GroundSideSpecial, GroundDownSpecial, GroundUpSpecial
DashAttack
SideSmash, DownSmash, UpSmash
NeutralAir, ForwardAir, BackAir, DownAir, UpAir
LedgeGrabbed

Just a little precision. Axe compiles program "in" the RAM area it will be executed. For Asm users, I mean there is no way to say .org 0. However, state adresses need to be the ones related to the beginning of the data, not absolute ones assuming the program will be located at a precise location. This is why you'll have to put a "[]→°DB" right after the header and a "-°DB" after all your adresses.
Luckily for you, you're in the Asm tutorial so we'll use .org 0. Notice that we need another label at the very end of the data that we will add to HeaderEnd in the "size of data" field in the header.

So this is what you have for now:
Code: [Select]
#define FalcoGravity 38

.org 0

.db 1
.db "SSBOCHAR",0
.dw HeaderEnd+DataEnd
.db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.db "Falco",0

HeaderEnd:

.org 0

;INFO ----------------------------

.db FalcoGravity
.db 5
.db 20
.db 2
.dw 255

.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand
.dw Stand

Stand:
;nothing here for now

DataEnd:

## dont forget that the DataEnd must be the last line of your program, it's not because you wrote it at a previous step that what you add at the next step must be written after it