// Metal Gear: Portable Ops Autosplitter // For use with the PPSSPP Emulator // Created by NickRPGreen // v1.03: // - New Game + support state("LiveSplit") {} startup{ vars.U = new ExpandoObject(); var u = vars.U; u.Log = (Action)(x => print("MPO ASL - " + x.ToString())); Assembly.Load(File.ReadAllBytes("Components/emu-help-v3")).CreateInstance("PSP"); u.USA = vars.Helper.Make(0x089E9AF2); // U = 85; u.PAL = vars.Helper.Make(0x089F1A92); // E = 69; u.JAP = vars.Helper.Make(0x089E9BA2); // J = 74; } init { var u = vars.U; u.ready = false; u.warning = false; u.started = false; u.tempIGT = 0; } update { var u = vars.U; if(!u.ready){ vars.Helper.Update(); u.region = null; if(u.USA.Current == 85){ u.region = "USA"; u.IGT = vars.Helper.Make(0x08a5cb90); u.LastIGT = vars.Helper.Make(0x08a24e20); // IGT of the last playthrough on the same save, is subtracted from IGT for NG+ u.ScreenID = vars.Helper.Make(0x08a1c2f8); // 0 on reset u.GameState = vars.Helper.Make(0x08a18e6c); // 20 = Mission, 30 = Stage Select, 60 = Cutscene; //u.Boss = vars.Helper.Make(0x08a24e60); u.Results = vars.Helper.Make(0x08a51e08); // 10 = Results - also triggers just before credits start, providing final split u.AreaID = vars.Helper.Make(0x08a24dcc); u.Log("US version detected. Memory watchers compiled"); } else if(u.PAL.Current == 69){ u.region = "PAL"; u.IGT = vars.Helper.Make(0x08A51AA0); u.LastIGT = vars.Helper.Make(0x08A78DB0); // IGT of the last playthrough on the same save, is subtracted from IGT for NG+ u.ScreenID = vars.Helper.Make(0x08A70384); // 0 on reset u.GameState = vars.Helper.Make(0x08A22D1C); // 20 = Mission, 30 = Stage Select, 60 = Cutscene; //u.Boss = vars.Helper.Make(0x08a24e60); u.Results = vars.Helper.Make(0x08A47328); // 11 = Results - also triggers just before credits start, providing final split u.AreaID = vars.Helper.Make(0x08A78ED4); u.Log("PAL version detected. Memory watchers compiled"); } else if(u.JAP.Current == 74){ u.region = "JAP"; u.IGT = vars.Helper.Make(0x08A1C3C8); u.LastIGT = vars.Helper.Make(0x08A24EE0); // IGT of the last playthrough on the same save, is subtracted from IGT for NG+ u.ScreenID = vars.Helper.Make(0x08A1C3B8); // 0 on reset u.GameState = vars.Helper.Make(0x08A22D1C); // 20 = Mission, 30 = Stage Select, 60 = Cutscene; //u.Boss = vars.Helper.Make(0x08a24e60);// u.Results = vars.Helper.Make(0x08A51EC8); // 10 = Results - also triggers just before credits start, providing final split u.AreaID = vars.Helper.Make(0x08A2F498); u.Log("JAP version detected. Memory watchers compiled"); } else if(!u.warning){ u.warning = true; u.Log("Version not detected, awaiting game launch"); return false; } else { return false; } u.ready = true; } vars.Helper.Update(); if((u.region == "USA" && u.USA.Changed) || (u.region == "PAL" && u.PAL.Changed) || (u.region == "JAP" && u.JAP.Changed)){ u.ready = false; u.warning = false; u.Log("ROM unloaded, scanning for new version"); } current.ScreenID = u.ScreenID.Current; current.AreaID = u.AreaID.Current; current.GameState = u.GameState.Current; current.Results = u.Results.Current; current.IGT = u.IGT.Current; current.LastIGT = u.LastIGT.Current; if(!u.started && u.Results.Current > 30){ u.started = true; } } gameTime { var u = vars.U; if(u.started){ return TimeSpan.FromMilliseconds((u.IGT.Current - u.LastIGT.Current)*1000/300); } else { return TimeSpan.FromMilliseconds((u.IGT.Current - u.tempIGT)*1000/300); } } start { var u = vars.U; return (u.ScreenID.Old == 1768189541 || u.ScreenID.Old == 0) && u.ScreenID.Current == 1935764582; } onStart { var u = vars.U; if(u.LastIGT.Current == 0){ u.started = true; } else{ u.started = false; u.tempIGT = u.IGT.Current; } } isLoading { return true; } split { var u = vars.U; // Split on area change whilst preventing splitting when returning to Prison to rescue Roy if (u.AreaID.Changed && u.AreaID.Current != 4){ return true; } // Split on credits start if(u.AreaID.Current == 20){ if ((u.region == "USA" || u.region == "JAP") && u.Results.Changed && u.Results.Current == 10){ return true; } if (u.region == "PAL" && u.Results.Changed && u.Results.Current == 11){ return true; } } } reset { return vars.U.ScreenID.Current == 0; }