News:

Don't forget to visit the main site! There's lots of helpful docs, patches, and more!

Main Menu

HYPER METROID project help

Started by Vener, January 30, 2011, 03:28:20 PM

Previous topic - Next topic

Quietus

The bytes are just single bits of information that can be manipulated using the ASM.  The instructions are the single words that are used to create the routines and subroutines.  Things like LDA, STA, RTS are all instructions, as they're telling the program what to do.  I'll await one of the gurus elaborating or clarifying. :O_o:

Vener

#101
Hexadecimal is just a conversion of ASM like ASM is a conversion of Hex , each bytes or groupe of bytes are the equivalence of Asm commandes , but ASM commandes use several processors . it's a variable language , soft but ugly ... Also , ASM , like every languages equal binary . if Binary tell that it's 1 , the resistor assigned is opened , electricity pass , if it's 0 , resistor is closed , and the ASM comandes are additions ,soustractions,multiplications and divisions of hex values between 0 and 256 or 0 and 65535 , etc .. translated per several 0 or/and 1 .

I ask just how the Metroid ROM work , because , if you compare the Megaman X ROM or the Secret of mana ROM (for exemple), there are a world between they , about the structure . Each ASM codage is unique , you can know everything of the Super metroid ASM scriptes functionement , and nothing when you try to hack ASM from another ROM .

Crashtour99

Quote from: Vener on July 05, 2011, 03:30:34 PM
Okey , thanks  :wink:
Now , that's clear enough .
Also , about the ROM , i see special codes at the beginning of ~ each banks , those codes are used for determine how the banks work ? Hum , i mean , each banks have an own functioning , have their own values for determine what mean what , Or the functioning is "universal" , the same for each banks ? Exemple , a check for physical modifications need to be write obviously in the physical bank , or he can be write everywhere ? Finally , a pointage (of 2 or 3 bytes) can be called also an instruction , or pointages are just pointages ?   

Probably what you're seeing at the beginning of each bank are general use routines.  Most of them have the same structure between banks, and are probably used via a pointer table somewhere else in that bank.  If you have several banks using the same routine but at varying times, it's just easier to use a pointer table to carry you over to that routine so you don't have to have copies of it in several places in the ROM.

Yes, the functioning of all banks is universal.  However several banks are set up for special usage.  Like in SM, banks $90 and $91 are mainly for physics, bank $84 is all the PLMs, etc.  They all function the same, but some are set up for special uses.  Technically, you could put some new physics coding in another bank that has freespace as long as you jump to it properly.  The routines that handle PLMs however are set up to only read/execute from a specific bank, so unless you modified those routines having PLMs in multiple banks is out of the question.

About pointers, they are not instructions.  Typically when you find pointers they will be in a table.  You might see something like:
LDA #$(table location), Y     or
JSR $(table location), X
What these would do, is grab the pointer from the table (based on the indexed value) and execute the code accordingly.  For an LDA, it would simply load that value to the accumulator.  For a JSR it would jump to the subroutine pointed to.  Pointer tables are usually used to make the coding more versatile and simplify things, usually to load specific values or jump to locations.

:about your later post:
Each ROM has a unique game engine, unique compression methods (for graphics, tilemaps, etc.) and lots of unique coding, some of it based on slight changes in hardware.  However the ASM language used for each is exactly the same.  Thus when you learn about how ASM works for Super Metroid, you aren't so much learning a specific type of assembly, but are instead learning how Super Metroid's game engine and coding structure works.

ASM is excruciatingly precise, and it will never do anything you didn't tell it to.  It is quite variable, but also detail oriented, so missing something tiny but important can screw the whole thing up.

Vener

Quote from: Crashtour99 on July 05, 2011, 10:33:14 PM
About pointers, they are not instructions.  Typically when you find pointers they will be in a table.  You might see something like:
LDA #$(table location), Y     or
JSR $(table location), X
What these would do, is grab the pointer from the table (based on the indexed value) and execute the code accordingly.  For an LDA, it would simply load that value to the accumulator.  For a JSR it would jump to the subroutine pointed to.  Pointer tables are usually used to make the coding more versatile and simplify things, usually to load specific values or jump to locations.

Then , if for exemple , i decide to create a new PLM (pre-PLM instruction & main PLM instruction). If i pointe the pre-plm instruction in the free space , it's an LDA , and if i pointe an already existing main PLM instruction for my main PLM instruction , it's an JSR ?

Crashtour99

Not necessarily.  It depends entirely on what instruction is calling the value from the table.

Any time you see a positive value (number between 0000 and 7FFF) it will always be loaded to somewhere, usually used as a delay counter or x/y axis adjustment (or something similar).
When you see a negative value (number between 8000 and FFFF) it is usually a location of code.  These can be manipulated by a number of instructions.
With space pirate AI, the location of the next code to run is always loaded into Y first, then jumped to later.  If you read through the routine, you'll be able to tell when it's getting a value from the table, and what it's doing once it has that value.
I've noticed that Super Metroid has a tendency to use multiple layers of tables, with pointers that are run sequentially.  So you might follow a pointer, just to have it lead you to another pointer, and you follow that one and perhaps find a routine (or you might find a few more layers of pointers to follow).

*I know how this works in my head, I'm just not sure if I'm communicating the idea properly.  lol*

Vener

#105
Thanks for explanations :wink:
I have already "learned" the ASM lessons from Sadyztik and Black Falcon ; but now , it's more simple to understand .
Very more !

Quote from: Crashtour99 on July 06, 2011, 05:42:25 PM
I've noticed that Super Metroid has a tendency to use multiple layers of tables, with pointers that are run sequentially.  So you might follow a pointer, just to have it lead you to another pointer, and you follow that one and perhaps find a routine (or you might find a few more layers of pointers to follow).

Yes , you are right  :grin:
That's an ingenious ROM codage , very elaborated , very optimized .


Vener

I have still some interrogations about ASM ... :S

- What is the difference between "Accumulator" and "Memory" ?
- What is "Increment" and "Decrement" ?
- What is "X" and "Y" registers ?
- What is "Branch" ?
and , what is 'Opcodes" ?

Quietus

I can help you with the easy one. :razz:

'Increment' means to get bigger in size / amount, usually in steps, and usually by a fixed amount.
'Decrement' means the same thing, but getting smaller in size / amount.

DSO

#108
Quote from: Vener on July 08, 2011, 03:11:33 PM
I have still some interrogations about ASM ... :S

- What is the difference between "Accumulator" and "Memory" ?
- What is "Increment" and "Decrement" ?
- What is "X" and "Y" registers ?
- What is "Branch" ?
and , what is 'Opcodes" ?


The accumulator, like X and Y, is a register you use to carry out math operations. They're the way you interact with RAM, or memory.
For example, Samus health is in memory at $09C2. Say you want to write code to deal 10 damage to Samus. To do this, you must load $09C2 into the accumulator (or another register, such as X or Y), and then you can perform subtraction on the accumulator, then you must store the new value back to $09C2 or else it will not be affected.
LDA $09C2 //Load Accumulator with value at $09C2
SEC
SBC #$000A //Subtract 10 from value in A
STA $09C2 //Store new value in A back to $09C2

Increment and Decrement are sort of an exception, though they don't have to be. Increment adds 1 to a value, and decrement takes one away. In this case, you can INC and DEC RAM without having to load it to a register, but you can also INC A or other registers.

Branches are how the game goes down different paths. The game has a lot of processor flags that determine how branches will act, and a lot of compare codes to determine what branches are set. Like suppose you were hijacking the routine that handles Samus taking damage, and wanted it to play a different sound if Samus took a large amount of damage than if she took a small amount. How do we do this? With branches! You would load the damage Samus recieved that frame, compare it against a value you set with CMP $#xxxx, then do a BPL branch. If the value in A that you just loaded was equal or greater than the value you compared to, the game would follow wherever the branch points. If it was less, it would go straight over the branch, an example in code:

LDX $07BB
LDA $8F0010, X
CMP #$A030
BCC Getout
LDX #$0000
STA $0012
JMP ($0012, X)
Getout:
RTL

In this example, should the value loaded by LDA $8F0010,X be less than the value compared to (A030), the game will follow the branch command and will go straight from the BCC to Getout:
Should the value be greater, it will not follow the branch and will proceed to LDX #$0000 STA $0012 etc... before ending with an RTL.

Opcodes are just your instructions. CMP is an opcode, LDA is an opcode, JMP, RTL, JSR, STA, etc. all are opcodes.

Vener

Okey , Great  :wink:
Thanks for yours times !

Also , it comes in my mind , in another register , an idea . The map tiles could be edited/changed ?
I talk about those tiles :



I see fog , water and lava tiles , maybe also some HUD and message box tiles , i can't touch of them because i keep everything . the X tiles are free space emplacements ?
There are unused/useless tiles in this square ? If yes , please , what is the offset for editing in TLP ?

Quietus

The X's are often unused space, but it is not always safe to overwrite then, as you may push everything along, and overwrite other data.

As for the map suggestion: The answer is 'yes, you can change the map tiles.'  Check here.

Silver Skree

Generally, where you find X marks like that, whether it's safe to overwrite them or not depends on if the data is compressed. For example, those map tiles are not compressed. Level data, tile tables and tile sets are compressed, so you should be wary of edits. Level data and Tile sets are compressed and have wiggle room, but tile tables have NO wiggle room, so overwriting an Xx4 tile can overwrite and destroy the next tile table.

Vener

Super  :grin:

I did not understand for what , oddly , certain X tile modifications screwed up the tables , and certain , not . Now , it make sense .
__________________________________________________________________________

Someone know How ennemies could appear in front of every layers , like the 3 Eticoons ?
It's Because Sadiztyk have made a new ennemie for me , but he appear like normal other ennemies .
On the base , the enemy should be overflow on the ground and the ceiling , that's why he need to be in front of all ..
In the DNA of the eticoons , layer value is 05 . i have tested value 05 , but here , no differences .
Smile said values 00 02 05 or 0B , i have tested values 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 40 80 C0 F0 FF and EA (hs). And after , also in addition with "Special GFX" with graphic unknown 00 04 and 06  , but there is no correcte reaction at all :S ..

Eticons are special AI/initiation case ?

Smiley

The layer value should be 00 for enemies to appear in front of everything. Etecoons' layer value is 05, so they appear behind Samus.
Also, you did remember to press "Save Enemy DNA" every time you changed the value, right?

Vener

I save always each changements of everything ...
Eticoons appear behind samus , but , in front of layer 1 tiles in this room .(and those layer 1 tiles are not with red squares , it's really layer 1 tiles !) . So , what the hell ?
Also , layer DNA value "00" doesn't make ennemies appear in front of all (or maybe just very some).

Crashtour99

It could have something to do with enemy tilemaps.  In each tilemap the segment of the enemy defined is given a layer priority, like a geemer's legs will be displayed over the top of it's body.  However I don't know if tilemap priority takes precedence over layer priority from fx effects or the value in enemy DNA.  Might be something to look into though.

Vener

#116
Layer tile prioritys for ennemies GFX are stored in the Initiation AI ?
And also , for some ennemies , if they are on walls or ceilings , and if a super missil is shoted everywhere in the screen , they falls on the ground . How adding this function to an ennemie that he haven't it ? that's in Running AI ?
_________________________________________________________
Another idea comes , it's about beams . Every beams , even missils , super missils , pass through the air , but when they goes off screen , they are deleted (the proximity screen margin is too little). Every beams , even missils , super missils , could be moving off screen  :?: (Or even just encrease the proximity screens margin)
_________________________________________________________
And finally  :yay: the power bomb explosion GFX is used also for the ceres station explosion . power bomb explosion pallette can be changed in the miscelaneous SMILE options . I change this pallette colours , but i want to conserve the original pallette colours for the ceres explosion , then , my question is , this pallete could be copy/past somewhere , the original pallette for ceres , and the 2nd pallette checked only for power bomb explosions ? those details are important for me 

Crashtour99

Quote from: Vener on July 18, 2011, 07:57:03 PM
Layer tile prioritys for ennemies GFX are stored in the Initiation AI ?
And also , for some ennemies , if they are on walls or ceilings , and if a super missil is shoted everywhere in the screen , they falls on the ground . How adding this function to an ennemie that he haven't it ? that's in Running AI ?
Layer priority is usually handled by the value in enemy DNA.  In some circumstances though it's handled by values in the enemy tilemaps (like for enemies with multiple parts such as geemers, zeelas, and space pirates).  Sadiztyk's EnemyTilemapsRundown document (in the documents section on the main site) has everything you need to find and edit the tilemaps.

As far as modifying behavior like a super missile explosion causing enemies to fall, that would require a bit of work.  Without having actually looked into it, I'd assume that the running AI probably has a check of some sort to determine if a super missile explosion has happened on screen.  If it has it would load a pointer table containing falling animation and code pointers (the way most AIs work is that the initiation AI sets up enemy RAM values that determine where in the running AI to start (among other things), the running AI then does a series of checks to determine what actions to take and loads the appropriate pointer table location for the general enemy routines in bank $A0 to run).

You'd basically have to go through the running AI for a geemer or zeela (or similar enemy), find out what it's doing to check for a super missile explosion, then hijack your target enemy's running AI and run a similar code.  The hardest (or most time consuming) part will be building the pointer table.  If you're lucky it'll be in the same bank as other enemies that fall, so you might be able to get away with using some of their pointers and routines (or perhaps copying them with minimal changes), but I wouldn't count on it.

Vener

#118
Hello Everybody  :yay:

I need to learn some things ..
1) how exactly enemy headers are stored* .
2) how and where FX1 routines are stored . for each regions (works with headers to?).
3) In FX1 , there is "door select" value . it's for that the room know with which door , when we enter , the FX modulation take effect . logicaly , this value should be the offset of the door/room concerned , but i see that it's not the case . How determinate this value ?
4) in the door editor , there are , for the elevators , values in the case "scroll pointer" . how point new elevator scroll values , and where ?
5) where the wrecked ship music data start , and where she's end ?
6) Adresse of the lava speed animation .

*1)Say if it's incorrect :

Enemy header . Always stored in bank $A0 (65 bytes)

XX XX      ?
XX XX      pointer for Palette colours
XX XX      HP value
XX XX      Damage value
XX XX      Width value
XX XX      Height value
XX           Enemy Bank
XX           Hurt Flash value
XX XX      pointer of enemy Sound
XX XX      ?
XX XX      pointer of routine for animations (Initiation)
XX XX      number of parts 
XX XX      ?
XX XX      ?
XX XX      pointer of routine for Grappling beam reaction
XX XX      B (?)
XX XX      pointer of routine for reaction with ice
XX XX      pointer of routine for reaction with xray
XX XX      pointer of routine for Death Animation
XX XX      F (?)
XX XX      G (?)
XX           H (?)
XX XX      pointer of routine for Power bomb Reaction
XX XX      I (?)
XX XX      J (?)
XX XX      K (?)
XX XX      pointer of routine for Enemy Touch
XX XX      pointer of routine for Enemy Shot reaction
XX XX      N (?)
XX XX XX pointer for Enemy Tiles emplacement
XX           Layer value
XX XX      pointer for Item Drop values 
XX XX      pointer of Vulnerability values
XX XX      pointer of Enemy name


Can you also said to me what is each "?" and "(?)" bytes ?

Thanks in advance !

Vener

Do you think that there is a way to put in the same room , two different FX ? 
I think to rooms with "Water" and "Fireflea FX" , with ennemis D6BF (Fireflies) ...