This repository has been archived on 2022-08-05. You can view files and clone it, but cannot push or open issues or pull requests.
OSK/OnScreenKeyboard/Program.cs

169 lines
6.7 KiB
C#

using System;
using System.Drawing;
using System.Globalization;
using CC_Functions.Commandline;
using CC_Functions.Commandline.TUI;
using CC_Functions.Core;
using D = CC_Functions.Commandline.DiffDraw;
namespace OnScreenKeyboard
{
class Program
{
private const string Keyboard = "qwertyuiop\nasdfghjkl_\nzxcvbnm,.-";
private const int Width = 10 * 3;
private const int Height = 4;
private static Point _ball = new Point(0, Height - 1);
private static Point _ballSpeed = new Point(1, -1);
private static int _peddle = 0;
private static string _input = "";
static void Main(string[] a)
{
ArgsParse args = new ArgsParse(a);
//args
if (args.GetBool("help") || args.GetBool("?") || args.GetBool("h"))
{
Console.WriteLine(@"JF OSK v1
Shows an interactive keyboard (stdout and stdin) and logs the output to stderr
Usage:
OSK [arguments]
Arguments:
delay The time to wait between ball movements.
no-color Do not output color. Use only if color doesn't work.
peddle-length The length of the peddle.
Examples:
OSK --delay:0.3 --peddle-length:3
OSK --no-color
OSK 2> output.txt");
return;
}
TimeSpan ballSpeed = args.Get("delay", s => s == null ? new TimeSpan(0, 0, 1) : TimeSpan.Parse($"0:0:0:{s}", CultureInfo.InvariantCulture));
bool color = !args.GetBool("no-color");
int peddleLength = args.Get("peddle-length", s => s == null ? 4 : int.Parse(s, CultureInfo.InvariantCulture));
if (peddleLength > Width)
peddleLength = Width;
//init
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
Console.Clear();
bool playing = true;
DateTime lastGameTick = DateTime.Now;
while (playing)
{
//Process input
bool left = false;
bool right = false;
bool select = false;
while (Console.KeyAvailable)
{
switch (Console.ReadKey().Key)
{
case ConsoleKey.LeftArrow:
case ConsoleKey.A:
left = true;
break;
case ConsoleKey.RightArrow:
case ConsoleKey.D:
right = true;
break;
case ConsoleKey.W:
case ConsoleKey.S:
case ConsoleKey.UpArrow:
case ConsoleKey.DownArrow:
case ConsoleKey.Spacebar:
case ConsoleKey.Enter:
select = true;
break;
case ConsoleKey.Escape:
playing = false;
break;
}
}
//Move peddle
if (left)
_peddle--;
if (right)
_peddle++;
if (_peddle < 0)
_peddle = 0;
if (_peddle > Width - peddleLength)
_peddle = Width - peddleLength;
//Scheduled game tick
if (lastGameTick + ballSpeed - DateTime.Now <= TimeSpan.Zero)
{
lastGameTick = DateTime.Now;
//Move ball
ball:
_ball = new Point(_ball.X + _ballSpeed.X, _ball.Y + _ballSpeed.Y);
if (_ball.X == 0 || _ball.X == Width - 1)
_ballSpeed = new Point(-_ballSpeed.X, _ballSpeed.Y);
if (_ball.Y == 0)
_ballSpeed = new Point(_ballSpeed.X, -_ballSpeed.Y);
if (_ball.Y == Height - 1 && _ball.X >= _peddle && _ball.X < _peddle + peddleLength)
{
if (_ball.X > 0 && _ball.X < Width - 1)
_ball.X -= _ballSpeed.X;
_ball.Y -= 1;
_ballSpeed = new Point(_ballSpeed.X, -_ballSpeed.Y);
goto ball;
}
if (_ball.Y == Height) playing = false;
}
//Post-input pre-draw stuff
if (!playing)
continue;
Pixel[,] empty = new Pixel[Height, Width];
empty.Populate(new Pixel(' '));
D.Clear(empty);
//Draw keyboard and add to output. Combined one to avoid major code duplication
int y = 0;
int sub = 0;
for (int i = 0; i < Keyboard.Length; i++)
{
char t = Keyboard[i];
if (t == '\n')
{
y++;
sub = i + 1;
}
else
{
Point start = new Point((i - sub) * 3, y);
bool selected = _ball.Y == start.Y && _ball.X >= start.X && _ball.X < start.X + 3;
if (selected && select)
_input += t;
DrawString(start,
$" {t} ",
selected ? Console.BackgroundColor : Console.ForegroundColor,
selected ? Console.ForegroundColor : Console.BackgroundColor);
}
}
//Draw ball
D.Set(_ball, new Pixel(Console.ForegroundColor, Console.BackgroundColor, 'X'));
//Draw paddle
DrawString(new Point(_peddle, Height - 1), new string('█', peddleLength), Console.ForegroundColor, Console.BackgroundColor);
//Finish frame
D.Draw(color);
Console.CursorLeft = 0;
Console.CursorTop = Height;
Console.Write(_input);
}
Console.ResetColor();
Console.Clear();
Console.Error.WriteLine(_input);
}
private static void DrawString(Point start, string chars, ConsoleColor foreColor, ConsoleColor backColor)
{
foreach (string s in chars.Split('\n'))
for (int i = 0; i < s.Length; i++)
{
char t = s[i];
D.Set(start.X + i, start.Y, new Pixel(backColor, foreColor, t));
}
}
}
}