don't click here

Basic Questions & Answers thread

Discussion in 'Engineering & Reverse Engineering' started by Tweaker, May 29, 2008.

  1. Hayate

    Hayate

    Tech Member
    Bits are binary digits.
    In decimal if you have one digit you can have 10 possible values (0 to 9). With two digits you can have 100, with three, you can have 1000, etc etc.
    It's exactly the same with binary - if you have one bit there are 2 values, two bits give you 4 values, three bits give you 8 values, four bits give you 16 values, etc. The number of possibilities doubles with each additional bit.

    So a 15-bit palette gives you 2^15 = 32,768 possible colors.

    Actually most GBA games use 16-color palettes instead of 256 or 32k colors - for the simple reason that it means the art is twice (or four times) as small in filesize.
    Sonic Advance 3 for example, uses a 256-color palette for the chao on the menu screen IIRC, though it uses 16-color palettes for the sprites and level art - just as the Genesis games do.
    The only differences are that a) the GBA has 32 palette lines (16 for sprites and 16 for tiles) whereas the Genesis only has 4 (shared between sprites and tiles), and that colors in GBA palettes can be specified with 15 bits, whereas colors in Genesis palettes are specified with only 9 bits (unless you do some shadow/highlight trickery, which I won't get into here).
     
  2. Volpino

    Volpino

    Things are looking up! Member
    1,207
    0
    0
    A secret. >:3
    So basically if I understand most of that right, the GBA has the RGB pallet inside it, but it can't use all those colors at one time? And that the carts have a set of which colors they use from the RGB pallet?
     
  3. GT Koopa

    GT Koopa

    Member
    2,021
    18
    18
    Elgin, IL
    Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
    While I can't do anything about it right now, how do you guys get the actual correct instruments when porting a song? It is only for games that use SMPS right? And only because said music hacking guide tells you where to go, right?

    Ok, so making this sound like THIS is out of the question? (I don't need the orchestra hit)

    Then again...changing the DAC samples in Sonic 1. If it isn't as easy as swapping them out in the disassembly, how do you do it?
     
  4. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,205
    432
    63
    Japan
    It is possible to generate any sound from one megadrive game onto another of say Sonic 1's SMPS, you'll find that if the format of the game you're getting the music from is also the SMPS format, then porting is much more easier, though to gain sounds from games that use a different engine, although posible, not easy, the music guide there can be useful for porting music/sounds, but as far as games go, it's far from complete.

    Perhaps this might be of some help Download (An old Sonic 1 rom rewriten into an SMPS editor, not a great one but it's useful for voice creating/changing/testing).

    Nope it can be done, but if it's not the same format then converting it (or recreating it) into SMPS format can be done insted (though like I said before, not easily).

    Sonic 1's DAC driver is probably not the most friendly of drivers when it comes to editing/using, but it's explained here just in case. Though I would recommend looking into alternative drivers that have been created by one or two individuals in the scene, here's the two most notable I've found:

    http://forums.sonicretro.org/index.php?showtopic=6920
    http://forums.sonicretro.org/index.php?showtopic=15064
     
  5. GT Koopa

    GT Koopa

    Member
    2,021
    18
    18
    Elgin, IL
    Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
    So the above is better than porting the Sonic 3 or Sonic 2 sound driver? I was afraid if I did those XM3SMPS/oerg outputted files wouldn't work with the dissasembly anymore.


    Ok, while I am asking questions, the background scrolling and deformation. After looking at the asm code and fiddling around I....still don't get it.

    I mean I know where it is, I just don't know how it works.
     
  6. Yeah, most of these older game systems work like that. They can generate a certain number of colors (GBA: 2^15 = 32768, Genesis: 2^9 = 512, Game Gear: 2^12 = 4096, Master System: 2^6 = 64, and so on) but the different video modes dictate how many of them you can show at a time. Most video modes used in actual games make use of several small palettes (the Genesis has 4 16-color palettes, the Master System has 2 16-color palettes, the NES has 8 4-color palettes, and so on), that you can fill using colors from the complete color space of the system in question.
     
  7. FraGag

    FraGag

    Tech Member
    It's very simple in theory, but it may be tricky to get the right effect in practise.

    In Sonic 1, there is an array starting at $FFCC00 that is used to tell by how many pixels each line will be shifted. This array is $400 (1024) bytes long; that's room for 256 lines for the foreground and 256 lines for the background, one word each. The values alternate between foreground and background; the first word corresponds to the first foreground line, the second word corresponds to the first background line, etc. The word is added to the X position of the line to shift it (when you move right, you need to use negative values to make the foreground and background move left!). The screen displays 224 lines, so some of them are not visible. Line 0 is always the first visible line at the top of the screen. Note that although the values from the last 32 lines are effectively unused, the code does write to them, and unless you really need 128 extra bytes in RAM, I wouldn't bother editing the code to avoid writing past 224 lines (especially if you don't understand it :v: ).

    In the original deformation code, you'll see some instances where it copies data by longwords to the array. In most levels, the foreground doesn't have any special deformation (Labyrinth Zone in REV01 is an exception), so the upper word (foreground) is set once based on the camera's X position, and then only the lower word (the background) has to be updated for each line. (When you do a word-sized operation on a register, you always access the lower word; if you want to access the upper word, you have to use the SWAP instruction.)

    You'll also see several loops (using DBF) that usually represent "strips" (groups of consecutive lines) that move at the same speed or at gradually increasing speeds. In the case of Green Hill Zone and Marble Zone (and maybe others), there are values in RAM that help to scroll certain "strips" (e.g. $FFF710, $FFF718). Try freezing them with a PAR code (FFF710:0000) to see how it affects the deformation.
     
  8. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,205
    432
    63
    Japan
    EDIT: Oooohh FraGag, you beat me to the punch!!

    Horizontal scrolling is more simpler than it seems, it's just the software written in Sonic games tend to be complexe for the purpose of reducing space and allowing faster processing. I'll try my best to explain, but I'll only explain what I think you'll need to know. Let's start by explaining the scroll format itself.

    From ($FFFFCC00) to ($FFFFCFFF) is the start of the scroll buffer space, you move the scroll positions in this space, the format is as followed:

    FFFFCC00 - FFFFCC01 = FG line 1 position
    FFFFCC02 - FFFFCC03 = BG line 1 position
    FFFFCC04 - FFFFCC05 = FG line 2 position
    FFFFCC06 - FFFFCC07 = BG line 2 position
    FFFFCC08 - FFFFCC09 = FG line 3 position
    FFFFCC0A - FFFFCC0B = BG line 3 position
    FFFFCC0C - FFFFCC0D = FG line 4 position
    FFFFCC0E - FFFFCC0F = BG line 4 position
    FFFFCC10 - FFFFCC11 = FG line 5 position
    FFFFCC12 - FFFFCC13 = BG line 5 position

    ...etc

    Line 1 is the very first scan line at the top of the screen, line 2 is the next scan line, line 3 is the next, so on and so forth... This leaves a "long-word" per scanline, the first word always being plane A position (The FG) and the second word always being B position (The BG).

    if we moved 0004 to FFFFCC00 - 01, the top FG scan line will shift right 4 pixels and remain there, if we moved 002A to FFFFCC0A - 0B, the 3rd BG scanline will shift right 2A pixels and ramain there, if we moved FFFC to FFFFCC10 - 11, the 5th FG scanline will shift left 4 pixels.

    That's the general format in this situation. Now to explain the software:

    You might see a bit of code that looks something like this (This one is not from the source, I wrote this just to explain)...

    Code (ASM):
    1.  
    2.         lea ($FFFFCC00).w,a1            ; load beginning of buffer address to a1
    3.         move.w  ($FFFFF700).w,d0            ; load screen's X position
    4.         neg.w   d0                  ; negate (positive to negative)
    5.         swap    d0                  ; send to the left side of d0
    6.         move.w  ($FFFFF700).w,d0            ; load screen's X position
    7.         neg.w   d0                  ; negate (positive to negative)
    8.         asr.w   #$01,d0                 ; divide by 2 (Slow down the scroll position)
    9.         move.w  #$00DF,d1               ; set number of scan lines to dump (minus 1 for dbf)
    10.  
    11. DeformLoop:
    12.         move.l  d0,(a1)+                ; dump both the FG and BG scanline position to buffer
    13.         dbf d1,DeformLoop               ; repeat d1 number of scanlines
    The comments should help, but the software is confusing anyway...

    What's happening here, is ($FFFFF700) is the X screen position (I.e. number of pixels the screen is from the left), when sonic moves right, the screen follows him and the X position increases further to the right. Now we want the FG and BG to scroll the other direction (I.e. go left), so the scenery looks like it's moving behind sonic and the screen as he moves, this is why we load it into d0 and then negate it.

    The neg command (Negate) will reverse the value from positive (00 - 7F) to negative (FF - 80) and vis versa, so we use this command to reverse the direction (or better yet reverse the screen position) so we can move it to the scroll position. (If the screen has moved right 4 pixels, the scroll position will move back 4 pixels, it's as simple as that.

    Now I've arranged it here so that d0 holds both FG and BG scroll positions, d0 = FFFFBBBB (F = FG|B = BG), this is why I've used the swap command, we move the screen's X position to d0, negate it to opposite, and then swap to send it to the left side, we then move the screens X positon again to the right side of d0 (this time for the BG), and negate it to go the other way too.

    The asr command (Algorithmetically? shift right) will divide the position value by 2, this will effectively make the BG's scroll position move left half the amount of the FG (making the BG appear to move slower, thus making it seem further away).

    Next we simply move d0 (Containing both the FG and BG positions) to the buffer:

    Code (ASM):
    1.         move.l  d0,(a1)+                ; dump both the FG and BG scanline position to buffer
    Now we could sit here all day putting in loads of these for each scanline like this:
    Code (ASM):
    1.         move.l  d0,(a1)+                ; dump both the FG and BG scanline position to buffer
    2.         move.l  d0,(a1)+                ; dump both the FG and BG scanline position to buffer
    3.         move.l  d0,(a1)+                ; dump both the FG and BG scanline position to buffer
    4.         move.l  d0,(a1)+                ; dump both the FG and BG scanline position to buffer
    5.         move.l  d0,(a1)+                ; dump both the FG and BG scanline position to buffer
    6.         etc...
    But it's assembly common sense to reduce the amount of memory usage, so we use the dbf command to repeat the one command on it's own, we do this d1 number of times (which is DF + 1 = E0 (Number of scanlines on screen)).

    And that's pretty much it...

    You can be a bit more complexe and make different parts of the BG (or even FG) scroll at different rates, but the draw code isn't always friendly =P
     
  9. GenesisFan64

    GenesisFan64

    The bright side of the dark side. Member
    108
    0
    16
    2 questions:
    1. I removed the 2P split screen mode from my hack, but I can't still use that reserved VRAM area from the split screen mode ($500-$570)
      [​IMG]
      Where's the subroutine that handles the Split Screen scroll area and how do I make this area free?
      EDIT: Solved, by removing these lines:
      Code (ASM):
      1.         move.l  #$60000082,(a5)
      2.         move.w  #0,($C00000).l
    2. And where's the subroutine that handles the Sonic's/Tails' "Twirl" animations?, SonicAniData doesn't have pointers to them...
    Note: I'm using the Sonic 2 Nick Arcade disassembly.
     
  10. Retroman

    Retroman

    Member
    733
    2
    18
    What version of the Sonic 2 Rom you're hacking? I think you are using the wrong version of the Sonic 2 Rom but I dunno, most likely will be proved wrong by experienced hackers here.
     
  11. theocas

    theocas

    Tech Member
    346
    0
    16
    Read plz.

    Maybe it's because 2-Player mode uses that area as some kind of scroll buffer or something? I have no idea, but maybe if you look closer at the code you'll figure it out.
     
  12. Hanoch

    Hanoch

    Also known as TheKnock, Birashot Member
    491
    0
    0
    Israel
    everything
    In Sonic 2's Hill Top Zone there are scrolling clouds which are probably animated art. But, there are also big brown mountains and behind them the blue mountains. If its animated art too, can it also be done without using animated art?
     
  13. GT Koopa

    GT Koopa

    Member
    2,021
    18
    18
    Elgin, IL
    Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
    Do you mind if you could put that information on the wiki? Maybe FraGag and Markey you guys could combine it into one "how to" tutorial.

    Also, here's another question for people, a simple one. How long can a song on sonic 1 be? There has to be a limit, right?
     
  14. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    While there isn't a limit on how long a song can play for, the actual song data + the rest of the game needs to fit in at most 4MB to work without a mapper or some other modification.
     
  15. GT Koopa

    GT Koopa

    Member
    2,021
    18
    18
    Elgin, IL
    Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
    And there is no -public- tutorial to expand said game correct? I think I remember it being said that Megamix expanded their game to be twice as big, though I can't seem to find it via search.

    Still, I was talking about those individual music slots in the code, there had to be a cut off point of how many bytes there could be before it overflows into the next music slot. Maybe I don't know what I am talking about. I should read that music tutorial harder. Also if anything, Markey's bg scroll deformation description seems the most wiki tutorial worthy.
     
  16. nineko

    nineko

    I am the Holy Cat Tech Member
    6,315
    489
    63
    italy
    There is no actual limit to the size of a specific song (other than the obvious 4MB pointed out by Andlabs of course). However keep in mind that Sonic 1 uses 16-bit signed pointers within a song, so if any section of your song is longer than ~32768 bytes you'll need to concatenate more pointers in a row. For Sonic 2 and Sonic 3 this is even worse because you're limited to a Z80 bank. However, it's unrealistic for an SMPS song to be bigger than 10 kB, and even that would be a HUUUUUUUUUGE song, to give you a comparison most of the songs in sonineko are smaller than 5 kB and they're not even optimised SMPS, you're likely to get way smaller songs with xm4smps's algorithms.
     
  17. GT Koopa

    GT Koopa

    Member
    2,021
    18
    18
    Elgin, IL
    Flicky Turncoat DX, T.L.W.S. Vs M.G.W.
    So a 1-2 minute song in general for every zone is a good choice?
     
  18. StephenUK

    StephenUK

    Liquor in the front, poker in the rear Tech Member
    1,678
    0
    16
    Manchester, UK
    Quackshot Disassembly
    Just to expand on this area a bit more, I've written some deformation following what you said there, but now my background doesn't display, it just shows the transparent colour. IIRC, there is a way to set the background start position or something to that effect. How is this done?
     
  19. Selbi

    Selbi

    The Euphonic Mess Member
    1,500
    50
    28
    Northern Germany
    Sonic ERaZor
    About that deformation thing, I asked Markey about this once and also recieved a plausible answer, I'd like to hear what other's have to say though:


    If I for example increase the background moving speed in MZ with something like asl.w #1,d0, it technically works fine, but the problem is that after you walk a few inches to the right, the background "starts to replace itself":

    [​IMG]

    The question for me now is: Is there a (simple) way to fix this (for everything; this is just an example)? I was told to modify the draw code but... look at it.
     
  20. FraGag

    FraGag

    Tech Member
    The background and the foreground planes are 512x256 pixels. When the planes need to be redrawn, I believe by default it loads a block (16 pixels) wide or high at a time, but with deformation, a column will be "spread" all around the plane. If you don't have a repeating pattern, it may screw up like this. In Sonic 1 REV01, there were modifications to the drawing code for some zones, probably to fix this kind of problem. If you make "strips" that don't fit on 16-pixel boundaries, it'll be even harder because you'll have to write more code to "break" the blocks.