Difference between revisions of "Sonic the Hedgehog 2 (16-bit)/Object Editing"
From Sonic Retro
(add + fix headers) |
(→Ring Placement) |
||
Line 156: | Line 156: | ||
03 46 10 2B | 03 46 10 2B | ||
− | If you see this, then you will get two horizontal rings at X = 0346 Y = 02B. The "1" determines how many rings there are, and | + | If you see this, then you will get two horizontal rings at X = 0346 Y = 02B. The "1" determines how many rings there are, and in which direction they go (horizontal or vertical). For the "T" nybble, the entry will create a column of rings if the uppermost bit is set, otherwise it will create a row of rings. The number of rings created is the lower 3 bits plus one. Therefore, you can get one to eight rings in a row or column with one ring entry. Notice that types 0 and 8 are the same, as a row of one ring is the same as a column of one ring. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
See the [[Sonic Community Hacking Guide/Sonic 2/Level Specific|level specific hacking info]] for the locations of the ring data. | See the [[Sonic Community Hacking Guide/Sonic 2/Level Specific|level specific hacking info]] for the locations of the ring data. |
Revision as of 09:23, 7 January 2008
Sonic Community Hacking Guide Sonic the Hedgehog 2 (16-bit) |
---|
Art |
Objects |
Levels |
Text |
Music |
RAM |
Miscellaneous |
Sounds
If you change the "ring" sound effect, all objects using that sound will have the new sound. This may not be desired, however - you may have only wanted the Super Ring powerup to play the new sound. With this list, you can edit the sound effect that an object plays. If you change the sound for the Super Ring power-up, only the Super Ring will have the new sound. Note that you are not changing any sound effects - you are only changing which effect will play.
These notes are for those who don't want see the programming stuff of the objects to change its sounds.
To change the sound, first, take a value from the sound test (Ex: 1-up sound is $18) , add $80 to it and you get $98. This is the way you have to replace sounds (take a value from sound test, add $80 to it, and after that, insert the byte in the offset where you wish change the sound.)
Offset List
The following list is the offset where you will place the new sound. I not will make a list with the values and its respective sounds. Use the trick (explained above) and Sound Test. Of course you can place the objects in any level you want (see Object Placement below), I'm just saying the level the object is used in for a better description.
Level | Description | Offset |
---|---|---|
ALL | Invincibility power-up | $12A81 |
ALL | Shield power-up | $12A37 |
ALL | Super Ring | $129CD |
ALL | Lamp Post: | $1F191 |
Casino Night | Bumper | $1F7F5 |
ALL | Red and Yellow Springs Facing Up | $18A69 |
ALL | Red and Yellow Springs Facing Right | $18BBF |
ALL | Red Spring Facing Down | $18D63 |
Chemical Plant | Speed booster | $223DB |
Chemical Plant | Blue worm (The sound is repeated 3 Times.) | $224EA |
Aquatic Ruin | Arrow launcher | $257B7 |
Casino Night | Slot machine cage | $2BE1F |
Casino Night | Point cage | $2BE6B |
Hill Top | Zip line | $21E75 |
Casino Night | Blue Bumper | $2C577 |
Casino Night | Green flipper | $2B30B |
Casino Night | Orange flipper | $2B3BF |
Casino Night | Impulse spring facing up | $2AE4F |
Wing Fortress | Propellor (repeat infinitely) | $3B3A3 |
Object Pointer List
See SCHG:Sonic 2/Object Editing/Pointers.
Sprite table (aka mappings)
Reference
The sprite table data can be expressed with this pseudocode:
struct spriteTablePiece{ byte yPosition; byte shape; byte attributes1P; byte artOffset1P; byte attributes2P; byte artOffset2P; word xPosition; }; struct spriteTableLenghth03{ const word length == 3; spriteTablePiece table[3]; } spriteTable01;
- The value of shape can range from $00 (1x1) to $0F (4x4). $01 is a 1x2 sprite, $02 is a 1x3 sprite, $04 is a 2x1 sprite, and so on.
- attributes1P and attributes2P are bitfields that controls various sprite attributes:
Bit Attribute 3 Flip sprite horizontally 4 Flip sprite vertically 5 Palette line +1 6 Palette line +2 7 Keep sprite in forground
- artOffset1P and artOffset2P control the offset from the object's base tile that the sprite should start reading from. For example, if the object's art started a tile $3F0, and artOffset1P was $06, then the sprite would start reading its art at $3F6.
Question: Are xPosition and yPosition offsets from the object's current position?
Dynamic PLCs
Dynamic PLCs (pattern load cues) were hard-coded and for the most part unnoticed in Sonic the Hedgehog. In Sonic 2, they are more flexible and used for many more objects. The format of DPLCs is simple: the first word is the number of DPLC requests to make, and each successive word (up to the value of the first word) is split up so that the first nybble is the number of tiles to load minus one, and the last three nybbles are the offset (in tiles, i.e. multiples of $20 bytes) of the art to load from the beginning of the object's specified art offset in ROM. Therefore, in order to request x tiles to be loaded, you need 1+floor(x/16) words in the DPLC.
Object Placement
There are six bytes in one object definition. The first two bytes are the X position of the object, and the next two bytes are the Y position. The 5th byte is the reference number on the object pointer list (see above), and the 6th byte is an optional declaration to use for defining that object's behavior and/or animation. This will depend on the object. See the level specific hacking info for the locations of the object lists.
The 6th byte, the object subtype, is loaded in byte $28 of the SST of that object (see below).
Ring Placement
There are four bytes for every ring object. The first 2 bytes are X coordinates, after that there is one nibble to determine how many rings, then three nibbles (or one nibble and one byte) for the Y coordinates. After you are done adding all your rings for the level, "FF FF" will end the ring data. A format would look like this:
XX XX TY YY
Where X represents X position, Y represents Y position, and T represents type, as per the table below.
Example: 03 46 10 2B
If you see this, then you will get two horizontal rings at X = 0346 Y = 02B. The "1" determines how many rings there are, and in which direction they go (horizontal or vertical). For the "T" nybble, the entry will create a column of rings if the uppermost bit is set, otherwise it will create a row of rings. The number of rings created is the lower 3 bits plus one. Therefore, you can get one to eight rings in a row or column with one ring entry. Notice that types 0 and 8 are the same, as a row of one ring is the same as a column of one ring.
See the level specific hacking info for the locations of the ring data.
Level Layout
Level layouts are compressed in Kosinski format, so to edit them you will need to decompress them first. (I recommend using TSDC for this)
Level layouts are pretty simple. There is one byte per 128x128 tile to place on the map. The blocks are put together from left to right, top to bottom. Each horizontal row is 60 bytes long. The rows are interlaced between the foreground and the background, so that there are 60 bytes for the first row of the foreground, then 60 bytes for the first row of the background, then 60 bytes for the second row of the foreground, etc.
See the level specific hacking info for the locations of level layout data.
Block Mappings
These are compressed in Kosinski format, so to edit them you will need to decompress them first.
struct blockElement { int cellProperties : 5; // c int vramCellIndex : 11; }; // i // cccc ciii iiii iiii blockElement (*blockMap)[0x100][4] = 0xFFFF0000; struct metaBlockElement { int : 4; // x int blockIndex : 12; }; // I // xxxx IIII IIII IIII metaBlockElement (*metaBlockMap)[0x300][8] = 0xFFFF9000;
A block is an array of four blockElements. blockElement->cellProperties describes the palette line and orientation of the cell. The actual mapping of block elements is like this:
0 1 2 3
Metablocks are basically arrays of indeces into blockMap. metaBlockElement->blockIndex provides the first index into blockMap; the upper four bits of the element appear to be unused.
Nemesis provides this chart of values for the upper four bits of cellProperties. The LSB mirrors the cell.
Value | Pallet Line | Flipped Horizntally |
Flipped Vertically |
---|---|---|---|
0 | 1 | n | n |
1 | 1 | n | y |
2 | 2 | n | n |
3 | 2 | n | y |
4 | 3 | n | n |
5 | 3 | n | y |
6 | 4 | n | n |
7 | 4 | n | y |
8 | 1 | n | n |
9 | 1 | y | n |
A | 2 | n | n |
B | 2 | y | n |
C | 3 | n | n |
D | 3 | y | n |
E | 4 | n | n |
F | 4 | y | n |
See the level specific hacking info for the locations of 16x16 data.
Text Editing
See SCHG:Sonic 2/Text Editing.