display-name: "Games/Rescue Rover"
meta: {"Working": ["Graphics", "Sound"]}

if (file.name like "*pic.rov")
{
	compressed "SWRLE"
	
	unsigned32 pic-size
	fixed-string(4) magic

	unsigned16 _width
	unsigned16 height

	image
	{
		format: "I4"
		width: _width * 8
		bit-stride: width * height
	}
}

palette: [0, 0, 0,  0, 0, 0xAA,  0, 0xAA, 0,  0x0, 0xAA, 0xAA,
	  0xFF, 0x55, 0x55,  0x55, 0xFF, 0xFF,  0x55, 0xFF, 0x55,  0xAA, 0x55, 0,
	  0xAA, 0x00, 0,  0x0, 0xAA, 0xAA, 0x0, 0xAA, 0xAA, 0x55, 0x55, 0xFF, 
	   0xFF, 0x55, 0x55,  0xFF, 0xFF,  0x55, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ]

if (file.name == "egatiles.rov")
{
	image
	{
		data-size: file.size
		format: "I4"
		width: 16
		height: 16
		bit-stride: width * height
		tiles-across: 5
	}
}

if (file.name == "egabtile.rov")
{
	image
	{
		data-size: file.size
		format: "I4"
		width: 32
		height: 32
		bit-stride: width * height
		tiles-across: 5
	}
}

if (file.name == "sounds.rov")
{
	interpret-as "archive-SND_DOS"
}

level-sprites: {
	0x01: "s_play.rov\\rovstand1",
	0x02: "s_play.rov\\guardn1",
	0x03: "s_play.rov\\guarde1",
	0x04: "s_play.rov\\guards1",
	0x05: "s_play.rov\\guardw1",
	0x06: "s_play.rov\\troopn1",
	0x07: "s_play.rov\\patrolw1",
	0x08: "s_play.rov\\homingw",
	0x09: "s_play.rov\\turretn",
	0x0A: "s_play.rov\\turrete",
	0x0B: "s_play.rov\\turrets",
	0x0C: "s_play.rov\\turretw",
	0xD: "s_play.rov\\mirror13",
	0xE: "s_play.rov\\mirror14",
	0xF: "s_play.rov\\mirror15",
	0x10: "s_play.rov\\mirror16",
	0x11: "s_play.rov\\crate",
	0x12: "s_play.rov\\pearl",
	0x13: "s_play.rov\\antigrav",
	0xFF: "s_play.rov\\rogstandn",
	0x1602: "",
	0x020D: "",
	"*": "debug"
}

if (file.name like "level*.rov")
{
	unsigned32 decompressed-size
	magic-number: 0xFEFE

	compressed [file.remaining-bytes] "KeenRLE"
	{
		unsigned16 width
		unsigned16 height
		unsigned16 level-plane-count //always 2
		unsigned32 zero //always 0
		unsigned32 ted-variables
		unsigned16 level-plane-size
		data(16) unknown

		level
		{
			grid-x: 32
			grid-y: 32

			if (file.name like ["level01.rov", "level11.rov", "level18.rov"])
			{
				compressed [level-plane-size] "FixRover"
				{
					level-layer
					{
						data-type: "unsigned16"
						layer-image: "egabtile.rov"
						order: 0
					}
				}
			}
			else
			{
				level-layer
				{
					data-type: "unsigned16"
					layer-image: "egabtile.rov"
					order: 0
				}
			}
			
			at level-plane-size + 32:

			if (file.name like ["level01.rov", "level11.rov", "level18.rov"])
			{
				compressed [level-plane-size] "FixRover"
				{
					level-layer
					{
						layer-name: "Objects"
						ignore-tile: 0
						data-type: "unsigned16"
						layer-images: level-sprites
						order: 1
					}
				}
			}
			else
			{
				level-layer
				{
					layer-name: "Objects"
					ignore-tile: 0
					data-type: "unsigned16"
					layer-images: level-sprites
					order: 1
				}
			}
		}
	}
}

function FixRover
{
	loop (10)
	{
		write unsigned16 0
	}

	at 10 * 2:
	unsigned8[file.remaining-bytes] dat
	write unsigned8 dat
}

if (file.name like "*.txt")
{
	text
}

if (file.name == "egaplane.rov")
{
	latch-file-size: file.size
	from "egahead.rov"
	{
		unsigned32 LatchPlaneSize	// Size of one plane of latch data
	  	unsigned32 SpritePlaneSize	// Size of one plane of sprite data
		unsigned32 OffBitmapTable	// Offset in EGAHEAD to bitmap table
		unsigned32 OffSpriteTable	// Offset in EGAHEAD to sprite table
		unsigned16 Num8Tiles		// Number of 8x8 tiles
		unsigned32 Off8Tiles		// Offset of 8x8 tiles (relative to plane data)
		unsigned16 Num32Tiles		// Number of 32x32 tiles (always 0)
		unsigned32 Off32Tiles		// Offset of 32x32 tiles (relative to plane data)
		if (OffBitmapTable == 0x40)
		{
			unsigned16 NumUnknown
			unsigned32 OffUnknown
		}
		unsigned16 Num16Tiles		// Number of 16x16 tiles
		unsigned32 Off16Tiles		// Offset of 16x16 tiles (relative to plane data)
		unsigned16 NumBitmaps		// Number of bitmaps in table
		unsigned32 OffBitmaps		// Offset of bitmaps (relative to plane data)
		unsigned16 NumSprites		// Number of sprites
		unsigned32 OffSprites		// Offset of sprites (relative to plane data)
		unsigned16 IsCompressed	    // (Keen 1 only) Nonzero: LZ compressed data

		at OffBitmapTable:

		file[NumBitmaps]
		{
			unsigned16 width-in-bytes
			width: width-in-bytes * 8
			unsigned16 height
			unsigned32 local-bitmap-offset
			bitmap-offset: local-bitmap-offset + OffBitmaps
			fixed-string(8) name
				
			interpret-as "keen13-bitmap"

			size: latch-file-size
			offset: 0
		}
	}

	file[1] {
		name: "8x8 tiles"
		offset: 0
		size: latch-file-size
		interpret-as "rov-8x8"
	}
}

if (file.name like ["s_*.rov"])
{
	compressed "SWRLE"

	unsigned32 decompressed-size
	sprite-name: file.name
	
	from "egahead.rov"
	{
		unsigned32 LatchPlaneSize	// Size of one plane of latch data
	  	unsigned32 SpritePlaneSize	// Size of one plane of sprite data
		unsigned32 OffBitmapTable	// Offset in EGAHEAD to bitmap table
		unsigned32 OffSpriteTable	// Offset in EGAHEAD to sprite table
		unsigned16 Num8Tiles		// Number of 8x8 tiles
		unsigned32 Off8Tiles		// Offset of 8x8 tiles (relative to plane data)
		unsigned16 Num32Tiles		// Number of 32x32 tiles (always 0)
		unsigned32 Off32Tiles		// Offset of 32x32 tiles (relative to plane data)
		if (OffBitmapTable == 0x40)
		{
			unsigned16 NumUnknown
			unsigned32 OffUnknown
		}
		unsigned16 Num16Tiles		// Number of 16x16 tiles
		unsigned32 Off16Tiles		// Offset of 16x16 tiles (relative to plane data)
		unsigned16 NumBitmaps		// Number of bitmaps in table
		unsigned32 OffBitmaps		// Offset of bitmaps (relative to plane data)
		unsigned16 NumSprites		// Number of sprites
		unsigned32 OffSprites		// Offset of sprites (relative to plane data)
		unsigned16 IsCompressed	    // (Keen 1 only) Nonzero: LZ compressed data

		at OffSpriteTable:

		if (sprite-name == "s_demo.rov")
		{
			NumSprites = NumSprites - 99
			at OffSpriteTable + (98 * 32 * 4):
		}
		else
		{
			NumSprites = 97
		}

		file[NumSprites]: i
		{
			unsigned16 width-in-bytes
			width: width-in-bytes * 8
			unsigned16 height
			unsigned16 offsetDelta
			unsigned16 offsetParas
			unsigned16 rx1
			unsigned16 ry1
			unsigned16 rx2
			unsigned16 ry2
			fixed-string(16) name

			name = name

			interpret-as "rov-sprite"

			sprite-offset: offsetParas * 16 + offsetDelta

			//as the various planes can be found all through the sprite file
			//we need to get the whole file
			size: decompressed-size - 6
			offset: 6

			data(32 * 3) unknown 	//dummy sprite headers

			SpritePlaneSize: decompressed-size / 5
		}
	}
}

file-format rov-8x8
{
	image
	{
		width: 8
		height: 8
		bit-stride: LatchPlaneSize * 8
		format: "I4"
		data-size: file.size
		tile-count: Num8Tiles
		per-image-offset: 8
	}
}

file-format rov-sprite
{
	folder: "Sprites"

	at sprite-offset:

	image
	{
		format: "I4A1"
		data-size: file.size - sprite-offset	
		alpha-mask: 1
		bit-stride: SpritePlaneSize * 8
	}
}


function ROVRLE
{	
	unsigned32 decompressed-size
	loop while (file.remaining-bytes > 0)
	{		
		read unsigned8 token

		if (token == 0xFE)
		{
			read unsigned8 count
			read unsigned8 value

			loop (count)
			{
				write unsigned8 value
			}			
		}
		else
		{
			write unsigned8 token			
		}
	}
}