display-name: "Games/Commander Keen 4-6"
meta: {"Working": ["All images", "Levels", "Audio"]}

keen4-sprites: [{
			1: {"name": "7", "y": -16}, //keen right
			2: {"name": "15", "y": -16}, //keen left
			3: "136", //world-map keen
			4: {"name": "233", "y": -16}, //council member
			5: {"name": "380", "y": -32}, //Berkeloid
			6: "209", //princess
			7: {"name": "340", "y": -8}, //Wormouth
			8: "324", //Skypest
			9: "376", //Thundercloud
			10: {"name": "214", "y": -48}, //foot
			11: "213", //inchworm
			12: {"name": "372", "y" : -8}, //Bounder
			13: {"name": "239", "y": -8}, //Blue bird egg
			14: {"name": "351", "y" : 0}, //Lick
			15: {"name": "282", "y": -48}, //Dopefish
			16: "298", //schoolfish
			17: {"name": "308", "y" : -8}, //Sprite
			18: {"name": "215", "y" : -16}, //Treasure eater
			19: {"name": "271", "y": -8}, //Mimrock
			20: {"name": "302", "y": -24}, //Arachnut
			21: "241", //Mad mushroom
			22: {"name": "192", "y": -8}, //slug
			23: "", //normal/hard only sprite
			24: "", //hard only sprite
			25: "", //v-scroll blocker
			26: "", //h-scroll blocker
			27: "361", //h-mover
			28: "361", //h-mover
			29: "361", //h-mover
			30: "361", //h-mover
			31: "", //h-mover point
			32: "361", //h-mover			
			34: "128", //ammo when low on ammo
			33: "", //Miragia marker?
			35: {"name": "307", "y": -16}, //wetsuit
			42: "188", //scuba keen
			43: "", //Medium/Hard only Slug
			44: "", //Hard only Slug
			45: "", //Medium/Hard only Skypest
			46: "", //Hard only Skypest
			47: "", //Medium/Hard only Lick
			48: "", //Hard only Lick
			49: "", //Medium/hard only Berkeloid
			50: "", //Hard only Berkeloid
			51: "", //Normal/hard wormouth
			52: "", //laser
			53: "", //laser
			54: "", //laser
			55: "", //laser
			56: "", //laser
			57: "119", //red diamond
			58: "121", //yellow diamond
			59: "123", //blue diamond
			60: "125", //green diamond
			61: "105", //red bottle
			62: "106", //diagonal choc
			63: "108", //upright choc
			64: "110", //red orb
			65: "112", //donut
			66: "114", //ice cream
			67: "116", //1-up bottle
			68: "129", //
			69: "317", //mine-v...different from 71?
			70: "317", //mine-h...different from 72?
			71: "317", //mine-v
			72: "317", //mine-h
			74: "", //Hard-only arachnut
			75: "", //??? top-left of pyramid of Moons
			77: "", //normal/hard mode only Blue Bird
			78: "", //hard mode only Blue Bird
			79: "", //laser
			80: "", //laser
			81: "", //laser
			82: "", //laser
			84: "", //laser
			85: "", //laser
			86: "", //laser
			87: "", //normal/hard Dopefish
			88: "", //hard Dopefish
			272: "" //special exit
		}, {
			23: {"name": "308", "y" : -8}, //Normal/Hard only sprite
			43: {"name": "192", "y": -8}, //Medium/Hard only Slug
			45: "324", //Medium/Hard only Skypest
			47: {"name": "347", "y" : 0}, //Medium/Hard only Lick
			49: {"name": "380", "y": -32}, //Medium/Hard only Berkeloid
			51: {"name": "340", "y": -8}, //Medium hard only Wormouth
			77: {"name": "252", "y": -8}, //normal/hard mode only Blue Bird
			87: {"name": "282", "y": -48} //normal/hard Dopefish
		}, {
			24: {"name": "308", "y" : -8}, //Hard only sprite
			44: {"name": "192", "y": -8}, //Hard only Slug
			46: "324", //Hard only Skypest
			48: {"name": "347", "y" : 0}, //Hard only Lick
			50: {"name": "380", "y": -32}, //Medium/Hard only Berkeloid
			74: {"name": "302", "y": -24}, //Hard only arachnut
			78: {"name": "252", "y": -8}, //hard mode only Blue Bird
			88: {"name": "282", "y": -48} //hard Dopefish
		}]

keen4-promo-sprites: [{
		1: {"name": "7", "y": -16}, //keen right
		2: {"name": "15", "y": -16}, //keen left
		3: "136", //world-map keen
		4: {"name": "235", "y": -16}, //council member
		6: "203", //princess
		8: "318", //Skypest
		9: "374", //Thundercloud
		11: "208", //Inch worm
		12: {"name": "370", "y": -8}, //Bounder
		19: {"name": "264", "y": -8}, //Mimrock
		21: {"name": "200", "y": -16}, //Mad mushroom
		22: {"name": "190", "y": -8}, //slug
		25: "", //scroll blocker-h
		26: "", //scroll blocker-v
		27: "359", //h-mover
		28: "359", //h-mover
		29: "359", //h-mover
		30: "359", //h-mover
		31: "", //h-mover point
		32: "359", //h-mover	
		33: "", //Miragia
		34: "125", //ammo
		43: "", //Medium/Hard only Slug
		44: "", //Hard only Slug
		45: "", //Normal/hard only Skypest
		46: "", //Hard only Skypest
		47: "", //Medium/Hard only Lick
		48: "", //Hard only Lick
		51: "", //Normal/hard wormouth
		52: "", //Hard only wormouth
		55: "", //laser
		57: "116", //red diamond
		58: "118", //yellow diamond
		59: "120", //blue diamond
		60: "122", //green diamond
		61: "96", //Shikadi soda
		62: "98", //Three-Tooth Gum
		63: "102", //Shikkers Candy Bar
		64: "104", //Jawbreaker
		65: "108", //donut
		66: "110", //ice cream
		68: "125", //ammo
		67: "114", //1-up bottle
		79: "", //laser
		80: "", //laser
		81: "", //laser
		85: "", //laser
		273: "" //special exit
	}, {
		43: {"name": "190", "y": -8}, //Medium/Hard only Slug
		45: "318", //Normal/Hard only Skypest
		47: {"name": "349", "y" : 0} //Medium/Hard only Lick
	}, {
		44: {"name": "190", "y": -8}, //Hard only Slug
		46: "318", //Hard only Skypest
		48: {"name": "349", "y" : 0}, //Hard only Lick
		52: {"name": "341", "y": -8} //Hard wormouth
	}]

keen5-sprites:  [{
			1: {"name": "7", "y": -16}, //keen right
			2: {"name": "15", "y": -16}, //keen left
			3: "143", //world-map keen
			4: {"name": "270", "y": -16}, //Sparky
			5: "", //Normal/Hard only Sparky
			6: "", //Hard only Sparky
			7: "277", //Shikadi mine
			8: "", //Normal/Hard only Shikadi mine
			9: "", //Hard only Shikadi mine
			10: {"name": "284", "y": 0}, //Slicestar v
			11: "", //Normal/hard only Slicestar v
			12: "", //Hard only Slicestar v
			13: {"name": "286", "y": -64}, //Robo Red
			14: "", //Normal/hard only Robo Red
			15: "", //Hard only Robo Red
			16: {"name": "292", "y": -16}, //Spirogrip
			17: "", //Normal/Hard only Spirogrip
			18: "", //Hard only Spirogrip
			19: {"name": "284", "y": 0}, //Slicestar diag
			20: "", //Normal/hard only Slicestar diag
			21: "", //Hard only Slicestar diag
			22: {"name": "284", "y": 0}, //Slicestar h
			23: "", //Normal/hard only Slicestar h
			24: "", //Hard only Slicestar h
			25: "", //scroll blocker
			26: "", //world map...thing?  Bottom right of world map
			27: "345",
			28: "345",
			29: "345",
			30: "345",
			31: "", //mover ends
			32: "345",
			33: "345",
			34: "345",
			35: "345",
			36: "345",
			37: "345",
			38: "345",
			39: "345",
			40: "345",
			41: "", //unknown, appears in top left of map sometimes
			42: {"name": "305", "y": -8}, //Little Ampton
			43: "", //Normal/Hard only Little Ampton
			44: "", //Hard only Little Ampton
			45: "", //laser
			46: "", //laser
			47: "", //laser
			48: "", //laser
			49: "", //laser
			50: "", //laser
			51: "", //laser
			52: "", //laser
			53: "", //laser
			54: "", //laser
			55: "", //laser
			56: "", //laser cannon
			57: "124", //red diamond
			58: "126", //yellow diamond
			59: "128", //blue diamond
			60: "130", //green diamond
			61: "110", //shikadi gum
			62: "112", //Marshmallow
			63: "114", //Choc milk
			64: "116", //Tart stix
			65: "118", //Sugar Stoopies Cereal
			66: "120", //Bag of sugar
			67: "122", //Keg o Vitalin
			68: "133", //ammo
			69: "133", //ammo, if low
			70: "106", //Keycard
			71: "316", //Volte-face
			72: "", //Normal/Hard only Volte-face
			73: "", //Hard only Volte-face
			74: "327", //Shelley
			75: "", //Normal/hard only Shelley
			76: "", //Hard only Shelley
			77: "323", //Spindred
			78: "", //Normal/hard only Spindred
			79: "", //Hard only Spindred
			80: {"name": "321", "x": -12, "y": 4 }, //mover
			81: {"name": "321", "x": -12, "y": 4 },//mover
			82: {"name": "321", "x": -12, "y": 4 },//mover
			83: {"name": "321", "x": -12, "y": 4 },//mover
			84: {"name": "321", "x": -12, "y": 4 },//mover
			85: {"name": "321", "x": -12, "y": 4 },//mover
			86: {"name": "321", "x": -12, "y": 4 },//mover
			87: {"name": "321", "x": -12, "y": 4 },//mover
			88: {"name": "206", "y": -24}, //Shikadi master
			89: "", //Normal/hard only Shikadi master
			90: "", //Hard only Shikadi master
			91: "", //track
			92: "", //track
			93: "", //track
			94: "", //track
			95: "", //track
			96: "", //track
			97: "", //track
			98: "", //track
			99: {"name": "219", "y": -16}, //Shikadi
			100: "", //Normal/Hard only Shikadi
			101: "", //Hard only Shikadi
			102: {"name": "219", "y": -16}, //Shockshund
			103: "", //Normal/Hard only Shockshund
			104: "", //Hard only Shockshund
			105: {"name": "259", "y": -16}, //Sphereful
			106: "", //Normal/Hard-only Sphereful
			107: "", //Hard-only Sphereful
			124: {"name": "201", "y": -8}, //Korath
			125: "" //Unknown, in wall in gravdamping hub

		}, {
			5: {"name": "270", "y": -16}, //Normal/Hard only Sparky
			8: "277", //Normal/Hard only Shikadi mine
			11: {"name": "284", "y": 0}, //Normal/Hard only Slicestar v
			14: {"name": "286", "y": -64}, //Normal/Hard only Robo Red
			17: {"name": "292", "y": -16}, //Normal/Hard only Spirogrip
			20: {"name": "284", "y": 0}, //Normal/Hard only Slicestar diag
			23: {"name": "284", "y": 0}, //Normal/Hard only Slicestar h
			43: {"name": "305", "y": -8}, //Normal/Hard only Little Ampton
			72: "316", //Normal/Hard only Volte-face
			75: "327", //Normal/Hard only Shelley
			78: "323", //Normal/Hard only Spindred
			89: {"name": "206", "y": -24}, //Normal/Hard only Shikadi master
			100: {"name": "219", "y": -16}, //Normal/Hard only Shikadi
			103: "239", //Normal/Hard only Shockshund
			106: {"name": "259", "y": -16} //Hard only Sphereful
		}, {
			6: {"name": "270", "y": -16}, //Hard only Sparky
			9: "277", //Hard only Shikadi mine
			12: {"name": "284", "y": 0}, //Hard only Slicestar v
			15: {"name": "286", "y": -64}, //Hard only Robo Red
			18: {"name": "292", "y": -16}, //Hard only Spirogrip
			21: {"name": "284", "y": 0}, //Hard only Slicestar diag
			24: {"name": "284", "y": 0}, //Hard only Slicestar h
			44: {"name": "305", "y": -8}, //Hard only Little Ampton
			73: "316", //Hard only Volte-face
			76: "327", //Hard only Shelley
			79: "323", //Hard only Spindred
			90: {"name": "206", "y": -24}, //Hard only Shikadi master
			99: {"name": "219", "y": -16}, //Hard only Shikadi
			104: "239", //Hard only Shockshund
			107: {"name": "259", "y": -16} //Hard only Sphereful
		}]

keen6-sprites: [{
			1: {"name": "7", "y": -16}, //keen right
			2: {"name": "15", "y": -16}, //keen left
			3: "143", //world-map keen
			4: {"name": "299", "y": -24}, //Bloog
			5: "", //Normal/hard only Bloog
			6: "", //Hard only Bloog
			7: {"name": "306", "y": -8}, //Blooglet - red
			8: {"name": "315", "y": -8}, //Blooglet - yellow
			9: {"name": "324", "y": -8}, //Blooglet - blue
			10: {"name": "333", "y": -8}, //Blooglet - green
			11: {"name": "306", "y": -8}, //Blooglet - red
			12: {"name": "315", "y": -8}, //Blooglet - yellow
			13: {"name": "324", "y": -8}, //Blooglet - blue
			14: {"name": "337", "y": -8}, //Blooglet - green
			15: "", //World map...cliff bottom
			16: "", //World map...cliff top
			18: {"name": "194", "y": -42}, //Fleex
			19: "", //Normal/hard only Fleex
			20: "", //Hard only Fleex
			24: "379", //mover
			25: "", //scroll blocker v
			26: "", //scroll blocker h
			27: "379", //mover
			28: "379", //mover
			29: "379", //mover
			30: "379", //mover
			31: "", //mover ends
			32: "379", //mover
			33: "379", //mover
			34: "379", //mover
			36: "379", //mover
			37: "379", //mover
			38: "379", //mover
			39: "379", //mover
			40: "379", //mover
			41: {"name": "360", "y": -32}, //Bobba
			42: "", //Normal/hard only Bobba
			43: "", //Hard only Bobba
			44: "", //World-map satellite point A
			45: "", //World-map satellite point B
			47: {"name": "253", "y": -24}, //Nospike
			48: "", //Normal/hard only Nospike
			49: "", //Hard only Nospike
			50: {"name": "342", "y": 0}, //Gik
			51: "", //Normal/hard only Gik
			52: "", //Hard only Gik
			53: "", //laser
			54: "", //laser
			55: "", //laser
			56: "", //laser
			57: "120", //red diamond
			58: "122", //yellow diamond
			59: "124", //blue diamond
			60: "126", //green diamond
			61: "106", //Bloog Soda
			62: "108", //Ice Cream Bar
			63: "110", //Pudding
			64: "112", //Root beer float
			65: "114", //Banana Split
			66: "116", //Pizza Slice
			67: "118", //Queen Viva
			68: "129", //ammo
			69: "129", //ammo, if low
			70: "284", //Orbatrix
			71: "", //Normal/hard only Orbatrix
			72: "", //Hard only Orbatrix
			73: "224", //Bip
			74: "", //Normal/hard only Bip
			75: "", //Hard only Bip
			76: {"name": "272", "y": -16}, //Flect
			77: "", //Normal/hard only Flect
			78: "", //Hard only Flect
			79: {"name": "354", "y": -16}, //Blorb
			80: "", //Normal/hard only Blorb
			81: "", //Hard only Blorb
			82: "202", //Ceilick
			83: "", //Normal/hard only Ceilick
			84: "", //Normal/hard only Ceilick
			85: {"name": "210", "y": -32}, //Blooguard
			86: "", //Normal/hard only Blooguard
			87: "", //Normal/hard only Blooguard
			88: "172", //Grabbiter
			89: "168", //satellite
			91: "", //mover?
			92: "", //mover?
			93: "", //mover?
			94: "", //mover?
			95: "", //mover?
			96: "", //mover?
			97: "", //mover?
			98: "", //mover?
			99: "138", //Grappling hook
			100: "137", ///Stupendous Sandwich of Chungella IV
			101: "390", //Bloogstar Rocket Passcard
			102: {"name": "240", "y": -8}, //Babobba
			103: "",
			104: "",
			105: "165", //Rocket
			106: "" //Rocket landing spot
		}, {
			5: {"name": "299", "y": -24}, //Normal/hard only Bloog
			19: {"name": "194", "y": -42}, //Normal/hard only Fleex
			42: {"name": "360", "y": -32}, //Normal/hard only Bobba
			48: {"name": "253", "y": -24}, //Normal/hard only Nospike
			51: {"name": "342", "y": 0}, //Normal/hard only Gik
			71: "284", //Normal/hard only Orbatrix
			74: "224", //Normal/hard only Bip
			77: {"name": "272", "y": -16}, //Normal/hard only Flect
			80: {"name": "354", "y": -16}, //Normal/hard only Blorb
			83: "202", //Normal/hard only Ceilick
			86: {"name": "210", "y": -32}, //Normal/hard only Blooguard
			103: {"name": "240", "y": -8} //Normal/hard only Babobba
		}, {
			6: {"name": "299", "y": -24}, //Hard only Bloog
			20: {"name": "194", "y": -42}, //Hard only Fleex
			43: {"name": "360", "y": -32}, //Hard only Bobba
			49: {"name": "253", "y": -24}, //Hard only Nospike
			52: {"name": "342", "y": 0}, //Hard only Gik
			72: "284", //Hard only Orbatrix
			75: "224", //Hard only Bip
			78: {"name": "272", "y": -16}, //Hard only Flect
			81: {"name": "354", "y": -16}, //Hard only Blorb
			84: "202", //Hard only Ceilick
			87: {"name": "210", "y": -32}, //Hard only Blooguard
			104: {"name": "240", "y": -8} //Hard only Babobba
		}]

keen6-sprites-demo: [{
		1: {"name": "7", "y": -16}, //keen right
		2: {"name": "15", "y": -16},//keen left
		3: "139", //world-map keen
		4: {"name": "216", "y": -24}, //Bloog
		5: "", //Normal/hard only Bloog
		6: "", //Hard only Bloog
		7: {"name": "225", "y": -8}, //Blooglet - red
		9: {"name": "243", "y": -8}, //Blooglet - blue
		15: "", //World map...cliff bottom
		16: "", //World map...cliff top
		25: "", //scroll blocker v
		26: "", //scroll blocker h
		27: "273", //mover
		28: "273", //mover
		29: "273", //mover
		30: "273", //mover
		31: "", //mover ends
		32: "273", //mover
		33: "273", //mover
		34: "273", //mover
		36: "273", //mover
		37: "273", //mover
		38: "273", //mover
		39: "273", //mover
		40: "273", //mover
		50: {"name": "261", "y": 0}, //Gik
		51: "", //Normal/hard only Gik
		52: "", //Hard only Gik
		54: "", //laser
		57: "120", //red diamond
		58: "122", //yellow diamond
		59: "124", //blue diamond
		60: "126", //green diamond
		61: "106", //Bloog Soda
		62: "108", //Ice Cream Bar
		63: "110", //Pudding
		64: "112", //Root beer float
		65: "114", //Banana Split
		66: "116", //Pizza Slice
		67: "118", //Queen Viva
		68: "128", //ammo
		69: "128", //ammo, if low
		83: "181", //Normal/hard only Ceilick
		85: "", //Blooguard
		86: "", //Normal/hard only Blooguard
		87: "", //Hard only Blooguard
		91: "", //mover?
		92: "", //mover?
		93: "", //mover?
		94: "", //mover?
		95: "", //mover?
		96: "", //mover?
		97: "", //mover?
		98: "", //mover?
		102: {"name": "204", "y": -8}, //Babobba
		103: "",
		104: ""
	}, {
		5: {"name": "216", "y": -24}, //Normal/hard only Bloog
		51: {"name": "261", "y": 0}, //Normal/hard only Gik
		83: "181", //Normal/hard only Ceilick
		86: {"name": "188", "y": -32}, //Normal/hard only Blooguard
		103: {"name": "204", "y": -8} //Normal/hard only Babobba
	}, {
		6: {"name": "216", "y": -24}, //Hard only Bloog
		52: {"name": "261", "y": 0}, //Hard only Gik
		87: {"name": "188", "y": -32}, //Hard only Blooguard
		104: {"name": "204", "y": -8} //Hard only Babobba
	}]

episode-data:
{
	["*.ck4"]: { "exe-name": "keen4e.exe",         "graphics-name":	"egagraph.ck4",	"num-16u": 1296, "num-16m": 2916, "num-ascii": 1, "misc-music":	2, "num-ascii2": 1, "num-text": 7, "num-other": 5
	},
	["*.ck5"]: { "exe-name": "keen5e.exe",         "graphics-name": "egagraph.ck5",	"num-16u": 1512, "num-16m": 2952, "num-ascii": 1, "misc-music":	2, "num-ascii2": 1, "num-text": 7, "num-other": 6
	},
	["*.ck6"]: { "exe-name": "keen6e.exe",         "graphics-name": "egagraph.ck6",	"num-16u": 2376, "num-16m": 2736, "num-ascii": 1, "misc-music":	2, "num-ascii2": 1, "num-text": 1, "num-other": 5
	},
	["*"]:	   { "exe-name": "UNKNOWN KEEN FILE!", "graphics-name": "",		"num-16u": 0,	 "num-16m": 0,	  "num-ascii": 0, "misc-music":	0, "num-ascii2": 0, "num-text": 0, "num-other": 0}
}

version-data:
{
	["keen4*.exe", "keen.exe"] : {
		258064: { "version": "1.0",    "table-offset": 0x22C10, "huff-offset": 0x371F6, "audio-head-offset": 0x22980, "audio-head-size": 652, "audio-huff-offset": 0x36DF6, "map-header-offset": 0x263B2, "sfx-count": 52, "level-sprites": keen4-sprites},
		259232: { "version": "1.1",    "table-offset": 0x22FE0, "huff-offset": 0x37682, "audio-head-offset": 0x22D50, "audio-head-size": 652, "audio-huff-offset": 0x37282, "map-header-offset": 0x26782, "sfx-count": 52, "level-sprites": keen4-sprites},
		259920: { "version": "1.2",    "table-offset": 0x23230, "huff-offset": 0x37934, "audio-head-offset": 0x22FA0, "audio-head-size": 652, "audio-huff-offset": 0x37534, "map-header-offset": 0x269E2, "sfx-count": 52, "level-sprites": keen4-sprites},
		263488: { "version": "1.4",    "table-offset": 0x23E80, "huff-offset": 0x386F6, "audio-head-offset": 0x23BF0, "audio-head-size": 652, "audio-huff-offset": 0x382F6, "map-header-offset": 0x27632, "sfx-count": 52, "level-sprites": keen4-sprites},
		264864: { "version": "1.4 GT", "table-offset": 0x24360,	"huff-offset": 0x38BD6,	"audio-head-offset": 0x240D0, "audio-head-size": 652, "audio-huff-offset": 0x387D6, "map-header-offset": 0x27B12, "sfx-count": 52, "level-sprites": keen4-sprites},
		262240: { "version": "DEMO",   "table-offset": 0x27000, "huff-offset": 0x38006, "audio-head-offset": 0xFFFFF, "audio-huff-offset": 0xFFFFF, "map-header-offset": 0x21492, "sfx-count": 52, "level-sprites": keen4-promo-sprites}
	},

	["keen5*.exe"] : {
		262176: { "version": "1.0",		"table-offset": 0x23DB0, "huff-offset": 0x37F8A, "audio-head-offset": 0x23A70, "audio-head-size": 828, "audio-huff-offset": 0x37B8A, "map-header-offset": 0x27782, "sfx-count": 64, "level-sprites": keen5-sprites},
		266096: { "version": "1.4",		"table-offset": 0x24BC0, "huff-offset": 0x38EC4, "audio-head-offset": 0x24880, "audio-head-size": 828, "audio-huff-offset": 0x38AC4, "map-header-offset": 0x28592, "sfx-count": 64, "level-sprites": keen5-sprites},
		267616: { "version": "1.4 GT",	"table-offset": 0x25120, "huff-offset": 0x39424, "audio-head-offset": 0x24DE0, "audio-head-size": 828, "audio-huff-offset": 0x39024, "map-header-offset": 0x28AF2, "sfx-count": 64, "level-sprites": keen5-sprites}
	},

	["keen6*.exe", "aliens.exe", "babysit.exe", "k6demo.exe"]: {
		266032: { "version": "1.0", "table-offset":0x22720, "huff-offset": 0x38912,	"audio-head-offset": 0x22420, "audio-head-size": 760, "audio-huff-offset": 0x38512,	"map-header-offset": 0x26852, "sfx-count": 60, "level-sprites": keen6-sprites},
		271696: { "version": "1.4", "table-offset":0x23B50, "huff-offset": 0x39EEE,	"audio-head-offset": 0x23850, "audio-head-size": 760, "audio-huff-offset": 0x39AEE,	"map-header-offset": 0x27C82, "sfx-count": 60, "level-sprites": keen6-sprites},
		270896: { "version": "1.5", "table-offset":0x285B0, "huff-offset": 0x39B4E,	"audio-head-offset": 0x282B0, "audio-head-size": 760, "audio-huff-offset": 0x3974E,	"map-header-offset": 0x2C6E2, "sfx-count": 60, "level-sprites": keen6-sprites},
		236112: {"version": "DEMO6", "table-offset": 0x1E630, "huff-offset": 0x31E40, "audio-head-offset": 0x1E3E0, "audio-head-size": 588, "audio-huff-offset": 0x31A40, "map-header-offset": 0x21962, "sfx-count": 47, "level-sprites": keen6-sprites-demo},
		238368: {"version": "PROMO6", "table-offset": 0x1EF60, "huff-offset": 0x32716, "audio-head-offset": 0x1ED10, "audio-head-size": 588, "audio-huff-offset": 0x32316, "map-header-offset": 0x22292, "sfx-count": 47, "level-sprites": keen6-sprites-demo}
	}
}

if (file.name like "egagraph.ck?")
{
	packed-name: file.name

	if (exists("audiohed.ck4")) //demo version
	{
		this-episode-data: {
		 "exe-name": "keen.exe",
	     "graphics-name":	"egagraph.ck4",
		 "num-16u": 1296,
		 "num-16m": 2916,
		 "num-ascii": 1,
		 "misc-music":	2, "num-ascii2": 0, "num-text": 0, "num-other": 0}
	}
	else
	{
		this-episode-data: episode-data[file.name]
	}
	exe-name: this-episode-data.exe-name //find the exe name, important data be here!

	if ((exe-name == "keen6e.exe") and exists("babysit.exe"))
	{
		exe-name = "babysit.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("keen6.exe"))
	{
		exe-name = "keen6.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("k6demo.exe"))
	{
		exe-name = "k6demo.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("aliens.exe"))
	{
		exe-name = "aliens.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("keen6c.exe"))
	{
		exe-name = "keen6c.exe"
	}
	else if ((exe-name == "keen4e.exe") and exists("keen4.exe"))
	{
		exe-name = "keen4.exe"
	}
	else if ((exe-name == "keen5e.exe") and exists("keen5.exe"))
	{
		exe-name = "keen5.exe"
	}

	//link in the Huffman decompression table, stored in the exe
	from exe-name
	{
		this-version-data: version-data[exe-name][file.size]
		header-offset: this-version-data.table-offset

		at this-version-data.huff-offset:
		unsigned16[512] huff-table
	}

	num16u: this-episode-data.num-16u
	if ((this-version-data.version == "DEMO6") or (this-version-data.version == "PROMO6"))
	{
		num16u = 1296
	}

	//link in the header, stored in the exe
	bitmap-count: 0
	masked-bitmap-count: 0
	sprite-count: 0

	from exe-name at this-version-data.table-offset
	{		
		file [1]
		{
			name: "Bitmaps header"

			if (this-version-data.version != "DEMO")
			{
				unsigned24 _offset
			}
			else
			{
				unsigned32 _offset
			}

			from packed-name at _offset
			{
				unsigned32 decompressed-size
				bitmap-count = decompressed-size / 4				
			}

			offset: _offset + 4

			compressed "keen-huffman"
		}

		file [1]
		{
			name: "Masked Bitmaps header"
			if (this-version-data.version != "DEMO")
			{
				unsigned24 _offset
			}
			else
			{
				unsigned32 _offset
			}

			from packed-name at _offset
			{
				unsigned32 decompressed-size
				masked-bitmap-count = decompressed-size / 4				
			}

			offset: _offset + 4

			compressed "keen-huffman"
		}

		file [1]
		{
			name: "Sprites header"
			if (this-version-data.version != "DEMO")
			{
				unsigned24 _offset
			}
			else
			{
				unsigned32 _offset
			}

			from packed-name at _offset
			{
				unsigned32 decompressed-size
				sprite-count = decompressed-size / 18				
			}

			offset: _offset + 4
			compressed "keen-huffman"			
		}

		file [3]: index
		{
			name: "Font " + (index + 1)
			folder: "Fonts"
			if (this-version-data.version != "DEMO")
			{
				unsigned24 _offset
			}
			else
			{
				unsigned32 _offset
			}
			
			from packed-name at _offset
			{
				unsigned32 decompressed-size			
			}

			offset: _offset + 4

			compressed "keen-huffman"

			interpret-as "keenengine-font"
		}

		file [bitmap-count]: index
		{
			name: "Bitmap " + (index + 1)
			bitmap-number: index

			if (this-version-data.version != "DEMO")
			{
				unsigned24 _offset
			}
			else
			{
				unsigned32 _offset
			}

			from packed-name at _offset
			{
				unsigned32 decompressed-size			
			}

			offset: _offset + 4

			compressed "keen-huffman"
		}

		file [masked-bitmap-count]: index
		{
			name: "Masked Bitmap " + (index + 1)
			bitmap-number: index

			if (this-version-data.version != "DEMO")
			{
				unsigned24 _offset
			}
			else
			{
				unsigned32 _offset
			}
			
			from packed-name at _offset
			{
				unsigned32 decompressed-size			
			}

			offset: _offset + 4

			compressed "keen-huffman"
		}

		file [sprite-count]: index
		{
			name: "Sprite " + (index + 1)
			bitmap-number: index

			if (this-version-data.version != "DEMO")
			{
				unsigned24 _offset
			}
			else
			{
				unsigned32 _offset
			}

			from packed-name at _offset
			{
				unsigned32 decompressed-size			
			}

			offset: _offset + 4

			compressed "keen-huffman"
		}

		file [1]
		{
			name: "Unmasked 8x8 tiles"
			if (this-version-data.version != "DEMO")
			{
				unsigned24 offset
			}
			else
			{
				unsigned32 offset
			}

			decompressed-size: 104 * 8 * 4
			compressed "keen-huffman"

			interpret-as "keenengine-unmasked8x8"
		}

		file [1] 
		{
			name: "Masked 8x8 tiles"
			if (this-version-data.version != "DEMO")
			{
				unsigned24 offset
			}
			else
			{
				unsigned32 offset
			}

			decompressed-size: 20 * 8 * 5
			compressed "keen-huffman"

			interpret-as "keenengine-masked8x8"
		}

		skips: 0

		file [1]
		{
			name: "Unmasked 16x16 tiles"
			use24: (this-version-data.version != "DEMO")
			offset: 0
			
			loop
			{
				if (this-version-data.version != "DEMO")
				{
					unsigned24 this_offset
				}
				else
				{
					unsigned32 this_offset
				}
				offset = this_offset
				skips = skips + 1				
			} while ((this_offset == 0xFFFFFF) or (this_offset == 0xFFFFFFFF))	
		}

		if (this-version-data.version != "DEMO")
		{
			data((num16u - skips) * 3) tile-offsets //unmasked 16x16 offsets
		}
		else
		{
			data((num16u - skips) * 4) tile-offsets //unmasked 16x16 offsets
		}

		skips = 0

		file [1]
		{
			name: "Masked 16x16 tiles"

			offset: 0
			use24: (this-version-data.version != "DEMO")	

			loop 
			{
				if (this-version-data.version != "DEMO")
				{
					unsigned24 this_offset
				}
				else
				{
					unsigned32 this_offset
				}
				offset = this_offset
				skips = skips + 1				
			} while ((this_offset == 0xFFFFFF) or (this_offset == 0xFFFFFFFF))	
		}

		if (this-version-data.version != "DEMO")
		{
			data((this-episode-data.num-16m - skips) * 3) tile-offsets //masked 16x16 offsets
		}
		else
		{
			data((this-episode-data.num-16m - skips) * 4) tile-offsets //masked 16x16 offsets
		}

		//other data here...misc, text and demos.
		if (!(packed-name like "egagraph.ck6"))
		{
			if (!(file.name like "*.ck4"))  //Keen 5 and 6 have text first, Keen 4 after Ascii Screen and those two music-like files
			{
				file [this-episode-data.num-text]: index
				{
					name: "Text" + (index + 1)
					if (this-version-data.version != "DEMO")
					{
						unsigned24 _offset
					}
					else
					{
						unsigned32 _offset
					}
					from packed-name at _offset
					{
						unsigned32 decompressed-size			
					}

					offset: _offset + 4
					compressed "keen-huffman"
				}
			}

			file [this-episode-data.num-ascii]
			{
				name: "DOS Screen"
				if (this-version-data.version != "DEMO")
				{
					unsigned24 _offset
				}
				else
				{
					unsigned32 _offset
				}

				from packed-name at _offset
				{
					unsigned32 decompressed-size			
				}

				offset: _offset + 4
				compressed "keen-huffman"
			}

			file [this-episode-data.misc-music]: index
			{
				name: "Other " + (index + 1) + ".music"
				if (this-version-data.version != "DEMO")
				{
					unsigned24 _offset
				}
				else
				{
					unsigned32 _offset
				}

				from packed-name at _offset
				{
					unsigned32 decompressed-size			
				}

				offset: _offset + 4
				compressed "keen-huffman"
			}

			file [this-episode-data.num-ascii2]
			{
				name: "DOS Screen"
				if (this-version-data.version != "DEMO")
				{
					unsigned24 _offset
				}
				else
				{
					unsigned32 _offset
				}
				
				from packed-name at _offset
				{
					unsigned32 decompressed-size			
				}

				offset: _offset + 4
				compressed "keen-huffman"
			}

			if (file.name like "*.ck4")
			{
				file[this-episode-data.num-text]: index
				{
					name: "Text " + (index + 1)
					if (this-version-data.version != "DEMO")
					{
						unsigned24 _offset
					}
					else
					{
						unsigned32 _offset
					}

					from packed-name at _offset
					{
						unsigned32 decompressed-size			
					}

					offset: _offset + 4
					compressed "keen-huffman"
				}
			}

			file [this-episode-data.num-other]: index
			{
				name: "Other " + (index + 1)
				if (this-version-data.version != "DEMO")
				{
					unsigned24 _offset
				}
				else
				{
					unsigned32 _offset
				}

				from packed-name at _offset
				{
					unsigned32 decompressed-size			
				}

				offset: _offset + 4
				compressed "keen-huffman"
			}
		}
	}
}

if (file.name like "DOS Screen")
{
	data(7) unknown
	b800-text
}

if (file.name like "Text*")
{
	text
}

if (file.name like "*art.ck4")
{
	text
}

alpha-mask: 1

if (file.name like "bitmap *")
{
	from "Bitmaps header" at bitmap-number * 4
	{
		unsigned16 width-in-bytes
		unsigned16 height
	}

	image
	{
		format: "I4"
		width: width-in-bytes * 8
		bit-stride: width * height
	}
}

if (file.name like "Masked Bitmap *")
{
	from "Masked Bitmaps header" at bitmap-number * 4 
	{
		unsigned16 width-in-bytes
		unsigned16 height
	}

	image
	{
		format: "A1I4"
		width: width-in-bytes * 8
		bit-stride: width * height
		alpha-mask: 1
	}
}

if (file.name like "Sprite *")
{
	folder: "Sprites"

	from "Sprites header" at bitmap-number * 18
	{
		unsigned16 width-in-bytes
		unsigned16 height
		signed16 OrgX
		signed16 OrgY
		signed16 Rx1
		signed16 Ry1
		signed16 Rx2
		signed16 Ry2
		unsigned16 Shifts
	}

	image
	{
		format: "A1I4"	
		width: width-in-bytes * 8
		bit-stride: width * height
		alpha-mask: 1
	}
}

if (file.name == "unmasked 16x16 tiles")
{
	exe-offset: (header-offset + (8 * 3) + (bitmap-count * 3) + (masked-bitmap-count * 3) + (sprite-count * 3))
	if (use24 == false)
	{
		exe-offset = (header-offset + (8 * 4) + (bitmap-count * 4) + (masked-bitmap-count * 4) + (sprite-count * 4))
	}
	from exe-name at exe-offset
	{
		if (use24 == true)
		{
			unsigned24[this-episode-data["num-16u"]] offsets
		}
		else
		{
			unsigned32[this-episode-data["num-16u"]] offsets
		}
	}
	current-tile: 0

	num16u: this-episode-data["num-16u"]
	if ((this-version-data.version == "DEMO6") or (this-version-data.version == "PROMO6"))
	{
		num16u = 1296
	}

	image-layout-width: 288
	image-layout
	{
		loop (num16u)
		{
			offset-to-image: offsets[current-tile]

			if ((offset-to-image != 0xFFFFFF) and (offset-to-image != 0xFFFFFFFF))
			{
				at offset-to-image - offset:

				decompressed-size: 128
				compressed[file.remaining-bytes] "keen-huffman"
				{
					image
					{
						format: "I4"
						width: 16
						height: 16
						bit-stride: width * height
					}
				}

			}
			else
			{
				image
				{
					format: "Blank"
					width: 16
					height: 16
				}
			}
			current-tile = current-tile + 1
		}
	}
}

if (file.name == "masked 16x16 tiles")
{
	exe-offset: (header-offset + (8 * 3) + (bitmap-count * 3) + (masked-bitmap-count * 3) + (sprite-count * 3) + (num16u * 3))
	if (use24 == false)
	{
		exe-offset = (header-offset + (8 * 4) + (bitmap-count * 4) + (masked-bitmap-count * 4) + (sprite-count * 4) + (num16u * 4))
	}
	from exe-name at exe-offset
	{
		if (use24 == true)
		{
			unsigned24[this-episode-data["num-16m"]] offsets
		}
		else
		{
			unsigned32[this-episode-data["num-16m"]] offsets
		}
	}
	current-tile: 0

	image-layout-width: 288
	image-layout
	{
		loop (this-episode-data["num-16m"])
		{
			offset-to-image: offsets[current-tile]

			if ((offset-to-image != 0xFFFFFF) and (offset-to-image != 0xFFFFFFFF))
			{
				at offset-to-image - offset:

				decompressed-size: 160
				compressed [file.remaining-bytes] "keen-huffman"
				{
					image
					{
						format: "A1I4"
						width: 16
						height: 16
						bit-stride: width * height
					}
				}
			}
			else
			{
				image
				{
					format: "Blank"
					width: 16
					height: 16
				}
			}
			current-tile = current-tile + 1
		}
	}
}

if (file.name like "gamemaps.ck?")
{
	packed-name: file.name
	packed-size: file.size
	exe-name: episode-data[file.name].exe-name

	if (exists("audiohed.ck4")) //demo version
	{
		exe-name = "keen.exe"
	}

	if ((exe-name == "keen6e.exe") and exists("babysit.exe"))
	{
		exe-name = "babysit.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("keen6.exe"))
	{
		exe-name = "keen6.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("k6demo.exe"))
	{
		exe-name = "k6demo.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("aliens.exe"))
	{
		exe-name = "aliens.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("keen6c.exe"))
	{
		exe-name = "keen6c.exe"
	}
	else if ((exe-name == "keen4e.exe") and exists("keen4.exe"))
	{
		exe-name = "keen4.exe"
	}
	else if ((exe-name == "keen5e.exe") and exists("keen5.exe"))
	{
		exe-name = "keen5.exe"
	}

	level-graphics-name: episode-data[file.name].graphics-name

	from exe-name
	{
		this-version-data: version-data[exe-name][file.size]
	}

	level-sprites: this-version-data.level-sprites

	from exe-name at this-version-data.map-header-offset
	{
		file [100]
		{
			unsigned32 headerOffset

			offset: 0
			size: packed-size

			skip-if headerOffset == 0

			from packed-name at headerOffset
			{
				unsigned32[3] planeOffsets
				unsigned16[3] planeSizes
				unsigned16 width
				unsigned16 height
				fixed-string(16) name
				fixed-string(4) signature //!ID!

				interpret-as "ck4-level"
			}
		}
	}
}

file-format ck4-level
{
	level
	{
		grid-x: 16
		grid-y: 16

		at planeOffsets[0] :
		unsigned16 sizeAfterDecarmack

		decompressedSize: sizeAfterDecarmack
		compressed [planeSizes[0]] "Carmack"
		{
			unsigned16 decompressedSize
			magic-number: 0xABCD
			compressed [sizeAfterDecarmack - 2] "KeenRLE"
			{
				level-layer
				{
					data-type: "unsigned16"
					layer-name: "Background"
					layer-image: level-graphics-name + "\\Unmasked 16x16 tiles"
					order: 0
				}
			}
		}

		at planeOffsets[1] :
		unsigned16 sizeAfterDecarmack

		decompressedSize: sizeAfterDecarmack
		compressed [planeSizes[1]] "Carmack"
		{
			unsigned16 decompressedSize
			magic-number: 0xABCD
			compressed [sizeAfterDecarmack - 2] "KeenRLE"
			{
				level-layer
				{
					data-type: "unsigned16"
					layer-name: "Foreground"
					layer-image: level-graphics-name + "\\Masked 16x16 tiles"
					order: 1
					ignore-tile: 0
				}
			}
		}

		level-layer-names: ["Objects", "Normal Objects", "Hard objects"]
		ignore-debug: [false, true, true]

		loop (3): i
		{
			at planeOffsets[2] :
			unsigned16 sizeAfterDecarmack

			decompressedSize: sizeAfterDecarmack
			compressed [planeSizes[2]] "Carmack"
			{
				unsigned16 decompressedSize
				magic-number: 0xABCD
				compressed [sizeAfterDecarmack - 2] "KeenRLE"
				{
					level-layer
					{
						data-type: "unsigned16"
						layer-name: level-layer-names[i]
						layer-images-prefix: level-graphics-name + "\\sprite "
						layer-images: level-sprites[i]
						//debug: true
						//layer-image: "debug"
						order: 1
						ignore-tile: 0
						ignore-unknown: ignore-debug[i]
						max-valid-tile: 0x1FF
					}
				}
			}
		}
	}
}

if (file.name like ["audio.ck4", "audio.ck5", "audio.ck6"]) {
	exe-name: episode-data[file.name].exe-name

	if ((exe-name == "keen6e.exe") and exists("babysit.exe"))
	{
		exe-name = "babysit.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("keen6.exe"))
	{
		exe-name = "keen6.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("k6demo.exe"))
	{
		exe-name = "k6demo.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("aliens.exe"))
	{
		exe-name = "aliens.exe"
	}
	else if ((exe-name == "keen6e.exe") and exists("keen6c.exe"))
	{
		exe-name = "keen6c.exe"
	}
	else if ((exe-name == "keen4e.exe") and exists("keen4.exe"))
	{
		exe-name = "keen4.exe"
	}
	else if ((exe-name == "keen5e.exe") and exists("keen5.exe"))
	{
		exe-name = "keen5.exe"
	}

	from exe-name
	{
		this-version-data: version-data[exe-name][file.size]

		audio-files: this-version-data.audio-head-size / 4
		at this-version-data.audio-head-offset:
		unsigned32[audio-files] audio-offsets

		at this-version-data.audio-huff-offset:
		unsigned16[512] huff-table
	} 

	first-music: 0-1

	file[audio-files]: i
	{
		name: "Audio " + i
		offset: audio-offsets[i]

		skip-if ((offset >= file.size) or (offset == 11333) or (offset == 8743) or (offset == 9716) or (offset == 9646))

		at offset
		{
			unsigned32 decompressed-size			
		}

		offset = offset + 4
		compressed "keen-huffman"

		if (i < this-version-data.sfx-count)
		{
			interpret-as "sound-PC-APOGEE-AUDIOT"
			name = "SFX\\sound " + i
		}
		else if (i >= (this-version-data.sfx-count * 2))
		{
			if (first-music == -1) {
				first-music = i
			}

			interpret-as "music-imf-560-2"
			name = "Music\\music " + (i - first-music)
		}
		else
		{
			name = "sfx-adlib\\sfx " + (i - (this-version-data.sfx-count))
			interpret-as "adlib-sound"
		}
	}
}

if (file.name like "audiot.ck4")
{
	from "audiohed.ck4"
	{
		unsigned32[file.size / 4] offsets
	} 

	first-music: 0-1

	file[offsets.length]: i
	{
		offset: offsets[i]
		
		name: "Audio " + i

		skip-if ((offset >= file.size) or (offset == 11333) or (offset == 8743))

		if (i < 52)
		{
			interpret-as "sound-PC-APOGEE-AUDIOT"
			name = "SFX\\sound " + i
		}
		else if (i >= (52 * 2))
		{
			if (first-music == -1) {
				first-music = i
			}
			offset = offset + 4
			interpret-as "music-imf-560"
			name = "Music\\music " + (i - first-music)
		}
		else
		{
			name = "sfx-adlib\\sfx " + (i - 52)
			interpret-as "adlib-sound"
		}
	}
}