Basic Questions and Answers Thread

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

  1. Natsumi

    Natsumi Phoenix egg Member

    Joined:
    Oct 7, 2011
    Messages:
    677
    Location:
    Long and dangerous river
    You can just google them and you find plenty good ones. I use HxD but not really for any specific reason.
     
  2. Iso Kilo

    Iso Kilo Local Idiot Member

    Joined:
    Oct 9, 2017
    Messages:
    112
    Location:
    Small Town in BC, Canada
    As Main and Natsumi said; a hex editor, pretty obvious. (I also use HxD) But if I recall, there is a tutorial by Ashuro on the matter in the archived section. I personally haven't looked at it, so I can't confirm whether it's actually useful or not.
     
    Tanman Tanner likes this.
  3. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    844
    The format of the file is extremely simple: each act of each zone has two bytes indicating the zone and act to go to after completion. Keeping in mind that each zone in Sonic 1 has four acts internally, the offset for any level's data can be calculated with (zone ID * 8) + (act ID * 2).
     
    Tanman Tanner likes this.
  4. nineko

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,759
    Location:
    italy
    Hur.

    I can't believe that such a program didn't exist yet.
     
  5. Samey

    Samey Le Bored Hedgie Member

    Joined:
    May 3, 2017
    Messages:
    24
    [edit please delete thiscomment]
     
    maple_t likes this.
  6. Cofahi

    Cofahi Newcomer Trialist

    Joined:
    Dec 14, 2018
    Messages:
    5
    I tried to port the ReadySonic disassembly wall jump to Sonic 2, but it doesn't seem to work.
    Code:
    Sonic_DoLevelCollision:
        move.l    #Primary_Collision,(Collision_addr).w
        cmpi.b    #$C,layer(a0)
        beq.s    +
        move.l    #Secondary_Collision,(Collision_addr).w
    +
        move.b    layer_plus(a0),d5
        move.w    x_vel(a0),d1
            move.w    y_vel(a0),d2
            jsr    (CalcAngle).l
            move.b    d0,($FFFFFFEC).w
            subi.b    #$20,d0
            move.b    d0,($FFFFFFED).w
            andi.b    #$C0,d0
            move.b    d0,($FFFFFFEE).w
            cmpi.b    #$40,d0
            beq.w    loc_13680
            cmpi.b    #$80,d0
            beq.w    loc_136E2
            cmpi.b    #$C0,d0
            beq.w    Sonic_HitRightWall
            bsr.w    CheckLeftWallDist
            tst.w    d1
            bpl.s    loc_135F0
            sub.w    d1,x_pos(a0)
            move.w    #0,x_vel(a0)
    
        if WallJumpActive=1    ;Mercury Wall Jump
            move.b    #button_left,d1
            bsr.w    WallJump
        endif    ;end Wall Jump
       
    loc_135F0:
            bsr.w    CheckRightWallDist
            tst.w    d1
            bpl.s    loc_13602
            add.w    d1,x_pos(a0)
            move.w    #0,x_vel(a0)
    
        if WallJumpActive=1    ;Mercury Wall Jump
            move.b    #button_right,d1
            bsr.w    WallJump
        endif    ;end Wall Jump
       
    loc_13602:
            bsr.w    Sonic_CheckFloor
            tst.w    d1
            bpl.s    locret_1367E
            move.b    y_vel(a0),d2
            addq.b    #8,d2
            neg.b    d2
            cmp.b    d2,d1
            bge.s    loc_1361E
            cmp.b    d2,d0
            blt.s    locret_1367E
    
    loc_1361E:
            add.w    d1,y_pos(a0)
            move.b    d3,angle(a0)
            bsr.w    Sonic_ResetOnFloor
            move.b    #0,Anim(a0)
            move.b    d3,d0
            addi.b    #$20,d0
            andi.b    #$40,d0
            bne.s    loc_1365C
            move.b    d3,d0
            addi.b    #$10,d0
            andi.b    #$20,d0
            beq.s    loc_1364E
            asr    y_vel(a0)
            bra.s    loc_13670
    ; ===========================================================================
    
    loc_1364E:
            move.w    #0,y_vel(a0)
            move.w    x_vel(a0),inertia(a0)
            rts
    ; ===========================================================================
    
    loc_1365C:
            move.w    #0,x_vel(a0)
            cmpi.w    #$FC0,y_vel(a0)
            ble.s    loc_13670
            move.w    #$FC0,y_vel(a0)
    
    loc_13670:
            move.w    y_vel(a0),inertia(a0)
            tst.b    d3
            bpl.s    locret_1367E
            neg.w    inertia(a0)
    
    locret_1367E:
            rts
    ; ===========================================================================
    
    loc_13680:
            bsr.w    CheckLeftWallDist
            tst.w    d1
            bpl.s    loc_1369A
            sub.w    d1,x_pos(a0)
            move.w    #0,x_vel(a0)
            move.w    y_vel(a0),inertia(a0)
            rts
    ; ===========================================================================
    
    loc_1369A:
            bsr.w    CheckCeilingDist
            tst.w    d1
            bpl.s    loc_136B4
            sub.w    d1,y_pos(a0)
            tst.w    y_vel(a0)
            bpl.s    locret_136B2
            move.w    #0,y_vel(a0)
    
    locret_136B2:
            rts
    ; ===========================================================================
    
    loc_136B4:
            tst.w    y_vel(a0)
            bmi.s    locret_136E0
            bsr.w    Sonic_CheckFloor
            tst.w    d1
            bpl.s    locret_136E0
            add.w    d1,y_pos(a0)
            move.b    d3,angle(a0)
            bsr.w    Sonic_ResetOnFloor
            move.b    #0,anim(a0)
            move.w    #0,y_vel(a0)
            move.w    x_vel(a0),inertia(a0)
    
    locret_136E0:
            rts
    ; ===========================================================================
    
    loc_136E2:
            bsr.w    CheckLeftWallDist
            tst.w    d1
            bpl.s    loc_136F4
            sub.w    d1,x_pos(a0)
            move.w    #0,x_vel(a0)
    
        if WallJumpActive=1    ;Mercury Wall Jump
            move.b    #button_left,d1
            bsr.w    WallJump
        endif    ;end Wall Jump
    
    loc_136F4:
            bsr.w    CheckRightWallDist
            tst.w    d1
            bpl.s    loc_13706
            add.w    d1,x_pos(a0)
            move.w    #0,x_vel(a0)
    
        if WallJumpActive=1    ;Mercury Wall Jump
            move.b    #button_right,d1
            bsr.w    WallJump
        endif    ;end Wall Jump
    
    loc_13706:
            bsr.w    CheckCeilingDist
            tst.w    d1
            bpl.s    locret_1373C
            sub.w    d1,y_pos(a0)
            move.b    d3,d0
            addi.b    #$20,d0
            andi.b    #$40,d0
            bne.s    loc_13726
            move.w    #0,y_vel(a0)
            rts
    ; ===========================================================================
    
    loc_13726:
            move.b    d3,angle(a0)
            bsr.w    Sonic_ResetOnFloor
            move.w    y_vel(a0),inertia(a0)
            tst.b    d3
            bpl.s    locret_1373C
            neg.w    inertia(a0)
    
    locret_1373C:
            rts
    ; ===========================================================================
    
    Sonic_HitRightWall:
            bsr.w    CheckRightWallDist
            tst.w    d1
            bpl.s    loc_13758
            add.w    d1,x_pos(a0)
            move.w    #0,x_vel(a0)
            move.w    y_vel(a0),inertia(a0)
            rts
    ; ===========================================================================
    
    loc_13758:
            bsr.w    CheckCeilingDist
            tst.w    d1
            bpl.s    loc_13772
            sub.w    d1,y_pos(a0)
            tst.w    y_vel(a0)
            bpl.s    locret_13770
            move.w    #0,y_vel(a0)
    
    locret_13770:
            rts
    ; ===========================================================================
    
    loc_13772:
            tst.w    y_vel(a0)
            bmi.s    locret_1379E
            bsr.w    Sonic_CheckFloor
            tst.w    d1
            bpl.s    locret_1379E
            add.w    d1,y_pos(a0)
            move.b    d3,angle(a0)
            bsr.w    Sonic_ResetOnFloor
            move.b    #0,anim(a0)
            move.w    #0,y_vel(a0)
            move.w    x_vel(a0),inertia(a0)
    
    locret_1379E:
            rts
    ; End of function Sonic_DolevelCollision
    
    
    
        if WallJumpActive=1    ;Mercury Wall Jump
    WallJump:
            tst.b    jumping(a0)    ;Mercury Constants
            beq.s    return_walljump
            tst.b    y_vel(a0)
            bmi.s    return_walljump
            move.b    ($FFFFF602).w,d0
            andi.b    #button_left_mask|button_right_mask,d0    ; keep just L and R state
            beq.s    return_walljump            ; fail if neither are pressed
            cmpi.b    #button_left_mask|button_right_mask,d0    ; fail if both are pressed
            beq.s    return_walljump
            and.b    d1,d0            ; keep only L or R depending on d1
            beq.s    return_walljump            ; fail if not pressed
            move.b    d0,obWallJump+1(a0)    ; remember them
            move.w    #0,y_vel(a0)
            move.b    #$18,obWallJump(a0)    ;Mercury Constants
            clr.b    jumping(a0)
            move.b    #2,anim(a0)
       
        return_walljump:
            rts
        endif    ;end Wall Jump
    I also added in other Sonic routines!

    Code:
    
    
    Obj01_Control:
        if WallJumpActive=1    ;Mercury Wall Jump
            tst.b    obWallJump(a0)
            beq.s    nodec
            subq.b    #1,obWallJump(a0)
            bne.s    chkLR
            move.b    #2,anim(a0) ; use "jumping" animation
       
    chkLR:
            move.b    ($FFFFF602).w,d0    ; get jpad
            and.b    #obWallJump+1,d0    ; compare jpad to stored L,R button states
            bne.s    skipa        ; if still held, branch
            move.w    #0,obWallJump(a0)    ; clear wall jump flag and button states
            move.b    #2,anim(a0) ; use "jumping" animation
     
    skipa:
            ;Mercury Wall Jump Smoke Puff
            ;USES Smoke Puff
        ;    move.b    (v_framebyte).w,d0
        ;    andi.b    #7,d0
        ;    cmpi.b    #7,d0
        ;    bne.s    @nodec
        ;create puff
        ;    bsr.w    FindFreeObj
        ;    bne.s    @nodec
        ;    move.b    #id_SmokePuff,0(a1) ; load missile object
        ;    move.w    obX(a0),obX(a1)
        ;    move.w    obY(a0),obY(a1)
        ;    addi.w    #$1C,obY(a1)
        ;    move.b    #1,obSubtype(a1)
            ;end Wall Jump Smoke Puff
       
    nodec:
        endif    ;end Wall Jump.......
    Code:
    Sonic_JumpHeight:
       if WallJumpActive=1    ;Mercury Wall Jump
            tst.b    obWallJump(a0)    ; on wall?
            beq.s    skipm
            move.b    (Ctrl_1_press_Logical).w,d0
            andi.b    #$70,d0            ; are buttons A, B or C being pressed?
            beq.s    skipm    ; if yes, branch
            move.w    #0,obWallJump(a0)    ; clear Wall Jump data
            move.b    #1,jumping(a0)    ;Mercury Constants
            move.b    #2,anim(a0) ; use "jumping" animation
            move.w    #-$600,d0
            btst    #button_up,(Ctrl_1_Held_Logical).w
            bne.s    uponlym
            move.w    #-$580,d0
            move.w    #-$400,x_vel(a0)
            btst    #0,Status(a0)    ;Mercury Constants
            beq.s    uponlym
            neg.w    x_Vel(a0)
       
    uponlym:
            btst    #6,Status(a0)    ;Mercury Constants
            beq.s    nowtrm
            addi.w    #$280,d0
       
    nowtrm:
            move.w    d0,y_Vel(a0)
       
    skipm:
        endif    ;end Wall Jump
        tst.b    jumping(a0)    ;Mercury Constants
            beq.s    loc_134C4
            move.w    #-$400,d1
            btst    #6,status(a0)    ;Mercury Constants
            beq.s    loc_134AE
            move.w    #-$200,d1
    
    loc_134AE:
            cmp.w    y_Vel(a0),d1
            ble.s    locret_134C2
            move.b    (Ctrl_1_Held_Logical).w,d0
        andi.b    #button_B_mask|button_C_mask|button_A_mask,d0 ; is a jump button pressed?
            bne.s    locret_134C2    ; if yes, branch
            move.w    d1,y_Vel(a0)
    
    locret_134C2:
            rts
    ; ===========================================================================
    
    loc_134C4:
            cmpi.w    #-$FC0,y_Vel(a0)
            bge.s    locret_134D2
            move.w    #-$FC0,y_Vel(a0)
    
    locret_134D2:
            rts
    ; End of function Sonic_JumpHeight 
     
  7. AkumaYin

    AkumaYin Well-Known Member Member

    Joined:
    Aug 21, 2014
    Messages:
    121
    Location:
    Param Zone
    "It won't work" isn't very specific. Are you having assembly errors? Just from having a brief look at your code, I can already see a few things you either have, or may have done wrong:
    1. The ported code is still using Sonic 1's RAM addresses, which are no longer equivalent in Sonic 2 due to the developers shifting around the used addresses both when adding flags and when freeing up the space used by chunks while implementing the new 128x128 system. I would advise looking at this page to determine the purpose of these RAM addresses, and using appropriate constants defined in the Sonic 2 disassembly.
    2. I'm going to assume you haven't defined the decision statements that ReadySonic uses to toggle abilities and design decisions. You'll need to add the one for the wall jump at the beginning of the file and switch it to 1, if you haven't done so already. Also, ReadySonic has a really hack-ish way of adding its animations, so considering you're working with Sonic 2, you'll need to port the art, mappings, and animation for the wall jump however you see fit. It won't work right out of the box.
    3. I'm seeing "Mercury constants" throughout the code; these are constants defined by Mercury in a special space in the ReadySonic disassembly, and if you try to use them in another disassembly without defining them, you'll get assembly errors. You'll need to either add them to s2.constants.asm, create a new file defining them, or just use the values that they represent. I have no way of telling if you've done so already.
    You're going to need to give more details on what's going wrong before anyone can give you serious help, but that should be enough to get you started.
     
    maple_t and EMK-20218 like this.
  8. Cofahi

    Cofahi Newcomer Trialist

    Joined:
    Dec 14, 2018
    Messages:
    5
    Thank you so much, it worked!!
     
    Last edited: Jan 12, 2019
  9. Iso Kilo

    Iso Kilo Local Idiot Member

    Joined:
    Oct 9, 2017
    Messages:
    112
    Location:
    Small Town in BC, Canada
    This is an issue I've been dealing with for a while now. But when pressing up against a wall or solid object, rather than playing the correct animation Tails does this;
    upload_2019-1-15_10-7-37.png
    I've sort of found the root of the issue, but then it also screws up the jumping animation. Here's the code of my SAnim_Push routine;
    Code:
    SAnim_Push:
            move.w    $10(a2),d1
            move.w    $12(a2),d2
            jsr    (CalcAngle).l
            moveq    #0,d1
            move.b    $22(a0),d2
            andi.b    #1,d2
            bne.s    loc_1D002
            not.b    d0
            bra.s    loc_1D006
    ; ===========================================================================
    
    loc_1D002:
            addi.b    #$80,d0
    
    loc_1D006:
            addi.b    #$10,d0
            bpl.s    loc_1D006_Cont
            moveq    #3,d1
    
    loc_1D006_Cont:
            andi.b    #$FC,1(a0)
            eor.b    d1,d2
            or.b    d2,1(a0)
            lsr.b    #3,d0
            andi.b    #$C,d0
            move.b    d0,d3
            lea    (Obj02Ani_Directional).l,a1
            move.b    #3,$1E(a0)
            bsr.w    SAnim_Do2
            add.b    d3,$1A(a0)
            rts
    I'll be grateful for any help, hints and suggestions. Feel free to just completely redo the routine too.

    Edit: Problem solved, turns out Xenowhirl disam is just mislabeled.
     
    Last edited: Jan 24, 2019
  10. GenesisDoes

    GenesisDoes Well-Known Member Member

    Joined:
    Jan 2, 2016
    Messages:
    125
    Location:
    Pittsburgh, PA
    So I've been looking into possibly doing a Knuckles' Chaotix hack this year, using SonED2/ROMulan project files. To get started, I'm creating new music, but have been having trouble with music hacking and porting to KC's sound driver.

    What I'm trying to do is to use XM4SMPS 4.1b (with 32x support for 4 PWM software channels) to create some original music. XM4SMPS compiles music for Sonic 1 driver (68k driver with relative pointers, big-endian), vs. KC's driver (banked z80-driver, absolute pointers, little-endian, with 4-channel PWM support), so music porting will be required. The best way to port would be S1->S2B->S2F/S3K/3D/KC/Crackers, using the music porting guide. I'm trying to get a test song created and ported to replace "Door into Summer" slot, with PWM support.

    According to the SCHG Music Hacking Guide, KC's music pointer list starts at $076AE9 in ROM, and the 3 songs banks in the game are broken down as such with regards to pointers:

    • Music Pointers (These add to $040000): $076AE9
    • Music Pointers (These add to $048000): $076B05
    • Music Pointers (These add to $050000): $076B33
    • Door into Summer: ROM Addr $040000 (1st song, 1st bank, located at $8000 in z80-bank)
    I've taken a look at the result 32x SMPS asm file for the test song, and, if I'm correct, it appears the SMPS music header seems to be different than the standard 32x SMPS music header documented in the SCHG music hacking guide. Namely, a macro call to smpsHeaderPWM1 is called before FM1 channel is setup, when it should be moved to after PSG3 channel as only a smpsHeaderPWM call for PWM1 channel. (smpsHeaderPWM1 is a macro with 2 params to setup the addr location of PWM1 channel and the amount of PWM channels in song, while smpsHeaderPWM is a macro with 1 param to setup the location of an individual PWM channel. The extra number of channels byte makes the music header a non-standard 32x one.) I'm assuming XM4SMPS 4.1b 32x support actually targets the old Sonic 32x sound driver, hence the nonstandard header and 68k pointers. I've made the following code changes to the asm file marked in order to make the header standard.

    Code:
    ;
    -------------------------------------------------------
    ; File created using XM4SMPS v4.1-beta (Qt 3.2.1 Win32)
    ; Created on Tue Dec 25 2018, 19:45:15
    ; For SMPS 32X
    ; -------------------------------------------------------
    
    virtua_Header:
        smpsHeaderVoice    virtua_Voices
        smpsHeaderChan    6,3
        smpsHeaderTempo    $4, $4
        ;smpsHeaderPWM1    virtua_PWM1, 3        ;!@ Sonic 32x header? Not compatible with KC32x
        smpsHeaderFM    virtua_FM1,    $0, $10
        smpsHeaderFM    virtua_FM2,    $0, $10
        smpsHeaderFM    virtua_FM3,    $0, $10
        smpsHeaderFM    virtua_FM4,    $0, $10
        smpsHeaderFM    virtua_FM5,    $0, $10
        smpsHeaderPSG    virtua_PSG1,    $dc, $2, $0
        smpsHeaderPSG    virtua_PSG2,    $dc, $2, $0
        smpsHeaderPSG    virtua_PSG3,    $dc, $2, $0
        smpsHeaderPWM    virtua_PWM1            ;!@ Moved here for proper 32x SMPS Music header
        smpsHeaderPWM    virtua_PWM2
        smpsHeaderPWM    virtua_PWM3
        smpsHeaderPWM    virtua_PWM4
    

    After recompiling the asm song manually with these changes, the song works in Sonic 1 (without PWM support, obviously). Afterwards, I use the notes in the music porting guide to port the song to S2, and then port to KC. According to the sound driver macros in the Sonic 2 disasm, the formula to convert a relative, big-endian 68k pointer to an absolute, z80-banked, little-endian pointer is:

    Code:
      Let x=absolute addr to start of song+S1 music pointer
    z80_Rom_Ptr = [(x<<8) & $FF00] | [(x>>8) & $7F] | [$80]
    This is the formula I used for recalculating the pointers when porting. After all of this work, the S2 ported song doesn't work in the Sonic 2 driver and neither the KC ported song in the KC driver. The KC SMPSPlay driver reports that the ported song is located at $FFC0 in the z80-bank vs. $8000 where it should belong

    Attached are my source files and notes in the porting process. What am I doing wrong for the math in the porting process? Am I correct with the non-standard 32x SMPS music header issue and the pointer conversion formula?
     

    Attached Files:

    EMK-20218 likes this.
  11. Natsumi

    Natsumi Phoenix egg Member

    Joined:
    Oct 7, 2011
    Messages:
    677
    Location:
    Long and dangerous river
    What I would assume, is some tool somewhere confused PWM1 with DAC. Indeed, Chaotix has the PWM channels after the last PSG/FM channel as per standard and no DAC channel. Something very important also is, that you only have 5 FM channels listed, but channel count is 6. This is wrong for the 32x driver and wont work, because its expecting to use 6 FM channels.

    The tools you are using to make the conversion are probably not all that good, and it would be much easier to disassemble the sound file when its created by xm4smps and then rebuild it targeting Knuckles Chaotix at z80 address $8000.
     
    EMK-20218 likes this.
  12. GenesisDoes

    GenesisDoes Well-Known Member Member

    Joined:
    Jan 2, 2016
    Messages:
    125
    Location:
    Pittsburgh, PA
    Wow, I feel stupid for overthinking and overlooking some of these dumb mistakes.

    As Natsumi pointed out, my song didn't have an FM channel 6 defined, and I didn't define the parameters for each PWM channels' initial volume/pitch. KC requires a channel setup of $0603, and usage of 6FM, 3 PSG, and 4 PWM channels for songs (unused channels can be NOP'd with rests for songs, obviously). This lack of FM6 channel and PWM initial settings caused the SMPS music header to be off by a few bytes in length, which made the song be located in the wrong z80-bank. There were a few other issues, which I fixed.




    During the porting process, I created a new SMPS2ASM include file for XM4SMPS 4.1b, which will compile a S1 song properly to KC z80 banks. S1 asm songs with 32x support (poorly) created by XM4SMPS still need some hand tweaking with some changes, then recompiled with the new SMPS2ASM include file to target KC z80 driver.

    Basically, the workflow now is:

    • Compile a Sonic 1 song with 32x option in XM4SMPS 4.1b using the standard SMPS2ASM include file,
      • Name the output song "S1", move the ASM file into XM4SMPS' directory.
      • Size issues
        • Ideally this new song should be smaller than the original KC song slot being replaced
        • Then pad new song to the size of the original
        • Otherwise you will need to recompile all other shifted songs with fixed pointers and fix the music pointer table. (Have fun with that...)

    • S1 ASM file edits
      • At top, define a constant for a target ROM address for the new song's location
        • E.g., $40000 to replace "Door into Summer"
        • Target EQU $40000
      • Set channel setup to $0603 (smpsHeaderChan 6,3).
        • Song must have 6 FM, 3 PSG, 4 PWM channels defined for KC!
      • Fix PWM channels (smpsHeaderPWM macros)
        • Fix the misplaced PWM1 macro (smpsHeaderPWM1 YourPWM1Label)
          • Rename the misplaced "smpsHeaderPWM1" macro call to "smpsHeaderPWM"
          • Remove the extra number of channels param in it
          • Move it to after PSG3 channel (smpsHeaderPSG YourPSG3)
        • Add an extra param of "Target" address constant to all smpsHeaderPWM macros
        • Add 2 more param bytes of initial volume and pitch to all smpsHeaderPWM macros
      • Add an extra param of "Target" address constant to the following macros after the 1st param
        • smpsHeaderVoice
        • smpsHeaderFM
        • smpsHeaderPSG
        • smpsJump
        • smpsLoop
        • smpsCall
      • Save the edited ASM file as "KC.asm" in XM4SMPS' directory

    • Recompile
      • At the path of XM4SMPS 4.1b directory
        • Extract the contents of my attached archive here
      • Run the batch script. It will
        • Run CompKC.asm, which will compile KC.asm using my new "_s1smps2asm_S1KC.asm" include file into KC.bin; new song z80-banked for usage in KC

    • Inject/fix (hex editor ROM hacking)
      • Replace the original song in ROM with your new one
      • Adjust music pointer table if necessary, recompile other songs with fixed pointers if their locations shifted.
      • Soundtest song name
        • Do a text search for the original song title from the Sound Test (should be located near address $227338 in ROM).
        • Replace the song's name
          • Use capital ASCII characters
          • Song name is null-terminated ($00 byte)
    • Adds a param after the 1st to the following macros, for defining a target ROM address location
      • smpsHeaderVoice
      • smpsHeaderFM
      • smpsHeaderPSG
      • smpsJump
      • smpsLoop
      • smpsCall
    • Adds target ROM address, volume, and pitch params to smpsHeaderPWM, to make it conform to the standard SMPS 32x music header
    • Defines a z80_Rom_Ptr macro used by the above macros, to convert absolute ROM addresses to z80 pointers
    • Uses the above macros to port S1 song to S2B (z80-banked)
    • Changes the following coordination flags (ports S2B song to KC/etc.)
      • smpsReturn $E3 -> $E9
      • smpsAlterPitch $E9 -> $FB

    Seems like a lot of work at first, but really simple once you get used to it, especially since this is basic z80 sound driver hacking. I'll probably look into further automating all of this into a bugfixed build of XM4SMPS 4.1 to properly support 32x later :) ...
     

    Attached Files:

  13. Natsumi

    Natsumi Phoenix egg Member

    Joined:
    Oct 7, 2011
    Messages:
    677
    Location:
    Long and dangerous river
    Just as an FYI, you could automate it using my SMPS2ASM in MDMusicPlayer to automatically disassemble the file in the correct format too. I can probably look into this some time but if you read the documentation you should have a fairly good picture of how to get it working.
     
  14. PoloBlue

    PoloBlue Newcomer Trialist

    Joined:
    Jan 18, 2019
    Messages:
    7
    Hey gang! I reckon this is the appropriate thread for a burning question I've had for a couple days, so here goes!

    Okay, so I'm trying to change the text in my Sonic 1 hack so it says something different besides "SONIC HAS PASSED"
    I used Selbi's Text Code Generator to get the code and put it in the ASM file "3A Got Through Card.asm" (I'm using the GitHub disassembly, btw) so the part of the code that handles the stage clear text looks like this:


    Code:
    Got_Config:    dc.b 9    ;  SONIC HAS | CHRIS HAS
            dc.b $F8, 5, 0, 8, $B0        ; C
            dc.b $F8, 5, 0, $1C, $C0    ; H
            dc.b $F8, 5, 0, $3A, $D0    ; R
            dc.b $F8, 1, 0, $20, $E0    ; I
            dc.b $F8, 5, 0, $3E, $E8    ; S
            dc.b $F8, 0, 0, $56, $F8    ; Space
            dc.b $F8, 5, 0, $1C, $8    ; H
            dc.b $F8, 5, 0, 0, $18        ; A
            dc.b $F8, 5, 0, $3E, $28    ; S
    
            dc.w -$120,    $120,    $D0            ; "PASSED"
            dc.b                 2,    1
    
            dc.w $40C,    $14C,    $D6            ; "ACT" 1/2/3
            dc.b                 2,    6
    But when I build the ROM, the game crashes whenever I clear an act. It looks like this:

    upload_2019-1-19_21-30-34.png

    Can somebody point me in the right direction so I can get this fixed and move on to other stuff in my hack? Thanks in advance! ^_^
     
    Last edited: Jan 20, 2019
  15. GenesisDoes

    GenesisDoes Well-Known Member Member

    Joined:
    Jan 2, 2016
    Messages:
    125
    Location:
    Pittsburgh, PA
    It would help a little if you can get the text for that error. (Use Gens KMod's Plane Explorer to get the error text on the FG layer).

    I'm going to take a guess and say that it is an "Address Error" bug, which basically means the M68k was trying to access a word (2 bytes) of data at an odd address.
    If you notice above "Got_Config" label, each object position defined in that function requires parameters of 3 words and 2 bytes, broken as such:

    Code:
    ;    x-start,   x-main,   y-main,
    ;    routine, frame number
    For S1 Git diasm, those particular pieces of new text aren't supposed to go into that function (hence the address error); it's supposed to go into "Disasm\_maps\Sonic Got Through.asm" file at labels "M_Got_SonicHas" and "M_Got_Passed" for "Sonic has" and "passed", respectively.

    For zone title cards, their text goes into "Disasm\_maps\Title Cards.asm" .
     
    Last edited: Jan 20, 2019
  16. PoloBlue

    PoloBlue Newcomer Trialist

    Joined:
    Jan 18, 2019
    Messages:
    7
    That fixed it! Interestingly enough, though, I didn't find those labels in the file you described. They were instead hiding in "sonic.asm". Thanks for your help all the same! :)
     
  17. Dark Lips

    Dark Lips Well-Known Member Member

    Joined:
    Nov 14, 2008
    Messages:
    285
    Location:
    Wolverhampton UK
    heya guys - quick question reguarding SRAM in Sonic 1 - I followed the guide to get Sonic1 to save and load the level to and from SRAM and thaught I had it figured out so went on to try make it save how many lives I have too - however it does not... just to be sure i loaded the .srm file into a hex editor and sure as apples are apples only the zone and act are present. This is what I did:

    Code:
        
                    move.b    #1,($A130F1).l     ; enable SRAM (required)
                    lea    ($200001).l,a1             ; base of SRAM
                    movep.w    0(a1),d0             ; load zone and act off SRAM into d0
                    move.w    d0,($FFFFFE10).w ; move the un-odded result into the level ID
                    lea    ($200004).l,a1            ; SRAM number of lives???
                    movep.w    0(a1),d0            ; load number of lives off SRAM into d0
                    move.b    d0,($FFFFFE12).w ; move result into the number of lives
                    move.b    #0,($A130F1).l    ; disable SRAM (required)
    have I missed the point?
     
  18. Natsumi

    Natsumi Phoenix egg Member

    Joined:
    Oct 7, 2011
    Messages:
    677
    Location:
    Long and dangerous river
    here is a little tip to making it easier. You could, instead of lea'ing a new ROM address into a1, just use
    Code:
            move.b 4(a1),($FFFFFE12).w
    I assume this is what you really wanted to do in your code. Currently, you are both loading the lives as a word (why?), and loading from an even address. While on the SRAM code, it defaults to SRAM being odd-byte only. This would mean, you basically read nonexistent memory that could default to anything. You could change it to read from
    $200005 as well to make it work though.
     
  19. Dark Lips

    Dark Lips Well-Known Member Member

    Joined:
    Nov 14, 2008
    Messages:
    285
    Location:
    Wolverhampton UK
    I just dont think i am understanding this properly... this is my save routine after trying a few different things including what you have said above - I think somewhere I need to tell it to move the lives to $200005 but not sure where?
    Code:
                    move.b    #1,($A130F1).l           ; enable SRAM (required)
                    lea    ($200001).l,a1             ; base of SRAM + 1
                    move.w  ($FFFFFE10).w,d0    ; move zone and act number to d0 (we can't do it directly)
                    move.b  ($FFFFFE12).w,4(a1)  ; SRAM number of lives
                    move.b    #0,($A130F1).l           ; disable SRAM (required)
     
  20. PoloBlue

    PoloBlue Newcomer Trialist

    Joined:
    Jan 18, 2019
    Messages:
    7
    Hey, me again! So I've come up on another snag in my project... (Sorry if I'm being a nuisance with questions btw, I figure it best though that I learn how to deal with these issues now so I'll know what to do if it comes up again later.)

    I'm in the process of using SonMapEd to bring some custom sprites in to replace Sonic. All has been working according to plan so far, except whenever I make this funny lil' dough boy run downhill at top speed, he looks like a garbled mess of Sonic tiles. It looks like the mapping for his sprites is all there, but it isn't loading the proper tiles to make it look like something coherent.

    Here's a side-by-side comparison of what the sprite should look like vs. what comes up in game:
    upload_2019-1-21_23-25-43.png

    Is there a fix for this? I've tried reinserting the sprites in SonMapEd, but that unfortunately hasn't done me any good. I'm all ears for any suggestions you guys might have though!