display-name: "Games/Stargunner"
meta: {"Working": ["File extraction", "Sounds"], "Partially working": "Tiles (some incorrect colors)", "Thanks to": "Malvineous, The_Coder"}

if (file.name == "stargun.dlt")
{
	fixed-string(4) signature
	unsigned16 version
	unsigned16 file-count

	file[file-count]
	{
		encrypted[32] "stargunner-name-xor"
		{
			fixed-string(32) name
		}
		unsigned32 unknown
		unsigned32 size
		offset: file.position

		fixed-string(4) compressed-check
		
		if (compressed-check == "PGBP")
		{
			unsigned32 decompressed-size
			compressed "stargunner-bpe"

			offset = offset + 8

			at file.position - 8:
		}
		else
		{
			at file.position - 4:
		}

		data(size) file-data
	}
}

function stargunner-bpe
{
	bytes-written: 0

	tableA: [](256)
	tableB: [](256)
	expbuf: [](32)

	loop while (bytes-written < decompressed-size)
	{
		//log("Written " + bytes-written + "/" + decompressed-size)

		chunk-written: 0
		read unsigned16 chunk-size
		//log("Chunk size: " + chunk-size)

		bytes-to-write-this-chunk: 4096
		if ((decompressed-size - bytes-written) < 4096)
		{
			bytes-to-write-this-chunk = decompressed-size - bytes-written
		}

		loop while (chunk-written < bytes-to-write-this-chunk)
		{
			loop(256): i
			{
				tableA[i] = i
			}

			//Read dictionary
			table-pos: 0
			code: 0

			loop while (table-pos < 256)
			{
				read unsigned8 code-read
				code = code-read

				if (code > 127) {
					table-pos = table-pos + (code - 127)
					code = 0
				}
				
				if (table-pos != 256)
				{
					loop (code + 1)
					{
						unsigned8 code-data
						tableA[table-pos] = code-data

						if (table-pos != code-data)
						{
							// If this codeword didn't expand to itself, store the second byte
							// of the expansion pair.
							unsigned8 second-byte
							tableB[table-pos] = second-byte
						}

						table-pos = table-pos + 1
					}
				}
			}

			//Decompress this chunk
			unsigned16 this-chunk-len
			//log("A here " + tableA.length)

			
			expbufpos: 0

			running: true

			//log("A here 2 " + tableA.length)

			loop while (running)
			{
				if (expbufpos != 0)
				{
					// There is data in the expansion buffer, use that
					expbufpos = expbufpos - 1
					code = expbuf[expbufpos]
				} 
				else 
				{
					// There is no data in the expansion buffer, use the input data
					this-chunk-len = this-chunk-len - 1
					if (this-chunk-len == -1)
					{
						 running = false // no more input data
					}

					if (running)
					{
						unsigned8 read-next-code
						code = read-next-code
					}
				}

				if (running)
				{
					if (code == tableA[code]) 
					{
						// This byte is itself, write this to the output
						write unsigned8 code
						bytes-written = bytes-written + 1
						chunk-written = chunk-written + 1
					}
					else 
					{
						// This byte is actually a codeword, expand it into the expansion buffer
						expbuf[expbufpos] = tableB[code]
						expbufpos = expbufpos + 1

						expbuf[expbufpos] = tableA[code]
						expbufpos = expbufpos + 1
					}
				}
			}
		}
	}
}

function stargunner-name-xor
{
	read unsigned8 byte
	write unsigned8 byte

	last-char: byte
	loop(31): i
	{
		read unsigned8 byte
		byte = byte ^ (last-char + i + 1)
		last-char = byte
		write unsigned8 byte
		//for (int i = 1; i < 32; i++) name[i] ^= name[i - 1] + i;
	}
}

if (file.name like "*.pcx")
{
	interpret-as "image-PCX"
}

if (file.name like ["*.ctl", "*.dfs"])
{
	text
}

if (file.name like "*.pal")
{
	palette
	{
		format: "R6G6B6"
		size: 256
	}
}

if (file.name like "*.flc")
{
	interpret-as "animation-flic"
}

tile-palettes: {
	"starg1.tlr": "newdata\\starg1.pal",
	"starg2.tlr": "newdata\\starg2.pal",
	"starg3.tlr": "newdata\\starg3.pal",
	["starg4*.tlr"]: "newdata\\starg4.pal", //nope
	"starg51.tlr": "newdata\\starg51.pal",
	"starg52.tlr": "newdata\\starg52.pal",
	"starg53.tlr": "newdata\\starg53.pal",
	"stars.tlr": "newdata\\stars.pal"
}

if (file.name like "*.tlr")
{
	image
	{
		format: "I8"
		width: 16
		height: 16
		tiles-across: 16
		data-size: file.size
		palette: tile-palettes[file.name]
	}
}

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