/// <summary> /// Loads inbound HCE executable with the inbound configuration. /// </summary> /// <param name="executable"> /// Object representing a legal HCE executable. /// </param> /// <param name="configuration"> /// Object representing the kernel configuration. /// </param> public static void Invoke(Executable executable, Configuration configuration) { /* Clear log file */ { if (Exists(Paths.Exception) && new FileInfo(Paths.Exception).Length > 1048576) // If larger than 1 MiB, ... { System.IO.File.WriteAllText(Paths.Exception, ""); // ...clear log. } } /* Switch to legacy kernel modes */ { if (!Exists(Legacy)) { configuration.Mode = Configuration.ConfigurationMode.SPV33; } } Init(); /* initc.txt declarations */ Blam(); /* blam.sav enhancements */ Open(); /* opensauce declarations */ Exec(); /* haloce.exe invocation */ Core("CORE.MAIN: Successfully updated the initiation, profile and OS files, and invoked the HCE executable."); /** * We declare the contents of the initiation file in this method before dealing with the profile enhancements and * the executable invocation. It's the most important task, so we have to deal with it first. * * The values declared by the HXE kernel for the initiation file are categorised into the following sections: * * - RESUME: Campaign resuming support for the SPV3 mod, which permits compatibility with SPV3's main UI; * - TWEAKS: Rudimentary tweaks including cinematic bars, and controller enhancements (magnetism & auto-aim); * - SHADER: SPV3 post-processing configurations, including activated shaders & shader intensity levels. */ void Init() { var init = (Initiation)GetFullPath(executable.Debug.Initiation); Resume(); /* spv3 campaign resume with ui.map compatibility */ Tweaks(); /* hce/spv3 start-up miscellaneous tweaks */ Shader(); /* spv3 post-processing toggles & settings */ Unlock(); /* spv3.1 legacy maps unlocking mechanism */ try { init.Save(); Core("MAIN.INIT: Initiation data has been successfully applied and saved."); } catch (Exception e) { var msg = " -- MAIN.INIT HALTED.\n Error: " + e.ToString() + "\n"; var log = (File)Paths.Exception; log.AppendAllText(msg); Error(msg); } /** * Resume the campaign based on the progress of the last used profile. This requires: * * - a LASTPROF.TXT file to be located in the profile path declared for the inbound executable; and * - the directory for the profile declared in the aforementioned plaintext file; and * - the savegame.bin for the respective profile, to infer the campaign progress. */ void Resume() { if (configuration.Mode != Configuration.ConfigurationMode.SPV32 && configuration.Mode != Configuration.ConfigurationMode.SPV33) { return; } try { var lastprof = (LastProfile)Custom.LastProfile(executable.Profile.Path); /** Check if lastprof.txt exists * If it exists, load its data * Else, create a new one */ if (lastprof.Exists()) { lastprof.Load(); } else { Error("Lastprof.txt does not Exist."); Core("Saving LastProf.txt..."); lastprof.Save(); } var name = lastprof.Profile; var save = (Progress)Custom.Progress(executable.Profile.Path, name); /** Check for the existence of the blam.sav specified by LastProfile. * If it exists, skip this abomination. * Else, create a new player profile * or search for existing profiles. */ if (!save.Exists()) { Error("Player Profile specified in LastProfile not found."); var savegames = Custom.Profiles(executable.Profile.Path); /** Check if the Savegames (profiles) folder exists. * If it exists, search for existing profiles. * Else, create a new player profile. */ if (Exists(savegames)) { List <Profile> profiles = Profile.List(savegames); List <Profile> validProfiles = new List <Profile> { }; /** Check for any existing profile folders * If any are found, check if their blam.sav also exists. * Select the first valid profile. * Else, create a new player profile. */ if (profiles.Count != 0) { foreach (Profile profile in profiles) { if (profile.Exists()) { validProfiles.Add(profile); // todo: implement better validation } } lastprof.Profile = validProfiles[0].Details.Name; lastprof.Save(); } else { Error("No profiles found in savegames folder."); Core("Generating new profile"); NewProfile.Generate(executable.Profile.Path, lastprof, new Profile(), false); } } else { Error("Savegames folder does not exist."); Core("Creating savegames folder and a new profile..."); NewProfile.Generate(executable.Profile.Path, lastprof, new Profile(), false);; } name = lastprof.Profile; save = (Progress)Custom.Progress(executable.Profile.Path, name); } var campaign = new Campaign(Paths.Campaign(configuration.Mode)); campaign.Load(); save.Load(campaign); init.Progress = save; init.Resume = campaign.Resume; Core("INIT.RESUME: Campaign checkpoint information has been applied to the initiation file."); Debug("INIT.RESUME: Mission - " + init.Progress.Mission.Name); Debug("INIT.RESUME: Difficulty - " + init.Progress.Difficulty.Name); } catch (Exception e) { var msg = " -- INIT.RESUME HALTED\n Error: " + e.ToString() + "\n"; var log = (File)Paths.Exception; log.AppendAllText(msg); Error(e.Message + " -- INIT.RESUME HALTED"); } } /** * Rudimentary tweaks including: * * - Player Auto-aim * - Player Magnetism * - Acceleration * * ... and stuff for SPV3: * * - Cinematic Bars * - Motion Sensor */ void Tweaks() { init.PlayerAutoaim = configuration.Tweaks.AutoAim; init.PlayerMagnetism = configuration.Tweaks.Magnetism; init.MouseAcceleration = configuration.Tweaks.Acceleration; init.Gamma = configuration.Video.Gamma; if (configuration.Mode == Configuration.ConfigurationMode.SPV32 || configuration.Mode == Configuration.ConfigurationMode.SPV33) { init.CinemaBars = configuration.Tweaks.CinemaBars; init.MotionSensor = configuration.Tweaks.Sensor; init.Unload = configuration.Tweaks.Unload; Core("INIT.TWEAKS: SPV3 cinematic bars, motion sensor and unload tweaks have been updated."); Debug("INIT.TWEAKS: Cinematic Bars - " + init.CinemaBars); Debug("INIT.TWEAKS: Motion Sensor - " + init.MotionSensor); Debug("INIT.TWEAKS: Unload - " + init.Unload); } Core("INIT.TWEAKS: Magnetism, auto-aim, and mouse acceleration tweaks have been updated."); Debug("INIT.TWEAKS: Player Auto-aim - " + init.PlayerAutoaim); Debug("INIT.TWEAKS: Player Magnetism - " + init.PlayerMagnetism); Debug("INIT.TWEAKS: Mouse Acceleration - " + init.MouseAcceleration); Debug("INIT.TWEAKS: Gamma - " + init.Gamma); } /** * SPV3 shader toggles and configurations. */ void Shader() { if (configuration.Mode != Configuration.ConfigurationMode.SPV32 && configuration.Mode != Configuration.ConfigurationMode.SPV33) { return; } init.Shaders = configuration.Shaders; Core("INIT.SHADER: SPV3 post-processing effects have been assigned to the initiation file."); } /** * Indeed, SPV3.1 had some DRM I wasn't quite a fan of. This routine unlocks the 3.1 campaigns. Is this a crack? * I should have a demo screen playing here, along with greetings to friends all over the world. * * Idea: Release 3.2 with an NFO file with ANSI art. */ void Unlock() { if (configuration.Mode != Configuration.ConfigurationMode.SPV32) { return; } init.Unlock = true; Core("INIT.UNLOCK: SPV3.1 campaign has been unlocked for subsequent invocation."); } } /** * We enhance the player's profile by applying the highest video & audio quality settings, along with forcing the * resolution declared in video parameters of the inbound executable. * * The enhancements are applied based on the provided configuration and the successful inference * the last used profile in the specified profiles directory. */ void Blam() { Profile blam; try { blam = Profile.Detect(executable.Profile.Path); Video(); Audio(); Input(); blam.Save(); Core("MAIN.BLAM: Profile enhancements have been successfully applied and saved."); } catch (FileNotFoundException) { var lastprof = (LastProfile)Custom.LastProfile(executable.Profile.Path); var scaffold = lastprof.Exists() && System.IO.File.Exists(Custom.Profile(executable.Profile.Path, lastprof.Profile)); if (!lastprof.Exists()) { Core("Lastprof.txt does not exist."); } if (!scaffold) { Debug("Savegames scaffold doesn't exist."); } else { Debug("Savegames scaffold detected."); } Core("Calling LastProfile.Generate()..."); NewProfile.Generate(executable.Profile.Path, lastprof, blam = new Profile(), scaffold); } catch (Exception e) { var msg = " -- MAIN.BLAM HALTED\n Error: " + e.ToString() + "\n"; var log = (File)Paths.Exception; log.AppendAllText(msg); Error(msg); } /** * Apply the resolution specified in video parameters of the inbound executable OR apply the primary screen's * current resolution. This enforces HCE to run at the desired or native resolution, and also obsoletes Ecran. * * Additionally, effects and qualities are enabled and set to the maximum level, respectively. Of course, this * also depends on the provided configuration. */ void Video() { if (!configuration.Video.ResolutionEnabled) { // infer from resolution if Native Resoluton preferred. if (executable.Video.Width == 0 || executable.Video.Height == 0) { executable.Video.Width = (ushort)PrimaryScreen.Bounds.Width; executable.Video.Height = (ushort)PrimaryScreen.Bounds.Height; Core("BLAM.VIDEO.RESOLUTION: No resolution provided. Applied native resolution to executable."); } else if (executable.Video.Width > (ushort)PrimaryScreen.Bounds.Width || executable.Video.Height > (ushort)PrimaryScreen.Bounds.Height) { executable.Video.Width = (ushort)PrimaryScreen.Bounds.Width; executable.Video.Height = (ushort)PrimaryScreen.Bounds.Height; Core("BLAM.VIDEO.RESOLUTION: Resolution out of bounds. Applied native resolution to executable."); } blam.Video.Resolution.Width = executable.Video.Width; blam.Video.Resolution.Height = executable.Video.Height; Core("BLAM.VIDEO.RESOLUTION: Executable resolution has been assigned to the inferred profile."); Debug("BLAM.VIDEO.RESOLUTION: Width - " + blam.Video.Resolution.Width); Debug("BLAM.VIDEO.RESOLUTION: Height - " + blam.Video.Resolution.Height); } if (configuration.Video.Bless) { executable.Video.Width -= 10; executable.Video.Height -= 10; Core("BLAM.VIDEO.BLESS: Tweaked executable resolution for border-less support."); } if (configuration.Video.Quality) { blam.Video.Effects.Specular = true; blam.Video.Effects.Shadows = true; blam.Video.Effects.Decals = true; blam.Video.Quality = VideoQuality.High; blam.Video.Particles = VideoParticles.High; Core("BLAM.VIDEO.QUALITY: Patched effects and quality to the highest levels."); Debug("BLAM.VIDEO.QUALITY: Specular - " + blam.Video.Effects.Specular); Debug("BLAM.VIDEO.QUALITY: Shadows - " + blam.Video.Effects.Shadows); Debug("BLAM.VIDEO.QUALITY: Decals - " + blam.Video.Effects.Decals); Debug("BLAM.VIDEO.QUALITY: Quality - " + blam.Video.Quality); Debug("BLAM.VIDEO.QUALITY: Particles - " + blam.Video.Particles); } if (configuration.Video.Uncap) { blam.Video.FrameRate = VideoFrameRate.VsyncOff; Core("BLAM.VIDEO.UNCAP: Applied V-Sync off for framerate uncap."); Debug("BLAM.VIDEO.UNCAP: Framerate - " + blam.Video.FrameRate); } Core("BLAM.VIDEO: Video enhancements have been applied accordingly."); } /** * Apply the highest audio settings and toggle Hardware Acceleration & EAX. The latter will require a compatible * library such as DSOAL for it to actually work. */ void Audio() { if (configuration.Audio.Quality) { blam.Audio.Quality = AudioQuality.High; blam.Audio.Variety = AudioVariety.High; Core("BLAM.AUDIO.QUALITY: Patched audio quality to the highest level."); Debug("BLAM.AUDIO.QUALITY: Quality - " + blam.Audio.Quality); Debug("BLAM.AUDIO.QUALITY: Variety - " + blam.Audio.Variety); } if (configuration.Audio.Enhancements) { if (System.IO.File.Exists(DSOAL)) { blam.Audio.HWA = true; blam.Audio.EAX = true; Core("BLAM.AUDIO.ENHANCEMENTS: Enabled Hardware Acceleration & EAX."); } else { blam.Audio.HWA = false; blam.Audio.EAX = false; Core("BLAM.AUDIO.ENHANCEMENTS: DSOAL not found. Refusing to enable HWA & EAX.."); } Debug("BLAM.AUDIO.ENHANCEMENTS: HWA - " + blam.Audio.HWA); Debug("BLAM.AUDIO.ENHANCEMENTS: EAX - " + blam.Audio.EAX); } Core("BLAM.AUDIO: Audio enhancements have been applied accordingly."); } /** * Apply SPV3's preset input to the controller. */ void Input() { if (!configuration.Input.Override) { return; } blam.Input.Mapping = new Dictionary <Profile.ProfileInput.Action, Profile.ProfileInput.Button> { { Profile.ProfileInput.Action.MoveForward, Profile.ProfileInput.Button.LSU }, { Profile.ProfileInput.Action.MoveBackward, Profile.ProfileInput.Button.LSD }, { Profile.ProfileInput.Action.MoveLeft, Profile.ProfileInput.Button.LSL }, { Profile.ProfileInput.Action.MoveRight, Profile.ProfileInput.Button.LSR }, { Profile.ProfileInput.Action.Crouch, Profile.ProfileInput.Button.LSM }, { Profile.ProfileInput.Action.Reload, Profile.ProfileInput.Button.DPU }, { Profile.ProfileInput.Action.Jump, Profile.ProfileInput.Button.A }, { Profile.ProfileInput.Action.SwitchGrenade, Profile.ProfileInput.Button.B }, { Profile.ProfileInput.Action.Action, Profile.ProfileInput.Button.X }, { Profile.ProfileInput.Action.SwitchWeapon, Profile.ProfileInput.Button.Y }, { Profile.ProfileInput.Action.LookUp, Profile.ProfileInput.Button.RSU }, { Profile.ProfileInput.Action.LookDown, Profile.ProfileInput.Button.RSD }, { Profile.ProfileInput.Action.LookLeft, Profile.ProfileInput.Button.RSL }, { Profile.ProfileInput.Action.LookRight, Profile.ProfileInput.Button.RSR }, { Profile.ProfileInput.Action.ScopeZoom, Profile.ProfileInput.Button.RSM }, { Profile.ProfileInput.Action.ThrowGrenade, Profile.ProfileInput.Button.LB }, { Profile.ProfileInput.Action.Flashlight, Profile.ProfileInput.Button.LT }, { Profile.ProfileInput.Action.MeleeAttack, Profile.ProfileInput.Button.RB }, { Profile.ProfileInput.Action.FireWeapon, Profile.ProfileInput.Button.RT } }; blam.Input.BitBinding = new Dictionary <Profile.ProfileInput.OddValues, Profile.ProfileInput.OddOffsets> { { Profile.ProfileInput.OddValues.Button1, Profile.ProfileInput.OddOffsets.MenuAccept }, { Profile.ProfileInput.OddValues.Button2, Profile.ProfileInput.OddOffsets.MenuBack } }; Core("BLAM.INPUT: Input overrides have been applied accordingly."); } } /** * For SPV3.2+, we will tweak the OpenSauce settings to ensure full compatibility with 3.2+'s specifications and * post-processing effects. */ void Open() { var open = (OpenSauce)Custom.OpenSauce(executable.Profile.Path); var mod = System.IO.File.Exists("./dinput8.dll") || System.IO.File.Exists("./mods/opensauce.dll"); if (System.IO.File.Exists("./dinput8.dll")) { Debug("dinput8.dll exists"); } else { Debug("dinput8 not found"); } if (System.IO.File.Exists("./mods/opensauce.dll")) { Debug("opensauce.dll exists"); } else { Debug("opensauce.dll not found"); } if (!mod) { Debug("Open Sauce not found"); } if (open.Exists() && mod) { open.Load(); } else if (mod) { open.Save(); open.Load(); } try { if (configuration.Mode == Configuration.ConfigurationMode.HCE) { return; } open.Rasterizer.PostProcessing.MotionBlur.Enabled = (configuration.Shaders & PP.MOTION_BLUR_BUILT_IN) != 0; open.HUD.ScaleHUD = true; /* fixes user interface */ open.Camera.IgnoreFOVChangeInCinematics = true; /* fixes user interface */ open.Camera.IgnoreFOVChangeInMainMenu = true; /* fixes user interface */ open.Rasterizer.ShaderExtensions.Effect.DepthFade = true; /* shader optimisations */ open.Save(); Core("MAIN.OPEN: Conditionally applied SPV3 fixes - enabled HUD scaling, FOV ignoreing, and depth fade."); Debug("MAIN.OPEN: Motion Blur - " + open.Rasterizer.PostProcessing.MotionBlur.Enabled); Debug("MAIN.OPEN: HUD Scaling - " + open.HUD.ScaleHUD); Debug("MAIN.OPEN: Cinematic FOV Ignore - " + open.Camera.IgnoreFOVChangeInCinematics); Debug("MAIN.OPEN: Main Menu FOV Ignore - " + open.Camera.IgnoreFOVChangeInMainMenu); Debug("MAIN.OPEN: Depth Fade Effects - " + open.Rasterizer.ShaderExtensions.Effect.DepthFade); } catch (Exception e) { var msg = " -- MAIN.OPEN\n Error: " + e.ToString() + "\n"; var log = (File)Paths.Exception; log.AppendAllText(msg); Error(msg); } } /** * Gracefully halt any potentially hanging HCE processes, conditionally patch the HCE executable with LAA flag, * and start the executable. */ void Exec() { Reset(); Patch(); Start(); Bless(); Core("MAIN.EXEC: All HCE execution routines have been successfully resolved."); /** * This method encourages the kernel to wait for a potential HCE process to end before proceeding with any * subsequent routines. For some odd reason, there are cases where HCE runs in the background after the end-user * exits it, thus prohibiting any additional processes from being invoked. To mitigate that, we gracefully kill * any existing ones. */ void Reset() { Info("Killing existing HCE processes"); try { foreach (var process in GetProcessesByName("haloce")) { process.Kill(); } } catch (Exception e) { var msg = " -- MAIN.BLAM HALTED\n Error: " + e.ToString() + "\n"; var log = (File)Paths.Exception; log.AppendAllText(msg); Info(msg); } var tries = 0; Wait("Waiting for existing HCE process to end "); while (GetProcessesByName("haloce").Length > 0 && tries <= 25) { System.Console.Write(Resources.Progress); tries++; } if (tries == 25) { Error("Could not kill HCE process. Process initiation errors may occur."); } Core("EXEC.RESET: Finalised attempts of killing potential HCE processes."); } /** * If the HCE executable is not already patched with the LAA flag, this method will take care of modifying the * byte's value to enable the respective LAA flag. */ void Patch() { if (configuration.Tweaks.Acceleration) { configuration.Tweaks.Patches |= Patcher.EXEP.DISABLE_MOUSE_ACCELERATION; } if (configuration.Video.GammaOn == false) { configuration.Tweaks.Patches |= Patcher.EXEP.DISABLE_SYSTEM_GAMMA; } try { new Patcher().Write(configuration.Tweaks.Patches, executable.Path); Core("EXEC.PATCH: Conditional patching has been handled."); } catch (Exception e) { var msg = " -- EXEC.PATCH HALTED\n Error: " + e.ToString() + "\n"; var log = (File)Paths.Exception; log.AppendAllText(msg); Error(msg); } } /** * God is on my side if this method actually gets called. */ void Start() { try { executable.Start(configuration.Main.Elevated); Core("EXEC.START: Successfully started the inferred HCE executable."); } catch (Exception e) { var msg = " -- EXEC.START HALTED\n Error: " + e.ToString() + "\n"; var log = (File)Paths.Exception; log.AppendAllText(msg); Error(msg); } } /** * Bless for border-less! */ void Bless() { if (!configuration.Video.Bless) { return; } const int LOADED_OFFSET = 0x0064533B; /* 0x6B4051 could also be used, according to github.com/gbMichelle */ const int PROCESS_WM_READ = 0x0010; const int GWL_STYLE = -16; const int SWP_NOMOVE = 0X2; const int SWP_NOSIZE = 1; const int SWP_NOZORDER = 0X4; const int SWP_SHOWWINDOW = 0x0040; const int WS_SYSMENU = 0x00080000; const int WS_MAXIMIZEBOX = 0x00010000; const int WS_MINIMIZEBOX = 0x00020000; const int WS_SIZEBOX = 0x00040000; const int WS_BORDER = 0x00800000; const int WS_DLGFRAME = 0x00400000; const int WS_CAPTION = SWP_NOMOVE | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_BORDER | WS_DLGFRAME | WS_SIZEBOX; try { var processes = GetProcesses(); foreach (var process in processes) { if (!process.ProcessName.StartsWith("haloce")) { continue; } /** * The bless hack is applied only when HCE has been loaded. HXE deems HCE as loaded when the main menu has * been initiated. * * This is determined by checking the value declared at LOADED_OFFSET. The value changes from 0 to 1 the * moment HCE has loaded. * * The reason we apply the hack then is for robustness: the HCE window becomes responsive around that time * after the loading sequence. */ var processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id); var bytesRead = 0; var buffer = new byte[1]; var loaded = false; while (!loaded && process.HasExited != true) { ReadProcessMemory((int)processHandle, LOADED_OFFSET, buffer, buffer.Length, ref bytesRead); loaded = buffer[0] == 1; } /** * The hack attempts to hide any window controls and also move the window to the top left of the current * display. In most circumstances, this should work just fine. If people are applying border-less mode and * use a resolution lower than their screen resolution, then, err... why? */ var pFoundWindow = process.MainWindowHandle; var style = GetWindowLong(pFoundWindow, GWL_STYLE); SetWindowLong(pFoundWindow, GWL_STYLE, style & ~WS_CAPTION); SetWindowPos(pFoundWindow, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW); Core("EXEC.BLESS: Applied border-less hack to the HCE process window."); } } catch (Exception e) { var msg = " -- EXEC.START HALTED\n Error: " + e.ToString() + "\n"; var log = (File)Paths.Exception; log.AppendAllText(msg); Error(msg); } } } }
/// <summary> /// Invokes the HCE executable. /// </summary> private static void InvokeExecutable(Executable executable) { executable.Start(); }
/// <summary> /// Loads inbound HCE executable with the inbound configuration. /// </summary> /// <param name="executable"> /// Object representing a legal HCE executable. /// </param> /// <param name="configuration"> /// Object representing the kernel configuration. /// </param> public static void Invoke(Executable executable, Configuration configuration) { Init(); /* initc.txt declarations */ Blam(); /* blam.sav enhancements */ Open(); /* opensauce declarations */ Exec(); /* haloce.exe invocation */ Core("CORE.MAIN: Successfully updated the initiation, profile and OS files, and invoked the HCE executable."); /** * We declare the contents of the initiation file in this method before dealing with the profile enhancements and * the executable invocation. It's the most important task, so we have to deal with it first. * * The values declared by the HXE kernel for the initiation file are categorised into the following sections: * * - RESUME: Campaign resuming support for the SPV3 mod, which permits compatibility with SPV3's main UI; * - TWEAKS: Rudimentary tweaks including cinematic bars, and controller enhancements (magnetism & auto-aim); * - SHADER: SPV3 post-processing configurations, including activated shaders & shader intensity levels. */ void Init() { var init = (Initiation)GetFullPath(executable.Debug.Initiation); Resume(); /* spv3 campaign resume with ui.map compatibility */ Tweaks(); /* hce/spv3 start-up miscellaneous tweaks */ Shader(); /* spv3 post-processing toggles & settings */ Unlock(); /* spv3.1 legacy maps unlocking mechanism */ try { init.Save(); Core("MAIN.INIT: Initiation data has been successfully applied and saved."); } catch (Exception e) { Error(e.Message + " -- MAIN.INIT HALTED"); } /** * Resume the campaign based on the progress of the last used profile. This requires: * * - a LASTPROF.TXT file to be located in the profile path declared for the inbound executable; and * - the directory for the profile declared in the aforementioned plaintext file; and * - the savegame.bin for the respective profile, to infer the campaign progress. */ void Resume() { try { var prof = (LastProfile)Custom.LastProfile(executable.Profile.Path); if (!prof.Exists()) { return; } prof.Load(); var name = prof.Profile; var save = (Progress)Custom.Progress(executable.Profile.Path, name); if (!save.Exists()) { return; } save.Load(); init.Mission = save.Mission; init.Difficulty = save.Difficulty; Core("INIT.RESUME: Campaign checkpoint information has been applied to the initiation file."); Debug("INIT.RESUME: Mission - " + init.Mission); Debug("INIT.RESUME: Difficulty - " + init.Difficulty); } catch (Exception e) { Error(e.Message + " -- INIT.RESUME HALTED"); } } /** * Rudimentary tweaks including: * * - Player Auto-aim * - Player Magnetism * - Execution speed * - Acceleration * * ... and stuff for SPV3: * * - Cinematic Bars * - Motion Sensor */ void Tweaks() { init.PlayerAutoaim = configuration.Tweaks.AutoAim; init.PlayerMagnetism = configuration.Tweaks.Magnetism; init.Speed = configuration.Tweaks.Speed; init.MouseAcceleration = configuration.Tweaks.Acceleration; init.Gamma = configuration.Video.Gamma; if (configuration.Mode == Configuration.ConfigurationMode.SPV32) { init.CinematicBars = configuration.Tweaks.Cinematic; init.MotionSensor = configuration.Tweaks.Sensor; init.Unload = configuration.Tweaks.Unload; Core("INIT.TWEAKS: SPV3.2 cinematic bars, motion sensor and unload tweaks have been updated."); Debug("INIT.TWEAKS: Cinematic Bars - " + init.CinematicBars); Debug("INIT.TWEAKS: Motion Sensor - " + init.MotionSensor); Debug("INIT.TWEAKS: Unload - " + init.Unload); } Core("INIT.TWEAKS: Magnetism, auto-aim, speed and mouse acceleration tweaks have been updated."); Debug("INIT.TWEAKS: Player Auto-aim - " + init.PlayerAutoaim); Debug("INIT.TWEAKS: Player Magnetism - " + init.PlayerMagnetism); Debug("INIT.TWEAKS: Speed - " + init.Speed); Debug("INIT.TWEAKS: Mouse Acceleration - " + init.MouseAcceleration); Debug("INIT.TWEAKS: Gamma - " + init.Gamma); } /** * SPV3.2 shader toggles and configurations. */ void Shader() { if (configuration.Mode != Configuration.ConfigurationMode.SPV32) { return; } init.PostProcessing.Internal = configuration.Shaders.Internal; init.PostProcessing.External = configuration.Shaders.External; init.PostProcessing.GBuffer = configuration.Shaders.GBuffer; init.PostProcessing.DepthFade = configuration.Shaders.DepthFade; init.PostProcessing.Bloom = configuration.Shaders.Bloom; init.PostProcessing.LensDirt = configuration.Shaders.LensDirt; init.PostProcessing.DynamicLensFlares = configuration.Shaders.DynamicLensFlares; init.PostProcessing.VolumetricLighting = configuration.Shaders.VolumetricLighting; init.PostProcessing.AntiAliasing = configuration.Shaders.AntiAliasing; init.PostProcessing.HudVisor = configuration.Shaders.HudVisor; init.PostProcessing.FilmGrain = configuration.Shaders.FilmGrain; init.PostProcessing.MotionBlur = configuration.Shaders.MotionBlur; init.PostProcessing.MXAO = configuration.Shaders.MXAO; init.PostProcessing.DOF = configuration.Shaders.DOF; Core("INIT.SHADER: SPV3.2 post-processing effects have been assigned to the initiation file."); Debug("INIT.SHADER: Internal - " + init.PostProcessing.Internal); Debug("INIT.SHADER: External - " + init.PostProcessing.External); Debug("INIT.SHADER: GBuffer - " + init.PostProcessing.GBuffer); Debug("INIT.SHADER: DepthFade - " + init.PostProcessing.DepthFade); Debug("INIT.SHADER: Bloom - " + init.PostProcessing.Bloom); Debug("INIT.SHADER: LensDirt - " + init.PostProcessing.LensDirt); Debug("INIT.SHADER: Dynamic Lens Flares - " + init.PostProcessing.DynamicLensFlares); Debug("INIT.SHADER: Volumetric Lighting - " + init.PostProcessing.VolumetricLighting); Debug("INIT.SHADER: Anti Aliasing - " + init.PostProcessing.AntiAliasing); Debug("INIT.SHADER: HUD Visor - " + init.PostProcessing.HudVisor); Debug("INIT.SHADER: Film Grain - " + init.PostProcessing.FilmGrain); Debug("INIT.SHADER: Motion Blur - " + init.PostProcessing.MotionBlur); Debug("INIT.SHADER: MXAO - " + init.PostProcessing.MXAO); Debug("INIT.SHADER: DOF - " + init.PostProcessing.DOF); } /** * Indeed, SPV3.1 had some DRM I wasn't quite a fan of. This routine unlocks the 3.1 campaigns. Is this a crack? * I should have a demo screen playing here, along with greetings to friends all over the world. * * Idea: Release 3.2 with an NFO file with ANSI art. */ void Unlock() { if (configuration.Mode != Configuration.ConfigurationMode.SPV31) { return; } init.Unlock = true; Core("INIT.UNLOCK: SPV3.1 campaign has been unlocked for subsequent invocation."); } } /** * We enhance the player's profile by applying the highest video & audio quality settings, along with forcing the * resolution declared in video parameters of the inbound executable. * * The enhancements are applied based on the provided configuration, and also the on the success rate of inferring * the last used profile in the specified profiles directory. */ void Blam() { Profile blam; try { blam = Profile.Detect(executable.Profile.Path); Video(); Audio(); Input(); blam.Save(); Core("MAIN.BLAM: Profile enhancements have been successfully applied and saved."); } catch (Exception e) { Error(e.Message + " -- MAIN.BLAM HALTED"); } /** * Apply the resolution specified in video parameters of the inbound executable OR apply the primary screen's * current resolution. This enforces HCE to run at the desired or native resolution, and also obsoletes Ecran. * * Additionally, effects and qualities are enabled and set to the maximum level, respectively. Of course, this * also depends on the provided configuration. */ void Video() { if (configuration.Video.Resolution) { if (executable.Video.Width == 0 || executable.Video.Height == 0) { executable.Video.Width = (ushort)PrimaryScreen.Bounds.Width; executable.Video.Height = (ushort)PrimaryScreen.Bounds.Height; Core("BLAM.VIDEO.RESOLUTION: No resolution provided. Applied native resolution to executable."); } if (executable.Video.Width > (ushort)PrimaryScreen.Bounds.Width || executable.Video.Height > (ushort)PrimaryScreen.Bounds.Height) { executable.Video.Width = (ushort)PrimaryScreen.Bounds.Width; executable.Video.Height = (ushort)PrimaryScreen.Bounds.Height; Core("BLAM.VIDEO.RESOLUTION: Resolution out of bounds. Applied native resolution to executable."); } blam.Video.Resolution.Width = executable.Video.Width; blam.Video.Resolution.Height = executable.Video.Height; Core("BLAM.VIDEO.RESOLUTION: Executable resolution has been assigned to the inferred profile."); Debug("BLAM.VIDEO.RESOLUTION: Width - " + blam.Video.Resolution.Width); Debug("BLAM.VIDEO.RESOLUTION: Height - " + blam.Video.Resolution.Height); } if (configuration.Video.Bless) { executable.Video.Width -= 10; executable.Video.Height -= 10; Core("BLAM.VIDEO.BLESS: Tweaked executable resolution for border-less support."); } if (configuration.Video.Quality) { blam.Video.Effects.Specular = true; blam.Video.Effects.Shadows = true; blam.Video.Effects.Decals = true; blam.Video.Quality = VideoQuality.High; blam.Video.Particles = VideoParticles.High; Core("BLAM.VIDEO.QUALITY: Patched effects and quality to the highest levels."); Debug("BLAM.VIDEO.QUALITY: Specular - " + blam.Video.Effects.Specular); Debug("BLAM.VIDEO.QUALITY: Shadows - " + blam.Video.Effects.Shadows); Debug("BLAM.VIDEO.QUALITY: Decals - " + blam.Video.Effects.Decals); Debug("BLAM.VIDEO.QUALITY: Quality - " + blam.Video.Quality); Debug("BLAM.VIDEO.QUALITY: Particles - " + blam.Video.Particles); } if (configuration.Video.Uncap) { blam.Video.FrameRate = VideoFrameRate.VsyncOff; Core("BLAM.VIDEO.UNCAP: Applied V-Sync off for framerate uncap."); Debug("BLAM.VIDEO.UNCAP: Framerate - " + blam.Video.FrameRate); } Core("BLAM.VIDEO: Video enhancements have been applied accordingly."); } /** * Apply the highest audio settings and toggle Hardware Acceleration & EAX. The latter will require a compatible * library such as DSOAL for it to actually work. */ void Audio() { if (configuration.Audio.Quality) { blam.Audio.Quality = AudioQuality.High; blam.Audio.Variety = AudioVariety.High; Core("BLAM.AUDIO.QUALITY: Patched audio quality to the highest level."); Debug("BLAM.AUDIO.QUALITY: Quality - " + blam.Audio.Quality); Debug("BLAM.AUDIO.QUALITY: Variety - " + blam.Audio.Variety); } if (configuration.Audio.Enhancements) { if (System.IO.File.Exists(DSOAL)) { blam.Audio.HWA = true; blam.Audio.EAX = true; Core("BLAM.AUDIO.ENHANCEMENTS: Enabled Hardware Acceleration & EAX."); } else { blam.Audio.HWA = false; blam.Audio.EAX = false; Core("BLAM.AUDIO.ENHANCEMENTS: DSOAL not found. Refusing to enable HWA & EAX.."); } Debug("BLAM.AUDIO.ENHANCEMENTS: HWA - " + blam.Audio.HWA); Debug("BLAM.AUDIO.ENHANCEMENTS: EAX - " + blam.Audio.EAX); } Core("BLAM.AUDIO: Audio enhancements have been applied accordingly."); } /** * Apply SPV3.2's preset input to the controller. */ void Input() { if (!configuration.Input.Override) { return; } blam.Input.Mapping = new Dictionary <Profile.ProfileInput.Action, Profile.ProfileInput.Button> { { Profile.ProfileInput.Action.MoveForward, Profile.ProfileInput.Button.LSU }, { Profile.ProfileInput.Action.MoveBackward, Profile.ProfileInput.Button.LSD }, { Profile.ProfileInput.Action.MoveLeft, Profile.ProfileInput.Button.LSL }, { Profile.ProfileInput.Action.MoveRight, Profile.ProfileInput.Button.LSR }, { Profile.ProfileInput.Action.Crouch, Profile.ProfileInput.Button.LSM }, { Profile.ProfileInput.Action.Reload, Profile.ProfileInput.Button.DPU }, { Profile.ProfileInput.Action.Jump, Profile.ProfileInput.Button.A }, { Profile.ProfileInput.Action.SwitchGrenade, Profile.ProfileInput.Button.B }, { Profile.ProfileInput.Action.Action, Profile.ProfileInput.Button.X }, { Profile.ProfileInput.Action.SwitchWeapon, Profile.ProfileInput.Button.Y }, { Profile.ProfileInput.Action.LookUp, Profile.ProfileInput.Button.RSU }, { Profile.ProfileInput.Action.LookDown, Profile.ProfileInput.Button.RSD }, { Profile.ProfileInput.Action.LookLeft, Profile.ProfileInput.Button.RSL }, { Profile.ProfileInput.Action.LookRight, Profile.ProfileInput.Button.RSR }, { Profile.ProfileInput.Action.ScopeZoom, Profile.ProfileInput.Button.RSM }, { Profile.ProfileInput.Action.ThrowGrenade, Profile.ProfileInput.Button.LB }, { Profile.ProfileInput.Action.Flashlight, Profile.ProfileInput.Button.LT }, { Profile.ProfileInput.Action.MeleeAttack, Profile.ProfileInput.Button.RB }, { Profile.ProfileInput.Action.FireWeapon, Profile.ProfileInput.Button.RT } }; Core("BLAM.INPUT: Input overrides have been applied accordingly."); } } /** * For SPV3.2, we will tweak the OpenSauce settings to ensure full compatibility with 3.2's specifications and * post-processing effects. */ void Open() { var open = (OpenSauce)Custom.OpenSauce(executable.Profile.Path); if (open.Exists()) { open.Load(); } try { if (configuration.Mode != Configuration.ConfigurationMode.SPV32) { return; } open.Rasterizer.PostProcessing.MotionBlur.Enabled = configuration.Shaders.MotionBlur == BuiltIn; open.HUD.ScaleHUD = true; /* fixes user interface */ open.Camera.IgnoreFOVChangeInCinematics = true; /* fixes user interface */ open.Camera.IgnoreFOVChangeInMainMenu = true; /* fixes user interface */ open.Rasterizer.ShaderExtensions.Effect.DepthFade = true; /* shader optimisations */ open.Save(); Core("MAIN.OPEN: Conditionally applied SPV3.2 fixes - enabled HUD scaling, FOV ignoreing, and depth fade."); Debug("MAIN.OPEN: Motion Blur - " + open.Rasterizer.PostProcessing.MotionBlur.Enabled); Debug("MAIN.OPEN: HUD Scaling - " + open.HUD.ScaleHUD); Debug("MAIN.OPEN: Cinematic FOV Ignore - " + open.Camera.IgnoreFOVChangeInCinematics); Debug("MAIN.OPEN: Main Menu FOV Ignore - " + open.Camera.IgnoreFOVChangeInMainMenu); Debug("MAIN.OPEN: Depth Fade Effects - " + open.Rasterizer.ShaderExtensions.Effect.DepthFade); } catch (Exception e) { Error(e.Message + " -- MAIN.OPEN HALTED"); } } /** * Gracefully halt any potentially hanging HCE processes, conditionally patch the HCE executable with LAA flag, * and start the executable. */ void Exec() { Reset(); Patch(); Start(); Bless(); Core("MAIN.EXEC: All HCE execution routines have been successfully resolved."); /** * This method encourages the kernel to wait for a potential HCE process to end before proceeding with any * subsequent routines. For some odd reason, there are cases where HCE runs in the background after the end-user * exits it, thus prohibiting any additional processes from being invoked. To mitigate that, we gracefully kill * any existing ones. */ void Reset() { Info("Killing existing HCE processes"); try { foreach (var process in Process.GetProcessesByName("haloce")) { process.Kill(); } } catch (Exception e) { Info(e.Message); } var tries = 0; Wait("Waiting for existing HCE process to end "); while (Process.GetProcessesByName("haloce").Length > 0 && tries <= 25) { System.Console.Write(Resources.Progress); tries++; } if (tries == 25) { Error("Could not kill HCE process. Process initiation errors may occur."); } Core("EXEC.RESET: Finalised attempts of killing potential HCE processes."); } /** * If the HCE executable is not already patched with the LAA flag, this method will take care of modifying the * byte's value to enable the respective LAA flag. */ void Patch() { const byte value = 0x2F; /* LAA flag */ const long offset = 0x136; /* LAA offset */ try { using (var fs = new FileStream(executable.Path, FileMode.Open, FileAccess.ReadWrite)) using (var ms = new MemoryStream(0x24B000)) using (var bw = new BinaryWriter(ms)) using (var br = new BinaryReader(ms)) { ms.Position = 0; fs.Position = 0; fs.CopyTo(ms); ms.Position = offset; if (br.ReadByte() != value) { ms.Position -= 1; /* restore position */ bw.Write(value); /* patch LAA flag */ fs.Position = 0; ms.Position = 0; ms.CopyTo(fs); Info("Applied LAA patch to the HCE executable"); } else { Info("HCE executable already patched with LAA"); } } Core("EXEC.PATCH: Conditional LAA patching has been handled."); } catch (Exception e) { Error(e.Message + " -- EXEC.PATCH HALTED"); } } /** * God is on my side if this method actually gets called. */ void Start() { try { executable.Start(); Core("EXEC.START: Successfully started the inferred HCE executable."); } catch (Exception e) { Error(e.Message + " -- EXEC.START HALTED"); } } /** * Bless for border-less! */ void Bless() { if (!configuration.Video.Bless) { return; } const int GWL_STYLE = -16; const int SWP_NOMOVE = 0X2; const int SWP_NOSIZE = 1; const int SWP_NOZORDER = 0X4; const int SWP_SHOWWINDOW = 0x0040; const int WS_SYSMENU = 0x00080000; const int WS_MAXIMIZEBOX = 0x00010000; const int WS_MINIMIZEBOX = 0x00020000; const int WS_SIZEBOX = 0x00040000; const int WS_BORDER = 0x00800000; const int WS_DLGFRAME = 0x00400000; const int WS_CAPTION = SWP_NOMOVE | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_BORDER | WS_DLGFRAME | WS_SIZEBOX; Thread.Sleep(5000); try { var processes = Process.GetProcesses(); foreach (var process in processes) { if (!process.ProcessName.StartsWith("haloce")) { continue; } process.WaitForInputIdle(); var pFoundWindow = process.MainWindowHandle; var style = GetWindowLong(pFoundWindow, GWL_STYLE); SetWindowLong(pFoundWindow, GWL_STYLE, style & ~WS_CAPTION); SetWindowPos(pFoundWindow, 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW); Core("EXEC.BLESS: Applied border-less hack to the HCE process window."); } } catch (Exception e) { Error(e.Message + " -- EXEC.BLESS HALTED"); } } } }