display-name: ["Games/Desert Strike", "Games/Jungle Strike"]
meta: {"Working": ["Resource extraction", "Sounds", "Graphics"]}

if (file.name == "jungle.dat" or file.name == "desert.dat")
{
	unsigned32 count
	unsigned8[12] unknown

	file [count]
	{
		fixed-string(8) name
		unsigned32 offset
		unsigned8[4] unknown
		compressed "strike"

		//No way to know anything
		if (name like ["chaingun", "explo?", "helfire", "hellfire", "helibang", "hydra", "mission", "rifle", "winch"])
		{
			interpret-as "sound-VOC"
		}
		else if (name like "map*") //Jungle strike maps
		{
			folder: "Maps"
			interpret-as "jstrike-map"
		}
		else if (name like "destmap*") //Desert strike map
		{
			folder: "Maps"
			interpret-as "desert-map"
		}
		else if (name like "!*")
		{
			folder: "Executable"
		}
		else if (name like ["briefing", "bunkf", "death", "demo*", "destmap", "flicdata", "level*", "logosam", "popup*",
		"prisoner", "reporter", "slap", "startup", "the_end", "things", "tune*", "win2", "zzzzzzzz", "dp_prefs", "map*", "letters",
		"title_c"])
		{
			folder: "Unknown"
		}
		else if ((file.name == "desert.dat") and (name like ["madman", "panel*"]))
		{
			folder: "Unknown"
		}
		else
		{
			folder: "Graphics"
			interpret-as "strike-graphics"
		}
	}	
}

if ((file.name like ["desert.lff", "briefing", "bunkf", "death", "madman", "panel*", "popup*", "prisoner", "reporter", "slap", "startup", "the_end", "win2", "zzzz*"]) and (file.name != "popup4"))
{
	folder: "Animations"
	interpret-as "animation-flic"
}

jstrike-level-tiles-map:
{
	"map1x": {"tiles": "blocks1x", "width": 256},
	"map2x": {"tiles": "blocks2x", "width": 320},
	"map3x": {"tiles": "blocks3x", "width": 320},
	"map4x": {"tiles": "blocks4x", "width": 256},
	"map5x": {"tiles": "blocks5x", "width": 224},
	"map6x": {"tiles": "blocks6x", "width": 256},
	"map7x": {"tiles": "blocks7x", "width": 384},
	"map8x": {"tiles": "blocks8x", "width": 288},
	"map9x": {"tiles": "blocks1x", "width": 192}
}

file-format jstrike-map
{
	level
	{
		grid-x: 16
		grid-y: 16

		xflip-bit: 8
		yflip-bit: 9

		width: jstrike-level-tiles-map[file.name].width
		height: (file.size / 2) / width

		level-layer
		{
			data-type: "unsigned16"
			order: 0
			layer-image: jstrike-level-tiles-map[file.name].tiles
			mask: 0xFF
			layer-name: "Background"
		}
	}
}

file-format desert-map
{
	level
	{
		grid-x: 8
		grid-y: 8

		width: 64
		height: (file.size / 2) / width

		level-layer
		{
			data-type: "unsigned16"
			order: 0
			layer-image: "chars"
			layer-name: "Background"
		}
	}
}

file-format strike-graphics
{
	loop while (file.remaining-bytes > 15)
	{
		fixed-string(8) graphics-header == "GRAPHICS"
		unsigned16 unknown0
		unsigned8 transparency
		unsigned8 unknown1
		unsigned32 palette-offset
		unsigned32 sprite-valid
		data(12) unknown

		palette-start: file.position + palette-offset

		at palette-start
		{

			fixed-string(8) palette-header == "PALETTE "

			//palette here
			unsigned16 colors

			at file.position + (0x20 - 10):

			compressed[colors * 3] "fix-palette"
			{
				palette
				{
					size: colors
					format: "R8G8B8"
				}
			}

			palette-end: file.position
		}

		loop while (file.position < palette-start)
		{
			chunk-start: file.position
			fixed-string(0x8) subtype

			if (subtype == "PICTURE ")
			{
				unsigned32 unknown
				unsigned16 width
				unsigned16 height

				image
				{
					format: "I8"
				}
			}
			else if (subtype == "SPRITES ")
			{
				unsigned16 sprite-count
				unsigned16 unknown
				unsigned32 data-offset-global

				loop (sprite-count): i
				{
					unsigned16 frame-width 
					unsigned16 frame-height 
					unsigned16 padding-left-sprite 
					unsigned16 padding-top-sprite

					unsigned16 sprite-width
					unsigned16 sprite-height
					unsigned32 data-offset
					
					if (data-offset-global != 0)
					{
						image-layout-offset-x: padding-left-sprite
						image-layout-offset-y: padding-top-sprite
						image-layout-width: sprite-width
						image-layout
						{
						at data-offset + 0x20
						{
							xtiles: sprite-width / 16
							ytiles: sprite-height / 16

							width: 16
							height: 16

							loop (xtiles * ytiles): t
							{
								unsigned16 tile-index
								if (tile-index == 0)
								{
									image
									{
										format: "blank"
									}
								}
								else
								{
									tile-index = tile-index - 1

									//flip flags
									flip-flags: tile-index >> 12

									flip-x: (flip-flags & 0x4) != 0
									flip-y: (flip-flags & 0x8) != 0

									tile-index = tile-index & 0xFFF

									at chunk-start + data-offset-global + 0x10 + (tile-index * 4)
									{
										unsigned32 local-offset

										compressed-this: (local-offset & 0x80000000) != 0
										local-offset: local-offset & 0x7FFFFFFF

										at chunk-start + data-offset-global + local-offset:

										if (compressed-this == true)
										{
											transparent-index: 0
											compressed[file.remaining-bytes] "strike-sprite"
											{
												image
												{
													format: "I8"
												}
											}
										}
										else
										{
											transparent-index: 256
											image
											{
												format: "I8"
											}
										}
									}
								}
							}
						}
						}
					}
					else
					{
						tile-count: 1
						padding-left: padding-left-sprite
						padding-top: padding-top-sprite  

						width: sprite-width
						height: sprite-height

						padding-right: frame-width - width - padding-left
						padding-bottom: frame-height - height - padding-right

						if (!(file.name like ["splane5", "copilots", "menu"]))
						{
							if ((width % 8) != 0)
							{
								width = width + (8 - (width % 8))
							}
						}

						at data-offset + 0x20
						{
							if (transparency == 0)
							{
								image
								{
									format: "I8"
								}
							}
							else
							{
								transparent-index: 0
								compressed[file.remaining-bytes] "strike-sprite"
								{
									image
									{
										format: "I8"
									}
								}
							}
						}
					}
				}

				if (data-offset-global != 0)
				{
					//at chunk-start + data-offset:
					at file.size:
				}
				else
				{
					at palette-start:
				}
			}
			else if (subtype == "BLOCKS  ")
			{
				unsigned16 tile-count-strike
				unsigned16 compressed-info
				unsigned16 width
				unsigned16 height

				image-layout-width: width * 10
				image-layout
				{
					if (compressed-info)
					{
						loop (tile-count-strike)
						{
							unsigned24 offset
							unsigned8 compressed
							tile-count: 1

							at chunk-start + offset
							{
								if (compressed == 0x80)
								{
									compressed[file.remaining-bytes] "strike-sprite"
									{
										image
										{
											format: "I8"
										}
									}
								}
								else
								{
									image
									{
										format: "I8"
									}
								}
							}
						}
					}
					else
					{
						tiles-across: 10
						tile-count: tile-count-strike

						image
						{
							format: "I8"
						}
					}
				}
			}
			else
			{
				log("Invalid chunk - " + subtype + " in " + file.name + " at " + file.position)
			}

			if ((file.position % 16) != 0)
			{
				data(16 - (file.position % 16)) padding
			}
		}

		//Skip palette
		at palette-end:

		if ((file.position % 16) != 0)
		{
			data(16 - (file.position % 16)) padding
		}
	}
}
function strike-sprite
{
	bytes-written: 0
	bytes-remaining: width * height
	current-x: 0

	loop while (bytes-remaining > 0)
	{
		read unsigned8 mask
		mask-bytes: 8
		current-x: 0

		loop while ((mask-bytes > 0) and (current-x < width))
		{
			if ((mask & 0x80) != 0)
			{
				read unsigned8 val
				write unsigned8 val
			}
			else
			{
				write unsigned8 0
			}

			bytes-remaining = bytes-remaining - 1 

			current-x = current-x + 1
			mask-bytes = mask-bytes - 1
			mask = mask << 1
		}

		if (current-x == width)
		{
			current-x = 0
		}
	}
}

function fix-palette
{
	loop (file.size)
	{
		read unsigned8 color
		write unsigned8 ((color << 2) | (color >> 4))
	}
}