Compare commits

...

22 commits

Author SHA1 Message Date
b9fd99de54 Update MainForm.cs 2025-06-01 14:10:28 -07:00
d44ae82757 further clean up stuff 2025-06-01 14:00:22 -07:00
5d216840db discontinue single character file format 2025-06-01 13:55:57 -07:00
4ec6533971 add studio c bit maps to converter 2025-06-01 13:23:21 -07:00
7896e1d0a3 oops 2025-06-01 13:04:15 -07:00
424d9331cd studio c 2025-06-01 13:00:52 -07:00
91aa378769 Update MainForm.cs 2025-05-31 23:28:48 -07:00
a79a5e54c5 cybers bit mappings in converter 2025-05-31 23:28:23 -07:00
1d387b5679 finish cybers bit mapping 2025-05-31 20:19:26 -07:00
6678780ef6 full 3 stage bit map and 256 bit conversion 2025-05-26 19:21:00 -07:00
1cb4b77f9a complete bit mapping for 3st/rae 2025-05-26 18:25:47 -07:00
0ed3491e3f add option to compress audio to mp3 when converting rshw 2025-05-26 08:59:59 -07:00
29799820e2 update goals file 2025-05-18 11:07:18 -07:00
f756c70c1c arduino mega 2025-05-11 12:39:24 -07:00
f167c0fcb1 i should maybe actually test these things 2025-05-11 09:38:50 -07:00
6f53e6dab4 thank you lexi for your wonderful improvement 2025-05-10 22:02:21 -07:00
31bedffa29 fix helen fw mappings 2025-05-10 17:25:48 -07:00
854d6e4c37 handle on process 2025-05-10 14:11:37 -07:00
1fb697626e player kinda works 2025-05-10 14:02:28 -07:00
8ef01ea1aa Update ServoWorker.ino 2025-05-05 19:38:13 -07:00
271be04b98 Update Firmware-Servo-ChuckEHelenGuestStar.ino 2025-05-05 19:36:58 -07:00
7ee8214615 update firmwares to send info to controlling computer 2025-05-05 19:08:45 -07:00
32 changed files with 1227 additions and 659 deletions

View file

@ -0,0 +1,138 @@
// PINKCONNECTION2 Client Program for 32 Valve Systems (Arduino Mega)
int byte1 = 0;
int byte2 = 0;
int byte3 = 0;
int byte4 = 0;
int byte5 = 0;
int byte6 = 0;
int byte7 = 0;
int byte8 = 0;
void setup()
{
for (int i = 22; i <= 53; i++) pinMode(i, OUTPUT);
Serial.begin(9600);
Serial.write("PC2,32,Universal,END");
}
void loop()
{
if (Serial.available() > 7)
{
byte1 = Serial.read();
byte2 = Serial.read();
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 & 1) digitalWrite(22, 1);
else digitalWrite(22, 0);
if (byte1 & 2) digitalWrite(23, 1);
else digitalWrite(23, 0);
if (byte1 & 4) digitalWrite(24, 1);
else digitalWrite(24, 0);
if (byte1 & 8) digitalWrite(25, 1);
else digitalWrite(25, 0);
if (byte2 & 1) digitalWrite(26, 1);
else digitalWrite(26, 0);
if (byte2 & 2) digitalWrite(27, 1);
else digitalWrite(27, 0);
if (byte2 & 4) digitalWrite(28, 1);
else digitalWrite(28, 0);
if (byte2 & 8) digitalWrite(29, 1);
else digitalWrite(29, 0);
if (byte3 & 1) digitalWrite(30, 1);
else digitalWrite(30, 0);
if (byte3 & 2) digitalWrite(31, 1);
else digitalWrite(31, 0);
if (byte3 & 4) digitalWrite(32, 1);
else digitalWrite(32, 0);
if (byte3 & 8) digitalWrite(33, 1);
else digitalWrite(33, 0);
if (byte4 & 1) digitalWrite(34, 1);
else digitalWrite(34, 0);
if (byte4 & 2) digitalWrite(35, 1);
else digitalWrite(35, 0);
if (byte4 & 4) digitalWrite(36, 1);
else digitalWrite(36, 0);
if (byte4 & 8) digitalWrite(37, 1);
else digitalWrite(37, 0);
if (byte5 & 1) digitalWrite(38, 1);
else digitalWrite(22, 0);
if (byte5 & 2) digitalWrite(39, 1);
else digitalWrite(23, 0);
if (byte5 & 4) digitalWrite(40, 1);
else digitalWrite(24, 0);
if (byte5 & 8) digitalWrite(41, 1);
else digitalWrite(25, 0);
if (byte6 & 1) digitalWrite(42, 1);
else digitalWrite(42, 0);
if (byte6 & 2) digitalWrite(43, 1);
else digitalWrite(43, 0);
if (byte6 & 4) digitalWrite(44, 1);
else digitalWrite(44, 0);
if (byte6 & 8) digitalWrite(45, 1);
else digitalWrite(45, 0);
if (byte7 & 1) digitalWrite(46, 1);
else digitalWrite(46, 0);
if (byte7 & 2) digitalWrite(47, 1);
else digitalWrite(47, 0);
if (byte7 & 4) digitalWrite(48, 1);
else digitalWrite(48, 0);
if (byte7 & 8) digitalWrite(49, 1);
else digitalWrite(49, 0);
if (byte8 & 1) digitalWrite(50, 1);
else digitalWrite(50, 0);
if (byte8 & 2) digitalWrite(51, 1);
else digitalWrite(51, 0);
if (byte8 & 4) digitalWrite(52, 1);
else digitalWrite(52, 0);
if (byte8 & 8) digitalWrite(53, 1);
else digitalWrite(53, 0);
}
}
}

View file

@ -1,9 +1,10 @@
// PINKCONNECTION2 Client Program for Valve Systems
// PINKCONNECTION2 Client Program for 8 Valve Systems
int byte1 = 0;
int byte2 = 0;
void setup() {
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
@ -13,13 +14,18 @@ void setup() {
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
Serial.begin(9600);
Serial.write("PC2,8,Universal,END");
}
void loop() {
if (Serial.available() > 1) {
void loop()
{
if (Serial.available() > 1)
{
byte1 = Serial.read();
byte2 = Serial.read();
if ((byte1 & 64) && (byte2 & 64)) {
if ((byte1 & 64) && (byte2 & 64))
{
if (byte1 & 1) digitalWrite(2, 1);
else digitalWrite(2, 0);

View file

@ -1,104 +0,0 @@
// PINKCONNECTION2 Client Program for Helen Henny/Chuck E./Guest Star Cyberamic Servo
#include <Servo.h>
#include <string.h>
Servo servoChannel[8];
byte onDegrees[8] = { 90, 0, 0, 0, 45, 135, 0, 0 }; // these are incomplete, i need to tune them when i get the servos in
byte offDegrees[8] = { 0, 0, 0, 0, 90, 90, 0, 0 };
int byte1 = 0;
int byte2 = 0;
void setup() {
servoChannel[0].attach(2);
servoChannel[1].attach(3);
servoChannel[2].attach(4);
servoChannel[3].attach(5);
servoChannel[4].attach(6);
servoChannel[5].attach(7);
servoChannel[6].attach(8);
servoChannel[7].attach(9);
pinMode(A0, OUTPUT);
pinMode(A1, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
for (int i = 0; i < 8; i++) servoChannel[i].write(offDegrees[i]);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 1) {
byte1 = Serial.read();
byte2 = Serial.read();
if ((byte1 & 64) && (byte2 & 64))
if (byte1 & 1) {
servoChannel[0].write(onDegrees[0]);
digitalWrite(A0, 1);
} else {
servoChannel[0].write(offDegrees[0]);
digitalWrite(A0, 0);
}
if (byte1 & 2) {
servoChannel[1].write(onDegrees[1]);
digitalWrite(A1, 1);
} else {
servoChannel[1].write(offDegrees[1]);
digitalWrite(A1, 0);
}
if (byte1 & 4) {
servoChannel[2].write(onDegrees[2]);
digitalWrite(A2, 1);
} else {
servoChannel[2].write(offDegrees[2]);
digitalWrite(A2, 0);
}
if (byte1 & 8) {
servoChannel[2].write(onDegrees[3]);
digitalWrite(A3, 1);
} else {
//servoChannel[2].write(offDegrees[3]); dont
digitalWrite(A3, 0);
}
if (byte2 & 1) {
servoChannel[4].write(onDegrees[4]);
digitalWrite(A4, 1);
} else {
servoChannel[4].write(offDegrees[4]);
digitalWrite(A4, 0);
}
if (byte2 & 2) {
servoChannel[4].write(onDegrees[5]);
digitalWrite(A5, 1);
} else {
//servoChannel[4].write(offDegrees[5]); dont
digitalWrite(A5, 0);
}
if (byte2 & 4) {
servoChannel[6].write(onDegrees[6]);
digitalWrite(10, 1);
} else {
servoChannel[6].write(offDegrees[6]);
digitalWrite(10, 0);
}
if (byte2 & 8) {
servoChannel[7].write(onDegrees[7]);
digitalWrite(11, 1);
} else {
servoChannel[7].write(offDegrees[7]);
digitalWrite(11, 0);
}
}
}

View file

@ -0,0 +1,61 @@
// PINKCONNECTION2 Client Program for Helen Henny/Chuck E./Guest Star Cyberamic Servo
#include <Servo.h>
Servo servoChannel[6];
byte onDegrees[8] = { 90, 0, 0, 0, 45, 135, 0, 0 }; // these are incomplete
byte offDegrees[8] = { 0 , 0, 0, 0, 90, 90 , 0, 0 };
byte mapping[8] = { 0 , 1, 1, 2, 3 , 3 , 4, 5 };
int byte1 = 0;
int byte2 = 0;
void setup()
{
servoChannel[0].attach(2);
servoChannel[1].attach(3);
servoChannel[2].attach(4);
servoChannel[3].attach(5);
servoChannel[4].attach(6);
servoChannel[5].attach(7);
for (int i = 0; i < 8; i++) servoChannel[mapping[i]].write(offDegrees[i]);
Serial.begin(9600);
Serial.write("PC2,8,Chuck E./Helen/Guest Star,END");
}
void loop()
{
if (Serial.available() > 1)
{
byte1 = Serial.read();
byte2 = Serial.read();
if ((byte1 & 64) && (byte2 & 64))
{
if (byte1 & 1) servoChannel[mapping[0]].write(onDegrees[0]);
else servoChannel[mapping[0]].write(offDegrees[0]);
if (byte1 & 2) servoChannel[mapping[1]].write(onDegrees[1]);
else servoChannel[mapping[1]].write(offDegrees[1]);
if (byte1 & 4) servoChannel[mapping[2]].write(onDegrees[2]);
else servoChannel[mapping[2]].write(offDegrees[2]);
if (byte1 & 8) servoChannel[mapping[3]].write(onDegrees[3]);
else servoChannel[mapping[3]].write(offDegrees[3]);
if (byte2 & 1) servoChannel[mapping[4]].write(onDegrees[4]);
else servoChannel[mapping[4]].write(offDegrees[4]);
if (byte2 & 2) servoChannel[mapping[5]].write(onDegrees[5]);
else servoChannel[mapping[5]].write(offDegrees[5]);
if (byte2 & 4) servoChannel[mapping[6]].write(onDegrees[6]);
else servoChannel[mapping[6]].write(offDegrees[6]);
if (byte2 & 8) servoChannel[mapping[7]].write(onDegrees[7]);
else servoChannel[mapping[7]].write(offDegrees[7]);
}
}
}

View file

@ -1,20 +1,23 @@
// PINKCONNECTION2 Client Program for Helen Henny/Mitzi Mozzarella Servo
#include <Servo.h>
#include <string.h>
Servo servoChannel[11]; // mouth earL earR eyelidL eyelidR eyeL eyeR headR headL headUp armUpL armUpR elbowR elbowL armTwistL armTwistR bodyTwistR bodyTwistL bodyLean
byte onDegrees[19] = { 45, 0, 0, 0, 0, 0, 0, 45, 135, 135, 90, 90, 90, 90, 90, 90, 0, 0, 0 };
byte offDegrees[19] = { 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 180, 0, 0, 180, 180, 0 , 0, 0, 0 };
byte mapping[19] = { 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 6, 3, 4, 7, 8, 5, 0, 0, 0 };
Servo servoChannel[11]; // mouth earL earR eyelidL eyelidR eyeL eyeR headL headR headUp armUpL armTwistL elbowL armUpR armTwistR elbowR bodyTwistR bodyTwistL bodyLean
byte onDegrees[19] = { 45, 0, 0, 0, 0, 0, 0, 135, 45, 135, 90, 90, 90, 90, 90, 90, 0, 0, 0 };
byte offDegrees[19] = { 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 180, 180, 180, 0, 0, 0 , 0, 0, 0 };
byte mapping[19] = { 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 3, 4, 5, 6, 7, 8, 9, 9, 10 };
int byte1 = 0;
int byte2 = 0;
int byte3 = 0;
int byte4 = 0;
int byte5 = 0;
int byte6 = 0;
int byte7 = 0;
int byte8 = 0;
void setup() {
void setup()
{
servoChannel[0].attach(2);
servoChannel[1].attach(3);
servoChannel[2].attach(4);
@ -26,15 +29,20 @@ void setup() {
servoChannel[8].attach(10);
for (int i = 0; i < 19; i++) servoChannel[mapping[i]].write(offDegrees[i]);
Serial.begin(9600);
Serial.write("PC2,32,Mitzi/Helen,END");
}
void loop() {
if (Serial.available() > 4) {
if (Serial.available() > 7)
{
byte1 = Serial.read();
byte2 = Serial.read();
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))
{

View file

@ -1,4 +1,4 @@
// tp1sm
// Ensure that a servo works, and get it to its 0 position
#include <Servo.h>
@ -14,5 +14,5 @@ void loop()
servoChannel.write(0);
delay(1000);
servoChannel.write(180);
delay(1000);
delay(2000);
}

View file

@ -1,4 +1,4 @@
# PINKCONNECTION2 Bit Mappings
# UST Bit Mappings
This information was sourced from Cheese-E-Pedia, the Showbiz Pizza Cyberstar Install Manual, and the Chuck E. Cheese 2-Stage Install Manual.
@ -6,7 +6,7 @@ This information was sourced from Cheese-E-Pedia, the Showbiz Pizza Cyberstar In
### Rolfe Dewolfe & Earl Schmerle/Chuck E. Cheese
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| --------------- | ------------------------ | ------------------ | ------------- | ----------- | ------------ | ------------ |
| Mouth | 1 | 1 | 1 | 1-1 | TB1 1-2 H1 | No |
| Left Ear | 2 | 2 | 9 | 1-9 | | |
@ -17,7 +17,7 @@ This information was sourced from Cheese-E-Pedia, the Showbiz Pizza Cyberstar In
| Eyes Right | 7 | 7 | 5 | 1-5 | TB1 9-10 H1 | No |
| Head Left | 8 | 8 | 6 | 1-6 | TB1 3-4 H1 | No |
| Head Right | 9 | 9 | 7 | 1-7 | TB1 5-6 H1 | No |
| Head Up | 10 | 10 | 8 | 1-8 | TB1 7-8 H1 | Yes |
| Head Up | 10 | 10 | 8 | 1-8 | TB1 7-8 H1 | No |
| Left Arm Up | 11 | 11 | 11 | 1-11 | | |
| Left Arm Twist | 12 | 12 | 12 | 1-12 | | |
| Left Elbow | 13 | 13 | 13 | 1-13 | | |
@ -35,7 +35,7 @@ Earl's movements were removed during Concept Unification.
### Mitzi Mozzarella/Helen Henny
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| --------------- | ------------------------ | ------------------ | ------------- | ----------- | ------------ | ------------ |
| Mouth | 1 | 23 | 185 | 2-35 | TB1 1-2 H5 | No |
| Left Ear | 2 | 24 | 176 | 2-26 | | |
@ -46,7 +46,7 @@ Earl's movements were removed during Concept Unification.
| Eyes Right | 7 | 29 | 184 | 2-34 | TB1 9-10 H5 | No |
| Head Left | 8 | 30 | 178 | 2-28 | TB1 3-4 H5 | No |
| Head Right | 9 | 31 | 179 | 2-29 | TB1 5-6 H5 | No |
| Head Up | 10 | 32 | 180 | 2-30 | TB1 7-8 H5 | Yes |
| Head Up | 10 | 32 | 180 | 2-30 | TB1 7-8 H5 | No |
| Left Arm Up | 11 | 33 | 173 | 2-23 | | |
| Left Arm Twist | 12 | 34 | 175 | 2-25 | | |
| Left Elbow | 13 | 35 | 174 | 2-24 | | |
@ -61,7 +61,7 @@ No movements were removed during Concept Unification.
### Fatz Geronimo/Mr. Munch
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| --------------- | ------------------------ | ------------------ | ------------- | ----------- | ------------ | ------------ |
| Mouth | 1 | 42 | 45 | 1-45 | TB1 1-2 H4 | No |
| Left Eyelid | 2 | 43 | 41 | 1-41 | TB1 11-12 H4 | Yes |
@ -84,7 +84,7 @@ No movements were removed during Concept Unification.
### Beach Bear/Jasper T. Jowls
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| --------------- | ------------------------ | ------------------ | ------------- | ----------- | ------------------------- | ------------ |
| Mouth | 1 | 58 | 166 | 2-16 | TB1 1-2 H2 | No |
| Left Eyelid | 2 | 59 | 151 | 2-1 | TB1 11-12 H2 | Yes |
@ -92,7 +92,7 @@ No movements were removed during Concept Unification.
| Eyes Cross | 4 | 61 | 153 | 2-3 | | |
| Head Left | 5 | 62 | 156 | 2-6 | TB1 3-4 H2 & TB1 15-16 H2 | No |
| Head Right | 6 | 63 | 157 | 2-7 | TB1 5-6 H2 & TB1 9-10 H2 | No |
| Head Up | 7 | 64 | 158 | 2-8 | TB1 7-8 H2 | Yes |
| Head Up | 7 | 64 | 158 | 2-8 | TB1 7-8 H2 | No |
| Right Arm Raise | 8 | 65 | 161 | 2-11 | | |
| Right Arm Twist | 9 | 66 | 162 | 2-12 | | |
| Right Elbow | 10 | 67 | 163 | 2-13 | TB1 13-14 H2 | No |
@ -107,7 +107,7 @@ No movements were removed during Concept Unification.
### Dook Larue/Pasqually
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| --------------- | ------------------------ | ------------------ | ------------- | ----------- | ------------ | ------------ |
| Mouth | 1 | 74 | 30 | 1-30 | TB1 1-2 H3 | No |
| Left Ear | 2 | 75 | 23 | 1-23 | | |
@ -131,7 +131,7 @@ Ear movements and Kick Drum were removed during Concept Unification.
### Billy Bob
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit |
| --------------- | ------------------------ | ------------------ | ------------- | ----------- |
| Mouth | 1 | 91 | 196 | 2-46 |
| Left Eyelid | 2 | 92 | 197 | 2-47 |
@ -158,7 +158,7 @@ Entire bot was removed during Concept Unification.
### Looney Bird/Pizzacam
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | Greybox Bit |
| --------------- | ------------------------ | ------------------ | ------------- | ----------- |
| Mouth | 1 | 111 | 167 | 2-17 |
| Left Eyelid | 2 | 112 | 191 | 2-41 |
@ -170,11 +170,114 @@ Entire bot was removed during Concept Unification.
Hand movement was removed during Concept Unification.
## R12 (Road/1-Stage/2-Stage)
### Props
| Name | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| ------------------- | ------------------ | ------------- | ----------- | ---------- | ------------ |
| Sun/Building Raise | 118 | 39 | 1-39 | | |
| Sun/Building Mouth | 119 | 38 | 1-38 | | |
| Moon Raise | 120 | 47 | 1-47 | | |
| Moon Mouth | 121 | 46 | 1-46 | | |
| Antioch/Wink | 122 | 49 | 1-49 | TB2 3-4 H1 | No |
| Choo-Choo/Munch Jr. | 123 | 50 | 1-50 | | |
### Spots
| Name | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| --------------------------------- | ------------------ | ------------- | ----------- | ------------ | ------------ |
| Rolfe/Chuck E. Spot | 124 | 88 | 1-88 | TB1 15-16 H7 | No |
| Dook/Helen Spot | 125 | 86 | 1-86 | TB1 11-12 H7 | No |
| Fatz/Munch Spot | 126 | 85 | 1-85 | TB2 9-10 H7 | No |
| Beach Bear/Jasper Spot | 127 | 82 | 1-82 | TB2 5-6 H7 | No |
| Beach Bear/Jasper Guitar Spot | 128 | 242 | 2-96 | | |
| Billy Bob/Pasqually Spot | 129 | 84 | 1-84 | TB1 7-8 H7 | No |
| Looney Bird/Pizzacam Spot | 130 | 83 | 1-83 | | |
| Mitzi/Wink Spot | 131 | 81 | 1-81 | TB2 5-6 H8 | No |
| Sun/Building Spot | 132 | 238 | 2-88 | | |
| Moon Spot | 133 | 239 | 2-89 | | |
| Antioch/Munch Jr. Spot/Gobo Light | 134 | 240 | 2-90 | TB1 7-8 H8 | No |
| Earl Spot/Helicopter Light/Gemini | 135 | 87 | 1-87 | TB2 3-4 H8 | No |
### Curtains
| Name | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| ------------------ | ------------------ | ------------- | ----------- | ------------------------- | ------------ |
| Stage Left Open | 136 | 93 | 1-93 | TB2 5-6 H2 & TB2 1-2 H2 | No |
| Stage Left Close | 137 | 94 | 1-94 | TB2 7-8 H2 & TB2 3-4 H2 | No |
| Center Stage Open | 138 | 91 | 1-91 | TB2 9-10 H2 & TB2 1-2 H2 | No |
| Center Stage Close | 139 | 92 | 1-92 | TB2 11-12 H2 & TB2 3-4 H2 | No |
| Stage Right Open | 140 | 89 | 1-89 | TB2 9-10 H2 & TB2 1-2 H2 | No |
| Stage Right Close | 141 | 90 | 1-90 | TB2 11-12 H2 & TB2 3-4 H2 | No |
### Floods
| Name | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| ------------------ | ------------------ | ------------- | ----------- | ------------ | ------------ |
| Stage Left Red | 142 | 229 | 2-79 | TB1 15-16 H8 | No |
| Stage Left Amber | 143 | 228 | 2-78 | TB1 7-8 H8 | No |
| Stage Left Green | 144 | 227 | 2-77 | | |
| Stage Left Blue | 145 | 226 | 2-76 | TB2 13-14 H8 | No |
| Center Stage Red | 146 | 224 | 2-74 | TB1 11-12 H8 | No |
| Center Stage Amber | 147 | 223 | 2-73 | TB1 9-10 H8 | No |
| Center Stage Blue | 148 | 221 | 2-71 | TB1 13-14 H8 | No |
| Stage Right Red | 149 | 219 | 2-69 | | |
| Stage Right Amber | 150 | 218 | 2-68 | | |
| Stage Right Green | 151 | 217 | 2-67 | | |
| Stage Right Blue | 152 | 216 | 2-66 | | |
| Live Flood | 153 | 222 | 2-72 | TB1 1-2 H7 | No |
### Backdrop
| Name | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| ---------------------- | ------------------ | ------------- | ----------- | ---------- | ------------ |
| Backdrop Red | 154 | 235 | 2-85 | TB1 3-4 H8 | No |
| Backdrop Yellow | 155 | 232 | 2-82 | TB1 1-2 H8 | No |
| Backdrop Green | 156 | 231 | 2-81 | | |
| Backdrop Blue | 157 | 234 | 2-84 | TB2 5-6 H8 | No |
| Backdrop Red Outer | 158 | 236 | 2-86 | | |
| Backdrop Blue Outer | 159 | 237 | 2-87 | | |
| Backdrop Red Buildings | 160 | 233 | 2-83 | | |
| Stage Right Red Floor | 161 | 242 | 2-92 | | |
| Stage Right Blue Floor | 162 | 243 | 2-93 | | |
### Organ
| Name | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| ----------------- | ------------------ | ------------- | ----------- | ------------ | ------------ |
| Organ Face Red | 163 | 67 | 1-67 | TB2 11-12 H7 | No |
| Organ Face Amber | 164 | 68 | 1-68 | TB2 7-8 H7 | No |
| Organ Face Green | 165 | 69 | 1-69 | | |
| Organ Face Blue | 166 | 66 | 1-66 | | |
| Organ Legs Top | 167 | 71 | 1-71 | TB1 9-10 H7 | No |
| Organ Legs Middle | 168 | 72 | 1-72 | TB2 3-4 H7 | No |
| Organ Legs Bottom | 169 | 73 | 1-73 | TB2 13-14 H7 | No |
### Sign
| Name | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| ----------- | ------------------ | ------------- | ----------- | ------------ | ------------ |
| Sign Outer | 170 | 78 | 1-78 | | |
| Sign Middle | 171 | 77 | 1-77 | TB2 11-12 H8 | No |
| Sign Inner | 172 | 76 | 1-76 | | |
| Sign Strobe | 173 | 79 | 1-79 | | |
| Sign Flash | 174 | 80 | 1-80 | | |
### Special
| Name | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| ------------------- | ------------------ | ------------- | ----------- | ------------ | ------------ |
| Chuck E. Star | 175 | 220 | 2-70 | TB1 13-14 H7 | No |
| Chuck E. Neon | 176 | 244 | 2-94 | TB2 1-2 H7 | No |
| Jukebox Topper | 177 | 245 | 2-95 | TB2 9-10 H8 | No |
| Fiber Optic Curtain | 178 | 225 | 2-75 | TB2 1-2 H8 | No |
| Snare Drum Light | 179 | 230 | 2-80 | | |
| Kick Drum Light | 180 | 241 | 2-91 | TB1 5-6 H7 | No |
## Cyberamics
### Chuck E. Cheese
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| Movement Name | Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ------------- | ------------------------ | ------------------ | ------------- | ------------ |
| Mouth | 1 | 1 | 1 | TB1 1-2 H1 |
| Head Left | 2 | 2 | 2 | TB1 3-4 H1 |
@ -187,7 +290,7 @@ Hand movement was removed during Concept Unification.
### Helen Henny/Guest Star
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ------------- | ------------------------ | ------------------ | ------------- | ------------ |
| Mouth | 1 | 9 | 65 | TB1 1-2 H5 |
| Head Left | 2 | 10 | 66 | TB1 3-4 H5 |
@ -200,7 +303,7 @@ Hand movement was removed during Concept Unification.
### Mr. Munch
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ------------- | ------------------------ | ------------------ | ------------- | ------------ |
| Mouth | 1 | 17 | 49 | TB1 1-2 H4 |
| Head Left | 2 | 18 | 50 | TB1 3-4 H4 |
@ -213,7 +316,7 @@ Hand movement was removed during Concept Unification.
### Jasper T. Jowls
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ------------- | ------------------------ | ------------------ | ------------- | ------------ |
| Mouth | 1 | 25 | 17 | TB1 1-2 H2 |
| Head Left | 2 | 26 | 18 | TB1 3-4 H2 |
@ -226,7 +329,7 @@ Hand movement was removed during Concept Unification.
### Pasqually
| Movement Name | UST Single Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ------------- | ------------------------ | ------------------ | ------------- | ------------ |
| Mouth | 1 | 33 | 33 | TB1 1-2 H3 |
| Head Left | 2 | 34 | 34 | TB1 3-4 H3 |
@ -236,3 +339,197 @@ Hand movement was removed during Concept Unification.
| Eyelids | 6 | 38 | 38 | TB1 11-12 H3 |
| Right Arm | 7 | 39 | 39 | TB1 13-14 H3 |
| Left Arm | 8 | 40 | 36 | TB1 7-8 H3 |
### Props
| Name | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ------------------------- | ------------------ | ------------- | ------------ |
| Warblettes/Flower Mouth 1 | 41 | 9 | TB2 1-2 H1 |
| Flower Mouth 2 | 42 | 46 | TB2 11-12 H3 |
| Flower Mouth 3 | 43 | 62 | TB2 11-12 H4 |
| Warblettes Body Rock/Wink | 44 | 10 | TB2 3-4 H1 |
| Flag 1 | 45 | 74 | TB2 3-4 H5 |
| Flag 2 | 46 | 75 | TB2 5-6 H5 |
| Flag 3 | 47 | 76 | TB2 7-8 H5 |
| Flag 4 | 48 | 77 | TB2 9-10 H5 |
| Flag 5 | 49 | 78 | TB2 11-12 H5 |
### Spots
| Name | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ----------------------- | ------------------ | ------------- | ------------ |
| Chuck E. Spot | 50 | 104 | TB1 15-16 H7 |
| Helen Spot | 51 | 102 | TB1 11-12 H7 |
| Munch Spot | 52 | 109 | TB2 9-10 H7 |
| Jasper Spot | 53 | 107 | TB2 5-6 H7 |
| Pasqually Spot | 54 | 100 | TB1 7-8 H7 |
| Wink Spot | 55 | 123 | TB2 5-6 H8 |
| Flowers/Warblettes Spot | 56 | 41 | TB2 1-2 H3 |
### Curtains
| Name | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ------------------------ | ------------------ | ------------- | ------------ |
| CEC Stage Curtain Open | 57 | 27 | TB2 5-6 H2 |
| CEC Stage Curtain Close | 58 | 28 | TB2 7-8 H2 |
| Main Stage Curtain Open | 59 | 29 | TB2 9-10 H2 |
| Main Stage Curtain Close | 60 | 30 | TB2 11-12 H2 |
| 1-Stage Curtain Open | 61 | 25 | TB2 1-2 H2 |
| 1-Stage Curtain Close | 62 | 26 | TB2 3-4 H2 |
| Turntable Bot Side | 63 | 57 | TB2 1-2 H4 |
| Turntable Live Side | 64 | 58 | TB2 3-4 H4 |
### Floods
| Name | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ------------------------- | ------------------ | ------------- | ------------ |
| CEC Stage Red Overhead | 65 | 120 | TB1 15-16 H8 |
| CEC Stage Amber Overhead | 66 | 116 | TB1 7-8 H8 |
| CEC Stage Blue Overhead | 67 | 127 | TB2 13-14 H8 |
| Main Stage Red Overhead | 68 | 118 | TB1 11-12 H8 |
| Main Stage Amber Overhead | 69 | 117 | TB1 9-10 H8 |
| Main Stage Blue Overhead | 70 | 119 | TB1 13-14 H8 |
### Backdrop
| Name | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| -------------- | ------------------ | ------------- | ---------- |
| Red Backdrop | 71 | 114 | TB1 3-4 H8 |
| Amber Backdrop | 72 | 113 | TB1 1-2 H8 |
| Blue Backdrop | 73 | 115 | TB1 5-6 H8 |
### Organ
| Name | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| ----------------- | ------------------ | ------------- | ------------ |
| Organ Face Amber | 74 | 110 | TB2 11-12 H7 |
| Organ Face Blue | 75 | 108 | TB2 7-8 H7 |
| Organ Legs Outer | 76 | 101 | TB1 9-10 H7 |
| Organ Legs Middle | 77 | 106 | TB2 3-4 H7 |
| Organ Legs Inner | 78 | 111 | TB2 13-14 H7 |
### Special
| Name | UST Full Stage Bit | RR Engine Bit | CCS Bit |
| -------------------- | ------------------ | ------------- | ------------ |
| CEC Star/Rope Lights | 79 | 103 | TB1 13-14 H7 |
| CEC Sign | 80 | 105 | TB2 1-2 H7 |
| Jukebox Topper | 81 | 125 | TB2 9-10 H8 |
| Fiber Curtain | 82 | 121 | TB2 1-2 H8 |
| Band Sign | 83 | 126 | TB2 11-12 H8 |
| Kick Drum | 84 | 99 | TB1 5-6 H7 |
| Gobo Light | 85 | 124 | TB2 7-8 H8 |
| Helicopter/Gemini | 86 | 122 | TB2 3-4 H8 |
| Live Flood | 87 | 97 | TB1 1-2 H7 |
| Live Strobe | 88 | 98 | TB1 3-4 H7 |
## Studio C
### Chuck E.
| Movement Name | UST Character Bit | UST Full Stage Bit | RR Engine Bit | DTU Bit | 16M |
| ----------------- | ------------------------ | ------------------ | ------------- | ------- | --- |
| Mouth | 1 | 1 | 21 | 1-21 | Yes |
| Nose | 2 | 2 | 28 | 1-28 | No |
| Eyelids Up | 3 | 3 | 25 | 1-25 | No |
| Eyelids Down | 4 | 4 | 24 | 1-24 | Yes |
| Eyes Left | 5 | 5 | 26 | 1-26 | Yes |
| Eyes Right | 6 | 6 | 27 | 1-27 | Yes |
| Eyebrows Up | 7 | 7 | 29 | 1-29 | No |
| Eyebrows Down | 8 | 8 | 30 | 1-30 | No |
| Ears | 9 | 9 | 31 | 1-31 | No |
| Head Turn Left | 10 | 10 | 18 | 1-18 | Yes |
| Head Turn Right | 11 | 11 | 19 | 1-19 | Yes |
| Head Tilt Left | 12 | 12 | 23 | 1-23 | No |
| Head Tilt Right | 13 | 13 | 22 | 1-22 | No |
| Head Up | 14 | 14 | 20 | 1-20 | Yes |
| Left Arm Out | 15 | 15 | 6 | 1-6 | No |
| Left Arm Swing | 16 | 16 | 7 | 1-7 | Yes |
| Left Arm Forward | 17 | 17 | 11 | 1-11 | No |
| Left Elbow | 18 | 18 | 8 | 1-8 | Yes |
| Left Wrist | 19 | 19 | 9 | 1-9 | No |
| Left Hand Wave | 20 | 20 | 10 | 1-10 | Yes |
| Right Arm Out | 21 | 21 | 1 | 1-1 | No |
| Right Arm Swing | 22 | 22 | 2 | 1-2 | Yes |
| Right Arm Forward | 23 | 23 | 17 | 1-17 | No |
| Right Elbow | 24 | 24 | 3 | 1-3 | Yes |
| Right Wrist | 25 | 25 | 4 | 1-4 | No |
| Right Hand Wave | 26 | 26 | 5 | 1-5 | Yes |
| Body Forward | 27 | 27 | 12 | 1-12 | Yes |
| Body Turn Left | 28 | 28 | 16 | 1-16 | Yes |
| Body Turn Right | 29 | 29 | 15 | 1-15 | Yes |
| Body Tilt Left | 30 | 30 | 13 | 1-13 | No |
| Body Tilt Right | 31 | 31 | 14 | 1-14 | No |
| Foot Tap | 32 | 32 | 32 | 1-32 | No |
### Props
| Name | UST Full Stage Bit | RR Engine Bit | DTU Bit |
| ------------- | ------------------ | ------------- | ------- |
| Bird Mouth | 33 | 33 | 1-33 |
| Bird Wings | 34 | 36 | 1-36 |
| Bird Bow | 35 | 34 | 1-34 |
| Bird Turn | 36 | 35 | 1-35 |
| Phone Swing | 37 | 40 | 1-40 |
| Clock Forward | 38 | 160 | 2-10 |
| Clock Reverse | 39 | 161 | 2-11 |
### Spots
| Name | UST Full Stage Bit | RR Engine Bit | DTU Bit |
| ------------- | ------------------ | ------------- | ------- |
| Chuck E. Spot | 40 | 177 | 2-27 |
| Bird Spot | 41 | 178 | 2-28 |
### Curtains
| Name | UST Full Stage Bit | RR Engine Bit | DTU Bit |
| -------------- | ------------------ | ------------- | ------- |
| Curtains Open | 42 | 44 | 1-44 |
| Curtains Close | 43 | 45 | 1-45 |
### Floods
| Name | UST Full Stage Bit | RR Engine Bit | DTU Bit |
| ------------------------ | ------------------ | ------------- | ------- |
| CEC Red Floods | 44 | 151 | 2-1 |
| CEC Amber Floods | 45 | 154 | 2-4 |
| CEC Green Floods | 46 | 152 | 2-2 |
| CEC Blue Floods | 47 | 153 | 2-3 |
| Blue Screen Red Floods | 48 | 155 | 2-5 |
| Blue Screen Amber Floods | 49 | 157 | 2-7 |
| Blue Screen Green Floods | 50 | 156 | 2-6 |
| Room Pink Floods | 51 | 181 | 2-31 |
| Room Amber Floods | 52 | 180 | 2-30 |
| Room Blue Floods | 53 | 182 | 2-32 |
### Monitor
| Name | UST Full Stage Bit | RR Engine Bit | DTU Bit |
| ------------- | ------------------ | ------------- | ------- |
| Monitor Pink | 54 | 172 | 2-22 |
| Monitor Green | 55 | 174 | 2-24 |
| Monitor Blue | 56 | 173 | 2-23 |
| Monitor Chase | 57 | 171 | 2-21 |
### Desk
| Name | UST Full Stage Bit | RR Engine Bit | DTU Bit |
| ----------- | ------------------ | ------------- | ------- |
| Desk Outer | 58 | 166 | 2-16 |
| Desk Middle | 59 | 165 | 2-15 |
| Desk Inner | 60 | 164 | 2-14 |
### Special
| Name | UST Full Stage Bit | RR Engine Bit | DTU Bit |
| -------------------- | ------------------ | ------------- | ------- |
| Clock Neon | 61 | 159 | 2-9 |
| City Lights | 62 | 163 | 2-13 |
| Phone Handset Lights | 63 | 167 | 2-17 |
| Phone Dial Lights | 64 | 168 | 2-18 |
| Gemini | 65 | 176 | 2-26 |
| On Air Sign | 66 | 169 | 2-19 |
| Applause Sign | 67 | 170 | 2-20 |
| Strobe | 68 | 162 | 2-12 |
| Live Floods | 69 | 179 | 2-29 |

View file

@ -1,17 +1,16 @@
# Future Goals
## PC2Converter
## USTConverter
- .SHW (ProgramBlue) input format
- .3ST/.R12/.C&R (APS) input format
- Biphase (Pianocorder and Cyberstar) from tape input format (unlikely)
- Biphase (Pianocorder and Cyberstar) from tape input format
- Studio C from Floppy Disk input format
- UST Full Stage to Single Character Stripper
## PC2Player
- Make the program.
- burn the damn thing to the ground and start over
## Firmwares
- Send controlling computer information about the number of outputs and which character it is set up for
- ~~Send controlling computer information about the number of outputs and which character it is set up for~~ Done!

View file

@ -0,0 +1,308 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Ports;
using System.Timers;
using Eto.Forms;
using Eto.Drawing;
namespace PC2Player
{
public partial class MainForm : Form
{
SerialPort Port = null;
string[] Signals;
System.Timers.Timer FrameTimer;
long Index = 0;
int FrameSkip = 6;
byte[] AudioData;
Process MPVProcess;
int SkipSeconds = 0;
string ShowtapeName = "";
string ShowtapeStageType = "";
string ShowtapeCharacter = "";
string ShowtapeBits = "";
string ShowtapeFormattedLength = "";
string ControllerCharacter = "";
string ControllerBits = "";
string ControllerHeader = "";
bool ControllerConnected = false;
bool ShowtapeLoaded = false;
bool Playing = false;
DropDown SerialPortDropDown = new DropDown();
Label ShowtapeNameLabel = new Label { Text = "Show Name: Not Loaded" };
Label ShowtapeStageTypeLabel = new Label { Text = "Stage Type: Not Loaded" };
Label ShowtapeCharacterLabel = new Label { Text = "Character: Not Loaded" };
Label ShowtapeBitsLabel = new Label { Text = "Bits: Not Loaded" };
Label ShowtapeLengthLabel = new Label { Text = "Length: Not Loaded" };
Label ControllerCharacterLabel = new Label { Text = "Character: Disconnected" };
Label ControllerBitsLabel = new Label { Text = "Bits: Disconnected" };
Button RefreshPortsButton = new Button { Text = "Refresh Ports", Width = 150 };
Button LoadShowtapeButton = new Button { Text = "Load Showtape", Width = 150 };
Button PlayButton = new Button { Text = "Play" };
Button StopButton = new Button { Text = "Stop" };
public MainForm()
{
Title = "PinkConnection2 Showtape Player";
Size = new Size(500, 450);
Maximizable = false;
Resizable = false;
foreach (string s in SerialPort.GetPortNames())
{
SerialPortDropDown.Items.Add(s);
}
SerialPortDropDown.SelectedValueChanged += (sender, e) => Event_SelectSerialPort();
MPVProcess = new Process();
MPVProcess.StartInfo.FileName = "mpv";
MPVProcess.StartInfo.Arguments = $"--start={SkipSeconds} tmp.wav";
FrameTimer = new System.Timers.Timer((1000d/60d)*FrameSkip);
FrameTimer.Elapsed += Event_FrameTimerTick;
FrameTimer.AutoReset = true;
PlayButton.Enabled = false;
StopButton.Enabled = false;
PlayButton.Command = new Command( (sender, e) => Event_PlayButton() );
StopButton.Command = new Command( (sender, e) => Event_StopButton() );
RefreshPortsButton.Command = new Command( (sender, e) => Event_RefreshPortsButton() );
LoadShowtapeButton.Command = new Command( (sender, e) => Event_LoadShowtapeButton() );
Content = BuildLayout();
}
DynamicLayout BuildLayout()
{
GroupBox showtapeInfoGroupBox = new GroupBox{ Text = "Showtape" };
DynamicLayout showtapeInfoGroupLayout = new DynamicLayout { DefaultSpacing = new Size(5, 5), DefaultPadding = new Padding(5, 5, 5, 5) };
showtapeInfoGroupLayout.AddRow(ShowtapeNameLabel);
showtapeInfoGroupLayout.AddRow(ShowtapeStageTypeLabel);
showtapeInfoGroupLayout.AddRow(ShowtapeCharacterLabel);
showtapeInfoGroupLayout.AddRow(ShowtapeBitsLabel);
showtapeInfoGroupLayout.AddRow(ShowtapeLengthLabel);
showtapeInfoGroupBox.Content = showtapeInfoGroupLayout;
GroupBox controllerInfoGroupBox = new GroupBox{ Text = "Controller" };
DynamicLayout controllerInfoGroupLayout = new DynamicLayout { DefaultSpacing = new Size(5, 5), DefaultPadding = new Padding(5, 5, 5, 5) };
controllerInfoGroupLayout.AddRow(ControllerCharacterLabel);
controllerInfoGroupLayout.AddRow(ControllerBitsLabel);
controllerInfoGroupBox.Content = controllerInfoGroupLayout;
DynamicLayout layout = new DynamicLayout { DefaultSpacing = new Size(10, 10), DefaultPadding = new Padding(5, 5, 5, 5) };
layout.BeginVertical();
layout.BeginHorizontal();
layout.Add(PlayButton, true);
layout.Add(StopButton, true);
layout.EndHorizontal();
layout.EndVertical();
layout.BeginVertical();
layout.BeginHorizontal();
layout.Add(new Label { Text = "Serial Port" });
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(SerialPortDropDown, true);
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(showtapeInfoGroupBox, true);
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(controllerInfoGroupBox, true);
layout.EndHorizontal();
layout.EndVertical();
layout.BeginVertical();
layout.BeginHorizontal();
layout.Add(null, true);
layout.Add(RefreshPortsButton);
layout.Add(LoadShowtapeButton);
layout.EndHorizontal();
layout.EndVertical();
layout.BeginVertical();
layout.Add(null, true);
layout.EndVertical();
return layout;
}
void CheckReady()
{
if (ControllerConnected && ShowtapeLoaded)
{
PlayButton.Enabled = true;
StopButton.Enabled = true;
}
else
{
PlayButton.Enabled = false;
StopButton.Enabled = false;
}
}
void Event_SelectSerialPort()
{
if (Port != null) Port.Close();
Port = new SerialPort((string)SerialPortDropDown.SelectedKey, 9600, Parity.None, 8, StopBits.One);
Port.DataReceived += new SerialDataReceivedEventHandler(Event_PortRecievedData);
ControllerHeader = "";
ControllerCharacterLabel.Text = "Character: Disconnected";
ControllerBitsLabel.Text = "Bits: Disconnected";
ControllerConnected = false;
CheckReady();
Port.Open();
}
void Event_PortRecievedData(object sender, SerialDataReceivedEventArgs e)
{
ControllerHeader += Port.ReadExisting();
if (ControllerHeader.EndsWith(",END"))
{
ControllerBits = ControllerHeader.Split(',')[1];
ControllerCharacter = ControllerHeader.Split(',')[2];
ControllerCharacterLabel.Text = $"Character: {ControllerCharacter}";
ControllerBitsLabel.Text = $"Bits: {ControllerBits}";
ControllerConnected = true;
CheckReady();
}
}
void Event_RefreshPortsButton()
{
foreach (string s in SerialPort.GetPortNames())
{
SerialPortDropDown.Items.Add(s);
}
}
void Event_LoadShowtapeButton()
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Filters.Add(new FileFilter("UST Files (.ust)", new string[]{ ".ust" }));
fileDialog.Title = "Select Show File.";
fileDialog.ShowDialog(this);
string tempUSTData = File.ReadAllText(fileDialog.FileName);
if (!tempUSTData.StartsWith("UST,1,"))
{
MessageBox.Show("This is not a UST Version 1 showtape.");
return;
}
string[] headerData = tempUSTData.Split(';')[0].Split(',');
string[] stringyBits = tempUSTData.Split(';')[1].Split(',');
AudioData = Convert.FromBase64String(tempUSTData.Split(';')[2]);
ShowtapeName = headerData[2];
ShowtapeBits = headerData[3];
ShowtapeStageType = headerData[4];
ShowtapeCharacter = headerData[5];
if (headerData[3] == "256")
{
MessageBox.Show("Can't load a full stage showtape right now!");
return;
}
TimeSpan time = TimeSpan.FromSeconds(stringyBits.Length/60);
ShowtapeFormattedLength = time.ToString(@"hh\:mm\:ss");
ShowtapeNameLabel.Text = $"Show Name: {ShowtapeName}";
ShowtapeStageTypeLabel.Text = $"Stage Type: {ShowtapeStageType}";
ShowtapeCharacterLabel.Text = $"Character: {ShowtapeCharacter}";
ShowtapeBitsLabel.Text = $"Bits: {ShowtapeBits}";
ShowtapeLengthLabel.Text = $"Length: {ShowtapeFormattedLength}";
List<string> tmpOut = new List<string>();
foreach (string frame in stringyBits)
{
int b = int.Parse(frame, NumberStyles.HexNumber);
char[] bytesOut = new char[8];
int bytes = int.Parse(ShowtapeBits)/4;
for (int i = 0; i < bytes; i++)
{
int offset = 4 * i;
int mask = 0b1111 << offset;
int masked_value = (b & mask) >> offset;
bytesOut[i] = (char)(64 | masked_value);
}
tmpOut.Add(new string(bytesOut));
}
Signals = tmpOut.ToArray();
ShowtapeLoaded = true;
CheckReady();
}
void Event_PlayButton()
{
if (Playing) return;
if (ShowtapeBits != ControllerBits)
{
MessageBox.Show("This showtape does not have the correct amount of bits for your controller.");
return;
}
File.WriteAllBytes("tmp.wav", AudioData);
Index = SkipSeconds*60;
MPVProcess.StartInfo.Arguments = $"--start={SkipSeconds} tmp.wav";
MPVProcess.Start();
FrameTimer.Start();
Playing = true;
PlayButton.Enabled = false;
RefreshPortsButton.Enabled = false;
LoadShowtapeButton.Enabled = false;
SerialPortDropDown.Enabled = false;
}
void Event_StopButton()
{
FrameTimer.Stop();
MPVProcess.Kill();
File.Delete("tmp.wav");
Playing = false;
PlayButton.Enabled = true;
RefreshPortsButton.Enabled = true;
LoadShowtapeButton.Enabled = true;
SerialPortDropDown.Enabled = true;
Index = 0;
}
void Event_FrameTimerTick(Object sender, ElapsedEventArgs e)
{
if (Index >= Signals.Length)
{
Event_StopButton();
return;
}
Port.Write(Signals[Index]);
Index += FrameSkip;
}
}
}

View file

@ -6,6 +6,7 @@
<ItemGroup>
<PackageReference Include="Eto.Forms" Version="2.9.0" />
<PackageReference Include="System.IO.Ports" Version="9.0.4" />
</ItemGroup>
</Project>
</Project>

View file

@ -11,7 +11,7 @@ namespace PinkConnection2_TestApp
SerialPort port = null;
byte b = 0;
TextBox CommandTextBox = new TextBox { MaxLength = 2 };
TextBox CommandTextBox = new TextBox { MaxLength = 8 };
DropDown SerialPortDropDown = new DropDown();
public MainForm()
@ -92,9 +92,9 @@ namespace PinkConnection2_TestApp
void sendRawSafe()
{
if (CommandTextBox.Text.Length != 2)
if (CommandTextBox.Text.Length != 8)
{
MessageBox.Show("Command length must not be less than 2");
MessageBox.Show("Command length must not be less than 8");
return;
}
if (port == null)

View file

@ -1,448 +0,0 @@
using System;
using System.Collections;
using System.IO;
using Eto.Forms;
using Eto.Drawing;
namespace PC2Converter
{
public partial class MainForm : Form
{
DropDown InputTypeSelector = new DropDown();
DropDown OutputTypeSelector = new DropDown();
DropDown CharacterSelector = new DropDown();
TextBox FilePathTextBox = new TextBox();
Button BrowseFileButton = new Button { Text = "Browse", Width = 100 };
Button ConvertButton = new Button { Text = "Convert", Width = 100 };
string[] InputTypes = { "RSHW File (RR Engine)", "CSHW File (RR Engine)", "SSHW File (RR Engine)" };
string[] RSHWOutputTypes = { "UST 32 Bits (Single Bot RAE/3st)", "UST 8 Bits (Single Bot Cybers Rosetta)", "UST 256 Bits (Full RAE/3st)" , "UST 256 Bits (Full Cybers Rosetta)" };
string[] CSHWOutputTypes = { "UST 8 Bits (Single Bot Cybers)", "UST 256 Bits (Full Cybers)" };
string[] SSHWOutputTypes = { "UST 32 Bits (Single Bot Studio C)", "UST 256 Bits (Full Studio C)" };
string[] RAE3stCharacters = { "Rolfe/Chuck E.", "Mitzi/Helen", "Fatz/Munch", "Beach Bear/Jasper", "Dook/Pasqually", "Billy Bob", "Looney Bird/PizzaCam"};
string[] CyberCharacters = { "Chuck E.", "Helen/Guest Star", "Munch", "Jasper", "Pasqually" };
string[] StudioCCharacters = { "Chuck E." };
int[][] SC_CyberBitMapR12 =
{
/* chuck */ new int[]{ 1, 2, 3, 4, 8, 5, 6, 7 },
/* helen */ new int[]{ 65, 66, 67, 68, 72, 69, 70, 71 },
/* munch */ new int[]{ 49, 50, 51, 56, 53, 54, 55, 52 },
/* jasper */ new int[]{ 17, 18, 19, 20, 24, 21, 22, 23 },
/* pasqually */ new int[]{ 33, 34, 35, 40, 37, 38, 39, 36 }
};
int[][] SC_CyberBitMapRosetta =
{
/* chuck */ new int[]{ 1, 6, 7, 8, 4, 5, 2, 19 },
/* helen */ new int[]{ 185, 178, 179, 180, 183, 184, 181, 169 },
/* munch */ new int[]{ 45, 54, 55, 43, 44, 41, 58, 59 },
/* jasper */ new int[]{ 166, 156, 157, 158, 156, 157, 151, 163 },
/* pasqually */ new int[]{ 30, 25, 21, 28, 29, 26, 31, 35 }
};
int[] CyberRosettaInvertedBits = { 2, 8, 181, 169, 41, 59, 58, 151, 158, 26, 35, 31 };
int[][] SC_RAE3stBitMap =
{
/* rolfe/chuck */ new int[]{ 1, 9, 10, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 17, 18, 19, 14, 15, 16, 20, 36, 37 },
/* mitzi/helen */ new int[]{ 185, 176, 177, 181, 182, 183, 184, 178, 179, 180, 173, 175, 174, 168, 170, 169, 186, 187, 188 },
/* fatz/munch */ new int[]{ 45, 41, 42, 43, 44, 54, 55, 51, 52, 53, 57, 59, 58, 60, 61, 62 },
/* beach bear/jasper */ new int[]{ 166, 151, 152, 153, 156, 157, 158, 161, 162, 163, 164, 154, 155, 159, 160, 165 },
/* dook/pasqually */ new int[]{ 30, 23, 24, 26, 27, 28, 29, 25, 21, 22, 33, 35, 34, 31, 32, 63, 64 },
/* billy bob */ new int[]{ 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 189, 190, 194, 211, 212, 213 },
/* looney/pizzacam */ new int[]{ 167, 191, 192, 193, 171, 172, 48 }
};
int[][] SC_StudioCBitMap =
{
/* chuck e. */ new int[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }
};
bool FullStage = false;
const int USTVersion = 1;
public MainForm()
{
Title = "PinkConnection2 Showtape Converter";
Size = new Size(512, 384);
Maximizable = false;
Resizable = false;
BrowseFileButton.Command = new Command((sender, e) => { Event_BrowseFileButton(); });
ConvertButton.Command = new Command((sender, e) => { Event_ConvertFileButton(); });
InputTypeSelector.SelectedValueChanged += (sender, e) => Event_ChangeInputType();
OutputTypeSelector.SelectedValueChanged += (sender, e) => Event_ChangeOutputType();
foreach (string s in InputTypes)
{
InputTypeSelector.Items.Add(s);
}
Content = BuildLayout();
}
DynamicLayout BuildLayout()
{
DynamicLayout layout = new DynamicLayout { DefaultSpacing = new Size(10, 10), DefaultPadding = new Padding(5, 5, 5, 5) };
layout.BeginVertical();
layout.BeginHorizontal();
layout.Add(new Label { Text = "Input Format" });
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(InputTypeSelector, true);
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(new Label { Text = "Output Type" });
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(OutputTypeSelector, true);
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(new Label { Text = "Character" });
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(CharacterSelector, true);
layout.EndHorizontal();
layout.EndVertical();
layout.BeginVertical();
layout.BeginHorizontal();
layout.Add(new Label { Text = "File to convert" });
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(FilePathTextBox, true);
layout.Add(BrowseFileButton);
layout.EndHorizontal();
layout.EndVertical();
layout.BeginVertical();
layout.BeginHorizontal();
layout.Add(null, true);
layout.Add(ConvertButton);
layout.EndHorizontal();
layout.EndVertical();
layout.BeginVertical();
layout.Add(null, true);
layout.EndVertical();
return layout;
}
string MakeHeader(string showName, string outputType, string character)
{
string headerOut = $"UST,{USTVersion.ToString()},{showName.Replace(",", "_").Replace(";", "_")},";
bool fullStage = false;
switch (outputType)
{
case "UST 32 Bits (Single Bot RAE/3st)":
headerOut += "32,";
headerOut += "Rockafire Explosion/3-Stage (Single Character),";
break;
case "UST 8 Bits (Single Bot Cybers Rosetta)":
headerOut += "8,";
headerOut += "Cyberamics (Single Character),";
break;
case "UST 256 Bits (Full RAE/3st)":
headerOut += "256,";
headerOut += "Rockafire Explosion/3-Stage (Full Stage),";
fullStage = true;
break;
case "UST 256 Bits (Full Cybers Rosetta)":
headerOut += "256,";
headerOut += "Cyberamics (Full Stage),";
fullStage = true;
break;
case "UST 8 Bits (Single Bot Cybers)":
headerOut += "8,";
headerOut += "Cyberamics (Single Character),";
break;
case "UST 256 Bits (Full Cybers)":
headerOut += "256,";
headerOut += "Cyberamics (Full Stage),";
fullStage = true;
break;
case "UST 32 Bits (Single Bot Studio C)":
headerOut += "32,";
headerOut += "Studio C (Single Character),";
break;
case "UST 256 Bits (Full Studio C)":
headerOut += "256,";
headerOut += "Studio C (Full Stage),";
fullStage = true;
break;
}
if (fullStage) headerOut += "N/A,";
else headerOut += character + ";";
return headerOut;
}
void Event_ChangeInputType()
{
switch(InputTypeSelector.SelectedIndex)
{
case 0:
OutputTypeSelector.Items.Clear();
CharacterSelector.Items.Clear();
foreach (string s in RSHWOutputTypes)
{
OutputTypeSelector.Items.Add(s);
}
break;
case 1:
OutputTypeSelector.Items.Clear();
CharacterSelector.Items.Clear();
foreach (string s in CSHWOutputTypes)
{
OutputTypeSelector.Items.Add(s);
}
break;
case 2:
OutputTypeSelector.Items.Clear();
CharacterSelector.Items.Clear();
foreach (string s in SSHWOutputTypes)
{
OutputTypeSelector.Items.Add(s);
}
break;
}
}
void Event_ChangeOutputType()
{
switch(InputTypeSelector.SelectedIndex)
{
case 0:
switch(OutputTypeSelector.SelectedIndex)
{
case 0:
CharacterSelector.Items.Clear();
foreach (string s in RAE3stCharacters)
{
CharacterSelector.Items.Add(s);
}
CharacterSelector.Enabled = true;
FullStage = false;
break;
case 1:
CharacterSelector.Items.Clear();
foreach (string s in CyberCharacters)
{
CharacterSelector.Items.Add(s);
}
CharacterSelector.Enabled = true;
FullStage = false;
break;
case 2:
CharacterSelector.Items.Clear();
CharacterSelector.Enabled = false;
FullStage = true;
break;
case 3:
CharacterSelector.Items.Clear();
CharacterSelector.Enabled = false;
FullStage = true;
break;
}
break;
case 1:
switch(OutputTypeSelector.SelectedIndex)
{
case 0:
CharacterSelector.Items.Clear();
foreach (string s in CyberCharacters)
{
CharacterSelector.Items.Add(s);
}
CharacterSelector.Enabled = true;
FullStage = false;
break;
case 1:
CharacterSelector.Items.Clear();
CharacterSelector.Enabled = false;
FullStage = true;
break;
}
break;
case 2:
switch(OutputTypeSelector.SelectedIndex)
{
case 0:
CharacterSelector.Items.Clear();
foreach (string s in StudioCCharacters)
{
CharacterSelector.Items.Add(s);
}
CharacterSelector.Enabled = true;
FullStage = false;
break;
case 1:
CharacterSelector.Items.Clear();
CharacterSelector.Enabled = false;
FullStage = true;
break;
}
break;
}
}
void Event_BrowseFileButton()
{
OpenFileDialog fileDialog = new OpenFileDialog();
string[] showFiles = { ".rshw", ".cshw", ".sshw" };
string[] allFiles = { ".*" };
fileDialog.Filters.Add(new FileFilter("Show Files (.rshw, .cshw, .sshw)", showFiles));
fileDialog.Filters.Add(new FileFilter("All Files", allFiles));
fileDialog.Title = "Select Show File.";
fileDialog.ShowDialog(this);
if (File.Exists(fileDialog.FileName)) FilePathTextBox.Text = fileDialog.FileName;
}
void Event_ConvertFileButton()
{
// safeties
if (InputTypeSelector.SelectedIndex == -1)
{
MessageBox.Show("Fatal: You must select an input type.");
return;
}
if (OutputTypeSelector.SelectedIndex == -1)
{
MessageBox.Show("Fatal: You must select an output type.");
return;
}
if (CharacterSelector.SelectedIndex == -1 && !FullStage)
{
MessageBox.Show("Fatal: You must select a character.");
return;
}
if (FilePathTextBox.Text.Trim() == "")
{
MessageBox.Show("Fatal: You must select an input file.");
return;
}
if (!File.Exists(FilePathTextBox.Text.Trim()))
{
MessageBox.Show("Fatal: Specified input file does not exist.");
return;
}
if (FullStage)
{
MessageBox.Show("Fatal: Full Stage mode is not supported at this time.");
return;
}
SaveFileDialog fileDialog = new SaveFileDialog();
fileDialog.Filters.Add(new FileFilter("UST Files (.ust)", new string[]{".ust"}));
fileDialog.Title = "Select Show File.";
fileDialog.ShowDialog(this);
if (fileDialog.FileName.Trim() == "") return;
string outFilePath = fileDialog.FileName;
// now its actually time to start doing some shit
string inputType = InputTypeSelector.SelectedKey;
string outputType = OutputTypeSelector.SelectedKey;
string filePath = FilePathTextBox.Text.Trim();
if (inputType == "RSHW File (RR Engine)" || inputType == "CSHW File (RR Engine)" || inputType == "SSHW File (RR Engine)")
{
// at some point there should be a warning displayed if the input type does not match the file extension but i dont feel like doing that right now
// rshw time
RSHWFile file = RSHWLoader.Load(filePath);
if (file.signalData == null)
{
MessageBox.Show("Fatal: This file contains no signal data.");
return;
}
if (file.audioData == null)
{
MessageBox.Show("Fatal: This file contains no audio data.");
return;
}
List<BitArray> rshwBits = new List<BitArray>();
int countlength = 0;
if (file.signalData[0] != 0)
{
countlength = 1;
BitArray bit = new BitArray(300);
rshwBits.Add(bit);
}
for (int i = 0; i < file.signalData.Length; i++)
{
if (file.signalData[i] == 0)
{
countlength += 1;
BitArray bit = new BitArray(300);
rshwBits.Add(bit);
}
else
{
rshwBits[countlength - 1].Set(file.signalData[i], true);
}
}
// pick which target bits to use and how many bytes the output should be
int bitsCount = 0;
int[] targetBits = { 0 };
switch (outputType)
{
case "UST 32 Bits (Single Bot RAE/3st)":
bitsCount = 32;
targetBits = SC_RAE3stBitMap[Array.IndexOf(RAE3stCharacters, CharacterSelector.SelectedKey)];
break;
case "UST 8 Bits (Single Bot Cybers Rosetta)":
bitsCount = 8;
targetBits = SC_CyberBitMapRosetta[Array.IndexOf(CyberCharacters, CharacterSelector.SelectedKey)];
break;
case "UST 256 Bits (Full RAE/3st)":
bitsCount = 256;
break;
case "UST 256 Bits (Full Cybers Rosetta)":
bitsCount = 256;
break;
case "UST 8 Bits (Single Bot Cybers)":
bitsCount = 8;
targetBits = SC_CyberBitMapR12[Array.IndexOf(CyberCharacters, CharacterSelector.SelectedKey)];
break;
case "UST 256 Bits (Full Cybers)":
bitsCount = 256;
break;
case "UST 32 Bits (Single Bot Studio C)":
bitsCount = 32;
targetBits = SC_StudioCBitMap[Array.IndexOf(StudioCCharacters, CharacterSelector.SelectedKey)];
break;
case "UST 256 Bits (Full Studio C)":
bitsCount = 256;
break;
}
List<string> writeOut = new List<string>();
foreach (BitArray bits in rshwBits)
{
int frameByte = 0;
for (int i = 0; i < targetBits.Length; i++)
{
if (bits.Get(targetBits[i])) frameByte += 1 << i;
}
writeOut.Add(frameByte.ToString($"X{(bitsCount/4).ToString()}"));
}
File.WriteAllText(outFilePath, MakeHeader(Path.GetFileNameWithoutExtension(outFilePath), outputType, CharacterSelector.SelectedKey)+String.Join(",", writeOut.ToArray())+";"+Convert.ToBase64String(file.audioData));
}
MessageBox.Show("Conversion complete!");
}
}
}

View file

@ -1,57 +0,0 @@
using System;
using Eto.Forms;
using Eto.Drawing;
namespace PC2Player
{
public partial class MainForm : Form
{
public MainForm()
{
Title = "My Eto Form";
MinimumSize = new Size(200, 200);
Content = new StackLayout
{
Padding = 10,
Items =
{
"Hello World!",
// add more controls here
}
};
// create a few commands that can be used for the menu and toolbar
var clickMe = new Command { MenuText = "Click Me!", ToolBarText = "Click Me!" };
clickMe.Executed += (sender, e) => MessageBox.Show(this, "I was clicked!");
var quitCommand = new Command { MenuText = "Quit", Shortcut = Application.Instance.CommonModifier | Keys.Q };
quitCommand.Executed += (sender, e) => Application.Instance.Quit();
var aboutCommand = new Command { MenuText = "About..." };
aboutCommand.Executed += (sender, e) => new AboutDialog().ShowDialog(this);
// create menu
Menu = new MenuBar
{
Items =
{
// File submenu
new SubMenuItem { Text = "&File", Items = { clickMe } },
// new SubMenuItem { Text = "&Edit", Items = { /* commands/items */ } },
// new SubMenuItem { Text = "&View", Items = { /* commands/items */ } },
},
ApplicationItems =
{
// application (OS X) or file menu (others)
new ButtonMenuItem { Text = "&Preferences..." },
},
QuitItem = quitCommand,
AboutItem = aboutCommand
};
// create toolbar
ToolBar = new ToolBar { Items = { clickMe } };
}
}
}

View file

@ -1,7 +1,7 @@
using System;
using Eto.Forms;
namespace PC2Converter.Gtk
namespace USTConverter.Gtk
{
class Program
{

View file

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PC2Converter\PC2Converter.csproj" />
<ProjectReference Include="..\USTConverter\USTConverter.csproj" />
</ItemGroup>
<ItemGroup>

View file

@ -3,11 +3,11 @@
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>PC2Converter</string>
<string>USTConverter</string>
<key>CFBundleIdentifier</key>
<string>com.example.PC2Converter</string>
<string>me.kawaiizenbo.USTConverter</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>1.3</string>
<key>LSMinimumSystemVersion</key>
<string>10.15</string>
<key>CFBundleDevelopmentRegion</key>

View file

@ -1,7 +1,7 @@
using System;
using Eto.Forms;
namespace PC2Converter.Mac
namespace USTConverter.Mac
{
class Program
{

View file

@ -8,7 +8,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PC2Converter\PC2Converter.csproj" />
<ProjectReference Include="..\USTConverter\USTConverter.csproj" />
</ItemGroup>
<ItemGroup>

View file

@ -1,7 +1,7 @@
using System;
using Eto.Forms;
namespace PC2Converter.Wpf
namespace USTConverter.Wpf
{
class Program
{

View file

@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PC2Converter\PC2Converter.csproj" />
<ProjectReference Include="..\USTConverter\USTConverter.csproj" />
</ItemGroup>
<ItemGroup>

View file

@ -0,0 +1,360 @@
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Numerics;
using Eto.Forms;
using Eto.Drawing;
namespace USTConverter
{
public partial class MainForm : Form
{
DropDown InputTypeSelector = new DropDown();
DropDown OutputTypeSelector = new DropDown();
TextBox FilePathTextBox = new TextBox();
Button BrowseFileButton = new Button { Text = "Browse", Width = 100 };
Button ConvertButton = new Button { Text = "Convert", Width = 100 };
CheckBox CompressAudioCheckBox = new CheckBox { Text = "Compress Audio" };
string[] InputTypes = {
"RSHW File (RR Engine)", "CSHW File (RR Engine)", "SSHW File (RR Engine)"/*,
"3ST File (APS)", "ROA/R12/C&R File (APS)"*/
};
string[] RAE3stOutputTypes = { "UST (Rock-afire Explosion/3-Stage)" , "UST (Cyberamics Rosetta)" };
string[] CyberOutputTypes = { "UST (Cyberamics)" };
string[] StudioCOutputTypes = { "UST (Studio C)" };
int[] CyberBitMap = {
1, 2, 3, 4, 8, 5, 6, 7,
65, 66, 67, 68, 72, 69, 70, 71,
49, 50, 51, 56, 53, 54, 55, 52,
17, 18, 19, 20, 24, 21, 22, 23,
33, 34, 35, 40, 37, 38, 39, 36,
9, 46, 62, 10, 74, 75, 76, 77, 78,
104, 102, 109, 107, 100, 123, 41,
27, 28, 29, 30, 25, 26, 57, 58,
120, 116, 127, 118, 117, 119,
114, 113, 115,
110, 108, 101, 106, 111,
103, 105, 125, 121, 126, 99, 124, 122, 97, 98
};
int[] CyberBitMapRosetta = {
1, 6, 7, 8, 4, 5, 2, 19,
185, 178, 179, 180, 183, 184, 181, 169,
45, 54, 55, 43, 44, 41, 58, 59,
166, 156, 157, 158, 156, 157, 151, 163,
30, 25, 21, 28, 29, 26, 31, 35,
0, 0, 0, 49, 0, 0, 0, 0, 0,
88, 86, 85, 82, 84, 81, 0,
93, 94, 91, 92, 91, 92, 0, 0,
229, 228, 226, 224, 223, 221,
235, 232, 234,
67, 68, 71, 72, 73,
220, 244, 245, 225, 77, 241, 240, 87, 222, 0
};
int[] RAE3stBitMap = {
1, 9, 10, 2, 3, 4, 5, 6, 7, 8, 11, 12, 13, 17, 18, 19, 14, 15, 16, 20, 36, 37,
185, 176, 177, 181, 182, 183, 184, 178, 179, 180, 173, 175, 174, 168, 170, 169, 186, 187, 188,
45, 41, 42, 43, 44, 54, 55, 51, 52, 53, 57, 59, 58, 60, 61, 62,
166, 151, 152, 153, 156, 157, 158, 161, 162, 163, 164, 154, 155, 159, 160, 165,
30, 23, 24, 26, 27, 28, 29, 25, 21, 22, 33, 35, 34, 31, 32, 63, 64,
196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 189, 190, 194, 211, 212, 213,
167, 191, 192, 193, 171, 172, 48,
39, 38, 47, 46, 49, 50,
88, 86, 85, 82, 242, 84, 83, 81, 238, 239, 240, 87,
93, 94, 91, 92, 89, 90,
229, 228, 227, 226, 224, 223, 221, 219, 218, 217, 216, 222,
235, 232, 231, 234, 236, 237, 233, 242, 243,
67, 68, 69, 66, 71, 72, 73,
78, 77, 76, 79, 80,
220, 244, 245, 225, 230, 241
};
int[] StudioCBitMap = {
21, 28, 25, 24, 26, 27, 29, 30, 31, 18, 19, 23, 22, 20, 6, 7, 11, 8, 9, 10, 1, 2, 17, 3, 4, 5, 12, 16, 15, 13, 14, 32,
33, 36, 34, 35, 40, 160, 161,
177, 178,
44, 45,
151, 154, 152, 153, 155, 157, 156, 181, 180, 182,
172, 174, 173, 171,
166, 165, 164,
159, 163, 167, 168, 176, 169, 170, 162, 179
};
int[] CyberRosettaInvertedBits = { 2, 181, 41, 59, 58, 151, 163, 26, 35, 31 };
int[] RAE3stAPSDescrambleTable = { 10, 11, 0, 1, 2, 3, 4, 12, 13, 5, 6, 7, 8, 9, 14, 15};
bool Rosetta = false;
const int USTVersion = 2;
public MainForm()
{
Title = "UST Showtape Converter";
Size = new Size(500, 300);
Maximizable = false;
Resizable = false;
BrowseFileButton.Command = new Command((sender, e) => { Event_BrowseFileButton(); });
ConvertButton.Command = new Command((sender, e) => { Event_ConvertFileButton(); });
InputTypeSelector.SelectedValueChanged += (sender, e) => Event_ChangeInputType();
foreach (string s in InputTypes)
{
InputTypeSelector.Items.Add(s);
}
Content = BuildLayout();
}
DynamicLayout BuildLayout()
{
DynamicLayout layout = new DynamicLayout { DefaultSpacing = new Size(10, 10), DefaultPadding = new Padding(5, 5, 5, 5) };
layout.BeginVertical();
layout.BeginHorizontal();
layout.Add(new Label { Text = "Input Format" });
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(InputTypeSelector, true);
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(new Label { Text = "Output Type" });
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(OutputTypeSelector, true);
layout.EndHorizontal();
layout.EndVertical();
layout.BeginVertical();
layout.BeginHorizontal();
layout.Add(new Label { Text = "File to convert" });
layout.EndHorizontal();
layout.BeginHorizontal();
layout.Add(FilePathTextBox, true);
layout.Add(BrowseFileButton);
layout.EndHorizontal();
layout.EndVertical();
layout.BeginVertical();
layout.BeginHorizontal();
layout.Add(null, true);
layout.Add(CompressAudioCheckBox);
layout.Add(ConvertButton);
layout.EndHorizontal();
layout.EndVertical();
layout.BeginVertical();
layout.Add(null, true);
layout.EndVertical();
return layout;
}
string MakeHeader(string showName, string outputType)
{
string headerOut = $"UST,{USTVersion.ToString()},{showName.Replace(",", "_").Replace(";", "_")},";
switch (outputType)
{
case "UST (Rock-afire Explosion/3-Stage)":
headerOut += "Rockafire Explosion/3-Stage;";
break;
case "UST (Cyberamics Rosetta)":
headerOut += "Cyberamics;";
break;
case "UST (Cyberamics)":
headerOut += "Cyberamics;";
break;
case "UST (Studio C)":
headerOut += "Studio C;";
break;
}
return headerOut;
}
void Event_ChangeInputType()
{
switch(InputTypeSelector.SelectedIndex)
{
case 0:
OutputTypeSelector.Items.Clear();
foreach (string s in RAE3stOutputTypes)
{
OutputTypeSelector.Items.Add(s);
}
break;
case 1:
OutputTypeSelector.Items.Clear();
foreach (string s in CyberOutputTypes)
{
OutputTypeSelector.Items.Add(s);
}
break;
case 2:
OutputTypeSelector.Items.Clear();
foreach (string s in StudioCOutputTypes)
{
OutputTypeSelector.Items.Add(s);
}
break;
}
}
void Event_BrowseFileButton()
{
OpenFileDialog fileDialog = new OpenFileDialog();
string[] showFiles = { ".rshw", ".cshw", ".sshw" };
string[] allFiles = { ".*" };
fileDialog.Filters.Add(new FileFilter("Show Files (.rshw, .cshw, .sshw)", showFiles));
fileDialog.Filters.Add(new FileFilter("All Files", allFiles));
fileDialog.Title = "Select Show File.";
fileDialog.ShowDialog(this);
if (File.Exists(fileDialog.FileName)) FilePathTextBox.Text = fileDialog.FileName;
}
void Event_ConvertFileButton()
{
// safeties
if (InputTypeSelector.SelectedIndex == -1)
{
MessageBox.Show("Fatal: You must select an input type.");
return;
}
if (OutputTypeSelector.SelectedIndex == -1)
{
MessageBox.Show("Fatal: You must select an output type.");
return;
}
if (FilePathTextBox.Text.Trim() == "")
{
MessageBox.Show("Fatal: You must select an input file.");
return;
}
if (!File.Exists(FilePathTextBox.Text.Trim()))
{
MessageBox.Show("Fatal: Specified input file does not exist.");
return;
}
SaveFileDialog fileDialog = new SaveFileDialog();
fileDialog.Filters.Add(new FileFilter("UST Files (.ust)", new string[]{".ust"}));
fileDialog.Title = "Select Output File.";
fileDialog.ShowDialog(this);
if (fileDialog.FileName.Trim() == "") return;
string outFilePath = fileDialog.FileName;
// now its actually time to start doing some shit
string inputType = InputTypeSelector.SelectedKey;
string outputType = OutputTypeSelector.SelectedKey;
string filePath = FilePathTextBox.Text.Trim();
if (inputType == "RSHW File (RR Engine)" || inputType == "CSHW File (RR Engine)" || inputType == "SSHW File (RR Engine)")
{
// at some point there should be a warning displayed if the input type does not match the file extension but i dont feel like doing that right now
// rshw time
RSHWFile file = RSHWLoader.Load(filePath);
if (file.signalData == null)
{
MessageBox.Show("Fatal: This file contains no signal data.");
return;
}
if (file.audioData == null)
{
MessageBox.Show("Fatal: This file contains no audio data.");
return;
}
List<BitArray> rshwBits = new List<BitArray>();
int countlength = 0;
if (file.signalData[0] != 0)
{
countlength = 1;
BitArray bit = new BitArray(300);
rshwBits.Add(bit);
}
for (int i = 0; i < file.signalData.Length; i++)
{
if (file.signalData[i] == 0)
{
countlength += 1;
BitArray bit = new BitArray(300);
rshwBits.Add(bit);
}
else
{
rshwBits[countlength - 1].Set(file.signalData[i], true);
}
}
// pick which target bits to use and how many bytes the output should be
int[] targetBits = { 0 };
switch (outputType)
{
case "UST (Rock-afire Explosion/3-Stage)":
targetBits = RAE3stBitMap;
break;
case "UST (Cyberamics Rosetta)":
targetBits = CyberBitMapRosetta;
Rosetta = true;
break;
case "UST (Cyberamics)":
targetBits = CyberBitMap;
break;
case "UST (Studio C)":
targetBits = StudioCBitMap;
break;
}
List<string> writeOut = new List<string>();
foreach (BitArray bits in rshwBits)
{
BigInteger frameByte = 0;
for (int i = 0; i < targetBits.Length; i++)
{
if (Rosetta && CyberRosettaInvertedBits.Contains(targetBits[i]))
{
if (!bits.Get(targetBits[i])) frameByte += BigInteger.Pow(2, i);
}
else { if (bits.Get(targetBits[i])) frameByte += BigInteger.Pow(2, i); }
}
writeOut.Add(frameByte.ToString($"X{(64).ToString()}"));
}
writeOut[0] = (0).ToString($"X{(64).ToString()}");
byte[] audioOut = file.audioData;
if ((bool)CompressAudioCheckBox.Checked)
{
if (File.Exists("tmp.mp3")) File.Delete("tmp.mp3");
File.WriteAllBytes("tmp.wav", audioOut);
Process ffmpegProcess = new Process();
ffmpegProcess.StartInfo.FileName = "ffmpeg";
ffmpegProcess.StartInfo.Arguments = "-i tmp.wav -c:a mp3 -b:a 128k tmp.mp3";
ffmpegProcess.Start();
ffmpegProcess.WaitForExit();
audioOut = File.ReadAllBytes("tmp.mp3");
File.Delete("tmp.wav");
File.Delete("tmp.mp3");
}
File.WriteAllText(outFilePath, MakeHeader(Path.GetFileNameWithoutExtension(outFilePath), outputType)+String.Join(",", writeOut.ToArray())+";"+Convert.ToBase64String(audioOut));
}
MessageBox.Show("Conversion complete!");
}
int RRtoAPSBit(int rrBit) // aps lower drawer starts at 129 instead of 151
{
int outAPSBit = rrBit;
if (rrBit > 150) outAPSBit = rrBit - 22;
return outAPSBit;
}
}
}

View file

@ -1,4 +1,3 @@
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;