Basic Questions and Answers Thread

Discussion in 'Discussion & Q&A' started by Malevolence, Jul 7, 2009.

  1. lavagaming1

    lavagaming1 Newcomer Trialist

    Joined:
    Jul 24, 2017
    Messages:
    9
    Location:
    united states
    hello i would like to know how chunks are formatted in sonic 3 (prob same as sonic 2) but the main question here is im trying to load chunks from both ram and rom [CODE/]
    AridValleyZoneChunks: ; start , end
    Binclude "level/Arid Valley Zone Act 1/Chunks.unc", 0, $F2*$80 ; only include $F2 of chunks

    dc.l AVZSwapableChunks,AVZSwapableChunks+$4,AVZSwapableChunks+$8,AVZSwapableChunks+$C
    dc.l AVZSwapableChunks+$10,AVZSwapableChunks+$14,AVZSwapableChunks+$18,AVZSwapableChunks+$1C

    dc.l AVZSwapableChunks+$20,AVZSwapableChunks+$24,AVZSwapableChunks+$28,AVZSwapableChunks+$2C
    dc.l AVZSwapableChunks+$30,AVZSwapableChunks+$34,AVZSwapableChunks+$38,AVZSwapableChunks+$3C[/CODE] basically what im trying to do is have $F2 chunks be loaded from ROM while the last 2 chunks are from ram (backgrounds chunks)
     
  2. Speems

    Speems Well-Known Member Member

    Joined:
    Mar 14, 2017
    Messages:
    85
    Location:
    Rochester Hills, MI
    In the case of the Sonic 1 title screen, what's the best possible spot to add the code for a "press start" sound effect? Like when you press start on the title, the noise plays during the fadeout and going to the level. I've seen it in a couple hacks (trailers with early footage included) and was curious to see where to put it, especially since it looks like just putting the SFX code in a specific spot, just don't know the exact spot.
     
  3. FeroTheInugami

    FeroTheInugami It's in the Blockchain Member

    Joined:
    Jul 10, 2023
    Messages:
    36
    I'm trying to port new BG to Sonic 1 on SonLVL and the result I got wasn't good, that even the GHZ loop's collision is broken:
    ReadySonic001.jpg

    The background I ported is from Sonic Advance:
    54.png
     
  4. Alegamer700

    Alegamer700 Newcomer Member

    Joined:
    Jun 14, 2021
    Messages:
    20
    Location:
    Somewhere in South America
    (Edit) Nevermind, throw this to the trash if you can
     
    Last edited: Aug 14, 2023
    nineko likes this.
  5. penPhobic

    penPhobic Everything's all topsy-turvy now. Member

    Joined:
    Dec 11, 2016
    Messages:
    68
    Location:
    Basement
    How can I set the language from YY-CHR program into English? All I see is garbage words trying to load Japanese texts.
     
    Last edited: Aug 19, 2023
  6. Thiago REzEnDe

    Thiago REzEnDe Newcomer Trialist

    Joined:
    Sep 17, 2022
    Messages:
    9
    Location:
    Hill Valey, California
  7. giovanni.gen

    giovanni.gen It's still Joe-vanni, not Geo-vanni. Member

    Joined:
    Apr 16, 2015
    Messages:
    314
    Location:
    Italy
    I'm using some code to call the Sonic 2 credits from any arbitrary gamemode. Here's the code I'm using:


    Code:
    GotoCredits:
            st.b    (Credits_Trigger).w
            bsr.w    Pal_FadeToBlack                    ; this masks graphical corruption during the vertical interrupt mode change
    
    
    MenuCredits_MainLoop:
            move.b    #VintID_Ending,(Vint_routine).w
            jsr        WaitForVint 
            jsr        EndgameCredits
            tst.w    (Level_Inactive_flag).w
            beq.s    MenuCredits_MainLoop
      
            addq.l    #4,sp                            ; the intended effect is to pop the stack enough to change the return address into MainGameLoop, thus correctly resetting the game. Desired value will vary.
            rts
    The code's functionality is simple. Call GotoCredits from anywhere in the game, and it will show the credits. This code was tested with a few gamemodes:

    • Title screen (Sonic 2)
    • Custom main menu (Sonic 2 - Score Rush)
    • Level (Sonic 2)
    The first two give me no problems, and look as intended. The last one, however...

    bizarre.gif

    Yeah. There are problems when it comes to loading the graphics.

    This is what the VRAM looks like when the credits are called from the title screen, in an otherwise untouched copy of Sonic 2.
    upload_2023-8-23_21-21-44.png

    The first line places all of the character graphics exactly where they're supposed to be.

    For the level, it's a different story.
    upload_2023-8-23_21-23-40.png

    Not only are most of the graphics missing on the first line, but some of the credits art data gets loaded near the end of VRAM. (Ignore the ones in the middle, those are from the Title Screen)

    Can someone explain what's going on here?
     
    Last edited: Aug 23, 2023
  8. Tarekboushi

    Tarekboushi Newcomer Trialist

    Joined:
    Jan 24, 2021
    Messages:
    19
    i would guess the vram is locked is it i think theres a feature for that
     
  9. giovanni.gen

    giovanni.gen It's still Joe-vanni, not Geo-vanni. Member

    Joined:
    Apr 16, 2015
    Messages:
    314
    Location:
    Italy
    A solution was found, courtesy of MarkeyJester.

    If you intend to use this code for yourself, then you will need to make one small modification to EndgameCredits. More specifically, right after the first call to Pal_FadeToBlack, this line is to be added:

    Code:
        move.w    #$2700,sr
    For an explanation as to what was happening...

    Of course, disabling interrupts with the above instruction fixes the graphical errors, allowing for the art to load correctly, and for the code to function universally.
     
    Last edited: Aug 25, 2023
  10. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,380
    Location:
    your mom
    You cannot "lock" the Mega Drive's VRAM.

    EDIT: I seriously just got ninja'd lol

    This can be simplified. The loop is there in EndingSequence, because it's actually waiting for the ending cutscene to play out all the way, in which the cutscene handler will set Credits_Trigger. Once that's set, EndgameCredits will continue to display the credits, and once it's done, it'll set Level_Inactive_flag, which is to tell that loop that the credits have indeed run and it can exit out.

    All you ACTUALLY really need to do is set Credits_Trigger and then call EndgameCredits, and it'll work just fine. Also, with returning to MainGameLoop, your best bet is to just reset the stack pointer and on exit, jump directly to MainGameLoop.

    The problem is that when the credits start, interrupts are still enabled while it tries to load the graphics. The V-INT routine that it will run is Vint_lag, since during loading, no explicit V-INT routine ID is set. Let's take a look at what it does.
    Code:
    Vint_Lag:
        cmpi.b    #GameModeID_TitleCard|GameModeID_Demo,(Game_Mode).w    ; pre-level Demo Mode?
        beq.s    loc_4C4
        cmpi.b    #GameModeID_TitleCard|GameModeID_Level,(Game_Mode).w    ; pre-level Zone play mode?
        beq.s    loc_4C4
        cmpi.b    #GameModeID_Demo,(Game_Mode).w    ; Demo Mode?
        beq.s    loc_4C4
        cmpi.b    #GameModeID_Level,(Game_Mode).w    ; Zone play mode?
        beq.s    loc_4C4
    
        stopZ80            ; stop the Z80
        bsr.w    sndDriverInput    ; give input to the sound driver
        startZ80        ; start the Z80
    
        bra.s    VintRet
    So, first, it checks if it's in the level game mode. If so, it goes to loc_4C4. Otherwise, it just flushes the sound driver queue and exits. So what does loc_4C4 do?
    Code:
    loc_4C4:
        tst.b    (Water_flag).w
        beq.w    Vint0_noWater
        move.w    (VDP_control_port).l,d0
       ...
        stopZ80
    
        tst.b    (Water_fullscreen_flag).w
        bne.s    loc_526
    
        dma68kToVDP Normal_palette,$0000,palette_line_size*4,CRAM
    
        bra.s    loc_54A
    ; ---------------------------------------------------------------------------
    
    loc_526:
        dma68kToVDP Underwater_palette,$0000,palette_line_size*4,CRAM
    
    loc_54A:
        move.w    (Hint_counter_reserve).w,(a5)
        move.w    #$8200|(VRAM_Plane_A_Name_Table/$400),(VDP_control_port).l    ; Set scroll A PNT base to $C000
       ...
    
    Vint0_noWater:
        move.w    (VDP_control_port).l,d0
        move.l    #vdpComm($0000,VSRAM,WRITE),(VDP_control_port).l
        move.l    (Vscroll_Factor).w,(VDP_data_port).l
       ...
        move.w    (Hint_counter_reserve).w,(VDP_control_port).l
        move.w    #$8200|(VRAM_Plane_A_Name_Table/$400),(VDP_control_port).l    ; Set scroll A PNT base to $C000
        move.l    (Vscroll_Factor_P2).w,(Vscroll_Factor_P2_HInt).w
    
        stopZ80
        dma68kToVDP Sprite_Table,VRAM_Sprite_Attribute_Table,VRAM_Sprite_Attribute_Table_Size,VRAM
        bsr.w    sndDriverInput
        startZ80
    
        bra.w    VintRet
    Right... it performs some updates with the VDP. This is the culprit. While the graphics get decompressed, this routine messes with the VDP control port and fucks up the write address, but only if the game mode is set to the level game mode, which is the case here.

    There are 2 ways you can go about fixing this. First is to disable interrupts after EndgameCredits fades to black:
    Code:
    EndgameCredits:
        tst.b    (Credits_Trigger).w
        beq.w    .return
        bsr.w    Pal_FadeToBlack
        move    #$2700,sr        ; <-- ADD THIS
    or force EndgameCredits to use the ending game mode ID instead:
    Code:
    EndgameCredits:
        move.b    #GameModeID_EndingSequence,(Game_Mode).w    ; <-- ADD THIS
     
    DeltaW and giovanni.gen like this.
  11. giovanni.gen

    giovanni.gen It's still Joe-vanni, not Geo-vanni. Member

    Joined:
    Apr 16, 2015
    Messages:
    314
    Location:
    Italy
    Yeah, you did get ninja'd :p

    Still, appreciated the optimization for the credits jump code, so thanks for that!
     
  12. Miles Sebas Prower

    Miles Sebas Prower Newcomer Member

    Joined:
    Aug 22, 2023
    Messages:
    21
    Location:
    Alvarenga, Charallave
    So I was taking a look at Sonic 1 and Sonic 2, and I always saw that in Sonic 1 there's no such thing as getting a 1-UP for every 50000 points scored, and taking a look at the code for it in Sonic 1 and Sonic 2, there's no code for it in Sonic 1 to get you a extra life for every 50000 points, this was added since Sonic 2 and Sonic 3 (& Knuckles) where this actually happens, but not in Sonic 1. So how would I go about adding this feature? (For Sonic 1 specifically, specifically for the Hivebrain 2005 disassembly)
     
  13. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,380
    Location:
    your mom
    It was added in REV01, and you can see it in the latest disassembly here.
     
    JGamer2151 likes this.
  14. JGamer2151

    JGamer2151 Well-Known Member/Lurker Member

    Joined:
    Dec 1, 2020
    Messages:
    97
    I’m sure this is already well-known by this point, but from what I recall, the Hivebrain 2005 disassembly of Sonic 1 was based on the REV00 revision of Sonic 1; the later SVN/HG/GitHub disassemblies of Sonic 1 included REV01 (and to a lesser extent, REVXB, the revision from Sonic Mega Collection with the "Spike Bug Fix").
     
  15. Miles Sebas Prower

    Miles Sebas Prower Newcomer Member

    Joined:
    Aug 22, 2023
    Messages:
    21
    Location:
    Alvarenga, Charallave
    Okay, I used the code as a reference and added it to the source code, and I compiled the rom hack, but I now got a problem, now the score counter doesn't add the points it's supposed to, I got half of what I wanted and what I did not, because every badnik destroyed, of course it gives me the points it should, but at the same time not, because it gives me 50000 for every badnik (Motobugs, Crab-Bots, Jaws, etc.) destroyed, (Ex, one badnik gives me 50100, two badniks destroyed gives me 100300, three gives me 150800, and so on), not to mention that the 1-UP theme is not playing after every 50000 points as it should after updating the lives counter, that by the way, of course the game updates the lives counter as it should, what should I do to correct this? I know that this is by the RAM address I've must put to it that causes the issue with the score counter, but I'm not sure what about the lives counter. Anyways, here's the code if I can get an explanation to what's with it

    Code:
    AddPoints:
            move.b    #1,($FFFFFE1F).w ; set score counter to    update
            lea    ($FFFFFFC0).w,a2
            lea    ($FFFFFE26).w,a3
            add.l    d0,(a3)        ; add d0*10 to the score
            move.l    #999999,d1
            cmp.l    (a3),d1 ; is score below 999999?
            bhi.w    loc_1C6AC    ; if yes, branch
            move.l    d1,(a3) ; reset score to 999999
    
    loc_1C6AC:
            move.l    (a3),d0
            cmp.l    (a2),d0 ; has Sonic got 50000+ points?
            blo.s    locret_1C6B6 ; if not, branch
            addi.l    #5000,($FFFFFE26).w ; increase requirement by 50000
            addq.b    #1,($FFFFFE12).w ; give extra life
            addq.b    #1,($FFFFFE1C).w
            move.w    #88,d0
            jmp    (PlaySound).l
    
    locret_1C6B6:
            rts    
     
  16. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,380
    Location:
    your mom
    Look more closely at the REV01 code. It doesn't make use of the a2 register at all, only REV00 does. You're supposed to be comparing against the 1UP score threshold.
     
  17. Miles Sebas Prower

    Miles Sebas Prower Newcomer Member

    Joined:
    Aug 22, 2023
    Messages:
    21
    Location:
    Alvarenga, Charallave
    Yeah, I can see that, I noticed it earlier, so I took the a2 line out, but the result I got wasn't good, in the level, everything is fine (Except it doesn't update the lives counter after 50000 points as it's supposed to like it does in REV01 and Sonic 2), but when I enter the giant ring, well... again the issue with the score counter

    So how would I go about getting it to work properly, and what's the RAM address that I have to look for that I must have missed that ensures the player gets a 1-UP after every 50000 points? (Like, you know, to get it to work like in REV01 and Sonic 2)
     
  18. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,380
    Location:
    your mom
    The variables file directly tell you which variable goes to which RAM address. "v_scorelife" replaces "v_scorecopy" at address $(FF)FFFFC0 in REV01 (which does actually mean that with your above code, you COULD use (a2), you'd just need to add the $5000 to that instead of $(FF)FFFE26, which is the direct score value, not the 1UP threshold).

    I also forgot to mention that you'll need to initialize "v_scorelife", too. See PlayLevel and Demo_Level. Whoops.
     
    Last edited: Sep 6, 2023
  19. Miles Sebas Prower

    Miles Sebas Prower Newcomer Member

    Joined:
    Aug 22, 2023
    Messages:
    21
    Location:
    Alvarenga, Charallave
    Gotcha. I got it now working just fine, now it gives me a extra life after every 50000 points as it should, and updates the lives counter like how it should. But I have one more problem with this. Usually the 1-UP theme plays after you either get 100 rings or destroy a 1-UP monitor, or after every 50000 points you get in REV01, Sonic 2 and Sonic 3 & Knuckles. In the rom hack, okay, it works just fine when I get either 100 rings or destroy the 1-UP monitor, either way, it plays, everything fine, however, I can not say the same about it when I get 50000 points, because, the theme doesn't play after every 50000 points, instead the game simply updates the lives counter, and of course it does like how it should. Something is off, does this have to do with the commands to play the theme?
     
  20. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,380
    Location:
    your mom
    Code:
           move.w    #88,d0
    You forgot to place a "$" before "88". Without it, you are setting d0 to just plain decimal 88, which is $58 in hexadecimal, which isn't a valid song ID. Adding the "$" will make it hexadecimal, turning it into the 1UP song ID.