Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overlays and the Ingame API #836

Draft
wants to merge 38 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4b8f333
overlay(windows): Initial tests using kaku injection
chyyran Jan 26, 2022
3134ddb
kaku: update kaku
chyyran Jan 27, 2022
898cd81
overlay: very experimental imgui hoverlay for dx9
chyyran Jan 29, 2022
a6127ac
overlay: dx11 hook POC
chyyran Jan 30, 2022
60c18f8
overlay(cef): Host CEF as a module
chyyran Jan 30, 2022
eae1f5a
overlay(ipc): sketch out rough IPC protocol over named pipes
chyyran Jan 30, 2022
32187ae
orchestration(GameEmulation): Add GUID as part of the instance proper…
chyyran Jan 30, 2022
2ed932e
overlay(ipc): move to a multi-tab model to allow for instances to hav…
chyyran Jan 30, 2022
2e4f509
overlay(ipc): allow broadcast to all open pipes
chyyran Jan 31, 2022
b744b8a
orchestration(ingame): Move renderer IPC into ingame API
chyyran Jan 31, 2022
93c4b44
overlay(render): finish dx11 drawing of texture
chyyran Feb 1, 2022
9a5bfbd
ingame(hook): Start IPC server ingame
chyyran Feb 1, 2022
48b516e
ingame(ipc): Fix synchronization issues by requiring client to initia…
chyyran Feb 2, 2022
e1308a2
ingame(runtime): fetch texture from shared memory
chyyran Feb 2, 2022
968f4bc
overlay(render): I have no clue why its not working please...
chyyran Feb 5, 2022
8e1d4bd
overlay(render): set imgui uv coords
chyyran Feb 5, 2022
b403fbf
overlay(render): fix viewport
chyyran Feb 6, 2022
bd1e1f4
ipc(renderer): Use ComPtr wrapper
chyyran Feb 6, 2022
112250a
ingame(hook): use more ComPtr to avoid leaks
chyyran Feb 6, 2022
d582b4d
impl(comptr): Use ComPtr for more stuff
chyyran Feb 6, 2022
63df820
doc(comptr): document comptr
chyyran Feb 6, 2022
ef4d5a8
ingame(overlay): abstract dx11 texture handling
chyyran Feb 7, 2022
bbaf8fe
overlay(imgui): abstract imgui
chyyran Feb 7, 2022
7807698
overlay(dx11): move resize logic into Present hook
chyyran Feb 7, 2022
27acd23
runtime(chore): cleanup old code
chyyran Feb 8, 2022
33f49d6
overlay(ogl): hook ogl
chyyran Feb 8, 2022
a02b180
ipc(renderer): hook ogl and some cleanup
chyyran Feb 11, 2022
60bc5a1
imgui: cleanup to use ImGui.NET
chyyran Feb 14, 2022
056ff00
opengl: try to get this to work?
chyyran Feb 14, 2022
941f5f5
overlay: fix params, try to get GL working again
chyyran Feb 16, 2022
a3f3de2
overlay(ogl): set proper size for memory handle import
chyyran Feb 16, 2022
de37509
overlay(ogl): Get ImGui reinit working
chyyran Feb 17, 2022
5e14228
debug: temporarily copy over input backend from ImGuiScene. Itll do f…
chyyran Feb 17, 2022
04f7ddd
overlay(vk): vulkan hook POC
chyyran Feb 18, 2022
55e7dc9
cef: fix Size message and prevent double-resize of textures
chyyran Mar 17, 2022
e2f5177
runtime(vk): preliminary vulkan hook
chyyran Mar 17, 2022
f94b617
runtime: remove runtime in favour of https://github.com/SnowflakePowe…
chyyran Mar 17, 2022
bb0dd64
sln: remove imguibackends reference
chyyran Mar 18, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/Snowflake.Bootstrap.Windows/Program.cs
Expand Up @@ -3,12 +3,27 @@

class Program
{
private static SnowflakeShell snowflakeShell;

static void Main(string[] args)
{
Console.WriteLine("Starting Shell...");
var snowflakeShell = new SnowflakeShell();
AppDomain.CurrentDomain.ProcessExit += ExitHandler;
Program.snowflakeShell = new SnowflakeShell();
snowflakeShell.StartCore();
while (Console.ReadLine() != "exit") ;

Console.WriteLine("Shutting down...");
snowflakeShell.ShutdownCore();

}

private static void ExitHandler(object sender, EventArgs e)
{
Console.WriteLine("Shutting down due to force exit...");
if (!snowflakeShell.IsShutdown)
{
snowflakeShell.ShutdownCore();
}
}
}
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RuntimeIdentifiers>win-x64;win10-x64;</RuntimeIdentifiers>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 4 additions & 0 deletions src/Snowflake.Bootstrap.Windows/SnowflakeShell.cs
Expand Up @@ -19,6 +19,8 @@ internal class SnowflakeShell

private IServiceContainer loadedCore;

public bool IsShutdown { get; private set; } = false;

internal SnowflakeShell()
{
}
Expand All @@ -35,12 +37,14 @@ public void RestartCore()
{
this.ShutdownCore();
this.StartCore();
this.IsShutdown = false;
}

public void ShutdownCore()
{
this.loadedCore.Dispose();
GC.WaitForPendingFinalizers();
this.IsShutdown = true;
}
}
}
Expand Up @@ -16,6 +16,11 @@ namespace Snowflake.Orchestration.Extensibility
/// </summary>
public interface IGameEmulation
{
/// <summary>
/// A unique ID used to identify this emulation instance.
/// </summary>
Guid Guid { get; }

/// <summary>
/// A list of <see cref="IEmulatedController"/> that representes the input devices that will be used
/// in this emulation instance.
Expand Down
@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Snowflake.Orchestration.Ingame
{

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CursorEventParams
{
public Cursor Cursor;
}

/// <summary>
/// Cursor types. These are the same as CefSharp cursors
/// </summary>
public enum Cursor : byte
{
Pointer = 0,
Cross,
Hand,
IBeam,
Wait,
Help,
EastResize,
NorthResize,
NortheastResize,
NorthwestResize,
SouthResize,
SoutheastResize,
SouthwestResize,
WestResize,
NorthSouthResize,
EastWestResize,
NortheastSouthwestResize,
NorthwestSoutheastResize,
ColumnResize,
RowResize,
MiddlePanning,
EastPanning,
NorthPanning,
NortheastPanning,
NorthwestPanning,
SouthPanning,
SoutheastPanning,
SouthwestPanning,
WestPanning,
Move,
VerticalText,
Cell,
ContextMenu,
Alias,
Progress,
NoDrop,
Copy,
None,
NotAllowed,
ZoomIn,
ZoomOut,
Grab,
Grabbing,
MiddlePanningVertical,
MiddlePanningHorizontal,
Custom,
DndNone,
DndMove,
DndCopy,
DndLink
}
}
@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Snowflake.Orchestration.Ingame
{


[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct GameWindowCommand
{
public const byte GameWindowMagic = 0x9F;

[FieldOffset(0)] public byte Magic;
[FieldOffset(1)] public GameWindowCommandType Type;
[FieldOffset(2)] public HandshakeEventParams HandshakeEvent;
[FieldOffset(2)] public WindowResizeEventParams ResizeEvent;
[FieldOffset(2)] public WindowMessageEventParams WindowMessageEvent;
[FieldOffset(2)] public MouseEventParams MouseEvent;
[FieldOffset(2)] public CursorEventParams CursorEvent;
[FieldOffset(2)] public OverlayTextureEventParams TextureEvent;

public ReadOnlyMemory<byte> ToBuffer()
{
return StructUtils.ToMemory(this);
}

public bool IntoBuffer(ref Span<byte> buffer)
{
return StructUtils.IntoSpan(this, ref buffer);
}

public static GameWindowCommand? FromBuffer(ReadOnlyMemory<byte> buffer)
{
return StructUtils.FromSpan<GameWindowCommand>(buffer);
}

public static GameWindowCommand Handshake(Guid id)
{
return new()
{
Magic = GameWindowMagic,
Type = GameWindowCommandType.Handshake,
HandshakeEvent = new()
{
Guid = id,
}
};
}

private static class StructUtils
{
public static unsafe ReadOnlyMemory<byte> ToMemory<T>(T value) where T : unmanaged
{
byte* pointer = (byte*)&value;

Memory<byte> _bytes = new byte[Marshal.SizeOf<GameWindowCommand>()];
Span<byte> bytes = _bytes.Span;

for (int i = 0; i < sizeof(T); i++)
{
bytes[i] = pointer[i];
}

return _bytes;
}

public static unsafe bool IntoSpan<T>(T value, ref Span<byte> bytes) where T : unmanaged
{
if (bytes.Length != Marshal.SizeOf<GameWindowCommand>())
return false;

byte* pointer = (byte*)&value;
for (int i = 0; i < sizeof(T); i++)
{
bytes[i] = pointer[i];
}
return true;
}

public static unsafe T? FromSpan<T>(ReadOnlyMemory<byte> value) where T : unmanaged
{
if (value.Length != Marshal.SizeOf<T>())
{
Console.WriteLine("Expected size " + Marshal.SizeOf<T>() + " but got " + value.Length);
return null;
}

return MemoryMarshal.Cast<byte, T>(value.Span)[0];
}
}
}
}
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Snowflake.Orchestration.Ingame
{
public enum GameWindowCommandType : byte
{
Handshake = 1,
WindowResizeEvent = 2,
WindowMessageEvent = 3,
MouseEvent = 4,
CursorEvent = 5,
OverlayTextureEvent = 6,
ShutdownEvent = 7,
}
}
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Snowflake.Orchestration.Ingame
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct HandshakeEventParams
{
public Guid Guid;
}
}
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Snowflake.Orchestration.Ingame
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MouseEventParams
{
public MouseButton MouseDoubleClick;

public MouseButton MouseDown;
public MouseButton MouseUp;
public ModifierKeys Modifiers;

public float MouseX;
public float MouseY;
public float WheelX;
public float WheelY;
}

[Flags]
public enum ModifierKeys : byte
{
None = 0,
Shift = 1 << 0,
Control = 1 << 1,
Alt = 1 << 2
}

[Flags]
public enum MouseButton : byte
{
None = 0,
Mouse1 = 1 << 0,
Mouse2 = 1 << 1,
Mouse3 = 1 << 2,
Mouse4 = 1 << 3,
Mouse5 = 1 << 4
}
}
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Snowflake.Orchestration.Ingame
{

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct OverlayTextureEventParams
{
public nint TextureHandle;
public int SourceProcessId;
public uint Width;
public uint Height;
public ulong Size;
public ulong Alignment;
public nint SyncHandle;
}
}
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Snowflake.Orchestration.Ingame
{

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct WindowMessageEventParams
{
public int Message;
public ulong WParam;
public int LParam;
}
}
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Snowflake.Orchestration.Ingame
{

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct WindowResizeEventParams
{
public int Height;
public int Width;
public byte Force;
}
}
Expand Up @@ -6,6 +6,7 @@
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
<_SnowflakeUseDevelopmentSDK>true</_SnowflakeUseDevelopmentSDK>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
Expand Down