don't click here

Basic Questions & Answers thread

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

  1. Nik Pi

    Nik Pi

    Member
    482
    303
    63
    Kazakhstan
    Sonic 2: Archives
    Cool. Thanks:)
     
  2. DeltaWooloo

    DeltaWooloo

    Be a boss-man and come to my big and tall man shop Member
    PlaneED is very limited in terms of features and reliability and has been surpassed by SonPLN. You should download SonLVL Updater and from there, you can download SonPLN and use it.

    To set it up, make sure you select SonPLN.ini which should be under the latest commits of both Sonic 1 and 2's GitHub disassembly.
     
    Last edited: Jul 22, 2022
  3. i didn't know that? thanks
    really have to download the new versions of these :(
    edit: nvm i have these and i just didn't know
     
    Last edited: Jul 22, 2022
  4. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    I have a somewhat not-so basic question/answer, it pertains to the speed of some code.

    So, in Sonic 1 and 2, the current VInt function is stored as a byte in RAM. Once VInt is run, it checks that byte, and uses this code to decide what to do in VInt:

    Code (Text):
    1.  
    2.     tst.b   (Vint_routine).w ; 12 cycles
    3.     beq.w   Vint_Lag       ;10 cycles if branch?
    4.     ; Some VDP stuff and PAL delay happens here.
    5.     move.b    (Vint_routine).w,d0 ;12 cycles
    6.     move.b    #VintID_Lag,(Vint_routine).w ;16 cycles
    7.     move.w    #1,(Hint_flag).w ;16 cycles
    8.     andi.w    #$3E,d0 ; 8 cycles
    9.     move.w    Vint_SwitchTbl(pc,d0.w),d0 ;14 cycles
    10.     jsr    Vint_SwitchTbl(pc,d0.w) ;22 cycles
    So, I had a thought though... How much faster would it be if instead of having VInt be a byte and read a relative pointer from a data table, what if I made VInt _Routine a direct pointer instead? So I could have the code be like this:
    Code (Text):
    1.    tst.w   (Vint_routine+2).w;12 cycles
    2.    beq.s   Vint_Lag       ;10 cycles if branch?
    3.     ; Some VDP stuff and PAL delay happens here.
    4.     move.w   #1,(Hint_flag).w               ;16 cycles
    5.     move.l   (Vint_routine).w,d0               ;16 cycles
    6.     move.w   #0,(Vint_routine+2).w           ;16 cycles
    7.     movea.l   d0,a1                           ; 4 cycles?
    8.     jsr       (a1)                           ;16 cycles
    9.  
    I did do the math according to https://mrjester.hapisan.com/04_MC68/CycleTimes.htm , and according to that, the original code is 102 cycles while my code is only 90 cycles, and since *all* my VInt functions are super early in the ROM, actually setting the VInt counter should be the same. Is there anything I'm missing here? Is this indeed actually faster to use? Is there something I can do to speed it up even more?

    Edit: I'm a bucket and I got the numbers swapped when I explained them lol
     
    Last edited: Jul 27, 2022
  5. Devon

    Devon

    I'm a loser, baby, so why don't you kill me? Tech Member
    1,248
    1,419
    93
    your mom
    If you want to stick to having your V-INT routine addresses being 16-bit, here's what I've come up with:

    Code (Text):
    1.  
    2.         lea     (Vint_routine).w,a1     ; 8  | Used to help save cycles and space by effectively "caching" the Vint_routine address
    3.         move.w  (a1),d1                 ; 8  | 2 bytes and 4 cycles saved from "tst.w (Vint_routine).w"
    4.                                         ;    | Also sets the zero flag if Vint_routine is 0
    5.                                         ;    | d1 is chosen, since it isn't overwritten by the "VDP shit"
    6.         beq.s   Vint_Lag                ; 8 on skip, 10 on branch
    7.  
    8.         ; VDP shit
    9.  
    10.         st      (Hint_flag).w           ; 16 | Hint_flag = FFxx, which is fine for how the flag is used in Sonic 2
    11.                                         ;    | 2 bytes and 0 cycles saved from "move.w #1,(Hint_flag).w"
    12.         clr.w   (a1)                    ; 12 | 4 bytes and 4 cycles saved from "move.w #0,(Vint_routine).w"
    13.         movea.w d1,a1                   ; 4  | 16-bit addresses are sign extended into 32-bit addresses
    14.                                         ;    | 2 bytes and 12 cycles saved from "move.l (Vint_routine).w,d0"
    15.                                         ;    | 2 bytes and 4 cycles saved from "movea.l d0,a1"
    16.         jsr     (a1)                    ; 16
    17.                                         ; Total: 72 on beq skip, 26 on beq branch
    18.  

    This can also work for code stored in RAM addresses FF8000-FFFFFF, due to the sign extension (also remember that the m68k address bus is 24-bit, so i.e. FFFF8000 is interpreted as FF8000; highest byte is ignored in a full 32-bit address).
     
    Last edited: Jul 27, 2022
  6. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    Oh wow, it didn't occur to me to use the address register for some reason. That's a huge gain over the hackish thing I was doing!
    Glad to know I was onto something though, thanks for the recommendation!
     
  7. Uh, hate to inform you, but your code just crashes upon startup; here's the Sonic 1 equivalent (and yes, it also crashes in Sonic 2.
    Code (Text):
    1. loc_B10:                ; XREF: Vectors
    2.         movem.l    d0-a6,-(sp)
    3.         lea    ($FFFFF62A).w,a1
    4.         move.w    (a1),d1
    5.         beq.s    loc_B88
    6.         move.w    ($C00004).l,d0
    7.         move.l    #$40000010,($C00004).l
    8.         move.l    ($FFFFF616).w,($C00000).l
    9.         btst    #6,($FFFFFFF8).w
    10.         beq.s    loc_B42
    11.         move.w    #$700,d0
    12.  
    13. loc_B3E:
    14.         dbf    d0,loc_B3E
    15.  
    16. loc_B42:
    17.         st    ($FFFFF644).w
    18.         clr.w    (a1)
    19.         movea.w    d1,a1
    20.         jsr    (a1)
    21.  
    22. loc_B5E:                ; XREF: loc_B88
    23.         jsr    (sub_71B4C).l
    24.  
    25. loc_B64:                ; XREF: loc_D50
    26.         addq.l    #1,($FFFFFE0C).w
    27.         movem.l    (sp)+,d0-a6
    28.         rte    
     
  8. Devon

    Devon

    I'm a loser, baby, so why don't you kill me? Tech Member
    1,248
    1,419
    93
    your mom
    ...you're storing the direct address of the V-INT routine (in 16 bits), right?
     
  9. Cokie

    Cokie

    C. Okie Member
    75
    22
    8
    For Genesis/Megadrive Sonic games and megadtive games in general is there a finite point where you will see in the emulator like exodus the updating if the scree like right at the RTS of a vertical interrupt or waitforvint subroutine? Or with Exodus Gens or even real hardware will there be some delay period before you actually see the vdp update the screen?
     
  10. Cokie

    Cokie

    C. Okie Member
    75
    22
    8
    ScrollVerti subroutines: .doScroll_medium , doScroll_slow and doScroll_fast all compare the result of d0 to determine if the player is
    going up or down too fast and we need to cap it to appropriate amount:

    ;.doScroll_medium:
    move.w #6<<8,d1 ; If player is going too fast, cap camera movement to 6 pixels per frame
    cmpi.w #6,d0 ; is player going down too fast?
    bgt.s .scrollDown_max ; if so, move camera at capped speed
    cmpi.w #-6,d0 ; is player going up too fast?
    blt.s .scrollUp_max ; if so, move camera at capped speed

    BUT, .decideScrollType oddly uses sonic's intertia to decide if we need to branch to doScroll_fast:

    .decideScrollType:
    cmpi.w #(224/2)-16,d3 ; is the camera bias normal?
    bne.s .doScroll_slow ; if not, branch
    (MACRO) mvabs.w inertia(a0),d1 ; get player ground velocity, force it to be positive
    move.w inertia(a0),d1 ; get player ground velocity, force it to be positive
    bpl.s .skip
    neg.w d1
    .skip
    cmpi.w #$800,d1 ; is the player travelling very fast?
    bhs.s .doScroll_fast ; if he is, branch
    Why not just use the result of d0 and store it into d1 and make it positive if necessary and compare it?

    move.w d0,d1
    bpl.s .skip
    neg.w d1
    cmpi.w #$800,d1 ; is the player travelling very fast?
    bhs.s .doScroll_fast ; if he is, branch

    Is there a key reason that I am misunderstanding about the code? Thanks.
     
  11. Devon

    Devon

    I'm a loser, baby, so why don't you kill me? Tech Member
    1,248
    1,419
    93
    your mom
    ".decideScrollType" is just used to determine whether to cap the camera at 6 or 16 depending on how fast you are moving on the ground. It goes to ".doScroll_fast" if abs(intertia) is >= $800, otherwise, it falls through to ".doScroll_medium".
     
  12. Hexinator

    Hexinator

    Hex Member
    Is there a way to port Sonic 3's tails flight to sonic 1? just trying to add tails to sonic 1
     
  13. Nik Pi

    Nik Pi

    Member
    482
    303
    63
    Kazakhstan
    Sonic 2: Archives
    Is the anywhere exist code and/or guide how to make a Sonic Retro splash screen for using in hacks?
     
    Last edited: Aug 6, 2022
  14. nineko

    nineko

    I am the Holy Cat Tech Member
    6,308
    486
    63
    italy
    Yes.
    A public guide for the Sonic Retro splash screen has never been made, but one for the SSRG splash screen exists. Since you seem pretty smart you might be able to adapt it, good luck!
     
  15. Nik Pi

    Nik Pi

    Member
    482
    303
    63
    Kazakhstan
    Sonic 2: Archives
    Sad.. and that link just gives me.. nothing, lol (and, i dont want so much insert ssrg splash).
    I was hoping that I would be able to express gratitude to people from here with this screen, and insert the screen into my hack.
    Well.. I hope that one day I will be able to achieve mastery, learn Zen, and earn trust in myself :)
    Anyway, thanks)
     
  16. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    You could always utilize this old thing I posted back in the day. https://forums.sonicretro.org/index.php?threads/static-splash-screen-guide.33562/
    It won't be animated, like the proper Sonic Retro splash, but you can at least get the logo to show up as long as you know how to add images using programs like SonPLN.

    It's possible to modify it more to add objects and animate them. My character select screen for this hack uses that post as a base for the screen code:
     
  17. I remember the source code for the screen was available after someone posted the code to a failed Sonic 4 demake in Sonic 1 on Github.
     
  18. Devon

    Devon

    I'm a loser, baby, so why don't you kill me? Tech Member
    1,248
    1,419
    93
    your mom
    The Sonic Retro splash screen is not supposed to be public, AFAIK. Cinossu only hosted it in the Tech Member lounge. At least, I haven't seen it officially released outside of there...

    EDIT: It's a disassembly of the splash screen in that repository, not the actual source.

    I will say that the splash screen is really old (if there are members on here that are or less than 14 years old, it's older than them; it was posted in 2008) and has not been maintained in years (in fact the link in the OP of the original thread is dead, apparently since 2011). You'd be better off learning to make your own splash screen. I'd find that to be a more rewarding and insightful experience when it comes to hacking.
     
    Last edited: Aug 7, 2022
  19. Nik Pi

    Nik Pi

    Member
    482
    303
    63
    Kazakhstan
    Sonic 2: Archives
    Ok, I think, you are right.
    Would be soo strange to see a screen in different various lousy hacks with repainting levels and shitty music :)
    Anyway, thanks for responses! I'll try the different ways
     
  20. Hexinator

    Hexinator

    Hex Member
    Do you need any code changes to make it adapt to sonic 1? using the github disassembly