Basic Questions and Answers Thread

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

  1. Pacca

    Pacca Level 1 inflatable otter thing Member

    Joined:
    Jul 5, 2014
    Messages:
    1,106
    Location:
    Twinleaf Town
    Thanks for cleaning it up! It works just fine now. There was only one minor problem I found but it was an easy fix. The value in d1 was different then what your touch_chkvalue optimization was expecting, so it'd use incorrect routines for lower values, and used garbage pointers past the end of the list on higher ones. It was a simple fix though, I just added this line before it:
    Code:
        asr.w    #1,d1    ;shift back to get the list pointer
        move.l    TouchRoutines-4(pc,d1.w),-(sp)    ; load routine
        rts                    ; run routine
    
    It does make the code ever so slightly slower, I suppose, but I'd much rather it happen here then in the collision detection code. Thanks for taking the time, it really helps.
     
    MarkeyJester likes this.
  2. RuthlessTheHooman

    RuthlessTheHooman Bad at choosing usernames Member

    Joined:
    Nov 20, 2016
    Messages:
    23
    Location:
    Rocky Ruin Zone
    I've been dipping my toes in hacking Sonic 2, and one thing that I want to know better is how to do music.

    What I'm asking is, what's the best way to make music for Sonic 2? I've never successfully put original music in it so I want to know how to do so.
    I've tried adding new sound drivers (S1, Clone Driver V2) but it's never worked.

    Also, can mid2smps make music for Sonic 2?

    Thanks in advance.
     
  3. Pacca

    Pacca Level 1 inflatable otter thing Member

    Joined:
    Jul 5, 2014
    Messages:
    1,106
    Location:
    Twinleaf Town
    I've only ever used the Clone Driver v2, but from what I've seen, I'd recommend starting with just SMPS2ASM. It allows you to easily swap music between games (especially from the Sonic 1 format, I use them with SMPS2ASM all the time), and doesn't require tearing the entire sound driver out and setting up a new one. It even gives more performance for your hack, since you'd be using the Vanilla S2 driver, which runs on the Z80 and leaves the 68k more time to process game play.

    I likely would have switched myself if I wasn't so found of having higher quality PCM samples that are simple to add. I wouldn't recommend messing with that stuff as a beginner, and it isn't worth the potential performance drop if you don't use it.
     
  4. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    814
    All you need to do to add music to Sonic 2 is set the 'uncompressed' flag for the slot in the playlist in the Z80 sound driver ASM file. Then just include the song you want as ASM with the rest of the music.
     
  5. RuthlessTheHooman

    RuthlessTheHooman Bad at choosing usernames Member

    Joined:
    Nov 20, 2016
    Messages:
    23
    Location:
    Rocky Ruin Zone
    Alright, I'm going to sound like a total noob, but I'm using Xenowhirl. (The SSRG splash version.) The driver is a .bin file. The reason I don't use Git is that the code is all compacted.

    I'm going to give the Clone driver (V2) another chance, but could I ask where some free ram is? (Also, sorry if any info is wrong as I'm in a car and can't use my laptop.)


    Edit: I found the asm file I needed, problem solved.
     
    Last edited: Sep 15, 2018 at 1:53 AM
  6. Pacca

    Pacca Level 1 inflatable otter thing Member

    Joined:
    Jul 5, 2014
    Messages:
    1,106
    Location:
    Twinleaf Town
    I think you might have missed the point I was trying to get across; I do not recommend starting out with the Clone Driver v2. Installing it is difficult, it slows down your hack, and wastes useful RAM. Although SMPS2ASM is included with the Clone Driver v2, it is also its' own stand alone utility, and is compatible with the sound driver that your Sonic 2 project already has preinstalled. Either way, you'd need to figure out how to use SMPS2ASM, but using it without the Clone Driver v2 gives you almost all of it's benefits, without any of the problems the Clone Driver v2 might cause. The few benefits the Clone Driver v2 brings likely aren't things you care about, anyways.
     
  7. Samey

    Samey Newcomer Member

    Joined:
    May 3, 2017
    Messages:
    13
    Hallo again, I've decided to try and add extra frames to the rings in Sonic 1. I've gotten the art all done, I had the mappings all set up.
    The problem is, the animation looks like this:
    https://i.imgur.com/qkMGWiS.gif

    I think this is something to do with the vram but I have no clue on where in the code I'd fix this issue...
    Edit: I'm using the Hivebrain 2005 disassembly if it helps.
    Edit 2: Just realized I massively screwed up the Special stage ring... Changed it so it uses the unused timer
     
    Last edited: Sep 15, 2018 at 4:06 AM
  8. Pacca

    Pacca Level 1 inflatable otter thing Member

    Joined:
    Jul 5, 2014
    Messages:
    1,106
    Location:
    Twinleaf Town
    The game stores all the graphics that can be rendered in a space called "VRAM" (short for Video RAM, if that helps you remember). It stores all the data that the Genesis can use to display artwork on the screen. Like any other form of RAM, it is limited, and it does have an end to it. Furthermore, since we're hacking what was intended to be a complete standalone game, most if not all of that VRAM will be in use or reserved by the original game.

    In this case, your trying to added extra graphics to the rings. While your graphics editor will do this just fine, and the game will attempt to load and display them like normal, there is a problem. The Sonic games use of VRAM assumes that the rings artwork will always be it's original size, so making it larger cause it to spread into VRAM that is actually used by Sonic 1s' graphics engine.

    Here's a picture showing what is in VRAM around the rings artwork in Vanilla Sonic 1:
    [​IMG]
    First, you can see some weird junk, which is actually used; when you see junk like that, it's the game doing important graphics stuff, so don't touch it. After that is some of Sonics' artwork, followed by the artwork for the points graphics. As you can see, it's carefully setup so that everything just barely fits together; adding even 1 or 2 extra tiles to Sonics' art could make the points art appear instead.

    Fast forwarding to the rings art (it's red here, but it is the real rings art), you can see that it fits very snugly next to some weird junk that's immediately after it. Your extra frames extend the artwork forward, causing the sparkle artwork at the end to conflict with the weird junk that comes after. Since the game is constantly changing the weird junk during gameplay, it overwrites the sparkle graphics, causing them to render the weird junk instead.

    Fixing this type of thing is a real hassle; I've been struggling with it myself. The best way to do it would be to find more free space, and move the ring graphics. Sadly, this is a painful and annoying procedure, especially in the Hivebrain disassembly, but it's not impossible. Like I said earlier, Sonic 1 already uses virtually all of the VRAM available, and any that isn't used in one case might be used in another, like in another zone. You do have some options, though. SuperEgg made a very helpful guide that makes the Shield and Invincibility stars take up less space in VRAM, freeing up a huge space that you can do whatever you want with.

    To move the rings art, you'll have to change some numbers in two places; where the art is loaded, and where the art is used. In this case, the art is loaded when starting a new level, and it is used by the ring object. Since the guide I mentioned earlier frees up lots of VRAM past tile $560, I'll move the rings art to tile $560 in this example. Keep in mind, you could attempt to use or load art from any location in VRAM like this, although it will most likely already be used.

    First, the ring object. Under "Obj25_MakeRings:", you should find this:
    Code:
            move.b    #$25,0(a1)    ; load ring object
            addq.b    #2,$24(a1)
            move.w    d2,8(a1)    ; set x-axis position based on d2
            move.w    8(a0),$32(a1)
            move.w    d3,$C(a1)    ; set y-axis position based on d3
            move.l    #Map_obj25,4(a1)
            move.w    #$27B2,2(a1)
            move.b    #4,1(a1)
            move.b    #2,$18(a1)
            move.b    #$47,$20(a1)
            move.b    #8,$19(a1)
            move.b    $23(a0),$23(a1)
            move.b    d1,$34(a1)
    
    A lot of important stuff is happening here, although sadly, the Hivebrain disassembly does not explain it very well. What we want to worry about right now, however, is the line "move.w #$27B2,2(a1)". An object can store lots of information about itself, and it does this using a number followed by "(a0)" or "(a1)". The value typically stored in 2(a0) or 2(a1) is the location of the art it should display in VRAM, plus some other weirdness involving colors and sprite priority.

    Conveniently, the first hex digit (2 in this case) holds all that extra weirdness, so as long as we don't touch it, we shouldn't have to worry about it. The lower 3 digits, however, are the location of the old rings art in VRAM! Since we're moving the rings to tile $560, just replace the "7B2" with "560" and the rings should now attempt to use the art there instead. Now we just need to load the rings art in the new location, so the rings actually render what we want them too, instead of whatever is left in that unused space (provided you followed SuperEggs guide).

    The Hivebrain disassembly split this part away from the main asm file, for some reason. It's in "_inc/Pattern load cues.asm". This file holds a bunch of data that the game uses to know what artwork to load at the start of a level and where. All sorts of neat stuff is in here, like the art locations for badniks, and level hazards in each zone, and much more! What we're looking for though, is in "PLC_Main:", which holds the artwork that is shared by all stages:
    Code:
    PLC_Main:    dc.w 4
            dc.l Nem_Lamp        ; lamppost
            dc.w $D800
            dc.l Nem_Hud        ; HUD
            dc.w $D940
            dc.l Nem_Lives        ; lives    counter
            dc.w $FA80
            dc.l Nem_Ring        ; rings
            dc.w $F640
            dc.l Nem_Points        ; points from enemy
            dc.w $F2E0
    
    As you can see, the rings art is in here! The way it's stored here, however, is in a different format, that doesn't use tiles. Since $560 is the tile we want to move to, and this doesn't use tiles, it looks pretty confusing. It can be fixed by just adding "<<5" after the VRAM tile address we want to use though, which converts it for us! Just replace the "$F640" that comes after the Nem_Ring reference with "$560<<5", and it should load the new ring art at the correct location!

    It should work just fine after that. Whew, that was quite the text dump, I've been meaning to write something like this for a while. Keep in mind, I haven't tested all of it myself, so there may be some problems that slipped in. If your curious about anything else VRAM related, I highly recommend getting a copy of the Regen emulator with debugging tools. It has a very helpful VRAM viewer that clearly shows what is loaded where (I used it to get the screenshot example near the start of this post).
     
  9. Samey

    Samey Newcomer Member

    Joined:
    May 3, 2017
    Messages:
    13
    Thanks! I'll see if I can get it to work. :)
    Edit: So, I got the shield and invincibility stars optimized, but theres a few bugs...
    Bugs are, some of the invincibility art is overwritten by some of the rings. :confused:
    And also, the trail for the invincibility, no longer actually flips around if you flip around, and it just looks off.
    I'm honestly thinking I shouldn't of bothered messing with the rings rn.

    I've also went ahead and tried seeing if it was just a problem with my hack or if it was the guide, or how I followed it.

    So I went and redid SuperEgg's guide in a completely clean disassembly, and the exact same thing happened. I messed around a bit with moving where the shield and invincibility stars art is loaded but nothing seemed to really change.
    And the sign posts sparkles are screwed too, I'ma see if I can fix this first.

    On the bright side, the rings are perfectly normal now.
     
    Last edited: Sep 15, 2018 at 10:37 PM
  10. Pacca

    Pacca Level 1 inflatable otter thing Member

    Joined:
    Jul 5, 2014
    Messages:
    1,106
    Location:
    Twinleaf Town
    Hm, I'm not sure what went off with the SuperEgg guide, but I can see what happened with the signpost sparkles. The signpost sparkles reuse the rings artwork, and since we moved it, and didn't update the sparkles, it's trying to use the old VRAM location for the rings. Take a look underneath "Obj0D_Sparkle:", it should be an easy fix given what I wrote before ;)
     
  11. Samey

    Samey Newcomer Member

    Joined:
    May 3, 2017
    Messages:
    13
    Yeah, I fixed it easily shortly after making the edit, the rings that Sonic spews out when it were messed up too (fixed em aswell) :p
    As for the invincibility, I've been trying to see what to do with fixing at least the visual bug. Looks like I might need to move the rings a tiny bit, and afterwards I'm going to compare the new and old routines for the trails to see if I can fix whats up with the trails.

    Edit: found a new bug... When you complete a special stage and start up a new level, the rings, instead of loading in the ring tiles, instead keep the continue icons tiles. This is probably why it looked like Sonic was overriding part of the invincibility because it also overrides part of the invincibility tiles... And also the rings inside the special stage appear to have ceased to exist, and it doesn't look like I can remedy it...:(
    Edit#200: Alright! I fixed the invincibility stars being overwritten!

    In SuperEgg's guide theres this code:

    Code:
    Obj38:                                  ; XREF: Obj_Index
            move.l  #UnC_Shield,d1                            ; Call for Regular Shield Art
            move.w  #$A820,d2                                ; Load Art from this location (VRAM location*20)
                                                            ; In this case, VRAM = $541*20
            move.w  #$200,d3
            jsr     (QueueDMATransfer).l
    And

    Code:
    Obj4A:                                  ; XREF: Obj_Index
            move.l  #UnC_Stars,d1
            move.w  #$A820,d2
            move.w  #$200,d3
            jsr     (QueueDMATransfer).l
    If you just change
    move.w #$200,d3
    to
    move.w #$240,d3
    The Invincibility stars won't be overwritten. :D

    So, the only problems I seem to have, at the moment are:
    the rings fail to reload when the level reloads (this is especially apparent after exiting a special stage)
    And the rings fail to appear in the special stage (and they are gonna majorly mess up the special stage if they are loaded where the rest of the game is going to load them...)
     
    Last edited: Sep 16, 2018 at 3:44 AM
    Pacca likes this.