clean up and dynamically detecting multiple controllers

This commit is contained in:
Baipyrus 2023-03-28 11:06:24 +02:00
parent 3a9992befd
commit c69b48f6ae

View File

@ -1,16 +1,20 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Collections.Generic;
using rpi_rgb_led_matrix_sharp;
namespace RPI_Matrix {
public static class RPI_Matrix {
// Initialize variables
private static int debugIndex;
private static bool debugMenu, debugSelect;
private static List<string> gamepadListeners = new();
private static int selectionIndex, keypressFrame, frameCount;
private static bool hasSelected, isInGame, isTetris, isFlappy, isSnake;
private static bool selection = true, focusHeight, focusGravity, focusJump, isFocused;
private static int selectionIndex, keypressFrame, frameCount;
public static void Main(string[] args) {
// Connect to RGB LED Matrix
@ -30,8 +34,8 @@ namespace RPI_Matrix {
Tetris.Tetris.Init(matrix, canvas);
// Start listening and interpreting Gamepad input in parallel
(new Thread(InterpretGamepadInput)).Start();
new Thread(InterpretGamepadInput).Start();
// Initialize Text-Font and -Color
RGBLedFont font = new("fonts/9x18B.bdf");
Color col = new(255, 255, 255);
@ -234,10 +238,31 @@ namespace RPI_Matrix {
}
private static void InterpretGamepadInput() {
// Read file "/dev/input/js0" in Raspbian for Raspberry 4 4GB.
// Read file "/dev/input/js*" in Raspbian for Raspberry 4 4GB.
// All inputs on a Gamepad are accessible from within here.
// Interpreting this data may only work in this program using a SNES Controller.
FileInfo targetFile = new FileInfo("/dev/input/js0");
while (true) {
string dir = "/dev/input";
IEnumerable<string> files = from retrieved in Directory.EnumerateFiles(dir)
where retrieved.Contains("js")
select retrieved;
foreach (string f in files)
if (!gamepadListeners.Contains(f)) {
gamepadListeners.Add(f);
new Thread(() => {
try {
WatchInputFile(f);
} catch (Exception) {
gamepadListeners.Remove(f);
}
}).Start();
}
Thread.Sleep(500);
}
}
private static void WatchInputFile(string file) {
FileInfo targetFile = new FileInfo(file);
using FileStream fs = targetFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Initialize Buffer (byte Array) to put read bytes into
byte[] buffer = new byte[1024];
@ -251,155 +276,167 @@ namespace RPI_Matrix {
else if (isSnake && !SnakeGame.SnakeGame.gameOver)
SnakeGame.SnakeGame.keypressFrame = SnakeGame.SnakeGame.frameCount;
// Convert Buffer to Hexadecimal, each Byte separated by a '-'
switch (BitConverter.ToString(buffer, 4, 4)) {
case "01-00-01-00":
// Code for X-Button Press
if (isTetris)
Tetris.Tetris.swapMemory();
break;
case "01-00-01-01":
// Code for A-Button Press
// If not already in a Game, now ready up to select one.
if (!isInGame)
hasSelected = true;
// Select given option in Tetris' 'GameOver' Screen
else if (isSnake && SnakeGame.SnakeGame.selection)
SnakeGame.SnakeGame.enterSelection();
else if (isFlappy && FlappyBird.FlappyBird.selection)
FlappyBird.FlappyBird.enterSelection();
else if (isTetris && Tetris.Tetris.selection)
Tetris.Tetris.enterSelection();
else
debugSelect = true;
break;
case "01-00-01-02":
// Code for B-Button Press
if (isFlappy) {
// Jump
if (FlappyBird.FlappyBird.isReady)
FlappyBird.FlappyBird.JumpOnce();
// Start Game
else
FlappyBird.FlappyBird.isReady = true;
// Place the current Block in Tetris
} else if (isTetris)
Tetris.Tetris.placeDownBlock();
else if (!isSnake) {
focusGravity = false;
focusHeight = false;
focusJump = false;
isFocused = false;
}
break;
case "01-00-01-04":
// Code for L-Button Press
// If in Tetris, rotate the current Block counter-Clockwise
if (isTetris)
Tetris.Tetris.rotateCounterClockwise();
break;
case "01-00-01-05":
// Code for R-Button Press
// If in Tetris, rotate the current Block Clockwise
if (isTetris)
Tetris.Tetris.rotateClockwise();
break;
case "01-00-01-09":
// Code for Start-Button Press
// If in SnakeGame, end the Game and return to menu
if (isSnake)
SnakeGame.SnakeGame.EndGame();
else if (isFlappy) {
// If in FlappyBirds' 'ready' Screen, return to menu
if (!FlappyBird.FlappyBird.isReady)
FlappyBird.FlappyBird.stopPlaying = true;
// Otherwise go back to 'ready' Screen by ending the Game
else {
FlappyBird.FlappyBird.EndGame();
FlappyBird.FlappyBird.selection = false;
}
// If in Tetris, end the Game and return to menu
} else if (isTetris)
Tetris.Tetris.EndGame();
break;
case "01-80-02-01":
// Code for Arrow-Up Press
// If in the selection screen, decrement index
if (!isInGame && selectionIndex > 0)
selectionIndex--;
else if (isSnake) {
// Handle index in 'GameOver' Screen
if (SnakeGame.SnakeGame.selection && SnakeGame.SnakeGame.selectionIndex > 0)
SnakeGame.SnakeGame.selectionIndex--;
// If in SnakeGame, Steer the Snake upwards
else
SnakeGame.SnakeGame.SteerUp(SnakeGame.SnakeGame.self);
// If in Tetris and in Tetris' 'GameOver' Screen, decrement its index.
} else if (isTetris && Tetris.Tetris.selection && Tetris.Tetris.selectionIndex > 0)
Tetris.Tetris.selectionIndex--;
else if (isFlappy && FlappyBird.FlappyBird.selection &&
FlappyBird.FlappyBird.selectionIndex > 0)
FlappyBird.FlappyBird.selectionIndex--;
else if (focusGravity)
FlappyBird.FlappyBird.gravity += 0.01f;
else if (focusHeight && FlappyBird.FlappyBird.spaceHeight < 58)
FlappyBird.FlappyBird.spaceHeight += 1;
else if (focusJump)
FlappyBird.FlappyBird.jumpVel += 0.01f;
else if (debugIndex > 0 && !isFocused)
debugIndex--;
break;
case "FF-7F-02-01":
// Code for Arrow-Down Press
// If in the selection screen, decrement index
if (!isInGame && selectionIndex < 4)
selectionIndex++;
// If in SnakeGame, Steer the Snake downwards
else if (isSnake) {
// Handle index in 'GameOver' Screen
if (SnakeGame.SnakeGame.selection && SnakeGame.SnakeGame.selectionIndex < 1)
SnakeGame.SnakeGame.selectionIndex++;
// If in SnakeGame, Steer the Snake downwards
else
SnakeGame.SnakeGame.SteerDown(SnakeGame.SnakeGame.self);
// If in Tetris and in Tetris' 'GameOver' Screen, decrement its index.
} else if (isTetris)
// If in Tetris and in Tetris' 'GameOver' Screen, increment its index.
if (Tetris.Tetris.selection && Tetris.Tetris.selectionIndex < 1)
Tetris.Tetris.selectionIndex++;
// Otherwise, move Tetris piece down
else
Tetris.Tetris.moveDownOnce();
else if (isFlappy && FlappyBird.FlappyBird.selection && FlappyBird.FlappyBird.selectionIndex < 1)
FlappyBird.FlappyBird.selectionIndex++;
else if (focusGravity && FlappyBird.FlappyBird.gravity > 0)
FlappyBird.FlappyBird.gravity -= 0.01f;
else if (focusHeight && FlappyBird.FlappyBird.spaceHeight > 2)
FlappyBird.FlappyBird.spaceHeight -= 1;
else if (focusJump && FlappyBird.FlappyBird.jumpVel > 0)
FlappyBird.FlappyBird.jumpVel -= 0.01f;
else if (debugIndex < 4 && !isFocused)
debugIndex++;
break;
case "01-80-02-00":
// Code for Arrow-Left Press
// If in SnakeGame, Steer the Snake to the left
if (isSnake)
SnakeGame.SnakeGame.SteerLeft(SnakeGame.SnakeGame.self);
// If in Tetris, move current Block to the left
else if (isTetris)
Tetris.Tetris.moveLeftSide();
break;
case "FF-7F-02-00":
// Code for Arrow-Right Press
// If in SnakeGame, Steer the Snake to the right
if (isSnake)
SnakeGame.SnakeGame.SteerRight(SnakeGame.SnakeGame.self);
// If in Tetris, move current Block to the right
else if (isTetris)
Tetris.Tetris.moveRightSide();
break;
}
Action method = BitConverter.ToString(buffer, 4, 4) switch {
"01-00-01-00" => XButtonPressed,
"01-00-01-01" => AButtonPressed,
"01-00-01-02" => BButtonPressed,
"01-00-01-04" => LButtonPressed,
"01-00-01-05" => RButtonPressed,
"01-00-01-09" => StartButtonPressed,
"01-80-02-01" => UpArrowButtonPressed,
"FF-7F-02-01" => DownArrowPressed,
"01-80-02-00" => LeftArrowPressed,
"FF-7F-02-00" => RightArrowPressed,
_ => () => {}
}; method.Invoke();
}
}
private static void RightArrowPressed() {
// Code for Arrow-Right Press
// If in SnakeGame, Steer the Snake to the right
if (isSnake) SnakeGame.SnakeGame.SteerRight(SnakeGame.SnakeGame.self);
// If in Tetris, move current Block to the right
else if (isTetris) Tetris.Tetris.moveRightSide();
}
private static void LeftArrowPressed() {
// Code for Arrow-Left Press
// If in SnakeGame, Steer the Snake to the left
if (isSnake) SnakeGame.SnakeGame.SteerLeft(SnakeGame.SnakeGame.self);
// If in Tetris, move current Block to the left
else if (isTetris) Tetris.Tetris.moveLeftSide();
}
private static void DownArrowPressed() {
// Code for Arrow-Down Press
// If in the selection screen, decrement index
if (!isInGame && selectionIndex < 4)
selectionIndex++;
// If in SnakeGame, Steer the Snake downwards
else if (isSnake) {
// Handle index in 'GameOver' Screen
if (SnakeGame.SnakeGame.selection && SnakeGame.SnakeGame.selectionIndex < 1)
SnakeGame.SnakeGame.selectionIndex++;
// If in SnakeGame, Steer the Snake downwards
else SnakeGame.SnakeGame.SteerDown(SnakeGame.SnakeGame.self);
// If in Tetris and in Tetris' 'GameOver' Screen, decrement its index.
}
else if (isTetris)
// If in Tetris and in Tetris' 'GameOver' Screen, increment its index.
if (Tetris.Tetris.selection && Tetris.Tetris.selectionIndex < 1)
Tetris.Tetris.selectionIndex++;
// Otherwise, move Tetris piece down
else Tetris.Tetris.moveDownOnce();
else if (isFlappy && FlappyBird.FlappyBird.selection && FlappyBird.FlappyBird.selectionIndex < 1)
FlappyBird.FlappyBird.selectionIndex++;
else if (focusGravity && FlappyBird.FlappyBird.gravity > 0)
FlappyBird.FlappyBird.gravity -= 0.01f;
else if (focusHeight && FlappyBird.FlappyBird.spaceHeight > 2)
FlappyBird.FlappyBird.spaceHeight -= 1;
else if (focusJump && FlappyBird.FlappyBird.jumpVel > 0)
FlappyBird.FlappyBird.jumpVel -= 0.01f;
else if (debugIndex < 4 && !isFocused)
debugIndex++;
}
private static void UpArrowButtonPressed() {
// Code for Arrow-Up Press
// If in the selection screen, decrement index
if (!isInGame && selectionIndex > 0)
selectionIndex--;
else if (isSnake) {
// Handle index in 'GameOver' Screen
if (SnakeGame.SnakeGame.selection && SnakeGame.SnakeGame.selectionIndex > 0)
SnakeGame.SnakeGame.selectionIndex--;
// If in SnakeGame, Steer the Snake upwards
else SnakeGame.SnakeGame.SteerUp(SnakeGame.SnakeGame.self);
// If in Tetris and in Tetris' 'GameOver' Screen, decrement its index.
}
else if (isTetris && Tetris.Tetris.selection && Tetris.Tetris.selectionIndex > 0)
Tetris.Tetris.selectionIndex--;
else if (isFlappy && FlappyBird.FlappyBird.selection && FlappyBird.FlappyBird.selectionIndex > 0)
FlappyBird.FlappyBird.selectionIndex--;
else if (focusGravity)
FlappyBird.FlappyBird.gravity += 0.01f;
else if (focusHeight && FlappyBird.FlappyBird.spaceHeight < 58)
FlappyBird.FlappyBird.spaceHeight += 1;
else if (focusJump)
FlappyBird.FlappyBird.jumpVel += 0.01f;
else if (debugIndex > 0 && !isFocused)
debugIndex--;
}
private static void StartButtonPressed() {
// Code for Start-Button Press
// If in SnakeGame, end the Game and return to menu
if (isSnake)
SnakeGame.SnakeGame.EndGame();
else if (isFlappy) {
// If in FlappyBirds' 'ready' Screen, return to menu
if (!FlappyBird.FlappyBird.isReady)
FlappyBird.FlappyBird.stopPlaying = true;
// Otherwise go back to 'ready' Screen by ending the Game
else {
FlappyBird.FlappyBird.EndGame();
FlappyBird.FlappyBird.selection = false;
}
// If in Tetris, end the Game and return to menu
}
else if (isTetris)
Tetris.Tetris.EndGame();
}
private static void RButtonPressed() {
// Code for R-Button Press
// If in Tetris, rotate the current Block Clockwise
if (isTetris) Tetris.Tetris.rotateClockwise();
}
private static void LButtonPressed() {
// Code for L-Button Press
// If in Tetris, rotate the current Block counter-Clockwise
if (isTetris) Tetris.Tetris.rotateCounterClockwise();
}
private static void BButtonPressed() {
// Code for B-Button Press
if (isFlappy) {
// Jump
if (FlappyBird.FlappyBird.isReady)
FlappyBird.FlappyBird.JumpOnce();
// Start Game
else FlappyBird.FlappyBird.isReady = true;
// Place the current Block in Tetris
}
else if (isTetris)
Tetris.Tetris.placeDownBlock();
else if (!isSnake) {
focusGravity = false;
focusHeight = false;
focusJump = false;
isFocused = false;
}
}
private static void AButtonPressed() {
// Code for A-Button Press
// If not already in a Game, now ready up to select one.
if (!isInGame)
hasSelected = true;
// Select given option in Tetris' 'GameOver' Screen
else if (isSnake && SnakeGame.SnakeGame.selection)
SnakeGame.SnakeGame.enterSelection();
else if (isFlappy && FlappyBird.FlappyBird.selection)
FlappyBird.FlappyBird.enterSelection();
else if (isTetris && Tetris.Tetris.selection)
Tetris.Tetris.enterSelection();
else debugSelect = true;
}
private static void XButtonPressed() {
// Code for X-Button Press
if (isTetris) Tetris.Tetris.swapMemory();
}
}
}