display-name: ["Games/Cannon Fodder", "Games/Cannon Fodder 2"]
meta: {"Working": ["Packed file extraction", "Tiles", "Sprites", "Audio", "Levels (tiles only)"]}

if (file.name == "cf_eng.dat")
{
	unsigned32 data-start

	file
	{
		pascal-string(unsigned8) name
		unsigned32 offset
		unsigned32 size
		compressed "CannonFodder"

		at offset
		{
			unsigned32 decompressed-size

			if (decompressed-size == 64768)
			{
				interpret-as "cannonfodder-interlacedimage"
			}
		}

	} while (file.position < data-start)
}

if (file.name like "*.spt")
{
	folder: "Level sprite info"
}

//Images
interlace-table:
{
	"hill.dat":		1,
	"morphbig.dat":		1,
	["*k"]:			1,
	["*"]:			4
}

file-format cannonfodder-interlacedimage
{
	at 64000
	{
		palette
		{
			size: 256
			format: "R6G6B6"
		}
	}

	image
	{
		format: "I8"
		width: 320
		height: 200		
		interlaced: interlace-table[file.name]
	}	
}

if (file.size == 64768)
{
	interpret-as "cannonfodder-interlacedimage"	
}

if (file.name like ["morp*", "junp*", "desp*", "intp*", "icep*"])
{
	at file.size - 768
	{
		palette
		{
			size: 256
			format: "R6G6B6"
		}
	}
	
	image
	{
		format:  "I8"
		width: 320
		height: (file.size - 768) / 320
		interlaced: 4
	}
}

if (file.name == "paraheli.dat")
{
	at file.size - 768
	{
		palette
		{
			size: 256
			format: "R6G6B6"
		}
	}
	
	image
	{
		format: "I4"
		width: 320
		height: (file.size - 768) / 160
		transparent-index: 0
	}	
}

if (file.name like ["pstuff.dat", "hillbits.dat"])
{
	at file.size - 48
	{
		palette
		{
			size: 16
			format: "R6G6B6"
		}
	}

	image
	{
		format: "I4"
		width: 320
		height: (file.size - 48) / 320
		data-size: file.size
	}	
}

if (file.name like "*copt*")
{
	at file.size - 768
	{
		palette
		{
			size: 256
			format: "R6G6B6"
		}
	}
		
	compressed[file.size - 768] "CoptSprites"
	{
		image
		{
			format: "I8"
			width: 320
			height: 340
			transparent-index: 0
		}
	}
}

if (file.name like "*army*")
{
	at file.size - 48
	{
		palette
		{
			size: 16
			format: "R6G6B6"
		}
	}

	image
	{
		format: "I4"
		width: 320
		height: 336
		transparent-index: 0
	}
}

if (file.name like "*.voc")
{
	interpret-as "sound-VOC"
}

if (file.name like "*.map")
{
	folder: "Levels"

	fixed-string(12) baseName
	data(4) unknown //some sort of tile mapping?

	fixed-string(12) subName
	data(4) unknown //some sort of tile mapping?
	
	data(0x30) unknown

	data(4) unknown //"CFED"
	unsigned16be width
	unsigned16be height

	data(8) unknown

	grid-x: 16
	grid-y: 16
	
	level
	{
		compressed[file.remaining-bytes] "CFLevel-BackgroundLayer"
		{
			level-layer
			{
				data-type: "unsigned8"
				order: 0
				layer-image: baseName					
				name: "Background"
				ignore-tile: 255
			}
		}

		at 0x60:
		
		compressed[file.remaining-bytes] "CFLevel-ForegroundLayer"
		{
			level-layer 
			{
				data-type: "unsigned8"
				order: 1
				layer-image: subName					
				name: "Foreground"
				ignore-tile: 255
			}
		}
	}
}

function CFLevel-BackgroundLayer
{
	loop while (file.remaining-bytes > 0)
	{
		read unsigned16be tile
		if (tile > 255)
		{
			write unsigned8 (tile & 0xFF)
		}
		else
		{
			write unsigned8 tile
		}
	}
}

function CFLevel-ForegroundLayer
{
	loop while (file.remaining-bytes > 0)
	{
		read unsigned16be tile
		if (tile < 240)
		{
			write unsigned8 255
		}
		else
		{
			tile-test: tile - 240
			if (tile-test > 239)
			{
				write unsigned8 255 //big, big value...hmm
			}
			else
			{
				write unsigned8 tile - 240
			}
		}
	}
}

// Sprite colour mapping - this data has to be somewhere, maybe the exe?

function CoptSprites
{
	x: 0
	y: 0

	loop (340): y
	{
		loop (160)
		{
			read unsigned8 current-bits

			mask: 0

			if ((x >= 244) and (x <= 263) and (y >= 35) and (y <= 49))
			{
				mask = 0x20
			}
			else if (y < 48)
			{
				mask = 0x10
			}
			else if ((y > 256) and (x < 160))
			{
				mask = 0x20
			}			
			else if ((y >= 311) and (x > 255))
			{
				mask = 0x20
			}
			else if ((y >= 286) and (x > 255))
			{
				mask = 0x30
			}
			else if ((y >= 225) and (x > 255))
			{
				mask = 0x20
			}
			else if ((y > 237) and (y < 257) and (x >= 80) and (x < 222))
			{
				mask = 0x10
			}
			else if ((y >= 176) and (y < 195) and (x >= 112) and (x < 190))
			{
				mask = 0x10
			}
			else if ((y >= 150) and (y <= 174) and (x >= 128) and (x <= 226))
			{
				mask = 0x10
			}
			else if ((y >= 179) and (y <= 219) and (x <= 127))
			{
				mask = 0x10
			}
			else if ((y > 256) and (y < 288) and (x >= 160) and (x < 255))
			{
				mask = 0x20
			}
			else if ((y >= 288) and (x >= 160) and (x < 255))
			{
				mask = 0x30
			}
			else if ((y < 68) and (x < 130))
			{
				mask = 0x10
			}
			else if ((y >= 68) and (y < 84) and (x > 50) and (x < 137))
			{
				mask = 0x10
			}
			else if ((y >= 118) and (y < 148) and (x < 192))
			{
				mask = 0x20
			}
			else if ((y >= 84) and (y < 116) and (x < 160))
			{
				mask = 0x20
			}
			else if ((y >= 88) and (y < 116) and (x >= 160))
			{
				mask = 0x20
			}
			else if ((y >= 168) and (y < 198) and (x >= 225))
			{
				mask = 0x30
			}
			else if ((y >= 198) and (y < 226) and (x > 161))
			{
				mask = 0x30
			}
			else if ((y >= 176) and (y <= 196) and (x >= 192) and (x <= 224))
			{
				mask = 0x20
			}
			else if ((y >= 198) and (y <= 226) and (x >= 128) and (x <= 161))
			{
				mask = 0x20
			}
			//else
			//{
			//mask = 0x70
			//}

			if ((current-bits >> 4) == 0)
			{
				write unsigned8 0
			}
			else
			{
				write unsigned8 (mask + (current-bits >> 4))
			}

			if ((current-bits & 0xF) == 0)
			{
				write unsigned8 0
			}
			else
			{
				write unsigned8 (mask + (current-bits & 0xF))
			}

			x = x + 2
		}

		x = 0
	}
}

if (file.name like "*.mid")
{
	interpret-as "music-midi"
}
