display-name: "Games/Prehistorik"
meta: {"Working": ["Packed file extraction", "Fonts", "Soundblaster sounds"], "Thanks to": "Malvineous, Jesses"}


if (file.name like ["*.vga", "*.cur"])
{
	struct file-header
	{
		unsigned16 data-start

		file
		{
			unsigned32 size
			
			skip-if (size == 0)
			string name

			if ((name like ["*.MAT", "*.MDI", "*.PC1"]) and (name != "CHARSET1.MAT"))
			{
				compressed "LZSS-Prehistorik"
			}
		} while (size > 0)
	}
}

if (file.name like "*.sqz")
{
	unsigned8 topBits
	unsigned8 compression-format
	unsigned16 decompressed-size
	decompressed-size = decompressed-size | (topBits << 16)

	unsigned16 huff-size

	unsigned16[huff-size / 2] huff-table

	file[1] {
		offset: file.position
		size: file.remaining-bytes
		name: "decompressed exe"
		compressed "SQZ-Huff"
		interpret-as "exe-DOS"
	}
}

function SQZ-Huff
{
	node: 0
	written: 0
	last: 0
	state: 0
	count: 0

	file.bit-reading-shift-out-right = false

	loop while (written < decompressed-size)
	{
		read bits(1) read-bit
		if (read-bit != 0)
		{
			node = node + 1
		}
		if (huff-table[node] < 0x8000) {
			// internal node
			node = huff-table[node] / 2
		} else {
			// leaf node
			cw: huff-table[node] & 0x7FFF
			
			l: cw & 0xFF
			h: cw >> 8

			if (state == 0)
			{
				if (h == 0)
				{
					last = l
					write unsigned8 last
					written = written + 1
				}
				else if (l == 0)
				{
					state = 1
				}
				else if (l == 1)
				{
					state = 2
				}
				else
				{
					loop (l)
					{
						write unsigned8 last
					}
					written = written + l
				}
			}
			else if (state == 1)
			{
				loop (cw)
				{
					write unsigned8 last
				}
				written = written + cw
				state = 0
			}
			else if (state == 2)
			{
				count = l * 256
				state = 3
			}
			else if (state == 3)
			{
				count = count + l
				loop (count)
				{
					write unsigned8 last
				}
				written = written + count
				state = 0
			}

			node = 0
		}
	}
}

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

if (file.name like "*.pc1")
{
	interpret-as "image-ILBM"
}

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

if ((file.name like "*.mat"))
{
	unsigned16be count

	if (file.name == "charset1.mat")
	{
		palette: [0, 0, 0, 0xFF, 0xFF, 0xFF]
	}
	else if (file.name like ["cool2.mat"])
	{
		palette: "filesa.vga\\cool3.pc1"
	}
	else if (file.name like ["h1.mat", "h2.mat", "h3.mat", "*2*.mat", "*4*.mat", "*6*.mat"])
	{
		palette: "filesb.vga\\ring.pc1"
	} 
	else if (file.name like ["*1*.mat"])
	{
		palette: "filesa.vga\\fond1.pc1"
	}
	else if (file.name like "*3*.mat")
	{
		palette: [0, 0, 0,    224, 160, 128,  160, 96, 64,  128, 64, 32,
				  96, 64, 32, 160, 0, 32,     224, 192, 32, 128, 96, 64,
				  0, 96, 64,  32, 128, 96,    0, 0, 0, 64, 64, 64,
				  96, 96, 96, 160, 128, 96,   192, 160, 128, 224, 224, 224]
	}
	else if (file.name like "*5*.mat")
	{
		palette: "filesb.vga\\fond5.pc1"
	}
	else if (file.name like "*7*.mat")
	{
		palette: "filesa.vga\\fond7.pc1"
	}
	
	loop (count)
	{
		unsigned16be width
	
		if ((width % 8) != 0)
		{
			output-width: width
			width = width + 8 - (width % 8)
		}

		unsigned16be height
		unsigned16be len

		format: "I4A1"

		if (file.name == "charset1.mat") {
			format = "I1"
		}
		
		if (len == 0)
		{
			image
			{
				bit-stride: width * height
			}
		}
		else
		{
			compressed[len] "ilbm-rle"
			{
				image
				{
					bit-stride: width * height
				}
			}
		}
	}
}

function LZSS-Prehistorik
{	
	file.bit-reading-shift-out-right = false

	unsigned32be decompressed-size
	bytes-left: decompressed-size

	loop while (decompressed-size > 0)
	{
		bits(1) flag

        	if (flag == 0)
        	{
            		bits(8) escape
            		write unsigned8 escape
            		decompressed-size = decompressed-size - 1
        	}
        	else
        	{
            		bits(2) length
            		length = length + 2
            		bits(8) offset

            		copy(from: -(offset + 1), length: length)

            		decompressed-size = decompressed-size - length
        	}
	}
}