/*
	This script file is part of the Sonic 3 A.I.R. script software distribution.
	Copyright (C) 2017-2024 by Eukaryot

	Published under the GNU GPLv3 open source software license, see license.txt
	or https://www.gnu.org/licenses/gpl-3.0.en.html
*/



//-------------------------------------------------------//
// Swinging Platform                                     //
//-------------------------------------------------------//

// Both types:
//  - Constantly swinging from left to right and back
//  - Swinging up when character steps on it

//# address-hook(0x04143c) end(0x0414f8)
function void fn04143c()
{
	objA0.mapping_offset = 0x0416c6
	objA0.sprite_attributes = (sprite_attribute.PALETTE.LINE2 | 0x0001)
	objA0.render_flags = render_flag.WORLD
	objA0.box_size.x = 0x20
	objA0.box_size.y = 0x10
	objA0.sprite_priority = 0x0280
	u16[A0 + 0x44] = objA0.position.x.u16
	u16[A0 + 0x46] = objA0.position.y.u16

	if (allocDynamicObjectAfterA0())
	{
		objA1.update_address = addressof(DrawObject)
		objA1.mapping_offset = objA0.mapping_offset
		objA1.sprite_attributes = objA0.sprite_attributes
		objA1.render_flags = render_flag.WORLD
		objA1.box_size.x = 0x60
		objA1.box_size.y = 0x60
		objA1.sprite_priority = 0x0280

		D2.u16 = objA0.position.x.u16
		D3.u16 = objA0.position.y.u16
		objA1.position.x.u16 = D2.u16
		objA1.position.y.u16 = D3.u16
		objA1.render_flags |= render_flag.COMPOUND

		A2 = A1 + 0x18
		D1.u16 = objA0.subtype2c & 0x0f
		objA1.compound.count = D1.u16
		while (D1.s16 > 0)
		{
			u16[(A2+=2)-2] = D2.u16
			u16[(A2+=2)-2] = D3.u16
			u16[(A2+=2)-2] = 1
			--D1.s16
		}

		objA1.compound.sprite1.animation.sprite = 2
		u8[A1 + 0x22] = 1
		u16[A0 + 0x3c] = A1.u16
	}

	u16[A0 + 0x26] = 0x4000
	objA0.value32 = 0
	objA0.subtype2c &= 0xf0

	objA0.update_address = 0x0414fe
	fn0414fe()
}


//# address-hook(0x0414fe) end(0x041546)
function void fn0414fe()
{
	u16 px = objA0.position.x.u16
	fn04154c()

	D1.u16 = 0x20
	D3.u16 = 0x11
	D4.u16 = px
	PlatformCheckClimbOn()

	D0.u16 = (u16[A0 + 0x44] & 0xff80) - level.despawn_position.x
	if (D0.u16 <= 0x0280)
	{
		DrawObject()
	}
	else
	{
		if (objA0.respawn_entry)
		{
			A2 = 0xffff0000 + objA0.respawn_entry
			u8[A2] &= ~0x80
		}
		A1 = 0xffff0000 + u16[A0 + 0x3c]
		UnloadObjectA1()
		UnloadObject()
	}
}


//# address-hook(0x04154c) end(0x041634)
function void fn04154c()
{
	D0 = 0
	D1 = 0
	D0.u8 = u8[0xfffffe88] + 0x80
	if (objA0.subtype2c != 0)
	{
		fn041636()
	}

	if (D0.u8 == u8[A0 + 0x36])
		return

	u8[A0 + 0x36] = D0.u8
	if (objA0.flags2a & 0x01)
	{
		D0.s16 = 0x80 - D0.s16
	}
	if (objA0.flags2a & 0x02)
	{
		D0.s16 = -D0.s16
	}
	LookupSinCos()
	D2.u16 = u16[A0 + 0x46]
	D3.u16 = u16[A0 + 0x44]
	D6 = 0
	A1 = 0xffff0000 + u16[A0 + 0x3c]
	D6.u16 = objA1.compound.count - 2
	if (D6.s16 < 0)
		return

	D0 = (D0 << 16) + (D0 >> 16)
	D1 = (D1 << 16) + (D1 >> 16)
	D0.s32 >>= 4
	D1.s32 >>= 4
	D4 = D0
	D5 = D1
	D4.s32 >>= 1
	D5.s32 >>= 1
	D4 += D0
	D5 += D1
	A2 = A1 + 0x1e

	while (D6.s16 >= 0)
	{
		push(D5)
		push(D4)

		D4 = (D4 << 16) + (D4 >> 16)
		D5 = (D5 << 16) + (D5 >> 16)
		D4.u16 += D2.u16
		D5.u16 += D3.u16
		u16[(A2+=2)-2] = D5.u16
		u16[(A2+=2)-2] = D4.u16

		D4 = pop()
		D5 = pop()

		D4 += D0
		D5 += D1
		A2 += 2
		--D6.s16
	}

	push(D5)
	push(D4)

	D4 = (D4 << 16) + (D4 >> 16)
	D5 = (D5 << 16) + (D5 >> 16)
	D4.u16 += D2.u16
	D5.u16 += D3.u16
	D2.u16 = u16[A1 + 0x24]
	D3.u16 = u16[A1 + 0x26]
	u16[A1 + 0x24] = D5.u16
	u16[A1 + 0x26] = D4.u16
	objA1.position.x.u16 = D2.u16
	objA1.position.y.u16 = D3.u16

	D4 = pop()
	D5 = pop()

	D0.s32 >>= 1
	D1.s32 >>= 1
	D4 += D0
	D5 += D1
	D4 = (D4 << 16) + (D4 >> 16)
	D5 = (D5 << 16) + (D5 >> 16)
	D4.u16 += u16[A0 + 0x46]
	D5.u16 += u16[A0 + 0x44]
	objA0.position.y.u16 = D4.u16
	if (objA0.subtype2c != 0)
	{
		D5.u16 += (objA0.flags2a & 0x01) ? 0x18 : -0x18
	}
	objA0.position.x.u16 = D5.u16
}



// Only for the variant that waits for a character to step on it

//# address-hook(0x041636) end(0x0416c4)
function void fn041636()
{
	if (u16[A0 + 0x34] != 0)
	{
		if ((objA0.flags2a & object.flag.P1_ON_OBJECT) == 0)
		{
			--u16[A0 + 0x34]
		}
	}
	else
	{
		if (u8[A0 + 0x31] == 0)
		{
			if ((objA0.flags2a & object.flag.P1_ON_OBJECT) == 0 || debug_mode.state != 0)
			{
				D0.u8 = objA0.value26
				return
			}
			u8[A0 + 0x31] = 1
		}

		if (u8[A0 + 0x30] == 0)
		{
			D0.u16 = objA0.value32 + 8
			objA0.value32 = D0.u16
			u16[A0 + 0x26] += D0.u16
			if (D0.u16 == 0)
			{
				u8[A0 + 0x31] = 0
			}
			if (objA0.value26 >= 0x80)
			{
				u8[A0 + 0x30] = 1
			}
		}
		else
		{
			D0.u16 = objA0.value32 - 8
			objA0.value32 = D0.u16
			u16[A0 + 0x26] += D0.u16
			if (D0.u16 == 0)
			{
				u16[A0 + 0x34] = 0x1e
			}
			if (objA0.value26 < 0x80)
			{
				u8[A0 + 0x30] = 0
			}
		}
	}

	D0.u8 = objA0.value26
}
