display-name: ["Games/Monster Bash", "Games/ScubaVenture"]
meta: {"Working": ["All images", "Levels", "Sounds"], "Thanks to": ["Gerald Lindsly", "Malvineous"]}

//Common image settings
palette: "main_r.pal"
plane-order: 3210

if (file.name like "*.dat")
{
	file while (file.remaining-bytes > 0)
	{
		unsigned16 type
		unsigned16 compressed-size
		fixed-string(31) name
		unsigned16 decompressed-size
		
		size: compressed-size
		offset: file.position

		data(compressed-size) file-data
		
		if (type == 0)
		{
			interpret-as "bash-level"
		}
		else if (type == 1)
		{
			folder: "Level data"
			name = name + ".lvbkg"
		}
		else if (type == 2)
		{
			folder: "Level data"
			name = name + ".lvfg"
		} 
		else if (type == 3)
		{
			folder: "Background tiles"
			name = name + ".bg"
			interpret-as "bash-background"
		}
		else if (type == 4)
		{
			folder: "Foreground tiles"
			interpret-as "bash-transparent-tiles"
			name = name + ".fg"
		}
		else if (type == 5)
		{
			folder: "Bonus tiles"
			interpret-as "bash-transparent-tiles"
			name = name + ".bonus"
		}
		else if (type == 6)
		{
			folder: "Level data"
			name = name + ".lvspr"
		}
		else if (type == 7)
		{
			folder: "Level data"
			name = name + ".lvact"
		}
		else if (type == 12)
		{
			folder: "Level data"
			name = name + ".back-prop"
		}
		else if (type == 13)
		{
			folder: "Level data"
			name = name + ".fore-prop"
		}
		else if (type == 14)
		{
			interpret-as "bash-palette"
			name = name + ".pal"
		}
		else if (type == 16)
		{
			folder: "Level data"
			name = name + ".bonus-prop"
		}
		else if (type == 64)
		{
			folder: "Sprites"
			interpret-as "bash-sprites"
		}
		else if ((type == 32) and (name like "*.imf"))
		{
			folder: "Music"
			interpret-as "music-imf-560"
		}

		if (decompressed-size != 0)
		{
			lz-start: 257
			lz-precode: 0
			lz-ignore-out-length: true
			compressed "LZW"
			compressed "BashRLE"
		}
	}
}

file-format bash-background
{
	image
	{
		format:  "I4"
		width: 16
		height: 16
		tiles-across: 20
		bit-stride: width * height
		data-size: file.size
	}
}

file-format bash-transparent-tiles
{
	image
	{
		format: "A1I4"
		width: 16
		height: 16
		tiles-across: 20
		data-size: file.size
		bit-stride: width * height		
		alpha-mask: 1
	}
}

file-format bash-palette
{
	palette
	{
		size: 16
		format: "EGA"
	}
}

file-format bash-sprites
{
	unsigned8 alwaysFF

	index: 0

	image-layout-width: 320
	image-layout
	{
		loop while (file.remaining-bytes > 12)
		{		
			unsigned16 spriteSize
			unsigned8 unknown
			unsigned8 height
			unsigned8 width
			unsigned8 unknown
			signed16 offset-x
			//padding-left: 0 - offset-x
			signed16 offset-y
			//padding-top: 0 - offset-y
			unsigned16 boundRectX
			unsigned16 boundRectY

			if (drawing-level-sprite == true)
			{
				//Mess around with position for level drawing :D
				padding-left: 128 + offset-x
				padding-top: 128 + offset-y
			}		

			//Work out size
			widthInBytes: width
			if ((widthInBytes % 8) != 0)
			{
				widthInBytes = widthInBytes + 8
			}

			widthInBytes = widthInBytes / 8
			planeSize: widthInBytes * height		
		
			width = widthInBytes * 8 //what, just stomp it...?

			//log "" + index + ": " + bytesRemaining + ", " + (spriteSize - 12)
			index = index + 1

			dataToRead: spriteSize - 12

			if (file.remaining-bytes < (spriteSize - 12))
			{
				dataToRead = file.remaining-bytes
			}
		
			compressed[dataToRead] "BashSprite"
			{
				image
				{
					format: "A1I4"
					alpha-mask: 1
					bit-stride: width * height
				}
			}

			if (drawing-level-sprite == true)
			{
				at file.size - 1:
				unsigned8 level-dummy
			}	
		}
	}
}

file-format bash-level
{
	fixed-string(31) backgroundFile
	fixed-string(31) foregroundFile
	fixed-string(31) bonusTiles
	fixed-string(31) levelFile
	fixed-string(31) paletteFile
	fixed-string(31) soundFile
	//and then 'UNNAMED'...

	level
	{
		grid-x: 16
		grid-y: 16

		from name + ".lvbkg"
		{
			unsigned8 width
			unsigned8 height

			data(6) unknown
			level-layer
			{
				data-type: "unsigned16"
				order: 0
				layer-image: backgroundFile + ".bg"
				mask: 0x01FF
				layer-name: "Background"
			}
		}		

		if (bonusTiles != "UNNAMED")
		{
			from name + ".lvfg"
			{
				data(2) unknown
				compressed[file.remaining-bytes] "GetBonusTiles"
				{
					level-layer
					{
						data-type: "unsigned8"
						order: 1
						layer-image: bonusTiles + ".bonus"						
						ignore-tile: 0
						layer-name: "Foreground"
					}
				}
			}
		}

		if (foregroundFile != "UNNAMED")
		{
			from name + ".lvfg"
			{
				data(2) unknown
				compressed[file.remaining-bytes] "GetFgTiles"
				{
					level-layer
					{
						data-type: "unsigned8"
						order: 1
						layer-image: foregroundFile + ".fg"						
						ignore-tile: 0
						layer-name: "Foreground"
					}
				}
			}
		}

		if (exists(name + ".lvact"))
		{
			from name + ".lvact"
			{
				unsigned16 unknown
				loop while (file.remaining-bytes > 2)
				{
					level-object
					{
						unsigned32 len
						unsigned32 unknown
						unsigned32 unknown
						unsigned16 unknown
						unsigned32 _offset-x
						offset-x: _offset-x - 128
						unsigned32 _offset-y
						offset-y: _offset-y - 128
						data(22) unknown

						string-length: len - 44
						fixed-string(string-length) _sprite

						if (exists("sprites\\" + _sprite)) {
							sprite: "sprites\\" + _sprite
						}
					}
				}
			}	
		}	
	}
}

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

// In archive snd dos lib
if (file.name like "*.snd")
{
	interpret-as "archive-SND_DOS"
}

if (file.name like "mb?_d?.bin")
{
	folder: "Demos"
}

if (file.name like "*.bin")
{
	b800-text
}

if (file.name like ["*.txt", "*.diz", "order.frm"])
{
	text
}

if (file.name like "score.mb?")
{
	folder: "Hi scores"

	loop (8)
	{
		property-list
		{	
			fixed-string(25) scoreName
			unsigned32 score
		}
	}
}

function BashRLE
{
	current-previous: 0

	loop while (file.remaining-bytes > 0)
	{
		read unsigned8 token
		if (token == 0x90)
		{
			read unsigned8 count
			
			if (count == 0)
			{
				current-previous = token
				write unsigned8 token
			}
			else
			{
				loop (count - 1)
				{
					write unsigned8 current-previous
				}
			}
		}
		else
		{
			current-previous = token
			write unsigned8 token
		}
	}
}

function BashSprite
{	
	decompressedData: [](planeSize * 5)
	
	firstPlane: true
	
	loop
	{
		read unsigned8 planeBits
		if (planeBits != 0)
		{
			read unsigned8[planeSize] spriteField
			
			if (firstPlane == true)
			{
				loop (planeSize): i
				{
					decompressedData[i] = spriteField[i]
				}
				firstPlane = false
			}
			else
			{			
				loop (5): i
				{				
					if ((planeBits & (1 << i)) != 0)
					{
						loop (planeSize): j
						{
							index: ((3 - i + 1)* planeSize) + j
							decompressedData[index] = decompressedData[index] ^ spriteField[j]					
						}
					}			
				}
			}
		}
	} while (planeBits != 0)
	
	loop (planeSize * 5): i
	{
		write unsigned8 decompressedData[i]
	}
}

function GetBonusTiles
{
	loop while (file.remaining-bytes > 0)
	{
		read unsigned8 tile
		if ((tile & 128) == 0)
		{
			write unsigned8 tile
		}
		else
		{
			write unsigned8 0
		}
	}
}

function GetFgTiles
{
	loop while (file.remaining-bytes > 0)
	{
		read unsigned8 tile
		if ((tile & 128) != 0)
		{
			write unsigned8 (tile & 127)			
		}
		else
		{
			write unsigned8 0
		}
	}
}

if (file.name like "save?.mb?")
{
	folder: "Save games"
	property-list
	{
		unsigned16 lives
		unsigned16 level
		unsigned16 difficulty
		unsigned32 score
		unsigned32 checksum
	}
}