To download a Compiled Rom and the Source Code, click here: http://goo.gl/4N1fY
To apply this guide, you need first apply the Homing Attack in Sonic 1 guide.

To make this, we need create a circumference that pass by Sonic and the Object. All circumference have a center, and in this case the Sonic don't is the center, now that I know it, we need make our center.

Why Pseudo? Because in the calculations the Sonic will be the center. The "Pseudo Center" is a point between Sonic and the Object, in other words, is the distance/2.
This will be used as the target in Homing Attack, because in this Homing Attack the Sonic don't attack the Object directly, the effect make Sonic attack the Object.

The "Real Circumference" is the circumference that will be used by the game to execute this effect, where Sonic is the center. To create the effect we need modify the angle, to the Sonic pass in a Pseudo Circumference (Pseudo Center make a Pseudo Circumference). Modifying the angle, Sonic go in a other direction, no in Pseudo Center direction, but in the direction that is need to create the circular movement effect.

This is the representation of what we need make to happen the effect. The "Green Lines" is the Homing Attack in the Pseudo Center direction, but to create the effect we need add or sub 90º (add = when go to left, sub = when go to right), this make the "Dark Red Lines".
Conclusion: To make this Homing Attack we need create a Pseudo Center between the Sonic and the Object, and attack the Pseudo Center adding or subtracting 90º to make the circular movement effect.
In Sonic_Homingattack subroutine, modify this:
- Code:
HA_calcdistance2: ; continuation of distance calculator
muls.w d1,d1 ; horizontal distance squared
muls.w d2,d2 ; vertical distance squared
add.l d2,d1 ; add vertical distance to horizontal distance
cmp.l #16384,d1 ; is distance of Sonic, greater than or equal 128 pixels of the object? (128^2=16384 // $80^2=$4000)
bge.s HA_nextobject ; if yes, don't execute the homing attack
move.w #$BC,d0 ; set homing attack sound
jsr (PlaySound).l ; play homing attack sound
bclr #4,$22(a0) ; clear "uncontrolled jump" flag
move.b #30,($FFFFFFD1).w ; number of frames Sonic can chasing the object
move.l a1,($FFFFFFD2).w ; save the object address that Sonic is chasing
; ---------------------------------------------------------------------------
HA_Move:
movea.l ($FFFFFFD2).w,a1 ; load the object address that Sonic is chasing
subi.b #1,($FFFFFFD1).w ; sub 1 of frames counter
tst.b ($FFFFFFD1).w ; the time to the Sonic chasing some object is over?
beq.w Sonic_HA_rts ; if yes, don't make the Homing Attack
; ---------------------------------------------------------------------------
; Recalculating the distance between the Sonic and the object (d1 = x distance / d2 = y distance)
move.w 8(a1),d1 ; move the object x-position to d1
move.w $C(a1),d2 ; move the object y-position to d2
sub.w 8(a0),d1 ; sub sonic x-position of object x-position
sub.w $C(a0),d2 ; sub sonic y-position of object y-position
jsr (CalcAngle).l ; calculates the angle
jsr (CalcSine).l ; calculates the sine and the cosine
muls.w #$C,d1 ; multiply cosine by $C
move.w d1,$10(a0) ; move d1 to X-velocity
muls.w #$C,d0 ; multiply sine by $C
move.w d0,$12(a0) ; move d0 to Y-velocity
Sonic_HA_rts:
rts ; return
; Command of Homingattack end here
- Code:
HA_calcdistance2: ; continuation of distance calculator
muls.w d1,d1 ; horizontal distance squared
muls.w d2,d2 ; vertical distance squared
add.l d2,d1 ; add vertical distance to horizontal distance
cmp.l #16384,d1 ; is distance of Sonic, greater than or equal 128 pixels of the object? (128^2=16384 // $80^2=$4000)
bge.s HA_nextobject ; if yes, don't execute the homing attack
move.w #$BC,d0 ; set homing attack sound
jsr (PlaySound).l ; play homing attack sound
bclr #4,$22(a0) ; clear "uncontrolled jump" flag
move.w #512,($FFFFFFD2).w ; number of frames Sonic can chasing the object
; ---------------------------------------------------------------------------
; get the Pseudo Center's real position
move.w 8(a1),d1 ; move the object x-position to d1
move.w $C(a1),d2 ; move the object y-position to d2
sub.w 8(a0),d1 ; sub sonic x-position of object x-position
sub.w $C(a0),d2 ; sub sonic y-position of object y-position
asr.w d1 ; /2 (get Pseudo Center's pseudo x-pos)
asr.w d2 ; /2 (get Pseudo Center's pseudo y-pos)
add.w 8(a0),d1 ; add the Sonic's x-pos to Pseudo Center's pseudo x-pos
; to get the Pseudo Center's real x-position
add.w $C(a0),d2 ; add the Sonic's y-pos to Pseudo Center's pseudo y-pos
; to get the Pseudo Center's real y-position
move.w d1,($FFFFFF40).w ; save Pseudo Center's real x-position
move.w d2,($FFFFFF42).w ; save Pseudo Center's real y-position
HA_Move:
subi.w #1,($FFFFFFD2).w ; sub 1 of frames counter
tst.w ($FFFFFFD2).w ; the time to the Sonic chasing some object is over?
bne.s HA_Cycle ; if not, make the Homing Attack
clr.b ($FFFFFFD1).w ; cancel the Homing Attack, clearing the side variable
; ---------------------------------------------------------------------------
HA_Cycle:
move.w ($FFFFFF40).w,d1 ; load Pseudo Center's real x-position
move.w ($FFFFFF42).w,d2 ; load Pseudo Center's real y-position
sub.w 8(a0),d1 ; sub sonic x-position of Pseudo Center's real x-position
sub.w $C(a0),d2 ; sub sonic y-position of Pseudo Center's real y-position
jsr (CalcAngle).l ; calculates the angle
moveq #0,d3 ; clear d3
lea ($FFFFFFD1).w,a3 ; set the side variable
cmpi.b #2,(a3) ; what side Sonic is going?
bgt.s HA_angletoleft ; left? if yes, branch
beq.s HA_angletoright ; right? if yes, branch
; if the Homing Attack don't was activated, continue
move.b #64,d3 ; set 64º (90º in real world) to d3
sub.b d3,d0 ; separates the angles in two sides, left (a<90º and 270º<a) and right(90º<a>270º)
cmpi.w #128,d0 ; is left side of cartesian plane?
ble.s HA_angletoleft ; if yes, branch
HA_angletoright:
sub.b #64,d0 ; sub 64º (90º in real world) degrees
move.b #2,(a3) ; say that is the right side of cartesian plane
bra.s HA_angleend
HA_angletoleft:
add.b #64,d0 ; add 64º (90º in real world) degrees
move.b #3,(a3) ; say that is the left side of cartesian plane
HA_angleend:
add.b d3,d0 ; repositions the angle
jsr (CalcSine).l ; calculates the sine and the cosine
muls.w #12,d1 ; multiply cosine by $C
move.w d1,$10(a0) ; move d1 to X-velocity
muls.w #12,d0 ; multiply sine by $C
move.w d0,$12(a0) ; move d0 to Y-velocity
Sonic_HA_rts:
rts ; return
; Command of Homingattack end here
To change the Pseudo Circumference size, modify the "#64", of these two codes:
- Code:
HA_angletoright:
sub.b #64,d0
- Code:
HA_angletoleft:
add.b #64,d0