player kinda works
This commit is contained in:
parent
8ef01ea1aa
commit
1fb697626e
5 changed files with 298 additions and 44 deletions
|
@ -14,7 +14,7 @@ void setup()
|
||||||
pinMode(8, OUTPUT);
|
pinMode(8, OUTPUT);
|
||||||
pinMode(9, OUTPUT);
|
pinMode(9, OUTPUT);
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
Serial.write("PC2,8,Universal");
|
Serial.write("PC2,8,Universal,END");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
|
|
@ -20,7 +20,7 @@ void setup()
|
||||||
servoChannel[5].attach(7);
|
servoChannel[5].attach(7);
|
||||||
for (int i = 0; i < 8; i++) servoChannel[mapping[i]].write(offDegrees[i]);
|
for (int i = 0; i < 8; i++) servoChannel[mapping[i]].write(offDegrees[i]);
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
Serial.write("PC2,8,Chuck E./Helen/Guest Star");
|
Serial.write("PC2,8,Chuck E./Helen/Guest Star,END");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
#include <Servo.h>
|
#include <Servo.h>
|
||||||
|
|
||||||
Servo servoChannel[11]; // mouth earL earR eyelidL eyelidR eyeL eyeR headR headL headUp armUpL armUpR elbowR elbowL armTwistL armTwistR bodyTwistR bodyTwistL bodyLean
|
Servo servoChannel[11]; // mouth earL earR eyelidL eyelidR eyeL eyeR headL headR headUp armUpL armUpR elbowR elbowL armTwistL armTwistR bodyTwistR bodyTwistL bodyLean
|
||||||
byte onDegrees[19] = { 45, 0, 0, 0, 0, 0, 0, 45, 135, 135, 90, 90, 90, 90, 90, 90, 0, 0, 0 };
|
byte onDegrees[19] = { 45, 0, 0, 0, 0, 0, 0, 135, 45, 135, 90, 90, 90, 90, 90, 90, 0, 0, 0 };
|
||||||
byte offDegrees[19] = { 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 180, 0, 0, 180, 180, 0 , 0, 0, 0 };
|
byte offDegrees[19] = { 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 180, 0, 0, 180, 180, 0 , 0, 0, 0 };
|
||||||
byte mapping[19] = { 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 6, 3, 4, 7, 8, 5, 0, 0, 0 };
|
byte mapping[19] = { 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 6, 3, 4, 7, 8, 5, 9, 9, 10 };
|
||||||
|
|
||||||
int byte1 = 0;
|
int byte1 = 0;
|
||||||
int byte2 = 0;
|
int byte2 = 0;
|
||||||
|
@ -29,7 +29,7 @@ void setup()
|
||||||
servoChannel[8].attach(10);
|
servoChannel[8].attach(10);
|
||||||
for (int i = 0; i < 19; i++) servoChannel[mapping[i]].write(offDegrees[i]);
|
for (int i = 0; i < 19; i++) servoChannel[mapping[i]].write(offDegrees[i]);
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
Serial.write("PC2,32,Mitzi/Helen");
|
Serial.write("PC2,32,Mitzi/Helen,END");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Ports;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
using Eto.Forms;
|
using Eto.Forms;
|
||||||
using Eto.Drawing;
|
using Eto.Drawing;
|
||||||
|
|
||||||
|
@ -6,52 +13,298 @@ namespace PC2Player
|
||||||
{
|
{
|
||||||
public partial class MainForm : Form
|
public partial class MainForm : Form
|
||||||
{
|
{
|
||||||
|
SerialPort Port = null;
|
||||||
|
string[] Signals;
|
||||||
|
System.Timers.Timer FrameTimer;
|
||||||
|
long Index = 0;
|
||||||
|
int FrameSkip = 6;
|
||||||
|
byte[] AudioData;
|
||||||
|
|
||||||
|
string ShowtapeName = "";
|
||||||
|
string ShowtapeStageType = "";
|
||||||
|
string ShowtapeCharacter = "";
|
||||||
|
string ShowtapeBits = "";
|
||||||
|
string ShowtapeFormattedLength = "";
|
||||||
|
|
||||||
|
string ControllerCharacter = "";
|
||||||
|
string ControllerBits = "";
|
||||||
|
|
||||||
|
string ControllerHeader = "";
|
||||||
|
|
||||||
|
bool ControllerConnected = false;
|
||||||
|
bool ShowtapeLoaded = false;
|
||||||
|
|
||||||
|
bool Playing = false;
|
||||||
|
|
||||||
|
DropDown SerialPortDropDown = new DropDown();
|
||||||
|
|
||||||
|
Label ShowtapeNameLabel = new Label { Text = "Show Name: Not Loaded" };
|
||||||
|
Label ShowtapeStageTypeLabel = new Label { Text = "Stage Type: Not Loaded" };
|
||||||
|
Label ShowtapeCharacterLabel = new Label { Text = "Character: Not Loaded" };
|
||||||
|
Label ShowtapeBitsLabel = new Label { Text = "Bits: Not Loaded" };
|
||||||
|
Label ShowtapeLengthLabel = new Label { Text = "Length: Not Loaded" };
|
||||||
|
|
||||||
|
Label ControllerCharacterLabel = new Label { Text = "Character: Disconnected" };
|
||||||
|
Label ControllerBitsLabel = new Label { Text = "Bits: Disconnected" };
|
||||||
|
|
||||||
|
Button RefreshPortsButton = new Button { Text = "Refresh Ports", Width = 150 };
|
||||||
|
Button LoadShowtapeButton = new Button { Text = "Load Showtape", Width = 150 };
|
||||||
|
|
||||||
|
Button PlayButton = new Button { Text = "Play" };
|
||||||
|
Button StopButton = new Button { Text = "Stop" };
|
||||||
|
|
||||||
public MainForm()
|
public MainForm()
|
||||||
{
|
{
|
||||||
Title = "My Eto Form";
|
Title = "PinkConnection2 Showtape Player";
|
||||||
MinimumSize = new Size(200, 200);
|
Size = new Size(500, 450);
|
||||||
|
Maximizable = false;
|
||||||
|
Resizable = false;
|
||||||
|
|
||||||
Content = new StackLayout
|
foreach (string s in SerialPort.GetPortNames())
|
||||||
{
|
{
|
||||||
Padding = 10,
|
SerialPortDropDown.Items.Add(s);
|
||||||
Items =
|
}
|
||||||
|
SerialPortDropDown.SelectedValueChanged += (sender, e) => Event_SelectSerialPort();
|
||||||
|
|
||||||
|
FrameTimer = new System.Timers.Timer((1000d/60d)*FrameSkip);
|
||||||
|
FrameTimer.Elapsed += Event_FrameTimerTick;
|
||||||
|
FrameTimer.AutoReset = true;
|
||||||
|
|
||||||
|
PlayButton.Enabled = false;
|
||||||
|
StopButton.Enabled = false;
|
||||||
|
|
||||||
|
PlayButton.Command = new Command( (sender, e) => Event_PlayButton() );
|
||||||
|
StopButton.Command = new Command( (sender, e) => Event_StopButton() );
|
||||||
|
RefreshPortsButton.Command = new Command( (sender, e) => Event_RefreshPortsButton() );
|
||||||
|
LoadShowtapeButton.Command = new Command( (sender, e) => Event_LoadShowtapeButton() );
|
||||||
|
|
||||||
|
Content = BuildLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicLayout BuildLayout()
|
||||||
|
{
|
||||||
|
GroupBox showtapeInfoGroupBox = new GroupBox{ Text = "Showtape" };
|
||||||
|
DynamicLayout showtapeInfoGroupLayout = new DynamicLayout { DefaultSpacing = new Size(5, 5), DefaultPadding = new Padding(5, 5, 5, 5) };
|
||||||
|
showtapeInfoGroupLayout.AddRow(ShowtapeNameLabel);
|
||||||
|
showtapeInfoGroupLayout.AddRow(ShowtapeStageTypeLabel);
|
||||||
|
showtapeInfoGroupLayout.AddRow(ShowtapeCharacterLabel);
|
||||||
|
showtapeInfoGroupLayout.AddRow(ShowtapeBitsLabel);
|
||||||
|
showtapeInfoGroupLayout.AddRow(ShowtapeLengthLabel);
|
||||||
|
showtapeInfoGroupBox.Content = showtapeInfoGroupLayout;
|
||||||
|
|
||||||
|
GroupBox controllerInfoGroupBox = new GroupBox{ Text = "Controller" };
|
||||||
|
DynamicLayout controllerInfoGroupLayout = new DynamicLayout { DefaultSpacing = new Size(5, 5), DefaultPadding = new Padding(5, 5, 5, 5) };
|
||||||
|
controllerInfoGroupLayout.AddRow(ControllerCharacterLabel);
|
||||||
|
controllerInfoGroupLayout.AddRow(ControllerBitsLabel);
|
||||||
|
controllerInfoGroupBox.Content = controllerInfoGroupLayout;
|
||||||
|
|
||||||
|
DynamicLayout layout = new DynamicLayout { DefaultSpacing = new Size(10, 10), DefaultPadding = new Padding(5, 5, 5, 5) };
|
||||||
|
|
||||||
|
layout.BeginVertical();
|
||||||
|
layout.BeginHorizontal();
|
||||||
|
layout.Add(PlayButton, true);
|
||||||
|
layout.Add(StopButton, true);
|
||||||
|
layout.EndHorizontal();
|
||||||
|
layout.EndVertical();
|
||||||
|
|
||||||
|
layout.BeginVertical();
|
||||||
|
|
||||||
|
layout.BeginHorizontal();
|
||||||
|
layout.Add(new Label { Text = "Serial Port" });
|
||||||
|
layout.EndHorizontal();
|
||||||
|
|
||||||
|
layout.BeginHorizontal();
|
||||||
|
layout.Add(SerialPortDropDown, true);
|
||||||
|
layout.EndHorizontal();
|
||||||
|
|
||||||
|
layout.BeginHorizontal();
|
||||||
|
layout.Add(showtapeInfoGroupBox, true);
|
||||||
|
layout.EndHorizontal();
|
||||||
|
|
||||||
|
layout.BeginHorizontal();
|
||||||
|
layout.Add(controllerInfoGroupBox, true);
|
||||||
|
layout.EndHorizontal();
|
||||||
|
|
||||||
|
layout.EndVertical();
|
||||||
|
|
||||||
|
layout.BeginVertical();
|
||||||
|
layout.BeginHorizontal();
|
||||||
|
layout.Add(null, true);
|
||||||
|
layout.Add(RefreshPortsButton);
|
||||||
|
layout.Add(LoadShowtapeButton);
|
||||||
|
layout.EndHorizontal();
|
||||||
|
layout.EndVertical();
|
||||||
|
|
||||||
|
layout.BeginVertical();
|
||||||
|
layout.Add(null, true);
|
||||||
|
layout.EndVertical();
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckReady()
|
||||||
|
{
|
||||||
|
if (ControllerConnected && ShowtapeLoaded)
|
||||||
|
{
|
||||||
|
PlayButton.Enabled = true;
|
||||||
|
StopButton.Enabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayButton.Enabled = false;
|
||||||
|
StopButton.Enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event_SelectSerialPort()
|
||||||
|
{
|
||||||
|
if (Port != null) Port.Close();
|
||||||
|
Port = new SerialPort((string)SerialPortDropDown.SelectedKey, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
Port.DataReceived += new SerialDataReceivedEventHandler(Event_PortRecievedData);
|
||||||
|
ControllerHeader = "";
|
||||||
|
ControllerCharacterLabel.Text = "Character: Disconnected";
|
||||||
|
ControllerBitsLabel.Text = "Bits: Disconnected";
|
||||||
|
ControllerConnected = false;
|
||||||
|
CheckReady();
|
||||||
|
Port.Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event_PortRecievedData(object sender, SerialDataReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
ControllerHeader += Port.ReadExisting();
|
||||||
|
if (ControllerHeader.EndsWith(",END"))
|
||||||
|
{
|
||||||
|
ControllerBits = ControllerHeader.Split(',')[1];
|
||||||
|
ControllerCharacter = ControllerHeader.Split(',')[2];
|
||||||
|
|
||||||
|
ControllerCharacterLabel.Text = $"Character: {ControllerCharacter}";
|
||||||
|
ControllerBitsLabel.Text = $"Bits: {ControllerBits}";
|
||||||
|
ControllerConnected = true;
|
||||||
|
CheckReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event_RefreshPortsButton()
|
||||||
|
{
|
||||||
|
foreach (string s in SerialPort.GetPortNames())
|
||||||
|
{
|
||||||
|
SerialPortDropDown.Items.Add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event_LoadShowtapeButton()
|
||||||
|
{
|
||||||
|
OpenFileDialog fileDialog = new OpenFileDialog();
|
||||||
|
fileDialog.Filters.Add(new FileFilter("UST Files (.ust)", new string[]{ ".ust" }));
|
||||||
|
fileDialog.Title = "Select Show File.";
|
||||||
|
fileDialog.ShowDialog(this);
|
||||||
|
|
||||||
|
string tempUSTData = File.ReadAllText(fileDialog.FileName);
|
||||||
|
if (!tempUSTData.StartsWith("UST,1,"))
|
||||||
|
{
|
||||||
|
MessageBox.Show("This is not a UST Version 1 showtape.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] headerData = tempUSTData.Split(';')[0].Split(',');
|
||||||
|
string[] stringyBits = tempUSTData.Split(';')[1].Split(',');
|
||||||
|
AudioData = Convert.FromBase64String(tempUSTData.Split(';')[2]);
|
||||||
|
|
||||||
|
ShowtapeName = headerData[2];
|
||||||
|
ShowtapeBits = headerData[3];
|
||||||
|
ShowtapeStageType = headerData[4];
|
||||||
|
ShowtapeCharacter = headerData[5];
|
||||||
|
|
||||||
|
if (headerData[3] == "256")
|
||||||
|
{
|
||||||
|
MessageBox.Show("Can't load a full stage showtape right now!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeSpan time = TimeSpan.FromSeconds(stringyBits.Length/60);
|
||||||
|
ShowtapeFormattedLength = time.ToString(@"hh\:mm\:ss");
|
||||||
|
|
||||||
|
ShowtapeNameLabel.Text = $"Show Name: {ShowtapeName}";
|
||||||
|
ShowtapeStageTypeLabel.Text = $"Stage Type: {ShowtapeStageType}";
|
||||||
|
ShowtapeCharacterLabel.Text = $"Character: {ShowtapeCharacter}";
|
||||||
|
ShowtapeBitsLabel.Text = $"Bits: {ShowtapeBits}";
|
||||||
|
ShowtapeLengthLabel.Text = $"Length: {ShowtapeFormattedLength}";
|
||||||
|
|
||||||
|
List<string> tmpOut = new List<string>();
|
||||||
|
foreach (string frame in stringyBits)
|
||||||
|
{
|
||||||
|
int b = int.Parse(frame, NumberStyles.HexNumber);
|
||||||
|
char[] bytesOut = { (char)64 };
|
||||||
|
if (ShowtapeBits == "8")
|
||||||
{
|
{
|
||||||
"Hello World!",
|
bytesOut = new char[]{
|
||||||
// add more controls here
|
(char)(64 | ((b & 8) | (b & 4) | (b & 2) | (b & 1))),
|
||||||
|
(char)(64 | (((b & 128) | (b & 64) | (b & 32) | (b & 16)) >> 4))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
};
|
else if (ShowtapeBits == "32")
|
||||||
|
{
|
||||||
|
bytesOut = new char[]{
|
||||||
|
(char)(64 | ((b & 8) | (b & 4) | (b & 2) | (b & 1))),
|
||||||
|
(char)(64 | (((b & 128) | (b & 64) | (b & 32) | (b & 16)) >> 4)),
|
||||||
|
(char)(64 | (((b & 2048) | (b & 1024) | (b & 512) | (b & 256)) >> 8)),
|
||||||
|
(char)(64 | (((b & 32768) | (b & 16384) | (b & 8192) | (b & 4096)) >> 12)),
|
||||||
|
(char)(64 | (((b & 524288) | (b & 262144) | (b & 131072) | (b & 65536)) >> 16)),
|
||||||
|
(char)(64 | (((b & 8388608) | (b & 4194304) | (b & 2097152) | (b & 1048576)) >> 20)),
|
||||||
|
(char)(64 | (((b & 134217728) | (b & 67108864) | (b & 33554432) | (b & 16777216)) >> 24)),
|
||||||
|
(char)(64 | (((b & 2147483648) | (b & 1073741824) | (b & 536870912) | (b & 268435456)) >> 28))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
tmpOut.Add(new string(bytesOut));
|
||||||
|
}
|
||||||
|
Signals = tmpOut.ToArray();
|
||||||
|
ShowtapeLoaded = true;
|
||||||
|
CheckReady();
|
||||||
|
}
|
||||||
|
|
||||||
// create a few commands that can be used for the menu and toolbar
|
void Event_PlayButton()
|
||||||
var clickMe = new Command { MenuText = "Click Me!", ToolBarText = "Click Me!" };
|
{
|
||||||
clickMe.Executed += (sender, e) => MessageBox.Show(this, "I was clicked!");
|
if (Playing) return;
|
||||||
|
if (ShowtapeBits != ControllerBits)
|
||||||
var quitCommand = new Command { MenuText = "Quit", Shortcut = Application.Instance.CommonModifier | Keys.Q };
|
|
||||||
quitCommand.Executed += (sender, e) => Application.Instance.Quit();
|
|
||||||
|
|
||||||
var aboutCommand = new Command { MenuText = "About..." };
|
|
||||||
aboutCommand.Executed += (sender, e) => new AboutDialog().ShowDialog(this);
|
|
||||||
|
|
||||||
// create menu
|
|
||||||
Menu = new MenuBar
|
|
||||||
{
|
{
|
||||||
Items =
|
MessageBox.Show("This showtape does not have the correct amount of bits for your controller.");
|
||||||
{
|
return;
|
||||||
// File submenu
|
}
|
||||||
new SubMenuItem { Text = "&File", Items = { clickMe } },
|
File.WriteAllBytes("tmp.wav", AudioData);
|
||||||
// new SubMenuItem { Text = "&Edit", Items = { /* commands/items */ } },
|
Process.Start("mpv", "tmp.wav");
|
||||||
// new SubMenuItem { Text = "&View", Items = { /* commands/items */ } },
|
FrameTimer.Start();
|
||||||
},
|
|
||||||
ApplicationItems =
|
|
||||||
{
|
|
||||||
// application (OS X) or file menu (others)
|
|
||||||
new ButtonMenuItem { Text = "&Preferences..." },
|
|
||||||
},
|
|
||||||
QuitItem = quitCommand,
|
|
||||||
AboutItem = aboutCommand
|
|
||||||
};
|
|
||||||
|
|
||||||
// create toolbar
|
Playing = true;
|
||||||
ToolBar = new ToolBar { Items = { clickMe } };
|
|
||||||
|
PlayButton.Enabled = false;
|
||||||
|
RefreshPortsButton.Enabled = false;
|
||||||
|
LoadShowtapeButton.Enabled = false;
|
||||||
|
SerialPortDropDown.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event_StopButton()
|
||||||
|
{
|
||||||
|
FrameTimer.Stop();
|
||||||
|
File.Delete("tmp.wav");
|
||||||
|
Playing = false;
|
||||||
|
|
||||||
|
PlayButton.Enabled = true;
|
||||||
|
RefreshPortsButton.Enabled = true;
|
||||||
|
LoadShowtapeButton.Enabled = true;
|
||||||
|
SerialPortDropDown.Enabled = true;
|
||||||
|
Index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event_FrameTimerTick(Object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
if (Index >= Signals.Length)
|
||||||
|
{
|
||||||
|
Event_StopButton();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Port.Write(Signals[Index]);
|
||||||
|
Index += FrameSkip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Eto.Forms" Version="2.9.0" />
|
<PackageReference Include="Eto.Forms" Version="2.9.0" />
|
||||||
|
<PackageReference Include="System.IO.Ports" Version="9.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Loading…
Add table
Reference in a new issue