state("scummvm", "GOG") {
	ushort cardID: "scummvm.exe", 0x004ED32C, 0xB4, 0x10;
	ushort sfxID: "scummvm.exe", 0x004ED32C, 0x6C, 0xC;
	int heldPage: "scummvm.exe", 0x004ED32C, 0x74, 0x8;
	int age: "scummvm.exe", 0x004ED32C, 0x74, 0x4;
	int clockBridge: "scummvm.exe", 0x004ED32C, 0x74, 0x48;
	byte32 markerSwitches: "scummvm.exe", 0x004ED32C, 0x74, 0x1C;
}

state("scummvm", "Steam/DVD") {
	ushort cardID: "scummvm.exe", 0x0052C34C, 0xB4, 0x10;
	ushort sfxID: "scummvm.exe", 0x0052C34C, 0x6C, 0xC;
	int heldPage: "scummvm.exe", 0x0052C34C, 0x74, 0x8;
	int age: "scummvm.exe", 0x0052C34C, 0x74, 0x4;
	int clockBridge: "scummvm.exe", 0x0052C34C, 0x74, 0x48;
	byte32 markerSwitches: "scummvm.exe", 0x0052C34C, 0x74, 0x1C;
}

init {
	//i robbed this md5 code from CptBrian's RotN autosplitter
	//shoutouts to him
	byte[] exeMD5HashBytes = new byte[0];
	using (var md5 = System.Security.Cryptography.MD5.Create()) {
		using (var s = File.Open(modules.First().FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
			exeMD5HashBytes = md5.ComputeHash(s); 
		} 
	}
	var MD5Hash = exeMD5HashBytes.Select(x => x.ToString("X2")).Aggregate((a, b) => a + b);
	print("MD5Hash: " + MD5Hash.ToString()); //Lets DebugView show me the MD5Hash of the game executable, which is actually useful.
	
	if (MD5Hash == "05DE98AFC709B66092EDF7395197308B") {
		print("From GOG, with love.");
		version = "GOG";
	} else if (MD5Hash == "C67ADFE717BE09C7FFDBB8D71F150110") {
		print("Steam/DVD Version.");
		version = "Steam/DVD";
	}
	
	//also this
	vars.firstLink = 0;
	vars.markerSwitchManager = 0;
}

startup {
	settings.Add("pages", true, "Split on handing in all non-library pages.");
	settings.Add("libpages", false, "Include library pages.", "pages");
	settings.Add("any", false, "Any% splits");
	settings.Add("fireplace", false, "Split on closing of the fireplace.", "any");
	settings.Add("clockbridge", false, "Split on raising of the clocktower bridge.", "any");
	settings.Add("switches", false, "Split on every marker switch being flipped.", "any");
	settings.Add("link", true, "Split when linking to another Age.");
	settings.Add("firstLink", true, "...but only the very first.", "link");
	settings.Add("returnToMyst", false, "...but only when linking back to Myst Island.", "link");
}

split {
	if (settings["pages"]) {
		// Held page changed on Myst Island, didn't drop white page
		if (current.age == 2 && old.heldPage != 0 && old.heldPage != 13 && current.heldPage == 0) {
			// Skip the library pages if user doesn't want to split for them
			if (settings["libpages"] || (old.heldPage != 1 && old.heldPage != 7)) {
				return true;
			}
		}
	}
	
	if (settings["link"]) {
		// Age transition, excluding menu; we only check transitions *to* K'veer since runs will always end there
		if (old.age != current.age && old.age <= 4 && current.age <= 6 && current.age != 5) {
			if (vars.firstLink == 0 && (!settings["returnToMyst"] || current.age == 2)) {
				if (settings["firstLink"]) vars.firstLink = 1;
				return true;
			}
		}
	}
	
	if (settings["any"]) {
		if (settings["fireplace"] && current.age == 2 && old.cardID != 4162 && current.cardID == 4162) {
			return true;
		}	
	
		if (settings["clockbridge"] && old.clockBridge == 0 && current.clockBridge == 1) {
			return true;
		}
	
		if (settings["switches"]) {
			//this is the only time i've managed to be sorta clever
			//marker switch flip state is stored in an int
			for (int i = 0; i < 8; i++) {
				if (((vars.markerSwitchManager & (1 << i)) == 0) && current.markerSwitches[4 * i] == 1) {
					vars.markerSwitchManager |= (1 << i);
					return true;
				}	
			}
		}
	}
		
	// Always split upon handing in white page in K'veer
	if (old.heldPage == 13 && current.heldPage == 0 && current.age == 6) {
		return true;
	}
}

start {
	if (current.cardID == 5 && old.sfxID == 0 && current.sfxID == 5) {
		vars.firstLink = 0;
		vars.markerSwitchManager = 0;
		return true;
	}
}