Compare commits
5 commits
Author | SHA1 | Date | |
---|---|---|---|
d7c01b93d5 | |||
72cc742e84 | |||
50043fd750 | |||
e696efbddd | |||
a99ced1ad1 |
48 changed files with 6300 additions and 19 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@
|
||||||
*/obj/
|
*/obj/
|
||||||
*/*/*/bin/
|
*/*/*/bin/
|
||||||
*/*/*/obj/
|
*/*/*/obj/
|
||||||
|
*.tmp
|
||||||
|
|
|
@ -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()
|
||||||
|
@ -22,12 +21,21 @@ void loop()
|
||||||
{
|
{
|
||||||
byte1 = Serial.read();
|
byte1 = Serial.read();
|
||||||
byte2 = Serial.read();
|
byte2 = Serial.read();
|
||||||
byte3 = Serial.read();
|
|
||||||
byte4 = Serial.read();
|
|
||||||
byte5 = Serial.read();
|
if ((byte1 & 32) && (byte2 & 32))
|
||||||
byte6 = Serial.read();
|
{
|
||||||
byte7 = Serial.read();
|
if (byte1 & 1) Serial.write("PC3,32\n");
|
||||||
byte8 = Serial.read();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte3 = Serial.read();
|
||||||
|
byte4 = Serial.read();
|
||||||
|
byte5 = Serial.read();
|
||||||
|
byte6 = Serial.read();
|
||||||
|
byte7 = Serial.read();
|
||||||
|
byte8 = Serial.read();
|
||||||
|
}
|
||||||
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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() {
|
||||||
|
@ -37,12 +36,21 @@ void loop() {
|
||||||
{
|
{
|
||||||
byte1 = Serial.read();
|
byte1 = Serial.read();
|
||||||
byte2 = Serial.read();
|
byte2 = Serial.read();
|
||||||
byte3 = Serial.read();
|
|
||||||
byte4 = Serial.read();
|
if ((byte1 & 32) && (byte2 & 32))
|
||||||
byte5 = Serial.read();
|
{
|
||||||
byte6 = Serial.read();
|
if (byte1 & 1) Serial.write("PC3,8\n");
|
||||||
byte7 = Serial.read();
|
}
|
||||||
byte8 = Serial.read();
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte3 = Serial.read();
|
||||||
|
byte4 = Serial.read();
|
||||||
|
byte5 = Serial.read();
|
||||||
|
byte6 = Serial.read();
|
||||||
|
byte7 = Serial.read();
|
||||||
|
byte8 = Serial.read();
|
||||||
|
}
|
||||||
|
|
||||||
if ((byte1 & 64) && (byte2 & 64) && (byte3 & 64) && (byte4 & 64) && (byte5 & 64))
|
if ((byte1 & 64) && (byte2 & 64) && (byte3 & 64) && (byte4 & 64) && (byte5 & 64))
|
||||||
{
|
{
|
||||||
|
|
15
ConsolePlayer/ConsolePlayer.csproj
Normal file
15
ConsolePlayer/ConsolePlayer.csproj
Normal 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>
|
308
ConsolePlayer/Program.cs
Normal file
308
ConsolePlayer/Program.cs
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO.Ports;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
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 System.Timers.Timer ResyncTimer;
|
||||||
|
static SoundPlayer AudioPlayer;
|
||||||
|
|
||||||
|
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 bool Paused = false;
|
||||||
|
static bool SyncMsg = 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;
|
||||||
|
|
||||||
|
ResyncTimer = new System.Timers.Timer(15000);
|
||||||
|
ResyncTimer.Elapsed += Resync;
|
||||||
|
ResyncTimer.AutoReset = true;
|
||||||
|
|
||||||
|
using MiniAudioEngine audioEngine = new MiniAudioEngine(48000, Capability.Playback);
|
||||||
|
|
||||||
|
using StreamDataProvider dataProvider = new StreamDataProvider(File.OpenRead("pc3playertempaudio.tmp"));
|
||||||
|
AudioPlayer = new SoundPlayer(dataProvider);
|
||||||
|
|
||||||
|
Mixer.Master.AddComponent(AudioPlayer);
|
||||||
|
|
||||||
|
Console.WriteLine($"Playing Showtape \"{ShowtapeName}\" ({ShowtapeFormattedLength})");
|
||||||
|
Console.WriteLine("Controls:\n[SPACE] to pause and unpause\n[TAB] to toggle sync messages");
|
||||||
|
Playing = true;
|
||||||
|
AudioPlayer.Play();
|
||||||
|
FrameTimer.Start();
|
||||||
|
ResyncTimer.Start();
|
||||||
|
while (Playing)
|
||||||
|
{
|
||||||
|
ConsoleKeyInfo input = Console.ReadKey();
|
||||||
|
if (Playing)
|
||||||
|
{
|
||||||
|
if (input.Key == ConsoleKey.Spacebar)
|
||||||
|
{
|
||||||
|
if (Paused)
|
||||||
|
{
|
||||||
|
Paused = false;
|
||||||
|
FrameTimer.Start();
|
||||||
|
ResyncTimer.Start();
|
||||||
|
AudioPlayer.Seek((float)(((float)ShowtapeIndex) / 60.0));
|
||||||
|
AudioPlayer.Play();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Paused = true;
|
||||||
|
FrameTimer.Stop();
|
||||||
|
ResyncTimer.Stop();
|
||||||
|
AudioPlayer.Pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (input.Key == ConsoleKey.Tab) SyncMsg = !SyncMsg;
|
||||||
|
}
|
||||||
|
else if (!Playing) break;
|
||||||
|
}
|
||||||
|
Mixer.Master.RemoveComponent(AudioPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) { continue; }
|
||||||
|
}
|
||||||
|
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! Press any key to exit.");
|
||||||
|
if (File.Exists("pc3playertempaudio.tmp")) File.Delete("pc3playertempaudio.tmp");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Port.Write(ShowtapeFrames[ShowtapeIndex]);
|
||||||
|
ShowtapeIndex += FramesPerTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Resync(Object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
if (SyncMsg) Console.WriteLine($"Resynced by {(int)(AudioPlayer.Time * 60) - ShowtapeIndex} frames");
|
||||||
|
ShowtapeIndex = (int)(AudioPlayer.Time * 60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
ConsolePlayer/channel mappings/BeachBearJasper.pcm
Normal file
1
ConsolePlayer/channel mappings/BeachBearJasper.pcm
Normal 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
|
1
ConsolePlayer/channel mappings/BillyBob.pcm
Normal file
1
ConsolePlayer/channel mappings/BillyBob.pcm
Normal 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
|
1
ConsolePlayer/channel mappings/CyberChuck.pcm
Normal file
1
ConsolePlayer/channel mappings/CyberChuck.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING;1,2,3,4,5,6,7,8
|
1
ConsolePlayer/channel mappings/CyberHelen.pcm
Normal file
1
ConsolePlayer/channel mappings/CyberHelen.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING;9,10,11,12,13,14,15,16
|
1
ConsolePlayer/channel mappings/CyberJasper.pcm
Normal file
1
ConsolePlayer/channel mappings/CyberJasper.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING;25,26,27,28,29,30,31,32
|
1
ConsolePlayer/channel mappings/CyberMunch.pcm
Normal file
1
ConsolePlayer/channel mappings/CyberMunch.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING;17,18,19,20,21,22,23,24
|
1
ConsolePlayer/channel mappings/CyberPasqually.pcm
Normal file
1
ConsolePlayer/channel mappings/CyberPasqually.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING;33,34,35,36,37,38,39,40
|
1
ConsolePlayer/channel mappings/DookPasqually.pcm
Normal file
1
ConsolePlayer/channel mappings/DookPasqually.pcm
Normal 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
|
1
ConsolePlayer/channel mappings/FatzMunch.pcm
Normal file
1
ConsolePlayer/channel mappings/FatzMunch.pcm
Normal 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
|
1
ConsolePlayer/channel mappings/MitziHelen.pcm
Normal file
1
ConsolePlayer/channel mappings/MitziHelen.pcm
Normal 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
|
1
ConsolePlayer/channel mappings/RolfeChuck.pcm
Normal file
1
ConsolePlayer/channel mappings/RolfeChuck.pcm
Normal 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
|
|
@ -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
|
||||||
|
|
||||||
|
|
25
PC3Player/PC3Player.sln
Normal file
25
PC3Player/PC3Player.sln
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.14.36221.1 d17.14
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PC3Player", "PC3Player\PC3Player.csproj", "{13092811-9CBA-4FD5-B780-E67E14221992}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{13092811-9CBA-4FD5-B780-E67E14221992}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{13092811-9CBA-4FD5-B780-E67E14221992}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{13092811-9CBA-4FD5-B780-E67E14221992}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{13092811-9CBA-4FD5-B780-E67E14221992}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {7BE19417-D601-45AA-B189-5AC9C4B041B6}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
829
PC3Player/PC3Player/AdvancedSettingsForm.Designer.cs
generated
Normal file
829
PC3Player/PC3Player/AdvancedSettingsForm.Designer.cs
generated
Normal file
|
@ -0,0 +1,829 @@
|
||||||
|
namespace PC3Player
|
||||||
|
{
|
||||||
|
partial class AdvancedSettingsForm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
components = new System.ComponentModel.Container();
|
||||||
|
PlaylistPlaybackGroupBox = new GroupBox();
|
||||||
|
LoopCheckBox = new CheckBox();
|
||||||
|
IntermissionUnitDropDown = new ComboBox();
|
||||||
|
IntermissionTimeCounter = new NumericUpDown();
|
||||||
|
IntermissionCheckBox = new CheckBox();
|
||||||
|
label2 = new Label();
|
||||||
|
ShowEndedDropDown = new ComboBox();
|
||||||
|
label1 = new Label();
|
||||||
|
PlaylistStartedDropDown = new ComboBox();
|
||||||
|
ShowSelectorGroupBox = new GroupBox();
|
||||||
|
AddSkitButton = new Button();
|
||||||
|
SkitCheckBox = new CheckBox();
|
||||||
|
label5 = new Label();
|
||||||
|
AlreadyPlayingDropDown = new ComboBox();
|
||||||
|
CooldownUnitDropDown = new ComboBox();
|
||||||
|
CooldownTimeCounter = new NumericUpDown();
|
||||||
|
CooldownCheckBox = new CheckBox();
|
||||||
|
label3 = new Label();
|
||||||
|
SelectedShowEndDropDown = new ComboBox();
|
||||||
|
label4 = new Label();
|
||||||
|
ButtonPressDropDown = new ComboBox();
|
||||||
|
ShowSelectorAssignmentGroupBox = new GroupBox();
|
||||||
|
AssignmentPanel = new Panel();
|
||||||
|
ButtonAssignDropDown1 = new ComboBox();
|
||||||
|
ButtonAssignDropDown2 = new ComboBox();
|
||||||
|
ButtonAssignDropDown3 = new ComboBox();
|
||||||
|
ButtonAssignDropDown4 = new ComboBox();
|
||||||
|
ButtonAssignDropDown5 = new ComboBox();
|
||||||
|
ButtonAssignDropDown6 = new ComboBox();
|
||||||
|
ButtonAssignDropDown7 = new ComboBox();
|
||||||
|
ButtonAssignDropDown8 = new ComboBox();
|
||||||
|
ButtonAssignDropDown9 = new ComboBox();
|
||||||
|
ButtonAssignDropDown10 = new ComboBox();
|
||||||
|
ButtonAssignDropDown11 = new ComboBox();
|
||||||
|
ButtonAssignDropDown12 = new ComboBox();
|
||||||
|
label14 = new Label();
|
||||||
|
label15 = new Label();
|
||||||
|
label16 = new Label();
|
||||||
|
label17 = new Label();
|
||||||
|
label10 = new Label();
|
||||||
|
label11 = new Label();
|
||||||
|
label12 = new Label();
|
||||||
|
label13 = new Label();
|
||||||
|
label8 = new Label();
|
||||||
|
label9 = new Label();
|
||||||
|
label7 = new Label();
|
||||||
|
label6 = new Label();
|
||||||
|
SkitListView = new ListView();
|
||||||
|
NameColumnHeader = new ColumnHeader();
|
||||||
|
LengthColumnHeader = new ColumnHeader();
|
||||||
|
SkitContextMenu = new ContextMenuStrip(components);
|
||||||
|
RemoveButton = new ToolStripMenuItem();
|
||||||
|
SaveButton = new Button();
|
||||||
|
CancelButton = new Button();
|
||||||
|
SelectShowFileDialog = new OpenFileDialog();
|
||||||
|
PlaybackGroupBox = new GroupBox();
|
||||||
|
label20 = new Label();
|
||||||
|
label19 = new Label();
|
||||||
|
label18 = new Label();
|
||||||
|
ResyncTimeOption = new NumericUpDown();
|
||||||
|
FrameShiftOption = new NumericUpDown();
|
||||||
|
FrameSkipOption = new NumericUpDown();
|
||||||
|
PlaylistPlaybackGroupBox.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)IntermissionTimeCounter).BeginInit();
|
||||||
|
ShowSelectorGroupBox.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)CooldownTimeCounter).BeginInit();
|
||||||
|
ShowSelectorAssignmentGroupBox.SuspendLayout();
|
||||||
|
AssignmentPanel.SuspendLayout();
|
||||||
|
SkitContextMenu.SuspendLayout();
|
||||||
|
PlaybackGroupBox.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)ResyncTimeOption).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)FrameShiftOption).BeginInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)FrameSkipOption).BeginInit();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// PlaylistPlaybackGroupBox
|
||||||
|
//
|
||||||
|
PlaylistPlaybackGroupBox.Controls.Add(LoopCheckBox);
|
||||||
|
PlaylistPlaybackGroupBox.Controls.Add(IntermissionUnitDropDown);
|
||||||
|
PlaylistPlaybackGroupBox.Controls.Add(IntermissionTimeCounter);
|
||||||
|
PlaylistPlaybackGroupBox.Controls.Add(IntermissionCheckBox);
|
||||||
|
PlaylistPlaybackGroupBox.Controls.Add(label2);
|
||||||
|
PlaylistPlaybackGroupBox.Controls.Add(ShowEndedDropDown);
|
||||||
|
PlaylistPlaybackGroupBox.Controls.Add(label1);
|
||||||
|
PlaylistPlaybackGroupBox.Controls.Add(PlaylistStartedDropDown);
|
||||||
|
PlaylistPlaybackGroupBox.Location = new Point(12, 12);
|
||||||
|
PlaylistPlaybackGroupBox.Name = "PlaylistPlaybackGroupBox";
|
||||||
|
PlaylistPlaybackGroupBox.Size = new Size(350, 138);
|
||||||
|
PlaylistPlaybackGroupBox.TabIndex = 0;
|
||||||
|
PlaylistPlaybackGroupBox.TabStop = false;
|
||||||
|
PlaylistPlaybackGroupBox.Text = "Playlist Playback";
|
||||||
|
//
|
||||||
|
// LoopCheckBox
|
||||||
|
//
|
||||||
|
LoopCheckBox.AutoSize = true;
|
||||||
|
LoopCheckBox.Location = new Point(6, 111);
|
||||||
|
LoopCheckBox.Name = "LoopCheckBox";
|
||||||
|
LoopCheckBox.Size = new Size(162, 19);
|
||||||
|
LoopCheckBox.TabIndex = 5;
|
||||||
|
LoopCheckBox.Text = "Loop when Playlist is over";
|
||||||
|
LoopCheckBox.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// IntermissionUnitDropDown
|
||||||
|
//
|
||||||
|
IntermissionUnitDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
IntermissionUnitDropDown.FormattingEnabled = true;
|
||||||
|
IntermissionUnitDropDown.Items.AddRange(new object[] { "Minutes", "Seconds" });
|
||||||
|
IntermissionUnitDropDown.Location = new Point(250, 80);
|
||||||
|
IntermissionUnitDropDown.Name = "IntermissionUnitDropDown";
|
||||||
|
IntermissionUnitDropDown.Size = new Size(94, 23);
|
||||||
|
IntermissionUnitDropDown.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// IntermissionTimeCounter
|
||||||
|
//
|
||||||
|
IntermissionTimeCounter.Location = new Point(194, 80);
|
||||||
|
IntermissionTimeCounter.Maximum = new decimal(new int[] { 60, 0, 0, 0 });
|
||||||
|
IntermissionTimeCounter.Name = "IntermissionTimeCounter";
|
||||||
|
IntermissionTimeCounter.Size = new Size(50, 23);
|
||||||
|
IntermissionTimeCounter.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// IntermissionCheckBox
|
||||||
|
//
|
||||||
|
IntermissionCheckBox.AutoSize = true;
|
||||||
|
IntermissionCheckBox.Location = new Point(6, 82);
|
||||||
|
IntermissionCheckBox.Name = "IntermissionCheckBox";
|
||||||
|
IntermissionCheckBox.Size = new Size(135, 19);
|
||||||
|
IntermissionCheckBox.TabIndex = 2;
|
||||||
|
IntermissionCheckBox.Text = "Wait between Shows";
|
||||||
|
IntermissionCheckBox.UseVisualStyleBackColor = true;
|
||||||
|
IntermissionCheckBox.CheckedChanged += IntermissionCheckBox_CheckedChanged;
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
label2.AutoSize = true;
|
||||||
|
label2.Location = new Point(6, 54);
|
||||||
|
label2.Name = "label2";
|
||||||
|
label2.Size = new Size(107, 15);
|
||||||
|
label2.TabIndex = 3;
|
||||||
|
label2.Text = "When a Show ends";
|
||||||
|
//
|
||||||
|
// ShowEndedDropDown
|
||||||
|
//
|
||||||
|
ShowEndedDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ShowEndedDropDown.FormattingEnabled = true;
|
||||||
|
ShowEndedDropDown.Items.AddRange(new object[] { "Play Next Show", "Play Random Show", "Repeat Show", "Stop Playlist" });
|
||||||
|
ShowEndedDropDown.Location = new Point(194, 51);
|
||||||
|
ShowEndedDropDown.Name = "ShowEndedDropDown";
|
||||||
|
ShowEndedDropDown.Size = new Size(150, 23);
|
||||||
|
ShowEndedDropDown.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(6, 25);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(128, 15);
|
||||||
|
label1.TabIndex = 1;
|
||||||
|
label1.Text = "When Playlist is started";
|
||||||
|
//
|
||||||
|
// PlaylistStartedDropDown
|
||||||
|
//
|
||||||
|
PlaylistStartedDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
PlaylistStartedDropDown.FormattingEnabled = true;
|
||||||
|
PlaylistStartedDropDown.Items.AddRange(new object[] { "Play First Show", "Play Random Show" });
|
||||||
|
PlaylistStartedDropDown.Location = new Point(194, 22);
|
||||||
|
PlaylistStartedDropDown.Name = "PlaylistStartedDropDown";
|
||||||
|
PlaylistStartedDropDown.Size = new Size(150, 23);
|
||||||
|
PlaylistStartedDropDown.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// ShowSelectorGroupBox
|
||||||
|
//
|
||||||
|
ShowSelectorGroupBox.Controls.Add(AddSkitButton);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(SkitCheckBox);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(label5);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(AlreadyPlayingDropDown);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(CooldownUnitDropDown);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(CooldownTimeCounter);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(CooldownCheckBox);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(label3);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(SelectedShowEndDropDown);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(label4);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(ButtonPressDropDown);
|
||||||
|
ShowSelectorGroupBox.Location = new Point(12, 156);
|
||||||
|
ShowSelectorGroupBox.Name = "ShowSelectorGroupBox";
|
||||||
|
ShowSelectorGroupBox.Size = new Size(350, 165);
|
||||||
|
ShowSelectorGroupBox.TabIndex = 1;
|
||||||
|
ShowSelectorGroupBox.TabStop = false;
|
||||||
|
ShowSelectorGroupBox.Text = "Show Selector";
|
||||||
|
//
|
||||||
|
// AddSkitButton
|
||||||
|
//
|
||||||
|
AddSkitButton.Location = new Point(250, 136);
|
||||||
|
AddSkitButton.Name = "AddSkitButton";
|
||||||
|
AddSkitButton.Size = new Size(94, 23);
|
||||||
|
AddSkitButton.TabIndex = 7;
|
||||||
|
AddSkitButton.Text = "Add Skit";
|
||||||
|
AddSkitButton.UseVisualStyleBackColor = true;
|
||||||
|
AddSkitButton.Click += AddSkitButton_Click;
|
||||||
|
//
|
||||||
|
// SkitCheckBox
|
||||||
|
//
|
||||||
|
SkitCheckBox.AutoSize = true;
|
||||||
|
SkitCheckBox.Location = new Point(6, 138);
|
||||||
|
SkitCheckBox.Name = "SkitCheckBox";
|
||||||
|
SkitCheckBox.Size = new Size(231, 19);
|
||||||
|
SkitCheckBox.TabIndex = 6;
|
||||||
|
SkitCheckBox.Text = "Play random Skit before Selected Show";
|
||||||
|
SkitCheckBox.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// label5
|
||||||
|
//
|
||||||
|
label5.AutoSize = true;
|
||||||
|
label5.Location = new Point(6, 54);
|
||||||
|
label5.Name = "label5";
|
||||||
|
label5.Size = new Size(149, 15);
|
||||||
|
label5.TabIndex = 8;
|
||||||
|
label5.Text = "If a Show is already playing";
|
||||||
|
//
|
||||||
|
// AlreadyPlayingDropDown
|
||||||
|
//
|
||||||
|
AlreadyPlayingDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
AlreadyPlayingDropDown.FormattingEnabled = true;
|
||||||
|
AlreadyPlayingDropDown.Items.AddRange(new object[] { "Stop current", "Play after finished", "Ignore button" });
|
||||||
|
AlreadyPlayingDropDown.Location = new Point(194, 51);
|
||||||
|
AlreadyPlayingDropDown.Name = "AlreadyPlayingDropDown";
|
||||||
|
AlreadyPlayingDropDown.Size = new Size(150, 23);
|
||||||
|
AlreadyPlayingDropDown.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// CooldownUnitDropDown
|
||||||
|
//
|
||||||
|
CooldownUnitDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
CooldownUnitDropDown.FormattingEnabled = true;
|
||||||
|
CooldownUnitDropDown.Items.AddRange(new object[] { "Minutes", "Seconds" });
|
||||||
|
CooldownUnitDropDown.Location = new Point(250, 107);
|
||||||
|
CooldownUnitDropDown.Name = "CooldownUnitDropDown";
|
||||||
|
CooldownUnitDropDown.Size = new Size(94, 23);
|
||||||
|
CooldownUnitDropDown.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// CooldownTimeCounter
|
||||||
|
//
|
||||||
|
CooldownTimeCounter.Location = new Point(194, 107);
|
||||||
|
CooldownTimeCounter.Maximum = new decimal(new int[] { 60, 0, 0, 0 });
|
||||||
|
CooldownTimeCounter.Name = "CooldownTimeCounter";
|
||||||
|
CooldownTimeCounter.Size = new Size(50, 23);
|
||||||
|
CooldownTimeCounter.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// CooldownCheckBox
|
||||||
|
//
|
||||||
|
CooldownCheckBox.AutoSize = true;
|
||||||
|
CooldownCheckBox.Location = new Point(6, 109);
|
||||||
|
CooldownCheckBox.Name = "CooldownCheckBox";
|
||||||
|
CooldownCheckBox.Size = new Size(185, 19);
|
||||||
|
CooldownCheckBox.TabIndex = 3;
|
||||||
|
CooldownCheckBox.Text = "Cooldown between Selections";
|
||||||
|
CooldownCheckBox.UseVisualStyleBackColor = true;
|
||||||
|
CooldownCheckBox.CheckedChanged += CooldownCheckBox_CheckedChanged;
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
label3.AutoSize = true;
|
||||||
|
label3.Location = new Point(6, 83);
|
||||||
|
label3.Name = "label3";
|
||||||
|
label3.Size = new Size(154, 15);
|
||||||
|
label3.TabIndex = 3;
|
||||||
|
label3.Text = "When a Selected Show ends";
|
||||||
|
//
|
||||||
|
// SelectedShowEndDropDown
|
||||||
|
//
|
||||||
|
SelectedShowEndDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
SelectedShowEndDropDown.FormattingEnabled = true;
|
||||||
|
SelectedShowEndDropDown.Items.AddRange(new object[] { "Return to Playlist", "Do Nothing" });
|
||||||
|
SelectedShowEndDropDown.Location = new Point(194, 80);
|
||||||
|
SelectedShowEndDropDown.Name = "SelectedShowEndDropDown";
|
||||||
|
SelectedShowEndDropDown.Size = new Size(150, 23);
|
||||||
|
SelectedShowEndDropDown.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// label4
|
||||||
|
//
|
||||||
|
label4.AutoSize = true;
|
||||||
|
label4.Location = new Point(6, 25);
|
||||||
|
label4.Name = "label4";
|
||||||
|
label4.Size = new Size(140, 15);
|
||||||
|
label4.TabIndex = 1;
|
||||||
|
label4.Text = "When a Button is pressed";
|
||||||
|
//
|
||||||
|
// ButtonPressDropDown
|
||||||
|
//
|
||||||
|
ButtonPressDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonPressDropDown.FormattingEnabled = true;
|
||||||
|
ButtonPressDropDown.Items.AddRange(new object[] { "Play Assigned Show", "Play Random Show" });
|
||||||
|
ButtonPressDropDown.Location = new Point(194, 22);
|
||||||
|
ButtonPressDropDown.Name = "ButtonPressDropDown";
|
||||||
|
ButtonPressDropDown.Size = new Size(150, 23);
|
||||||
|
ButtonPressDropDown.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// ShowSelectorAssignmentGroupBox
|
||||||
|
//
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(AssignmentPanel);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label14);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label15);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label16);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label17);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label10);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label11);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label12);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label13);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label8);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label9);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label7);
|
||||||
|
ShowSelectorAssignmentGroupBox.Controls.Add(label6);
|
||||||
|
ShowSelectorAssignmentGroupBox.Location = new Point(368, 12);
|
||||||
|
ShowSelectorAssignmentGroupBox.Name = "ShowSelectorAssignmentGroupBox";
|
||||||
|
ShowSelectorAssignmentGroupBox.Size = new Size(256, 370);
|
||||||
|
ShowSelectorAssignmentGroupBox.TabIndex = 3;
|
||||||
|
ShowSelectorAssignmentGroupBox.TabStop = false;
|
||||||
|
ShowSelectorAssignmentGroupBox.Text = "Show Selector Assignment";
|
||||||
|
//
|
||||||
|
// AssignmentPanel
|
||||||
|
//
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown1);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown2);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown3);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown4);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown5);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown6);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown7);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown8);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown9);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown10);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown11);
|
||||||
|
AssignmentPanel.Controls.Add(ButtonAssignDropDown12);
|
||||||
|
AssignmentPanel.Location = new Point(100, 22);
|
||||||
|
AssignmentPanel.Name = "AssignmentPanel";
|
||||||
|
AssignmentPanel.Size = new Size(150, 342);
|
||||||
|
AssignmentPanel.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown1
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown1.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown1.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown1.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown1.Location = new Point(0, 0);
|
||||||
|
ButtonAssignDropDown1.Name = "ButtonAssignDropDown1";
|
||||||
|
ButtonAssignDropDown1.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown1.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown2
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown2.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown2.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown2.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown2.Location = new Point(0, 29);
|
||||||
|
ButtonAssignDropDown2.Name = "ButtonAssignDropDown2";
|
||||||
|
ButtonAssignDropDown2.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown2.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown3
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown3.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown3.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown3.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown3.Location = new Point(0, 58);
|
||||||
|
ButtonAssignDropDown3.Name = "ButtonAssignDropDown3";
|
||||||
|
ButtonAssignDropDown3.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown3.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown4
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown4.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown4.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown4.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown4.Location = new Point(0, 87);
|
||||||
|
ButtonAssignDropDown4.Name = "ButtonAssignDropDown4";
|
||||||
|
ButtonAssignDropDown4.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown4.TabIndex = 3;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown5
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown5.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown5.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown5.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown5.Location = new Point(0, 116);
|
||||||
|
ButtonAssignDropDown5.Name = "ButtonAssignDropDown5";
|
||||||
|
ButtonAssignDropDown5.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown5.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown6
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown6.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown6.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown6.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown6.Location = new Point(0, 145);
|
||||||
|
ButtonAssignDropDown6.Name = "ButtonAssignDropDown6";
|
||||||
|
ButtonAssignDropDown6.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown6.TabIndex = 5;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown7
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown7.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown7.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown7.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown7.Location = new Point(0, 174);
|
||||||
|
ButtonAssignDropDown7.Name = "ButtonAssignDropDown7";
|
||||||
|
ButtonAssignDropDown7.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown7.TabIndex = 6;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown8
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown8.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown8.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown8.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown8.Location = new Point(0, 203);
|
||||||
|
ButtonAssignDropDown8.Name = "ButtonAssignDropDown8";
|
||||||
|
ButtonAssignDropDown8.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown8.TabIndex = 7;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown9
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown9.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown9.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown9.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown9.Location = new Point(0, 232);
|
||||||
|
ButtonAssignDropDown9.Name = "ButtonAssignDropDown9";
|
||||||
|
ButtonAssignDropDown9.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown9.TabIndex = 8;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown10
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown10.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown10.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown10.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown10.Location = new Point(0, 261);
|
||||||
|
ButtonAssignDropDown10.Name = "ButtonAssignDropDown10";
|
||||||
|
ButtonAssignDropDown10.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown10.TabIndex = 9;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown11
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown11.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown11.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown11.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown11.Location = new Point(0, 290);
|
||||||
|
ButtonAssignDropDown11.Name = "ButtonAssignDropDown11";
|
||||||
|
ButtonAssignDropDown11.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown11.TabIndex = 10;
|
||||||
|
//
|
||||||
|
// ButtonAssignDropDown12
|
||||||
|
//
|
||||||
|
ButtonAssignDropDown12.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
ButtonAssignDropDown12.FormattingEnabled = true;
|
||||||
|
ButtonAssignDropDown12.Items.AddRange(new object[] { "(None)" });
|
||||||
|
ButtonAssignDropDown12.Location = new Point(0, 319);
|
||||||
|
ButtonAssignDropDown12.Name = "ButtonAssignDropDown12";
|
||||||
|
ButtonAssignDropDown12.Size = new Size(150, 23);
|
||||||
|
ButtonAssignDropDown12.TabIndex = 11;
|
||||||
|
//
|
||||||
|
// label14
|
||||||
|
//
|
||||||
|
label14.AutoSize = true;
|
||||||
|
label14.Location = new Point(6, 344);
|
||||||
|
label14.Name = "label14";
|
||||||
|
label14.Size = new Size(58, 15);
|
||||||
|
label14.TabIndex = 30;
|
||||||
|
label14.Text = "Button 12";
|
||||||
|
//
|
||||||
|
// label15
|
||||||
|
//
|
||||||
|
label15.AutoSize = true;
|
||||||
|
label15.Location = new Point(6, 315);
|
||||||
|
label15.Name = "label15";
|
||||||
|
label15.Size = new Size(58, 15);
|
||||||
|
label15.TabIndex = 28;
|
||||||
|
label15.Text = "Button 11";
|
||||||
|
//
|
||||||
|
// label16
|
||||||
|
//
|
||||||
|
label16.AutoSize = true;
|
||||||
|
label16.Location = new Point(6, 286);
|
||||||
|
label16.Name = "label16";
|
||||||
|
label16.Size = new Size(58, 15);
|
||||||
|
label16.TabIndex = 26;
|
||||||
|
label16.Text = "Button 10";
|
||||||
|
//
|
||||||
|
// label17
|
||||||
|
//
|
||||||
|
label17.AutoSize = true;
|
||||||
|
label17.Location = new Point(6, 257);
|
||||||
|
label17.Name = "label17";
|
||||||
|
label17.Size = new Size(52, 15);
|
||||||
|
label17.TabIndex = 24;
|
||||||
|
label17.Text = "Button 9";
|
||||||
|
//
|
||||||
|
// label10
|
||||||
|
//
|
||||||
|
label10.AutoSize = true;
|
||||||
|
label10.Location = new Point(6, 228);
|
||||||
|
label10.Name = "label10";
|
||||||
|
label10.Size = new Size(52, 15);
|
||||||
|
label10.TabIndex = 22;
|
||||||
|
label10.Text = "Button 8";
|
||||||
|
//
|
||||||
|
// label11
|
||||||
|
//
|
||||||
|
label11.AutoSize = true;
|
||||||
|
label11.Location = new Point(6, 199);
|
||||||
|
label11.Name = "label11";
|
||||||
|
label11.Size = new Size(52, 15);
|
||||||
|
label11.TabIndex = 20;
|
||||||
|
label11.Text = "Button 7";
|
||||||
|
//
|
||||||
|
// label12
|
||||||
|
//
|
||||||
|
label12.AutoSize = true;
|
||||||
|
label12.Location = new Point(6, 170);
|
||||||
|
label12.Name = "label12";
|
||||||
|
label12.Size = new Size(52, 15);
|
||||||
|
label12.TabIndex = 18;
|
||||||
|
label12.Text = "Button 6";
|
||||||
|
//
|
||||||
|
// label13
|
||||||
|
//
|
||||||
|
label13.AutoSize = true;
|
||||||
|
label13.Location = new Point(6, 141);
|
||||||
|
label13.Name = "label13";
|
||||||
|
label13.Size = new Size(52, 15);
|
||||||
|
label13.TabIndex = 16;
|
||||||
|
label13.Text = "Button 5";
|
||||||
|
//
|
||||||
|
// label8
|
||||||
|
//
|
||||||
|
label8.AutoSize = true;
|
||||||
|
label8.Location = new Point(6, 112);
|
||||||
|
label8.Name = "label8";
|
||||||
|
label8.Size = new Size(52, 15);
|
||||||
|
label8.TabIndex = 14;
|
||||||
|
label8.Text = "Button 4";
|
||||||
|
//
|
||||||
|
// label9
|
||||||
|
//
|
||||||
|
label9.AutoSize = true;
|
||||||
|
label9.Location = new Point(6, 83);
|
||||||
|
label9.Name = "label9";
|
||||||
|
label9.Size = new Size(52, 15);
|
||||||
|
label9.TabIndex = 12;
|
||||||
|
label9.Text = "Button 3";
|
||||||
|
//
|
||||||
|
// label7
|
||||||
|
//
|
||||||
|
label7.AutoSize = true;
|
||||||
|
label7.Location = new Point(6, 54);
|
||||||
|
label7.Name = "label7";
|
||||||
|
label7.Size = new Size(52, 15);
|
||||||
|
label7.TabIndex = 10;
|
||||||
|
label7.Text = "Button 2";
|
||||||
|
//
|
||||||
|
// label6
|
||||||
|
//
|
||||||
|
label6.AutoSize = true;
|
||||||
|
label6.Location = new Point(6, 25);
|
||||||
|
label6.Name = "label6";
|
||||||
|
label6.Size = new Size(52, 15);
|
||||||
|
label6.TabIndex = 8;
|
||||||
|
label6.Text = "Button 1";
|
||||||
|
//
|
||||||
|
// SkitListView
|
||||||
|
//
|
||||||
|
SkitListView.AutoArrange = false;
|
||||||
|
SkitListView.Columns.AddRange(new ColumnHeader[] { NameColumnHeader, LengthColumnHeader });
|
||||||
|
SkitListView.ContextMenuStrip = SkitContextMenu;
|
||||||
|
SkitListView.GridLines = true;
|
||||||
|
SkitListView.HeaderStyle = ColumnHeaderStyle.Nonclickable;
|
||||||
|
SkitListView.Location = new Point(12, 327);
|
||||||
|
SkitListView.MultiSelect = false;
|
||||||
|
SkitListView.Name = "SkitListView";
|
||||||
|
SkitListView.Size = new Size(350, 201);
|
||||||
|
SkitListView.TabIndex = 2;
|
||||||
|
SkitListView.UseCompatibleStateImageBehavior = false;
|
||||||
|
SkitListView.View = View.Details;
|
||||||
|
//
|
||||||
|
// NameColumnHeader
|
||||||
|
//
|
||||||
|
NameColumnHeader.Text = "Skit Name";
|
||||||
|
NameColumnHeader.Width = 260;
|
||||||
|
//
|
||||||
|
// LengthColumnHeader
|
||||||
|
//
|
||||||
|
LengthColumnHeader.Text = "Length";
|
||||||
|
//
|
||||||
|
// SkitContextMenu
|
||||||
|
//
|
||||||
|
SkitContextMenu.Items.AddRange(new ToolStripItem[] { RemoveButton });
|
||||||
|
SkitContextMenu.Name = "ShowContextMenu";
|
||||||
|
SkitContextMenu.Size = new Size(118, 26);
|
||||||
|
//
|
||||||
|
// RemoveButton
|
||||||
|
//
|
||||||
|
RemoveButton.Name = "RemoveButton";
|
||||||
|
RemoveButton.Size = new Size(117, 22);
|
||||||
|
RemoveButton.Text = "Remove";
|
||||||
|
RemoveButton.Click += RemoveButton_Click;
|
||||||
|
//
|
||||||
|
// SaveButton
|
||||||
|
//
|
||||||
|
SaveButton.DialogResult = DialogResult.OK;
|
||||||
|
SaveButton.Location = new Point(549, 503);
|
||||||
|
SaveButton.Name = "SaveButton";
|
||||||
|
SaveButton.Size = new Size(75, 25);
|
||||||
|
SaveButton.TabIndex = 10;
|
||||||
|
SaveButton.Text = "Save";
|
||||||
|
SaveButton.UseVisualStyleBackColor = true;
|
||||||
|
SaveButton.Click += SaveButton_Click;
|
||||||
|
//
|
||||||
|
// CancelButton
|
||||||
|
//
|
||||||
|
CancelButton.DialogResult = DialogResult.Cancel;
|
||||||
|
CancelButton.Location = new Point(468, 503);
|
||||||
|
CancelButton.Name = "CancelButton";
|
||||||
|
CancelButton.Size = new Size(75, 25);
|
||||||
|
CancelButton.TabIndex = 11;
|
||||||
|
CancelButton.Text = "Cancel";
|
||||||
|
CancelButton.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// SelectShowFileDialog
|
||||||
|
//
|
||||||
|
SelectShowFileDialog.Filter = "UST Showtapes|*.ust";
|
||||||
|
SelectShowFileDialog.Multiselect = true;
|
||||||
|
//
|
||||||
|
// PlaybackGroupBox
|
||||||
|
//
|
||||||
|
PlaybackGroupBox.Controls.Add(label20);
|
||||||
|
PlaybackGroupBox.Controls.Add(label19);
|
||||||
|
PlaybackGroupBox.Controls.Add(label18);
|
||||||
|
PlaybackGroupBox.Controls.Add(ResyncTimeOption);
|
||||||
|
PlaybackGroupBox.Controls.Add(FrameShiftOption);
|
||||||
|
PlaybackGroupBox.Controls.Add(FrameSkipOption);
|
||||||
|
PlaybackGroupBox.Location = new Point(368, 388);
|
||||||
|
PlaybackGroupBox.Name = "PlaybackGroupBox";
|
||||||
|
PlaybackGroupBox.Size = new Size(256, 109);
|
||||||
|
PlaybackGroupBox.TabIndex = 4;
|
||||||
|
PlaybackGroupBox.TabStop = false;
|
||||||
|
PlaybackGroupBox.Text = "Tracking Adjustments";
|
||||||
|
//
|
||||||
|
// label20
|
||||||
|
//
|
||||||
|
label20.AutoSize = true;
|
||||||
|
label20.Location = new Point(6, 82);
|
||||||
|
label20.Name = "label20";
|
||||||
|
label20.Size = new Size(67, 15);
|
||||||
|
label20.TabIndex = 5;
|
||||||
|
label20.Text = "Frame Shift";
|
||||||
|
//
|
||||||
|
// label19
|
||||||
|
//
|
||||||
|
label19.AutoSize = true;
|
||||||
|
label19.Location = new Point(6, 53);
|
||||||
|
label19.Name = "label19";
|
||||||
|
label19.Size = new Size(73, 15);
|
||||||
|
label19.TabIndex = 4;
|
||||||
|
label19.Text = "Resync Time";
|
||||||
|
//
|
||||||
|
// label18
|
||||||
|
//
|
||||||
|
label18.AutoSize = true;
|
||||||
|
label18.Location = new Point(6, 24);
|
||||||
|
label18.Name = "label18";
|
||||||
|
label18.Size = new Size(65, 15);
|
||||||
|
label18.TabIndex = 3;
|
||||||
|
label18.Text = "Frame Skip";
|
||||||
|
//
|
||||||
|
// ResyncTimeOption
|
||||||
|
//
|
||||||
|
ResyncTimeOption.Location = new Point(200, 51);
|
||||||
|
ResyncTimeOption.Maximum = new decimal(new int[] { 60, 0, 0, 0 });
|
||||||
|
ResyncTimeOption.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
ResyncTimeOption.Name = "ResyncTimeOption";
|
||||||
|
ResyncTimeOption.Size = new Size(50, 23);
|
||||||
|
ResyncTimeOption.TabIndex = 1;
|
||||||
|
ResyncTimeOption.Value = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
//
|
||||||
|
// FrameShiftOption
|
||||||
|
//
|
||||||
|
FrameShiftOption.Location = new Point(200, 80);
|
||||||
|
FrameShiftOption.Maximum = new decimal(new int[] { 60, 0, 0, 0 });
|
||||||
|
FrameShiftOption.Minimum = new decimal(new int[] { 60, 0, 0, int.MinValue });
|
||||||
|
FrameShiftOption.Name = "FrameShiftOption";
|
||||||
|
FrameShiftOption.Size = new Size(50, 23);
|
||||||
|
FrameShiftOption.TabIndex = 2;
|
||||||
|
//
|
||||||
|
// FrameSkipOption
|
||||||
|
//
|
||||||
|
FrameSkipOption.Location = new Point(200, 22);
|
||||||
|
FrameSkipOption.Maximum = new decimal(new int[] { 10, 0, 0, 0 });
|
||||||
|
FrameSkipOption.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
FrameSkipOption.Name = "FrameSkipOption";
|
||||||
|
FrameSkipOption.Size = new Size(50, 23);
|
||||||
|
FrameSkipOption.TabIndex = 0;
|
||||||
|
FrameSkipOption.Value = new decimal(new int[] { 1, 0, 0, 0 });
|
||||||
|
//
|
||||||
|
// AdvancedSettingsForm
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(636, 540);
|
||||||
|
Controls.Add(PlaybackGroupBox);
|
||||||
|
Controls.Add(CancelButton);
|
||||||
|
Controls.Add(SaveButton);
|
||||||
|
Controls.Add(SkitListView);
|
||||||
|
Controls.Add(ShowSelectorAssignmentGroupBox);
|
||||||
|
Controls.Add(ShowSelectorGroupBox);
|
||||||
|
Controls.Add(PlaylistPlaybackGroupBox);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
MaximizeBox = false;
|
||||||
|
Name = "AdvancedSettingsForm";
|
||||||
|
Text = "Advanced Settings";
|
||||||
|
PlaylistPlaybackGroupBox.ResumeLayout(false);
|
||||||
|
PlaylistPlaybackGroupBox.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)IntermissionTimeCounter).EndInit();
|
||||||
|
ShowSelectorGroupBox.ResumeLayout(false);
|
||||||
|
ShowSelectorGroupBox.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)CooldownTimeCounter).EndInit();
|
||||||
|
ShowSelectorAssignmentGroupBox.ResumeLayout(false);
|
||||||
|
ShowSelectorAssignmentGroupBox.PerformLayout();
|
||||||
|
AssignmentPanel.ResumeLayout(false);
|
||||||
|
SkitContextMenu.ResumeLayout(false);
|
||||||
|
PlaybackGroupBox.ResumeLayout(false);
|
||||||
|
PlaybackGroupBox.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)ResyncTimeOption).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)FrameShiftOption).EndInit();
|
||||||
|
((System.ComponentModel.ISupportInitialize)FrameSkipOption).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private GroupBox PlaylistPlaybackGroupBox;
|
||||||
|
private Label label1;
|
||||||
|
private ComboBox PlaylistStartedDropDown;
|
||||||
|
private ComboBox ShowEndedDropDown;
|
||||||
|
private ComboBox IntermissionUnitDropDown;
|
||||||
|
private NumericUpDown IntermissionTimeCounter;
|
||||||
|
private CheckBox IntermissionCheckBox;
|
||||||
|
private Label label2;
|
||||||
|
private GroupBox ShowSelectorGroupBox;
|
||||||
|
private ComboBox CooldownUnitDropDown;
|
||||||
|
private NumericUpDown CooldownTimeCounter;
|
||||||
|
private CheckBox CooldownCheckBox;
|
||||||
|
private Label label3;
|
||||||
|
private ComboBox SelectedShowEndDropDown;
|
||||||
|
private Label label4;
|
||||||
|
private ComboBox ButtonPressDropDown;
|
||||||
|
private Label label5;
|
||||||
|
private ComboBox AlreadyPlayingDropDown;
|
||||||
|
private CheckBox SkitCheckBox;
|
||||||
|
private Button AddSkitButton;
|
||||||
|
private GroupBox ShowSelectorAssignmentGroupBox;
|
||||||
|
private Label label14;
|
||||||
|
private ComboBox ButtonAssignDropDown12;
|
||||||
|
private Label label15;
|
||||||
|
private ComboBox ButtonAssignDropDown11;
|
||||||
|
private Label label16;
|
||||||
|
private ComboBox ButtonAssignDropDown10;
|
||||||
|
private Label label17;
|
||||||
|
private ComboBox ButtonAssignDropDown9;
|
||||||
|
private Label label10;
|
||||||
|
private ComboBox ButtonAssignDropDown8;
|
||||||
|
private Label label11;
|
||||||
|
private ComboBox ButtonAssignDropDown7;
|
||||||
|
private Label label12;
|
||||||
|
private ComboBox ButtonAssignDropDown6;
|
||||||
|
private Label label13;
|
||||||
|
private ComboBox ButtonAssignDropDown5;
|
||||||
|
private Label label8;
|
||||||
|
private ComboBox ButtonAssignDropDown4;
|
||||||
|
private Label label9;
|
||||||
|
private ComboBox ButtonAssignDropDown3;
|
||||||
|
private Label label7;
|
||||||
|
private ComboBox ButtonAssignDropDown2;
|
||||||
|
private Label label6;
|
||||||
|
private ComboBox ButtonAssignDropDown1;
|
||||||
|
private ListView SkitListView;
|
||||||
|
private ColumnHeader NameColumnHeader;
|
||||||
|
private ColumnHeader LengthColumnHeader;
|
||||||
|
private Button SaveButton;
|
||||||
|
private Button CancelButton;
|
||||||
|
private ContextMenuStrip SkitContextMenu;
|
||||||
|
private ToolStripMenuItem RemoveButton;
|
||||||
|
private OpenFileDialog SelectShowFileDialog;
|
||||||
|
private Panel AssignmentPanel;
|
||||||
|
private CheckBox LoopCheckBox;
|
||||||
|
private GroupBox PlaybackGroupBox;
|
||||||
|
private Label label18;
|
||||||
|
private NumericUpDown ResyncTimeOption;
|
||||||
|
private NumericUpDown FrameShiftOption;
|
||||||
|
private NumericUpDown FrameSkipOption;
|
||||||
|
private Label label20;
|
||||||
|
private Label label19;
|
||||||
|
}
|
||||||
|
}
|
146
PC3Player/PC3Player/AdvancedSettingsForm.cs
Normal file
146
PC3Player/PC3Player/AdvancedSettingsForm.cs
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
namespace PC3Player
|
||||||
|
{
|
||||||
|
public partial class AdvancedSettingsForm : Form
|
||||||
|
{
|
||||||
|
public PlaylistConfig EditingObject { get; set; }
|
||||||
|
public AdvancedSettingsForm(PlaylistConfig playlist)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
EditingObject = playlist;
|
||||||
|
|
||||||
|
PlaylistStartedDropDown.SelectedIndex = EditingObject.PlaylistStartOption;
|
||||||
|
ShowEndedDropDown.SelectedIndex = EditingObject.PlaylistShowEndOption;
|
||||||
|
IntermissionCheckBox.Checked = EditingObject.PlaylistIntermissionOption;
|
||||||
|
IntermissionTimeCounter.Value = EditingObject.PlaylistIntermissionTimeOption;
|
||||||
|
IntermissionUnitDropDown.SelectedIndex = EditingObject.PlaylistIntermissionUnitOption;
|
||||||
|
LoopCheckBox.Checked = EditingObject.PlaylistLoopOption;
|
||||||
|
|
||||||
|
ButtonPressDropDown.SelectedIndex = EditingObject.SelectorButtonPressOption;
|
||||||
|
AlreadyPlayingDropDown.SelectedIndex = EditingObject.SelectorShowAlreadyPlayingOption;
|
||||||
|
SelectedShowEndDropDown.SelectedIndex = EditingObject.SelectorShowEndOption;
|
||||||
|
CooldownCheckBox.Checked = EditingObject.SelectorCooldownOption;
|
||||||
|
CooldownTimeCounter.Value = EditingObject.SelectorCooldownTimeOption;
|
||||||
|
CooldownUnitDropDown.SelectedIndex = EditingObject.SelectorCooldownUnitOption;
|
||||||
|
SkitCheckBox.Checked = EditingObject.SelectorPlaySkitOption;
|
||||||
|
|
||||||
|
FrameSkipOption.Value = EditingObject.FramesPerTick;
|
||||||
|
FrameShiftOption.Value = EditingObject.FrameShift;
|
||||||
|
ResyncTimeOption.Value = EditingObject.ResyncSeconds;
|
||||||
|
|
||||||
|
IntermissionTimeCounter.Enabled = IntermissionCheckBox.Checked;
|
||||||
|
IntermissionUnitDropDown.Enabled = IntermissionCheckBox.Checked;
|
||||||
|
|
||||||
|
CooldownTimeCounter.Enabled = CooldownCheckBox.Checked;
|
||||||
|
CooldownUnitDropDown.Enabled = CooldownCheckBox.Checked;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
foreach (ComboBox c in AssignmentPanel.Controls)
|
||||||
|
{
|
||||||
|
foreach (PlaylistShow s in EditingObject.Shows) c.Items.Add(s.Name);
|
||||||
|
if (EditingObject.SelectorAssignments[i] == null) c.SelectedIndex = 0;
|
||||||
|
else c.SelectedIndex = (int)EditingObject.SelectorAssignments[i] + 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateListView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateListView()
|
||||||
|
{
|
||||||
|
SkitListView.Items.Clear();
|
||||||
|
foreach (PlaylistShow s in EditingObject.Skits) SkitListView.Items.Add(new ListViewItem(new[] { s.Name, s.Length }));
|
||||||
|
SkitCheckBox.Enabled = EditingObject.Skits.Count != 0;
|
||||||
|
if (EditingObject.Skits.Count == 0) SkitCheckBox.Checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IntermissionCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
IntermissionTimeCounter.Enabled = IntermissionCheckBox.Checked;
|
||||||
|
IntermissionUnitDropDown.Enabled = IntermissionCheckBox.Checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CooldownCheckBox_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
CooldownTimeCounter.Enabled = CooldownCheckBox.Checked;
|
||||||
|
CooldownUnitDropDown.Enabled = CooldownCheckBox.Checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (SkitListView.SelectedIndices.Count == 0) return;
|
||||||
|
EditingObject.Skits.RemoveAt(SkitListView.SelectedIndices[0]);
|
||||||
|
UpdateListView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddSkitButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!MainForm.ChannelMappingLoaded)
|
||||||
|
{
|
||||||
|
MessageBox.Show("You must load a channel mapping first.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SelectShowFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
string tempUSTData = File.ReadAllText(SelectShowFileDialog.FileName);
|
||||||
|
if (!tempUSTData.StartsWith("UST,2,"))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Selected showtape is not a UST version 2 showtape.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] headerData = tempUSTData.Split(';')[0].Split(',');
|
||||||
|
string[] stringyBits = tempUSTData.Split(';')[1].Split(',');
|
||||||
|
|
||||||
|
TimeSpan time = TimeSpan.FromSeconds(stringyBits.Length / 60);
|
||||||
|
string formattedLength = time.ToString(@"hh\:mm\:ss");
|
||||||
|
|
||||||
|
tempUSTData = null;
|
||||||
|
stringyBits = null;
|
||||||
|
|
||||||
|
if (headerData[3] != EditingObject.Mapping.Type)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
$"Selected showtape type does not match the loaded Channel Map." +
|
||||||
|
$"\nLoaded Channel Map Type: {EditingObject.Mapping.Type}" +
|
||||||
|
$"\nShowtape Type: {headerData[3]}"
|
||||||
|
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditingObject.Skits.Add(new PlaylistShow(headerData[2], formattedLength, headerData[3], SelectShowFileDialog.FileName));
|
||||||
|
UpdateListView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
EditingObject.PlaylistStartOption = PlaylistStartedDropDown.SelectedIndex;
|
||||||
|
EditingObject.PlaylistShowEndOption = ShowEndedDropDown.SelectedIndex;
|
||||||
|
EditingObject.PlaylistIntermissionOption = IntermissionCheckBox.Checked;
|
||||||
|
EditingObject.PlaylistIntermissionTimeOption = (int)IntermissionTimeCounter.Value;
|
||||||
|
EditingObject.PlaylistIntermissionUnitOption = IntermissionUnitDropDown.SelectedIndex;
|
||||||
|
EditingObject.PlaylistLoopOption = LoopCheckBox.Checked;
|
||||||
|
|
||||||
|
EditingObject.SelectorButtonPressOption = ButtonPressDropDown.SelectedIndex;
|
||||||
|
EditingObject.SelectorShowAlreadyPlayingOption = AlreadyPlayingDropDown.SelectedIndex;
|
||||||
|
EditingObject.SelectorShowEndOption = SelectedShowEndDropDown.SelectedIndex;
|
||||||
|
EditingObject.SelectorCooldownOption = CooldownCheckBox.Checked;
|
||||||
|
EditingObject.SelectorCooldownTimeOption = (int)CooldownTimeCounter.Value;
|
||||||
|
EditingObject.SelectorCooldownUnitOption = CooldownUnitDropDown.SelectedIndex;
|
||||||
|
EditingObject.SelectorPlaySkitOption = SkitCheckBox.Checked;
|
||||||
|
|
||||||
|
EditingObject.ResyncSeconds = (int)ResyncTimeOption.Value;
|
||||||
|
EditingObject.FrameShift = (int)FrameShiftOption.Value;
|
||||||
|
EditingObject.FramesPerTick = (int)FrameSkipOption.Value;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
foreach (ComboBox c in AssignmentPanel.Controls)
|
||||||
|
{
|
||||||
|
if (c.SelectedIndex == 0) EditingObject.SelectorAssignments[i] = null;
|
||||||
|
else EditingObject.SelectorAssignments[i] = c.SelectedIndex - 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
126
PC3Player/PC3Player/AdvancedSettingsForm.resx
Normal file
126
PC3Player/PC3Player/AdvancedSettingsForm.resx
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="SkitContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>51, 28</value>
|
||||||
|
</metadata>
|
||||||
|
<metadata name="SelectShowFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>215, 23</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
1
PC3Player/PC3Player/Channel Mappings/BeachBearJasper.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/BeachBearJasper.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Beach Bear/Jasper,Rockafire Explosion/3-Stage;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;0
|
1
PC3Player/PC3Player/Channel Mappings/BillyBob.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/BillyBob.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Billy Bob,Rockafire Explosion/3-Stage;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;0
|
1
PC3Player/PC3Player/Channel Mappings/CyberChuck.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/CyberChuck.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Cyberamic Chuck E.,Cyberamics;1,2,3,4,5,6,7,8;0
|
1
PC3Player/PC3Player/Channel Mappings/CyberHelen.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/CyberHelen.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Cyberamic Helen,Cyberamics;9,10,11,12,13,14,15,16;0
|
1
PC3Player/PC3Player/Channel Mappings/CyberJasper.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/CyberJasper.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Cyberamic Jasper,Cyberamics;25,26,27,28,29,30,31,32;0
|
1
PC3Player/PC3Player/Channel Mappings/CyberMunch.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/CyberMunch.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Cyberamic Munch,Cyberamics;17,18,19,20,21,22,23,24;0
|
1
PC3Player/PC3Player/Channel Mappings/CyberPasqually.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/CyberPasqually.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Cyberamic Pasqually,Cyberamics;33,34,35,36,37,38,39,40;0
|
1
PC3Player/PC3Player/Channel Mappings/DookPasqually.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/DookPasqually.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Dook/Pasqually,Rockafire Explosion/3-Stage;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;0
|
1
PC3Player/PC3Player/Channel Mappings/FatzMunch.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/FatzMunch.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Fatz/Munch,Rockafire Explosion/3-Stage;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;0
|
1
PC3Player/PC3Player/Channel Mappings/MitziHelen.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/MitziHelen.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Mitzi/Helen,Rockafire Explosion/3-Stage;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;0
|
1
PC3Player/PC3Player/Channel Mappings/RolfeChuck.pcm
Normal file
1
PC3Player/PC3Player/Channel Mappings/RolfeChuck.pcm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PC3MAPPING,2,Rolfe/Chuck,Rockafire Explosion/3-Stage;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;0
|
73
PC3Player/PC3Player/DataTypes.cs
Normal file
73
PC3Player/PC3Player/DataTypes.cs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
using System.Diagnostics.Eventing.Reader;
|
||||||
|
|
||||||
|
namespace PC3Player
|
||||||
|
{
|
||||||
|
public class PlaylistShow
|
||||||
|
{
|
||||||
|
public PlaylistShow(string name, string length, string type, string filePath)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Type = type;
|
||||||
|
Length = length;
|
||||||
|
FilePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
public string Length { get; set; }
|
||||||
|
public string FilePath { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ChannelMapping
|
||||||
|
{
|
||||||
|
public ChannelMapping(string name, string type, int[] bits, int[] invertedBits)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Type = type;
|
||||||
|
Bits = bits;
|
||||||
|
InvertedBits = invertedBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
public int[] Bits { get; set; }
|
||||||
|
public int[] InvertedBits { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PlaylistConfig
|
||||||
|
{
|
||||||
|
public int PlaylistStartOption { get; set; } = 0;
|
||||||
|
public int PlaylistShowEndOption { get; set; } = 0;
|
||||||
|
public bool PlaylistIntermissionOption { get; set; } = false;
|
||||||
|
public int PlaylistIntermissionTimeOption { get; set; } = 8;
|
||||||
|
public int PlaylistIntermissionUnitOption { get; set; } = 0;
|
||||||
|
public bool PlaylistLoopOption { get; set; } = true;
|
||||||
|
|
||||||
|
public int SelectorButtonPressOption { get; set; } = 0;
|
||||||
|
public int SelectorShowAlreadyPlayingOption { get; set; } = 0;
|
||||||
|
public int SelectorShowEndOption { get; set; } = 0;
|
||||||
|
public bool SelectorCooldownOption { get; set; } = false;
|
||||||
|
public int SelectorCooldownTimeOption { get; set; } = 30;
|
||||||
|
public int SelectorCooldownUnitOption { get; set; } = 1;
|
||||||
|
public bool SelectorPlaySkitOption { get; set; } = false;
|
||||||
|
|
||||||
|
public int?[] SelectorAssignments { get; set; } = new int?[12];
|
||||||
|
|
||||||
|
public int FramesPerTick { get; set; } = 6;
|
||||||
|
public int ResyncSeconds { get; set; } = 1;
|
||||||
|
public int FrameShift { get; set; } = 0;
|
||||||
|
|
||||||
|
public ChannelMapping Mapping { get; set; }
|
||||||
|
|
||||||
|
public List<PlaylistShow> Shows { get; set; } = new List<PlaylistShow>();
|
||||||
|
public List<PlaylistShow> Skits { get; set; } = new List<PlaylistShow>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StartMethod
|
||||||
|
{
|
||||||
|
PlaylistStart,
|
||||||
|
PlaylistShowEnd,
|
||||||
|
SelectorPress,
|
||||||
|
SelectorShowEnd
|
||||||
|
}
|
||||||
|
}
|
414
PC3Player/PC3Player/MainForm.Designer.cs
generated
Normal file
414
PC3Player/PC3Player/MainForm.Designer.cs
generated
Normal file
|
@ -0,0 +1,414 @@
|
||||||
|
namespace PC3Player
|
||||||
|
{
|
||||||
|
partial class MainForm
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
components = new System.ComponentModel.Container();
|
||||||
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||||
|
ControllerGroupBox = new GroupBox();
|
||||||
|
ControllerSelectSerialPortButton = new Button();
|
||||||
|
ControllerAutoDetectButton = new Button();
|
||||||
|
PlaybackControlsGroupBox = new GroupBox();
|
||||||
|
TimeLabel = new Label();
|
||||||
|
StopButton = new Button();
|
||||||
|
SkipButton = new Button();
|
||||||
|
PauseButton = new Button();
|
||||||
|
StartButton = new Button();
|
||||||
|
ShowSelectorGroupBox = new GroupBox();
|
||||||
|
ShowSelectorSelectPortButton = new Button();
|
||||||
|
ShowSelectorAutoDetectButton = new Button();
|
||||||
|
PlaylistGroupBox = new GroupBox();
|
||||||
|
AdvancedSettingsButton = new Button();
|
||||||
|
AddShowButton = new Button();
|
||||||
|
LoadPlaylistButton = new Button();
|
||||||
|
SavePlaylistButton = new Button();
|
||||||
|
ChannelMappingGroupBox = new GroupBox();
|
||||||
|
LoadChannelMapButton = new Button();
|
||||||
|
PlaylistListView = new ListView();
|
||||||
|
NameColumnHeader = new ColumnHeader();
|
||||||
|
LengthColumnHeader = new ColumnHeader();
|
||||||
|
ShowContextMenu = new ContextMenuStrip(components);
|
||||||
|
MoveUpButton = new ToolStripMenuItem();
|
||||||
|
MoveDownButton = new ToolStripMenuItem();
|
||||||
|
RemoveButton = new ToolStripMenuItem();
|
||||||
|
SelectShowFileDialog = new OpenFileDialog();
|
||||||
|
SelectMappingFileDialog = new OpenFileDialog();
|
||||||
|
SavePlaylistFileDialog = new SaveFileDialog();
|
||||||
|
OpenPlaylistFileDialog = new OpenFileDialog();
|
||||||
|
NewPlaylistButton = new Button();
|
||||||
|
ControllerGroupBox.SuspendLayout();
|
||||||
|
PlaybackControlsGroupBox.SuspendLayout();
|
||||||
|
ShowSelectorGroupBox.SuspendLayout();
|
||||||
|
PlaylistGroupBox.SuspendLayout();
|
||||||
|
ChannelMappingGroupBox.SuspendLayout();
|
||||||
|
ShowContextMenu.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// ControllerGroupBox
|
||||||
|
//
|
||||||
|
ControllerGroupBox.Controls.Add(ControllerSelectSerialPortButton);
|
||||||
|
ControllerGroupBox.Controls.Add(ControllerAutoDetectButton);
|
||||||
|
ControllerGroupBox.Location = new Point(12, 12);
|
||||||
|
ControllerGroupBox.Name = "ControllerGroupBox";
|
||||||
|
ControllerGroupBox.Size = new Size(256, 84);
|
||||||
|
ControllerGroupBox.TabIndex = 0;
|
||||||
|
ControllerGroupBox.TabStop = false;
|
||||||
|
ControllerGroupBox.Text = "Controller: Not Connected";
|
||||||
|
//
|
||||||
|
// ControllerSelectSerialPortButton
|
||||||
|
//
|
||||||
|
ControllerSelectSerialPortButton.Location = new Point(6, 53);
|
||||||
|
ControllerSelectSerialPortButton.Name = "ControllerSelectSerialPortButton";
|
||||||
|
ControllerSelectSerialPortButton.Size = new Size(244, 25);
|
||||||
|
ControllerSelectSerialPortButton.TabIndex = 1;
|
||||||
|
ControllerSelectSerialPortButton.Text = "Select Serial Port";
|
||||||
|
ControllerSelectSerialPortButton.UseVisualStyleBackColor = true;
|
||||||
|
ControllerSelectSerialPortButton.Click += ControllerSelectSerialPortButton_Click;
|
||||||
|
//
|
||||||
|
// ControllerAutoDetectButton
|
||||||
|
//
|
||||||
|
ControllerAutoDetectButton.Location = new Point(6, 22);
|
||||||
|
ControllerAutoDetectButton.Name = "ControllerAutoDetectButton";
|
||||||
|
ControllerAutoDetectButton.Size = new Size(244, 25);
|
||||||
|
ControllerAutoDetectButton.TabIndex = 0;
|
||||||
|
ControllerAutoDetectButton.Text = "Auto Detect";
|
||||||
|
ControllerAutoDetectButton.UseVisualStyleBackColor = true;
|
||||||
|
ControllerAutoDetectButton.Click += ControllerAutoDetectButton_Click;
|
||||||
|
//
|
||||||
|
// PlaybackControlsGroupBox
|
||||||
|
//
|
||||||
|
PlaybackControlsGroupBox.Controls.Add(TimeLabel);
|
||||||
|
PlaybackControlsGroupBox.Controls.Add(StopButton);
|
||||||
|
PlaybackControlsGroupBox.Controls.Add(SkipButton);
|
||||||
|
PlaybackControlsGroupBox.Controls.Add(PauseButton);
|
||||||
|
PlaybackControlsGroupBox.Controls.Add(StartButton);
|
||||||
|
PlaybackControlsGroupBox.Location = new Point(12, 376);
|
||||||
|
PlaybackControlsGroupBox.Name = "PlaybackControlsGroupBox";
|
||||||
|
PlaybackControlsGroupBox.Size = new Size(256, 99);
|
||||||
|
PlaybackControlsGroupBox.TabIndex = 4;
|
||||||
|
PlaybackControlsGroupBox.TabStop = false;
|
||||||
|
PlaybackControlsGroupBox.Text = "Controls: Not Playing";
|
||||||
|
//
|
||||||
|
// TimeLabel
|
||||||
|
//
|
||||||
|
TimeLabel.AutoSize = true;
|
||||||
|
TimeLabel.Location = new Point(6, 81);
|
||||||
|
TimeLabel.Name = "TimeLabel";
|
||||||
|
TimeLabel.Size = new Size(104, 15);
|
||||||
|
TimeLabel.TabIndex = 4;
|
||||||
|
TimeLabel.Text = "(00:00:00/00:00:00)";
|
||||||
|
//
|
||||||
|
// StopButton
|
||||||
|
//
|
||||||
|
StopButton.Enabled = false;
|
||||||
|
StopButton.Location = new Point(131, 53);
|
||||||
|
StopButton.Name = "StopButton";
|
||||||
|
StopButton.Size = new Size(119, 25);
|
||||||
|
StopButton.TabIndex = 3;
|
||||||
|
StopButton.Text = "Stop";
|
||||||
|
StopButton.UseVisualStyleBackColor = true;
|
||||||
|
StopButton.Click += StopButton_Click;
|
||||||
|
//
|
||||||
|
// SkipButton
|
||||||
|
//
|
||||||
|
SkipButton.Enabled = false;
|
||||||
|
SkipButton.Location = new Point(6, 53);
|
||||||
|
SkipButton.Name = "SkipButton";
|
||||||
|
SkipButton.Size = new Size(119, 25);
|
||||||
|
SkipButton.TabIndex = 2;
|
||||||
|
SkipButton.Text = "Skip";
|
||||||
|
SkipButton.UseVisualStyleBackColor = true;
|
||||||
|
SkipButton.Click += SkipButton_Click;
|
||||||
|
//
|
||||||
|
// PauseButton
|
||||||
|
//
|
||||||
|
PauseButton.Enabled = false;
|
||||||
|
PauseButton.Location = new Point(131, 22);
|
||||||
|
PauseButton.Name = "PauseButton";
|
||||||
|
PauseButton.Size = new Size(119, 25);
|
||||||
|
PauseButton.TabIndex = 1;
|
||||||
|
PauseButton.Text = "Pause";
|
||||||
|
PauseButton.UseVisualStyleBackColor = true;
|
||||||
|
PauseButton.Click += PauseButton_Click;
|
||||||
|
//
|
||||||
|
// StartButton
|
||||||
|
//
|
||||||
|
StartButton.Location = new Point(6, 22);
|
||||||
|
StartButton.Name = "StartButton";
|
||||||
|
StartButton.Size = new Size(119, 25);
|
||||||
|
StartButton.TabIndex = 0;
|
||||||
|
StartButton.Text = "Start Playlist";
|
||||||
|
StartButton.UseVisualStyleBackColor = true;
|
||||||
|
StartButton.Click += StartButton_Click;
|
||||||
|
//
|
||||||
|
// ShowSelectorGroupBox
|
||||||
|
//
|
||||||
|
ShowSelectorGroupBox.Controls.Add(ShowSelectorSelectPortButton);
|
||||||
|
ShowSelectorGroupBox.Controls.Add(ShowSelectorAutoDetectButton);
|
||||||
|
ShowSelectorGroupBox.Enabled = false;
|
||||||
|
ShowSelectorGroupBox.Location = new Point(12, 102);
|
||||||
|
ShowSelectorGroupBox.Name = "ShowSelectorGroupBox";
|
||||||
|
ShowSelectorGroupBox.Size = new Size(256, 84);
|
||||||
|
ShowSelectorGroupBox.TabIndex = 1;
|
||||||
|
ShowSelectorGroupBox.TabStop = false;
|
||||||
|
ShowSelectorGroupBox.Text = "Show Selector: Not Connected";
|
||||||
|
//
|
||||||
|
// ShowSelectorSelectPortButton
|
||||||
|
//
|
||||||
|
ShowSelectorSelectPortButton.Location = new Point(6, 53);
|
||||||
|
ShowSelectorSelectPortButton.Name = "ShowSelectorSelectPortButton";
|
||||||
|
ShowSelectorSelectPortButton.Size = new Size(244, 25);
|
||||||
|
ShowSelectorSelectPortButton.TabIndex = 1;
|
||||||
|
ShowSelectorSelectPortButton.Text = "Select Serial Port";
|
||||||
|
ShowSelectorSelectPortButton.UseVisualStyleBackColor = true;
|
||||||
|
ShowSelectorSelectPortButton.Click += ShowSelectorSelectPortButton_Click;
|
||||||
|
//
|
||||||
|
// ShowSelectorAutoDetectButton
|
||||||
|
//
|
||||||
|
ShowSelectorAutoDetectButton.Location = new Point(6, 22);
|
||||||
|
ShowSelectorAutoDetectButton.Name = "ShowSelectorAutoDetectButton";
|
||||||
|
ShowSelectorAutoDetectButton.Size = new Size(244, 25);
|
||||||
|
ShowSelectorAutoDetectButton.TabIndex = 0;
|
||||||
|
ShowSelectorAutoDetectButton.Text = "Auto Detect";
|
||||||
|
ShowSelectorAutoDetectButton.UseVisualStyleBackColor = true;
|
||||||
|
ShowSelectorAutoDetectButton.Click += ShowSelectorAutoDetectButton_Click;
|
||||||
|
//
|
||||||
|
// PlaylistGroupBox
|
||||||
|
//
|
||||||
|
PlaylistGroupBox.Controls.Add(NewPlaylistButton);
|
||||||
|
PlaylistGroupBox.Controls.Add(AdvancedSettingsButton);
|
||||||
|
PlaylistGroupBox.Controls.Add(AddShowButton);
|
||||||
|
PlaylistGroupBox.Controls.Add(LoadPlaylistButton);
|
||||||
|
PlaylistGroupBox.Controls.Add(SavePlaylistButton);
|
||||||
|
PlaylistGroupBox.Location = new Point(12, 254);
|
||||||
|
PlaylistGroupBox.Name = "PlaylistGroupBox";
|
||||||
|
PlaylistGroupBox.Size = new Size(256, 116);
|
||||||
|
PlaylistGroupBox.TabIndex = 3;
|
||||||
|
PlaylistGroupBox.TabStop = false;
|
||||||
|
PlaylistGroupBox.Text = "Playlist: Unsaved";
|
||||||
|
//
|
||||||
|
// AdvancedSettingsButton
|
||||||
|
//
|
||||||
|
AdvancedSettingsButton.Location = new Point(131, 22);
|
||||||
|
AdvancedSettingsButton.Name = "AdvancedSettingsButton";
|
||||||
|
AdvancedSettingsButton.Size = new Size(119, 25);
|
||||||
|
AdvancedSettingsButton.TabIndex = 1;
|
||||||
|
AdvancedSettingsButton.Text = "Advanced";
|
||||||
|
AdvancedSettingsButton.UseVisualStyleBackColor = true;
|
||||||
|
AdvancedSettingsButton.Click += AdvancedSettingsButton_Click;
|
||||||
|
//
|
||||||
|
// AddShowButton
|
||||||
|
//
|
||||||
|
AddShowButton.Location = new Point(6, 22);
|
||||||
|
AddShowButton.Name = "AddShowButton";
|
||||||
|
AddShowButton.Size = new Size(119, 25);
|
||||||
|
AddShowButton.TabIndex = 0;
|
||||||
|
AddShowButton.Text = "Add Show";
|
||||||
|
AddShowButton.UseVisualStyleBackColor = true;
|
||||||
|
AddShowButton.Click += AddShowButton_Click;
|
||||||
|
//
|
||||||
|
// LoadPlaylistButton
|
||||||
|
//
|
||||||
|
LoadPlaylistButton.Location = new Point(131, 53);
|
||||||
|
LoadPlaylistButton.Name = "LoadPlaylistButton";
|
||||||
|
LoadPlaylistButton.Size = new Size(119, 25);
|
||||||
|
LoadPlaylistButton.TabIndex = 3;
|
||||||
|
LoadPlaylistButton.Text = "Load Playlist";
|
||||||
|
LoadPlaylistButton.UseVisualStyleBackColor = true;
|
||||||
|
LoadPlaylistButton.Click += LoadPlaylistButton_Click;
|
||||||
|
//
|
||||||
|
// SavePlaylistButton
|
||||||
|
//
|
||||||
|
SavePlaylistButton.Location = new Point(6, 53);
|
||||||
|
SavePlaylistButton.Name = "SavePlaylistButton";
|
||||||
|
SavePlaylistButton.Size = new Size(119, 25);
|
||||||
|
SavePlaylistButton.TabIndex = 2;
|
||||||
|
SavePlaylistButton.Text = "Save Playlist";
|
||||||
|
SavePlaylistButton.UseVisualStyleBackColor = true;
|
||||||
|
SavePlaylistButton.Click += SavePlaylistButton_Click;
|
||||||
|
//
|
||||||
|
// ChannelMappingGroupBox
|
||||||
|
//
|
||||||
|
ChannelMappingGroupBox.Controls.Add(LoadChannelMapButton);
|
||||||
|
ChannelMappingGroupBox.Location = new Point(12, 192);
|
||||||
|
ChannelMappingGroupBox.Name = "ChannelMappingGroupBox";
|
||||||
|
ChannelMappingGroupBox.Size = new Size(256, 56);
|
||||||
|
ChannelMappingGroupBox.TabIndex = 2;
|
||||||
|
ChannelMappingGroupBox.TabStop = false;
|
||||||
|
ChannelMappingGroupBox.Text = "Channel Map: None Loaded";
|
||||||
|
//
|
||||||
|
// LoadChannelMapButton
|
||||||
|
//
|
||||||
|
LoadChannelMapButton.Location = new Point(6, 22);
|
||||||
|
LoadChannelMapButton.Name = "LoadChannelMapButton";
|
||||||
|
LoadChannelMapButton.Size = new Size(244, 25);
|
||||||
|
LoadChannelMapButton.TabIndex = 0;
|
||||||
|
LoadChannelMapButton.Text = "Load Channel Map";
|
||||||
|
LoadChannelMapButton.UseVisualStyleBackColor = true;
|
||||||
|
LoadChannelMapButton.Click += LoadChannelMapButton_Click;
|
||||||
|
//
|
||||||
|
// PlaylistListView
|
||||||
|
//
|
||||||
|
PlaylistListView.AutoArrange = false;
|
||||||
|
PlaylistListView.Columns.AddRange(new ColumnHeader[] { NameColumnHeader, LengthColumnHeader });
|
||||||
|
PlaylistListView.ContextMenuStrip = ShowContextMenu;
|
||||||
|
PlaylistListView.GridLines = true;
|
||||||
|
PlaylistListView.HeaderStyle = ColumnHeaderStyle.Nonclickable;
|
||||||
|
PlaylistListView.Location = new Point(274, 12);
|
||||||
|
PlaylistListView.MultiSelect = false;
|
||||||
|
PlaylistListView.Name = "PlaylistListView";
|
||||||
|
PlaylistListView.Size = new Size(400, 463);
|
||||||
|
PlaylistListView.TabIndex = 5;
|
||||||
|
PlaylistListView.UseCompatibleStateImageBehavior = false;
|
||||||
|
PlaylistListView.View = View.Details;
|
||||||
|
//
|
||||||
|
// NameColumnHeader
|
||||||
|
//
|
||||||
|
NameColumnHeader.Text = "Show Name";
|
||||||
|
NameColumnHeader.Width = 310;
|
||||||
|
//
|
||||||
|
// LengthColumnHeader
|
||||||
|
//
|
||||||
|
LengthColumnHeader.Text = "Length";
|
||||||
|
//
|
||||||
|
// ShowContextMenu
|
||||||
|
//
|
||||||
|
ShowContextMenu.Items.AddRange(new ToolStripItem[] { MoveUpButton, MoveDownButton, RemoveButton });
|
||||||
|
ShowContextMenu.Name = "ShowContextMenu";
|
||||||
|
ShowContextMenu.Size = new Size(139, 70);
|
||||||
|
//
|
||||||
|
// MoveUpButton
|
||||||
|
//
|
||||||
|
MoveUpButton.Name = "MoveUpButton";
|
||||||
|
MoveUpButton.Size = new Size(138, 22);
|
||||||
|
MoveUpButton.Text = "Move Up";
|
||||||
|
MoveUpButton.Click += MoveUpButton_Click;
|
||||||
|
//
|
||||||
|
// MoveDownButton
|
||||||
|
//
|
||||||
|
MoveDownButton.Name = "MoveDownButton";
|
||||||
|
MoveDownButton.Size = new Size(138, 22);
|
||||||
|
MoveDownButton.Text = "Move Down";
|
||||||
|
MoveDownButton.Click += MoveDownButton_Click;
|
||||||
|
//
|
||||||
|
// RemoveButton
|
||||||
|
//
|
||||||
|
RemoveButton.Name = "RemoveButton";
|
||||||
|
RemoveButton.Size = new Size(138, 22);
|
||||||
|
RemoveButton.Text = "Remove";
|
||||||
|
RemoveButton.Click += RemoveButton_Click;
|
||||||
|
//
|
||||||
|
// SelectShowFileDialog
|
||||||
|
//
|
||||||
|
SelectShowFileDialog.Filter = "UST Showtapes|*.ust";
|
||||||
|
SelectShowFileDialog.Multiselect = true;
|
||||||
|
//
|
||||||
|
// SelectMappingFileDialog
|
||||||
|
//
|
||||||
|
SelectMappingFileDialog.Filter = "PinkConnection Channel Map|*.pcm";
|
||||||
|
//
|
||||||
|
// SavePlaylistFileDialog
|
||||||
|
//
|
||||||
|
SavePlaylistFileDialog.Filter = "PC3Player Playlists (JSON Files)|*.json";
|
||||||
|
//
|
||||||
|
// OpenPlaylistFileDialog
|
||||||
|
//
|
||||||
|
OpenPlaylistFileDialog.Filter = "PC3Player Playlists (JSON Files)|*.json";
|
||||||
|
//
|
||||||
|
// NewPlaylistButton
|
||||||
|
//
|
||||||
|
NewPlaylistButton.Location = new Point(6, 84);
|
||||||
|
NewPlaylistButton.Name = "NewPlaylistButton";
|
||||||
|
NewPlaylistButton.Size = new Size(244, 25);
|
||||||
|
NewPlaylistButton.TabIndex = 4;
|
||||||
|
NewPlaylistButton.Text = "New Playlist";
|
||||||
|
NewPlaylistButton.UseVisualStyleBackColor = true;
|
||||||
|
NewPlaylistButton.Click += NewPlaylistButton_Click;
|
||||||
|
//
|
||||||
|
// MainForm
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(686, 487);
|
||||||
|
Controls.Add(PlaylistListView);
|
||||||
|
Controls.Add(ChannelMappingGroupBox);
|
||||||
|
Controls.Add(PlaylistGroupBox);
|
||||||
|
Controls.Add(ShowSelectorGroupBox);
|
||||||
|
Controls.Add(PlaybackControlsGroupBox);
|
||||||
|
Controls.Add(ControllerGroupBox);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||||
|
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||||
|
MaximizeBox = false;
|
||||||
|
Name = "MainForm";
|
||||||
|
Text = "PinkConnection3 Player";
|
||||||
|
FormClosing += MainForm_FormClosing;
|
||||||
|
ControllerGroupBox.ResumeLayout(false);
|
||||||
|
PlaybackControlsGroupBox.ResumeLayout(false);
|
||||||
|
PlaybackControlsGroupBox.PerformLayout();
|
||||||
|
ShowSelectorGroupBox.ResumeLayout(false);
|
||||||
|
PlaylistGroupBox.ResumeLayout(false);
|
||||||
|
ChannelMappingGroupBox.ResumeLayout(false);
|
||||||
|
ShowContextMenu.ResumeLayout(false);
|
||||||
|
ResumeLayout(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private GroupBox ControllerGroupBox;
|
||||||
|
private Button ControllerSelectSerialPortButton;
|
||||||
|
private Button ControllerAutoDetectButton;
|
||||||
|
private GroupBox PlaybackControlsGroupBox;
|
||||||
|
private Button SkipButton;
|
||||||
|
private Button PauseButton;
|
||||||
|
private Button StartButton;
|
||||||
|
private GroupBox ShowSelectorGroupBox;
|
||||||
|
private Button ShowSelectorSelectPortButton;
|
||||||
|
private Button ShowSelectorAutoDetectButton;
|
||||||
|
private GroupBox PlaylistGroupBox;
|
||||||
|
private Button AddShowButton;
|
||||||
|
private GroupBox ChannelMappingGroupBox;
|
||||||
|
private Button LoadChannelMapButton;
|
||||||
|
private ListView PlaylistListView;
|
||||||
|
private ColumnHeader NameColumnHeader;
|
||||||
|
private ColumnHeader LengthColumnHeader;
|
||||||
|
private Button StopButton;
|
||||||
|
private Button SavePlaylistButton;
|
||||||
|
private Button LoadPlaylistButton;
|
||||||
|
private OpenFileDialog SelectShowFileDialog;
|
||||||
|
private OpenFileDialog SelectMappingFileDialog;
|
||||||
|
private Button AdvancedSettingsButton;
|
||||||
|
private ContextMenuStrip ShowContextMenu;
|
||||||
|
private ToolStripMenuItem RemoveButton;
|
||||||
|
private ToolStripMenuItem MoveUpButton;
|
||||||
|
private ToolStripMenuItem MoveDownButton;
|
||||||
|
private SaveFileDialog SavePlaylistFileDialog;
|
||||||
|
private OpenFileDialog OpenPlaylistFileDialog;
|
||||||
|
private Label TimeLabel;
|
||||||
|
private Button NewPlaylistButton;
|
||||||
|
}
|
||||||
|
}
|
900
PC3Player/PC3Player/MainForm.cs
Normal file
900
PC3Player/PC3Player/MainForm.cs
Normal file
|
@ -0,0 +1,900 @@
|
||||||
|
using SoundFlow.Backends.MiniAudio;
|
||||||
|
using SoundFlow.Components;
|
||||||
|
using SoundFlow.Enums;
|
||||||
|
using SoundFlow.Providers;
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO.Ports;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace PC3Player
|
||||||
|
{
|
||||||
|
public partial class MainForm : Form
|
||||||
|
{
|
||||||
|
static PlaylistConfig Config = new();
|
||||||
|
|
||||||
|
static SerialPort ControllerPort;
|
||||||
|
static SerialPort ShowSelectorPort;
|
||||||
|
|
||||||
|
static Random SelectRandom = new Random();
|
||||||
|
|
||||||
|
System.Timers.Timer FrameTimer;
|
||||||
|
System.Timers.Timer ResyncTimer;
|
||||||
|
System.Timers.Timer GUIUpdateTimer;
|
||||||
|
|
||||||
|
SoundPlayer AudioPlayer;
|
||||||
|
StreamDataProvider dataProvider;
|
||||||
|
|
||||||
|
static int ShowtapeIndex = 0;
|
||||||
|
static int PlaylistIndex = 0;
|
||||||
|
static int IntermissionSecondsLeft = 0;
|
||||||
|
static int IntermissionTotalTime = 0;
|
||||||
|
static int ControllerBits;
|
||||||
|
static int SelectorButtons;
|
||||||
|
|
||||||
|
static bool ControllerConnected = false;
|
||||||
|
static bool ShowSelectorConnected = false;
|
||||||
|
|
||||||
|
public static bool ChannelMappingLoaded = false;
|
||||||
|
|
||||||
|
static bool Playing = false;
|
||||||
|
static bool Paused = false;
|
||||||
|
static bool InvalidateSave = false;
|
||||||
|
static bool Intermission;
|
||||||
|
|
||||||
|
static string[] ShowtapeFrames;
|
||||||
|
static PlaylistShow CurrentlyPlaying;
|
||||||
|
|
||||||
|
public MainForm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
GUIUpdateTimer = new System.Timers.Timer(1000);
|
||||||
|
GUIUpdateTimer.Elapsed += GUIUpdateTick;
|
||||||
|
GUIUpdateTimer.AutoReset = true;
|
||||||
|
MiniAudioEngine audioEngine = new MiniAudioEngine(48000, Capability.Playback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateListView()
|
||||||
|
{
|
||||||
|
PlaylistListView.Items.Clear();
|
||||||
|
foreach (PlaylistShow s in Config.Shows) PlaylistListView.Items.Add(new ListViewItem(new[] { s.Name, s.Length }));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadChannelMapButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!ControllerConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("You must connect a Controller first.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SelectMappingFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
string tempMappingData = File.ReadAllText(SelectMappingFileDialog.FileName);
|
||||||
|
if (!tempMappingData.StartsWith("PC3MAPPING,2,"))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Selected mapping file is not a Version 2 PinkConnection channel map.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] header = tempMappingData.Split(";")[0].Split(",");
|
||||||
|
|
||||||
|
List<int> targetBits = new List<int>();
|
||||||
|
foreach (string s in tempMappingData.Split(";")[1].Split(","))
|
||||||
|
{
|
||||||
|
targetBits.Add(int.Parse(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ChannelMappingLoaded)
|
||||||
|
{
|
||||||
|
if (header[3] != Config.Mapping.Type)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
$"Selected Channel Map \"{header[2]}\"'s type does not match the old Channel Map's type." +
|
||||||
|
$"\nOld Channel Map Type: {Config.Mapping.Type}" +
|
||||||
|
$"\nNew Channel Map Type: {header[3]}"
|
||||||
|
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetBits.Count != ControllerBits)
|
||||||
|
{
|
||||||
|
MessageBox.Show("The mapped channel count is not equal to the connected controller's bit count.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetBits.Count % 4 != 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("The mapped channel count is not divisible by 4.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> invertedBits = new List<int>();
|
||||||
|
foreach (string s in tempMappingData.Split(";")[2].Split(","))
|
||||||
|
{
|
||||||
|
int ints = int.Parse(s);
|
||||||
|
if (ints == 0) continue;
|
||||||
|
invertedBits.Add(ints);
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.Mapping = new ChannelMapping(header[2], header[3], targetBits.ToArray(), invertedBits.ToArray());
|
||||||
|
ChannelMappingLoaded = true;
|
||||||
|
|
||||||
|
ChannelMappingGroupBox.Text = $"Channel Map: {Config.Mapping.Name}";
|
||||||
|
InvalidateSave = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ControllerAutoDetectButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (ControllerConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("A Controller is already connected.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string successPortName = "";
|
||||||
|
|
||||||
|
foreach (string portName in SerialPort.GetPortNames())
|
||||||
|
{
|
||||||
|
if (ControllerConnected) break;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SerialPort tempPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
tempPort.Open();
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
tempPort.Write("! ");
|
||||||
|
Thread.Sleep(100);
|
||||||
|
string readAttempt = tempPort.ReadExisting();
|
||||||
|
if (readAttempt.Split(",")[0] == "PC3")
|
||||||
|
{
|
||||||
|
ControllerBits = int.Parse(readAttempt.Split(",")[1]);
|
||||||
|
ControllerConnected = true;
|
||||||
|
tempPort.Close();
|
||||||
|
ControllerPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
ControllerPort.Open();
|
||||||
|
successPortName = portName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempPort.Close();
|
||||||
|
}
|
||||||
|
catch (Exception) { continue; }
|
||||||
|
}
|
||||||
|
if (!ControllerConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Could not detect a PinkConnection3 controller on any of your serial ports.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ControllerGroupBox.Text = $"Controller: {ControllerBits} channel on {successPortName}";
|
||||||
|
ControllerAutoDetectButton.Enabled = false;
|
||||||
|
ControllerSelectSerialPortButton.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ControllerSelectSerialPortButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (ControllerConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("A Controller is already connected.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialPortSelector portDialog = new SerialPortSelector();
|
||||||
|
if (portDialog.ShowDialog() != DialogResult.OK) return;
|
||||||
|
|
||||||
|
string successPortName = "";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SerialPort tempPort = new SerialPort(portDialog.PortName, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
tempPort.Open();
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
tempPort.Write("! ");
|
||||||
|
Thread.Sleep(100);
|
||||||
|
string readAttempt = tempPort.ReadExisting();
|
||||||
|
if (readAttempt.Split(",")[0] == "PC3")
|
||||||
|
{
|
||||||
|
ControllerBits = int.Parse(readAttempt.Split(",")[1]);
|
||||||
|
ControllerConnected = true;
|
||||||
|
tempPort.Close();
|
||||||
|
ControllerPort = new SerialPort(portDialog.PortName, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
ControllerPort.Open();
|
||||||
|
successPortName = portDialog.PortName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tempPort.Close();
|
||||||
|
|
||||||
|
if (!ControllerConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Could not detect a PinkConnection3 controller on the specified serial port.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Could not detect a PinkConnection3 controller on the specified serial port.\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ControllerGroupBox.Text = $"Controller: {ControllerBits} channel on {successPortName}";
|
||||||
|
ControllerAutoDetectButton.Enabled = false;
|
||||||
|
ControllerSelectSerialPortButton.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddShowButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!ChannelMappingLoaded)
|
||||||
|
{
|
||||||
|
MessageBox.Show("You must load a channel mapping first.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SelectShowFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
foreach (string showFilePath in SelectShowFileDialog.FileNames)
|
||||||
|
{
|
||||||
|
string tempUSTData = File.ReadAllText(showFilePath);
|
||||||
|
if (!tempUSTData.StartsWith("UST,2,"))
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Selected showtape \"{Path.GetFileNameWithoutExtension(showFilePath)}\" is not a UST version 2 showtape.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] headerData = tempUSTData.Split(';')[0].Split(',');
|
||||||
|
string[] stringyBits = tempUSTData.Split(';')[1].Split(',');
|
||||||
|
|
||||||
|
TimeSpan time = TimeSpan.FromSeconds(stringyBits.Length / 60);
|
||||||
|
string formattedLength = time.ToString(@"hh\:mm\:ss");
|
||||||
|
|
||||||
|
tempUSTData = null;
|
||||||
|
stringyBits = null;
|
||||||
|
|
||||||
|
if (headerData[3] != Config.Mapping.Type)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
$"Selected Show \"{headerData[2]}\"'s type does not match the loaded Channel Map." +
|
||||||
|
$"\nLoaded Channel Map Type: {Config.Mapping.Type}" +
|
||||||
|
$"\nShow Type: {headerData[3]}"
|
||||||
|
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.Shows.Add(new PlaylistShow(headerData[2], formattedLength, headerData[3], showFilePath));
|
||||||
|
}
|
||||||
|
UpdateListView();
|
||||||
|
InvalidateSave = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (PlaylistListView.SelectedIndices.Count == 0) return;
|
||||||
|
Config = RemoveShowAt(PlaylistListView.SelectedIndices[0], Config);
|
||||||
|
UpdateListView();
|
||||||
|
InvalidateSave = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveUpButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (PlaylistListView.SelectedIndices.Count == 0) return;
|
||||||
|
int selectedIndex = PlaylistListView.SelectedIndices[0];
|
||||||
|
if (selectedIndex == 0) return;
|
||||||
|
int assindex = 0;
|
||||||
|
foreach (int? assignment in Config.SelectorAssignments)
|
||||||
|
{
|
||||||
|
if (assignment == null) continue;
|
||||||
|
if (assignment == selectedIndex) Config.SelectorAssignments[assindex]--;
|
||||||
|
if (assignment == selectedIndex - 1) Config.SelectorAssignments[assindex]++;
|
||||||
|
assindex++;
|
||||||
|
}
|
||||||
|
PlaylistShow temp = Config.Shows[selectedIndex];
|
||||||
|
Config.Shows.RemoveAt(selectedIndex);
|
||||||
|
Config.Shows.Insert(selectedIndex - 1, temp);
|
||||||
|
UpdateListView();
|
||||||
|
InvalidateSave = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MoveDownButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (PlaylistListView.SelectedIndices.Count == 0) return;
|
||||||
|
int selectedIndex = PlaylistListView.SelectedIndices[0];
|
||||||
|
if (selectedIndex >= PlaylistListView.Items.Count - 1) return;
|
||||||
|
int assindex = 0;
|
||||||
|
foreach (int? assignment in Config.SelectorAssignments)
|
||||||
|
{
|
||||||
|
if (assignment == null) continue;
|
||||||
|
if (assignment == selectedIndex) Config.SelectorAssignments[assindex]++;
|
||||||
|
if (assignment == selectedIndex + 1) Config.SelectorAssignments[assindex]--;
|
||||||
|
assindex++;
|
||||||
|
}
|
||||||
|
PlaylistShow temp = Config.Shows[selectedIndex];
|
||||||
|
Config.Shows.RemoveAt(selectedIndex);
|
||||||
|
Config.Shows.Insert(selectedIndex + 1, temp);
|
||||||
|
UpdateListView();
|
||||||
|
InvalidateSave = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AdvancedSettingsButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
AdvancedSettingsForm advancedSettingsForm = new AdvancedSettingsForm(Config);
|
||||||
|
if (Config != advancedSettingsForm.EditingObject) InvalidateSave = true;
|
||||||
|
if (advancedSettingsForm.ShowDialog() == DialogResult.OK) Config = advancedSettingsForm.EditingObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowSelectorAutoDetectButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (ShowSelectorConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("A Show Selector is already connected.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string successPortName = "";
|
||||||
|
|
||||||
|
foreach (string portName in SerialPort.GetPortNames())
|
||||||
|
{
|
||||||
|
if (ShowSelectorConnected) break;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SerialPort tempPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
tempPort.Open();
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
tempPort.Write("\" ");
|
||||||
|
Thread.Sleep(100);
|
||||||
|
string readAttempt = tempPort.ReadExisting();
|
||||||
|
if (readAttempt.Split(",")[0] == "PCSELECTOR")
|
||||||
|
{
|
||||||
|
SelectorButtons = int.Parse(readAttempt.Split(",")[1]);
|
||||||
|
ShowSelectorConnected = true;
|
||||||
|
tempPort.Close();
|
||||||
|
ShowSelectorPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
ShowSelectorPort.Open();
|
||||||
|
successPortName = portName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempPort.Close();
|
||||||
|
}
|
||||||
|
catch (Exception) { continue; }
|
||||||
|
}
|
||||||
|
if (!ShowSelectorConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Could not detect a PinkConnection Show Selector on any of your serial ports.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ShowSelectorGroupBox.Text = $"{SelectorButtons} button on {successPortName}";
|
||||||
|
ShowSelectorAutoDetectButton.Enabled = false;
|
||||||
|
ShowSelectorSelectPortButton.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowSelectorSelectPortButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (ShowSelectorConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("A Show Selector is already connected.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialPortSelector portDialog = new SerialPortSelector();
|
||||||
|
if (portDialog.ShowDialog() != DialogResult.OK) return;
|
||||||
|
|
||||||
|
string successPortName = "";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SerialPort tempPort = new SerialPort(portDialog.PortName, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
tempPort.Open();
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
tempPort.Write("\" ");
|
||||||
|
Thread.Sleep(100);
|
||||||
|
string readAttempt = tempPort.ReadExisting();
|
||||||
|
if (readAttempt.Split(",")[0] == "PCSELECTOR")
|
||||||
|
{
|
||||||
|
SelectorButtons = int.Parse(readAttempt.Split(",")[1]);
|
||||||
|
ShowSelectorConnected = true;
|
||||||
|
tempPort.Close();
|
||||||
|
ShowSelectorPort = new SerialPort(portDialog.PortName, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
ShowSelectorPort.Open();
|
||||||
|
successPortName = portDialog.PortName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tempPort.Close();
|
||||||
|
|
||||||
|
if (!ShowSelectorConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Could not detect a PinkConnection Show Selector on the specified serial port.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Could not detect a PinkConnection Show Selector on the specified serial port.\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ShowSelectorGroupBox.Text = $"Show Selector: {SelectorButtons} button on {successPortName}";
|
||||||
|
ShowSelectorAutoDetectButton.Enabled = false;
|
||||||
|
ShowSelectorSelectPortButton.Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
if (Playing) Stop();
|
||||||
|
if (InvalidateSave)
|
||||||
|
if (MessageBox.Show(
|
||||||
|
"You have an unsaved Playlist!\nDo you still want to exit?",
|
||||||
|
"Unsaved Playlist",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Exclamation
|
||||||
|
) != DialogResult.Yes)
|
||||||
|
e.Cancel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SavePlaylistButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (SavePlaylistFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
File.WriteAllText(SavePlaylistFileDialog.FileName, JsonSerializer.Serialize<PlaylistConfig>(Config));
|
||||||
|
InvalidateSave = false;
|
||||||
|
PlaylistGroupBox.Text = "Playlist: " + Path.GetFileNameWithoutExtension(SavePlaylistFileDialog.FileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadPlaylistButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Playing)
|
||||||
|
{
|
||||||
|
if (MessageBox.Show(
|
||||||
|
"A show is currently playing!\nPerforming this action will stop it.\nAre you sure?",
|
||||||
|
"Show Playing",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Exclamation
|
||||||
|
) != DialogResult.Yes)
|
||||||
|
return;
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ControllerConnected)
|
||||||
|
{
|
||||||
|
MessageBox.Show("You must connect a Controller first.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InvalidateSave)
|
||||||
|
if (MessageBox.Show(
|
||||||
|
"You have an unsaved Playlist!\nDo you still want to load another?",
|
||||||
|
"Unsaved Playlist",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Exclamation
|
||||||
|
) != DialogResult.Yes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (OpenPlaylistFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
PlaylistConfig? tempConfig;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tempConfig = JsonSerializer.Deserialize<PlaylistConfig>(File.ReadAllText(OpenPlaylistFileDialog.FileName));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Could not read the selected Playlist file.\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (tempConfig == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Could not read the selected Playlist file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempConfig.Mapping != null)
|
||||||
|
{
|
||||||
|
if (tempConfig.Mapping.Bits.Length % 4 != 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("The mapped channel count is not divisible by 4.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ChannelMappingGroupBox.Text = $"Channel Map: {tempConfig.Mapping.Name}";
|
||||||
|
ChannelMappingLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int showIndex = 0;
|
||||||
|
foreach (PlaylistShow show in tempConfig.Shows)
|
||||||
|
{
|
||||||
|
if (tempConfig.Mapping == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
"The Playlist does not have a loaded Channel Map" +
|
||||||
|
"\nNo Shows or Skits will be loaded."
|
||||||
|
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!File.Exists(show.FilePath))
|
||||||
|
{
|
||||||
|
if (MessageBox.Show(
|
||||||
|
$"Could not locate the file for the Show {show.Name}" +
|
||||||
|
$"\nWould you like to relocate it?",
|
||||||
|
"Could not find Show file",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Exclamation
|
||||||
|
) == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
if (SelectShowFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
tempConfig.Shows[showIndex].FilePath = SelectShowFileDialog.FileName;
|
||||||
|
}
|
||||||
|
else tempConfig = RemoveShowAt(showIndex, tempConfig);
|
||||||
|
}
|
||||||
|
else tempConfig = RemoveShowAt(showIndex, tempConfig);
|
||||||
|
}
|
||||||
|
if (show.Type != tempConfig.Mapping.Type)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
$"Show \"{show.Name}\"'s type does not match the Playlist's Channel Map." +
|
||||||
|
$"\nIt will be removed from the playlist." +
|
||||||
|
$"\nLoaded Channel Map Type: {tempConfig.Mapping.Type}" +
|
||||||
|
$"\nShow Type: {show.Type}"
|
||||||
|
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
tempConfig = RemoveShowAt(showIndex, tempConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
showIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int skitIndex = 0;
|
||||||
|
foreach (PlaylistShow skit in tempConfig.Skits)
|
||||||
|
{
|
||||||
|
if (tempConfig.Mapping == null) break;
|
||||||
|
if (!File.Exists(skit.FilePath))
|
||||||
|
{
|
||||||
|
if (MessageBox.Show(
|
||||||
|
$"Could not locate the file for the Skit {skit.Name}" +
|
||||||
|
$"\nWould you like to relocate it?",
|
||||||
|
"Could not find Skit file",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Exclamation
|
||||||
|
) == DialogResult.Yes)
|
||||||
|
{
|
||||||
|
if (SelectShowFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
tempConfig.Skits[skitIndex].FilePath = SelectShowFileDialog.FileName;
|
||||||
|
}
|
||||||
|
else tempConfig.Skits.RemoveAt(skitIndex);
|
||||||
|
}
|
||||||
|
else tempConfig.Skits.RemoveAt(skitIndex);
|
||||||
|
}
|
||||||
|
if (skit.Type != tempConfig.Mapping.Type)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
$"Skit \"{skit.Name}\"'s type does not match the Playlist's Channel Map." +
|
||||||
|
$"\nIt will be removed from the playlist." +
|
||||||
|
$"\nLoaded Channel Map Type: {tempConfig.Mapping.Type}" +
|
||||||
|
$"\nSkit Type: {skit.Type}"
|
||||||
|
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
tempConfig.Skits.RemoveAt(skitIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
skitIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Config = tempConfig;
|
||||||
|
PlaylistGroupBox.Text = "Playlist: " + Path.GetFileNameWithoutExtension(OpenPlaylistFileDialog.FileName);
|
||||||
|
UpdateListView();
|
||||||
|
InvalidateSave = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlaylistConfig RemoveShowAt(int position, PlaylistConfig pcfg)
|
||||||
|
{
|
||||||
|
int assindex = 0;
|
||||||
|
foreach (int? assignment in pcfg.SelectorAssignments)
|
||||||
|
{
|
||||||
|
if (assignment == null) continue;
|
||||||
|
if (assignment == position) pcfg.SelectorAssignments[assindex] = null;
|
||||||
|
if (assignment > position) pcfg.SelectorAssignments[assindex]--;
|
||||||
|
assindex++;
|
||||||
|
}
|
||||||
|
pcfg.Shows.RemoveAt(position);
|
||||||
|
return pcfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadNextShowtape()
|
||||||
|
{
|
||||||
|
string tempUSTData = File.ReadAllText(CurrentlyPlaying.FilePath);
|
||||||
|
if (!tempUSTData.StartsWith("UST,2,"))
|
||||||
|
{
|
||||||
|
MessageBox.Show($"Selected showtape \"{Path.GetFileNameWithoutExtension(CurrentlyPlaying.FilePath)}\" is not a UST version 2 showtape.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] stringyBits = tempUSTData.Split(';')[1].Split(',');
|
||||||
|
if (File.Exists("pc3playertempaudio.tmp")) File.Delete("pc3playertempaudio.tmp");
|
||||||
|
File.WriteAllBytes("pc3playertempaudio.tmp", Convert.FromBase64String(tempUSTData.Split(';')[2]));
|
||||||
|
|
||||||
|
tempUSTData = null;
|
||||||
|
|
||||||
|
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 < Config.Mapping.Bits.Count() / 4; i++)
|
||||||
|
{
|
||||||
|
byte quartet = 64;
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
if (Config.Mapping.Bits[selectBit] == 0) continue;
|
||||||
|
if (Config.Mapping.InvertedBits.Contains(Config.Mapping.Bits[selectBit])) { if (!((frame & BigInteger.Pow(2, Config.Mapping.Bits[selectBit] - 1)) == BigInteger.Pow(2, Config.Mapping.Bits[selectBit] - 1))) quartet += (byte)Math.Pow(2, j); }
|
||||||
|
else { if ((frame & BigInteger.Pow(2, Config.Mapping.Bits[selectBit] - 1)) == BigInteger.Pow(2, Config.Mapping.Bits[selectBit] - 1)) quartet += (byte)Math.Pow(2, j); }
|
||||||
|
selectBit++;
|
||||||
|
}
|
||||||
|
frameStringOut[i] = (char)quartet;
|
||||||
|
}
|
||||||
|
tempShowData.Add(new string(frameStringOut).Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
ShowtapeFrames = tempShowData.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectNextShowtape(StartMethod method)
|
||||||
|
{
|
||||||
|
ShowtapeFrames = [];
|
||||||
|
ShowtapeIndex = 0;
|
||||||
|
if (Config.Shows.Count() == 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("There are no shows in the playlist.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool willStartShow = false;
|
||||||
|
bool bypassIntermission = false;
|
||||||
|
if (Intermission)
|
||||||
|
{
|
||||||
|
Intermission = false;
|
||||||
|
bypassIntermission = true;
|
||||||
|
GUIUpdateTimer.Stop();
|
||||||
|
}
|
||||||
|
switch (method)
|
||||||
|
{
|
||||||
|
case StartMethod.PlaylistStart:
|
||||||
|
switch (Config.PlaylistStartOption)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
PlaylistIndex = 0;
|
||||||
|
willStartShow = true;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
PlaylistIndex = SelectRandom.Next(Config.Shows.Count());
|
||||||
|
willStartShow = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case StartMethod.PlaylistShowEnd:
|
||||||
|
if (Config.PlaylistIntermissionOption && (!bypassIntermission))
|
||||||
|
{
|
||||||
|
Intermission = true;
|
||||||
|
IntermissionTotalTime = IntermissionSecondsLeft = Config.PlaylistIntermissionTimeOption * ((Config.PlaylistIntermissionUnitOption == 1) ? 1 : 60);
|
||||||
|
SkipButton.Enabled = true;
|
||||||
|
StopButton.Enabled = true;
|
||||||
|
PauseButton.Enabled = true;
|
||||||
|
Invoke(delegate { PlaybackControlsGroupBox.Text = "Controls: Intermission"; });
|
||||||
|
GUIUpdateTimer.Start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (Config.PlaylistShowEndOption)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
PlaylistIndex++;
|
||||||
|
if (PlaylistIndex >= Config.Shows.Count())
|
||||||
|
{
|
||||||
|
if (Config.PlaylistLoopOption)
|
||||||
|
{
|
||||||
|
PlaylistIndex = 0;
|
||||||
|
willStartShow = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else willStartShow = true;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
PlaylistIndex = SelectRandom.Next(Config.Shows.Count());
|
||||||
|
willStartShow = true;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
willStartShow = true;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (willStartShow)
|
||||||
|
{
|
||||||
|
CurrentlyPlaying = Config.Shows[PlaylistIndex];
|
||||||
|
LoadNextShowtape();
|
||||||
|
|
||||||
|
FrameTimer = new System.Timers.Timer((1000d / 60d) * Config.FramesPerTick);
|
||||||
|
FrameTimer.Elapsed += PlayFrame;
|
||||||
|
FrameTimer.AutoReset = true;
|
||||||
|
|
||||||
|
ResyncTimer = new System.Timers.Timer(Config.ResyncSeconds * 1000);
|
||||||
|
ResyncTimer.Elapsed += Resync;
|
||||||
|
ResyncTimer.AutoReset = true;
|
||||||
|
|
||||||
|
dataProvider = new StreamDataProvider(File.OpenRead("pc3playertempaudio.tmp"));
|
||||||
|
AudioPlayer = new SoundPlayer(dataProvider);
|
||||||
|
|
||||||
|
Invoke(delegate { PlaybackControlsGroupBox.Text = $"Controls: Playing {CurrentlyPlaying.Name}"; });
|
||||||
|
|
||||||
|
Mixer.Master.AddComponent(AudioPlayer);
|
||||||
|
Playing = true;
|
||||||
|
AudioPlayer.Play();
|
||||||
|
FrameTimer.Start();
|
||||||
|
ResyncTimer.Start();
|
||||||
|
GUIUpdateTimer.Start();
|
||||||
|
PauseButton.Enabled = true;
|
||||||
|
StopButton.Enabled = true;
|
||||||
|
SkipButton.Enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GUIUpdateTick(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
if (Playing)
|
||||||
|
{
|
||||||
|
Invoke(delegate { TimeLabel.Text = $"({TimeSpan.FromSeconds(AudioPlayer.Time).ToString(@"hh\:mm\:ss")}/{CurrentlyPlaying.Length})"; });
|
||||||
|
}
|
||||||
|
if (Intermission)
|
||||||
|
{
|
||||||
|
if (IntermissionSecondsLeft == 0) SelectNextShowtape(StartMethod.PlaylistShowEnd);
|
||||||
|
Invoke(delegate { TimeLabel.Text = $"({TimeSpan.FromSeconds(IntermissionTotalTime - IntermissionSecondsLeft).ToString(@"hh\:mm\:ss")}/{TimeSpan.FromSeconds(IntermissionTotalTime).ToString(@"hh\:mm\:ss")})"; });
|
||||||
|
if (!Paused) IntermissionSecondsLeft--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayFrame(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
if (ShowtapeIndex + Config.FrameShift >= ShowtapeFrames.Length)
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
SelectNextShowtape(StartMethod.PlaylistShowEnd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ControllerPort.Write(ShowtapeFrames[ShowtapeIndex + Config.FrameShift]);
|
||||||
|
ShowtapeIndex += Config.FramesPerTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resync(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
ShowtapeIndex = (int)(AudioPlayer.Time * 60f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PauseButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Paused)
|
||||||
|
{
|
||||||
|
Paused = false;
|
||||||
|
PauseButton.Text = "Pause";
|
||||||
|
if (Playing)
|
||||||
|
{
|
||||||
|
FrameTimer.Start();
|
||||||
|
ResyncTimer.Start();
|
||||||
|
AudioPlayer.Seek((float)(((float)ShowtapeIndex) / 60.0));
|
||||||
|
AudioPlayer.Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Paused = true;
|
||||||
|
PauseButton.Text = "Unpause";
|
||||||
|
if (Playing)
|
||||||
|
{
|
||||||
|
FrameTimer.Stop();
|
||||||
|
ResyncTimer.Stop();
|
||||||
|
AudioPlayer.Pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StopButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SkipButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Playing) Stop();
|
||||||
|
SelectNextShowtape(StartMethod.PlaylistShowEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Playing)
|
||||||
|
{
|
||||||
|
if (MessageBox.Show(
|
||||||
|
"A show is currently playing!\nPerforming this action will stop it.\nAre you sure?",
|
||||||
|
"Show Playing",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Exclamation
|
||||||
|
) != DialogResult.Yes)
|
||||||
|
return;
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
SelectNextShowtape(StartMethod.PlaylistStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop()
|
||||||
|
{
|
||||||
|
Playing = false;
|
||||||
|
AudioPlayer.Stop();
|
||||||
|
FrameTimer.Stop();
|
||||||
|
ResyncTimer.Stop();
|
||||||
|
GUIUpdateTimer.Stop();
|
||||||
|
ResyncTimer.Dispose();
|
||||||
|
FrameTimer.Dispose();
|
||||||
|
PauseButton.Enabled = false;
|
||||||
|
StopButton.Enabled = false;
|
||||||
|
SkipButton.Enabled = false;
|
||||||
|
if (Playing) Mixer.Master.RemoveComponent(AudioPlayer);
|
||||||
|
Paused = false;
|
||||||
|
Invoke(delegate
|
||||||
|
{
|
||||||
|
PlaybackControlsGroupBox.Text = "Controls: Not Playing";
|
||||||
|
PauseButton.Text = "Pause";
|
||||||
|
TimeLabel.Text = "(00:00:00/00:00:00)";
|
||||||
|
});
|
||||||
|
dataProvider.Dispose();
|
||||||
|
if (File.Exists("pc3playertempaudio.tmp")) File.Delete("pc3playertempaudio.tmp");
|
||||||
|
ShowtapeFrames = [];
|
||||||
|
ShowtapeIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NewPlaylistButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (Playing)
|
||||||
|
{
|
||||||
|
if (MessageBox.Show(
|
||||||
|
"A show is currently playing!\nPerforming this action will stop it.\nAre you sure?",
|
||||||
|
"Show Playing",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Exclamation
|
||||||
|
) != DialogResult.Yes)
|
||||||
|
return;
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InvalidateSave)
|
||||||
|
if (MessageBox.Show(
|
||||||
|
"You have an unsaved Playlist!\nDo you still want to create a new one?",
|
||||||
|
"Unsaved Playlist",
|
||||||
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Exclamation
|
||||||
|
) != DialogResult.Yes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Config = new PlaylistConfig();
|
||||||
|
ChannelMappingGroupBox.Text = "Channel Map: None Loaded";
|
||||||
|
PlaylistGroupBox.Text = "Playlist: Unsaved";
|
||||||
|
UpdateListView();
|
||||||
|
InvalidateSave = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3064
PC3Player/PC3Player/MainForm.resx
Normal file
3064
PC3Player/PC3Player/MainForm.resx
Normal file
File diff suppressed because it is too large
Load diff
21
PC3Player/PC3Player/PC3Player.csproj
Normal file
21
PC3Player/PC3Player/PC3Player.csproj
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="icon.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="SoundFlow" Version="1.1.1" />
|
||||||
|
<PackageReference Include="System.IO.Ports" Version="9.0.6" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
17
PC3Player/PC3Player/PC3Player.csproj.user
Normal file
17
PC3Player/PC3Player/PC3Player.csproj.user
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<_LastSelectedProfileId>C:\Users\Persephone\source\repos\PC3Player\PC3Player\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="AdvancedSettingsForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="MainForm.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Update="SerialPortSelector.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
17
PC3Player/PC3Player/Program.cs
Normal file
17
PC3Player/PC3Player/Program.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
namespace PC3Player
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
static void Main()
|
||||||
|
{
|
||||||
|
// To customize application configuration such as set high DPI settings or default font,
|
||||||
|
// see https://aka.ms/applicationconfiguration.
|
||||||
|
ApplicationConfiguration.Initialize();
|
||||||
|
Application.Run(new MainForm());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Any CPU</Platform>
|
||||||
|
<PublishDir>bin\Release\net8.0-windows\publish\</PublishDir>
|
||||||
|
<PublishProtocol>FileSystem</PublishProtocol>
|
||||||
|
<_TargetId>Folder</_TargetId>
|
||||||
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
|
<SelfContained>false</SelfContained>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<History>True|2025-07-08T03:32:00.3108399Z||;True|2025-07-07T16:13:43.3420483-07:00||;</History>
|
||||||
|
<LastFailureDetails />
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
114
PC3Player/PC3Player/SerialPortSelector.Designer.cs
generated
Normal file
114
PC3Player/PC3Player/SerialPortSelector.Designer.cs
generated
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
namespace PC3Player
|
||||||
|
{
|
||||||
|
partial class SerialPortSelector
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Windows Form Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
label1 = new Label();
|
||||||
|
PortDropDown = new ComboBox();
|
||||||
|
CancelButton = new Button();
|
||||||
|
OKButton = new Button();
|
||||||
|
panel1 = new Panel();
|
||||||
|
panel1.SuspendLayout();
|
||||||
|
SuspendLayout();
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.AutoSize = true;
|
||||||
|
label1.Location = new Point(12, 15);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(29, 15);
|
||||||
|
label1.TabIndex = 0;
|
||||||
|
label1.Text = "Port";
|
||||||
|
//
|
||||||
|
// PortDropDown
|
||||||
|
//
|
||||||
|
PortDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||||
|
PortDropDown.FormattingEnabled = true;
|
||||||
|
PortDropDown.Location = new Point(47, 12);
|
||||||
|
PortDropDown.Name = "PortDropDown";
|
||||||
|
PortDropDown.Size = new Size(191, 23);
|
||||||
|
PortDropDown.TabIndex = 1;
|
||||||
|
//
|
||||||
|
// CancelButton
|
||||||
|
//
|
||||||
|
CancelButton.DialogResult = DialogResult.Cancel;
|
||||||
|
CancelButton.Location = new Point(82, 13);
|
||||||
|
CancelButton.Name = "CancelButton";
|
||||||
|
CancelButton.Size = new Size(75, 25);
|
||||||
|
CancelButton.TabIndex = 2;
|
||||||
|
CancelButton.Text = "Cancel";
|
||||||
|
CancelButton.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// OKButton
|
||||||
|
//
|
||||||
|
OKButton.DialogResult = DialogResult.OK;
|
||||||
|
OKButton.Location = new Point(163, 13);
|
||||||
|
OKButton.Name = "OKButton";
|
||||||
|
OKButton.Size = new Size(75, 25);
|
||||||
|
OKButton.TabIndex = 3;
|
||||||
|
OKButton.Text = "OK";
|
||||||
|
OKButton.UseVisualStyleBackColor = true;
|
||||||
|
OKButton.Click += OKButton_Click;
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
panel1.BackColor = SystemColors.MenuBar;
|
||||||
|
panel1.Controls.Add(OKButton);
|
||||||
|
panel1.Controls.Add(CancelButton);
|
||||||
|
panel1.Location = new Point(0, 50);
|
||||||
|
panel1.Name = "panel1";
|
||||||
|
panel1.Size = new Size(250, 50);
|
||||||
|
panel1.TabIndex = 4;
|
||||||
|
//
|
||||||
|
// SerialPortSelector
|
||||||
|
//
|
||||||
|
AcceptButton = OKButton;
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(250, 100);
|
||||||
|
Controls.Add(panel1);
|
||||||
|
Controls.Add(PortDropDown);
|
||||||
|
Controls.Add(label1);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||||
|
Name = "SerialPortSelector";
|
||||||
|
Text = "Select a Serial Port";
|
||||||
|
Load += SerialPortSelector_Load;
|
||||||
|
panel1.ResumeLayout(false);
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Label label1;
|
||||||
|
private ComboBox PortDropDown;
|
||||||
|
private Button CancelButton;
|
||||||
|
private Button OKButton;
|
||||||
|
private Panel panel1;
|
||||||
|
}
|
||||||
|
}
|
24
PC3Player/PC3Player/SerialPortSelector.cs
Normal file
24
PC3Player/PC3Player/SerialPortSelector.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
using System.IO.Ports;
|
||||||
|
|
||||||
|
namespace PC3Player
|
||||||
|
{
|
||||||
|
public partial class SerialPortSelector : Form
|
||||||
|
{
|
||||||
|
public string PortName { get; set; }
|
||||||
|
public SerialPortSelector()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SerialPortSelector_Load(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
PortDropDown.Items.Clear();
|
||||||
|
foreach (string port in SerialPort.GetPortNames()) PortDropDown.Items.Add(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OKButton_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
PortName = (string)PortDropDown.SelectedItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
PC3Player/PC3Player/SerialPortSelector.resx
Normal file
120
PC3Player/PC3Player/SerialPortSelector.resx
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
BIN
PC3Player/PC3Player/icon.ico
Normal file
BIN
PC3Player/PC3Player/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 171 KiB |
|
@ -1,3 +1,3 @@
|
||||||
# PinkConnection2
|
# PinkConnection
|
||||||
|
|
||||||
Software for use with PinkConnection2 Animatronic Controllers
|
Software for use with PinkConnection Animatronic Controllers
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue