diff --git a/.gitignore b/.gitignore
index a320c3c..9f5642d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
*/obj/
*/*/*/bin/
*/*/*/obj/
+*.tmp
diff --git a/Arduino Firmware/Firmware-32Valve-Mega/Firmware-32Valve-Mega.ino b/Arduino Firmware/Firmware-32Valve-Mega/Firmware-32Valve-Mega.ino
index 401c848..684d842 100644
--- a/Arduino Firmware/Firmware-32Valve-Mega/Firmware-32Valve-Mega.ino
+++ b/Arduino Firmware/Firmware-32Valve-Mega/Firmware-32Valve-Mega.ino
@@ -13,7 +13,6 @@ void setup()
{
for (int i = 22; i <= 53; i++) pinMode(i, OUTPUT);
Serial.begin(9600);
- Serial.write("PC2,32,Universal,END");
}
void loop()
@@ -22,12 +21,21 @@ void loop()
{
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 & 32) && (byte2 & 32))
+ {
+ if (byte1 & 1) Serial.write("PC3,32\n");
+ }
+ 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))
{
diff --git a/Arduino Firmware/Firmware-8Valve/Firmware-8Valve.ino b/Arduino Firmware/Firmware-8Valve/Firmware-8Valve.ino
index 9c4fd69..6054452 100644
--- a/Arduino Firmware/Firmware-8Valve/Firmware-8Valve.ino
+++ b/Arduino Firmware/Firmware-8Valve/Firmware-8Valve.ino
@@ -14,7 +14,6 @@ void setup()
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
Serial.begin(9600);
- Serial.write("PC2,8,Universal,END");
}
void loop()
@@ -24,6 +23,11 @@ void loop()
byte1 = 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 & 1) digitalWrite(2, 1);
diff --git a/Arduino Firmware/Servo/Firmware-Servo-ChuckEHelenGuestStar/Firmware-Servo-ChuckEHelenGuestStar.ino b/Arduino Firmware/Servo/Firmware-Servo-ChuckEHelenGuestStar/Firmware-Servo-ChuckEHelenGuestStar.ino
index 17c095e..9b60dda 100644
--- a/Arduino Firmware/Servo/Firmware-Servo-ChuckEHelenGuestStar/Firmware-Servo-ChuckEHelenGuestStar.ino
+++ b/Arduino Firmware/Servo/Firmware-Servo-ChuckEHelenGuestStar/Firmware-Servo-ChuckEHelenGuestStar.ino
@@ -20,7 +20,6 @@ void setup()
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()
@@ -30,6 +29,11 @@ void loop()
byte1 = 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 & 1) servoChannel[mapping[0]].write(onDegrees[0]);
diff --git a/Arduino Firmware/Servo/Firmware-Servo-HelenMitzi/Firmware-Servo-HelenMitzi.ino b/Arduino Firmware/Servo/Firmware-Servo-HelenMitzi/Firmware-Servo-HelenMitzi.ino
index e17e30c..1311e8d 100644
--- a/Arduino Firmware/Servo/Firmware-Servo-HelenMitzi/Firmware-Servo-HelenMitzi.ino
+++ b/Arduino Firmware/Servo/Firmware-Servo-HelenMitzi/Firmware-Servo-HelenMitzi.ino
@@ -29,7 +29,6 @@ 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() {
@@ -37,12 +36,21 @@ void loop() {
{
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 & 32) && (byte2 & 32))
+ {
+ if (byte1 & 1) Serial.write("PC3,8\n");
+ }
+
+ 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))
{
diff --git a/Bit Mappings.md b/Bit Mappings.md
index 724b55f..d1a1a4a 100644
--- a/Bit Mappings.md
+++ b/Bit Mappings.md
@@ -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 |
@@ -185,7 +185,7 @@ Hand movement was removed during Concept Unification.
| Name | UST Full Stage Bit | RR Engine Bit | Greybox Bit | R12 Bit | R12 Inverted |
| --------------------------------- | ------------------ | ------------- | ----------- | ------------ | ------------ |
-| Rolfe/Chuck Spot | 124 | 88 | 1-88 | TB1 15-16 H7 | No |
+| 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 |
@@ -273,11 +273,11 @@ Hand movement was removed during Concept Unification.
| Snare Drum Light | 179 | 230 | 2-80 | | |
| Kick Drum Light | 180 | 241 | 2-91 | TB1 5-6 H7 | No |
-## R12 (Road/1-Stage/2-Stage)
+## 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 |
@@ -290,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 |
@@ -303,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 |
@@ -316,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 |
@@ -329,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 |
@@ -339,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 |
diff --git a/ConsolePlayer/ConsolePlayer.csproj b/ConsolePlayer/ConsolePlayer.csproj
new file mode 100644
index 0000000..c461e59
--- /dev/null
+++ b/ConsolePlayer/ConsolePlayer.csproj
@@ -0,0 +1,15 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/ConsolePlayer/Program.cs b/ConsolePlayer/Program.cs
new file mode 100644
index 0000000..d8c7ba2
--- /dev/null
+++ b/ConsolePlayer/Program.cs
@@ -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 targetBits = new List();
+ 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 tempShowData = new List();
+
+ 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);
+ }
+ }
+}
diff --git a/ConsolePlayer/channel mappings/BeachBearJasper.pcm b/ConsolePlayer/channel mappings/BeachBearJasper.pcm
new file mode 100644
index 0000000..f25db0c
--- /dev/null
+++ b/ConsolePlayer/channel mappings/BeachBearJasper.pcm
@@ -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
diff --git a/ConsolePlayer/channel mappings/BillyBob.pcm b/ConsolePlayer/channel mappings/BillyBob.pcm
new file mode 100644
index 0000000..d2f42d2
--- /dev/null
+++ b/ConsolePlayer/channel mappings/BillyBob.pcm
@@ -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
diff --git a/ConsolePlayer/channel mappings/CyberChuck.pcm b/ConsolePlayer/channel mappings/CyberChuck.pcm
new file mode 100644
index 0000000..7225c89
--- /dev/null
+++ b/ConsolePlayer/channel mappings/CyberChuck.pcm
@@ -0,0 +1 @@
+PC3MAPPING;1,2,3,4,5,6,7,8
diff --git a/ConsolePlayer/channel mappings/CyberHelen.pcm b/ConsolePlayer/channel mappings/CyberHelen.pcm
new file mode 100644
index 0000000..71bd573
--- /dev/null
+++ b/ConsolePlayer/channel mappings/CyberHelen.pcm
@@ -0,0 +1 @@
+PC3MAPPING;9,10,11,12,13,14,15,16
diff --git a/ConsolePlayer/channel mappings/CyberJasper.pcm b/ConsolePlayer/channel mappings/CyberJasper.pcm
new file mode 100644
index 0000000..103181b
--- /dev/null
+++ b/ConsolePlayer/channel mappings/CyberJasper.pcm
@@ -0,0 +1 @@
+PC3MAPPING;25,26,27,28,29,30,31,32
diff --git a/ConsolePlayer/channel mappings/CyberMunch.pcm b/ConsolePlayer/channel mappings/CyberMunch.pcm
new file mode 100644
index 0000000..8338e88
--- /dev/null
+++ b/ConsolePlayer/channel mappings/CyberMunch.pcm
@@ -0,0 +1 @@
+PC3MAPPING;17,18,19,20,21,22,23,24
diff --git a/ConsolePlayer/channel mappings/CyberPasqually.pcm b/ConsolePlayer/channel mappings/CyberPasqually.pcm
new file mode 100644
index 0000000..eac80d9
--- /dev/null
+++ b/ConsolePlayer/channel mappings/CyberPasqually.pcm
@@ -0,0 +1 @@
+PC3MAPPING;33,34,35,36,37,38,39,40
diff --git a/ConsolePlayer/channel mappings/DookPasqually.pcm b/ConsolePlayer/channel mappings/DookPasqually.pcm
new file mode 100644
index 0000000..19b2875
--- /dev/null
+++ b/ConsolePlayer/channel mappings/DookPasqually.pcm
@@ -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
diff --git a/ConsolePlayer/channel mappings/FatzMunch.pcm b/ConsolePlayer/channel mappings/FatzMunch.pcm
new file mode 100644
index 0000000..b9ea160
--- /dev/null
+++ b/ConsolePlayer/channel mappings/FatzMunch.pcm
@@ -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
diff --git a/ConsolePlayer/channel mappings/MitziHelen.pcm b/ConsolePlayer/channel mappings/MitziHelen.pcm
new file mode 100644
index 0000000..40eed4d
--- /dev/null
+++ b/ConsolePlayer/channel mappings/MitziHelen.pcm
@@ -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
diff --git a/ConsolePlayer/channel mappings/RolfeChuck.pcm b/ConsolePlayer/channel mappings/RolfeChuck.pcm
new file mode 100644
index 0000000..72b6811
--- /dev/null
+++ b/ConsolePlayer/channel mappings/RolfeChuck.pcm
@@ -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
diff --git a/Future Goals.md b/Future Goals.md
index 30f46c1..54cdff2 100644
--- a/Future Goals.md
+++ b/Future Goals.md
@@ -1,18 +1,15 @@
# Future Goals
-## PC2Converter
+## USTConverter
- .SHW (ProgramBlue) input format
- .3ST/.R12/.C&R (APS) input format
- 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~~ done!!
- - fix memory leak issue
- - make audio player work on windows
+ - ~~burn the damn thing to the ground and start over~~ Done!
## Firmwares
diff --git a/PC2Player/PC2Player.Gtk/PC2Player.Gtk.csproj b/Legacy Tools/PC2Player.Old/PC2Player.Gtk/PC2Player.Gtk.csproj
similarity index 100%
rename from PC2Player/PC2Player.Gtk/PC2Player.Gtk.csproj
rename to Legacy Tools/PC2Player.Old/PC2Player.Gtk/PC2Player.Gtk.csproj
diff --git a/PC2Player/PC2Player.Gtk/Program.cs b/Legacy Tools/PC2Player.Old/PC2Player.Gtk/Program.cs
similarity index 100%
rename from PC2Player/PC2Player.Gtk/Program.cs
rename to Legacy Tools/PC2Player.Old/PC2Player.Gtk/Program.cs
diff --git a/PC2Converter/PC2Converter.Mac/Icon.icns b/Legacy Tools/PC2Player.Old/PC2Player.Mac/Icon.icns
similarity index 100%
rename from PC2Converter/PC2Converter.Mac/Icon.icns
rename to Legacy Tools/PC2Player.Old/PC2Player.Mac/Icon.icns
diff --git a/PC2Player/PC2Player.Mac/Info.plist b/Legacy Tools/PC2Player.Old/PC2Player.Mac/Info.plist
similarity index 100%
rename from PC2Player/PC2Player.Mac/Info.plist
rename to Legacy Tools/PC2Player.Old/PC2Player.Mac/Info.plist
diff --git a/PC2Player/PC2Player.Mac/PC2Player.Mac.csproj b/Legacy Tools/PC2Player.Old/PC2Player.Mac/PC2Player.Mac.csproj
similarity index 100%
rename from PC2Player/PC2Player.Mac/PC2Player.Mac.csproj
rename to Legacy Tools/PC2Player.Old/PC2Player.Mac/PC2Player.Mac.csproj
diff --git a/PC2Player/PC2Player.Mac/Program.cs b/Legacy Tools/PC2Player.Old/PC2Player.Mac/Program.cs
similarity index 100%
rename from PC2Player/PC2Player.Mac/Program.cs
rename to Legacy Tools/PC2Player.Old/PC2Player.Mac/Program.cs
diff --git a/PC2Player/PC2Player.Wpf/PC2Player.Wpf.csproj b/Legacy Tools/PC2Player.Old/PC2Player.Wpf/PC2Player.Wpf.csproj
similarity index 100%
rename from PC2Player/PC2Player.Wpf/PC2Player.Wpf.csproj
rename to Legacy Tools/PC2Player.Old/PC2Player.Wpf/PC2Player.Wpf.csproj
diff --git a/PC2Player/PC2Player.Wpf/Program.cs b/Legacy Tools/PC2Player.Old/PC2Player.Wpf/Program.cs
similarity index 100%
rename from PC2Player/PC2Player.Wpf/Program.cs
rename to Legacy Tools/PC2Player.Old/PC2Player.Wpf/Program.cs
diff --git a/PC2Player/PC2Player/MainForm.cs b/Legacy Tools/PC2Player.Old/PC2Player/MainForm.cs
similarity index 100%
rename from PC2Player/PC2Player/MainForm.cs
rename to Legacy Tools/PC2Player.Old/PC2Player/MainForm.cs
diff --git a/PC2Player/PC2Player/PC2Player.csproj b/Legacy Tools/PC2Player.Old/PC2Player/PC2Player.csproj
similarity index 100%
rename from PC2Player/PC2Player/PC2Player.csproj
rename to Legacy Tools/PC2Player.Old/PC2Player/PC2Player.csproj
diff --git a/PC2Converter/PC2Converter/MainForm.cs b/PC2Converter/PC2Converter/MainForm.cs
deleted file mode 100644
index af76e5d..0000000
--- a/PC2Converter/PC2Converter/MainForm.cs
+++ /dev/null
@@ -1,499 +0,0 @@
-using System;
-using System.Collections;
-using System.Diagnostics;
-using System.Numerics;
-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 };
- CheckBox CompressAudioCheckBox = new CheckBox { Text = "Compress Audio", Width = 100 };
-
- 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 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[] CyberOutputTypes = { "UST 8 Bits (Single Bot Cybers)", "UST 256 Bits (Full Cybers)" };
- string[] StudioCOutputTypes = { "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[][] 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 }
- };
-
- int[] FS_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[] CyberRosettaInvertedBits = { 2, 8, 181, 169, 41, 59, 58, 151, 158, 26, 35, 31 };
- int[] RAE3stAPSDescrambleTable = { 10, 11, 0, 1, 2, 3, 4, 12, 13, 5, 6, 7, 8, 9, 14, 15};
-
- 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(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 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 += "All,";
- else headerOut += character + ";";
- return headerOut;
- }
-
- void Event_ChangeInputType()
- {
- switch(InputTypeSelector.SelectedIndex)
- {
- case 0:
- OutputTypeSelector.Items.Clear();
- CharacterSelector.Items.Clear();
- foreach (string s in RAE3stOutputTypes)
- {
- OutputTypeSelector.Items.Add(s);
- }
- break;
- case 1:
- OutputTypeSelector.Items.Clear();
- CharacterSelector.Items.Clear();
- foreach (string s in CyberOutputTypes)
- {
- OutputTypeSelector.Items.Add(s);
- }
- break;
- case 2:
- OutputTypeSelector.Items.Clear();
- CharacterSelector.Items.Clear();
- foreach (string s in StudioCOutputTypes)
- {
- 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 && (string)OutputTypeSelector.SelectedKey != "UST 256 Bits (Full RAE/3st)")
- {
- MessageBox.Show("Fatal: Full Stage mode is not supported for cybers and studio c 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 rshwBits = new List();
- 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;
- targetBits = FS_RAE3stBitMap;
- 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 writeOut = new List();
- foreach (BitArray bits in rshwBits)
- {
- BigInteger frameByte = 0;
- for (int i = 0; i < targetBits.Length; i++)
- {
- if (bits.Get(targetBits[i])) frameByte += BigInteger.Pow(2, i);
- }
- writeOut.Add(frameByte.ToString($"X{(bitsCount/4).ToString()}"));
- }
-
- byte[] audioOut = file.audioData;
- if ((bool)CompressAudioCheckBox.Checked)
- {
- MessageBox.Show("press ok to start compressing audio");
- 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, CharacterSelector.SelectedKey)+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;
- }
- }
-}
diff --git a/PC2Converter/PC2Converter.Gtk/Program.cs b/USTConverter/USTConverter.Gtk/Program.cs
similarity index 81%
rename from PC2Converter/PC2Converter.Gtk/Program.cs
rename to USTConverter/USTConverter.Gtk/Program.cs
index 3297df7..1d1b0b0 100644
--- a/PC2Converter/PC2Converter.Gtk/Program.cs
+++ b/USTConverter/USTConverter.Gtk/Program.cs
@@ -1,7 +1,7 @@
using System;
using Eto.Forms;
-namespace PC2Converter.Gtk
+namespace USTConverter.Gtk
{
class Program
{
diff --git a/PC2Converter/PC2Converter.Gtk/PC2Converter.Gtk.csproj b/USTConverter/USTConverter.Gtk/USTConverter.Gtk.csproj
similarity index 83%
rename from PC2Converter/PC2Converter.Gtk/PC2Converter.Gtk.csproj
rename to USTConverter/USTConverter.Gtk/USTConverter.Gtk.csproj
index 7e86dbd..3832d00 100644
--- a/PC2Converter/PC2Converter.Gtk/PC2Converter.Gtk.csproj
+++ b/USTConverter/USTConverter.Gtk/USTConverter.Gtk.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/PC2Player/PC2Player.Mac/Icon.icns b/USTConverter/USTConverter.Mac/Icon.icns
similarity index 100%
rename from PC2Player/PC2Player.Mac/Icon.icns
rename to USTConverter/USTConverter.Mac/Icon.icns
diff --git a/PC2Converter/PC2Converter.Mac/Info.plist b/USTConverter/USTConverter.Mac/Info.plist
similarity index 81%
rename from PC2Converter/PC2Converter.Mac/Info.plist
rename to USTConverter/USTConverter.Mac/Info.plist
index 6157797..667bce4 100644
--- a/PC2Converter/PC2Converter.Mac/Info.plist
+++ b/USTConverter/USTConverter.Mac/Info.plist
@@ -3,11 +3,11 @@
CFBundleName
- PC2Converter
+ USTConverter
CFBundleIdentifier
- com.example.PC2Converter
+ me.kawaiizenbo.USTConverter
CFBundleShortVersionString
- 1.0
+ 1.3
LSMinimumSystemVersion
10.15
CFBundleDevelopmentRegion
diff --git a/PC2Converter/PC2Converter.Mac/Program.cs b/USTConverter/USTConverter.Mac/Program.cs
similarity index 81%
rename from PC2Converter/PC2Converter.Mac/Program.cs
rename to USTConverter/USTConverter.Mac/Program.cs
index 973dc3d..089435e 100644
--- a/PC2Converter/PC2Converter.Mac/Program.cs
+++ b/USTConverter/USTConverter.Mac/Program.cs
@@ -1,7 +1,7 @@
using System;
using Eto.Forms;
-namespace PC2Converter.Mac
+namespace USTConverter.Mac
{
class Program
{
diff --git a/PC2Converter/PC2Converter.Mac/PC2Converter.Mac.csproj b/USTConverter/USTConverter.Mac/USTConverter.Mac.csproj
similarity index 84%
rename from PC2Converter/PC2Converter.Mac/PC2Converter.Mac.csproj
rename to USTConverter/USTConverter.Mac/USTConverter.Mac.csproj
index 437ecec..2f87570 100644
--- a/PC2Converter/PC2Converter.Mac/PC2Converter.Mac.csproj
+++ b/USTConverter/USTConverter.Mac/USTConverter.Mac.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/PC2Converter/PC2Converter.Wpf/Program.cs b/USTConverter/USTConverter.Wpf/Program.cs
similarity index 81%
rename from PC2Converter/PC2Converter.Wpf/Program.cs
rename to USTConverter/USTConverter.Wpf/Program.cs
index 8a370b0..df54590 100644
--- a/PC2Converter/PC2Converter.Wpf/Program.cs
+++ b/USTConverter/USTConverter.Wpf/Program.cs
@@ -1,7 +1,7 @@
using System;
using Eto.Forms;
-namespace PC2Converter.Wpf
+namespace USTConverter.Wpf
{
class Program
{
diff --git a/PC2Converter/PC2Converter.Wpf/PC2Converter.Wpf.csproj b/USTConverter/USTConverter.Wpf/USTConverter.Wpf.csproj
similarity index 83%
rename from PC2Converter/PC2Converter.Wpf/PC2Converter.Wpf.csproj
rename to USTConverter/USTConverter.Wpf/USTConverter.Wpf.csproj
index 32ab58c..89efd4b 100644
--- a/PC2Converter/PC2Converter.Wpf/PC2Converter.Wpf.csproj
+++ b/USTConverter/USTConverter.Wpf/USTConverter.Wpf.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/USTConverter/USTConverter/MainForm.cs b/USTConverter/USTConverter/MainForm.cs
new file mode 100644
index 0000000..66a1bd5
--- /dev/null
+++ b/USTConverter/USTConverter/MainForm.cs
@@ -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 rshwBits = new List();
+ 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 writeOut = new List();
+ 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;
+ }
+ }
+}
diff --git a/PC2Converter/PC2Converter/RSHWFile.cs b/USTConverter/USTConverter/RSHWFile.cs
similarity index 97%
rename from PC2Converter/PC2Converter/RSHWFile.cs
rename to USTConverter/USTConverter/RSHWFile.cs
index d155ddf..8e09a5f 100644
--- a/PC2Converter/PC2Converter/RSHWFile.cs
+++ b/USTConverter/USTConverter/RSHWFile.cs
@@ -1,4 +1,3 @@
-using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
diff --git a/PC2Converter/PC2Converter/PC2Converter.csproj b/USTConverter/USTConverter/USTConverter.csproj
similarity index 100%
rename from PC2Converter/PC2Converter/PC2Converter.csproj
rename to USTConverter/USTConverter/USTConverter.csproj