Basic Questions and Answers Thread

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

  1. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    The sprite mappings for the HUD will need modifying, both the text and the numbers of the HUD have their art setup specifically for the sprite's rendering. Every HUD sprite will be given a shape that has a tile height usually of 2 (not sure why they didn't use 4 for the top but there you go), and the width is variable depending on the text/numbers. Usually these will be 4 width to make the most of a single sprite. Sprites render vertically first then horizontally afterwards, so every text/number is rendered top tile first, then second tile after, followed by the next digit/character's top tile, then bottom tile.

    To change the HUD such that it is 1 tile height, the shape of every sprite needs to be altered. Usually these sprites are D (for 2 height and 4 width, reducing this by 1 will reduce the height to 1, though, this will ruin the order of the tiles). However, I believe judging by your post, you've already modified the number rendering routine such that it already renders 1 tile at a time (and in order), so the sprite rearrangement should fall in-line with your modification.

    The VRAM addresses of the sprites will also need adjustments, the problem is, since we don't know the order of the text/number font/tiles in VRAM for your HUD, it's impossible to give you the exact shapes/pattern index. Another thing is, we don't know which game you are modifying, so it's difficult to give methods of modifications required.

    I will move onto the art rendering in Sonic 1 as an example:

    Code:
    loc_1C8FE:
    		tst.w	d4
    		beq.s	loc_1C92C
    		lsl.w	#6,d2		; <- Change to 5 (shift 6 is x40 (2 tiles), shift 5 is x20 (1 tile))
    		move.l	d0,4(a6)
    		lea	(a1,d2.w),a3
    		move.l	(a3)+,(a6)
    		move.l	(a3)+,(a6)
    		move.l	(a3)+,(a6)
    		move.l	(a3)+,(a6)
    		move.l	(a3)+,(a6)
    		move.l	(a3)+,(a6)
    		move.l	(a3)+,(a6)
    		move.l	(a3)+,(a6)
    		move.l	(a3)+,(a6)		; <- Remove these 8 lines, this is the second tile.
    		move.l	(a3)+,(a6)		; <- Remove
    		move.l	(a3)+,(a6)		; <- Remove
    		move.l	(a3)+,(a6)		; <- Remove
    		move.l	(a3)+,(a6)		; <- Remove
    		move.l	(a3)+,(a6)		; <- Remove
    		move.l	(a3)+,(a6)		; <- Remove
    		move.l	(a3)+,(a6)		; <- Remove
    
    loc_1C92C:
    		addi.l	#$200000,d0		; <- VRAM advancement to 20 bytes rather than 40
    		dbf	d6,Hud_ScoreLoop
    
    		rts	 
    Keep in mind the uncompressed number tile art will need to be digits 0 to 9 in order, one tile each.
     
    Last edited: Aug 14, 2019
    AsuharaMoon and ProjectFM like this.
  2. AsuharaMoon

    AsuharaMoon kakyoin did you lay this egg Member

    Joined:
    Aug 15, 2013
    Messages:
    67
    Great! It worked out fine enough, but there's still one last thing:

    [​IMG]

    Hud_LoadZero / Hud_Base seems to work a bit different that the others (I guess?), so.. yeah. I don't know where to begin with this.
     
  3. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    There is:

    Code:
    		move.w	#$F,d1
    Change the F to 7.
     
    AsuharaMoon likes this.
  4. Giovanni

    Giovanni It's Joe-vanni, not Geo-vanni. Member

    Joined:
    Apr 16, 2015
    Messages:
    311
    Location:
    Italy
    How do I make Sonic 1's Level Select start from a selection different from 0?
     
  5. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Right above "MainGameLoop:" you will see:

    Code:
    		move.b	#0,($FFFFF600).w ; set Game Mode to Sega Screen
    Put this in just below it (but above MainGameLoop):

    Code:
    		move.w	#4,($FFFFFF82).w	; set level select Y position
     
    nineko and Giovanni like this.
  6. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    Does anyone know how to create images with built in palettes for use in importing into sonlvl? It has the feature to use an images built in, preexisting color order to assign colors to it (I often end up having to change the image format to work around this even), but I've no idea how to look at these built in palettes at all, let alone rearrange them. I vaguely recall that there's programs out there that lets you modify them, but I can't seem to search for them properly; I just get a bunch of silly tools to help artists find colors they like.
     
  7. nineko

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,902
    Location:
    italy
    Older versions of Paint Shop Pro (such as 5, which is easy to... make it work for more than 30 days) allow you to see and alter the palette of indexed images. I'd post a screenshot but I won't be at home until tomorrow.

    Besides, I'm sure someone else will recommend some more modern alternative soon. It's just that, unsurprisingly, I like to work with older software.
     
    Animemaster and Pacca like this.
  8. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    Your suggestion jogged my memory and ended up leading me to search for indexed images! I found gimp does exactly what I need, if your looking for a similar solution!
     
  9. AkumaYin

    AkumaYin Well-Known Member Exiled

    Joined:
    Aug 21, 2014
    Messages:
    157
    I'd like to know more about Sonic 3K's routine for rendering sprites; specifically, how it differs in functionality from that of the previous two games, and how it can be used to display sprites that aren't attached to objects. If someone would be willing to give an explanation of the code in question, that would be much appreciated.
     
  10. Devon

    Devon Down you're going... down you're going... Member

    Joined:
    Aug 26, 2013
    Messages:
    1,372
    Location:
    your mom
    One major difference is the way it handles the link value for each sprite. Rather than setting the link value for each sprite and then set the last sprite's link value to 0, like it does in Sonic 1 and 2, it sets the link values for every sprite slot at the start of the game mode, making it so that the sprite renderer doesn't have to set them every frame. I believe that for every unused sprite slot, it just moves them offscreen.

    Sonic 2 and 3K also feature a "child sprite" (or "sub sprite") feature where you can sacrifce some object RAM in order to be able to independently draw another sprite or 2 within that object. The bridge object uses this to render multiple logs in 1 object. Same with any swinging platform held by a chain of some sort.

    I am pretty sure you can call the routine that actually parses the sprite frame mapping data independently from the object sprite rendering routine for all 3 games, you'd just need to specify the parameters correctly. I know Sonic 2 and 3K does so to draw the HUD at the very start of the routine, and also calls a separate routine to render rings, all before it starts rendering the actual objects. (Sonic 1's HUD and rings were objects, fyi, but not in Sonic 2 and 3K, to save object RAM).

    Child sprites use a separate routine to send data to the sprite cache that checks if each sprite piece is on screen.

    Any other differences I can think of is mainly minor little changes for optimization and to account for the different mappings format.

    I guess it is worth noting that in Sonic 1, you can set which camera position (foreground, background deformation 1, background deformation 2, etc.) you want the object's sprite be drawn relative to. This funcionality was removed in Sonic 2, most likely because it was never really used AFAIK, but don't quote me on that.

    And also the fact that for the "render at screen coordinates" flag, Sonic 1 and 2 used the X position's lower word for the Y position. Sonic 3K just used the standard Y position variable.
     
    Last edited: Aug 30, 2019
  11. Picayune

    Picayune Newcomer Member

    Joined:
    Dec 12, 2018
    Messages:
    22
    Location:
    Ohio
    So I was wondering how do you port ristar music over to sonic 1?
     
  12. AURORA☆FIELDS

    AURORA☆FIELDS so uh yes Exiled

    Joined:
    Oct 7, 2011
    Messages:
    759
    There are many ways to port music from one SMPS game to another, however, I like converting the music to ASM format first, then editing it in such a way that it is compatible with the game I want (in this case, Sonic 1), and including the music in ASM format inside of the game. To make this process a lot easier, I've written a custom SMPS2ASM tool which can be downloaded with this program. Conveniently, it already includes data for converting Ristar music. To get the music files itself, I always use SMPS Research Pack, but any way you can find the data files for the game will work, provided it is in the original format.

    Ristar is a bit of a special case, since it has 2 DAC channels, instead of 1 in most games (including Sonic 1). Additionally, it uses a lot of DAC samples which Sonic 1 by default will be unable to support. Opting for Mega PCM or Dual PCM (or a fully custom sound driver such as AMPS) may be required for accurate ports. SMPS Research Pack will also include the DAC used in the game, but they will have to be converted to appropriate format for use in Sonic 1, Dual PCM or Mega PCM, mainly because the sample rate will be different. You can use tools such as Audacity to import these samples into the program and exporting them back with the correct sample rate, or in the case of Dual PCM and Mega PCM, you can export to .wav file (provided it is still unsigned 8-bit PCM!). In the ASM file itself, you will have to create new equates to identify your samples, and replace all references to old sample names (by default, my SMPS2ASM will have names such as d81, d82, etc.) so that the samples will have correct ID's when built. If you are not using Dual PCM, you will have to either merge the 2 sample channels into 1, or just ditch one of them completely.

    You will also need to port the PSG volume envelopes, or replace them with equivalent or similar ones. This ensures the PSG sounds are as accurate as possible to the original. Ristar may use different end flags for PSG envelopes that are not supported by Sonic 1. In this case, not a whole lot can be done about it. Additionally, Ristar may use modulation envelopes, which again are not supported by Sonic 1 and will have to be removed.

    Other features such as LFO, SSG-EG, pitch slides, what have you may be used. These will have to be emulated through software or removed completely since Sonic 1 does not support these either.

    Also do note, if you use my SMPS2ASM for converting to ASM, you must also use the SMPS2ASM definitions file from the "MegaPCM" folder, as these settings are equivalent to Sonic 1 and will work without an issue. Attempting to use anyone elses SMPS2ASM definitions will not work with files disassembled using mine, as naming conventions are different and therefore incompatible.

    Porting music is not very easy, especially from a more featured game such as Ristar to a far less featured like Sonic 1. Unfortunately, there is not much that can be done about that, and you will have to learn what to do in each instance. However, despite the lacking features, you can get fairly accurate ports if you put enough effort towards it.
     
    MarkeyJester, Devon and Picayune like this.
  13. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    On a side note; I would love to hear how clean Ristar's vocals/percussion would've been if it weren't for the obvious interruptions. Would be nice to get them ported over to a cleaner driver and get hardware recordings of the music.
     
    Picayune and AURORA☆FIELDS like this.
  14. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    Isn't that basically what SMPSPlay does?
     
    TheInvisibleSun and Joshwoakes like this.
  15. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    No, please re-read my post.
     
    AkumaYin and AURORA☆FIELDS like this.
  16. DeltaWooloo

    DeltaWooloo The noob next door Member

    Joined:
    Aug 7, 2019
    Messages:
    373
    Hey guys,

    Here is something strange about my hack. When I test my hack on Fusion, it works normally. But then I use Regen, there is some glitchy mess or the game crashes. This is the same with MD.EMU on my Galaxy S9+. Pure crashes. Do you know the reason why and possible to fix?

    BTW, I'm using the Sonic 1 Hivebrain 2005 disassembly
     
    Last edited: Oct 9, 2019
  17. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    The most common cause is the Motorola 68k's inability to access a word from an odd offset, due to the 16-bit bus. Attempting word odd address accesses triggers an address error. Emulators which do not emulate this behaviour will either; read the upper byte of the 16-bit entry as the lower and the lower as the upper, or they will attempt to access the next 16-bit entry and use that upper byte as the lower, in these instances, the CPU will continue.

    A few other causes can be; timing issues (usually with the VDP), incorrect latching and/or FIFO access, DMA fill/copy issues, reading from or writing to prohibited or reserved offsets in the CPU memory map, or incorrect Z80 bus request responses (such as requesting a stop when it's already stopped, the Z80 will not reset the flag, thus a software lock).

    But I am highly certain the one in the first paragraph is your issue. Ensure that all incbin/binclude'd files have "even" after them, as well as all "dc" directive tables which are byte sequenced in some way, and ensure no address registers are reading/writing words from odd offsets, or ensure you don't directly access a word on an odd address.
     
    Kilo likes this.
  18. warr1or2

    warr1or2 I AM CLG Member

    Joined:
    Apr 7, 2008
    Messages:
    416
    Location:
    Town Creek, AL
    I've been away from Sonic Hacking for a while (Real life issues), but I seem to have gotten rusty.
    All I'm trying to do is have a basic Super Sonic from a jumpdash code.
    Code:
    ; ===========================================================================
    ; ---------------------------------------------------------------------------
    ; subroutine to turn Sonic Super (Yeah I'm At it again)
    ; ---------------------------------------------------------------------------
    Super:   tst.b (SuperRam).w
       bne Super_Rts
    (The problem is somewhere from here)
       ;cmpi.b #$32,(Rings).w
       ;blt Super_Rts
       ;cmpi.b #2,Status(a0)
       ;Bne Super_Rts
    (to here keeping it from working)
       btst #7,Status(a0) ; was  flag set?
       bne Super_Rts ; if yes, branch
    (and here)
       move.b (ButtonPress),d0  ($F603)
       cmpi.b #ButtonA,d0 ($40)
       beq.w Super_Rts ; if not, branch
    (to here which ONLY A after a jump should activate, but activates the same time during a jump)
       cmpi.b #2,Animation(a0) ; is Sonic rolling?
       bne Super_Rts ; if no, branch
       bset #7,Status(a0) ; set Jump Dash flag
       move.b #1,(SuperRam).w
    The_Super_Monitor:  move.b #1,($FFFFFE2D).w ; make Sonic invincible
     
      move.b #4,($FFFFD2DC).w
      Move.w #$00EE,($FFFFFB04)
      Move.w #$00EE,($FFFFFB06)
      Move.w #$00EE,($FFFFFB08)
      Move.w #$00EE,($FFFFFB0A)
     
      move.w #$06,d0
      jsr (PlaySound).l ; play invincibility musicb
       move.b #$13,Animation(a0) ; ++ use the spring animation
       bset #2,Status(a0) ; ++ clear the "jumping or rolling" flag
      
     
     
    Super_Rts:   rts
    
    What is it I'm doing wrong?
     
    Last edited: Sep 18, 2019
  19. Samey

    Samey Le Bored Hedgie Member

    Joined:
    May 3, 2017
    Messages:
    57
    So I'm still working on my peelout.
    Turns out whatever I did before really messed with Labyrinth Zone (I added special underwater walking sprites which is why)

    I took a look at the original peelout code, and I tried this:

    Code:
            cmpi.b    #$1E,$3A(a0)                    ; is it maxed?
            beq.s    Sonic_SuperPeeloutResetScr        ; if yes, cap it
            addi.b    #1,$3A(a0)                        ; add 1 to timer
            addi.b    #1,$14(a0)                        ; adds 1 to inertia (for anim) TOO FAST.
            jmp   Sonic_SuperPeeloutResetScr
    Its just the code telling it how long to charge, and I have added a line that changes Sonic's Inertia while its doing the timer.
    Everything works fine, except the charging animation happens in splitsecond.

    How would I have it add up slower?

    Heres what it looks like right now:
    https://imgur.com/a/3KvYopl
     
  20. Devon

    Devon Down you're going... down you're going... Member

    Joined:
    Aug 26, 2013
    Messages:
    1,372
    Location:
    your mom
    $14(a0) is 16 bits, so you should be using addi.w. Will give you extra precision to work with. In Sonic CD, the value it uses is 100 (decimal, $64 hexadecimal).

    And just an FYI, just in case, the max charge up value is Sonic's current max speed * 2 without speed shoes, or the current max speed * 2 minus the max speed / 2 with speed shoes. Unsure if you already have that in, but judging from the GIF, you probably already did.
     
    Last edited: Sep 24, 2019
    Samey and MarkeyJester like this.