Basic Questions & Answers thread

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

  1. AppleSauce

    AppleSauce

    It's now illegal to use your meme! Member
    44
    2
    8
    So I have been romhacking Sonic 1 to implement a new character, and yellow numbers appear on the jump sprites. Anyone got a fix?
     
  2. Ralakimus

    Ralakimus

    Mommy says I'm just built different Tech Member
    622
    254
    63
    In Sonic 1, the way the player's sprite graphics are loaded is that it takes the current sprite frame, loads it into an area of main memory, which is then loaded into video memory. That area of main memory has a fixed size, so that means if you have too many tiles in a frame, then it will only load what it can fit in there.

    The yellow numbers are the points graphics that display when you destroy a badnik. They are placed right after Sonic's graphics area in video memory. Due to the extra tiles not being loaded over into that area, the areas of the sprite that should have those extra unloaded tiles appear as those numbers.

    There are 2 fixes that come to mind. You can either expand the size of the sprite graphics area in main memory, or you can use the DMA queue, which basically allows you to easily load graphics straight from ROM into video memory without having to store the graphics in main memory first or having to deal with a limited space for loading the player graphics in. I personally recommend the second option. There's even a Sonic 1 implementation in part 3 of the spindash porting guide in the wiki, so it shouldn't be difficult to implement.

    Now, because with this you are allowing the extra tiles to load in video memory, they will overwrite the points graphics, so they will have to be relocated to another spot in video memory.
     
  3. Aerosol

    Aerosol

    Not here. Moderator
    10,947
    304
    63
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    [​IMG]

    So I'm finally using the object code Markey provided 300 years ago (thanks Markey!). I get how it works and have it up and running in Sonic 1. It's a lot of fun, and I've played with it a bit.

    I'm trying to port it to Sonic 2 now and uh, I can't figure out how to import new art for a new object.

    Code (Text):
    1. move.l    #Obj17_MapUnc,mappings(a0)
    2. move.w  #make_art_tile(ArtTile_ArtNem_Pole,0,0),art_tile(ao)
    3.  
    4. #And then much later near the end of the rom, right before the "align $100" that says it's free space.
    5.  
    6.     even
    7. ArtNem_Pole:    BINCLUDE "art/nemesis/Pole.bin"
    8.     even
    9. Obj17_MapUnc: BINCLUDE "mappings/sprite/newObj17.bin"
    10.  
    11. #And in constants
    12.  
    13. ArtTile_ArtNem_Pole = $03BE
    Forgive any whitespacing issues you see, I'm retyping this from another machine. Where have I screwed up?
     
  4. MarkeyJester

    MarkeyJester

    A D V A N C E Resident Jester
    2,098
    229
    43
    Japan
    Open "newObj17.bin" with a hex editor, and share what the values are inside of it,

    I have a... ...feeeling.
     
  5. Aerosol

    Aerosol

    Not here. Moderator
    10,947
    304
    63
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    Sure thing

    Code (Text):
    1.  
    2. 00  00 02 00 02 f8 0c 00 00 00 00 ff f0 00 00 00 04 00 02 ff f0
    3.  
     
  6. MarkeyJester

    MarkeyJester

    A D V A N C E Resident Jester
    2,098
    229
    43
    Japan
    Usually the wild sprites are a sign the sprite rendering routine is given a rouge list of random crap.

    Given the mappings you've shared are fine, then it has to be something within the object's routine itself. It could be the map frame ID is wrong, or perhaps some wrong subroutine calls, there is no way of telling from the above information.
     
  7. Aerosol

    Aerosol

    Not here. Moderator
    10,947
    304
    63
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    Thanks Markey

    The changes I listed above are the only changes I've made. Obj17 is the unused helix spike object from Sonic 1, at loc_10324. The rest of this object's code hasn't been touched, including the other times it tries to move the helix graphics to a0. Maybe that's it?
     
  8. MarkeyJester

    MarkeyJester

    A D V A N C E Resident Jester
    2,098
    229
    43
    Japan
    That's why then. The spike log changes the frame ID rotating around from 00 to 07 in a loop. You only have one frame (map frame 00), you need another 7 (01 to 07).
     
  9. Aerosol

    Aerosol

    Not here. Moderator
    10,947
    304
    63
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    [​IMG]
    Well I went back into Flex2 and cloned the sprite a few times to fill out the animation and got this. It no longer softlocks, so that's a plus.

    Quick note: This specific look is a result of me changing the existing label in Obj17 to point to my mappings file. I changed it back to the way I quoted up above but still had a similar issue. Just different tiles showed up (Coconuts ones, actually).
     
  10. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,603
    198
    43
    SonLVL
    Did you add the pole graphics to the PLC list?
     
  11. Aerosol

    Aerosol

    Not here. Moderator
    10,947
    304
    63
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    [​IMG]

    Nope, didn't know I had to do something like that. It's there now, it's that weird pole looking thing.

    Code (Text):
    1. PlrList_Ehz1: plrlistheader
    2.     plreq ArtTile_ArtNem_Waterfall, ArtNem_Waterfall
    3.     plreq ArtTile_ArtNem_EHZ_Bridge, ArtNem_EHZ_Bridge
    4.     plreq ArtTile_ArtNem_Buzzer_Fireball, ArtNem_HtzFireball1
    5.     plreq ArtTile_ArtNem_Buzzer, ArtNem_Buzzer
    6.     plreq ArtTile_ArtNem_Coconuts, ArtNem_Coconuts
    7.     plreq ArtTile_ArtNem_Masher, ArtNem_Masher
    8.   plreq ArtTile_ArtNem_Pole, ArtNem_Pole
    9. PlrList_Ehz1_End
    So that's what the PLC list looks like for EHZ now. It's fine now, but some frames look like the above. What else have I done wrong? I'd like to avoid this in the future :V

    And yea the palette is wrong, but I'll figure that out later.
     
  12. AppleSauce

    AppleSauce

    It's now illegal to use your meme! Member
    44
    2
    8
    Alright, so how would I expand the sprite graphics in the main memory? It sounds a lot easier than the second fix and I'm a lazy piece of crap.
     
  13. Ralakimus

    Ralakimus

    Mommy says I'm just built different Tech Member
    622
    254
    63
    Just gonna steal this from an SSRG MarkeyJester made...
    Ultimately, though, adding a DMA queue will be better for you in the long run as it saves spaces in memory and is more flexible.

    You will still need to move the points graphics. Regardless of how you approach it, they will still get overwritten by the additional tiles being loaded for the player's sprite.

    @Aerosol It may help to show more of the object code or the mappings data again, because it still looks like there's still some kind of mappings error or sprite frame error.
     
    Last edited: Jun 12, 2020
  14. E-122-Psi

    E-122-Psi

    Member
    2,215
    423
    63
    Is anyone experienced with adding DPLCs to objects.

    I've tried adding DPLC to a projectile of mine to save tile space, but the issue is that now the object doesn't delete when the routine commands it to:

    Code (Text):
    1.  
    2.     lea    (Ani_Laser).l,a1
    3.     jsr    AnimateSprite
    4.     bsr.w    LoadProjDynPLC
    5.     jsr    (TouchResponse).l ;Touch_KillEnemy, Touch_Monitor
    6.     jmp    DisplaySprite  
    7.  
    8. Obj_Blob_Destroy:
    9.     clr.b    ($FFFFFFA4).w    ; clear flag  
    10.     jmp DeleteObject
    11.  
    12.  
    13. ; loc_1D1AC:
    14. LoadProjDynPLC:
    15.     moveq    #0,d0
    16.     move.b    mapping_frame(a0),d0                ; load frame number
    17. ; loc_1D1B2:
    18. LoadProjDynPLC_Part2:
    19.     cmp.b    objoff_30(a0),d0
    20.     beq.w    return_ProjDPLC
    21.     move.b    d0,objoff_30(a0)
    22.     lea    (MapRUnc_Proj).l,a2
    23.     add.w    d0,d0
    24.     adda.w    (a2,d0.w),a2
    25.     move.w    (a2)+,d5
    26.     subq.w    #1,d5
    27.     bmi.s    return_ProjDPLC
    28.     move.w    #$9280,d4                        ; ****** Here
    29. ; loc_1D1D2:
    30. PPLC_ReadEntry:
    31.     moveq    #0,d1
    32.     move.w    (a2)+,d1
    33.     move.w    d1,d3
    34.     lsr.w    #8,d3
    35.     andi.w    #$F0,d3
    36.     addi.w    #$10,d3
    37.     andi.w    #$FFF,d1
    38.     lsl.l    #5,d1
    39.     addi.l    #ArtUnc_Proj,d1
    40.     move.w    d4,d2
    41.     add.w    d3,d4
    42.     add.w    d3,d4
    43.     jsr    (QueueDMATransfer).l
    44.     dbf    d5,PPLC_ReadEntry                        ; repeat for number of entries
    45.  
    46. return_ProjDPLC:
    47.     rts
    48.  
    49. ; ===========================================================================
    50. Ani_Laser:
    51.     dc.w laser0-Ani_Laser
    52. laser0:    dc.b 1,1,2,3,$FF
    53.     even
    54.  
    55. Map_Obj4D:    include "ProjMap_Unc.asm"
    56.  even
    57. MapRUnc_Proj:    include "ProjPLC_Unc.asm"
    58.  even
    59.  
    Any idea what I'm doing wrong here?
     
  15. Aerosol

    Aerosol

    Not here. Moderator
    10,947
    304
    63
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    Hitaxas pitched in. Turns out the object code trying to load sub objects is what screwed it up. He went over the existing code and showed me what he stripped out and now my pole is displaying in game properly. Neat.

    Aaaand I thought I posted this a while ago but I forgot to hit reply. Sorry @Ralakimus :V

    There's a few more objects I want to add though, and apparently I have precious little tile space to add them in. Is there some...thing I can port from Sonic 3 to Sonic 2 to free up room or something? I know I can overwrite the letters used during the Sonic and Tails screen but I (ironically) want something a bit less hacky. A more complete solution to the space problem.
     
    Last edited: Jun 12, 2020
  16. E-122-Psi

    E-122-Psi

    Member
    2,215
    423
    63
    Ah right sorry:

    Code (Text):
    1.  
    2. Obj4D:
    3.     moveq    #0,d0
    4.     move.b    $24(a0),d0
    5.     move.w    Obj_Blob_Index(pc,d0),d0
    6.     jmp    Obj_Blob_Index(pc,d0)
    7.  
    8. Obj_Blob_Index:
    9.     dc.w    Obj_Blob_Init-Obj_Blob_Index
    10.     dc.w    Obj_Blob_Move-Obj_Blob_Index
    11.     dc.w    Obj_Blob_Destroy-Obj_Blob_Index
    12.  
    13. Obj_Blob_Init:
    14.     move.l    #Map_Obj4D,mappings(a0) ; ($C)
    15.     move.w    #$2,priority(a0)
    16.     move.b    #$8,width_pixels(a0)
    17.     move.w  #$9280/$20,art_tile(a0)
    18.     move.b    #$4,render_flags(a0)
    19.     move.b    #$4,y_radius(a0) ; $A
    20.     lea    (MainCharacter).w,a1
    21.         cmpi.b  #$25,anim(a1)    ; is NICOLE attack being performed?
    22.         beq.w   MinThrow           ; if not, branch
    23.         cmpi.b  #$30,anim(a1)    ; is NICOLE attack being performed?
    24.         beq.w   MaxThrow           ; if not, branch
    25. MinThrow:
    26.     move.w     #$2C0,x_vel(a0)                ; speed of laser
    27.     move.w     #-$430,y_vel(a0)                ; speed of laser
    28.     move.b    #$38,$30(a0)                 ; distance laser will travel
    29.     bra.w    Obj4D_Cont
    30. MaxThrow:
    31.     move.w     #$740,x_vel(a0)                ; speed of laser
    32.     move.w     #-$490,y_vel(a0)                ; speed of laser
    33.     move.b    #$38,$30(a0)                 ; distance laser will travel
    34.  
    35. Obj4D_Cont:
    36.     btst    #0,($FFFFB001).w
    37.     beq.s +
    38.     neg.w    x_vel(a0)
    39.     add.w    #$40,x_pos(a0)
    40.     bra.w    ++
    41. +
    42.     sub.w    #$40,x_pos(a0)
    43. +
    44.     move.w #$9280,d2
    45.     addq.b    #2,$24(a0) ;
    46.  
    47.  
    48. Obj_Blob_Move:
    49.     cmp.b    #0,$30(a0)
    50.     bne.w    ContCounter
    51.     bra.w    Obj_Blob_Destroy
    52.  
    53. ContCounter:
    54.     sub.b     #$1,$30(a0)
    55.     bsr.w    ObjectMoveAndFall
    56.     move.b    $40,$20(a0)    ; lol
    57.  
    58.     clr.w d0
    59.     move.b $1A(a0),d0
    60.     asl.w #$1,d0     ; *2 for correct offset  
    61.     lea (ArtUnc_Proj).l,a1
    62.     adda.w (a1,d0.w),a1
    63.     move.w #$9280,d2
    64.  
    65.     lea    (Ani_Laser).l,a1
    66.     jsr    AnimateSprite
    67.     bsr.w    LoadProjDynPLC
    68.     jsr    (TouchResponse).l ;Touch_KillEnemy, Touch_Monitor
    69.     jmp    DisplaySprite  
    70.    
    71. Obj_Blob_Destroy:
    72.     clr.b    ($FFFFFFA4).w    ; clear flag    
    73.     jmp DeleteObject
    74.  
    75.  
    76. ; loc_1D1AC:
    77. LoadProjDynPLC:
    78.     moveq    #0,d0
    79.     move.b    mapping_frame(a0),d0                ; load frame number
    80. ; loc_1D1B2:
    81. LoadProjDynPLC_Part2:
    82.     cmp.b    objoff_30(a0),d0
    83.     beq.w    return_ProjDPLC
    84.     move.b    d0,objoff_30(a0)
    85.     lea    (MapRUnc_Proj).l,a2
    86.     add.w    d0,d0
    87.     adda.w    (a2,d0.w),a2
    88.     move.w    (a2)+,d5
    89.     subq.w    #1,d5
    90.     bmi.s    return_ProjDPLC
    91.     move.w    #$9280,d4                        ; ****** Here
    92. ; loc_1D1D2:
    93. PPLC_ReadEntry:
    94.     moveq    #0,d1
    95.     move.w    (a2)+,d1
    96.     move.w    d1,d3
    97.     lsr.w    #8,d3
    98.     andi.w    #$F0,d3
    99.     addi.w    #$10,d3
    100.     andi.w    #$FFF,d1
    101.     lsl.l    #5,d1
    102.     addi.l    #ArtUnc_Proj,d1
    103.     move.w    d4,d2
    104.     add.w    d3,d4
    105.     add.w    d3,d4
    106.     jsr    (QueueDMATransfer).l
    107.     dbf    d5,PPLC_ReadEntry                        ; repeat for number of entries
    108.  
    109. return_ProjDPLC:
    110.     rts
    111.  
    112. ; ===========================================================================
    113. Ani_Laser:
    114.     dc.w laser0-Ani_Laser
    115. laser0:    dc.b 1,1,2,3,$FF
    116.     even
    117.  
    118. Map_Obj4D:    include "ProjMap_Unc.asm"
    119.  even
    120. MapRUnc_Proj:    include "ProjPLC_Unc.asm"
    121.  even
     
  17. Fred

    Fred

    Taking a break Oldbie
    1,563
    115
    43
    Portugal
    Sonic 3 Unlocked
    Right here you're decrementing $30(a0) and bailing out when it gets down to zero. However...
    Right here you're using $30(a0) to store the last queued PLC frame. If frame zero never gets queued, then we'll continue taking the branch to ContCounter forever.

    Just move either of these to a different byte and you should be good.
     
  18. Ralakimus

    Ralakimus

    Mommy says I'm just built different Tech Member
    622
    254
    63
    One thing that comes to mind is having the shield and invincibility stars art be uncompressed, have both objects share the same VRAM space, like in S3K, since neither of them show up simultaneously, so it just makes sense to only have the current powerup graphics loaded at one time. Bonus points if you have them use DPLCs so only the currently shown art is loaded into VRAM at once.

    I don't think it'll save a whole lot of space, but it certainly helps, although I think this would only work out in 1P mode, since it is possible for Sonic to have a shield and Tails to have invincibility and vice versa in 2P mode. Maybe someone who has more experience working with Sonic 2 can chime in.

    You can also pull a Sonic CD and split off the level into sections, and only load the graphics for certain objects that are used in each section.
     
    Last edited: Jun 12, 2020
  19. E-122-Psi

    E-122-Psi

    Member
    2,215
    423
    63
    Ah that seems to have done it. Thanx. :d
     
  20. Aerosol

    Aerosol

    Not here. Moderator
    10,947
    304
    63
    Not where I want to be.
    Sonic (?): Coming summer of 2055...?
    I actually wouldn't mind ripping out 2p mode entirely at some point, so if doing this breaks anything I'm not worried about it