About the new frontend in development ...
Forum rules
Keep it classy!
Keep it classy!
- No ROM requests or links.
- Do not ask to be a play tester.
- Do not ask about release dates.
- No drama!
About the new frontend in development ...
Hi everyone,
It's the new frontend i am developing right now.
I've studied C# from the beginning and try my best to develop it as possible. I know i am in a very slow pace, wish you guys will like it when I finish.
Here is what I did so far. Enjoy.
https://www.youtube.com/watch?v=OGzriGmIZ6E
It's the new frontend i am developing right now.
I've studied C# from the beginning and try my best to develop it as possible. I know i am in a very slow pace, wish you guys will like it when I finish.
Here is what I did so far. Enjoy.
https://www.youtube.com/watch?v=OGzriGmIZ6E
Re: About the new frontend in development ...
This looks really nice. Beautiful, simple, sleek aesthetic.
Supermodel has needed a good UI for a while now.
Great work.
You must have done some sort of coding before ?
Supermodel has needed a good UI for a while now.
Great work.
You must have done some sort of coding before ?
aka rokfpoewrkcpoqwkcp
- Masked Ninja
- Posts: 9
- Joined: Sat Nov 11, 2023 9:48 pm
Re: About the new frontend in development ...
It looks great, please make sure you add all the commands.
Thank you so much...![Very Happy :D](./images/smilies/icon_e_biggrin.gif)
Thank you so much...
![Very Happy :D](./images/smilies/icon_e_biggrin.gif)
Re: About the new frontend in development ...
I will implement all config parameters such as -true-hz- of the latest version Supermodel for sure.
What I am struggling right now is the keys/buttons/joystick mapping UI, and wish I can find a best way to finish it ASAP.
What I am struggling right now is the keys/buttons/joystick mapping UI, and wish I can find a best way to finish it ASAP.
Re: About the new frontend in development ...
I've used SharpDX (and SharpDX.XInput and SharpDX.DirectInput) in the past to capture inputs. Though now 'archived', it may still be useful or lead you in the right direction.
If you'd like any help with the project, feel free to DM me. You can keep 100% of the credit for the project. Makes no matter to me.
![Very Happy :D](./images/smilies/icon_e_biggrin.gif)
![Wink ;)](./images/smilies/icon_e_wink.gif)
Re: About the new frontend in development ...
Hi, Viking245,Viking245 wrote: ↑Mon Jan 22, 2024 2:13 pmI've used SharpDX (and SharpDX.XInput and SharpDX.DirectInput) in the past to capture inputs. Though now 'archived', it may still be useful or lead you in the right direction.
If you'd like any help with the project, feel free to DM me. You can keep 100% of the credit for the project. Makes no matter to me.(I did try to DM you, but 'lurkers' aren't allowed.
)
Nice to meet you here. It is very welcome to invite you to join the new frontend project's development, and I believe we can finish the project sooner with your great help.
I've tried SharpDX.XInput in the development and get the inputs successfully. What I am confused is how to map the naming in SharpDX.Xinput or Dinput to the Suerpmodel's naming. For example, in Supermodel "JOY1_BUTTON1" to SharpDX's names, especially there are more than only 1 joystick connected.
I am thinking if you can develop a C# class with method which will return the user's input name once a time and I will implement other UI and Key mapping stuff for each game. Or you can give me other suggestion will be great.
Thank you.
Following are the source codes that I've written for Joystick input testing UI.
======================================================================================
using System;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Timer = System.Windows.Forms.Timer;
using System.Drawing.Drawing2D;
using SharpDX.XInput;
using SharpDX.DirectInput;
using SharpDX.Mathematics.Interop;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;
namespace SuperM3UI
{
public partial class FormControlTest : Form
{
private Timer updateTimer;
private Controller controller;
int JStickPos;
int JStickPos_pre;
int shiftX = 120;
int shiftY = 120;
int shiftUR = 84;
int ballPosX = 220;
int ballPosY = 170;
Bitmap myBitmap;
Rectangle expansionRectangle;
public Image sourceImage;
public FormControlTest()
{
InitializeComponent();
// Initialize Timer
updateTimer = new Timer();
updateTimer.Interval = 16; // every16ms, around 60fps
updateTimer.Tick += UpdateTimer_Tick;
// Intialize JStick Position on UI
JStickPos = 5;
JStickPos_pre = 5;
sourceImage = Image.FromFile(@"C:\Development\SuperM3UI\SuperM3UI\icons\sticks-ball-mid.png");
myBitmap = new Bitmap(@"C:\Development\SuperM3UI\SuperM3UI\icons\sticks-ball-mid.png");
// Initialize Xbox controller
controller = new Controller(UserIndex.One);
if (!controller.IsConnected)
{
MessageBox.Show("Xbox Controller is not connected。");
}
}
private void FormControlTest_Load(object sender, EventArgs e)
{
updateTimer.Start();
this.Location = new System.Drawing.Point(this.Location.X + 110, this.Location.Y + 65);
}
private void UpdateTimer_Tick(object sender, EventArgs e)
{
if (controller.IsConnected)
{
State st = controller.GetState();
//lb_PosX.Text = "Parent's X/Y =" + this.Parent.Location.X.ToString() + "//" + this.Parent.Location.Y.ToString();
//lb_PosY.Text = "It's X/Y =" + this.Location.X.ToString() + "//" + this.Location.Y.ToString();
// Checked buttons / joystick 's input
Boolean A_Btn_Now_pressed = ((st.Gamepad.Buttons & GamepadButtonFlags.A) != 0);
if (A_Btn_Now_pressed) { picBox_GreenBtnPress.Visible = true; } else { picBox_GreenBtnPress.Visible = false; }
//labelButton_A.Text = $"A Button: {A_Btn_Now_pressed}";
Boolean B_Btn_Now_pressed = ((st.Gamepad.Buttons & GamepadButtonFlags.B) != 0);
if (B_Btn_Now_pressed) { picBox_BlueBtnPress.Visible = true; } else { picBox_BlueBtnPress.Visible = false; }
//labelButton_B.Text = $"B Button: {(st.Gamepad.Buttons & GamepadButtonFlags.B) != 0}";
Boolean X_Btn_Now_pressed = ((st.Gamepad.Buttons & GamepadButtonFlags.X) != 0);
if (X_Btn_Now_pressed) { picBox_PinkBtnPress.Visible = true; } else { picBox_PinkBtnPress.Visible = false; }
//labelButton_X.Text = $"X Button: {(st.Gamepad.Buttons & GamepadButtonFlags.X) != 0}";
Boolean Y_Btn_Now_pressed = ((st.Gamepad.Buttons & GamepadButtonFlags.Y) != 0);
if (Y_Btn_Now_pressed) { picBox_RedBtnPress.Visible = true; } else { picBox_RedBtnPress.Visible = false; }
//labelButton_Y.Text = $"Y Button: {(st.Gamepad.Buttons & GamepadButtonFlags.Y) != 0}";
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadUp) != 0)
{
JStickPos = 8;
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadUp) != 0 && (st.Gamepad.Buttons & GamepadButtonFlags.DPadRight) != 0) JStickPos = 9;
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadUp) != 0 && (st.Gamepad.Buttons & GamepadButtonFlags.DPadLeft) != 0) JStickPos = 7;
}
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadDown) != 0)
{
JStickPos = 2;
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadDown) != 0 && (st.Gamepad.Buttons & GamepadButtonFlags.DPadRight) != 0) JStickPos = 3;
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadDown) != 0 && (st.Gamepad.Buttons & GamepadButtonFlags.DPadLeft) != 0) JStickPos = 1;
}
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadRight) != 0)
{
JStickPos = 6;
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadRight) != 0 && (st.Gamepad.Buttons & GamepadButtonFlags.DPadUp) != 0) JStickPos = 9;
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadRight) != 0 && (st.Gamepad.Buttons & GamepadButtonFlags.DPadDown) != 0) JStickPos = 3;
}
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadLeft) != 0)
{
JStickPos = 4;
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadLeft) != 0 && (st.Gamepad.Buttons & GamepadButtonFlags.DPadUp) != 0) JStickPos = 7;
if ((st.Gamepad.Buttons & GamepadButtonFlags.DPadLeft) != 0 && (st.Gamepad.Buttons & GamepadButtonFlags.DPadDown) != 0) JStickPos = 1;
}
if (((st.Gamepad.Buttons & GamepadButtonFlags.DPadLeft) == 0) && ((st.Gamepad.Buttons & GamepadButtonFlags.DPadRight) == 0)
&& ((st.Gamepad.Buttons & GamepadButtonFlags.DPadUp) == 0) && ((st.Gamepad.Buttons & GamepadButtonFlags.DPadDown) == 0))
{
JStickPos = 5;
}
if (JStickPos_pre != JStickPos) panel1.Invalidate();
JStickPos_pre = JStickPos;
}
}
private void FormControlTest_FormClosed(object sender, FormClosedEventArgs e)
{
updateTimer.Stop();
}
private void rjButton2_Click(object sender, EventArgs e)
{
this.Close();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics graphics = e.Graphics;
expansionRectangle = new Rectangle(ballPosX, ballPosY, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
// Draw a portion of the source image.
if (JStickPos == 1)
{
expansionRectangle = new Rectangle(ballPosX - shiftUR, ballPosY + shiftUR, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
graphics.DrawImage(myBitmap, expansionRectangle);
}
if (JStickPos == 2)
{
expansionRectangle = new Rectangle(ballPosX, ballPosY + shiftY, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
graphics.DrawImage(myBitmap, expansionRectangle);
}
if (JStickPos == 3)
{
expansionRectangle = new Rectangle(ballPosX + shiftUR, ballPosY + shiftUR, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
graphics.DrawImage(myBitmap, expansionRectangle);
}
if (JStickPos == 4)
{
expansionRectangle = new Rectangle(ballPosX - shiftX, ballPosY, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
graphics.DrawImage(myBitmap, expansionRectangle);
}
if (JStickPos == 5)
{
expansionRectangle = new Rectangle(ballPosX, ballPosY, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
graphics.DrawImage(myBitmap, expansionRectangle);
}
if (JStickPos == 6)
{
expansionRectangle = new Rectangle(ballPosX + shiftX, ballPosY, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
graphics.DrawImage(myBitmap, expansionRectangle);
}
if (JStickPos == 7)
{
expansionRectangle = new Rectangle(ballPosX - shiftUR, ballPosY - shiftUR, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
graphics.DrawImage(myBitmap, expansionRectangle);
}
if (JStickPos == 8)
{
expansionRectangle = new Rectangle(ballPosX, ballPosY - shiftY, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
graphics.DrawImage(myBitmap, expansionRectangle);
}
if (JStickPos == 9)
{
expansionRectangle = new Rectangle(ballPosX + shiftUR, ballPosY - shiftUR, myBitmap.Width * 14 / 10, myBitmap.Height * 14 / 10);
graphics.DrawImage(myBitmap, expansionRectangle);
}
}
}
}
======================================================================================
Re: About the new frontend in development ...
The video clip of my testing implement of Joystick input testing.
https://youtu.be/YXV8efEmFfk
However, it's a quite old version codes which I used C# Winforms and I am learning and using WPF to develop the new codes for much better outlook of the UI.
https://youtu.be/YXV8efEmFfk
However, it's a quite old version codes which I used C# Winforms and I am learning and using WPF to develop the new codes for much better outlook of the UI.
Re: About the new frontend in development ...
WPF will definitely look WAY better than WinForms.
![Wink ;)](./images/smilies/icon_e_wink.gif)
Say you ask the user to select an input for 'Player 1 - Coin'. This can trigger a Method that has a Do/While loop to wait for a controller Button press (or time out). The Method captures the input and returns the transposed value. i.e. they want to use the Back Buton. (truncated method)What I am confused is how to map the naming in SharpDX.Xinput or Dinput to the Suerpmodel's naming.
Edit: moved 'State st =' to inside do loop
Code: Select all
public string GetControllerInput()
{
TimeSpan timeout = TimeSpan.FromSeconds(5);
var stopwatch = Stopwatch.StartNew();
//State st = controller.GetState();
do
{
//needs to be inside do loop
State st = controller.GetState();
if ((st.Gamepad.Buttons & GamepadButtonFlags.Back) != 0)
{
return "KEY_1,JOY1_BUTTON7";
}
//... all other possible inputs
}
while (stopwatch.Elapsed < timeout);
return string.Empty;
}
Code: Select all
Controller controller1 = new Controller(UserIndex.One);
Controller controller2 = new Controller(UserIndex.Two);
Controller controller3 = new Controller(UserIndex.Three);
//.... etc.
Code: Select all
State st1 = controller1.GetState();
State st2 = controller2.GetState();
State st3 = controller3.GetState();
//...
if ((st1.Gamepad.Buttons & GamepadButtonFlags.Back) != 0)
{
return "KEY_1,JOY1_BUTTON7";
}
if ((st2.Gamepad.Buttons & GamepadButtonFlags.Back) != 0)
{
return "KEY_1,JOY2_BUTTON7";
}
//...
Code: Select all
string InputCoin1 = GetControllerInput();
if (InputCoin1 == string.Empty)
{
//do something to indicate there's no 'InputCoin1'
}
![Wink ;)](./images/smilies/icon_e_wink.gif)
Re: About the new frontend in development ...
Thanks for your great help and wonderful advice. It is very useful information for me.Viking245 wrote: ↑Wed Jan 24, 2024 1:45 pmWPF will definitely look WAY better than WinForms.Which Framework are you using?
I used the standard WPF for Microsoft in the beginning, but I changed to use Avalonia with MVVM community toolkit and rewrite everything now.
Say you ask the user to select an input for 'Player 1 - Coin'. This can trigger a Method that has a Do/While loop to wait for a controller Button press (or time out). The Method captures the input and returns the transposed value. i.e. they want to use the Back Buton. (truncated method)What I am confused is how to map the naming in SharpDX.Xinput or Dinput to the Suerpmodel's naming.
Edit: moved 'State st =' to inside do loop
To get Controller #2, #3 etc., probably need to declare all [possible] controllers.Code: Select all
public string GetControllerInput() { TimeSpan timeout = TimeSpan.FromSeconds(5); var stopwatch = Stopwatch.StartNew(); //State st = controller.GetState(); do { //needs to be inside do loop State st = controller.GetState(); if ((st.Gamepad.Buttons & GamepadButtonFlags.Back) != 0) { return "KEY_1,JOY1_BUTTON7"; } //... all other possible inputs } while (stopwatch.Elapsed < timeout); return string.Empty; }
Then in the above method, account for the 'possibilities'.Code: Select all
Controller controller1 = new Controller(UserIndex.One); Controller controller2 = new Controller(UserIndex.Two); Controller controller3 = new Controller(UserIndex.Three); //.... etc.
Then.. however you plan to 'ask the question', followed up withCode: Select all
State st1 = controller1.GetState(); State st2 = controller2.GetState(); State st3 = controller3.GetState(); //... if ((st1.Gamepad.Buttons & GamepadButtonFlags.Back) != 0) { return "KEY_1,JOY1_BUTTON7"; } if ((st2.Gamepad.Buttons & GamepadButtonFlags.Back) != 0) { return "KEY_1,JOY2_BUTTON7"; } //...
Hope that helps. Or at least gives you some momentum. This is just one way of doing it, as I'm sure there's at least 50 others.Code: Select all
string InputCoin1 = GetControllerInput(); if (InputCoin1 == string.Empty) { //do something to indicate there's no 'InputCoin1' }
![]()
However, I am so busy in working recently. I may restart to write new codes in Feb.
Keep in touch !!!