Compare commits
No commits in common. "9a6a6079d4430a3ebed8f45bece559d1517e67e2" and "7810086348207af489a2afbd75278a1ab89f3d7e" have entirely different histories.
9a6a6079d4
...
7810086348
19
README.md
|
|
@ -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:
|
||||
|
||||

|
||||
|
||||
All buttons held and stick held left:
|
||||
|
||||

|
||||
|
||||
The images composing the stick and button visuals are provided and can be customized. If they're missing at runtime, these defaults are used.
|
||||
40
ROADMAP.md
|
|
@ -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:
|
||||
|
||||

|
||||
|
||||
### 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
|
||||
|
|
@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29326.143
|
||||
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
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
|
@ -1,14 +1,13 @@
|
|||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace sticky_viewer
|
||||
namespace input_display
|
||||
{
|
||||
/// <summary>
|
||||
/// Access functionality from user32.dll
|
||||
|
|
@ -32,12 +31,6 @@ namespace sticky_viewer
|
|||
private Texture2D pressed;
|
||||
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 neutral;
|
||||
private Texture2D right;
|
||||
|
|
@ -48,6 +41,7 @@ namespace sticky_viewer
|
|||
private Texture2D C;
|
||||
private Texture2D J;
|
||||
private Texture2D S;
|
||||
|
||||
public Display()
|
||||
{
|
||||
graphics = new GraphicsDeviceManager(this);
|
||||
|
|
@ -72,27 +66,6 @@ namespace sticky_viewer
|
|||
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>
|
||||
/// LoadContent will be called once per game and is the place to load
|
||||
/// all of your content.
|
||||
|
|
@ -112,20 +85,66 @@ namespace sticky_viewer
|
|||
// default images
|
||||
Assembly assembly = Assembly.GetExecutingAssembly();
|
||||
|
||||
pressed = GetTexture(assembly, "pressed");
|
||||
unpressed = GetTexture(assembly, "unpressed");
|
||||
upleft = GetTexture(assembly, "upleft");
|
||||
up = GetTexture(assembly, "up");
|
||||
upright = GetTexture(assembly, "upright");
|
||||
left = GetTexture(assembly, "left");
|
||||
neutral = GetTexture(assembly, "neutral");
|
||||
right = GetTexture(assembly, "right");
|
||||
downleft = GetTexture(assembly, "downleft");
|
||||
down = GetTexture(assembly, "down");
|
||||
downright = GetTexture(assembly, "downright");
|
||||
Stream dataStream = assembly.GetManifestResourceStream(assembly.GetName().Name.Replace(' ', '_') + ".Content.left.png");
|
||||
left = Texture2D.FromStream(GraphicsDevice, dataStream);
|
||||
dataStream.Dispose();
|
||||
|
||||
dataStream = assembly.GetManifestResourceStream(assembly.GetName().Name.Replace(' ', '_') + ".Content.neutral.png");
|
||||
neutral = Texture2D.FromStream(GraphicsDevice, dataStream);
|
||||
dataStream.Dispose();
|
||||
|
||||
dataStream = assembly.GetManifestResourceStream(assembly.GetName().Name.Replace(' ', '_') + ".Content.right.png");
|
||||
right = Texture2D.FromStream(GraphicsDevice, dataStream);
|
||||
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.
|
||||
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>
|
||||
|
|
@ -149,53 +168,19 @@ namespace sticky_viewer
|
|||
Exit();
|
||||
}
|
||||
|
||||
// Find the controller being used currently
|
||||
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)
|
||||
if (GamePad.GetState(PlayerIndex.One).DPad.Left == ButtonState.Pressed)
|
||||
{
|
||||
stick = left;
|
||||
}
|
||||
else if (dpad.Right == ButtonState.Pressed)
|
||||
} else if (GamePad.GetState(PlayerIndex.One).DPad.Right == ButtonState.Pressed)
|
||||
{
|
||||
stick = right;
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
stick = neutral;
|
||||
}
|
||||
|
||||
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
|
||||
|
||||
Dictionary<string, bool> inputs = new Dictionary<string, bool>()
|
||||
{
|
||||
{"A", currentState.Buttons.A == ButtonState.Pressed},
|
||||
|
|
@ -227,7 +212,7 @@ namespace sticky_viewer
|
|||
|
||||
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(B, new Vector2(128, 6), Color.White);
|
||||
spriteBatch.Draw(C, new Vector2(161, 6), Color.White);
|
||||
|
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 167 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace sticky_viewer
|
||||
namespace input_display
|
||||
{
|
||||
#if WINDOWS || LINUX
|
||||
/// <summary>
|
||||
|
|
@ -5,8 +5,8 @@ using System.Runtime.InteropServices;
|
|||
// 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("Sticky Viewer")]
|
||||
[assembly: AssemblyProduct("Sticky Viewer")]
|
||||
[assembly: AssemblyTitle("input display")]
|
||||
[assembly: AssemblyProduct("input display")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
|
|
@ -10,8 +10,8 @@
|
|||
<ProjectGuid>{7D0FEB20-AB4F-4E57-AD69-CC88D4423F53}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>sticky_viewer</RootNamespace>
|
||||
<AssemblyName>sticky_viewer</AssemblyName>
|
||||
<RootNamespace>input_display</RootNamespace>
|
||||
<AssemblyName>input_display</AssemblyName>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<MonoGamePlatform>Windows</MonoGamePlatform>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
|
|
@ -57,30 +57,6 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</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">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<TargetPath>left.png</TargetPath>
|
||||
|
|
@ -116,12 +92,6 @@
|
|||
<EmbeddedResource Include="Content\unpressed.png">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</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" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 7.0 KiB |