display-name: "Games/God of Thunder"
meta: {"Working": ["Images", "Levels"], "Thanks to": "Grom PE"}

if (file.name == "gotres.dat")
{
	file
	{
		current-read: file.position
		encrypted [23] "godOfThunderXOR"
		{
			fixed-string(8) name
			unsigned8 zero
			unsigned32 offset
			unsigned32 size
			unsigned32 decompressed-size
			unsigned8 isCompressed
			unsigned8 zero

			if (isCompressed != 0 )
			{
				compressed "godOfThunderLZSS"
			}
		}
	}  while (name != "")
}

if (file.name like ["song*", "*song"])
{
	folder: "Music"

	unsigned16 unknown //always 0x0001

	opl3-rate: 140
	compressed [file.remaining-bytes] "got-opl3"
	{
		sound
		{
			channels: 1
			samples-per-second: 44100
			bits-per-sample: 16
		}
	}
}

function got-opl3
{
	loop(file.remaining-bytes / 4)
	{
		read unsigned8 wait
		read unsigned8 reg
		read unsigned8 val

		write opl3-reg reg val
		write opl3-wait wait
	}
}

if (file.name == "palette")
{
	palette
	{
		size: 256
		format: "R8G8B8"
	}
}


if (file.name == "storypal")
{
	palette
	{
		size: 256
		format: "R6G6B6"
	}
}

//common properties for most images
palette: "palette"

if (file.name like "actor*")
{
	width: 16
	height: 16

	compressed [file.size] "got-crushtransparent"
	{
		image
		{
			format: "I8"
			if (drawing-level-sprite == false)
			{
				data-size: file.size
			}
			tiles-across: 16
			transparent-index: 0
		}
	}
}

//Expand internally, for level drawing
if (file.name like "objects")
{
	interpret-as-internally "expand-got-objects"

	image-layout-width: 16 * 23
	image-layout
	{
		loop while (file.remaining-bytes > 0)
		{
			unsigned16 _width
			width: _width * 4
			unsigned16 height
			unsigned16 unknown

			image
			{
				format: "I8"
				interlaced: 4
			}
		}
	}
}

file-format expand-got-objects
{
	file while (file.remaining-bytes > 0): i
	{
		offset: file.position
		name: "" + i
		interpret-as "got-internal-image"
		unsigned16 _width
		width: _width * 4
		unsigned16 height
		unsigned16 unknown

		data(width * height) image-data
	}
}

file-format got-internal-image
{
	unsigned16 _width
	width: _width * 4
	unsigned16 height
	unsigned16 unknown

	compressed [width * height] "got-crushtransparent"
	{
		image
		{
			format: "I8"
			interlaced: 4
			transparent-index: 0
		}
	}
}

if (file.name like ["bpics*", "face*", "hampic", "odinpic", "openback", "objects", "openp*"])
{
	crush015: true

	if (file.name like "openp*")
	{
		palette = "storypal"
		crush015 = false
	}

	image-layout-width: 16 * 23
	image-layout
	{
		loop while (file.remaining-bytes > 0)
		{
			unsigned16 _width
			width: _width * 4
			unsigned16 height
			unsigned16 unknown

			if (crush015 == true)
			{
				compressed [width * height] "got-crushtransparent"
				{
					image
					{
						format: "I8"
						interlaced: 4
						transparent-index: 0
					}
				}
			}
			else
			{
				image
				{
					format: "I8"
					interlaced: 4
				}
			}
		}
	}
}

function got-crushtransparent
{
	loop (file.size)
	{
		read unsigned8 test
		if (test == 15)
		{
			write unsigned8 0
		}
		else
		{
			write unsigned8 test
		}
	}
}

level-mapping:
{
	//(-containerName-,		levelName,	tileset),
	"sdat1":			{"level-name": "level1-",	"tileset": "bpics1"},
	"sdat2":			{"level-name": "level2-",	"tileset": "bpics2"},
	"sdat3":			{"level-name": "level3-",	"tileset": "bpics3"}
}

if (file.name like "sdat?")
{
	container-name: file.name

	//TODO: derive offset from size :)
	file-number: 0
	file [120]
	{
		name: level-mapping[container-name].level-name + file-number
		offset: file-number * 512
		size: 512
		file-number = file-number + 1
	}
}

if (file.name like "level?-*")
{
	level
	{
		grid-x: 16
		grid-y: 16

		width: 20
		height: 12

		//Default BG
		at 240
		{
			compressed[1] "repeat-default"
			{
				level-layer
				{
					data-type:  "unsigned8"
					order: 0
					layer-image: level-mapping[container-name].tileset
					name: "Background"
				}
			}
		}

		level-layer
		{
			data-type:  "unsigned8"
			order: 0
			layer-image: level-mapping[container-name].tileset
			name: "Background"
		}

		unsigned8 defaultbg
		unsigned8 songid

		unsigned8[16] actorid
		unsigned8[16] actorpos
		data(48) unknown

		loop(16): i
		{
			if (actorid[i] != 0)
			{
				level-object
				{
					offset-x: (actorpos[i] % 20) * 16
					offset-y: (actorpos[i] / 20) * 16
					sprite: "actor" + actorid[i]
				}
			}
		}

		unsigned8[30] objectid
		unsigned16[30] objectx
		unsigned16[30] objecty

		loop(30): i
		{
			if (objectid[i] != 0)
			{
				level-object
				{
					offset-x: objectx[i] * 16
					offset-y: objecty[i] * 16
					sprite: "objects\\" + (objectid[i] - 1)
				}
			}
		}
	}
}

function repeat-default
{
	read unsigned8 default

	loop (width * height)
	{
		write unsigned8 default
	}
}

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

if (file.name like ["speak?", "story?"])
{
	text
}

function godOfThunderXOR 
{
	currentLoc: current-read
	
	loop while (file.remaining-bytes > 0)
	{
		read unsigned8 datas
		datas = datas ^ ( currentLoc % 256 )
		datas = datas ^ 128
		write unsigned8 datas
		currentLoc = currentLoc + 1
	}
}

function godOfThunderLZSS
{
	read unsigned16 decompressed-size
	read unsigned16 unknown

	bytes-written: 0

	file.bit-reading-cache-ahead = false

	loop while (bytes-written < decompressed-size)
	{
		bits(1) lzval

		if (lzval == 0)
		{
			read unsigned16 control
			length-copy: (control >> 12) + 2
			offset-from: -(control & 0xFFF)
			copy(offset: offset-from, length: length-copy)

			bytes-written = bytes-written + length-copy
		}
		else
		{
			read unsigned8 src
			write unsigned8 src
			bytes-written = bytes-written + 1
		}

	}
}