don't click here

Basic Questions & Answers thread

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

  1. Nomz

    Nomz

    Member
    17
    0
    0
    I'm a little confused here, and I'm slightly afraid of goofing anything up, so I've refrained from using any .exe files contained within the SA Tools Package.

    Any tutorials or help?

    Thanks.
     
  2. pablodrago

    pablodrago

    Member
    34
    0
    0
    BS AS
    The easy way, is just using the .bat files, so you can skip the issue of the the path name, the important part, is before the split put all files in the SADX folder, and also use a clean SADX.
     
  3. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,742
    338
    63
    SonLVL
    The tools in SA Tools are in separate folders for each version of the games supported. So you pick the folder that matches the game you want to edit, and copy the contents of the folder into the game's main folder (for Dreamcast, this is the folder with 1ST_READ.BIN, for PC, this is the folder with sonic.exe or sonic2app.exe). After running the .bat files to split data from the game, you can use the other tools, which are all described at the SA Tools wiki page.
     
  4. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    Jumping back to Sonic 2 for a minute...

    You all know the flipping blocks in the walls of Casino Night Zone, right? Well, I've been editing them and I just noticed... The very first frame isn't in the bin file with the rest! Any idea where that is?
    Also, what would be the most effective way to edit art that doesn't have mapping like that? Tile Layer Pro is a little dated. XD
     
  5. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,742
    338
    63
    SonLVL
    I'm not sure what you mean by that, all the frames look like they're there to me...

    As far as tile editors, I use YY-CHR myself. The .NET version has some nice features like a pattern editor (create a pattern 4 width 4 height vertical orientation to display the CNZ tiles), but there's a bit of untranslated Japanese in the UI. The original version is better translated. In either case, you have to select the 4bpp MSX format for MD games. Unfortunately neither version supports importing MD palettes directly, though a converter would be simple for me to make.
     
  6. Jimmy Hedgehog

    Jimmy Hedgehog

    Member
    1,728
    8
    18
    England - Slough
    Getting the motivation to continue old projects
    Another question here, bit of a long one with examples so bare with me. Is there a way to have an object load different art (though using the same mappings, as the art works using them) for an object based on a check? Like, simply loading the art from a different file? For example, say I gain a shield (which in the monitor code sets "#1,($FFFFFE2C).w"), which of course uses the art from "shield.bin". Would I be able to use art from, let's say "shield2.bin" if the shield flag was set to "#2,($FFFFFE2C).w" instead?

    Whereas in the case of the Character adding guide, changing what art the character used was simply down to replacing a section relating to "Art_Sonic" with this:
    Code (ASM):
    1.         cmpi.b  #$01, ($FFFFFFFE).w ; is the multiple character flag set to $01 (Metal Sonic)?
    2.         bne.s   SonicArtLoad        ; if not, load Sonic's art
    3.         lea (Art_MetalSonic).l,a1   ; load Metal Sonic's art
    4.         bra.s   ContLoadPLC     ; branch to rest of code
    5.  
    6. SonicArtLoad:
    7.         lea (Art_Sonic).l, a1   ; load Sonic's art
    8.  
    9. ContLoadPLC:
    Which then got the art location from these:
    Code (ASM):
    1. ; ---------------------------------------------------------------------------
    2. ; Uncompressed graphics    - Sonic
    3. ; ---------------------------------------------------------------------------
    4. Art_Sonic:  incbin  artunc\sonic.bin; Sonic
    5.         even
    6.  
    7. ; ---------------------------------------------------------------------------
    8. ; Uncompressed graphics    - Metal Sonic
    9. ; ---------------------------------------------------------------------------
    10. Art_MetalSonic: incbin  artunc\msonic.bin; Metal Sonic
    11.         even
    I can't seem to find a similar scenario for the shield's art, as searching for "Nem_Shield" only returns this:
    Code (ASM):
    1. Nem_Shield: incbin  artnem\shield.bin   ; shield
    2.         even
    And then this in a seperate PLC related file:
    Code (ASM):
    1.         dc.l Nem_Shield     ; shield
    2.         dc.w $A820
    From what I'm looking at and what I know, I can't seem to figure out a way to choose an art-file based on a check in the way you can with character art, and it has me pretty stumped. Any advice?
     
  7. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    Okay, so to make this question basic, I'm trying to make Tails fall slow if a certain flag is set. I've tried all sorts of things, and I haven't been able to get it to work. Is there something simple I'm overlooking?
     
  8. Beltway

    Beltway

    The most grateful Sonic fan of all time this week Member
    1,663
    182
    43
    Sega of Darkest Peru
    Artwork and classes
    Your mix in particular, which I happened to enjoy. Sorry for the late reply!
     
  9. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,202
    432
    63
    Japan
    The main issue with what you are looking for, is compression, the reason why Sonic's art is so successful at loading; is simply because his art is completely uncompressed within the ROM, hence, it's a simple transfer to VRAM, your shield art on the other hand; is compressed in the "Nemesis" format, which is a "huffman" varient of encoding and is quite time consuming during decompression, so you might very well find that your shield object will load onto screen before the art can decompress on time, resulting in glitched graphics for a short few frames.

    It is recommended to have your shield art either uncompressed in the ROM and transfered directly (just like Sonic's art), or, if you are anal about ROM space and wish to keep it down, then try a compression format that is quicker to decompress, likethe "Kosinski" format, which is a "Lempel–Ziv–Storer–Szymanski" (LZSS) format and is pretty fast as it deals mainly with uncompressed data, retraced backwards.

    I recommend uncompressed on the basis that; it's quicker to process, and easier to code, here's a simple example of transfering uncompressed shield art to VRAM at address 0020:

    Code (Text):
    1.         move.b  ($FFFFFE2C).w,d0            ; load shield flag
    2.         cmp.b   ($FFFFFF90).w,d0            ; has the shield changed?
    3.         beq NoShieldArt             ; if not, branch
    4.         move.b  d0,($FFFFFF90).w            ; update shield flag
    5.         lea (Shield1Art).l,a0           ; load uncompressed shield 1 data address
    6.         moveq   #$0F,d7                 ; set number of tiles to load (0x10 tiles)
    7.         cmpi.b  #$01,d0                 ; is shield 1 selected?
    8.         beq Shield01Art             ; if so, branch
    9.         lea (Shield2Art).l,a0           ; load uncompressed shield 2 data address
    10.         moveq   #$03,d7                 ; set number of tiles to load (0x04 tiles)
    11.  
    12. Shield01Art:
    13.         lea ($C00000).l,a5              ; load VDP data port
    14.         lea $04(a5),a6              ; load VDP address port
    15.         move.l  #$40200000,(a6)             ; set VDP write mode and address
    16.  
    17. LoadShieldArt:
    18.         move.l  (a0)+,(a5)              ; write 1st line of 8 pixels
    19.         move.l  (a0)+,(a5)              ; write 2nd line of 8 pixels
    20.         move.l  (a0)+,(a5)              ; write 3rd line of 8 pixels
    21.         move.l  (a0)+,(a5)              ; write 4th line of 8 pixels
    22.         move.l  (a0)+,(a5)              ; write 5th line of 8 pixels
    23.         move.l  (a0)+,(a5)              ; write 6th line of 8 pixels
    24.         move.l  (a0)+,(a5)              ; write 7th line of 8 pixels
    25.         move.l  (a0)+,(a5)              ; write last line of 8 pixels
    26.         dbf d7,LoadShieldArt            ; repeat until all tiles have been loaded to VRAM
    27.  
    28. NoShieldArt:
    I recommend placing this code after the lable "loc_D50:", that's in V-blank, so there's no chance of graphical glitches, now, the "40200000" you see is the VRAM write address, I've chosen VRAM 0020 as an example, 0020 is where the level art is usually loaded, so you may want to change that to a different VRAM address, also in this example, I've used RAM address FFFFFF90 to store a redraw flag, if you're using that RAM address for something else then you'll want to consider a different RAM address, otherwise that'll be fine, and finally, the numbers being moved to d7 act as a tile counter, they set how many tiles of your shield art to transfered, there's two of them, one for shield 1, and the other for shield 2, you'll want to change those too.

    I'll leave you to figure the rest out as I'm sure you'll want to experiment, but that would be the basic principle for loading uncompressed art.
     
  10. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,742
    338
    63
    SonLVL
    If you look in both Obj02_MdAir: and Obj02_MdJump: you'll see these lines right under the call to ObjectMoveAndFall:
    Code (ASM):
    1.     btst    #6,status(a0)   ; is Tails underwater?
    2.     beq.s   +       ; if not, branch
    3.     subi.w  #$28,y_vel(a0)  ; reduce gravity by $28 ($38-$28=$10)
    4. +
    What this does is test Tails' underwater flag (bit 6 in the status byte), and if it's set, subtracts $28 from his y_vel, to reduce the $38 gravity that ObjectMoveAndFall adds.
    You can add your code right near this (just remember to do both places) to check your flag and reduce gravity by an amount of your choosing. However, note that when Tails is underwater, his gravity is only $10, so if you subtract too much, he could end up with zero or negative gravity, unless you check for underwater in your code as well.
     
  11. Jimmy Hedgehog

    Jimmy Hedgehog

    Member
    1,728
    8
    18
    England - Slough
    Getting the motivation to continue old projects
    So, with tweaks done to it, is this the sort of thing I'm aiming for? ("68200003" is VRAM A820, which is the original shield's VRAM...I think. And I assume tiles refers to number of tiles in the art file, which is 36 for both so in hex that'd be 24).
    Code (ASM):
    1. LoadShield:
    2.         move.b  ($FFFFFE2C).w,d0            ; load shield flag
    3.         cmp.b   ($FFFFFF90).w,d0            ; has the shield changed?
    4.         beq NoShieldArt             ; if not, branch
    5.         move.b  d0,($FFFFFF90).w            ; update shield flag
    6.         lea (Art_Shield).l,a0           ; load uncompressed shield 1 data address
    7.         moveq   #$24,d7                 ; set number of tiles to load (0x10 tiles)
    8.         cmpi.b  #$01,d0             ; is shield 1 selected?
    9.         beq Shield01Art             ; if so, branch
    10.         lea (Art_Shield2).l,a0          ; load uncompressed shield 2 data address
    11.         moveq   #$24,d7                 ; set number of tiles to load (0x04 tiles)
    12.  
    13. Shield01Art:
    14.         lea ($C00000).l,a5              ; load VDP data port
    15.         lea $04(a5),a6              ; load VDP address port
    16.         move.l  #$68200003,(a6)             ; set VDP write mode and address
    17.  
    18. LoadShieldArt:
    19.         move.l  (a0)+,(a5)              ; write 1st line of 8 pixels
    20.         move.l  (a0)+,(a5)              ; write 2nd line of 8 pixels
    21.         move.l  (a0)+,(a5)              ; write 3rd line of 8 pixels
    22.         move.l  (a0)+,(a5)              ; write 4th line of 8 pixels
    23.         move.l  (a0)+,(a5)              ; write 5th line of 8 pixels
    24.         move.l  (a0)+,(a5)              ; write 6th line of 8 pixels
    25.         move.l  (a0)+,(a5)              ; write 7th line of 8 pixels
    26.         move.l  (a0)+,(a5)              ; write last line of 8 pixels
    27.         dbf d7,LoadShieldArt            ; repeat until all tiles have been loaded to VRAM
    28.  
    29. NoShieldArt:
    And then I went and took out the "Nem_Shield" part and put this under "Art_Sonic" (I decompressed the art files in "The Sega Data Compressor" and put then in the artunc folder).
    Code (ASM):
    1. ; ---------------------------------------------------------------------------
    2. ; Uncompressed graphics - Shields
    3. ; ---------------------------------------------------------------------------
    4. Art_Shield: incbin  artunc\shield.bin   ; shield
    5.         even
    6. Art_Shield2:    incbin  artunc\shield2.bin  ; shield
    7.         even
    After this, is it simply a case of replacing the jump to "DisplaySprite" in this part below with one to the new "LoadShield", or is there a bit more to it?
    Code (ASM):
    1. Obj38_Shield:               ; XREF: Obj38_Index
    2.         tst.b   ($FFFFFE2D).w   ; does Sonic have invincibility?
    3.         bne.s   Obj38_RmvShield ; if yes, branch
    4.         tst.b   ($FFFFFE2C).w   ; does Sonic have shield?
    5.         beq.s   Obj38_Delete    ; if not, branch
    6.         move.w  ($FFFFD008).w,8(a0)
    7.         move.w  ($FFFFD00C).w,$C(a0)
    8.         move.b  ($FFFFD022).w,$22(a0)
    9.         lea (Ani_obj38).l,a1
    10.         jsr AnimateSprite
    11.         jmp DisplaySprite
     
  12. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,202
    432
    63
    Japan
    The VRAM value 68200003 is E820, what you want is the VRAM value 68200002 for A820.

    Correct, except, you'll want the numbers as 23 in the code, as 0 counts as one tile:

    Code (Text):
    1.         moveq   #$23,d7                 ; set number of tiles to load (0x24 tiles)
    That object code can stay exactly as it is, what's important though is...

    So your art loading code:

    You'll put that directly after the lable "loc_D50:", like so:

    Code (Text):
    1.         ...
    2.         ...
    3.         move.w  #$7000,(a5)
    4.         move.w  #$83,($FFFFF640).w
    5.         move.w  ($FFFFF640).w,(a5)
    6.         move.b  #0,($FFFFF767).w
    7.  
    8. loc_D50:
    9.  
    10. LoadShield:
    11.         move.b  ($FFFFFE2C).w,d0            ; load shield flag
    12.         cmp.b   ($FFFFFF90).w,d0            ; has the shield changed?
    13.         beq NoShieldArt             ; if not, branch
    14.         move.b  d0,($FFFFFF90).w            ; update shield flag
    15.         lea (Art_Shield).l,a0           ; load uncompressed shield 1 data address
    16.         moveq   #$24,d7                 ; set number of tiles to load (0x10 tiles)
    17.         cmpi.b  #$01,d0             ; is shield 1 selected?
    18.         beq Shield01Art             ; if so, branch
    19.         lea (Art_Shield2).l,a0          ; load uncompressed shield 2 data address
    20.         moveq   #$24,d7                 ; set number of tiles to load (0x04 tiles)
    21.  
    22. Shield01Art:
    23.         lea ($C00000).l,a5              ; load VDP data port
    24.         lea $04(a5),a6              ; load VDP address port
    25.         move.l  #$68200003,(a6)             ; set VDP write mode and address
    26.  
    27. LoadShieldArt:
    28.         move.l  (a0)+,(a5)              ; write 1st line of 8 pixels
    29.         move.l  (a0)+,(a5)              ; write 2nd line of 8 pixels
    30.         move.l  (a0)+,(a5)              ; write 3rd line of 8 pixels
    31.         move.l  (a0)+,(a5)              ; write 4th line of 8 pixels
    32.         move.l  (a0)+,(a5)              ; write 5th line of 8 pixels
    33.         move.l  (a0)+,(a5)              ; write 6th line of 8 pixels
    34.         move.l  (a0)+,(a5)              ; write 7th line of 8 pixels
    35.         move.l  (a0)+,(a5)              ; write last line of 8 pixels
    36.         dbf d7,LoadShieldArt            ; repeat until all tiles have been loaded to VRAM
    37.  
    38. NoShieldArt:
    39.         move.w  #0,($A11100).l
    40.         movem.l ($FFFFF700).w,d0-d7
    41.         movem.l d0-d7,($FFFFFF10).w
    42.         movem.l ($FFFFF754).w,d0-d1
    43.         ...
    44.         ...
    Now unless there's something we've missed, it should in theory, work well, get back to me once you've tried it out.
     
  13. Jimmy Hedgehog

    Jimmy Hedgehog

    Member
    1,728
    8
    18
    England - Slough
    Getting the motivation to continue old projects
    Oh, DIRECTLY under, I for some reason thought you meant under what was already in loc_D50. Didn't actually try it though since I didn't have much time to build and test but I imagine that would've gone horribly wrong XD I also for some reason keep forgetting tile 0 counts as the first tile...anyway, thank you very much for the corrections and thanks a bunch for the help! Worked without any issues ^_^

    [​IMG]

    I originally had the second shield type load an edited invincibility art, since my hack at current isn't using invincibility, but figured it'd be better to get it to literally load the shield object with a different art file in the end just incase I a) Decide to use invincibility again or b) Want to add more types of shield.
     
  14. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    Thanks very much, Mainmemory. This really helped, and I actually learned something really useful; that is, distinguishing between the different types of conditional branches. Some would argue I should've known that befor going in, but meh, I like to learn by doing.

    I appreciate everyone's help. What I was doing is essentially giving Tail's a basic flight ability in Sonic 2, and I got it working minus the physics being somewhat off. I also limited it rather strictly as the game wasn't designed around it so it's quite broken.

    with that said, my question is, would I have been better off porting Sonic 3's code for it in, and if so, how much easier/harder would that have been that building off of what was already there?

    EDIT: While I'm at it, do you know anything about editing the background scrolling in levels? Anyone?
     
  15. Jimmy Hedgehog

    Jimmy Hedgehog

    Member
    1,728
    8
    18
    England - Slough
    Getting the motivation to continue old projects
    Another random question here, how would I have Sonic 1's "Life Icon" use the 1-Up Monitor Art instead? (Since it's the same thing). Those 4 art tiles the life icon are using would really come in handy for getting something working.

    EDIT: Or the alternative, have the 1-up monitor icon tiles be/stay on screen where the life icon normally goes. Unless that's how it's normally done anyway, then it's not really an alternative XD
     
  16. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    So.. I don't know if this is really a "Basic" question, but does anyone know anything about adding an actual act 3 properly into a zone in Sonic 2? If so, what if that third act should be like Scrap Brain Zone in that it used a different set of data?
     
  17. Jimmy Hedgehog

    Jimmy Hedgehog

    Member
    1,728
    8
    18
    England - Slough
    Getting the motivation to continue old projects
    Adding on to this, I'm at the moment life-iconless (though not fussed right now) since I now have the minutes numbers there...which work perfectly! Except...sometimes when loading Green Hill 1 (starting the game basically) they aren't there...but appear when the time goes up a second to 00:01. Leading on from this, when I take longer than a minute, whatever's in the "minutes" tiles gets carried over to the next stage. Again though, they revert after the first second. For example, if the previous level took 1 minute, it'd say "01:00" until "00:01", if I took 7 minutes, "07:00" until 1 seconds passes, etc.

    So essentially, there's some sort of loading delay for the minutes figures. Not really sure what to do here. Other than literally moving the life icon mapping to where the minutes would go (as of course that's the VRAM it's using), this is the only change I've made to it:

    Code (ASM):
    1. loc_1C734:
    2.         move.l  #$7A800003,d0
    3.         moveq   #0,d1
    4.         move.b  ($FFFFFE23).w,d1 ; load minutes
    5.         bsr.w   Hud_Secs
    6.         move.l  #$5EC00003,d0
    7.         moveq   #0,d1
    8.         move.b  ($FFFFFE24).w,d1 ; load seconds
    9.         bsr.w   Hud_Secs
    The only changes from the original here being of course, the VRAM address and that first "bsr.w Hud_Secs" which was originally "Hud_Mins", which I needed to change to have it actually update both of the 0s I'm pretty sure (allowing it to go up to and show 10 and above).
     
  18. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,742
    338
    63
    SonLVL
    It would be much easier to make four acts than three, and either way you'd have to expand a bunch of tables and alter the formula used for indexing those tables. As for act 3 using different art, it's as simple as finding the code that loads the data you want, and adding an exception to make it load a specific set of data in that level/act.

    It sounds like what you're after might be easier with the MTZ3 solution: make a new zone that calls itself act 3 on the title card/score tally.
     
  19. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    I was hoping to avoid that because all the zones in Sonic 2 proper are already (most likely) going to be used, but I guess extending the Zone Tables won't be the worst crime I've committed in Sonic Hacking. especially since Sonic 2 itself did it.

    So, I asked this before and I think it got missed; does anyone here know how the background layer scrolling works well enough to explain it to me? I've got a level almost finished, but the background has buildings that are moving all at different speeds, and it quite irks me.
     
  20. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Okay, quick question here. Although I fear that the answer would be "Port the S3K camera manager over".


    Does anyone know how to make the whole screen redraw itself without making it flash in Sonic 2?


    For example, you know in S3 at the end of Angel Island 2 with that plane dropping the bombs? Sonic runs and when reaches a certain distance, Sonic and Tails and the plane (and bombs) and the camera goes back really quick. The long time you're running is actually quite short, it just keeps resetting itself, you just don't notice it.

    I've got a similar thing in my hack going and it works; only problem is when it pulls this stunt off, the screen flashes (only 1 frame) but it is noticable.

    This happens when the RAM dirty_flag is set. It then obviously refreshes the whole screen, but causes this flash. Now, if I don't move 1 to dirty_flag, it still works and there is no flash, but then if you're moving vertically at all, the tiles get glitched a little bit, and will remain glitched untl it goes off-screen (going back to it and it's fine). If just moving horizontly, its all good, but no doubt when someone comes to play this, they'll jump and notice it.


    Any ideas?