Compare commits

..

No commits in common. "9a6a6079d4430a3ebed8f45bece559d1517e67e2" and "7810086348207af489a2afbd75278a1ab89f3d7e" have entirely different histories.

29 changed files with 73 additions and 177 deletions

View File

@ -1,19 +0,0 @@
# Sticky Viewer
A simple XInput input viewer designed for fightsticks. Appears always-on-top.
Currently, configuration is quite limited. Check ROADMAP.md for planned updates. Most notably, exactly five remappable buttons ~~and only left and right stick directions~~ are supported right now, because I play Fantasy Strike and that was my priority. :P **UPDATE: we got all nine valid stick positions babey**
To remap buttons, open sticky_viewer.exe.config and modify the values there. If the configuration file is missing at runtime, the values used in the unmodified file are the defaults.
## Screenshots
No inputs held:
![fightstick with no inputs held](https://i.imgur.com/TcLUlLw.png)
All buttons held and stick held left:
![fightstick with all buttons held and stick held left](https://i.imgur.com/GkvcVxI.png)
The images composing the stick and button visuals are provided and can be customized. If they're missing at runtime, these defaults are used.

View File

@ -1,40 +0,0 @@
# Roadmap
These are the plans for what I want to be customizable via .config modification and supplying custom images.
## Visual Customization
### Buttons
- How many buttons are visible ☐
- Position of buttons ☐
- Which hardware button is mapped to which visible button 🗹
- Pressed and unpressed images of buttons 🗹
- Override images for specific buttons ☐
- e.g. something like this:
![overriding a specific button image with a custom one](https://i.imgur.com/QU5pTDm.png)
### Stick
- Choose between left analog, right analog or d-pad ☐
- How the stick looks 🗹
- Position of stick ☐
- Hitbox mode ☐
- Could be implemented by allowing you to turn off stick display and just adding more buttons, I guess
- Analog directions would have to be made valid button inputs, but I'm already doing something like that for LT and RT
### Window
- Location (support both x/y coords and something like BOTTOM_MIDDLE, TOP_LEFT) ☐
- Width and height ☐
- Background (support both RGBA colour and a supplied image) ☐
## Misc
- Optionally assign "close" keybind to a combination of stick buttons ☐
- Choose an XInput device instead of defaulting to whichever one is considered player 1 🗹
- ~~"Press Start" prompt if ambiguous, save to config file?~~
- Every frame, just use the controller with the lowest index and any input
- Keybinds to generate .config file and default images in execution folder ☐
- This would allow the distribution of just the .exe file. If someone wishes to customize, those default resources could be generated from the program

View File

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 16
VisualStudioVersion = 16.0.29326.143 VisualStudioVersion = 16.0.29326.143
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sticky_viewer", "sticky_viewer\sticky_viewer.csproj", "{7D0FEB20-AB4F-4E57-AD69-CC88D4423F53}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "input_display", "input_display\input_display.csproj", "{7D0FEB20-AB4F-4E57-AD69-CC88D4423F53}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -1,14 +1,13 @@
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Configuration; using System.Configuration;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace sticky_viewer namespace input_display
{ {
/// <summary> /// <summary>
/// Access functionality from user32.dll /// Access functionality from user32.dll
@ -32,12 +31,6 @@ namespace sticky_viewer
private Texture2D pressed; private Texture2D pressed;
private Texture2D unpressed; private Texture2D unpressed;
private Texture2D upleft;
private Texture2D up;
private Texture2D upright;
private Texture2D downleft;
private Texture2D down;
private Texture2D downright;
private Texture2D left; private Texture2D left;
private Texture2D neutral; private Texture2D neutral;
private Texture2D right; private Texture2D right;
@ -48,6 +41,7 @@ namespace sticky_viewer
private Texture2D C; private Texture2D C;
private Texture2D J; private Texture2D J;
private Texture2D S; private Texture2D S;
public Display() public Display()
{ {
graphics = new GraphicsDeviceManager(this); graphics = new GraphicsDeviceManager(this);
@ -72,27 +66,6 @@ namespace sticky_viewer
base.Initialize(); base.Initialize();
} }
Stream GetStreamFromFileOrAssembly(Assembly assembly, string s)
{
try
{
return new FileStream($"{s}.png", FileMode.Open);
}
catch
{
// uh oh,! time to panic
return assembly.GetManifestResourceStream(assembly.GetName().Name.Replace(' ', '_') + $".Content.{s}.png");
}
}
Texture2D GetTexture(Assembly assembly, string s)
{
using (Stream stream = GetStreamFromFileOrAssembly(assembly, s))
{
return Texture2D.FromStream(GraphicsDevice, stream);
}
}
/// <summary> /// <summary>
/// LoadContent will be called once per game and is the place to load /// LoadContent will be called once per game and is the place to load
/// all of your content. /// all of your content.
@ -112,20 +85,66 @@ namespace sticky_viewer
// default images // default images
Assembly assembly = Assembly.GetExecutingAssembly(); Assembly assembly = Assembly.GetExecutingAssembly();
pressed = GetTexture(assembly, "pressed"); Stream dataStream = assembly.GetManifestResourceStream(assembly.GetName().Name.Replace(' ', '_') + ".Content.left.png");
unpressed = GetTexture(assembly, "unpressed"); left = Texture2D.FromStream(GraphicsDevice, dataStream);
upleft = GetTexture(assembly, "upleft"); dataStream.Dispose();
up = GetTexture(assembly, "up");
upright = GetTexture(assembly, "upright"); dataStream = assembly.GetManifestResourceStream(assembly.GetName().Name.Replace(' ', '_') + ".Content.neutral.png");
left = GetTexture(assembly, "left"); neutral = Texture2D.FromStream(GraphicsDevice, dataStream);
neutral = GetTexture(assembly, "neutral"); dataStream.Dispose();
right = GetTexture(assembly, "right");
downleft = GetTexture(assembly, "downleft"); dataStream = assembly.GetManifestResourceStream(assembly.GetName().Name.Replace(' ', '_') + ".Content.right.png");
down = GetTexture(assembly, "down"); right = Texture2D.FromStream(GraphicsDevice, dataStream);
downright = GetTexture(assembly, "downright"); dataStream.Dispose();
dataStream = assembly.GetManifestResourceStream(assembly.GetName().Name.Replace(' ', '_') + ".Content.pressed.png");
pressed = Texture2D.FromStream(GraphicsDevice, dataStream);
dataStream.Dispose();
dataStream = assembly.GetManifestResourceStream(assembly.GetName().Name.Replace(' ', '_') + ".Content.unpressed.png");
unpressed = Texture2D.FromStream(GraphicsDevice, dataStream);
dataStream.Dispose();
// Create a new SpriteBatch, which can be used to draw textures. // Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice); spriteBatch = new SpriteBatch(GraphicsDevice);
// If an image file exists, replace the one in memory with it
FileStream fileStream;
if (File.Exists("pressed.png"))
{
fileStream = new FileStream("pressed.png", FileMode.Open);
pressed = Texture2D.FromStream(GraphicsDevice, fileStream);
fileStream.Dispose();
}
if (File.Exists("unpressed.png"))
{
fileStream = new FileStream("unpressed.png", FileMode.Open);
unpressed = Texture2D.FromStream(GraphicsDevice, fileStream);
fileStream.Dispose();
}
if (File.Exists("left.png"))
{
fileStream = new FileStream("left.png", FileMode.Open);
left = Texture2D.FromStream(GraphicsDevice, fileStream);
fileStream.Dispose();
}
if (File.Exists("neutral.png"))
{
fileStream = new FileStream("neutral.png", FileMode.Open);
neutral = Texture2D.FromStream(GraphicsDevice, fileStream);
fileStream.Dispose();
}
if (File.Exists("right.png"))
{
fileStream = new FileStream("right.png", FileMode.Open);
right = Texture2D.FromStream(GraphicsDevice, fileStream);
fileStream.Dispose();
}
} }
/// <summary> /// <summary>
@ -149,53 +168,19 @@ namespace sticky_viewer
Exit(); Exit();
} }
// Find the controller being used currently if (GamePad.GetState(PlayerIndex.One).DPad.Left == ButtonState.Pressed)
GamePadState emptyInput = new GamePadState();
GamePadState currentState = new GamePadState();
foreach (PlayerIndex p in Enum.GetValues(typeof(PlayerIndex)))
{
if ((currentState = GamePad.GetState(p)) != emptyInput) { break; }
}
GamePadDPad dpad = currentState.DPad;
if (dpad.Up == ButtonState.Pressed && dpad.Left == ButtonState.Pressed)
{
stick = upleft;
}
else if (dpad.Up == ButtonState.Pressed && dpad.Right == ButtonState.Pressed)
{
stick = upright;
}
else if (dpad.Up == ButtonState.Pressed)
{
stick = up;
}
else if (dpad.Down == ButtonState.Pressed && dpad.Left == ButtonState.Pressed)
{
stick = downleft;
}
else if (dpad.Down == ButtonState.Pressed && dpad.Right == ButtonState.Pressed)
{
stick = downright;
}
else if (dpad.Down == ButtonState.Pressed)
{
stick = down;
}
else if (dpad.Left == ButtonState.Pressed)
{ {
stick = left; stick = left;
} } else if (GamePad.GetState(PlayerIndex.One).DPad.Right == ButtonState.Pressed)
else if (dpad.Right == ButtonState.Pressed)
{ {
stick = right; stick = right;
} } else
else
{ {
stick = neutral; stick = neutral;
} }
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
Dictionary<string, bool> inputs = new Dictionary<string, bool>() Dictionary<string, bool> inputs = new Dictionary<string, bool>()
{ {
{"A", currentState.Buttons.A == ButtonState.Pressed}, {"A", currentState.Buttons.A == ButtonState.Pressed},
@ -227,7 +212,7 @@ namespace sticky_viewer
spriteBatch.Begin(); spriteBatch.Begin();
spriteBatch.Draw(stick, new Vector2(21, 16), Color.White); spriteBatch.Draw(stick, new Vector2(16, 24), Color.White);
spriteBatch.Draw(A, new Vector2(96, 11), Color.White); spriteBatch.Draw(A, new Vector2(96, 11), Color.White);
spriteBatch.Draw(B, new Vector2(128, 6), Color.White); spriteBatch.Draw(B, new Vector2(128, 6), Color.White);
spriteBatch.Draw(C, new Vector2(161, 6), Color.White); spriteBatch.Draw(C, new Vector2(161, 6), Color.White);

View File

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 167 KiB

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -1,6 +1,6 @@
using System; using System;
namespace sticky_viewer namespace input_display
{ {
#if WINDOWS || LINUX #if WINDOWS || LINUX
/// <summary> /// <summary>

View File

@ -5,8 +5,8 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("Sticky Viewer")] [assembly: AssemblyTitle("input display")]
[assembly: AssemblyProduct("Sticky Viewer")] [assembly: AssemblyProduct("input display")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="sticky_viewer"/> <assemblyIdentity version="1.0.0.0" name="input_display"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security> <security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">

View File

@ -10,8 +10,8 @@
<ProjectGuid>{7D0FEB20-AB4F-4E57-AD69-CC88D4423F53}</ProjectGuid> <ProjectGuid>{7D0FEB20-AB4F-4E57-AD69-CC88D4423F53}</ProjectGuid>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>sticky_viewer</RootNamespace> <RootNamespace>input_display</RootNamespace>
<AssemblyName>sticky_viewer</AssemblyName> <AssemblyName>input_display</AssemblyName>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<MonoGamePlatform>Windows</MonoGamePlatform> <MonoGamePlatform>Windows</MonoGamePlatform>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
@ -57,30 +57,6 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ContentWithTargetPath Include="Content\upleft.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>upleft.png</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Content\up.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>up.png</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Content\upright.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>upright.png</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Content\downleft.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>downleft.png</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Content\down.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>down.png</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Content\downright.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>downright.png</TargetPath>
</ContentWithTargetPath>
<ContentWithTargetPath Include="Content\left.png"> <ContentWithTargetPath Include="Content\left.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>left.png</TargetPath> <TargetPath>left.png</TargetPath>
@ -116,12 +92,6 @@
<EmbeddedResource Include="Content\unpressed.png"> <EmbeddedResource Include="Content\unpressed.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory> <CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Content\down.png" />
<EmbeddedResource Include="Content\downleft.png" />
<EmbeddedResource Include="Content\downright.png" />
<EmbeddedResource Include="Content\up.png" />
<EmbeddedResource Include="Content\upleft.png" />
<EmbeddedResource Include="Content\upright.png" />
<Content Include="Icon.ico" /> <Content Include="Icon.ico" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB