Skip to content

Commit

Permalink
load gamecontrollerdb.txt if it exists; add ability to load them manu…
Browse files Browse the repository at this point in the history
…ally
  • Loading branch information
NoelFB committed Feb 12, 2024
1 parent 71cd134 commit 444dd3b
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 18 deletions.
7 changes: 6 additions & 1 deletion Framework/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,14 @@ public static void Run(string applicationName, int width, int height, bool fulls

MainThreadID = Thread.CurrentThread.ManagedThreadId;

// toggle fulscreen flag
if (fullscreen)
flags |= Platform.FosterFlags.Fullscreen;

// run the application
var name = Platform.ToUTF8(applicationName);
title = applicationName;
Name = applicationName;
var name = Platform.ToUTF8(applicationName);

Platform.FosterStartup(new()
{
Expand All @@ -327,6 +329,9 @@ public static void Run(string applicationName, int width, int height, bool fulls
UserPath = Platform.ParseUTF8(Platform.FosterGetUserPath());
Graphics.Initialize();

// load default input mappings if they exist
Input.AddDefaultSdlGamepadMappings(AppContext.BaseDirectory);

// Clear Time
Time.Frame = 0;
Time.Duration = new();
Expand Down
66 changes: 50 additions & 16 deletions Framework/Input/Input.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.ObjectModel;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;

namespace Foster.Framework;

Expand Down Expand Up @@ -51,30 +52,42 @@ public static class Input
/// </summary>
public static float RepeatInterval = 0.03f;

/// <summary>
///
/// </summary>
public delegate void TextInputHandler(char value);

/// <summary>
/// Called whenever keyboard text is typed
/// </summary>
public static event TextInputHandler? OnTextEvent;

internal static readonly List<WeakReference<VirtualButton>> virtualButtons = new List<WeakReference<VirtualButton>>();
/// <summary>
/// Holds references to all Virtual Buttons so they can be updated.
/// </summary>
internal static readonly List<WeakReference<VirtualButton>> virtualButtons = [];

/// <summary>
/// Run at the beginning of a frame to step the input state.
/// After this, the Application will poll the platform for more inputs, which call back
/// to the various Input.On internal methods.
/// Loads 'gamecontrollerdb.txt' from a local file or falls back to the
/// default embedded SDL gamepad mappings
/// </summary>
internal static void Step()
internal static void AddDefaultSdlGamepadMappings(string relativePath)
{
LastState.Copy(State);
State.Copy(nextState);
nextState.Step();
var path = Path.Combine(relativePath, "gamecontrollerdb.txt");
if (File.Exists(path))
AddSdlGamepadMappings(File.ReadAllLines(path));
}

for (int i = virtualButtons.Count - 1; i >= 0; i--)
{
var button = virtualButtons[i];
if (button.TryGetTarget(out var target))
target.Update();
else
virtualButtons.RemoveAt(i);
}
/// <summary>
/// Loads a list of SDL Gamepad Mappings.
/// You can find more information here: https://github.com/mdqinc/SDL_GameControllerDB
/// By default, any 'gamecontrollerdb.txt' found adjacent to the application at runtime
/// will be loaded automatically.
/// </summary>
public static void AddSdlGamepadMappings(string[] mappings)
{
foreach (var mapping in mappings)
Platform.SDL_GameControllerAddMapping(mapping);
}

/// <summary>
Expand All @@ -94,6 +107,27 @@ public static string GetClipboardString()
return Platform.ParseUTF8(ptr);
}

/// <summary>
/// Run at the beginning of a frame to step the input state.
/// After this, the Application will poll the platform for more inputs, which call back
/// to the various Input.On internal methods.
/// </summary>
internal static void Step()
{
LastState.Copy(State);
State.Copy(nextState);
nextState.Step();

for (int i = virtualButtons.Count - 1; i >= 0; i--)
{
var button = virtualButtons[i];
if (button.TryGetTarget(out var target))
target.Update();
else
virtualButtons.RemoveAt(i);
}
}

private static unsafe void OnText(IntPtr cstr)
{
byte* ptr = (byte*)cstr;
Expand Down
5 changes: 5 additions & 0 deletions Framework/Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,11 @@ static unsafe Platform()
public static extern void FosterDraw(ref FosterDrawCommand command);
[DllImport(DLL)]
public static extern void FosterClear(ref FosterClearCommand command);

// Non-Foster Calls:

[DllImport(DLL, CharSet = CharSet.Ansi)]
public static extern int SDL_GameControllerAddMapping(string mappingString);

// [DllImport(DLL)]
// public static extern void emscripten_set_main_loop(IntPtr action, int fps, bool simulateInfiniteLoop);
Expand Down
Binary file modified Platform/libs/lib64/libFosterPlatform.so
Binary file not shown.
2 changes: 1 addition & 1 deletion Platform/src/foster_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ void FosterStartup(FosterDesc desc)
SDL_SetHint(SDL_HINT_WINDOWS_DPI_AWARENESS, "permonitorv2");

// use physical button layout, not labels
SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0");
SDL_SetHintWithPriority(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0", SDL_HINT_OVERRIDE);

// by default allow controller presses while unfocused, let game decide if it should handle them
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
Expand Down

0 comments on commit 444dd3b

Please sign in to comment.