- Messages
- 41
- Location
- England, United Kingdom
Alright, lads and lassies, this is the first guide to a successful internet forum. For those who’ve seen videos of my hack on Discord, Twitter or YouTube, you may have noticed that I’ve included the insta-shield and elemental shield in my hack. Since you like those features, I figured I should demonstrate how to port them to Sonic 1. This post will show you how to port the Insta-Shield to Sonic 1. Later at some point, I’ll be sending my elemental shields guide port. If I forget, gimmie a shout. =P
So if you want to get a bit of context as to what the Insta-Shield is and how it works in Sonic 3 and Knuckles, check out this link.
Before we add the code in, let’s check how Sonic 3 and Knuckles manages the object:
This code loads the insta shield object and makes sure it swaps checks for reverse gravity or sets different reviews when loading different frames. To get it working under Sonic 1, we need to make a few changes. Firstly, we need to remove checks that sets the gravity. Find this bit of code:
And just remove it as we wouldn’t need it in Sonic 1.
Now we need to compare the SSTs and RAM bytes between Sonic 3K and Sonic 1. You need to open up this and this. You need to open up sonic3k.constants.asm in the S3K disassembly during this process. Let’s do a quick example:
We need to focus on this bit of the line: “mappings” as that is an SST we need to change. In s3k.constants.asm, it says the SST is $C. If we check here, but in Sonic 1, it’s $4, so replace mappings with $4. Do you not get the concept? Let me show you the line below what I’ve shown:
We need to look at this bit “DPLC_Address” as that’s an SST byte. Copy and paste and search the file in s3k.constants.asm. The byte is $3C, and in Sonic 1, it’s doesn’t have a byte so just change DPLC_Address to $3C. It will still work as $3C is a free byte in Sonic 1. Now, if you get the gist of it, try using the two links I sent above to compare the SST byte. If there isn’t a matching SST byte
This will take time to do, but once you do a few on your own, you should get it.
Find this line:
Draw_Sprite is an equivalent of DisplaySprite so replace that with:
We need to fix the priorities too to make it support Sonic 1, on so replace:
With
And find:
This sets the height for the object, which Sonic 1 doesn’t need to do, so remove or comment it out.
We also need to add an index so under the object's label, add this:
Then replace this:
with this:
If you did everything right, your result should be something like this:
Next, we need to set up PLCLoad_Shields this is where it loads the DPLCs for the insta-shield art. Here is the original code:
Like before, you need to modify the SST and change some labels such as Add_To_DMA_Queue to QueueDMATransfer. The result should be this:
Now we need to load the object in your hack, so open up Object pointers.asm, and we need to find an accessible object ID. Open it up, and you’ll see a bunch of lines with “ObjectFall” in them. These are dummy object files, so you can replace one of them with the object name you wrote. Just make sure you know what object ID you selected. For example, if you replace the first ObjectFall after Obj01, it will be object ID 02.
Now comes loading in the object within Sonic’s object. You would want to go to Obj01_Main, and at the end of the subroutine, add this:
XX - that will be the object ID you set in the object pointers file.
Up next is to modify Sonic_JumpHeight. The reason is due to the way Sonic 3 handles double jumping. Let me show you a snippet of code:
To summarise, the code checks for the double jump flag before setting it to 1 for the fire shield to do its action. It also prevents the move from happening when your Super which is a useful move to do. In order to make the move work, we need to install Sonic_InstaAndShieldMoves. Go to loc_134AE and replace
With
Under locret_134D2, place this:
In my hack, I set $B8 as the sound effect, but you can change it to any sound ID you desire. $AB sounds close enough, so use that if you like. Also, if you’ve been following the code, I set double_jump_flag to be $2F since there is no equivalent in Sonic 1 and a free SST. Now we’ve come to the last two steps of modifying the code: Making sure the insta shield works when we’ve jumped after landing and expanding the touch’s size when the insta-shield is performed. Let’s go with the easiest step.
We want to make sure the double jump flag is reset to 0 when Sonic lands on the floor; otherwise, he wouldn’t perform the insta-shield move after he jumps again. Let’s go over to Sonic_ResetOnFloor. Under the label “loc_137E4”, insert this:
This will reset the double jump flag the next time Sonic hits the ground.
For the last bit, modify TouchResponse so Sonic’s hitbox largens when he makes the insta-shield attack. Go to TouchResponse, and under the label, insert this:
You may notice that we have a new label: Touch_Process. This allows the code to interact with the object RAM. To utilise this, just replace Touch_NoDuck with this:
All right, the code side is done. Now it’s time to add the art in:
First of all, make sure you got your SK disassembly ready. The easiest thing to do is to go to:
“skdisasm-master\General\Sprites\Shields” and look for DPLC - Insta-Shield.asm. Since PLCLoad_Shield retains using the same S3K format when it comes to DPLC mappings, we don’t need to change anything, so copy that file and paste it in the disassembly in your hack. As for the mappings, we need to convert to format to Sonic 1. You can use one of the three tools to do this:
One tool is called SonMapEd. Open it up and set the Game Format setting to "Sonic 3 & Knuckles", load the mappings file, change the Game Format setting to "Sonic 1", and save the mappings as “Map - Insta-Shield.asm” in the “_maps” folder of your disassembly.
Another tool is MappingsConverter. Open it up and load the mappings with input set to Game: "Sonic 3 & Knuckles", Format: ASM and output set to Game: "Sonic 1", Format: ASM, and save the mappings as “Map - Insta-Shield.asm” in the “_maps” folder of your disassembly.
Another tool is Flex2. Open it up and insert the mappings and make sure the format is set as S3K. Load it, convert it to Sonic 1 and save it. The tool should overwrite the original mapping, and you should go back to the shields folder of the SK disassembly, copy the mappings and place it in “_maps” folder of your disassembly.
As for the art, you’ll need to load PaletteConverter as the player palettes between Sonic 3K and 1 are vastly different. Open it up and you will see this:
We are going to do this according to the numbers I added.
“skdisasm-master\General\Sprites\Sonic\Palettes\SonicandTails.bin”
2. Secondly, open up Sonic’s S1 palette file. It should be under:
“yourdisassembly\pallet\Sonic.bin”
You need to match the palette bytes by dragging Sonic 3K’s byte to match S1’s; and the outcome should be this:
3. Open up convert uncompressed file and open up the Insta-Shield art; It should be located at:
It will give you a pop-up asking if you want to overwrite the source with the converted artwork. Say no and save the file in your disassembly in artunc and name it: “Insta-Shield.bin”
I’ve linked a .rar file with everything converted here if you struggled to get that set up. Then, just drag and drop the files to its respective folder.
Open up sonic1.asm, and under the insta-shield object, insert this:
You need to make sure the object loads if you managed to obtain a shield and remove it. Go to the shield object and find the line that clears the shield RAM and place this:
Again, XX should be the object ID you set for the insta-shield. Build your disassembly, and it should run well. Next time, I’ll get the elemental shields to guide up and running alongside making references to GitHub’s disassembly. If you have any questions or if it works, feel free to comment down below. =D
Also, can you please credit me if you used this guide as it took me quite a while to write this and set up with a bit of guidance?
Until then...
EDIT: changed the constants to be SSTs
So if you want to get a bit of context as to what the Insta-Shield is and how it works in Sonic 3 and Knuckles, check out this link.
This guide is meant for the 2005 Hivebrain disassembly, and I will reference the code in the tutorial. Original S3K code will be from GitHub’s disassembly; please download it as we will need some of its assets later throughout the tutorial. However, it should work if you want to add it into any other disassembly, such as GitHub or Sonic 2. Just be mindful of the code and label changes, especially with RAM and constants.
Also, I don’t want to see an argument that the shields will be “overused” in Sonic 1 hacks. This is an absurd view, in my opinion, as this tutorial teaches people how to port code from one disassembly to another and add new features. Also, if you are adding it, be sure to know if it’s worth porting over to your hack. I know that sounds vague, but I’d rather see the shields have interesting purposes than just a gimmick.
The tutorial still works, although I haven’t managed to get around to commentating on a few things. That will be done very soon. And also, this isn’t a copy and paste guide, and this guide teaches people how to differentiate between different disassemblies and add new moves to their hacks.
Also, you need to make sure you install QueueDMATransfer by checking out here, and this has to be installed too. Click me. However, the uncompressed art links are dead so I uncompressed the art myself and linked it here.
Also, I don’t want to see an argument that the shields will be “overused” in Sonic 1 hacks. This is an absurd view, in my opinion, as this tutorial teaches people how to port code from one disassembly to another and add new features. Also, if you are adding it, be sure to know if it’s worth porting over to your hack. I know that sounds vague, but I’d rather see the shields have interesting purposes than just a gimmick.
The tutorial still works, although I haven’t managed to get around to commentating on a few things. That will be done very soon. And also, this isn’t a copy and paste guide, and this guide teaches people how to differentiate between different disassemblies and add new moves to their hacks.
Also, you need to make sure you install QueueDMATransfer by checking out here, and this has to be installed too. Click me. However, the uncompressed art links are dead so I uncompressed the art myself and linked it here.
Before we add the code in, let’s check how Sonic 3 and Knuckles manages the object:
Code:
Obj_Insta_Shield:
; Init
move.l #Map_InstaShield,mappings(a0)
move.l #DPLC_InstaShield,DPLC_Address(a0) ; Used by PLCLoad_Shields
move.l #ArtUnc_InstaShield,Art_Address(a0) ; Used by PLCLoad_Shields
move.b #4,render_flags(a0)
move.w #$80,priority(a0)
move.b #$18,width_pixels(a0)
move.b #$18,height_pixels(a0)
move.w #ArtTile_Shield,art_tile(a0)
move.w #tiles_to_bytes(ArtTile_Shield),vram_art(a0) ; Used by PLCLoad_Shields
btst #7,(Player_1+art_tile).w
beq.s .nothighpriority
bset #7,art_tile(a0)
.nothighpriority:
move.w #1,anim(a0) ; Clear anim and set prev_anim to 1
move.b #-1,LastLoadedDPLC(a0) ; Reset LastLoadedDPLC (used by PLCLoad_Shields)
move.l #Obj_Insta_Shield_Main,(a0)
Obj_Insta_Shield_Main:
movea.w parent(a0),a2
btst #Status_Invincible,status_secondary(a2) ; Is the player invincible?
bne.s locret_195A4 ; If so, return
move.w x_pos(a2),x_pos(a0) ; Inherit player's x_pos
move.w y_pos(a2),y_pos(a0) ; Inherit player's y_pos
move.b status(a2),status(a0) ; Inherit status
andi.b #1,status(a0) ; Limit inheritance to 'orientation' bit
tst.b (Reverse_gravity_flag).w
beq.s .normalgravity
ori.b #2,status(a0) ; Reverse the vertical mirror render_flag bit (On if Off beforehand and vice versa)
.normalgravity:
andi.w #drawing_mask,art_tile(a0)
tst.w art_tile(a2)
bpl.s .nothighpriority
ori.w #high_priority,art_tile(a0)
.nothighpriority:
lea (Ani_InstaShield).l,a1
jsr (Animate_Sprite).l
cmpi.b #7,mapping_frame(a0) ; Has it reached then end of its animation?
bne.s .notover ; If not, branch
tst.b double_jump_flag(a2) ; Is it in its attacking state?
beq.s .notover ; If not, branch
move.b #2,double_jump_flag(a2) ; Mark attack as over
.notover:
tst.b mapping_frame(a0) ; Is this the first frame?
beq.s .loadnewDPLC ; If so, branch and load the DPLC for this and the next few frames
cmpi.b #3,mapping_frame(a0) ; Is this the third frame?
bne.s .skipDPLC ; If not, branch as we don't need to load another DPLC yet
.loadnewDPLC:
bsr.w PLCLoad_Shields
.skipDPLC:
jmp (Draw_Sprite).l
; ---------------------------------------------------------------------------
locret_195A4:
rts
; ---------------------------------------------------------------------------
This code loads the insta shield object and makes sure it swaps checks for reverse gravity or sets different reviews when loading different frames. To get it working under Sonic 1, we need to make a few changes. Firstly, we need to remove checks that sets the gravity. Find this bit of code:
Code:
move.b status(a2),status(a0) ; Inherit status
andi.b #1,status(a0) ; Limit inheritance to 'orientation' bit
tst.b (Reverse_gravity_flag).w
beq.s .normalgravity
ori.b #2,status(a0) ; Reverse the vertical mirror render_flag bit (On if Off beforehand and vice versa)
.normalgravity:
And just remove it as we wouldn’t need it in Sonic 1.
Now we need to compare the SSTs and RAM bytes between Sonic 3K and Sonic 1. You need to open up this and this. You need to open up sonic3k.constants.asm in the S3K disassembly during this process. Let’s do a quick example:
Code:
move.l #Map_InstaShield,mappings(a0)
We need to focus on this bit of the line: “mappings” as that is an SST we need to change. In s3k.constants.asm, it says the SST is $C. If we check here, but in Sonic 1, it’s $4, so replace mappings with $4. Do you not get the concept? Let me show you the line below what I’ve shown:
Code:
move.l #DPLC_InstaShield,DPLC_Address(a0)
We need to look at this bit “DPLC_Address” as that’s an SST byte. Copy and paste and search the file in s3k.constants.asm. The byte is $3C, and in Sonic 1, it’s doesn’t have a byte so just change DPLC_Address to $3C. It will still work as $3C is a free byte in Sonic 1. Now, if you get the gist of it, try using the two links I sent above to compare the SST byte. If there isn’t a matching SST byte
This will take time to do, but once you do a few on your own, you should get it.
Find this line:
Code:
jmp (Draw_Sprite).l
Code:
jmp (DisplaySprite).l
We need to fix the priorities too to make it support Sonic 1, on so replace:
Code:
move.w #$80,$18(a0)
With
Code:
move.b #1,$18(a0)
And find:
Code:
move.b #$18,$16(a0)
This sets the height for the object, which Sonic 1 doesn’t need to do, so remove or comment it out.
We also need to add an index so under the object's label, add this:
Code:
moveq #0,d0
move.b $24(a0),d0
move.w InstaShieldObj_Index(pc,d0.w),d1
jmp InstaShieldObj_Index(pc,d1.w)
; ===========================================================================
InstaShieldObj_Index:
dc.w InstaShieldObj_Main-InstaShieldObj_Index
dc.w loc3_1952A-InstaShieldObj_Index
; ===========================================================================
Then replace this:
Code:
move.w #1,$1C(a0) ; Clear anim and set prev_anim to 1
move.b #-1,$30(a0) ; Reset LastLoadedDPLC (used by PLCLoad_Shields)
move.l #Obj_Insta_Shield_Main,(a0)
with this:
Code:
move.w #1,$1C(a0)
move.b #-1,$30(a0)
addq.b #2,$24(a0)
If you did everything right, your result should be something like this:
Code:
; --------------------------------------------------
; InstaShieldObj: Insta-Shield
; --------------------------------------------------
InstaShieldObj: ; XREF: Obj_Index
moveq #0,d0
move.b $24(a0),d0
move.w InstaShieldObj_Index(pc,d0.w),d1
jmp InstaShieldObj_Index(pc,d1.w)
; ===========================================================================
InstaShieldObj_Index:
dc.w InstaShieldObj_Main-InstaShieldObj_Index
dc.w loc3_1952A-InstaShieldObj_Index
; ===========================================================================
InstaShieldObj_Main:
tst.b ($FFFFFE2D).w
bne.w locret3_195A4
move.l #Map_InstaShield,$4(a0) ;Mappings
move.l #DPLC_InstaShield,$3C(a0) ;Dynamic Pattern Load Cues
move.l #ArtUnc_InstaShield,$38(a0)
move.b #$14,1(a0)
move.b #1,$18(a0)
move.b #$18,$16(a0)
move.w #$A820,$36(a0)
move.w #$541,2(a0)
loc3_19518: ; CODE XREF: ROM:00019510j
move.w #1,$1C(a0)
move.b #-1,$30(a0)
addq.b #2,$24(a0)
loc3_1952A: ; DATA XREF: ROM:00019524o
lea ($FFFFD000).w,a2
tst.b ($FFFFFE2D).w
bne.s locret3_195A4
move.w $8(a2),$8(a0)
move.w $C(a2),$C(a0)
;loc3_1955A: ; CODE XREF: ROM:00019552j
andi.w #$7FFF,art_tile(a0)
tst.w $A(a2)
bpl.s loc3_1956C
ori.w #$8000,2(a0)
loc3_1956C: ; CODE XREF: ROM:00019564j
lea (Ani_InstaShield).l,a1 ; load animation script address to a1
jsr AnimateSprite
cmpi.b #7,$1A(a0)
bne.s loc3_1958C
tst.b $2F(a2)
beq.s loc3_1958C
move.b #2,$2F(a2)
loc3_1958C: ; CODE XREF: ROM:0001957Ej
; ROM:00019584j
tst.b $1A(a0)
beq.s loc3_1959A
cmpi.b #3,$1A(a0)
bne.s loc3_1959E
loc3_1959A: ; CODE XREF: ROM:00019590j
bsr.w PLCLoad_Shields
loc3_1959E: ; CODE XREF: ROM:00019598j
jmp DisplaySprite
; ???????????????????????????????????????????????????????????????????????????
locret3_195A4: ; CODE XREF: ROM:00019534j
rts
Next, we need to set up PLCLoad_Shields this is where it loads the DPLCs for the insta-shield art. Here is the original code:
Code:
PLCLoad_Shields:
moveq #0,d0
move.b mapping_frame(a0),d0
cmp.b LastLoadedDPLC(a0),d0
beq.s locret_199E8
move.b d0,LastLoadedDPLC(a0)
movea.l DPLC_Address(a0),a2
add.w d0,d0
adda.w (a2,d0.w),a2
move.w (a2)+,d5
subq.w #1,d5
bmi.s locret_199E8
move.w vram_art(a0),d4
PLCLoad_Shields_ReadEntry:
moveq #0,d1
move.w (a2)+,d1
move.w d1,d3
lsr.w #8,d3
andi.w #$F0,d3
addi.w #$10,d3
andi.w #$FFF,d1
lsl.l #5,d1
add.l Art_Address(a0),d1
move.w d4,d2
add.w d3,d4
add.w d3,d4
jsr (Add_To_DMA_Queue).l
dbf d5,PLCLoad_Shields_ReadEntry
locret_199E8:
rts
; End of function PLCLoad_Shields
Like before, you need to modify the SST and change some labels such as Add_To_DMA_Queue to QueueDMATransfer. The result should be this:
Code:
PLCLoad_Shields:
moveq #0,d0
move.b $1A(a0),d0 ; load frame number
cmp.b $33(a0),d0
beq.s locret2_13C96
move.b d0,$33(a0)
move.l $3C(A0),a2
add.w D0,D0
adda.w (a2,D0),a2
move.w (a2)+,d5
subq.w #1,D5
bmi.s locret2_13C96
move.w $36(A0),D4
loc_199BE:
moveq #0,d1
move.b (a2)+,d1
lsl.w #8,d1
move.b (a2)+,d1
move.w d1,d3
lsr.w #8,d3
andi.w #$F0,d3
addi.w #$10,d3
andi.w #$FFF,d1
lsl.l #5,d1
add.l $38(a0),d1
move.w D4,D2
add.w D3,D4
add.w D3,D4
jsr (QueueDMATransfer)
dbf d5,loc_199BE ; repeat for number of entries
locret2_13C96:
rts
; End of function PLCLoad_Shields
Now we need to load the object in your hack, so open up Object pointers.asm, and we need to find an accessible object ID. Open it up, and you’ll see a bunch of lines with “ObjectFall” in them. These are dummy object files, so you can replace one of them with the object name you wrote. Just make sure you know what object ID you selected. For example, if you replace the first ObjectFall after Obj01, it will be object ID 02.
Now comes loading in the object within Sonic’s object. You would want to go to Obj01_Main, and at the end of the subroutine, add this:
Code:
move.b #XX,$FFFFD180.w ; load the insta shield object
XX - that will be the object ID you set in the object pointers file.
Up next is to modify Sonic_JumpHeight. The reason is due to the way Sonic 3 handles double jumping. Let me show you a snippet of code:
Code:
loc_118D2:
cmp.w y_vel(a0),d1 ; is y speed greater than 4? (2 if underwater)
ble.w Sonic_InstaAndShieldMoves ; if not, branch
move.b (Ctrl_1_logical).w,d0
andi.b #$70,d0 ; are buttons A, B or C being pressed?
bne.s locret_118E8 ; if yes, branch
move.w d1,y_vel(a0) ; cap jump height
locret_118E8:
rts
; ---------------------------------------------------------------------------
Sonic_UpVelCap:
tst.b spin_dash_flag(a0) ; is Sonic charging his spin dash?
bne.s locret_118FE ; if yes, branch
cmpi.w #-$FC0,y_vel(a0) ; is Sonic's Y speed faster (less than) than -15.75 (-$FC0)?
bge.s locret_118FE ; if not, branch
move.w #-$FC0,y_vel(a0) ; cap upward speed
locret_118FE:
rts
; ---------------------------------------------------------------------------
Sonic_InstaAndShieldMoves:
tst.b double_jump_flag(a0) ; is Sonic currently performing a double jump?
bne.w locret_11A14 ; if yes, branch
move.b (Ctrl_1_pressed_logical).w,d0
andi.b #$70,d0 ; are buttons A, B, or C being pressed?
beq.w locret_11A14 ; if not, branch
bclr #Status_RollJump,status(a0)
tst.b (Super_Sonic_Knux_flag).w ; check Super-state
beq.s Sonic_FireShield ; if not in a super-state, branch
bmi.w Sonic_HyperDash ; if Hyper, branch
move.b #1,double_jump_flag(a0)
rts
; ---------------------------------------------------------------------------
Sonic_FireShield:
btst #Status_Invincible,status_secondary(a0) ; first, does Sonic have invincibility?
bne.w locret_11A14 ; if yes, branch
btst #Status_FireShield,status_secondary(a0) ; does Sonic have a Fire Shield?
beq.s Sonic_LightningShield ; if not, branch
move.b #1,(Shield+anim).w
move.b #1,double_jump_flag(a0)
move.w #$800,d0
btst #Status_Facing,status(a0) ; is Sonic facing left?
beq.s loc_11958 ; if not, branch
neg.w d0 ; reverse speed value, moving Sonic left
loc_11958:
move.w d0,x_vel(a0) ; apply velocity...
move.w d0,ground_vel(a0) ; ...both ground and air
move.w #0,y_vel(a0) ; kill y-velocity
move.w #$2000,(H_scroll_frame_offset).w
bsr.w Reset_Player_Position_Array
move.w #sfx_FireAttack,d0
jmp (Play_Sound_2).l
; ---------------------------------------------------------------------------
To summarise, the code checks for the double jump flag before setting it to 1 for the fire shield to do its action. It also prevents the move from happening when your Super which is a useful move to do. In order to make the move work, we need to install Sonic_InstaAndShieldMoves. Go to loc_134AE and replace
Code:
ble.s locret_134C2
With
Code:
ble.s Sonic_InstaAndShieldMoves
Under locret_134D2, place this:
Code:
Sonic_InstaAndShieldMoves:
tst.b $2F(a0)
bne.w locret_134D2
move.b ($FFFFF603).w,d0
andi.b #$70,d0
beq.w locret_134D2
bclr #4,$2A(a0)
bne.w Sonic_InstaShield
move.b #1,$2F(a0)
rts
Sonic_InstaShield:
tst.b ($FFFFFE2D).w
bne.s Shieldrts
tst.b ($FFFFFE2C).w
bne.s Shieldrts
move.b #1,($FFFFD180+$1C).w
move.w #$B8,d0
jsr (PlaySound_Special).l
Shieldrts:
We want to make sure the double jump flag is reset to 0 when Sonic lands on the floor; otherwise, he wouldn’t perform the insta-shield move after he jumps again. Let’s go over to Sonic_ResetOnFloor. Under the label “loc_137E4”, insert this:
Code:
move.b #0,$2F(a0)
This will reset the double jump flag the next time Sonic hits the ground.
For the last bit, modify TouchResponse so Sonic’s hitbox largens when he makes the insta-shield attack. Go to TouchResponse, and under the label, insert this:
Code:
nop
tst.b ($FFFFFE2C).w ; Does Sonic Have Shield?
bne.s Touch_NoInstaShield ; If so, branch
tst.b ($FFFFFE2D).w ; Does Sonic Is invincible?
bne.s Touch_NoInstaShield ; If so,branch
; By this point, we're focussing purely on the Insta-Shield
cmpi.b #1,double_jump_flag(a0) ; Is the Insta-Shield currently in its 'attacking' mode?
bne.s Touch_NoInstaShield ; If not, branch
move.b #1,($FFFFFE2D).w ; make Sonic invincible
move.w 8(a0),d2 ; Get player's x_pos
move.w $A(a0),d3 ; Get player's y_pos
subi.w #$18,d2 ; Subtract width of Insta-Shield
subi.w #$18,d3 ; Subtract height of Insta-Shield
move.w #$30,d4 ; Player's width
move.w #$30,d5 ; Player's height
bsr.s Touch_Process
clr.b ($FFFFFE2D).w
Alreadyinvincible:
moveq #0,d0
rts
; ---------------------------------------------------------------------------
; Normal TouchResponse comes after this
You may notice that we have a new label: Touch_Process. This allows the code to interact with the object RAM. To utilise this, just replace Touch_NoDuck with this:
Code:
Touch_NoDuck:
move.w #$10,d4
add.w d5,d5
Touch_Process:
lea ($FFFFD800).w,a1 ; begin checking the object RAM
move.w #$5F,d6
All right, the code side is done. Now it’s time to add the art in:
First of all, make sure you got your SK disassembly ready. The easiest thing to do is to go to:
“skdisasm-master\General\Sprites\Shields” and look for DPLC - Insta-Shield.asm. Since PLCLoad_Shield retains using the same S3K format when it comes to DPLC mappings, we don’t need to change anything, so copy that file and paste it in the disassembly in your hack. As for the mappings, we need to convert to format to Sonic 1. You can use one of the three tools to do this:
One tool is called SonMapEd. Open it up and set the Game Format setting to "Sonic 3 & Knuckles", load the mappings file, change the Game Format setting to "Sonic 1", and save the mappings as “Map - Insta-Shield.asm” in the “_maps” folder of your disassembly.
Another tool is MappingsConverter. Open it up and load the mappings with input set to Game: "Sonic 3 & Knuckles", Format: ASM and output set to Game: "Sonic 1", Format: ASM, and save the mappings as “Map - Insta-Shield.asm” in the “_maps” folder of your disassembly.
Another tool is Flex2. Open it up and insert the mappings and make sure the format is set as S3K. Load it, convert it to Sonic 1 and save it. The tool should overwrite the original mapping, and you should go back to the shields folder of the SK disassembly, copy the mappings and place it in “_maps” folder of your disassembly.
As for the art, you’ll need to load PaletteConverter as the player palettes between Sonic 3K and 1 are vastly different. Open it up and you will see this:
We are going to do this according to the numbers I added.
- First of all, click on load BIN and open up Sonic’s S3K palette file. It should be under:
“skdisasm-master\General\Sprites\Sonic\Palettes\SonicandTails.bin”
2. Secondly, open up Sonic’s S1 palette file. It should be under:
“yourdisassembly\pallet\Sonic.bin”
You need to match the palette bytes by dragging Sonic 3K’s byte to match S1’s; and the outcome should be this:
3. Open up convert uncompressed file and open up the Insta-Shield art; It should be located at:
Code:
“skdisasm-master\General\Sprites\Shields\Insta-Shield.bin”
It will give you a pop-up asking if you want to overwrite the source with the converted artwork. Say no and save the file in your disassembly in artunc and name it: “Insta-Shield.bin”
I’ve linked a .rar file with everything converted here if you struggled to get that set up. Then, just drag and drop the files to its respective folder.
Open up sonic1.asm, and under the insta-shield object, insert this:
Code:
; --------------------------------------------------------------
; Insta-Shield art and mappings
; --------------------------------------------------------------
Map_InstaShield:
include "_maps\Insta-Shield.asm" ; Insta-Shield mappings
DPLC_InstaShield:
include "_inc\DPLC - Insta-Shield.asm" ; Insta-Shield DPLCs
Ani_InstaShield:
dc.w byte_199EE3-Ani_InstaShield
dc.w byte_199F13-Ani_InstaShield
byte_199EE3: dc.b $1F, 6, $FF
byte_199F13: dc.b 0, 0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 7, $FD, 0
even
ArtUnc_InstaShield: incbin "artunc\Insta-Shield.bin"
even ; Insta-Shield uncompressed art
You need to make sure the object loads if you managed to obtain a shield and remove it. Go to the shield object and find the line that clears the shield RAM and place this:
Code:
move.b #$XX,(a0) ;Revert shield sprite to Insta-Shield
move.b #$0,$24(a0) ;Reset the routine counter to trigger Insta-Shield Init
Again, XX should be the object ID you set for the insta-shield. Build your disassembly, and it should run well. Next time, I’ll get the elemental shields to guide up and running alongside making references to GitHub’s disassembly. If you have any questions or if it works, feel free to comment down below. =D
Also, can you please credit me if you used this guide as it took me quite a while to write this and set up with a bit of guidance?
Until then...
EDIT: changed the constants to be SSTs
Last edited: