/// <summary>
        /// Toggles party mode status, adds/removes an overlay covering the screen which will rotate all of the colours.
        /// </summary>
        public void Toggle_Party_Mode()
        {
            if (PartyModeEnabled)
            {
                // Remove the additional function pointer assigned to the delegate to render the box during the game menu editing.
                Program.Sonic_Heroes_Overlay.direct2DRenderMethod -= Draw_Overlay;
                PartyModeEnabled = false;
            }
            else
            {
                // Add a function pointer to the delegate delegate to render the box during the game menu editing.
                Program.Sonic_Heroes_Overlay.direct2DRenderMethod += Draw_Overlay;

                // Play the song "Diamond in The Sky"
                Invoke_External_Class.Play_Song(Pointer_DiamondInTheSky);

                // Disable The Character voices if they are enabled.
                if (Program.Feature_Toggle_Character_Chatter_X.Get_CharacterChatter())
                {
                    Program.Feature_Toggle_Character_Chatter_X.Toggle_CharacterChatter();
                }
                if (Program.Feature_Toggle_Character_Chatter_X.Get_VoiceComments())
                {
                    Program.Feature_Toggle_Character_Chatter_X.Toggle_CharacterCommentChatter();
                }

                // Go Go Go RGB
                Program.Feature_Cycle_RGB_Colours_X.Toggle_HUE_Cycle_All_Combined();
                PartyModeEnabled = true;
            }
        }
        /// <summary>
        /// Loads the AFS file, effectively swapping the voices.
        /// </summary>
        private void Load_AFS_File(int AFS_Pointer)
        {
            // Backup the conditional jump preventing from reloading of AFS file.
            byte[] OriginalCheck = Program.Sonic_Heroes_Process.ReadMemory((IntPtr)AFS_NO_RELOAD_JUMP_STATEMENT, 2);

            // NOP the jump which checks/verifies the AFS reloading.
            Program.Sonic_Heroes_Process.WriteMemory((IntPtr)AFS_NO_RELOAD_JUMP_STATEMENT, new byte[] { 0x90, 0x90 });

            // Writes the current offset to the new AFS file name into memory.
            Program.Sonic_Heroes_Process.WriteMemory((IntPtr)AFS_FILE_NAME_OFFSET_LOCATION_MEMORY, BitConverter.GetBytes(AFS_Pointer));

            // Reads the current song name string for backup purposes.
            int String_Length = 0;

            while ((Program.Sonic_Heroes_Process.ReadMemory <byte>((IntPtr)ADX_CURRENT_SONG_NAME_MEMORY + String_Length, 1)) != 0)
            {
                String_Length += 1;
            }
            string Original_Song_Name = Encoding.ASCII.GetString(Program.Sonic_Heroes_Process.ReadMemory((IntPtr)0xA6DB8A, String_Length));

            // Load the currently set AFS File.
            Invoke_External_Class.Load_AFS_Language_File();

            // Rewrite the song name string in memory after it being wiped by the AFS loading function.
            List <byte> Original_Song_Bytes = Encoding.ASCII.GetBytes(Original_Song_Name).ToList();

            Original_Song_Bytes.Add(0x00); // Just in case, add additional null terminator.
            Program.Sonic_Heroes_Process.WriteMemory((IntPtr)ADX_CURRENT_SONG_NAME_MEMORY, Original_Song_Bytes.ToArray());

            // Restart the last playing music track.
            Invoke_External_Class.Play_Song(ADX_CURRENT_SONG_NAME_MEMORY);

            // Restore the original check if an AFS file is already loaded.
            Program.Sonic_Heroes_Process.WriteMemory((IntPtr)AFS_NO_RELOAD_JUMP_STATEMENT, OriginalCheck);
        }
 /// <summary>
 /// Hit the payload.
 /// </summary>
 private void Payload_II()
 {
     if (!Emerald_Coast_Trigger_Activated)
     {
         // Secretly put us back in the main menu if we are in a stage.
         Invoke_External_Class.Exit_Stage_X();
         Emerald_Coast_Trigger_Activated = true;
     }
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Plays ADX which contains in its name the passed in string. Calls C++ Function with our own pointer to the music track.
 /// </summary>
 public void Play_ADX_Track(string ADXName)
 {
     for (int x = 0; x < BGM_List.Count; x++)
     {
         if (BGM_List[x].Song_Name.Contains(ADXName))
         {
             Invoke_External_Class.Play_Song(BGM_List[x].Song_Pointer); break;
         }
     }
 }
        /// <summary>
        /// Draws the overlay if necessary, i.e. if character is in a level.
        /// </summary>
        /// <param name="DirectX_Graphics_Window"></param>
        private void Draw_Overlay(WindowRenderTarget DirectX_Graphics_Window)
        {
            // Get Information of whether the overlay should be shown.
            byte Is_Currently_In_Level = Program.Sonic_Heroes_Process.ReadMemory <byte>((IntPtr)SonicHeroesVariables.Game_CurrentState.CurrentlyInLevel, 1);

            // If the player is in a stage.
            if (Is_Currently_In_Level == 1)
            {
                Draw_Window(DirectX_Graphics_Window); Invoke_External_Class.Play_Song(Pointer_DiamondInTheSky);
            }
        }
        /// <summary>
        /// Plays the passed in set combination of "Sound Bank" and "Sound ID"
        /// </summary>
        private void Play_Sound_Bank_Internal(int BankID, int BankNumber)
        {
            // Standard protection from any game function calling shenanigans.
            // The way the game reads sound effects from the passed in register is... weird to say the least.
            try
            {
                // Convert the Sound Bank ID into Hexadecimal.
                string Sound_Bank_Hex = String.Format("{0:X2}", BankID);

                // Convert the Sound ID in the bank to Hexadecimal.
                string Sound_Bank_ID_Hex = String.Format("{0:X2}", BankNumber);

                // Bytes to be pushed onto the register as a method operand.
                string Bytes_To_Push;

                // If we are playing from Bank0, set the Bank ID to E0 (This is weird, lol), else reverse sound bank ID.
                if (Sound_Bank_Hex == "00")
                {
                    Bytes_To_Push = "E0" + Sound_Bank_ID_Hex;
                }
                else
                {
                    Bytes_To_Push = Sound_Bank_Hex.Reverse_String() + Sound_Bank_ID_Hex;
                }

                // If we are not in a level and want to use Bank5, do nothing, it is not loaded.
                if (Bytes_To_Push.StartsWith("50") && Program.Sonic_Heroes_Process.ReadMemory <byte>((IntPtr)SonicHeroesVariables.Game_CurrentState.CurrentlyInLevel, 1) == 0)
                {
                }
                else
                {
                    // Convert Hex String to Raw Hex.
                    int Sound_Parameter = Int32.Parse(Bytes_To_Push, System.Globalization.NumberStyles.HexNumber);

                    // Read unknown pointer.
                    int Sound_Pointer = Program.Sonic_Heroes_Process.ReadMemory <int>((IntPtr)0x00A2F8B0, 4);

                    // Play the Sound!
                    Invoke_External_Class.Play_Sound(Sound_Parameter, Sound_Pointer, 1, 1);
                }
            }
            catch { }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Loads a level with a specified ID into the game.
        /// </summary>
        public void Load_Level_ID(int LevelID)
        {
            // Write Passed in Level ID
            Program.Sonic_Heroes_Process.WriteMemory((IntPtr)SonicHeroesVariables.Stage_CurrentStage.PlayerStageIDToLoad, BitConverter.GetBytes(LevelID));
            Program.Sonic_Heroes_Process.WriteMemory((IntPtr)SonicHeroesVariables.Stage_CurrentStage.PlayerStageChoiceMainMenu, BitConverter.GetBytes(LevelID));

            // Check if in level.
            byte In_Level = Program.Sonic_Heroes_Process.ReadMemory <byte>((IntPtr)SonicHeroes.Variables.SonicHeroesVariables.Game_CurrentState.CurrentlyInLevel, 1);

            if (In_Level == 1)
            {
                // Secretly put us back in the main menu if we are in a stage.
                Invoke_External_Class.Exit_Stage_X();
                Menu_Enter_Hook_ASM.Activate();
                Menu_Enter_Hook.Activate();
            }
            else
            {
                Force_Load_Level_Method();
            }
        }
        /// <summary>
        /// Loads the currently set bank file at Tsonic_win.EXE+3873BC to act as character voices.
        /// </summary>
        private void Reload_Bank3_II()
        {
            // In the case the game function returns an unexpected value (it shouldn't).
            try
            {
                // Remove the onframe safety toggle.
                Program.Sonic_Heroes_Overlay.direct2DOnframeDelegate -= Reload_Bank3_II;

                // Convert desired track name to list of bytes.
                List <byte> TrackNameASCII = Encoding.ASCII.GetBytes("sound\\" + Get_Current_Bank3_PAC_Name()).ToList();

                // Add null terminator
                TrackNameASCII.Add(0x00);

                // Write bank name to memory.
                Program.Sonic_Heroes_Process.WriteMemory((IntPtr)FILE_BANK3_LOCATION_MEMORY, TrackNameASCII.ToArray());

                // Backup and remove check preventing a file to be loaded again.
                byte[] Backup_Array = Program.Sonic_Heroes_Process.ReadMemory((IntPtr)BRANCH_CHECK_DO_NOT_RELOAD_FILES, 6);

                // Remove the ASM check which prevents the game from reloading the Bank3 file.
                Program.Sonic_Heroes_Process.WriteMemory((IntPtr)BRANCH_CHECK_DO_NOT_RELOAD_FILES, new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 });

                // Retrieve the this* pointer that is to be passed to the method.
                int ProgramX = Program.Sonic_Heroes_Process.ReadMemory <int>((IntPtr)0x00A2F8B0, 4);

                // Load the sound bank into bank3 using C++ P/Invoke and Inline Assembly.
                Invoke_External_Class.Reload_Bank3(ProgramX);

                // Restore file reload branch instruction.
                Program.Sonic_Heroes_Process.WriteMemory((IntPtr)BRANCH_CHECK_DO_NOT_RELOAD_FILES, Backup_Array);
            }
            catch (Exception Ex)
            {
                // Send details of exception to the mod loader server.
                Program.Sonic_Heroes_Networking_Client.SendData_Alternate(Message_Type.Client_Call_Send_Message, Encoding.ASCII.GetBytes("[DEBUG] " + Program.Mod_Name + " | Reload Bank3 Function, Bank Utilities Class, Exception Thrown: " + Ex.Message), false);
            }
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Plays the currently selected ADX track. Calls C++ Function with our own pointer to the music track.
 /// </summary>
 public void Play_ADX_Track()
 {
     Invoke_External_Class.Play_Song(BGM_List[Current_ADX_Track].Song_Pointer);
 }
Ejemplo n.º 10
0
        static void Main()
        {
            try
            {
                // Set Culture
                System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
                CultureInfo.DefaultThreadCurrentCulture   = new CultureInfo("en-US");
                CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");

                ////////////// MOD LOADER DLL SKELETON CODE ///////////////////////////////////////////////////////////////////////////////////////////////////
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(SonicHeroes.Misc.SonicHeroes_Miscallenous.CurrentDomain_SetAssemblyResolve);
                Sonic_Heroes_Networking_Client.SetupClient(IPAddress.Loopback);                                                                                                            /// Set up networking with the Sonic Heroes Mod Loader.
                byte[] Response = Sonic_Heroes_Networking_Client.SendData_Alternate(Message_Type.Client_Call_Send_Message, Encoding.ASCII.GetBytes(Mod_Name + " | Loading... OK!"), true); /// Say to the Mod Loader that we have loaded so the end user can know.
                Sonic_Heroes_Process = Process.GetCurrentProcess();                                                                                                                        /// We will use this for reading and writing memory.
                ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                // Enable Aero Glass if Disabled
                // Check to see if composition is Enabled
                if (!Invoke_External_Class.DwmIsCompositionEnabled())
                {
                    Invoke_External_Class.DwmEnableComposition(true);
                }

                // Sets up DirectX & Direct2D
                Sonic_Heroes_Overlay = new SonicHeroes.Overlay.Overlay_External_Direct2D();
                Sonic_Heroes_Overlay.Initialize_DirectX();
                Sonic_Heroes_Overlay.direct2DRenderMethod = Draw_DirectX;
                Windows_Form_Thread = new Thread(() => { while (true)
                                                         {
                                                             Application.Run(Sonic_Heroes_Overlay.overlayWinForm);
                                                         }
                                                 });
                Windows_Form_Thread.Start();

                // Get Original OnFrame Controller Poll Instruction (Used for Controller Disabling)
                Original_Controller_Call_OnFrame = Sonic_Heroes_Process.ReadMemory((IntPtr)SonicHeroes_Functions.Controller_Polling_Functions.Master_Function_Control_OnFrame_Call, 5);

                // Initialize Controller
                Controller_Manager = new DirectInput_Joystick_Manager();

                // Initialize Thread to Update Controller Inputs.
                Heroes_Controller_Update_Thread = new Thread(() => {
                    while (true)
                    {
                        Controller_Poll_Method(); Thread.Sleep(16);
                    }
                }
                                                             );

                // Initialize Thread to Update GUI
                Heroes_GUI_Update_Thread = new Thread(() => {
                    while (true)
                    {
                        DirectX_Render_Method(); Thread.Sleep(16);
                    }
                });

                // Run the Two Individual Threads
                Heroes_GUI_Update_Thread.Start();
                Heroes_Controller_Update_Thread.Start();

                // Initialize Features
                Feature_PAC_Clip_Player_X               = new Feature_PAC_Utilities();
                Feature_Force_Load_Level_X              = new Feature_Force_Load_Level();
                Feature_ADX_Player_X                    = new Feature_ADX_Utilities();
                Feature_AFS_Utilities_X                 = new Feature_AFS_Utilities();
                Feature_Toggle_Character_Chatter_X      = new Feature_Toggle_Character_Chatter();
                Feature_Toggle_Music_OnPause_X          = new Feature_Toggle_Music_OnPause();
                Feature_Physics_Swapper_X               = new Feature_Physics_Swap();
                Feature_Magnetic_Barrier_X              = new Feature_Magnetic_Barrier();
                Feature_Party_Mode_X                    = new Feature_Party_Mode();
                Feature_Toggle_Moveset_Restrictions_X   = new Feature_Toggle_Moveset_Restrictions();
                Feature_Invisibility_Fixes_X            = new Feature_Invisbility_Fixes();
                Feature_Cycle_RGB_Colours_X             = new Feature_Cycle_RGB_Colours();
                Feature_Minimal_HUD_X                   = new Feature_Minimal_HUD();
                Feature_Trail_Editor_X                  = new Feature_Trail_Editor();
                Feature_Toggle_Super_Metal_Characters_X = new Feature_Toggle_Super_Metal_Characters();
                Feature_Position_XYZ_Window_X           = new Feature_Position_XYZ_Window();
                Feature_Enhanced_Debug_Movement_Mode_X  = new Feature_Enhanced_Debug_Movement_Mode();
                Feature_Set_Editor_X                    = new Feature_SET_Editor();
                Feature_Enhanced_FOV_Fix_X              = new Feature_Enhanced_FOV_Fix();
                Feature_Enhanced_FOV_Fix_X.Button_Set_FOV_Aspect_Ratio_Fix();

                // Initialize Menus
                Menu_Main            = new Menu_Main_Menu();
                Menu_Sound_Test      = new Menu_Sound_Test();
                Menu_Graphics_Tweaks = new Menu_Graphics_Tweaks();
                Menu_Trail_Editor    = new Menu_Trail_Editor();
                Menu_Miscallenous    = new Menu_Misc_Menu();
                Menu_Moveset_Tweaks  = new Menu_Moveset_Tweaks();
                Menu_Experiments     = new Menu_Experiments();
                Menu_Gameplay_Items  = new Menu_Gameplay_Items();
                Menu_Physics_Swapper = new Menu_Physics_Swapper();
                Menu_Debug_Stuff     = new Menu_Debug_Stuff();
                Menu_HUD_Adjustments = new Menu_HUD_Adjustments();

                // Set the current startup menu.
                Current_Menu = Menu_Main;

                // Load Station Square
                Feature_Toggle_Character_Chatter_X.Toggle_CharacterChatter();
                Feature_Toggle_Character_Chatter_X.Toggle_CharacterCommentChatter();
            }
            catch (Exception Ex) { Sonic_Heroes_Networking_Client.SendData_Alternate(Message_Type.Client_Call_Send_Message, Encoding.ASCII.GetBytes(Mod_Name + " Failed To Load: " + Ex.Message + " | " + Ex.StackTrace), false); }
        }