Samus Animation Guide - By Crashtour99 (Included Pic: www.metroidconstruction.com/images/crashtour99_VRAMview.png) So, you'd like to edit Samus' animations huh? Well, there's a lot of stuff involved in it. Hope you're ready! There are basically two separate sections, each with different types of data. The first we'll be looking at are Samus' tilemap pointers and tables. The second deals with which graphics are loaded for any particular frame of animation, and how they're loaded. A final section will tie this info together. Let's get started. ================================================================================================================ Section 1 - Tilemapping The first thing you'll need to do is find out which animation you'd like to edit. Open up SMILE and go to Edit > Samus poses. A rather complex looking window will open up. Don't worry, we won't really be doing much with this. The important things are the dropdown menus at the top and bottom of this window. When you open these dropdown menus you will see a list of values followed by descritpions, ranging from 00: Facing forward, ala Elevator Pose to FC: Crouching to standing, facing left and aiming downleft. These values come from $7E:0A1C which define Samus' current position/state. This is important because these values are used a lot for indexing based on what pose Samus is in. So let's select an animation to edit. Say, 49: Moonwalk, facing left. Multiply this value by 2 to get your base indexing value. There are many tables that will use this to find pointers, and we'll be dealing with a TON of pointers here. At $92945D (ROM address) is a table. This table contains indexing offsets for the tilemap pointer tables, and itself indexed by current position/state. So we have: 49 - current position/state (pose moonwalking facing left) 92 - position/state * 2 Add that to $92945D to get an address of $9294EF. The value here is #$04F7. This value is then multiplied by 2 to give us #$09EE. This is our complete index for finding the pointer to the start of the tilemap table. The tilemap pointer table for ALL animations starts at $92808D, and is indexed by the complete index value we just calculated. So, the start of the tilemap pointer table for pose 49: moonwalk facing left is: $92808D + #$09EE = $928A7B Of course you'll need to use frame progression or slowdown to count all the frames the animation has, so that way you can get all of the necessary pointers. Moonwalking has 6 animations, so starting at $928A7B you'll find the following: $92:8A7B ED B3 03 B4 84 B1 C9 B3 0F B4 95 B1 And those are your tilemap pointers. For Samus' LOWER HALF... Yep, we're not done yet. There is another table at $929263. This table is just like the other one at $92945D, only for Samus' top half. Use the same process as you did before and you'll get all the tilemap pointers you need. Editing the tilemaps is essentially the same process as for editing enemy tilemaps. There are a few differences, but we'll get into that in a bit. Be aware that some animations may share tilemaps, so you may need to repoint. Next on the list is: =============================================================================================================================== Section 2 - Loading the Graphics At $92D94E is another table indexed by current position/state. This table has pointers to a type of data we'll call "Animation Frame Progression Tables". So starting out with our chosen pose of 49: moonwalking facing left: 49 - current position/state (pose moonwalking facing left) 92 - position/state * 2 Add that to $92D94E and you get a location of $92D9E0. The value at this location is #$DCE8. This is the pointer to our Animation Frame Progression Table for moonwalking facing left. Let's take a look at what this data is. At $92DCE8 we see: 00 11 01 03 02 1B 01 04 02 1B 01 15 00 11 01 00 02 1B 01 05 02 1B 01 16 Ok, but what does all this stuff mean? Let's break it down into groups of 4 bytes, which I'll define next. 00 11 01 03 - frame 1 gfx 02 1B 01 04 - frame 2 gfx 02 1B 01 15 - frame 3 gfx 00 11 01 00 - frame 4 gfx 02 1B 01 05 - frame 5 gfx 02 1B 01 16 - frame 6 gfx | | | |_index for bottom half sprites DMA entry (which entry from the table to use) | | |____index for bottom half sprites DMA table (which DMA table to select the entry from) | |_______index for top half sprites DMA entry (which entry from the table to use) |___________index for top half sprites DMA table (which DMA table to select the entry from) So, by these descriptions, you can see that each group of 4 bytes defines the graphics for any one particular frame of animation, and that there are multiple DMA tables, with each table having multiple entries. (For those who are unaware, DMA = Direct Memory Access and is used by the SNES for high speed transfer of data such as graphics to VRAM) Here are the lists (tables) of DMA tables available for use. $92D91E: TOP HALF GFX (index shall not exceed #$0C): EE CB CE CC A0 CD 80 CE F7 CE 6E CF E5 CF 5C D0 E8 D0 2E D1 13 D6 A6 D6 4E D7 $92D938: BOTTOM HALF GFX (index shall not exceed #$0A): 9E D1 7E D2 5E D3 D7 D6 06 D4 A7 D4 4F D5 86 D7 F0 D5 9B D7 05 D6 So with that, let's follow the first frame of animation's gfx info. 00 11 01 03 - frame 1 gfx | | | |_index for bottom half sprites DMA entry (which entry from the table to use) | | |____index for bottom half sprites DMA table (which DMA table to select the entry from) | |_______index for top half sprites DMA entry (which entry from the table to use) |___________index for top half sprites DMA table (which DMA table to select the entry from) Our top half sprites DMA table index is 00, so that gives us a pointer of CBEE. At $92CBEE we find: 00 80 9E 80 00 80 00 ;00 00 81 9E 80 00 80 00 ;01 00 82 9E A0 00 80 00 ;02 20 83 9E A0 00 80 00 ;03 40 84 9E 80 00 80 00 ;04 40 85 9E C0 00 C0 00 ;05 C0 86 9E 80 00 80 00 ;06 C0 87 9E 80 00 80 00 ;07 C0 88 9E C0 00 C0 00 ;08 40 8A 9E C0 00 C0 00 ;09 C0 8B 9E 80 00 80 00 ;0A C0 8C 9E A0 00 80 00 ;0B E0 8D 9E E0 00 40 00 ;0C 00 8F 9E E0 00 40 00 ;0D 20 90 9E E0 00 80 00 ;0E 80 91 9E E0 00 80 00 ;0F E0 92 9E C0 00 40 00 ;10 E0 93 9E C0 00 40 00 ;11 E0 94 9E C0 00 80 00 ;12 20 96 9E C0 00 80 00 ;13 60 97 9E A0 00 80 00 ;14 80 98 9E C0 00 C0 00 ;15 00 9A 9E C0 00 40 00 ;16 00 9B 9E C0 00 40 00 ;17 00 9C 9E A0 00 80 00 ;18 20 9D 9E A0 00 80 00 ;19 40 9E 9E C0 00 40 00 ;1A 40 9F 9E E0 00 40 00 ;1B 60 A0 9E 00 01 C0 00 ;1C 20 A2 9E 00 01 C0 00 ;1D E0 A3 9E 00 01 40 00 ;1E 20 A5 9E 00 01 40 00 ;1F That's a whole ton of stuff. Our index for top half sprites DMA entry is 11, so the 11th entry in the list is: E0 93 9E C0 00 40 00 ;11 Ok, so what's that mean? The first 3 bytes are a long pointer to the actual graphics in the ROM. The next 4 bytes define how much data to transfer for parts 1 and 2. $9E93E0 = long pointer to gfx #$00C0 = how many bytes of data to transfer for part 1 #$0040 = how many bytes of data to transfer for part 2 The part size refers to how the data is loaded into VRAM. (See attached image for a visual representation) Each 8x8 tile is $20 bytes, and each part cannot exceed 8 tiles ($0100 bytes). Do the same to find the DMA data for the bottom half gfx. Again, some of this stuff may be shared between animations, so use backups and edit carefully. ============================================================================================================================= Section 3 - Putting it all together. When you looked at the included image you probably noticed that all of Samus' graphics are clumped together right above the "always loaded graphics" for things like explosions and particle effects. This section is the start of your tile indexing for the tilemaps. In a tilemap for Samus, the top sprites will almost always use tiles 00 - 07 or 10 - 17. It is a similar case for the bottom sprites. Also, you must always be sure that the number of animations matches the number of tilemap pointers AND number of entries in the Animation Frame Progression table. If you have 6 animations, you need 6 tilemap pointers and 6 4-byte-entries in the progression table. If you don't, things will get very weird (and probably break). What about frame delays between animations you ask? For that there is a table at $91B010. Again, this is indexed by the current position/state. So for moonwalking facing left, we add 92 to $91B010 to get a location of $91B0A2. At this location is a pointer. The pointer here is B226. This is the start of the list of frame delays to use for this animation series. $91B226: 10 10 10 10 10 10 So each animation lasts for 10 frames (hex). And that my friends is how to edit Samus' animations. If you'd like to expand an animation sequence and add more, well it's certainly possible. Most of these use pointers, so you can just repoint a bunch of things. The harder part will be repointing the tilemap table itself, as it uses some convoluted indexing methods. But if you understand it well enough, I'm sure you'll figure out how to do it. Alright folks, let's see some magic happen!