; ---------------------------------------------------------------
; Notes:
; Bottom floor should be at least $20 (32) px.
; ---------------------------------------------------------------

MrBoss_Hits:			equ	20				; number of hits boss could receive
MrBoss_ScreenX:		equ	$20C0			; screen's xpos
MrBoss_ScreenY:		equ	$3C0			; screen's ypos
MrBoss_Cnt:			equ	$34				; address for internal counter
MrBoss_Missileptr:	equ	$32
MrBoss_Parentptr:	equ	$36				; address for parent object pointer
MrBoss_Maskptr:		equ	$38				; address for mask object pointer
MrBoss_Eggmanptr:	equ	$3A				; address for eggman object pointer
MrBoss_Timer:		equ	$3C
MrBoss_InitFlag:		equ	$3F				; flag that signifies boss has begun attacking

MrBoss_SetSprite:	macro
		move.b	#4,obRender(a1)					; use cam coordinates
		move.w	#$0380,obGfx(a1)					; VRAM address to use / $20
		move.l	#Map_MrBossExtra,obMap(a1)		; mappnigs to use
	endm
; ===========================================================================

MrBoss:
		moveq	#0,d0
		move.b	obRoutine(a0),d0
		move.w	@index(pc,d0.w),d0
		jmp	@index(pc,d0.w)
; ===========================================================================

@index:
		dc.w	MrBoss_Init-@index				; $00
		dc.w	MrBoss_MoveMain-@index			; $02
		dc.w	MrBoss_DisplayPlane-@index		; $04
		dc.w	MrBoss_Mask-@index				; $06
		dc.w	MrBoss_MaskAway-@index		; $08
		dc.w	MrBoss_Eggman2-@index			; $0A
		dc.w	MrBoss_Eggman-@index			; $0C
		dc.w	MrBoss_EggHurt-@index			; $0E
		dc.w	MrBoss_Mark-@index				; $10
		dc.w	MrBoss_Missile-@index			; $12
		dc.w	MrBoss_Smoke-@index			; $14
		dc.w	MrBoss_Delete-@index			; $16
		dc.w	MrBoss_EggDefeated-@index		; $18
		dc.w	MrBoss_Defeated-@index			; $1A
; loading shitty code :/ (relax :P. Thanks a lot for your help!)
		dc.w MrBoss_Plat_Init-@index			; $1C
		dc.w MrBoss_Plat_RefreshPos-@index	; $1E
		dc.w MrBoss_Plat_FindSonic-@index	; $20
		dc.w MrBoss_Plat_Fall-@index			; $22
		dc.w MrBoss_Plat_Up-@index			; $24
		dc.w MrBoss_Plat_Restore-@index		; $26
		dc.w MrBoss_Plat_Return-@index		; $28
; ===========================================================================

MrBoss_Plat_Init:
		addq.b	#2,obRoutine(a0)
		move.l	#Map_MrBossPlat,obMap(a0)
		move.w	#$E450,obGfx(a0)
		move.b	#4,obRender(a0)
		move.b	#128/2,obWidth(a0)
		move.b	#32/2,obHeight(a0)
		move.b	#128/2,obActWid(a0)
		move.b	#7,obPriority(a0)		; show behind missiles (to give coherent illusion of black arms)
		move.b	#-$60,$30(a0)
		move.b	#-$50,$31(a0)
		tst.b	$28(a0)
		beq.s	@0
		move.b	#$60,$30(a0)
		bset	#0,1(a0)

@0		move.w	($FFFFA800).w,d0
		move.b	$30(a0),d1
		ext.w	d1
		add.w	d1,d0
		move.w	d0,8(a0)

MrBoss_Plat_RefreshPos:
		move.w	($FFFFA800).w,d0
		move.b	$30(a0),d1
		ext.w	d1
		add.w	d1,d0
;		move.w	d0,8(a0)
; d0 is our target

	swap	d0
	move.w	#0,d0
		move.l	obX(a0),d1				; Source pos
		sub.l	d0,d1
		asr.l	#1,d1
		sub.l	d1,obX(a0)
;		cmpi.w	d0,obX(a0)
;		beq	MrBoss_MoveClear2


		move.w	($FFFFA802).w,d0
		move.b	$31(a0),d1
		ext.w	d1
		add.w	d1,d0
		move.w	d0,$C(a0)
		movea.w	$34(a0),a1
		cmpi.b	#6,ob2ndRout(a1)
		bne.w	MrBoss_Plat_Draw
		addq.b	#2,obRoutine(a0)
		move.l	#0,$10(a0)
		move.w	#$80,$3C(a0)

MrBoss_Plat_FindSonic:
		jsr	(SpeedToPos).l
		move.w	($FFFFF700).w,d0
		btst	#0,1(a0)
		bne.s	@1
		addi.w	#$3E,d0
		cmp.w	obX(a0),d0
		bge.w	@2
		move.w	#-$100,obVelX(a0)
		bra.w	MrBoss_Plat_Draw
@1		addi.w	#$102,d0
		cmp.w	obX(a0),d0
		ble.w	@2
		move.w	#$100,obVelX(a0)
		bra.w	MrBoss_Plat_Draw
@2		bsr.w	Find_SonicObject
		move.w	#$100,d1
		tst.w	d0
		bne.s	@0
		neg.w	d1
@0		move.w	d1,$10(a0)
		subq.w	#1,$3C(a0)
		bpl.w	MrBoss_Plat_Draw
		addq.b	#2,obRoutine(a0)
		move.l	#0,$10(a0)

MrBoss_Plat_Fall:
		ori.w	#$8000,obGfx(a0)
		move.b	#0,obPriority(a0)		; show front missiles
		jsr	(ObjectFall).l
		jsr	(ObjFloorDist).l
		tst.w	d1
		bpl.w	MrBoss_Plat_Draw
		add.w	d1,obY(a0)
		move.l	#0,$10(a0)
		addq.b	#2,obRoutine(a0)
		move.w	#-$400,$12(a0)

MrBoss_Plat_Up:
		jsr	(SpeedToPos).l
		move.w	($FFFFF704).w,d0
		addi.w	#$40,d0
		cmp.w	obY(a0),d0
		bcs.s	MrBoss_Plat_Draw
		addq.b	#2,obRoutine(a0)
		move.w	#0,$12(a0)

MrBoss_Plat_Restore:
		jsr	(SpeedToPos).l
		move.w	($FFFFF700).w,d0
		move.w	#$400,obVelX(a0)
		btst	#0,1(a0)
		beq.s	@1
		neg.w	obVelX(a0)
		addi.w	#$102,d0
		cmp.w	obX(a0),d0
		ble.s		MrBoss_Plat_Draw
		bra.s	@2
@1		addi.w	#$3E,d0
		cmp.w	obX(a0),d0
		bge.s	MrBoss_Plat_Draw
@2		addq.b	#2,obRoutine(a0)
		move.l	#0,$10(a0)

MrBoss_Plat_Return:
		movea.w	$34(a0),a1
		cmpi.b	#4,ob2ndRout(a1)
		bne.s	MrBoss_Plat_Draw
		move.b	#$1E,obRoutine(a0)
		andi.w	#$7FFF,obGfx(a0)
		move.b	#7,obPriority(a0)		; show behind missiles

MrBoss_Plat_Draw:
		movea.w	$34(a0),a2
		tst.b	(a2)
		beq.s	@1
		tst.b	MrBoss_InitFlag(a2)
		beq.s	@0
		move.w	#$30,d1
		move.w	#$0F,d2
		move.w	#$10,d3
		move.w	obX(a0),d4
		jsr	(SolidObject).l
@0		bra.w	MrBoss_Display
@1		move.b	#id_ExplosionBomb,(a0)
		move.b	#0,obRoutine(a0)
		jmp	ExplosionBomb
		rts
; ===========================================================================

MrBoss_rts:
		rts
; ===========================================================================

MrBoss_Init:
		tst.l	(v_plc_buffer).w						; are there any items in the pattern load cue?
		bne.s	MrBoss_rts						; if yes, branch
		addq.b	#2,obRoutine(a0)
		move.l	#VBlank_MrBoss,v_vblank+2.w		; set new vertical interrupt rout
		move.l	#HBlank_MrBoss,v_hblank+2.w		; set new horizontal interrupt rout
		moveq	#0,d2
		move.w	#1,d1
@loop	jsr	FindNextFreeObj
		bne.s	@next
		move.b	(a0),(a1)							; copy ID
		move.b	#$1C,obRoutine(a1)				; set routine
		move.b	d2,$28(a1)
		move.w	a0,$34(a1)
		addq.w	#2,d2
		dbf	d1,@loop
@next
		jsr	FindNextFreeObj						; spawn Mask
		bne	@0
		move.b	(a0),(a1)							; copy ID
		move.b	#$06,obRoutine(a1)				; set routine
		MrBoss_SetSprite							; set sprite config
		move.b	#88/2,obWidth(a1)
		move.b	#88/2,obActWid(a1)
		move.b	#7,obPriority(a1)
		move.b	#3,obFrame(a1)
		move.w	a0,MrBoss_Parentptr(a1)
		move.w	a1,MrBoss_Maskptr(a0)
		jsr	FindNextFreeObj						; spawn Eggman
		bne.s	@0
		move.b	(a0),(a1)
		move.b	#$0A,obRoutine(a1)
		MrBoss_SetSprite
		move.b	#88/2,obWidth(a1)
		move.b	#88/2,obActWid(a1)
		move.b	#7,obPriority(a1)
		move.b	#0,obAnim(a1)
		move.b	#MrBoss_Hits,obColProp(a1)
		move.w	a0,MrBoss_Parentptr(a1)
		move.w	a1,MrBoss_Eggmanptr(a0)
@0		jsr	MrBoss_MoveClear(pc)

MrBoss_MoveMain:
		pea	MrBoss_DisplayPlane(pc)
		moveq	#0,d0
		move.b	ob2ndRout(a0),d0
		move.w	@index(pc,d0.w),d0
		jmp	@index(pc,d0.w)
; ===========================================================================
@index:
		dc.w	MrBoss_MoveAppear-@index		; $00
		dc.w	MrBoss_MoveChooseAttack-@index		; $02
		dc.w	MrBoss_MoveSideways-@index		; $04
		dc.w	MrBoss_ShootMissiles-@index		; $06
; ===========================================================================

MrBoss_MoveAppear:
		move.l	#(MrBoss_ScreenY+(224/2)+$20)<<16,d1	; Destination pos (en formato longword a la izquierda)
		move.l	obY(a0),d0				; Source pos
		sub.l	d1,d0
		asr.l	#4,d0
		sub.l	d0,obY(a0)
		cmpi.w	#(MrBoss_ScreenY+(224/2)+$20),obY(a0)
		beq	MrBoss_MoveClear2
@rts	rts
; ===========================================================================
MrBoss_MoveClear:
		move.w	#(MrBoss_ScreenY+(224/2)+$20)+$80,obY(a0)

MrBoss_moveClear3:
		move.w	#MrBoss_ScreenX+(320/2),obX(a0)
		moveq	#0,d0
		move.w	d0,obVelX(a0)
		move.w	d0,obVelY(a0)
		move.w	d0,MrBoss_Cnt(a0)
		move.b	d0,ob2ndRout(a0)
		rts
; ===========================================================================
MrBoss_MoveClear2:
		move.w	#MrBoss_ScreenX+(320/2),obX(a0)
		move.w	#(MrBoss_ScreenY+(224/2)+$20),obY(a0)
		moveq	#0,d0
		move.w	d0,obVelX(a0)
		move.w	d0,obVelY(a0)
		move.w	d0,MrBoss_Cnt(a0)
		move.b	#2,ob2ndRout(a0)
		tst.b	MrBoss_InitFlag(a0)
		bne.s	@rts
		move.b	#1,MrBoss_InitFlag(a0)
		movea.w	MrBoss_Maskptr(a0),a1
		tst.b	(a1)
		beq.s	@0
		move.b	#$25+$40,obColType(a1)
@0		movea.w	MrBoss_Eggmanptr(a0),a1
		move.b	#$25,obColType(a1)
		addq.b	#2,obRoutine(a1)
@rts	rts
; ===========================================================================

MrBoss_MoveChooseAttack:					; assuming two unique attacks
		jsr	RandomNumber
		andi.w	#1,d0
		bne.s	@0
		move.b	#$04,ob2ndRout(a0)
		rts
; ===========================================================================
@0		move.b	#$06,ob2ndRout(a0)
		rts
; ===========================================================================

MrBoss_ShootMissiles:
		subq.w	#1,MrBoss_Timer(a0)
		bpl.w	@0
		cmpi.w	#@Array_End-@Array+4,MrBoss_Cnt(a0)
		beq	MrBoss_moveClear3
		move.w	#14,MrBoss_Timer(a0)
		jsr	FindFreeObj				; spawn Missile 16x48
		bne	@0
		move.b	(a0),(a1)				; copy ID
		move.b	#$12,obRoutine(a1)			; set routine
		MrBoss_SetSprite						; set sprite config
		move.b	#16/2,obWidth(a1)
		move.b	#16/2,obActWid(a1)
		move.b	#48/2,obHeight(a1)
		move.b	#6,obPriority(a1)
		move.b	#4,obFrame(a1)
		move.w	MrBoss_Cnt(a0),d0
		lea	@Array(pc,d0.w),a2
		move.w	obX(a0),d0
		add.w	(a2)+,d0
		move.w	d0,obX(a1)
		move.w	obY(a0),d0
		add.w	(a2)+,d0
		move.w	d0,obY(a1)
		move.w	#$A9,d0
		jsr	(PlaySound_Special).l
		addq.w	#4,MrBoss_Cnt(a0)
		cmpi.w	#@Array_End-@Array,MrBoss_Cnt(a0)
		beq.s	@1
@0		rts
; ===========================================================================
@1		move.w	#(3*60)-20,MrBoss_Timer(a0)
		addq.w	#4,MrBoss_Cnt(a0)
		rts
; ===========================================================================

@Array:		;	x shift	y shift
		dc.w	-$54,	$2C
		dc.w	$54,	$2C
		dc.w	-$44,	-$10
		dc.w	$44,	-$10
		dc.w	-$3A,	-$10
		dc.w	$3A,	-$10
		dc.w	-$30,	-$10
		dc.w	$30,	$10
@Array_End:
; ===========================================================================

MrBoss_MoveSideways:
		jsr	ObjectFall
		cmpi.w	#(MrBoss_ScreenY+(224/2)+$20)+$40,obY(a0)
		bcs.s	@rts
		move.w	#$CA,d0
		jsr	(PlaySound_Special).l
		move.w	#-$500,obVelY(a0)
		move.w	MrBoss_Cnt(a0),d0
		move.w	@index(pc,d0.w),d0
		move.w	d0,d1
		andi.w	#$7FFF,d0
		beq	MrBoss_MoveClear3
		move.w	d1,obVelX(a0)
		addq.w	#2,MrBoss_Cnt(a0)
@rts	rts
; ===========================================================================
@index:
		dc.w	$200, $200
		dc.w	-$200, -$200
		dc.w	-$200, -$200
		dc.w	$200, $200
		dc.w	$8000
; ===========================================================================

MrBoss_Defeated:
MrBoss_Explode:
		pea	MrBoss_Display(pc)
		move.b	v_framebyte,d0
		andi.w	#1,d0
		bne.s	@rts
		jsr	FindFreeObj
		bne.s	@rts
		move.b	#id_UpwardsExplosion,(a1)
		move.w	obX(a0),d3			; this one method is lazy, but I'm very tired
		subi.w	#184/2,d3
@loop		jsr	RandomNumber
		andi.w	#$FF,d0
		cmpi.w	#184,d0
		bcc.s	@loop
		add.w	d0,d3
		move.w	d3,obX(a1)
		move.w	obY(a0),d0
		addi.w	#$10,d0
		move.w	obY(a0),obY(a1)
@rts		rts
; ===========================================================================

MrBoss_DisplayPlane:
		move.w	obX(a0),$FFFFA800.w
		move.w	obY(a0),$FFFFA802.w
		rts
; ===========================================================================

MrBoss_MaskAway:
		tst.w	ObVelX(a0)
		bne.s	@falling
		cmpi.b	#id_roll,v_player+obAnim.w
		beq.s	@0
		move.l	a0,-(sp)
		lea	v_player.w,a0
		jsr	HurtSonic
		move.l	(sp)+,a0
@0		; to-do: spawn explosion
		move.b	#0,obColType(a0)
		move.b	#0,obPriority(a0)
		ori.w	#$8000,obGfx(a0)
		neg.w	v_player+obVelX.w
		neg.w	v_player+obVelY.w
		move.w	#-$200,obVelX(a0)
		move.w	#-$400,obVelY(a0)
		movea.w	MrBoss_Parentptr(a0),a1
		move.w	obVelX(a1),d0
		lsl.w	#1,d0
		neg.w	d0
		beq.s	@falling
		move.w	d0,obVelX(a0)

@falling	subq.b	#1,MrBoss_Cnt(a0)
		bpl.s	@1
		move.b	#3,MrBoss_Cnt(a0)
		jsr	FindFreeObj
		bne.s	@1
		move.b	#id_ExplosionBomb,(a1)
		move.w	obX(a0),obX(a1)
		move.w	obY(a0),obY(a1)
;		ori.w	#$8000,obGfx(a1)
@1		move.w	v_screenposy.w,d0
		addi.w	#224,d0
		cmp.w	obY(a0),d0
		bcs.s	MrBoss_Delete
		pea	MrBoss_Display(pc)
		jmp	ObjectFall
; ===========================================================================

MrBoss_Delete:
		jmp	DeleteObject
; ===========================================================================

MrBoss_EggHurt:
; if bit 7 from obStatus is set, that means boss is defeated
		tst.b	obStatus(a0)
		bmi	MrBoss_SetDefeated
		tst.w	v_pal_dry+$7C.w
		beq.s	@0
		move.w	#$000,v_pal_dry+$7C.w
		bra.s	@1
@0		move.w	#$EEE,v_pal_dry+$7C.w
@1		addq.b	#1,MrBoss_Cnt(a0)
		cmpi.b	#30,MrBoss_Cnt(a0)
		bne	MrBoss_Mask
		move.b	#0,MrBoss_Cnt(a0)
		move.b	#$25,obColType(a0)
		subq.b	#2,obRoutine(a0)
		bra	MrBoss_mask
; ===========================================================================

MrBoss_SetDefeated:
		movea.w	MrBoss_ParentPtr(a0),a1
		move.b	#$1A,obRoutine(a1)
		move.b	#0,ob2ndRout(a1)
		bclr	#7,obStatus(a0)
		move.b	#0,ob2ndRout(a0)
		move.b	#$18,obRoutine(a0)
		move.b	#0,obFrame(a0)
		move.b	#0,obColType(a0)
		move.w	#$8328,obGfx(a0)
		move.l	#Map_EggPack,obMap(a0)
		move.b	#20,MrBoss_Timer(a0)

MrBoss_EggDefeated:
		out_of_range	@quit
		pea	MrBoss_Display(pc)
		moveq	#0,d0
		move.b	ob2ndRout(a0),d0
		move.w	@index(pc,d0.w),d0
		jmp	@index(pc,d0.w)
@index:		dc.w	@MoveUp-@index
		dc.w	@MoveRight-@index

@MoveUp:	subq.w	#1,obY(a0)
		subq.b	#1,MrBoss_Timer(a0)
		bne.s	@rts
		addq.b	#2,ob2ndRout(a0)
		move.b	#3,obAnim(a0)
@rts		rts
@quit:		movea.w	MrBoss_ParentPtr(a0),a1
		move.b	#$16,obRoutine(a1)
		move.l	#VBlank,v_vblank+2.w
		addq.b	#2,v_dle_routine.w
		pea	MrBoss_Delete(pc)
		jmp	GotThroughAct

@MoveRight:	jsr	SpeedToPos
		addi.w	#$18,obVelX(a0)
		lea	Ani_MrBoss,a1
		jmp	ANimateSprite
; ===========================================================================

MrBoss_Eggman:
		tst.b	obColType(a0)
		bne.s	@0
		addq.b	#2,obRoutine(a0)
		move.w	#$AC,d0
		jmp	(PlaySound_Special).l
; ===========================================================================
@0
MrBoss_Eggman2:
		lea	Ani_MrBoss,a1
		jsr	AnimateSprite

MrBoss_Mask:
		movea.w	MrBoss_Parentptr(a0),a1
		move.w	obX(a1),obX(a0)
		move.w	obY(a1),d0
		subi.w	#$57,d0
		move.w	d0,obY(a0)

MrBoss_DisplaySprite:
MrBoss_Display:
		jmp	DisplaySprite
; ===========================================================================

MrBoss_Mark:
		movea.w	MrBoss_Missileptr(a0),a1
		tst.b	(a1)
		beq	MrBoss_Delete
		lea	Ani_MrBoss,a1
		jsr	AnimateSprite
		bra.s	MrBoss_Display
; ===========================================================================

MrBoss_Smoke:
;		movea.w	MrBoss_Missileptr(a0),a1
;		tst.b	(a1)
;		beq	MrBoss_Delete
		jsr	SpeedToPos
		lea	Ani_MrBoss,a1
		jsr	AnimateSprite
		bra.s	MrBoss_Display
; ===========================================================================

MrBoss_Missile:
		pea	MrBoss_Display(pc)
		moveq	#0,d0
		move.b	ob2ndRout(a0),d0
		move.w	@index(pc,d0.w),d0
		jmp	@index(pc,d0.w)
; ===========================================================================
@index
		dc.w	@init-@index
		dc.w	@wait1-@index
		dc.w	@upwards-@index
		dc.w	@wait2-@index
		dc.w	@downwards-@index
		dc.w	@explode-@index
		dc.w	MrBoss_Delete-@index
; ===========================================================================

@target_obY:	equ	$30

@init:
		move.w	obY(a0),d0
		subi.w	#$20,d0
		move.w	d0,@target_obY(a0)
		addq.b	#2,ob2ndRout(a0)

@wait1:
		move.l	@target_obY(a0),d1			; Destination pos (en formato longword a la izquierda)
		move.l	obY(a0),d0				; Source pos
		sub.l	d1,d0
		asr.l	#3,d0
		sub.l	d0,obY(a0)
		move.w	@target_obY(a0),d1
		cmp.w	obY(a0),d1
		bne	@rts
		move.b	#45,MrBoss_Timer(a0)
		addq.b	#2,ob2ndRout(a0)

@upwards:
		jsr	@smoke(pc)
		jsr	SpeedToPos
		subi.w	#$40,obVelY(a0)
		subq.b	#1,MrBoss_Timer(a0)
		bne		@rts
		move.w	#MrBoss_ScreenY-(48/2),obY(a0)

@rndpos
		jsr	RandomNumber
		andi.w	#$1F0,d0
		cmpi.w	#320-16,d0
		bcc.s	@rndpos
		addi.w	#MrBoss_ScreenX+(16/2),d0
		move.w	d0,obX(a0)
		ori.w	#$8000,obGfx(a0)
		neg.w	obVelY(a0)
		subi.w	#$40,obVelY(a0)
		move.b	#45,MrBoss_Cnt(a0)
		bchg	#1,obRender(a0)
		bchg	#1,obStatus(a0)

		jsr	FindFreeObj				; spawn Missile marker
		bne	@rts2
		move.b	(a0),(a1)				; copy ID
		move.b	#$10,obRoutine(a1)			; set routine
		MrBoss_SetSprite				; set sprite config
		ori.w	#$8000,obGfx(a1)
		move.b	#1,obAnim(a1)
		move.w	obX(a0),obX(a1)
		move.w	#MrBoss_ScreenY+224-$20-(16/2),obY(a1)
		move.w	a0,MrBoss_Missileptr(a1)
@rts2	addq.b	#2,ob2ndRout(a0)
		move.w	#$BA,d0
		jsr	(PlaySound_Special).l
@rts	rts
; ===========================================================================
@wait2:
		subq.b	#1,MrBoss_Cnt(a0)
		bne.s	@rts
		addq.b	#2,ob2ndRout(a0)
		rts
; ===========================================================================

@downwards:
		jsr	@smoke(pc)
		jsr	ObjectFall
		jsr	ObjFloorDist
		tst.w	d1
		bpl.s	@rts
		add.w	d1,obY(a0)
		addq.b	#2,ob2ndRout(a0)
		rts
; ===========================================================================

@explode:
		jsr	FindFreeObj
		bne	@rts
		move.b	#id_ExplosionMissile,(a1)
		move.w	obX(a0),obX(a1)
		move.w	obY(a0),obY(a1)
		move.b	#$26+$80,obColType(a0)
		addq.b	#2,ob2ndRout(a0)
		rts
; ===========================================================================

@SMoke:
		subq.b	#1,MrBoss_Timer+1(a0)
		bpl	@rtss
		move.b	#5,MrBoss_Timer+1(a0)
		jsr	FindFreeObj				; spawn Missile smoke
		bne	@rtss
		move.b	(a0),(a1)				; copy ID
		move.b	#$14,obRoutine(a1)			; set routine
		MrBoss_SetSprite				; set sprite config
		move.w	obGfx(a0),obGfx(a1)
		move.b	#2,obAnim(a1)
		move.w	obX(a0),obX(a1)
		move.w	obY(a0),obY(a1)
		move.w	#$10,d1
		move.w	#$180,d0
		btst	#1,obRender(a0)
		beq.s	@noflip
		neg.w	d0
		neg.w	d1
@noflip
		add.w	d1,obY(a1)
		move.w	ObVelY(a0),d1
		asr.w	#2,d1
		add.w	d1,d0
		move.w	d0,obVelY(a1)
		move.w	a0,MrBoss_MissilePtr(a1)
@rtss	rts
; ===========================================================================

VBlank_MrBoss:
		movem.l	d0-a6,-(sp)
		move.w	(vdp_control_port).l,d0
		move.l	#$40000010,(vdp_control_port).l
		move.w	$FFFFA802.w,d0
		addi.w	#$B0,d0
		neg.w	d0
		move.w	d0,vdp_data_port
		move.w	#$8200+(vram_bossmap>>10),vdp_control_port
		jmp	VBlank_Normal
; ===========================================================================

HBlank_MrBoss:
		tst.w	f_hbla_pal.w
		beq.s	@nochg
		move.w	#$8200+(vram_fg>>10),vdp_control_port
		move.l	#$40000010,(vdp_control_port).l
		move.l	(v_scrposy_dup).w,(vdp_data_port).l	; send screen y-axis pos. to VSRAM
		move.w	#$8A00+224-1,vdp_control_port		; reset HBlank register
		move.w	#0,f_hbla_pal.w

	@nochg:
		tst.b	($FFFFF64F).w
		bne.s	@doupdates
		rte
; ===========================================================================

@doupdates
		clr.b	($FFFFF64F).w
		movem.l	d0-a6,-(sp)
		jsr	Demo_Time
		jsr	(UpdateMusic).l
		movem.l	(sp)+,d0-a6
		rte
; ---------------------------------------------------------------------------
; Object - explosion a destroyed missile
; ---------------------------------------------------------------------------

ExplosionMissile:
		moveq	#0,d0
		move.b	obRoutine(a0),d0
		move.w	@Index(pc,d0.w),d1
		jmp	@Index(pc,d1.w)
; ===========================================================================

@Index:
		dc.w @Main-@Index
		dc.w @ExItem_Animate-@Index
; ===========================================================================

@Cnt:		equ	$34
@timer:		equ	$36

@Main:		; Routine 0
		addq.b	#2,obRoutine(a0)
		move.l	#Map_ExplodeBomb,obMap(a0)
		move.w	#$85A0,obGfx(a0)
		move.b	#4,obRender(a0)
		move.b	#1,obPriority(a0)
		move.b	#0,obColType(a0)
		move.b	#$C,obActWid(a0)
		move.b	#7,obTimeFrame(a0)
		move.b	#0,obFrame(a0)
		move.b	#sfx_Bomb,d0
		jsr	PlaySound_Special
		move.w	@Cnt(a0),d0
		lea	@Array(pc,d0.w),a1
		move.w	(a1)+,d0
		add.w	d0,obX(a0)
		move.w	(a1)+,d0
		add.w	d0,obY(a0)
		move.w	(a1)+,@timer(a0)

@ExItem_Animate:
		cmpi.w	#@Array_End-@Array,@Cnt(a0)
		subq.w	#1,@timer(a0)
		bne.s	@0
		jsr	FindFreeObj
		move.b	(a0),(a1)
		move.w	obX(a0),obX(a1)
		move.w	obY(a0),obY(a1)
		move.w	@Cnt(a0),d0
		addq.w	#$06,d0
		move.w	d0,@Cnt(a1)
@0		jmp	ExItem_Animate
; ===========================================================================

@Array:		;	x shift	y shift	timer
		dc.w	$00,	$10,	$05
		dc.w	$00,	-$10,	$05
		dc.w	-$06,	-$10,	$01
		dc.w	$10,	$00,	$01
@Array_End:
; ===========================================================================

UpwardsExplosion:
		moveq	#0,d0
		move.b	obRoutine(a0),d0
		move.w	@Index(pc,d0.w),d1
		jmp	@Index(pc,d1.w)
; ===========================================================================

@Index:		dc.w @Main-@Index
		dc.w @ExItem_Animate-@Index
; ===========================================================================

@Main:		; Routine 0
		addq.b	#2,obRoutine(a0)
		move.l	#Map_ExplodeBomb,obMap(a0)
		move.w	#$85A0,obGfx(a0)
		move.b	#4,obRender(a0)
		move.b	#1,obPriority(a0)
		move.b	#0,obColType(a0)
		move.b	#$C,obActWid(a0)
		move.b	#7,obTimeFrame(a0)
		move.b	#0,obFrame(a0)
		move.w	#-$440,obVelY(a0)
		move.b	#sfx_Bomb,d0
		jsr	PlaySound_Special

@ExItem_Animate:
		subq.w	#8,obVelY(a0)
		jsr	SpeedToPos
		jmp	ExItem_Animate
; ===========================================================================

Find_Sonic:
Find_SonicObject:
		lea	(v_player).w,a1

Find_OtherObject:
		moveq	#0,d0
		move.w	x_pos(a0),d2
		sub.w	x_pos(a1),d2
		bpl.s	loc_84BAE
		neg.w	d2
		addq.w	#2,d0

loc_84BAE:
		moveq	#0,d1
		move.w	y_pos(a0),d3
		sub.w	y_pos(a1),d3
		bpl.s	locret_84BBE
		neg.w	d3
		addq.w	#2,d1

locret_84BBE:
		rts
; End of function Find_OtherObject
; ===========================================================================

Ani_MrBoss:
		dc.w	@anim0-Ani_MrBoss
		dc.w	@anim1-Ani_MrBoss
		dc.w	@anim2-Ani_MrBoss
		dc.w	@anim3-Ani_MrBoss
@anim0:	dc.b	$0F, $01, $02, afEnd
@anim1:		dc.b	$03, $09, $0A, afEnd
@anim2:		dc.b	$03, $05, $06, $07, $08, afRoutine
@anim3:		dc.b	$03, $01, $02, afEnd
		even
Map_MrBossExtra:	include	"_maps\MrBossExtra.asm"
		even
Map_MrBossPlat:		include	"_maps\MrBoss_PlatMap.asm"
		even
Map_EggPack:		include	"_maps\Eggpack.asm"
		even
