Skip to content
Clément Gallet edited this page Jul 2, 2014 · 4 revisions

Executing command 60 or attacking with an Amulet can make the jump to the long address stored in $DC9B-$DC9D. This variable is inside a big area used for animations as it seems. Before each animation, the whole area is FFed and function C1/A0B5 is filling a very little portion of it depending on the animation to do. What and where to write depends on variables $7AEA-$7AEF that are set in function C1/A18B for spells. The spell graphic animations are stored in $6273, $6275, $6277 and $627E, and are taken in function C1/9CB3 from $D07FB2.

Here is a lua script to determine which animation is filling those variables:

memory.usememorydomain("CARTROM")

for anim_id = 0,649 do

	write_list = {}

	-- Function C1/A18B --

	anim_offset = anim_id * 0x06
	anim1 = memory.readbyte(0x14D000 + anim_offset) -- $7AEA
	anim2 = memory.readbyte(0x14D001 + anim_offset) -- ...
	anim3 = memory.read_u16_le(0x14D002 + anim_offset)
	anim5 = memory.readbyte(0x14D004 + anim_offset)
	anim6 = memory.readbyte(0x14D005 + anim_offset) -- $7AEF

	-- Function C1/A0B5 --
	write_pointer1 = 0xCE3F -- $14
	write_pointer2 = 0xD8BF -- $1C

	anim1 = bit.band(anim1, 0x3F)
	var18 = bit.lshift(anim5, 3) % 256 -- $18
	var19 = bit.lshift(anim6, 3) % 256 -- $19
  
	for it = 1,anim1 do

		pointer_offset = anim3 * 2 -- X
		pointer1 = memory.read_u16_le(0x14DF3C + pointer_offset) -- $10
		pointer2 = memory.read_u16_le(0x14DF3E + pointer_offset) -- $1A

		write_offset = 0 -- Y

		while ((pointer1 ~= pointer2) and (memory.readbyte(0x110000 + pointer1) ~= 0xFF or memory.readbyte(0x110001 + pointer1) ~= 0xFF)) do

			value1 = memory.readbyte(0x110000 + pointer1)
			var22 = bit.band(value1, 0xF0) -- $22
			write_list[write_pointer1+write_offset] = var22 - var18
			write_list[write_pointer2+write_offset] = bit.bxor(var22, 0xFF) + 1 - 0x10 + var18
			write_offset = write_offset + 1
			modvalue1 = bit.band(value1, 0x0F) * 16 - var19
			write_list[write_pointer1+write_offset] = modvalue1
			write_list[write_pointer2+write_offset] = modvalue1
			write_offset = write_offset + 1
			pointer1 = pointer1 + 1
			value1 = memory.readbyte(0x110000 + pointer1)
			var16 = bit.band(value1, 0x07) * 2
			write_list[write_pointer1+write_offset] = bit.band(value1, 0x38) * 4 + var16
			write_list[write_pointer2+write_offset] = bit.band(value1, 0x38) * 4 + var16
			write_offset = write_offset + 1
			write_list[write_pointer1+write_offset] = bit.band(value1, 0xC0)
			write_list[write_pointer2+write_offset] = bit.bxor(bit.band(value1, 0xC0), 0x40)
			write_offset = write_offset + 1
			pointer1 = pointer1 + 1
		end	

		-- $C1/A164
		write_list[write_pointer1+write_offset] = 0xFF
		write_list[write_pointer2+write_offset] = 0xFF
		write_pointer1 = write_pointer1 + 0x54
		write_pointer2 = write_pointer2 + 0x54
		anim3 = anim3 + 1
	end

	-- Print results
	if write_list[0xDC9B] ~= nil then
	ss = bizstring.hex(write_list[0xDC9B])
	console.writeline(string.format("Anim %d: DC9B is %s", anim_id, ss))	
	end
	if write_list[0xDC9C] ~= nil then
	ss = bizstring.hex(write_list[0xDC9C])
	console.writeline(string.format("Anim %d: DC9B is %s", anim_id, ss))	
	end
	if write_list[0xDC9D] ~= nil then
	ss = bizstring.hex(write_list[0xDC9D])
	console.writeline(string.format("Anim %d: DC9B is %s", anim_id, ss))	
	end
  
end

Testing glitched weapons:

  • Moogle Suit (9F): $DC9B = $28:20E0
Clone this wiki locally