diff --git a/GGXrdWakeupDPUtil.sln b/GGXrdWakeupDPUtil.sln
new file mode 100644
index 0000000..e38b604
--- /dev/null
+++ b/GGXrdWakeupDPUtil.sln
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26430.12
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GGXrdWakeupDPUtil", "GGXrdWakeupDPUtil\GGXrdWakeupDPUtil.csproj", "{22A91F28-F083-4E8D-95B4-D084781033C4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Debug|x64.ActiveCfg = Debug|x64
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Debug|x64.Build.0 = Debug|x64
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Debug|x86.ActiveCfg = Debug|x86
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Debug|x86.Build.0 = Debug|x86
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Release|x64.ActiveCfg = Release|x64
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Release|x64.Build.0 = Release|x64
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Release|x86.ActiveCfg = Release|x86
+ {22A91F28-F083-4E8D-95B4-D084781033C4}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/GGXrdWakeupDPUtil/App.config b/GGXrdWakeupDPUtil/App.config
new file mode 100644
index 0000000..88fa402
--- /dev/null
+++ b/GGXrdWakeupDPUtil/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GGXrdWakeupDPUtil/App.xaml b/GGXrdWakeupDPUtil/App.xaml
new file mode 100644
index 0000000..732b32b
--- /dev/null
+++ b/GGXrdWakeupDPUtil/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/GGXrdWakeupDPUtil/App.xaml.cs b/GGXrdWakeupDPUtil/App.xaml.cs
new file mode 100644
index 0000000..7770abf
--- /dev/null
+++ b/GGXrdWakeupDPUtil/App.xaml.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace GGXrdWakeupDPUtil
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+
+ }
+}
diff --git a/GGXrdWakeupDPUtil/Fasm.NET.xml b/GGXrdWakeupDPUtil/Fasm.NET.xml
new file mode 100644
index 0000000..3a28ccf
--- /dev/null
+++ b/GGXrdWakeupDPUtil/Fasm.NET.xml
@@ -0,0 +1,337 @@
+
+
+
+ "Fasm.NET"
+
+
+
+
+Gets the mnemonics.
+
+
+
+
+Inserts the text representation of the specified array of objects, followed by the current line terminator at the specified character position.
+
+ The position in this instance where insertion begins.
+ The composite format string.
+ The array of objects to write using format.
+
+Inserts the text representation of the specified array of objects, followed by the current line terminator at the specified character position.
+
+ The position in this instance where insertion begins.
+ The composite format string.
+ The array of objects to write using format.
+
+
+
+Removes all characters from the current instance.
+
+
+Removes all characters from the current instance.
+
+
+
+
+Assembles the mnemonics with a given origin address.
+
+ The address used as starting address for the assebmly code.
+
+Assembles the mnemonics with a given origin address.
+
+ The address used as starting address for the assebmly code.
+
+
+
+Assembles the mnemonics.
+
+
+Assembles the mnemonics.
+
+
+
+
+Adds the text representation of the specified array of objects, followed by the current line terminator.
+
+ The composite format string.
+ The array of objects to write using format.
+
+Adds the text representation of the specified array of objects, followed by the current line terminator.
+
+ The composite format string.
+ The array of objects to write using format.
+
+
+
+Initializes a new instance of the class.
+
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+Initializes a new instance of the class.
+
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+
+
+Initializes a new instance of the class.
+
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+Initializes a new instance of the class.
+
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+
+
+Assembles the specified files by appending them.
+
+ The path of the files to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+Assembles the specified files by appending them.
+
+ The path of the files to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+
+
+Assembles the specified files by appending them.
+
+ The path of the files to assemble.
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+Assembles the specified files by appending them.
+
+ The path of the files to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+
+
+Assembles the specified file.
+
+ The path of the file to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+Assembles the specified file.
+
+ The path of the file to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+
+
+Assembles the specified file.
+
+ The path of the file to assemble.
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+Assembles the specified file.
+
+ The path of the file to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+
+
+Assembles the given mnemonics.
+
+ The array containing mnemonics to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+Assembles the given mnemonics.
+
+ The array containing mnemonics to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+
+
+Assembles the given mnemonics.
+
+ The array containing mnemonics to assemble.
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+Assembles the given mnemonics.
+
+ The array containing mnemonics to assemble.
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+
+
+Assembles the given mnemonics.
+
+ The mnemonics to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+Assembles the given mnemonics.
+
+ The mnemonics to assemble.
+ The memory size allocated for the buffer.
+ The maximum number of pass to perform.
+
+
+
+Assembles the given mnemonics.
+
+ The mnemonics to assemble.
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+Assembles the given mnemonics.
+
+ The mnemonics to assemble.
+ The default memory size used is 4096 bytes and the maximum number of pass is 100.
+
+
+
+Gets the version of FASM compiler.
+
+
+Gets the version of FASM compiler.
+
+
+
+
+The maximum number of pass to perform.
+
+
+
+
+The memory size allocated for the buffer.
+
+
+
+
+The mnemonics inserted by the user.
+
+
+
+
+The managed wrapper to interfact with FASM compiler.
+
+
+
+
+The following structure resides at the beginning of memory block provided
+to the fasm_Assemble function. The condition field contains the same value
+as the one returned by function.
+
+When function returns FASM_OK condition, the output_length and
+output_data fields are filled - with pointer to generated output
+(somewhere within the provided memory block) and the count of bytes stored
+there.
+
+When function returns FASM_ERROR, the error_code is filled with the
+code of specific error that happened and error_line is a pointer to the
+LINE_HEADER structure, providing information about the line that caused
+the error.
+
+
+
+
+The following structure has two variants - it either defines the line
+that was loaded directly from source, or the line that was generated by
+macroinstruction. First case has the highest bit of line_number set to 0,
+while the second case has this bit set.
+
+In the first case, the file_path field contains pointer to the path of
+source file (empty string if it's the source that was provided directly to
+fasm_Assemble function), the line_number is the number of line within
+that file (starting from 1) and the file_offset field contains the offset
+within the file where the line starts.
+
+In the second case the macro_calling_line field contains the pointer to
+LINE_HEADER structure for the line which called the macroinstruction, and
+the macro_line field contains the pointer to LINE_HEADER structure for the
+line within the definition of macroinstruction, which generated this one.
+
+
+
+
+The native function to get the version of FASM compiler embedded in Fasm.obj.
+
+ The return valus is a double word containg major version in lower 16 bits, and minor version in the higher 16 bits.
+
+
+
+Initializes a new instance of the class.
+
+ The error code.
+ The line where is the error.
+ The offset within the file where the line starts.
+ The assembled mnemonics when the error occurred.
+
+Initializes a new instance of the class.
+
+ The error code.
+ The line where is the error.
+ The offset within the file where the line starts.
+ The assembled mnemonics when the error occurred.
+
+
+
+The assembled mnemonics when the error occurred.
+
+
+
+
+The offset within the file where the line starts.
+
+
+
+
+The line where is the error.
+
+
+
+
+The error code.
+
+
+
+
+The private field containing the assembled mnemonics when the error occurred.
+
+
+
+
+The private field containing the offset within the file where the line starts.
+
+
+
+
+The private field containing the line where is the error.
+
+
+
+
+The private field containing the error code.
+
+
+
+
+The exception that is thrown when a FASM compiler error occurs.
+
+
+
+
+The enumeration containing all errors of FASM compiler.
+
+
+
+
+The enumeration containing all results of FASM compiler.
+
+
+
+
+
\ No newline at end of file
diff --git a/GGXrdWakeupDPUtil/GGXrdWakeupDPUtil.csproj b/GGXrdWakeupDPUtil/GGXrdWakeupDPUtil.csproj
new file mode 100644
index 0000000..a075ae3
--- /dev/null
+++ b/GGXrdWakeupDPUtil/GGXrdWakeupDPUtil.csproj
@@ -0,0 +1,178 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {22A91F28-F083-4E8D-95B4-D084781033C4}
+ WinExe
+ GGXrdWakeupDPUtil
+ GGXrdWakeupDPUtil
+ v4.5.2
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ true
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ bin\x86\Release\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+ ..\packages\Fasm.NET.1.70.03\lib\Fasm.NET.dll
+
+
+ False
+ ..\..\..\..\..\Downloads\Frida.dll
+
+
+ ..\packages\MemorySharp.1.2.0\lib\MemorySharp.dll
+
+
+
+
+
+
+
+
+
+
+ 4.0
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ App.xaml
+ Code
+
+
+ MainWindow.xaml
+ Code
+
+
+
+
+ Code
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4.5.2 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
\ No newline at end of file
diff --git a/GGXrdWakeupDPUtil/MainWindow.xaml b/GGXrdWakeupDPUtil/MainWindow.xaml
new file mode 100644
index 0000000..ac17dc8
--- /dev/null
+++ b/GGXrdWakeupDPUtil/MainWindow.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GGXrdWakeupDPUtil/MainWindow.xaml.cs b/GGXrdWakeupDPUtil/MainWindow.xaml.cs
new file mode 100644
index 0000000..37646a9
--- /dev/null
+++ b/GGXrdWakeupDPUtil/MainWindow.xaml.cs
@@ -0,0 +1,524 @@
+using Binarysharp.MemoryManagement;
+using Binarysharp.MemoryManagement.Windows;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace GGXrdWakeupDPUtil
+{
+ public class NameWakeupData
+ {
+ public String charName { get; }
+ public int faceUpFrames { get; }
+ public int faceDownFrames { get; }
+ public NameWakeupData(string cn, int fu, int fd)
+ {
+ charName = cn;
+ faceUpFrames = fu;
+ faceDownFrames = fd;
+ }
+ }
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ const int P2IDOffset = 0x1BDCE08;
+ private List P1AnimOffsets = new List { 0x1674508, 0x28, 0xD8, 0x4A8, 0x490, 0x484, 0x244C };
+ private List P1AnimOffsets_fallback = new List { 0x0167EFCC, 0x370, 0xE4, 0x414, 0x4C, 0x484, 0x244C };
+ private List P2AnimOffsets = new List { 0x1674574, 0x28, 0xD8, 0x4A8, 0x494, 0x484, 0x244C };
+ private List P2AnimOffsets_fallback = new List { 0x016775F4, 0x2D8, 0xD8, 0x4A8, 0x494, 0x484, 0x244C };
+ private List P1P2FlipOffsets = new List { 0x16DF5FC, 0x5A8, 0x42C, 0x34C ,0x18 ,0x400 };
+ const int frameCounterOffset = 0x1BD2F6C;
+ const int recordingSlotOneOffset = 0x1AC5F58;
+ const int recordingSlotSize = 4808;
+ const int recFlagOffset = 0x1BD17C0;
+ const int playbackFrameCountOffset = 0x1BD438C;
+ public MemorySharp msggprocess = null;
+ public List nameWakeupDataList = new List
+ {
+ new NameWakeupData("Sol", 25, 21),
+ new NameWakeupData("Ky", 23, 21),
+ new NameWakeupData("May", 25, 22),
+ new NameWakeupData("Millia", 25, 23),
+ new NameWakeupData("Zato", 25, 22),
+ new NameWakeupData("Potemkin", 24, 22),
+ new NameWakeupData("Chipp", 30, 24),
+ new NameWakeupData("Faust", 25, 29),
+ new NameWakeupData("Axl", 25, 21),
+ new NameWakeupData("Venom", 21, 26),
+ new NameWakeupData("Slayer", 26, 20),
+ new NameWakeupData("I-No", 24, 20),
+ new NameWakeupData("Bedman", 24, 30),
+ new NameWakeupData("Ramlethal", 25, 23),
+ new NameWakeupData("Sin", 30, 21),
+ new NameWakeupData("Elphelt", 27, 27),
+ new NameWakeupData("Leo", 28, 26),
+ new NameWakeupData("Johnny", 25, 24),
+ new NameWakeupData("Jack-O'", 25, 23),
+ new NameWakeupData("Jam", 26, 25),
+ new NameWakeupData("Haehyun", 25, 27),
+ new NameWakeupData("Raven", 25, 24),
+ new NameWakeupData("Dizzy", 25, 24),
+ new NameWakeupData("Baiken", 22, 21),
+ new NameWakeupData("Answer", 24, 24)
+
+ };
+ private string ggprocname = "GuiltyGearXrd";
+ private string facedown = "CmnActFDown2Stand";
+ private string faceup = "CmnActBDown2Stand";
+ private const char frameDelimiter = ',';
+ private const char wakeupFrame = '!';
+ const int playbackFlag = 0x800;
+ const int recordFlip = 0;
+ Regex inputregex = new Regex(@"!?[1-9]{1}[PKSHD]{0,5}");
+ Regex whitespaceregex = new Regex(@"\s+");
+ int[] directions = new[] { 0b0110, 0b0010, 0b1010, 0b0100, 0b0000, 0b1000, 0b0101, 0b0001, 0b1001 };
+ Frida.DeviceManager devman;
+ Frida.Device localdev;
+ Frida.Process ggproc;
+ Frida.Script script;
+ Frida.Session session;
+ string scriptsrc = @"var xrdbase = Module.findBaseAddress('GuiltyGearXrd.exe');
+ var hookaddr = xrdbase.add(0xB83236);
+ var playingback = false;
+ var running = true;
+ Interceptor.attach(hookaddr, function(args){
+ if(playingback && this.context.edi.equals(ptr('3'))){
+ playingback = false;
+ this.context.ebp = ptr(Memory.readU32(this.context.edx).toString());
+ }
+ });
+ var quit = recv('quit', function (value) {
+ Interceptor.detachAll();
+ running = false;
+ });
+setTimeout( function () {
+ while (running){
+ var op = recv('playback', function (value) {
+ playingback=true;
+ });
+ op.wait();
+ }
+ }, 0);
+";
+ enum Buttons
+ {
+ P = 0x10,
+ K = 0x20,
+ S = 0x40,
+ H = 0x80,
+ D = 0x100
+ }
+ const int wakeupFrameMask = 0x200;
+ int currentDummyId;
+ public bool flip;
+ CancellationTokenSource source, idsource;
+ CancellationToken token, idtoken;
+ private bool fallbackp1 = false;
+ private bool fallbackp2 = false;
+ private short singleInputParse(string input)
+ {
+ if (inputregex.IsMatch(input))
+ {
+ var result = 0;
+ if (input[0] == '!')
+ {
+ result += wakeupFrameMask;
+ input = input.Substring(1);
+ }
+ var direction = Int32.Parse(input.Substring(0, 1));
+ result |= directions[direction - 1];
+ if (input.Length == 1)
+ {
+ return (short)result;
+ }
+ var buttons = input.Substring(1).ToCharArray();
+ foreach (char button in buttons)
+ {
+ switch (button)
+ {
+ case 'P':
+ result |= (int)Buttons.P;
+ break;
+ case 'K':
+ result |= (int)Buttons.K;
+ break;
+ case 'S':
+ result |= (int)Buttons.S;
+ break;
+ case 'H':
+ result |= (int)Buttons.H;
+ break;
+ case 'D':
+ result |= (int)Buttons.D;
+ break;
+ }
+ }
+ return (short)result;
+ } else
+ {
+ return -1;
+ }
+ }
+ public MainWindow()
+ {
+ InitializeComponent();
+ DataContext = this;
+ Loaded += new RoutedEventHandler(MainWindow_Loaded);
+ Closed += MainWindow_Closed;
+ }
+
+ private void MainWindow_Closed(object sender, EventArgs e)
+ {
+ if (source != null && !source.IsCancellationRequested)
+ {
+ source.Cancel();
+ }
+ if (idsource != null && !idsource.IsCancellationRequested)
+ {
+ idsource.Cancel();
+ }
+ if (session != null)
+ {
+ session.Detach();
+ }
+ }
+
+ private void MainWindow_Loaded(object sender, RoutedEventArgs e)
+ {
+ if (System.Diagnostics.Process.GetProcessesByName(ggprocname).Length > 0)
+ {
+ msggprocess = new MemorySharp(System.Diagnostics.Process.GetProcessesByName(ggprocname).First());
+ try
+ {
+ readAnimString(1);
+
+ }
+ catch (Exception)
+ {
+ try
+ {
+ readFallbackAnimString(1);
+ fallbackp1 = true;
+ }
+ catch (Exception)
+ {
+ MessageBox.Show("You have GG open but are not in training mode! Open it up and pause the game before starting this program. This program will now close.");
+ Application.Current.Shutdown();
+ return;
+ }
+ }
+ try
+ {
+ readAnimString(2);
+
+ }
+ catch (Exception)
+ {
+ try
+ {
+ readFallbackAnimString(2);
+ fallbackp2 = true;
+ }
+ catch (Exception)
+ {
+ MessageBox.Show("You have GG open but are not in training mode! Open it up and pause the game before starting this program. This program will now close.");
+ Application.Current.Shutdown();
+ return;
+ }
+ }
+ setDummyID();
+ }
+ else
+ {
+ MessageBox.Show("Guilty Gear not found open! Remember, be in training mode paused when you open this program. This program will now close.");
+ Application.Current.Shutdown();
+ return;
+ }
+ devman = new Frida.DeviceManager(Dispatcher);
+ localdev = null;
+ foreach (Frida.Device d in devman.EnumerateDevices())
+ {
+ if (d.Type == Frida.DeviceType.Local)
+ {
+ localdev = d;
+ break;
+ }
+ }
+ if(localdev == null)
+ {
+ MessageBox.Show("Local device not found. This application will now close.");
+ Application.Current.Shutdown();
+ return;
+ }
+ ggproc = null;
+ foreach (Frida.Process p in localdev.EnumerateProcesses())
+ {
+ if(p.Pid == msggprocess.Pid)
+ {
+ ggproc = p;
+ break;
+ }
+ }
+ if(ggproc == null)
+ {
+ MessageBox.Show("Guilty Gear not found open! Remember, be in training mode paused when you open this program.");
+ Application.Current.Shutdown();
+ return;
+ }
+
+ idsource = new CancellationTokenSource();
+ idtoken = idsource.Token;
+ setDummyID();
+ Task.Run(() => updateIDLoop());
+ }
+
+ private void Script_Message(object sender, Frida.ScriptMessageEventArgs e)
+ {
+ var senderscript = (Frida.Script)sender;
+ MessageBox.Show(e.Message);
+ }
+
+ private void updateIDLoop()
+ {
+ while (!idtoken.IsCancellationRequested)
+ {
+ if(msggprocess.Read((IntPtr)P2IDOffset) != currentDummyId)
+ {
+ setDummyID();
+ }
+ Thread.Sleep(500);
+ }
+ }
+
+ private string readAnimString(int player)
+ {
+ if (player == 1) {
+ var addr = (IntPtr)(msggprocess.Read((IntPtr)P1AnimOffsets[0]));
+ foreach (int offset in P1AnimOffsets.GetRange(1, 5)) {
+ addr = IntPtr.Add(addr, offset);
+ addr = (IntPtr)msggprocess.Read(addr, false);
+ }
+ return msggprocess.ReadString(IntPtr.Add(addr, P1AnimOffsets[6]), false, 32);
+ }
+ if (player == 2)
+ {
+ var addr = (IntPtr)(msggprocess.Read((IntPtr)P2AnimOffsets[0]));
+ foreach (int offset in P2AnimOffsets.GetRange(1, 5))
+ {
+ addr = IntPtr.Add(addr, offset);
+ addr = (IntPtr)msggprocess.Read(addr, false);
+ }
+ return msggprocess.ReadString(IntPtr.Add(addr, P2AnimOffsets[6]), false, 32);
+ }
+ return "";
+ }
+ private string readFallbackAnimString(int player)
+ {
+ if (player == 1)
+ {
+ var addr = (IntPtr)(msggprocess.Read((IntPtr)P1AnimOffsets_fallback[0]));
+ foreach (int offset in P1AnimOffsets_fallback.GetRange(1, 5))
+ {
+ addr = IntPtr.Add(addr, offset);
+ addr = (IntPtr)msggprocess.Read(addr, false);
+ }
+ return msggprocess.ReadString(IntPtr.Add(addr, P1AnimOffsets_fallback[6]), false, 32);
+ }
+ if (player == 2)
+ {
+ var addr = (IntPtr)(msggprocess.Read((IntPtr)P2AnimOffsets_fallback[0]));
+ foreach (int offset in P2AnimOffsets_fallback.GetRange(1, 5))
+ {
+ addr = IntPtr.Add(addr, offset);
+ addr = (IntPtr)msggprocess.Read(addr, false);
+ }
+ return msggprocess.ReadString(IntPtr.Add(addr, P2AnimOffsets_fallback[6]), false, 32);
+ }
+ return "";
+ }
+ private void setDummyID()
+ {
+ var idx = msggprocess.Read((IntPtr)P2IDOffset);
+ try
+ {
+ dummyTextBlock.Text = dummyTextBlock.Text.Split(':')[0] + ": " + nameWakeupDataList[idx].charName;
+ } catch (IndexOutOfRangeException)
+ {
+ MessageBox.Show("Yell at Labryz for 'royally fucking up the id offset'. This application will now close.");
+ Application.Current.Shutdown();
+ return;
+ }
+ currentDummyId = idx;
+ }
+ private void enableButton_Click(object sender, RoutedEventArgs e)
+ {
+ var text = inputTextBox.Text;
+ text = whitespaceregex.Replace(text, "");
+ string[] splittext = text.Split(new char[] { frameDelimiter });
+ List inputnums = new List { };
+ foreach (string inputstr in splittext)
+ {
+ inputnums.Add(singleInputParse(inputstr));
+ if (inputnums.Last() < 0)
+ {
+ MessageBox.Show("Invalid input with input '" + inputstr + "'. Read the README for formatting information.");
+ return;
+ }
+ }
+ var ggwindow = msggprocess.Windows.MainWindow;
+ var wakeupframeidx = inputnums.FindLastIndex(delegate (short n)
+ {
+ return n >= 0x200;
+ });
+ if (wakeupframeidx < 0)
+ {
+ MessageBox.Show("No ! frame specified. See the readme for more information.");
+ return;
+ }
+ inputnums[wakeupframeidx] -= wakeupFrameMask;
+ var slotidx = -1;
+ if ((bool)Slot1R.IsChecked)
+ {
+ slotidx = 0;
+ } else if ((bool)Slot2R.IsChecked)
+ {
+ slotidx = 1;
+ }
+ else if ((bool)Slot3R.IsChecked)
+ {
+ slotidx = 2;
+ }
+ if (slotidx >= 0)
+ {
+ overwriteSlot(slotidx, inputnums);
+ } else
+ {
+ MessageBox.Show("No slot chosen. Please make sure you picked a slot to overwrite.");
+ return;
+ }
+ enableButton.IsEnabled = false;
+ Slot1R.IsEnabled = false;
+ Slot2R.IsEnabled = false;
+ Slot3R.IsEnabled = false;
+ disableButton.IsEnabled = true;
+ session = localdev.Attach((uint)msggprocess.Pid);
+ script = session.CreateScript(scriptsrc);
+ script.Message += Script_Message;
+ script.Load();
+ ggwindow.Activate();
+ source = new CancellationTokenSource();
+ token = source.Token;
+ Task.Run(() => enableLoop(fallbackp2, wakeupframeidx));
+
+ }
+ private void setFlip()
+ {
+ var addr = (IntPtr)(msggprocess.Read((IntPtr)P1P2FlipOffsets[0]));
+ foreach (int offset in P1P2FlipOffsets.GetRange(1, 4))
+ {
+ addr = IntPtr.Add(addr, offset);
+ addr = (IntPtr)msggprocess.Read(addr, false);
+ }
+ flip = msggprocess.Read(IntPtr.Add(addr, P1P2FlipOffsets[5]), false) == 0;
+
+ }
+ private void overwriteSlot(int slotidx, List inputs)
+ {
+ var addr = recordingSlotOneOffset + recordingSlotSize * slotidx;
+ var header = new List {0, 0, (short)inputs.Count, 0 };
+ msggprocess.Write((IntPtr)addr, header.Concat(inputs).ToArray());
+ }
+ private void enableLoop(bool useFallback, int wakeupframeidx)
+ {
+ idsource.Cancel();
+ if (useFallback)
+ {
+ while (!token.IsCancellationRequested)
+ {
+ int wakeuptiming = 0;
+ if (facedown == readFallbackAnimString(2))
+ {
+ wakeuptiming = nameWakeupDataList[currentDummyId].faceDownFrames;
+ Task framewait = Task.Run(() => waitFrames(wakeuptiming - wakeupframeidx - 1));
+ framewait.Wait();
+ }
+ else if (faceup == readFallbackAnimString(2))
+ {
+ wakeuptiming = nameWakeupDataList[currentDummyId].faceUpFrames;
+ Task framewait = Task.Run(() => waitFrames(wakeuptiming - wakeupframeidx - 1));
+ framewait.Wait();
+ }
+ if (wakeuptiming == 0)
+ {
+ continue;
+ }
+ else
+ {
+ script.Post("{\"type\": \"playback\"}");
+ }
+ }
+ }
+ else
+ {
+ while (!token.IsCancellationRequested)
+ {
+ int wakeuptiming = 0;
+ if (facedown == readAnimString(2))
+ {
+ wakeuptiming = nameWakeupDataList[currentDummyId].faceDownFrames;
+ Task framewait = Task.Run(() => waitFrames(wakeuptiming - wakeupframeidx - 1));
+ framewait.Wait();
+ }
+ else if (faceup == readAnimString(2))
+ {
+ wakeuptiming = nameWakeupDataList[currentDummyId].faceUpFrames;
+ Task framewait = Task.Run(() => waitFrames(wakeuptiming - wakeupframeidx - 1));
+ framewait.Wait();
+ }
+ if (wakeuptiming == 0)
+ {
+ continue;
+ }
+ else
+ {
+ script.Post("{\"type\": \"playback\"}");
+ }
+ }
+ }
+ idsource = new CancellationTokenSource();
+ idtoken = idsource.Token;
+ }
+
+
+
+ private void waitFrames(int frames)
+ {
+ int fc = msggprocess.Read((IntPtr)frameCounterOffset);
+ while(msggprocess.Read((IntPtr)frameCounterOffset) < fc + frames && !token.IsCancellationRequested)
+ {
+
+ }
+ }
+ private void disableButton_Click(object sender, RoutedEventArgs e)
+ {
+ source.Cancel();
+ source.Dispose();
+ script.Post("{\"type\": \"quit\"}");
+ script.Unload();
+ session.Detach();
+ enableButton.IsEnabled = true;
+ Slot1R.IsEnabled = true;
+ Slot2R.IsEnabled = true;
+ Slot3R.IsEnabled = true;
+ disableButton.IsEnabled = false;
+ }
+
+
+ }
+}
diff --git a/GGXrdWakeupDPUtil/Properties/AssemblyInfo.cs b/GGXrdWakeupDPUtil/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..ec109e7
--- /dev/null
+++ b/GGXrdWakeupDPUtil/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GGXrdWakeupDPUtil")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GGXrdWakeupDPUtil")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/GGXrdWakeupDPUtil/Properties/Resources.Designer.cs b/GGXrdWakeupDPUtil/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..f0776fa
--- /dev/null
+++ b/GGXrdWakeupDPUtil/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace GGXrdWakeupDPUtil.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GGXrdWakeupDPUtil.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/GGXrdWakeupDPUtil/Properties/Resources.resx b/GGXrdWakeupDPUtil/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/GGXrdWakeupDPUtil/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/GGXrdWakeupDPUtil/Properties/Settings.Designer.cs b/GGXrdWakeupDPUtil/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..4b65455
--- /dev/null
+++ b/GGXrdWakeupDPUtil/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace GGXrdWakeupDPUtil.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/GGXrdWakeupDPUtil/Properties/Settings.settings b/GGXrdWakeupDPUtil/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/GGXrdWakeupDPUtil/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GGXrdWakeupDPUtil/packages.config b/GGXrdWakeupDPUtil/packages.config
new file mode 100644
index 0000000..b0bb9f1
--- /dev/null
+++ b/GGXrdWakeupDPUtil/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file