don't click here

Basic Questions & Answers thread

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

  1. Devon


    The spider man is having me for dinner tonight Tech Member
    Because it's actually part of the Sonic 3 alone data, not Sonic & Knuckles. See "Lockon S3/LockOn Data.asm"
  2. SEGACast


    Thanks. I think I did what you said correctly, but there's another error that has come up now.


    I checked the file, but it doesn't seem like anything is out of place. Could it be that the issue stems from what I did with the LockOn file, or something else? This has been more difficult than I thought it'd be. :ohdear:

    Here's the code I edited, incase you want to look at it.

    Code (Text):
    1. ArtUnc_SStageTails:
    2.         binclude "General/Sprites/Tails/Art/SStage Tails.bin"
    3.         even
    4. Map_SStageTails:
    5.         include "General/Sprites/Tails/Map - SStage Tails.asm"
    7. PLC_SStageTails:
    8.     include "General/Sprites/Tails/DPLC - SStage Tails.asm"
    10. ArtUnc_SStageTailstails:
    11.         binclude "General/Sprites/Tails/Art/SStage Tails tails.bin"
    12.         even
    13. Map_SStageTailstails:
    14.         include "General/Sprites/Tails/Map - SStage Tails tails.asm"
    16. PLC_SStageTailstails:
    17.     include "General/Sprites/Tails/DPLC - SStage Tails Tails.asm"
  3. Devon


    The spider man is having me for dinner tonight Tech Member
    Judging from what you posted about PLC_SStageTailstails, it already has the "PLC_SStageTailstails" inside the DPLC file. So, you can remove label, or go into the DPLC file and change all instances of "PLC_SStageTailstails" into something else.
  4. Nik Pi

    Nik Pi

    I had a questions:
    1) How does works wall recoil animation in Sonic 2 betas?
    When you bonk to wall- you start a 2 animations; first- it's just a one sprite, but how does second animation is started?
    2) I accidentally delete some animated tiles from EHZ (animated cave tiles), and now it looks incorrectly..
    How I can restore it?
    Last edited: Aug 16, 2022
  5. Hitaxas


    Retro 80's themed Twitch streamer ( on hiatus) Member
    In the Nick Arcade disassembly, this is labeled as
    Code (Text):
    1. Sonic_WallRecoil

    What it does is actually really simple:

    Code (Text):
    1. Sonic_WallRecoil:            ; CODE XREF: Sonic_Move+180j
    2.                     ; Sonic_Move+1A0j
    3.         move.b    #4,$24(a0)            ; set Sonic's routine to 4
    4.         bsr.w    Sonic_ResetOnFloor     ; call for Sonic's ResetOnFloor function
    5.         bset    #1,$22(a0)              ; set in air status bit
    6.         move.w    #$FE00,d0             ; move $FE00 into destination 0
    7.         tst.w    $10(a0)                ; test for x velocity
    8.         bpl.s    Sonic_WallRecoil_Right ; if positive, the wall is to the right
    9.         neg.w    d0                     ; otherwise, the wall is to the left
    11. Sonic_WallRecoil_Right:            ; CODE XREF: Sonic_Move+1D2j
    12.         move.w    d0,$10(a0)            ; move $FE00 from destination 0 into Sonic's x_vel, giving him some backwards momentum
    13.         move.w    #$FC00,$12(a0)        ; set Sonic's y velocity to $FC00, moving him up
    14.         move.w    #0,$14(a0)            ; set Sonic's inertia to 0
    15.         move.b    #$A,$1C(a0)           ; play Sonic's recoil animation
    16.         move.b    #1,$25(a0)            ; set Sonic's secondary routine to 1
    17.         move.w    #$A3,d0    ; '�'     ; prepare sound effect
    18.         jsr    (PlaySound_Special).l    ; play sound effect
    19.         rts
    20. ; End of function Sonic_Move

    This code is called by
    Code (Text):
    1. Sonic_CheckWallsOnGround
    or, in the NA disassembly:
    Code (Text):
    1. loc_FE8E
    Code (Text):
    3. loc_FE8E:                ; CODE XREF: Sonic_Move+14Cj
    4.        move.b    $26(a0),d0
    5.        add.b    d1,d0
    6.        move.w    d0,-(sp)
    7.        bsr.w    Sonic_WalkSpeed
    8.        move.w    (sp)+,d0
    9.        tst.w    d1
    10.        bpl.s    locret_FEF6
    11.        asl.w    #8,d1
    12.        addi.b    #$20,d0    ; ' '
    13.        andi.b    #$C0,d0
    14.        beq.s    loc_FEF2
    15.        cmpi.b    #$40,d0    ; '@'
    16.        beq.s    loc_FED8
    17.        cmpi.b    #$80,d0
    18.        beq.s    loc_FED2
    19.        cmpi.w    #$600,$10(a0)   ; Is Sonic running fast enough to recoil off a wall?
    20.        bge.s    Sonic_WallRecoil ; if speed = $600 or greater, branch
    21.        add.w    d1,$10(a0)
    22.        bset    #5,$22(a0)
    23.        move.w    #0,$14(a0)
    24.        rts
    Hopefully that helps you understand how it works.

    Easiest way is to reacquire the appropriate files, and replace the files you messed with. It's as simple as that.
  6. Nik Pi

    Nik Pi

    I already FIND the way to port code to final S2 in February. I need to find the way to port animation
    I change too much, for using not changed files.
    Anyway, thanks for responding

    EDIT: I find that guide, that I write about recoil:
  7. Hitaxas


    Retro 80's themed Twitch streamer ( on hiatus) Member
    Adding animations is simple. All you need is a sprite sheet, and knowledge on how to import sprites using Flex 2 or SonMapED. Then you need to add the animation to Sonic's animation script, and call for that new animation. The first animation being the knock back animation, which then goes to the next, which is the laying on floor in a daze animation.

    Such things are simple.

    As an example, you can see here in Sonic's "stop" animation:
    Code (Text):
    2. SonAni_Stop:    dc.b   5,$D2,$D3,$D4,$D5,$FD,  0 ; halt/skidding animation
    Byte $FD is telling the script that the animation should change to animation 0 (walking/running) after it is complete.

    You can do the same thing for the recoil.
    Last edited: Aug 16, 2022
  8. Nik Pi

    Nik Pi

    Ok, thanks. I'll try it :)
  9. Hexinator


    Hex Member
    Hello! i am making another hack, which makes sonic not roll and not roll while jumping, but when jumping on an enemy it causes that enemy to no damage me, whats a fix to this? i removed the Touch_KillEnemy Function, using hivebrain disasm (sonic 1)
  10. the easiest way is to delete the sonic_roll function
    you mean it doesn't damage you?
    i haven't touched a sonic game in a long time so idk the code anymore but probably (not 100% sure), this is why:
    pretty sure that you should have that label
  11. Hexinator


    Hex Member
    Thank you! i managed to restore that label and add HurtSonic being executed when it launches, one thing i forgot to tell you is that rings are no longer collectable, so thats why i did that
    Also why is my SHC Expo Entry the only one? :
    Last edited: Aug 28, 2022
  12. Devon


    The spider man is having me for dinner tonight Tech Member
    Because the Contest/Expo isn't open yet to the public. You can only see and edit your own entries in the mean time.
  13. I'm attempting to write a simple VRAM test for the Mega Drive/Genesis (more on that below), but while I have the results readout down, I need some help with the actual implementation.

    Code (Text):
    2. TestVRAM:
    3.        dma_fill   0,$FFFF,0            ; clear VRAM
    5.    .waitforDMA1:
    6.        move.w   (a5),d1                   ; get status register (a5= vdp_control_port)
    7.        btst   #1,d1                   ; is dma_fill still running?
    8.        bne.s   .waitforDMA1               ; if yes, branch
    10.        dma_fill   1,$FFFF,0            ; fill entire VRAM with 1s
    12.    .waitforDMA2:
    13.        move.w   (a5),d1                   ; get status register
    14.        btst   #1,d1                   ; is dma_fill still running?
    15.        bne.s   .waitforDMA2           ; if yes, branch
    18.        move.l   #$00000000,(a5)           ; set VDP to VRAM read
    19.        lea (startof_ram).l,a4           ; load start of RAM
    20.        lea (vdp_data_port).l,a3       ; load  VDP data port
    21.        move.w   #(sizeof_ram/2)-1,d0    ; set number of times to loop
    23.    .readloop:
    24.        move.w   (a3),(a4)+               ; copy contents of VRAM to RAM
    25.        dbf   d0,.readloop               ; repeat until done (if VRAM is good, RAM should be all 1s)
    28.    .check:
    29.        lea (startof_ram),a0           ; start checking bytes at the start of RAM
    30.        lea (endof_ram),a1               ; stop at end of RAM
    31.        move.l   a1,d0                   ; copy end address to d0
    32.        moveq   #0,d1                   ; clear d1
    34.    .loop:
    35.        add.w   (a0)+,d1               ; add words at current address to d1 and increment
    36.        cmp.l   a0,d0                   ; have we reached the end?
    37.        bne.s   .loop                   ; if not, branch
    39.        lea (psg_input).l,a4           ; load PSG input register
    40.        move.w  #cGreen,d2               ; make screen green
    41.        cmpi.l  #sizeof_ram,d1           ; is entire RAM 1s? (assuming RAM is not faulty, it will be if the VRAM is good)
    42.        beq.s   .passtone               ; if it is, branch
    43.        move.w   #cRed,d2               ; if failed, make screen red
    45.    ;.failtone:
    46.        move.b   #$8C,(a4) ; make PSG0 produce a 160hz tone; #%10001100
    47.        move.b   #$2B,(a4) ; #%00101011
    48.        bra.s   TestResultScreen
    50.    .passtone:
    51.        move.b   #$8D,(a4) ; make PSG0 produce a 895hz tone; #%10001101
    52.        move.b   #$7,(a4) ; #%00000111
    54. TestResultScreen:
    55.        move.b   #$90,(a4) ; set PSG0 to maximum volume
    56.        move.l   #$C0000000,(a5)           ; set VDP to CRAM write
    57.        moveq   #(sizeof_pal_all/2)-1,d7   ; set number of times to loop
    59.    .fillpalette:
    60.        move.w   d2,(a3)                   ; fill palette with red if test failed, green if passed
    61.        dbf   d7,.fillpalette               ; repeat $3F more times
    63.    .endlessloop:
    64.        bra.s   .endlessloop
    The idea here is to fill the entire VRAM with 1s via DMA (the dma_fill macro is taken from the Sonic 1 Hivebrain 2022 disassembly), then copy the entire VRAM contents to RAM, sum the contents of the RAM into a data register, and compare to the sum of 64 KB of 1s. If the test passes, a green screen is displayed and a high tone is played on the PSG; if it fails, a red screen and a low tone. I don't know if that method will work, but I can't tell because the read from VRAM does not appear to be working!

    The intended usage I'm aiming for is to set a flashcart to run the last game on boot instead of going to the menu, run the test from said cart on a known good system, then place the flashcart into the system to be tested and power on, allowing the test to be run even if the console is unable to output coherent video.
  14. Hivebrain


    53.4N, 1.5W
    Wouldn't copying the entire VRAM to RAM also overwrite the stack?
  15. Devon


    The spider man is having me for dinner tonight Tech Member
    The problem is that DMA fill fills in bytes, not words. Seems like neither the Sonic Retro or Hivebrain 2022 disassembly take that into account. It fills VRAM with the high byte in the word written to the VDP data port, and since it's only setting 0x0001, it's really just filling VRAM with 0. You can fix the macro to shift the value to fill 8 bits to the left, or set it to 0x0100.

    Also, before peforming your VRAM read, you need to reset the auto-increment back to 2. The DMA fill needs it set to 1, which the macro does do, but it doesn't reset it back to 2 after (honestly, the macro SHOULD include it along with the DMA wait loop, it wouldn't break bit-perfectness in the disassembly, and I think it's pretty obvious that the loop and auto-increment reset were part of whatever original macro they had, because it appears after EVERY DMA fill call).

    Even with that fixed, you're also performing the summation word by word, so you'd really be adding 0x0101 continuously, and that loops 0x8000 times since 2 bytes per word. On top of that, you're then checking for a longword result. With the size of RAM being 0x10000 bytes, even if it were just adding 1 every time, the summing process won't actually get to that ever.

    You'd wanna do something like this to get your desired result:
    Code (Text):
    1.     moveq    #0,d2            ; Read buffer
    3. .loop:
    4.     move.b   (a0)+,d2         ; Read byte into lower byte of d2 and increment
    5.     add.l    d2,d1            ; Add d2 as a longword to d1
    6.     cmp.l    a0,d0            ; Have we reached the end?
    7.     bne.s    .loop            ; If not, loop

    Also, last I recalled, passing the PSG control port into an address register and then writing to sequential data to it isn't a good idea, because apparently it's not quick enough to handle that. I remember having an issue with a sound driver that did that some years ago.

    It would, but it looks like it's not using the stack in this code (assuming interrupts are disabled), so they shouldn't be running into any issues.

    I can't really wrap my head around what you are trying to accomplish here. Could you elaborate further?
    Last edited: Aug 31, 2022
  16. I noticed that my code was getting stuck in a seemingly infinite loop there. Figured there was something wrong with the summing logic. Thanks.

    But, even with the workaround to the flaw in the dma_fill macro, there seems to be another issue with it. If the VRAM editor in Exodus is to be believed, it's only writing the first word of VRAM instead of filling it! (That word is being written back to RAM correctly, though, so at least that part is working.)

    Bingo. Interrupts disabled, no stack usage at all, and no usage of RAM for anything other than the test. The only other code in the binary is the standard Mega Drive Setup library, which branches straight to the VRAM test after disabling interrupts.

    It's meant to take advantage of a feature of the Mega EverDrive where, instead of booting to the Everdrive's UI, you can set it to boot straight into whatever game was last played. This would allow the test to be easily run on a Genesis that, for whatever reason, is incapable of outputting video (and thus impossible to navigate the flashcart's UI): configure the flashcart to boot to the last played game, put the test binary on the flashcart, run the test on a known good unit, then put the flashcart in the unit to be tested, and power on. The PSG tones are meant to enable the test to be run on Model 1 units without the need for a video cable.
  17. Hexinator


    Hex Member
    Please don't be mad that i keep posting here, i am a newbie and don't know a lot of stuff, i want to place the emerald hill background as the title screen one, how do i do that? Sonic 2 github disassembly

  18. MainMemory


    Kate the Wolf Tech Member
    The simplest way would be to export the level's background as an image from SonLVL and then import it into SonPLN over the existing background.
  19. Hexinator


    Hex Member
    It worked, but the pallete is wrong, whats the pallete for emerald hill's bg?
  20. MainMemory


    Kate the Wolf Tech Member
    It's in EHZ's palette file.