Streets of Rage Online
[ Hacking ]
Info on hacking both the ROM and game savestates. Please submit anything you find; you will get full credit for it.

Savestates
- Game Data
- Character Data
- Score Data
- GFX Data
- Palette Data

ROM
- Text
- Other

Useful Info
- Palette Guide
- Font Table

Programs
- Trainers

[ Streets of Rage 2 Menu ]

Savestate Hacking: Info
This info is for savestates created by Gens/Genecyst (plus any other emulators that use the same format). You will need to understand hexeditors to make use of this info.

To learn how to convert this information into a PAR code go to SOR3 Hacking.

Savestate Hacking: Game Data

1207B - Screen Select
This is a powerful address that tells the game to move from one screen to another. Changing this can produce some corrupted graphics, especially if you try to move from in-game. The values in-between values appear to have the same function; for example, both 08 and 0A take you to the demo, and 1C and 1E both take you to the ending.

Values:

  • 00 - Sega logo
  • 04 - Title screen
  • 08 - Demo
  • 0C - Menu
  • 10 - Options
  • 14 - In-game (setting to this starts on a new game on Round 1)
  • 18 - Character Select
  • 1C - Ending
  • 20 - Duel in-game
  • 24 - Intro
  • 28 - High Score Table

120B4 - Time Remaining
The amount of time remaining to finish a set of punks (as shown on screen). Changes can be seen only when the number on screen is refreshed. This is stored simply as a decimal value, so for 74 seconds remaining you enter 74.

120BB - Stage
Controls the stage you are currently on. It loads in the floor plan (ie where you can and cannot walk) from the ROM. Changing the value means adding a another level's layout to the current level, which looks very odd. The actual enemies remain unchanged, but they appear at the "trigger points" from the level you have loaded. When you complete a stage you go to the next stage of the level you loaded, which tends to be completely messed up and often devoid of punks. Values: Round 1=00, Round 2=02, Round 3=04... Round 8=0E.

120BD - Set Number
The waves of punks in SOR2 are divided into "sets"; every time you are given the "GO" sign or finish a scene you move onto a new set of punks. Changing this midway through a level fools the game into thinking you are at a different point in a level and loads in the appropriate punks; however the graphics often don't catch up with the screen, leading to messed up backgrounds and other bugs. 00=1st set, 02=2nd set, 04=3rd set etc.

120E3 - Difficulty Setting
Controls the difficulty setting, and can be changed at any time with no apparent bugs. Very Easy is 00, Easy is 02, Normal is 04, Hard is 06, Hardest is 08 and Mania is 0A.

12187 - Starting Stage
The stage you will begin a new game on. 00=Round 1, 01=Round 2... 07=Round 8

Savestate Hacking: Character Data
SOR2 stores the data for the onscreen characters' (ie players & punks) status bars in blocks. Each block is (I think) 256 bytes and uses the same layout, so techniques for editing the players can be used to edit the punks and so on. Objects such as bonuses also have blocks but share few of the player/punk values. The first block is Player 1, the second Player 2, and then the punks, then any objects such as containers, bonuses or weapons. I'm pretty sure that the Player 1 block begins at 11379, and to get to the next block you add "100" (it's actually 256 but who cares?), so 11479 is the start of Player 2 data.

In the info below the 3rd digit of the offset address is X. Simply replace these with 3 for P1, 4 for P2, 5 for first punk, 6 for second punk and so on. For some of the offsets a Y is used. This is X+1, so for Player 1's data Y is 3+1=4 . You will hopefully notice that you can move from block in Hexposure simply by pressing Page Down. This allows you to easily compare values, as if you are on the sprite address for P1, pressing Page Down will take straight to the equivalent for P2, and a second press will take you to that for the first punk.

11X7B - Sprite X co-ordinate
11X7F - Sprite Y co-ordinate
These values control where the character/object's sprite appears on screen. These are measured in pixels, converted to hex, from the top-left of the screen. These should always be identical to the real XY position of the object (see below); changing them will get the two sets of values out of sync for a moment.

11X82 (1st digit) - Palette
Changing this obviously changes the colours of the sprite you're editing. Acceptable values are 0, 2, 4 and 6 which represent the 4 on screen palettes. Palette 0 is the player palette used by all 4 characters, the status bar, and most of the punks in their standard incarnations (eg Galsia rather than Joseph). It is possible to use 8, A, C and E, which also represent the 4 palettes. However, the game will interpret any object with this value as being part of the foreground, so the object will be visible through any scenery.

11X82 (2nd digit)-11X83 - Graphics Location
Tells the Genesis where in RAM it will find the graphics for a sprite. Changing the value can give some bizarre results. It can be used to transform a punk; match it to that of a different on-screen punk and also change the punk's 11X85 value to that of the different punk.

11X85 - Character
Changes character/punk. However, this doesn't change the graphic set the Genesis is using to create the sprite (especially for punks!). To fully change a punk into another you need to edit both this address and the graphics tiles stuff above. Below is the list of values that represent the different characters. Thanks to Greers & Quickman for most of these.

  • 00: Max
  • 02: Axel
  • 04: Blaze
  • 06: Skate

  • 08: Galsia
  • 0A: Donovan
  • 0C: Jack
  • 0E: Barbon
  • 10: Electra
  • 12: Y. Signal
  • 14: Fog
  • 16: Ninja (unarmed)
  • 18: Big Ben
  • 1A: Hakuyo
  • 1E: Raven
  • 20: Jet
  • 22: Zamza
  • 24: R. Bear
  • 26: Abadede
  • 2C: Oxygen
  • 30: Mr. X
  • 32: Shiva
  • 34: Ninja (with kunai)
  • 36: Ninja (with katana)
  • 3A: Vehelits

  • 3C: Knife
  • 3E: Pipe
  • 40: Kunai(?)
  • 42: Katana
  • 44: Kunai(?)
  • 46: Grenade

  • 4C: Bin(?) container
  • 4E: Barrier container
  • 5A: Table container - (all the item containers will have different values)

  • 8C: Money
  • 8E: Gold
  • 90: 1up
  • 92: Apple
  • 94: Chicken

You will notice that the hex value increases in multiples of 2. Putting in an odd value, such as 03 or 0B, produces some weird results with both players and punks, creating characters which cannot cause damage and that have messed up icon pics. 01, 03 & 05 give "hyper" versions of Max, Axel, and Blaze respectively, but these are horribly bugged and were clearly not intended as a cheat.

The ninjas are listed three times, presumerably as the AI for the differently-armed versions is so different.

Interestingly, this value does not change for punks that are armed, or for when the bikers are on their bikes. This must be controlled elsewhere.

Placing a punk value in the player 1 or 2 address crashes the game, but does change the sprite to the selected one. If you do this on the character select screen however, you get an "enemy select" screen, where you can scroll through most of the enemy sprites (generally messed up and/or using the palette). Check it out in this savestate from Felipe Moniz.

11X95 - "Real" X co-ordinate
11X99 - "Real" Y co-ordinate
These values control where the character/object really is on the screen, regardless of the position of the sprite displaying it. These are measured in pixels, converted to hex, from the top-left of the screen. If these values are different to those of the sprite, it always uses these values to get them back into sync.

11XC4-11XC5 - Number of KOs
The number of KOs made by the player in his/her last continue in hex eg 0200 would give 512 KOs. Press A on the high score table to view.

11XEC-11XEE - Position of status bar
These appear to control the onscreen position of the status bars.

  • 11XEC 1st digit - Always 5. Unknown function.
  • 11XEC 2nd digit & 11XED 1st digit - The Y co-ordinate of the top of the status bar in hex. Default is 08 (ie 8 pixels from top of screen) for players, and 18 (24 pixels) for punks.
  • 11XED 2nd digit & 11XEE 1st digit - The X co-ordinate of the right edge of the health bar in hex. For Player 1 and punks being hit by P1 this will be 80 (128 pixels from left of screen).
  • 11XEE 2nd digit - Seems to be 0. Unknown function.
If you've lost me, try and look this example of the default values of the 3 bytes for P1. The blue digits are the Y value, the red the X value.

508800

Changing the values tends to screw up the display, and putting in very large values tends to turn the status bar into part of the background. Just thought I'd warn you.

11XFO-11XF7 - Character name
Players are given 5 characters for this, punks are given 8. Other than that it's very simple.

11XF9 - Health
The amount of health in the player/punk's health bar. The max is 68 (which is hex for 104, the total number of pixels in the health bar).

11XFB - Lives
The number of lives the player has, or in the case of a punk the number of stars on their life bar (which are in effect it's lives). 00=1 life, 01=2 lives, 02=3 lives and so on. Note: The number of lives for a player displayed on screen will not change until you force it to refresh the number by, for example, gaining or losing a life.

11Y0E-11Y10 - Score
Score is stored in three bytes (ie 6 digits) as a decimal number, with the first byte dealing with thousands, the second with hundreds, and the third tens. Example: if Player 1's score was 11570, 1140E would be 01, 1140F would be 15, and 11410 would be 70.

Savestate Hacking: High Score Table Data
All the info from this is carried around inside a savestate. It's very easy to edit as it uses the same format as some of the above. Each part of the table takes up 16 bytes, so you move between the same data for each entry in the table by pressing up/down. XX represents 1A for first place, 1B for second and 23 for tenth. Y as before is X+1.

12XX8-12XXA - Score
Score is stored in three bytes (ie 6 digits) as a decimal number, with the first byte dealing with thousands, the second with hundreds, and the third tens (same format as in status bar). Example: if the first person's score was 11570, 121A8 would be 01, 121A9 would be 15, and 121AA would be 70.

12XXB - Round
This was the round the person reached before dying. 00= Round 1, 01 Round 2 etc.

12XXC - Character
Same format as before; Max is 00, Axel is 02, Blaze is 04 and Skate is 06.

12XXD-12XXF - Initials
Three characters, normal text format.

12XY0 - Difficulty
The difficulty the person played on. Very Easy is 00, Easy is 02, Normal is 04, Hard is 06, Hardest is 08 and Mania is 0A.

12XY2-12XY3 - Number of KOs
The number of KOs made by the player in his/her last continue in hex eg 0200 would give 512 KOs. Press A on the high score table to view.

Savestate Hacking: Graphics Data
As you will probably know, the graphics you see onscreen are made up of 8x8 tiles (open up Patterns in Genecyst to see them). Inside the savestate is a map of where to place these tiles in order to create the graphics, which can be easily edited. However, it does not affect the actual floor plan of the level, which is stored elsewhere.

Graphics data is spaced throughout the savestate RAM, with the background, foreground etc being spaced apart. The format used is 2 bytes per tile eg. 4085. The tiles are listed in rows from left to right.

The first digit of the first byte is the palette of the tile; acceptable values are 0, 2, 4 and 6 which represent the 4 on screen palettes. Use 8, A, C or E to get the game to interpret the tile as being part of the foreground, so it will be visible in front of everything else.

The three remaining numbers are to select which of the many tiles loaded in RAM should be used. In the example above, 085 means the 85th tile. The tiles start at 12498 in the savestate - use TLP to view them.

Savestate Hacking: Palette Data
Note: You will probably need to read the guide to understand how to edit this data.

The SOR2 savestate contains a number of palettes loaded from the ROM for use in game (although only 4 will used at any one time). These begin at 11078 and seem to extend up to (but not including) 112A8, which presumerably means that 18 palettes are being stored, which seems slightly improbable. Entering palette values of above 3 doesn't seem to access the 15 palettes above 3, so what may happen is that the game redefines where to look in the list of loaded palettes for it's palettes, and so changes the colours that way.

Any changes you make to the palettes will last only until the end of the stage when the palettes are changed for the new graphics. Below are those known for definite. Putting one of the palette values below into the 1st digit of 11X82 should hopefully change that sprites palette, but things may not happen exactly as anticipated as I don't fully understand what's going on yet.

11078-11097 - Palette 0
11098-110B7 - Palette 1

ROM Hacking: Text
All the text in SOR2 uses the standard text format, so you will not need to construct a font table (although some the symbols will not show up - see here for values). Offsets here are usually approximate and give the start of the text only. You will notice that Sammy and Skate are referred to as different characters.


100 - Header
360 - Default High Scorers
59AC - Lockout
5CE0 - Title Screen
646E - Difficulty Settings
657C - High Score
73B2 - Status bar player names(?)
7450 - Menu text
74C6 - Character select text
75BC - Duel options
8F92 - Round Clear
B734 - Select Player
BA60 - Continue
FE30 - Options
223E0 - Credits
249A6 - Intro
2F26B - Font table(?)
1EFC56 - Punk names

ROM Hacking: Other Addresses

255E - Damage inflicted by Axel's knee attack
Same format as health bar ie number of pixels converted into hex. Normal amount is 08.

255F - Sound effect to play for Axel's knee attack
This is one of the Voice sound effects. To change to another, take its value in the sound test and convert to hex. Normal voice is 00.

2576 - Damage inflicted by Axel's double knee attack
Same format as health bar ie number of pixels converted into hex. Normal amount is 08.

2577 - Sound effect to play for Axel's double knee attack
This is one of the Voice sound effects. To change to another, take its value in the sound test and convert to hex. Normal voice is 01.

Useful Info: Guide to working with Genesis Palette Data
The Genesis/Megadrive has a total colour palette of 256 colours (comprising of 16 shades of red, blue and green in different combinations) but it can only use a fraction of these at once. It uses four 16 colour palettes, meaning that at most there are going to be 64 colours onscreen. Each palette is usually dedicated to certain sprites onscreen. Here's what the 4 palettes deal with in SOR2.

Palette 0: The players, the punks (generally not bosses) in their "normal" colours, the status bar and the onscreen items such as weapons and containers

Palette 1: The punks onscreen in different colours and most bosses.

Palette 2: Background graphics (sometimes foreground too)

Palette 3: Foreground graphics (sometimes background too)

To see this for yourself take a screenshot with Genecyst and open it in Paint Shop Pro (it helpfully arranges the colours in 4 rows of 16). Open the palette and move the cursor across the image to see that the colours on certain sprites are restricted to a certain palettes. Doing this also allows you to discover what colours each palette contains, so you can convert them and find them in the ROM/savestate.

The first colour of each palette is a transparent colour that obviously doesn't show up on screen (although on a real Genesis/Megadrive this is used as the border colour above and below the screen). This means that only 15 of the 16 colours are used, bringing the number on screen down to just 60.

The 16 colour palette in all Genesis/Megadrive games is made up of 32 bytes, with 2 bytes (4 digits) for each colour. As you should hopefully know, a colour on a monitor is a combination of Red, Blue and Green, of which there are 256 (ie 0-255) shades. Since the Genesis/Megadrive has only 16 shades to work with, each RGB component can be stored as a single hex number ie 0 to E. The first digit of the first byte is always 0. Then the colours are entered in as BGR (don't ask why it isn't RGB). So the values of the bytes to give a light grey colour would be like this inside a ROM/savestate: 0EEE. A palette is simply stored as 16 of these in a row with no spaces between.

Converting a RGB colour to Genesis/Megadrive format

An example RGB colour is 224,100,50, which gives this orange. To convert this to Genesis format we have to turn this combination of 256 shades of RGB into a combination only 16 shades of RGB. To do this we first divide each part by 16. If you end up with anything after the decimal point just round down (never up) to the last interger. This, in the example above, gives 14,6,3. We then convert to hex (use Windows calculator if you're not sure), and forget the 0 at the start of each number, giving us E,6,3. Finally we rearrange this into BGR order and put a nought in front to give 036E, which is how the orange would be stored in a ROM or savestate.

Converting a Genesis/Megadrive format colour to RGB

To convert the other way you do the reverse; lose the first nought, rearrange from BGR into RGB, convert to decimal and multiply each part by 16.

Useful Info: Font Table
You can put some interesting text characters into the game (ROM or savestate) where the blue font is used. Below is a list of values that will be worth using - you could put of Axel's face into the text but that would look crap...

20=
21=!
22="
23="S" from Sega logo on title screen
24="E" from Sega logo on title screen
25="G" from Sega logo on title screen
26="A" from Sega logo on title screen
27='
28=(
29=)
2B=Cursor
2C=,
2E=.
2F=/
30=0
31=1
32=2
33=3
34=4
35=5
36=6
37=7
38=8
39=9
3A=* (yellow star)
3B=faded 0 from score bar
3F=?
40=©
41=A
42=B
43=C
44=D
45=E
46=F
47=G
48=H
49=I
4A=J
4B=K
4C=L
4D=M
4E=N
4F=O
50=P
51=Q
52=R
53=S
54=T
55=U
56=V
57=W
58=X
59=Y
5A=Z
5B=E/D symbol

Programs: Trainers
Greers' trainer for SOR2 allows you to change your character, lives, health, difficulty and round ingame, and can also morph you into Shiva (unplayable) and tweak the BGM music. It's available for download here.

Note: You will require Gens 1.20 & a copy of the SOR2 ROM.