add new player and new firmware

This commit is contained in:
Persephone Bubblegum-Holidy 2025-07-01 19:04:25 -07:00
parent b9fd99de54
commit a99ced1ad1
19 changed files with 315 additions and 5 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@
*/obj/ */obj/
*/*/*/bin/ */*/*/bin/
*/*/*/obj/ */*/*/obj/
*.tmp

View file

@ -13,7 +13,6 @@ void setup()
{ {
for (int i = 22; i <= 53; i++) pinMode(i, OUTPUT); for (int i = 22; i <= 53; i++) pinMode(i, OUTPUT);
Serial.begin(9600); Serial.begin(9600);
Serial.write("PC2,32,Universal,END");
} }
void loop() void loop()
@ -29,6 +28,11 @@ void loop()
byte7 = Serial.read(); byte7 = Serial.read();
byte8 = Serial.read(); byte8 = Serial.read();
if ((byte1 & 32) && (byte2 & 32))
{
if (byte1 & 1) Serial.write("PC3,32\n");
}
if ((byte1 & 64) && (byte2 & 64) && (byte3 & 64) && (byte4 & 64) && (byte5 & 64) && (byte6 & 64) && (byte7 & 64) && (byte8 & 64)) if ((byte1 & 64) && (byte2 & 64) && (byte3 & 64) && (byte4 & 64) && (byte5 & 64) && (byte6 & 64) && (byte7 & 64) && (byte8 & 64))
{ {
if (byte1 & 1) digitalWrite(22, 1); if (byte1 & 1) digitalWrite(22, 1);

View file

@ -14,7 +14,6 @@ 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,END");
} }
void loop() void loop()
@ -24,6 +23,11 @@ void loop()
byte1 = Serial.read(); byte1 = Serial.read();
byte2 = Serial.read(); byte2 = Serial.read();
if ((byte1 & 32) && (byte2 & 32))
{
if (byte1 & 1) Serial.write("PC3,8\n");
}
if ((byte1 & 64) && (byte2 & 64)) if ((byte1 & 64) && (byte2 & 64))
{ {
if (byte1 & 1) digitalWrite(2, 1); if (byte1 & 1) digitalWrite(2, 1);

View file

@ -20,7 +20,6 @@ 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,END");
} }
void loop() void loop()
@ -30,6 +29,11 @@ void loop()
byte1 = Serial.read(); byte1 = Serial.read();
byte2 = Serial.read(); byte2 = Serial.read();
if ((byte1 & 32) && (byte2 & 32))
{
if (byte1 & 1) Serial.write("PC3,8\n");
}
if ((byte1 & 64) && (byte2 & 64)) if ((byte1 & 64) && (byte2 & 64))
{ {
if (byte1 & 1) servoChannel[mapping[0]].write(onDegrees[0]); if (byte1 & 1) servoChannel[mapping[0]].write(onDegrees[0]);

View file

@ -29,7 +29,6 @@ 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,END");
} }
void loop() { void loop() {
@ -44,6 +43,11 @@ void loop() {
byte7 = Serial.read(); byte7 = Serial.read();
byte8 = Serial.read(); byte8 = Serial.read();
if ((byte1 & 32) && (byte2 & 32))
{
if (byte1 & 1) Serial.write("PC3,8\n");
}
if ((byte1 & 64) && (byte2 & 64) && (byte3 & 64) && (byte4 & 64) && (byte5 & 64)) if ((byte1 & 64) && (byte2 & 64) && (byte3 & 64) && (byte4 & 64) && (byte5 & 64))
{ {
if (byte1 & 1) servoChannel[mapping[0]].write(onDegrees[0]); if (byte1 & 1) servoChannel[mapping[0]].write(onDegrees[0]);

View file

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SoundFlow" Version="1.1.1" />
<PackageReference Include="System.IO.Ports" Version="9.0.4" />
</ItemGroup>
</Project>

267
ConsolePlayer/Program.cs Normal file
View file

@ -0,0 +1,267 @@
using System.Globalization;
using System.IO.Ports;
using System.Numerics;
using System.Timers;
using SoundFlow.Abstracts;
using SoundFlow.Backends.MiniAudio;
using SoundFlow.Components;
using SoundFlow.Enums;
using SoundFlow.Providers;
namespace ConsolePlayer
{
public class Program
{
static SerialPort Port;
static System.Timers.Timer FrameTimer;
static int FramesPerTick = 6;
static int ShowtapeIndex = 0;
static int ControllerBits;
static string ShowtapeName;
static string ShowtapeFormattedLength;
static bool DetectedController = false;
static bool Playing = false;
static bool TripFlag = false;
static string[] ShowtapeFrames;
public static void Main(string[] args)
{
Console.WriteLine("PinkConnection3 Console Player");
if (args.Length < 2)
{
Console.WriteLine("Not enough arguments!");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
return;
}
if (!File.Exists(args[0]))
{
Console.WriteLine("Specified showtape does not exist!");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
return;
}
if (!File.Exists(args[1]))
{
Console.WriteLine("Specified mapping file does not exist!");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
return;
}
if (args.Length == 3) OpenSerialPortSpecific(args[2]);
else OpenSerialPort();
if (TripFlag) return;
LoadShowtape(args[0], args[1]);
if (TripFlag) return;
FrameTimer = new System.Timers.Timer((1000d/60d)*FramesPerTick);
FrameTimer.Elapsed += PlayFrame;
FrameTimer.AutoReset = true;
using MiniAudioEngine audioEngine = new MiniAudioEngine(44100, Capability.Playback);
using StreamDataProvider dataProvider = new StreamDataProvider(File.OpenRead("pc3playertempaudio.tmp"));
SoundPlayer player = new SoundPlayer(dataProvider);
Mixer.Master.AddComponent(player);
Console.WriteLine($"Playing Showtape \"{ShowtapeName}\" ({ShowtapeFormattedLength})");
Playing = true;
player.Play();
FrameTimer.Start();
while (Playing) Thread.Sleep(1000);
Mixer.Master.RemoveComponent(player);
}
static void OpenSerialPortSpecific(string specifiedPortName)
{
string successPortName = "";
Console.WriteLine("Serial port was manually specified");
try
{
Console.Write("Waiting for controller");
Port = new SerialPort(specifiedPortName, 9600, Parity.None, 8, StopBits.One);
Port.Open();
for (int i = 0; i < 10; i++)
{
if (i % 5 == 0) Console.Write(".");
Port.Write("! ");
Thread.Sleep(100);
string readAttempt = Port.ReadExisting();
if (readAttempt.Split(",")[0] == "PC3")
{
ControllerBits = int.Parse(readAttempt.Split(",")[1]);
DetectedController = true;
successPortName = specifiedPortName;
break;
}
}
if (!DetectedController)
{
Console.WriteLine("\nCould not detect a PinkConnection3 controller on the specified serial port.");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
TripFlag = true;
return;
}
}
catch (Exception e)
{
Console.WriteLine("\nFailed to connect to the specified serial port.");
Console.WriteLine(e.Message);
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
TripFlag = true;
return;
}
}
static void OpenSerialPort()
{
string successPortName = "";
Console.Write("Searching for controller");
foreach (string portName in SerialPort.GetPortNames())
{
if (DetectedController) break;
try
{
Port = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
Port.Open();
for (int i = 0; i < 10; i++)
{
if (i % 5 == 0) Console.Write(".");
Port.Write("! ");
Thread.Sleep(100);
string readAttempt = Port.ReadExisting();
if (readAttempt.Split(",")[0] == "PC3")
{
ControllerBits = int.Parse(readAttempt.Split(",")[1]);
DetectedController = true;
successPortName = portName;
break;
}
}
} catch (Exception) {}
}
if (!DetectedController)
{
Console.WriteLine("\nCould not detect a PinkConnection3 controller on any of your serial ports.");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
TripFlag = true;
return;
}
Console.WriteLine("\nDetected PinkConnection3 Controller on " + successPortName);
}
static void LoadShowtape(string ustPath, string mappingPath)
{
Console.WriteLine("Loading showtape file...");
string tempMappingData = File.ReadAllText(mappingPath);
if (!tempMappingData.StartsWith("PC3MAPPING;"))
{
Console.WriteLine("Specified mapping file is not a PinkConnection3 channel map.");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
TripFlag = true;
return;
}
List<int> targetBits = new List<int>();
foreach (string s in tempMappingData.Split(";")[1].Split(","))
{
targetBits.Add(int.Parse(s));
}
if (targetBits.Count != ControllerBits)
{
Console.WriteLine("The mapped channel count is not equal to the connected controller's bit count.");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
TripFlag = true;
return;
}
if (targetBits.Count % 4 != 0)
{
Console.WriteLine("The mapped channel count is not divisible by 4.");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
TripFlag = true;
return;
}
string tempUSTData = File.ReadAllText(ustPath);
if (!tempUSTData.StartsWith("UST,2,"))
{
Console.WriteLine("Specified showtape is not a UST version 2 showtape.");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
TripFlag = true;
return;
}
string[] headerData = tempUSTData.Split(';')[0].Split(',');
string[] stringyBits = tempUSTData.Split(';')[1].Split(',');
File.WriteAllBytes("pc3playertempaudio.tmp", Convert.FromBase64String(tempUSTData.Split(';')[2]));
tempUSTData = null;
ShowtapeName = headerData[2];
TimeSpan time = TimeSpan.FromSeconds(stringyBits.Length/60);
ShowtapeFormattedLength = time.ToString(@"hh\:mm\:ss");
List<string> tempShowData = new List<string>();
foreach (string stringyFrame in stringyBits)
{
BigInteger frame = BigInteger.Parse(stringyFrame, NumberStyles.HexNumber);
int selectBit = 0;
char[] frameStringOut = new char[64];
for (int i = 0; i < targetBits.Count / 4; i++)
{
byte quartet = 64;
for (int j = 0; j < 4; j++)
{
if (targetBits[selectBit] == 0) continue;
if ((frame & BigInteger.Pow(2, targetBits[selectBit]-1)) == BigInteger.Pow(2, targetBits[selectBit]-1)) quartet += (byte)Math.Pow(2, j);
selectBit++;
}
frameStringOut[i] = (char)quartet;
}
tempShowData.Add(new string(frameStringOut).Trim());
}
ShowtapeFrames = tempShowData.ToArray();
}
static void PlayFrame(Object sender, ElapsedEventArgs e)
{
if (ShowtapeIndex >= ShowtapeFrames.Length)
{
FrameTimer.Stop();
Playing = false;
Console.WriteLine("Complete!");
if (File.Exists("pc3playertempaudio.tmp")) File.Delete("pc3playertempaudio.tmp");
return;
}
Port.Write(ShowtapeFrames[ShowtapeIndex]);
ShowtapeIndex += FramesPerTick;
}
}
}

View file

@ -0,0 +1 @@
PC3MAPPING;58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

View file

@ -0,0 +1 @@
PC3MAPPING;91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,0,0,0,0,0,0,0,0,0,0,0,0

View file

@ -0,0 +1 @@
PC3MAPPING;1,2,3,4,5,6,7,8

View file

@ -0,0 +1 @@
PC3MAPPING;9,10,11,12,13,14,15,16

View file

@ -0,0 +1 @@
PC3MAPPING;25,26,27,28,29,30,31,32

View file

@ -0,0 +1 @@
PC3MAPPING;17,18,19,20,21,22,23,24

View file

@ -0,0 +1 @@
PC3MAPPING;33,34,35,36,37,38,39,40

View file

@ -0,0 +1 @@
PC3MAPPING;74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

View file

@ -0,0 +1 @@
PC3MAPPING;42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

View file

@ -0,0 +1 @@
PC3MAPPING;23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,0,0,0,0,0,0,0,0,0,0,0,0,0

View file

@ -0,0 +1 @@
PC3MAPPING;1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,0,0,0,0,0,0,0,0,0,0

View file

@ -9,7 +9,7 @@
## PC2Player ## PC2Player
- burn the damn thing to the ground and start over - ~~burn the damn thing to the ground and start over~~ Done!
## Firmwares ## Firmwares