don't click here

Basic Questions & Answers thread

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

  1. Pyrochrome

    Pyrochrome

    Member
    6
    0
    1
    Where do I go for general assistance with a romhack? Is there a Discord server? I'm trying to implement new moves like a double jump and it's not quite working.

    edit: and also, how does Sonic 1 handle pointers to walking/running sprites when Sonic is tilted?
     
  2. Sonic Retro's discord server has a channel for hacking discussion. You can also use the search feature on this site to look at others' forum posts and see how they solved problems. Sonic Stuff Research Group is another forum site to look at if you can't find something here. Hope this helps.
     
  3. Cokie

    Cokie

    C. Okie Member
    76
    22
    8
    The Obj_SOZGhosts object in SOZ2 in SK is absolute coordinates and is offscreen the entire time, according to the render flags. It sets it coordinates as 0x120 0xA0 ( X AND Y ) . It seems to be a parent object that is not displayed and is kind of a "dummy" in the sense that it creates children by

    loc_8F108:
    lea ChildObjDat_8F674(pc),a2
    jmp (CreateChild6_Simple).l

    where:
    ChildObjDat_8F674:
    dc.w 0
    dc.l loc_8F11E

    note loc_8F11E is a part of Obj_SOZGhostsobject

    What is the Obj_SOZGhostsobject then if it is a non seen parent object that isn't really a ghost but rather seems to be a spawner of the ghost and have code that controls it. Is this a common theme in sonic 1 2 3 knuckes engines to have the object name be a dummy that spawns?

    Why have the Obj_SOZGhosts object be at this particular coordinate point mentioned above. And why bother making it absolute? And why bother making it offscreen if there is no sprite? I am missing some fundamentals of parent child creation in sonic games i believe.

    Also the ghosts being made by CreateChild6_Simple take upon the Obj_SOZGhosts x and y and by default are absolute while the ghosts float left and right while they are small and only change to playfield coordinates when they move diagonally and then disappear and come back to the top are absolute only to repeat back the cycle. Any clue why?

    Here is a video of what is going on. I wrote a script to show the objects base slot in object ram, its object code , its coord system type ( absolute / playfield ), if its on scree and its x and y

     
    • Informative Informative x 2
    • List
  4. Tried to put in a custom song for the HPZ entry in the music index, got this error that I cannot figure out for the life of me. I tried to use the +20h on its inclusion to the index like the 1up/credits/drowning track and the include asm path, still doesn't work. How do I fix this?
    [​IMG]
     
  5. BenoitRen

    BenoitRen

    Tech Member
    411
    183
    43
    The error seems pretty self-explanatory to me. Your new song is too big for the decompression buffer. It even gives you a solution: add it uncompressed.
     
  6. The problem is that I can't figure out how to add it uncompressed. Last time I've checked, I couldn't find anything on adding uncompressed songs.
     
  7. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Member
    316
    327
    63
    Canada
    This isn't so much of a basic question, but I've been working at this for 6 hours now with no luck, and I'm out of ideas.
    I'm replacing the Sega screen in my hack with a custom one:
    [​IMG]
    I want the neon lights to go from being off to unstable flickering, and then stays on. I've been trying to achieve this with a table of nybbles to indicate the lights are active or inactive. However no matter how many times I've rewritten this, it's either resulted in the screen just loading the initial palette and then fading out, or the lights get disabled and then it fades out to the title screen. I'm not sure if this is an issue with reading the nybbles, or how I'm handling the timer. But any help is greatly appreciated.
    Code (Text):
    1.         moveq    #PALID_KILOANDSEGA,d0
    2.         bsr.w    Pal_LoadBuffer
    3.  
    4. Logos_FlashLoop:
    5.         moveq    #0,d0
    6.         move.w    (logos_flashidx).w,d0        ; Load the current flash frame.
    7.         addi.w    #1,(logos_flashidx).w
    8.         move.b    d0,d1                        ; Copy it, since we're going to modify d0.
    9.         tst.b    d0                            ; Are we at frame 0?
    10.         beq.s    @DontCheckEven                ; If so, don't check if the frame is odd or even.
    11.         btst    #0,d0                        ; Is this an even frame?
    12.         bne.s    @DontCheckEven                ; If not, branch.
    13.         subq.b    #1,d0                        ; Subtract 1, since we're working with nybbles.
    14.  
    15. @DontCheckEven:
    16.         lea    (Logos_KiloFlashFrames).l,a0    ; Load our flash flags.
    17.         adda.w    d0,a0                        ; And add our offset given the frame.
    18.         move.b    (a0),d2                        ; Move it to d2 for masking.
    19.         adda.w    #Logos_SEGAFlashFrames-Logos_KiloFlashFrames,a0    ; And add an offset for the SEGA palette.
    20.         move.b    (a0),d3                        ; Move it to d3 for masking.
    21.         btst    #0,d1                        ; Is it an even frame?
    22.         bne.s    @Odd                        ; If not, branch.
    23.         and.b    #%10000,d2                    ; Mask out lower nybble.
    24.         and.b    #%10000,d3                    ; Mask out lower nybble.
    25.         bra.s    @Continue
    26.  
    27. @Odd:
    28.         and.b    #%1,d2                        ; Mask out higher nybble.
    29.         and.b    #%1,d3                        ; Mask out higher nybble.
    30.  
    31. @Continue:
    32.         lea    (Pal_LogoInactive).l,a0            ; Load inactive palette.
    33.         tst.b    d2                            ; Is the frame inactive?
    34.         beq.s    @DoKiloPalette                ; If so, branch.
    35.         lea    (Pal_KiloLogoActive).l,a0        ; Otherwise, load active palette.
    36.  
    37. @DoKiloPalette:
    38.         lea    (pal_buffer+4).w,a1                ; Load palette buffer.
    39.         moveq    #5-1,d4                        ; Set loop counter.
    40.  
    41. @KiloLoop:
    42.         move.w    (a0)+,(a1)+                    ; Write colors to palette buffer.
    43.         dbf    d4,@KiloLoop                    ; Loop.
    44.  
    45.         lea    (Pal_LogoInactive).l,a0            ; Load inactive palette.
    46.         tst.b    d2                            ; Is the frame inactive?
    47.         beq.s    @DoSEGAPalette                ; If so, branch.
    48.         lea    (Pal_SEGALogoActive).l,a0        ; Otherwise, load active palette.
    49.  
    50. @DoSEGAPalette:
    51.         lea    (pal_buffer+$E).w,a1            ; Load palette buffer.
    52.         moveq    #5-1,d4                        ; Set loop counter.
    53.  
    54. @SEGALoop:
    55.         move.w    (a0)+,(a1)+                    ; Write colors to palette buffer.
    56.         dbf    d4,@SEGALoop                    ; Loop.
    57.  
    58.         move.b    #VINTID_SEGA,d0
    59.         bsr.w    VInt_Wait
    60.  
    61.         cmp.w    #5*60,(logos_flashidx).w
    62.         blt.w    Logos_FlashLoop
    63.  
    64.         move.b    #SCNID_TITLE,(scene_id).w                        ; Go to the title screen.
    65.         rts
    66.  
    67. Logos_KiloFlashFrames:
    68.         dc.b    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    69.         dc.b    $00, $00, $00, $00, $00, $00, $00, $00, $01, $00, $00, $00, $00, $01, $00, $00, $00, $00, $01, $01, $00, $00, $01, $00, $00, $00, $01, $11, $00, $00
    70.         dc.b    $01, $10, $11, $01, $10, $00, $10, $11, $10, $00, $10, $00, $10, $01, $11, $11, $10, $11, $10, $01, $00, $11, $10, $11, $11, $11, $10, $10, $11, $11
    71.         dc.b    $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11
    72.         dc.b    $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11
    73.  
    74. Logos_SEGAFlashFrames:
    75.         dc.b    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00
    76.         dc.b    $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $10, $00, $01
    77.         dc.b    $11, $10, $00, $10, $11, $01, $11, $01, $01, $11, $01, $11, $10, $10, $11, $10, $01, $11, $10, $01, $11, $10, $11, $00, $01, $11, $10, $11, $11, $11
    78.         dc.b    $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11
    79.         dc.b    $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11, $11
    80.  
    81. Pal_LogoInactive:
    82.         dc.w    $000, $000, $000, $000, $000
    83.  
    84. Pal_KiloLogoActive:
    85.         dc.w    $EEE, $EAE, $82E, $608, $204
    86.  
    87. Pal_SEGALogoActive:
    88.         dc.w    $EEE, $EEA, $E82, $C00, $800
     
  8. OrionNavattan

    OrionNavattan

    Tech Member
    166
    164
    43
    Oregon
    I doubt it's the cause of your issue, but FWIW the "blt.w Logos_FlashLoop" should probably be a "bcs.w", since it doesn't seem to be a signed comparison.
     
  9. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Member
    316
    327
    63
    Canada
    I always get confused on when to use bcs or bcc. blt and bgt are just easier for me to understand their condition. But thanks.
     
  10. Devon

    Devon

    I'm a loser, baby, so why don't you kill me? Tech Member
    1,249
    1,420
    93
    your mom
    Register d3 doesn't seem to actually be checked when loading the Sega palette. Also, wouldn't it be more ideal to just divide d0 by 2 and use the bit shifted out into the carry flag to check if it was odd? Your logic for picking which index to use for the flashing is kinda weird, with the order ending up being 0, 1, 1, 3, 3, 5, 5...

    Maybe something like this?
    Code (Text):
    1.     moveq   #%00001,d1       ; Lower nibble
    2.     lsr.w   #1,d0            ; Divide frame by 2
    3.     bcs.s   @GotIndex        ; Branch if it was odd
    4.     moveq   #%10000,d1       ; High nibble
    5.  
    6. @GotIndex:
    7.     move.b  Logos_KiloFlashFrames(pc,d0.w),d2
    8.     move.b  Logos_SEGAFlashFrames(pc,d0.w),d3
    9.     and.b   d1,d2
    10.     and.b   d1,d3

    I also assume VInt_Wait is set to take in d0 as the V-INT routine ID?
     
    Last edited: Feb 17, 2024
  11. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Member
    316
    327
    63
    Canada
    That would be because I copied the Kilo palette code and didn't change it, whoops.
    Gotta use a lea, the code and tables are too large to use a move with the pc d0 offset thing and it causes an illegal value when building. No problem though I can just combine this with my old code.
    No it does not, why did I do that.

    But yes! This worked, thank you so much!
    ezgif-4-8f4d94c8c8.gif
     
  12. OrionNavattan

    OrionNavattan

    Tech Member
    166
    164
    43
    Oregon
    This has been resolved, my wait loop checks weren't thorough enough.

    Not a very basic question at all, but hopefully someone will be able to help wit this snag that my Sonic CD Mode 1 project has run into. As part of it, I want to be able to check for a disc in the Mega CD and determine if it's a an audio CD or a planned data disc that will contain FMV data and CD audio. Unfortunately, I'm not having much luck getting it to work. The following code is intended to check for the presence of a disc, and if one is present, check if it's a copy of Sonic CD (or in my case,CD++), or an audio CD with 35 or more tracks. However, so far it doesn't work: whether a disc is present or not, it always returns "audio CD with 35 tracks." I can only guess I may have misunderstood something related to one of the BIOS calls given how sparse the documentation for them is. Either way, I'd appreciate some help.

    Code (ASM):
    1. Init:
    2.        lea SetupValues(pc),a0 ; pointers to exception entry points
    3.        lea (_AddressError).w,a1   ; first error vector in jump table
    4.        moveq   #10-1,d0           ; 9 vectors + GFX int
    5.  
    6.    .vectorloop:
    7.        addq.w   #2,a1       ; skip over instruction word
    8.        move.l   (a0)+,(a1)+   ; set table entry to point to exception entry point
    9.        dbf d0,.vectorloop   ; repeat for all vectors and GFX int
    10.  
    11.        move.l   (a0)+,(_TimerInt+2).w           ; set timer interrupt address
    12.        move.b   2(a0),(mcd_timerint_interval).w   ; set timer interrupt interval
    13.  
    14.        moveq   #DriveInit,d0
    15.        jsr   (_CDBIOS).w               ; initialize the drive and get TOC (will start after controller finishes initializing)
    16.  
    17.        moveq   #0,d0
    18.        clear_ram.w   SubCPUGlobalVars,sizeof_SubCPUGlobalVars   ; clear global variables
    19.  
    20.        moveq   #id_FileFunc_EngineInit,d0
    21.        jsr   (FileFunction).w       ; initialize the file engine
    22.        jmp   (DriverInit).l           ; initialize the PCM driver
    23. ; ===========================================================================
    24.  
    25. SetupValues:
    26.        dc.l AddressError
    27.        dc.l IllegalInstr
    28.        dc.l ZeroDivide
    29.        dc.l ChkInstr
    30.        dc.l TrapvInstr
    31.        dc.l PrivilegeViol
    32.        dc.l Trace
    33.        dc.l Line1010Emu
    34.        dc.l Line1111Emu
    35.        dc.l GFXInt           ; GFX int address
    36.        dc.l RunPCMDriver   ; timer int address
    37.        dc.b 1,$FF           ; drive init parameters
    38.        dc.b 255           ; timer interrupt interval
    39.  
    40. DiscType:
    41.        dc.b    'SEGADISCSYSTEM  '
    42.    ;   dc.b   'SEGADATADISC    '
    43.        arraysize   DiscType
    44. HeaderTitle:
    45.        dc.b   'SONIC THE HEDGEHOG-CD                           '
    46.    ;   dc.b   'SONIC THE HEDGEHOG CD MODE 1 DATA DISC          '
    47.        arraysize   HeaderTitle
    48.        even
    49. ; ===========================================================================
    50.  
    51. Main:
    52.        addq.w #4,sp   ; throw away return address to BIOS usercall loop, as we will not be returning there
    53.  
    54.    .delay:
    55.        jsr   (_WaitForVBlank).w           ; delay for two seconds to allow drive controller to finish initializing
    56.        cmpi.b   #2*60,(v_vblank_counter).w   ; have we waited 120 frames?
    57.        bcs.s   .delay                   ; branch if not
    58.  
    59.    .waitinit:
    60.        move.w   #BIOSStatus,d0
    61.        jsr   (_CDBIOS).w                   ; get BIOS status
    62.        btst   #drive_ready_bit,(a0)   ; a0 = _BIOSStatus
    63.        bne.s   .waitinit               ; branch if drive init hasn't finished
    64.  
    65.        btst   #no_disc_bit,(a0)    ; bit 4, but it always seems to return zero?
    66.        bne.s   .nodisc                   ; branch if no disc in drive
    67.  
    68.        move.w   #TOCRead,d0
    69.        moveq   #1,d1
    70.        jsr   (_CDBIOS).w               ; fetch TOC entry for track 1
    71.  
    72.        tst.b   d1                   ; (supposed to be 0 if audio track, $FF if data track, but seems to always return 0)
    73.        beq.w   .checktrackcount   ; if this is an audio track, it's not a CD-ROM
    74.  
    75.        jsr   (LoadDiscHeader).w       ; (routine hacked into Sonic CD's file engine that reads the first sector of disc)
    76.  
    77.        cmpi.w   #fstatus_ok,d0       ; was the operation a success?
    78.        bne.s   .nodisc               ; if not, assume no disc
    79.  
    80.        lea (FileVars+fe_dirreadbuf).l,a1   ; a1 = disc type in header
    81.        lea DiscType(pc),a2                   ; header type we're checking for
    82.        moveq   #sizeof_DiscType-1,d1
    83.  
    84.        jsr   (CompareStrings).w               ; does the type in the header match?
    85.        bne.s   .checktrackcount           ; if not, branch
    86.  
    87.        lea (FileVars+fe_dirreadbuf+Domestic_title),a1   ; game title in header
    88.        lea HeaderTitle(pc),a2                           ; header title we're checking for
    89.        moveq   #sizeof_HeaderTitle-1,d1
    90.  
    91.        jsr   (CompareStrings).w       ; does the title in the header match?
    92.        beq.s   .getfiles           ; if so, branch
    93.  
    94.    .checktrackcount:
    95.        cmpi.b   #35,(_CDDStatus+CDD_LastTrack).w       ; does this disc have at least 35 tracks?
    96.        bcc.s   .audiocd               ; if so, we can play music from this CD
    97.        bra.s   .nodisc                   ; otherwise, we can't use it; assume no disc
    98. ; ==============================================
    99.    .getfiles:
    100.        moveq   #id_FileFunc_GetFiles,d0
    101.        bsr.s   FileFunction           ; load the disc's filesystem
    102.  
    103.    .waitfiles:
    104.        jsr   (_WaitForVBlank).w           ; file engine only runs during VBlank
    105.  
    106.        moveq   #id_FileFunc_GetStatus,d0       ; is the operation finished?
    107.        bsr.s   FileFunction
    108.        bcs.s   .waitfiles               ; if not, wait
    109.  
    110.        addq.b   #1,(v_disc_status).w   ; 2 = full CD audio and FMV support
    111.  
    112.    .audiocd:
    113.        addq.b   #1,(v_disc_status).w   ; 1 = CD audio only
    114.  
    115.    .nodisc:
    116.        move.b   (v_disc_status).w,(mcd_subcom_1).w   ; give disc status to main CPU
    117.  
    118.        moveq   #'R',d0
    119.        move.b   d0,(mcd_subcom_0).w       ; signal initialization success
     
    Last edited: Feb 19, 2024
  13. Edit: Can a mod please remove this post? I'm going to move my issue to its own new thread.
     
    Last edited: Feb 26, 2024
  14. Good morning.
    I continue to do SEEK Engine, development is very early at the moment but still ongoing. I had a doubt/question:
    I'm following Sonic's physics guide, which is excellent. My question is regarding the resolution and the variables that physics uses. On a Mega Drive the resolution is 320x224, if I want the engine to run at 1920x1080... How should I update the physics accordingly? Using a scalar multiplier? Or is there another way?
    Thank you so much!!
     
  15. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Member
    316
    327
    63
    Canada
    The physics guide assumes your base unit is 1 pixel. In theory you can just make your higher resolution assets smaller and your camera more zoomed in and work with the original value. But if you're really curious, how much you need to multiply it by is pretty simple. Just divide 1080 by 240 (240's a bit more standard than 224) so your multiplier would be 4.5.
     
  16. Thank you so much!!
     
  17. Where can I download sonic sprites in high quality or transparent? I know about The Sprites Resources, but I want to know if there are alternatives. thank you
     
  18. XPointZPoint

    XPointZPoint

    That's no good! Member
    56
    13
    8
    I'm following this guide: https://info.sonicretro.org/SCHG_How-to:Port_Knuckles_into_Sonic_2

    and the error seems to be coming from the steps in the Life Icon mappings section. Before following the CNZ Slot Machines section, I decide to build the ROM, just to test it out so far, and I get an error stating that "PLCID_Tails1up" & "PLCID_Miles1up" are not symbols. The guide is outdated, sure, so I fix it and put the correct PLCIDs in there, rebuild and get an error saying:

    Code (Text):
    1. [...] jump distance too big
    2. bne.s    ++           ; rts
    So, I change it back to one + instead of two, and then rebuild. New error shows up:

    Code (Text):
    1. [...] jump distance too big
    2. bhs.s return_2AA10
    What can I do to fix both of these problems?
     
  19. Devon

    Devon

    I'm a loser, baby, so why don't you kill me? Tech Member
    1,249
    1,420
    93
    your mom
    Change the ".s" to ".w" for both of them.

    ".s" indicates a "short" or "byte" branch, which only accepts a signed byte-wide distance to be branched to, which isn't very much, but the instruction only takes 2 bytes. ".w" indicates a "word" branch, which accepts a signed 16-bit word-wide distance, which is a much bigger range, but the instruction takes up 4 bytes.
     
  20. Kilo

    Kilo

    That inbetween sprite from S&K's title screen Member
    316
    327
    63
    Canada
    So I'm trying to make the most out of my Everdrive by using the USB port to record some of the player's data (X pos, Y pos, velocity, etc.), just like how Sonic Team would have back in the 90's (Although they only recorded input timings, I'm using object data for a specific reason.)
    The issue is that I can't seem to get it to transmit any data. I was using one of the example programs on krikzz's site, ssf-ex-test to reference the code, and VCPTestCENET, to view any data output, but got none. I figured maybe I bit more than I could chew, the program is used for text data and not what I'm doing so I thought I'd take a step back and do something more simple, just send the letter A, but not even that worked. Could someone tell me where I went wrong?

    Code (Text):
    1. usb_port = $A13000
    2.  
    3. USB_DATA = 226
    4. USB_STATUS = 228
    5. USB_CONFIG = 230
    6. USB_CTRL = 240
    7.  
    8. USB_READY = 2
    9.         lea    (usb_port).l,a0
    10.         move.w    #$8000,USB_CTRL(a0)    ; Enable register access
    11.         move.w    #1,USB_CONFIG(a0)    ; Set USB config
    12. @Wait:
    13.         move.w    USB_STATUS(a0),d1    ; Get USB status.
    14.         and.w    #USB_READY,d1        ; Check if it's ready for a write.
    15.         bne.s    @Wait                ; If not, wait.
    16.         move.b    #"A",USB_DATA(a0)