Compare commits

..

14 commits

71 changed files with 6882 additions and 550 deletions

1
.gitignore vendored
View file

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

View file

@ -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();
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))
{

View file

@ -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);

View file

@ -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]);

View file

@ -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();
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))
{

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 |
@ -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 |

View file

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

308
ConsolePlayer/Program.cs Normal file
View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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

View file

@ -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<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;
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<string> writeOut = new List<string>();
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;
}
}
}

25
PC3Player/PC3Player.sln Normal file
View file

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36221.1 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PC3Player", "PC3Player\PC3Player.csproj", "{13092811-9CBA-4FD5-B780-E67E14221992}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{13092811-9CBA-4FD5-B780-E67E14221992}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{13092811-9CBA-4FD5-B780-E67E14221992}.Debug|Any CPU.Build.0 = Debug|Any CPU
{13092811-9CBA-4FD5-B780-E67E14221992}.Release|Any CPU.ActiveCfg = Release|Any CPU
{13092811-9CBA-4FD5-B780-E67E14221992}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7BE19417-D601-45AA-B189-5AC9C4B041B6}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,829 @@
namespace PC3Player
{
partial class AdvancedSettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
PlaylistPlaybackGroupBox = new GroupBox();
LoopCheckBox = new CheckBox();
IntermissionUnitDropDown = new ComboBox();
IntermissionTimeCounter = new NumericUpDown();
IntermissionCheckBox = new CheckBox();
label2 = new Label();
ShowEndedDropDown = new ComboBox();
label1 = new Label();
PlaylistStartedDropDown = new ComboBox();
ShowSelectorGroupBox = new GroupBox();
AddSkitButton = new Button();
SkitCheckBox = new CheckBox();
label5 = new Label();
AlreadyPlayingDropDown = new ComboBox();
CooldownUnitDropDown = new ComboBox();
CooldownTimeCounter = new NumericUpDown();
CooldownCheckBox = new CheckBox();
label3 = new Label();
SelectedShowEndDropDown = new ComboBox();
label4 = new Label();
ButtonPressDropDown = new ComboBox();
ShowSelectorAssignmentGroupBox = new GroupBox();
AssignmentPanel = new Panel();
ButtonAssignDropDown1 = new ComboBox();
ButtonAssignDropDown2 = new ComboBox();
ButtonAssignDropDown3 = new ComboBox();
ButtonAssignDropDown4 = new ComboBox();
ButtonAssignDropDown5 = new ComboBox();
ButtonAssignDropDown6 = new ComboBox();
ButtonAssignDropDown7 = new ComboBox();
ButtonAssignDropDown8 = new ComboBox();
ButtonAssignDropDown9 = new ComboBox();
ButtonAssignDropDown10 = new ComboBox();
ButtonAssignDropDown11 = new ComboBox();
ButtonAssignDropDown12 = new ComboBox();
label14 = new Label();
label15 = new Label();
label16 = new Label();
label17 = new Label();
label10 = new Label();
label11 = new Label();
label12 = new Label();
label13 = new Label();
label8 = new Label();
label9 = new Label();
label7 = new Label();
label6 = new Label();
SkitListView = new ListView();
NameColumnHeader = new ColumnHeader();
LengthColumnHeader = new ColumnHeader();
SkitContextMenu = new ContextMenuStrip(components);
RemoveButton = new ToolStripMenuItem();
SaveButton = new Button();
CancelButton = new Button();
SelectShowFileDialog = new OpenFileDialog();
PlaybackGroupBox = new GroupBox();
label20 = new Label();
label19 = new Label();
label18 = new Label();
ResyncTimeOption = new NumericUpDown();
FrameShiftOption = new NumericUpDown();
FrameSkipOption = new NumericUpDown();
PlaylistPlaybackGroupBox.SuspendLayout();
((System.ComponentModel.ISupportInitialize)IntermissionTimeCounter).BeginInit();
ShowSelectorGroupBox.SuspendLayout();
((System.ComponentModel.ISupportInitialize)CooldownTimeCounter).BeginInit();
ShowSelectorAssignmentGroupBox.SuspendLayout();
AssignmentPanel.SuspendLayout();
SkitContextMenu.SuspendLayout();
PlaybackGroupBox.SuspendLayout();
((System.ComponentModel.ISupportInitialize)ResyncTimeOption).BeginInit();
((System.ComponentModel.ISupportInitialize)FrameShiftOption).BeginInit();
((System.ComponentModel.ISupportInitialize)FrameSkipOption).BeginInit();
SuspendLayout();
//
// PlaylistPlaybackGroupBox
//
PlaylistPlaybackGroupBox.Controls.Add(LoopCheckBox);
PlaylistPlaybackGroupBox.Controls.Add(IntermissionUnitDropDown);
PlaylistPlaybackGroupBox.Controls.Add(IntermissionTimeCounter);
PlaylistPlaybackGroupBox.Controls.Add(IntermissionCheckBox);
PlaylistPlaybackGroupBox.Controls.Add(label2);
PlaylistPlaybackGroupBox.Controls.Add(ShowEndedDropDown);
PlaylistPlaybackGroupBox.Controls.Add(label1);
PlaylistPlaybackGroupBox.Controls.Add(PlaylistStartedDropDown);
PlaylistPlaybackGroupBox.Location = new Point(12, 12);
PlaylistPlaybackGroupBox.Name = "PlaylistPlaybackGroupBox";
PlaylistPlaybackGroupBox.Size = new Size(350, 138);
PlaylistPlaybackGroupBox.TabIndex = 0;
PlaylistPlaybackGroupBox.TabStop = false;
PlaylistPlaybackGroupBox.Text = "Playlist Playback";
//
// LoopCheckBox
//
LoopCheckBox.AutoSize = true;
LoopCheckBox.Location = new Point(6, 111);
LoopCheckBox.Name = "LoopCheckBox";
LoopCheckBox.Size = new Size(162, 19);
LoopCheckBox.TabIndex = 5;
LoopCheckBox.Text = "Loop when Playlist is over";
LoopCheckBox.UseVisualStyleBackColor = true;
//
// IntermissionUnitDropDown
//
IntermissionUnitDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
IntermissionUnitDropDown.FormattingEnabled = true;
IntermissionUnitDropDown.Items.AddRange(new object[] { "Minutes", "Seconds" });
IntermissionUnitDropDown.Location = new Point(250, 80);
IntermissionUnitDropDown.Name = "IntermissionUnitDropDown";
IntermissionUnitDropDown.Size = new Size(94, 23);
IntermissionUnitDropDown.TabIndex = 4;
//
// IntermissionTimeCounter
//
IntermissionTimeCounter.Location = new Point(194, 80);
IntermissionTimeCounter.Maximum = new decimal(new int[] { 60, 0, 0, 0 });
IntermissionTimeCounter.Name = "IntermissionTimeCounter";
IntermissionTimeCounter.Size = new Size(50, 23);
IntermissionTimeCounter.TabIndex = 3;
//
// IntermissionCheckBox
//
IntermissionCheckBox.AutoSize = true;
IntermissionCheckBox.Location = new Point(6, 82);
IntermissionCheckBox.Name = "IntermissionCheckBox";
IntermissionCheckBox.Size = new Size(135, 19);
IntermissionCheckBox.TabIndex = 2;
IntermissionCheckBox.Text = "Wait between Shows";
IntermissionCheckBox.UseVisualStyleBackColor = true;
IntermissionCheckBox.CheckedChanged += IntermissionCheckBox_CheckedChanged;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(6, 54);
label2.Name = "label2";
label2.Size = new Size(107, 15);
label2.TabIndex = 3;
label2.Text = "When a Show ends";
//
// ShowEndedDropDown
//
ShowEndedDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
ShowEndedDropDown.FormattingEnabled = true;
ShowEndedDropDown.Items.AddRange(new object[] { "Play Next Show", "Play Random Show", "Repeat Show", "Stop Playlist" });
ShowEndedDropDown.Location = new Point(194, 51);
ShowEndedDropDown.Name = "ShowEndedDropDown";
ShowEndedDropDown.Size = new Size(150, 23);
ShowEndedDropDown.TabIndex = 1;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(6, 25);
label1.Name = "label1";
label1.Size = new Size(128, 15);
label1.TabIndex = 1;
label1.Text = "When Playlist is started";
//
// PlaylistStartedDropDown
//
PlaylistStartedDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
PlaylistStartedDropDown.FormattingEnabled = true;
PlaylistStartedDropDown.Items.AddRange(new object[] { "Play First Show", "Play Random Show" });
PlaylistStartedDropDown.Location = new Point(194, 22);
PlaylistStartedDropDown.Name = "PlaylistStartedDropDown";
PlaylistStartedDropDown.Size = new Size(150, 23);
PlaylistStartedDropDown.TabIndex = 0;
//
// ShowSelectorGroupBox
//
ShowSelectorGroupBox.Controls.Add(AddSkitButton);
ShowSelectorGroupBox.Controls.Add(SkitCheckBox);
ShowSelectorGroupBox.Controls.Add(label5);
ShowSelectorGroupBox.Controls.Add(AlreadyPlayingDropDown);
ShowSelectorGroupBox.Controls.Add(CooldownUnitDropDown);
ShowSelectorGroupBox.Controls.Add(CooldownTimeCounter);
ShowSelectorGroupBox.Controls.Add(CooldownCheckBox);
ShowSelectorGroupBox.Controls.Add(label3);
ShowSelectorGroupBox.Controls.Add(SelectedShowEndDropDown);
ShowSelectorGroupBox.Controls.Add(label4);
ShowSelectorGroupBox.Controls.Add(ButtonPressDropDown);
ShowSelectorGroupBox.Location = new Point(12, 156);
ShowSelectorGroupBox.Name = "ShowSelectorGroupBox";
ShowSelectorGroupBox.Size = new Size(350, 165);
ShowSelectorGroupBox.TabIndex = 1;
ShowSelectorGroupBox.TabStop = false;
ShowSelectorGroupBox.Text = "Show Selector";
//
// AddSkitButton
//
AddSkitButton.Location = new Point(250, 136);
AddSkitButton.Name = "AddSkitButton";
AddSkitButton.Size = new Size(94, 23);
AddSkitButton.TabIndex = 7;
AddSkitButton.Text = "Add Skit";
AddSkitButton.UseVisualStyleBackColor = true;
AddSkitButton.Click += AddSkitButton_Click;
//
// SkitCheckBox
//
SkitCheckBox.AutoSize = true;
SkitCheckBox.Location = new Point(6, 138);
SkitCheckBox.Name = "SkitCheckBox";
SkitCheckBox.Size = new Size(231, 19);
SkitCheckBox.TabIndex = 6;
SkitCheckBox.Text = "Play random Skit before Selected Show";
SkitCheckBox.UseVisualStyleBackColor = true;
//
// label5
//
label5.AutoSize = true;
label5.Location = new Point(6, 54);
label5.Name = "label5";
label5.Size = new Size(149, 15);
label5.TabIndex = 8;
label5.Text = "If a Show is already playing";
//
// AlreadyPlayingDropDown
//
AlreadyPlayingDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
AlreadyPlayingDropDown.FormattingEnabled = true;
AlreadyPlayingDropDown.Items.AddRange(new object[] { "Stop current", "Play after finished", "Ignore button" });
AlreadyPlayingDropDown.Location = new Point(194, 51);
AlreadyPlayingDropDown.Name = "AlreadyPlayingDropDown";
AlreadyPlayingDropDown.Size = new Size(150, 23);
AlreadyPlayingDropDown.TabIndex = 1;
//
// CooldownUnitDropDown
//
CooldownUnitDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
CooldownUnitDropDown.FormattingEnabled = true;
CooldownUnitDropDown.Items.AddRange(new object[] { "Minutes", "Seconds" });
CooldownUnitDropDown.Location = new Point(250, 107);
CooldownUnitDropDown.Name = "CooldownUnitDropDown";
CooldownUnitDropDown.Size = new Size(94, 23);
CooldownUnitDropDown.TabIndex = 5;
//
// CooldownTimeCounter
//
CooldownTimeCounter.Location = new Point(194, 107);
CooldownTimeCounter.Maximum = new decimal(new int[] { 60, 0, 0, 0 });
CooldownTimeCounter.Name = "CooldownTimeCounter";
CooldownTimeCounter.Size = new Size(50, 23);
CooldownTimeCounter.TabIndex = 4;
//
// CooldownCheckBox
//
CooldownCheckBox.AutoSize = true;
CooldownCheckBox.Location = new Point(6, 109);
CooldownCheckBox.Name = "CooldownCheckBox";
CooldownCheckBox.Size = new Size(185, 19);
CooldownCheckBox.TabIndex = 3;
CooldownCheckBox.Text = "Cooldown between Selections";
CooldownCheckBox.UseVisualStyleBackColor = true;
CooldownCheckBox.CheckedChanged += CooldownCheckBox_CheckedChanged;
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(6, 83);
label3.Name = "label3";
label3.Size = new Size(154, 15);
label3.TabIndex = 3;
label3.Text = "When a Selected Show ends";
//
// SelectedShowEndDropDown
//
SelectedShowEndDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
SelectedShowEndDropDown.FormattingEnabled = true;
SelectedShowEndDropDown.Items.AddRange(new object[] { "Return to Playlist", "Do Nothing" });
SelectedShowEndDropDown.Location = new Point(194, 80);
SelectedShowEndDropDown.Name = "SelectedShowEndDropDown";
SelectedShowEndDropDown.Size = new Size(150, 23);
SelectedShowEndDropDown.TabIndex = 2;
//
// label4
//
label4.AutoSize = true;
label4.Location = new Point(6, 25);
label4.Name = "label4";
label4.Size = new Size(140, 15);
label4.TabIndex = 1;
label4.Text = "When a Button is pressed";
//
// ButtonPressDropDown
//
ButtonPressDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonPressDropDown.FormattingEnabled = true;
ButtonPressDropDown.Items.AddRange(new object[] { "Play Assigned Show", "Play Random Show" });
ButtonPressDropDown.Location = new Point(194, 22);
ButtonPressDropDown.Name = "ButtonPressDropDown";
ButtonPressDropDown.Size = new Size(150, 23);
ButtonPressDropDown.TabIndex = 0;
//
// ShowSelectorAssignmentGroupBox
//
ShowSelectorAssignmentGroupBox.Controls.Add(AssignmentPanel);
ShowSelectorAssignmentGroupBox.Controls.Add(label14);
ShowSelectorAssignmentGroupBox.Controls.Add(label15);
ShowSelectorAssignmentGroupBox.Controls.Add(label16);
ShowSelectorAssignmentGroupBox.Controls.Add(label17);
ShowSelectorAssignmentGroupBox.Controls.Add(label10);
ShowSelectorAssignmentGroupBox.Controls.Add(label11);
ShowSelectorAssignmentGroupBox.Controls.Add(label12);
ShowSelectorAssignmentGroupBox.Controls.Add(label13);
ShowSelectorAssignmentGroupBox.Controls.Add(label8);
ShowSelectorAssignmentGroupBox.Controls.Add(label9);
ShowSelectorAssignmentGroupBox.Controls.Add(label7);
ShowSelectorAssignmentGroupBox.Controls.Add(label6);
ShowSelectorAssignmentGroupBox.Location = new Point(368, 12);
ShowSelectorAssignmentGroupBox.Name = "ShowSelectorAssignmentGroupBox";
ShowSelectorAssignmentGroupBox.Size = new Size(256, 370);
ShowSelectorAssignmentGroupBox.TabIndex = 3;
ShowSelectorAssignmentGroupBox.TabStop = false;
ShowSelectorAssignmentGroupBox.Text = "Show Selector Assignment";
//
// AssignmentPanel
//
AssignmentPanel.Controls.Add(ButtonAssignDropDown1);
AssignmentPanel.Controls.Add(ButtonAssignDropDown2);
AssignmentPanel.Controls.Add(ButtonAssignDropDown3);
AssignmentPanel.Controls.Add(ButtonAssignDropDown4);
AssignmentPanel.Controls.Add(ButtonAssignDropDown5);
AssignmentPanel.Controls.Add(ButtonAssignDropDown6);
AssignmentPanel.Controls.Add(ButtonAssignDropDown7);
AssignmentPanel.Controls.Add(ButtonAssignDropDown8);
AssignmentPanel.Controls.Add(ButtonAssignDropDown9);
AssignmentPanel.Controls.Add(ButtonAssignDropDown10);
AssignmentPanel.Controls.Add(ButtonAssignDropDown11);
AssignmentPanel.Controls.Add(ButtonAssignDropDown12);
AssignmentPanel.Location = new Point(100, 22);
AssignmentPanel.Name = "AssignmentPanel";
AssignmentPanel.Size = new Size(150, 342);
AssignmentPanel.TabIndex = 0;
//
// ButtonAssignDropDown1
//
ButtonAssignDropDown1.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown1.FormattingEnabled = true;
ButtonAssignDropDown1.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown1.Location = new Point(0, 0);
ButtonAssignDropDown1.Name = "ButtonAssignDropDown1";
ButtonAssignDropDown1.Size = new Size(150, 23);
ButtonAssignDropDown1.TabIndex = 0;
//
// ButtonAssignDropDown2
//
ButtonAssignDropDown2.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown2.FormattingEnabled = true;
ButtonAssignDropDown2.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown2.Location = new Point(0, 29);
ButtonAssignDropDown2.Name = "ButtonAssignDropDown2";
ButtonAssignDropDown2.Size = new Size(150, 23);
ButtonAssignDropDown2.TabIndex = 1;
//
// ButtonAssignDropDown3
//
ButtonAssignDropDown3.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown3.FormattingEnabled = true;
ButtonAssignDropDown3.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown3.Location = new Point(0, 58);
ButtonAssignDropDown3.Name = "ButtonAssignDropDown3";
ButtonAssignDropDown3.Size = new Size(150, 23);
ButtonAssignDropDown3.TabIndex = 2;
//
// ButtonAssignDropDown4
//
ButtonAssignDropDown4.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown4.FormattingEnabled = true;
ButtonAssignDropDown4.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown4.Location = new Point(0, 87);
ButtonAssignDropDown4.Name = "ButtonAssignDropDown4";
ButtonAssignDropDown4.Size = new Size(150, 23);
ButtonAssignDropDown4.TabIndex = 3;
//
// ButtonAssignDropDown5
//
ButtonAssignDropDown5.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown5.FormattingEnabled = true;
ButtonAssignDropDown5.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown5.Location = new Point(0, 116);
ButtonAssignDropDown5.Name = "ButtonAssignDropDown5";
ButtonAssignDropDown5.Size = new Size(150, 23);
ButtonAssignDropDown5.TabIndex = 4;
//
// ButtonAssignDropDown6
//
ButtonAssignDropDown6.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown6.FormattingEnabled = true;
ButtonAssignDropDown6.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown6.Location = new Point(0, 145);
ButtonAssignDropDown6.Name = "ButtonAssignDropDown6";
ButtonAssignDropDown6.Size = new Size(150, 23);
ButtonAssignDropDown6.TabIndex = 5;
//
// ButtonAssignDropDown7
//
ButtonAssignDropDown7.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown7.FormattingEnabled = true;
ButtonAssignDropDown7.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown7.Location = new Point(0, 174);
ButtonAssignDropDown7.Name = "ButtonAssignDropDown7";
ButtonAssignDropDown7.Size = new Size(150, 23);
ButtonAssignDropDown7.TabIndex = 6;
//
// ButtonAssignDropDown8
//
ButtonAssignDropDown8.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown8.FormattingEnabled = true;
ButtonAssignDropDown8.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown8.Location = new Point(0, 203);
ButtonAssignDropDown8.Name = "ButtonAssignDropDown8";
ButtonAssignDropDown8.Size = new Size(150, 23);
ButtonAssignDropDown8.TabIndex = 7;
//
// ButtonAssignDropDown9
//
ButtonAssignDropDown9.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown9.FormattingEnabled = true;
ButtonAssignDropDown9.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown9.Location = new Point(0, 232);
ButtonAssignDropDown9.Name = "ButtonAssignDropDown9";
ButtonAssignDropDown9.Size = new Size(150, 23);
ButtonAssignDropDown9.TabIndex = 8;
//
// ButtonAssignDropDown10
//
ButtonAssignDropDown10.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown10.FormattingEnabled = true;
ButtonAssignDropDown10.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown10.Location = new Point(0, 261);
ButtonAssignDropDown10.Name = "ButtonAssignDropDown10";
ButtonAssignDropDown10.Size = new Size(150, 23);
ButtonAssignDropDown10.TabIndex = 9;
//
// ButtonAssignDropDown11
//
ButtonAssignDropDown11.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown11.FormattingEnabled = true;
ButtonAssignDropDown11.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown11.Location = new Point(0, 290);
ButtonAssignDropDown11.Name = "ButtonAssignDropDown11";
ButtonAssignDropDown11.Size = new Size(150, 23);
ButtonAssignDropDown11.TabIndex = 10;
//
// ButtonAssignDropDown12
//
ButtonAssignDropDown12.DropDownStyle = ComboBoxStyle.DropDownList;
ButtonAssignDropDown12.FormattingEnabled = true;
ButtonAssignDropDown12.Items.AddRange(new object[] { "(None)" });
ButtonAssignDropDown12.Location = new Point(0, 319);
ButtonAssignDropDown12.Name = "ButtonAssignDropDown12";
ButtonAssignDropDown12.Size = new Size(150, 23);
ButtonAssignDropDown12.TabIndex = 11;
//
// label14
//
label14.AutoSize = true;
label14.Location = new Point(6, 344);
label14.Name = "label14";
label14.Size = new Size(58, 15);
label14.TabIndex = 30;
label14.Text = "Button 12";
//
// label15
//
label15.AutoSize = true;
label15.Location = new Point(6, 315);
label15.Name = "label15";
label15.Size = new Size(58, 15);
label15.TabIndex = 28;
label15.Text = "Button 11";
//
// label16
//
label16.AutoSize = true;
label16.Location = new Point(6, 286);
label16.Name = "label16";
label16.Size = new Size(58, 15);
label16.TabIndex = 26;
label16.Text = "Button 10";
//
// label17
//
label17.AutoSize = true;
label17.Location = new Point(6, 257);
label17.Name = "label17";
label17.Size = new Size(52, 15);
label17.TabIndex = 24;
label17.Text = "Button 9";
//
// label10
//
label10.AutoSize = true;
label10.Location = new Point(6, 228);
label10.Name = "label10";
label10.Size = new Size(52, 15);
label10.TabIndex = 22;
label10.Text = "Button 8";
//
// label11
//
label11.AutoSize = true;
label11.Location = new Point(6, 199);
label11.Name = "label11";
label11.Size = new Size(52, 15);
label11.TabIndex = 20;
label11.Text = "Button 7";
//
// label12
//
label12.AutoSize = true;
label12.Location = new Point(6, 170);
label12.Name = "label12";
label12.Size = new Size(52, 15);
label12.TabIndex = 18;
label12.Text = "Button 6";
//
// label13
//
label13.AutoSize = true;
label13.Location = new Point(6, 141);
label13.Name = "label13";
label13.Size = new Size(52, 15);
label13.TabIndex = 16;
label13.Text = "Button 5";
//
// label8
//
label8.AutoSize = true;
label8.Location = new Point(6, 112);
label8.Name = "label8";
label8.Size = new Size(52, 15);
label8.TabIndex = 14;
label8.Text = "Button 4";
//
// label9
//
label9.AutoSize = true;
label9.Location = new Point(6, 83);
label9.Name = "label9";
label9.Size = new Size(52, 15);
label9.TabIndex = 12;
label9.Text = "Button 3";
//
// label7
//
label7.AutoSize = true;
label7.Location = new Point(6, 54);
label7.Name = "label7";
label7.Size = new Size(52, 15);
label7.TabIndex = 10;
label7.Text = "Button 2";
//
// label6
//
label6.AutoSize = true;
label6.Location = new Point(6, 25);
label6.Name = "label6";
label6.Size = new Size(52, 15);
label6.TabIndex = 8;
label6.Text = "Button 1";
//
// SkitListView
//
SkitListView.AutoArrange = false;
SkitListView.Columns.AddRange(new ColumnHeader[] { NameColumnHeader, LengthColumnHeader });
SkitListView.ContextMenuStrip = SkitContextMenu;
SkitListView.GridLines = true;
SkitListView.HeaderStyle = ColumnHeaderStyle.Nonclickable;
SkitListView.Location = new Point(12, 327);
SkitListView.MultiSelect = false;
SkitListView.Name = "SkitListView";
SkitListView.Size = new Size(350, 201);
SkitListView.TabIndex = 2;
SkitListView.UseCompatibleStateImageBehavior = false;
SkitListView.View = View.Details;
//
// NameColumnHeader
//
NameColumnHeader.Text = "Skit Name";
NameColumnHeader.Width = 260;
//
// LengthColumnHeader
//
LengthColumnHeader.Text = "Length";
//
// SkitContextMenu
//
SkitContextMenu.Items.AddRange(new ToolStripItem[] { RemoveButton });
SkitContextMenu.Name = "ShowContextMenu";
SkitContextMenu.Size = new Size(118, 26);
//
// RemoveButton
//
RemoveButton.Name = "RemoveButton";
RemoveButton.Size = new Size(117, 22);
RemoveButton.Text = "Remove";
RemoveButton.Click += RemoveButton_Click;
//
// SaveButton
//
SaveButton.DialogResult = DialogResult.OK;
SaveButton.Location = new Point(549, 503);
SaveButton.Name = "SaveButton";
SaveButton.Size = new Size(75, 25);
SaveButton.TabIndex = 10;
SaveButton.Text = "Save";
SaveButton.UseVisualStyleBackColor = true;
SaveButton.Click += SaveButton_Click;
//
// CancelButton
//
CancelButton.DialogResult = DialogResult.Cancel;
CancelButton.Location = new Point(468, 503);
CancelButton.Name = "CancelButton";
CancelButton.Size = new Size(75, 25);
CancelButton.TabIndex = 11;
CancelButton.Text = "Cancel";
CancelButton.UseVisualStyleBackColor = true;
//
// SelectShowFileDialog
//
SelectShowFileDialog.Filter = "UST Showtapes|*.ust";
SelectShowFileDialog.Multiselect = true;
//
// PlaybackGroupBox
//
PlaybackGroupBox.Controls.Add(label20);
PlaybackGroupBox.Controls.Add(label19);
PlaybackGroupBox.Controls.Add(label18);
PlaybackGroupBox.Controls.Add(ResyncTimeOption);
PlaybackGroupBox.Controls.Add(FrameShiftOption);
PlaybackGroupBox.Controls.Add(FrameSkipOption);
PlaybackGroupBox.Location = new Point(368, 388);
PlaybackGroupBox.Name = "PlaybackGroupBox";
PlaybackGroupBox.Size = new Size(256, 109);
PlaybackGroupBox.TabIndex = 4;
PlaybackGroupBox.TabStop = false;
PlaybackGroupBox.Text = "Tracking Adjustments";
//
// label20
//
label20.AutoSize = true;
label20.Location = new Point(6, 82);
label20.Name = "label20";
label20.Size = new Size(67, 15);
label20.TabIndex = 5;
label20.Text = "Frame Shift";
//
// label19
//
label19.AutoSize = true;
label19.Location = new Point(6, 53);
label19.Name = "label19";
label19.Size = new Size(73, 15);
label19.TabIndex = 4;
label19.Text = "Resync Time";
//
// label18
//
label18.AutoSize = true;
label18.Location = new Point(6, 24);
label18.Name = "label18";
label18.Size = new Size(65, 15);
label18.TabIndex = 3;
label18.Text = "Frame Skip";
//
// ResyncTimeOption
//
ResyncTimeOption.Location = new Point(200, 51);
ResyncTimeOption.Maximum = new decimal(new int[] { 60, 0, 0, 0 });
ResyncTimeOption.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
ResyncTimeOption.Name = "ResyncTimeOption";
ResyncTimeOption.Size = new Size(50, 23);
ResyncTimeOption.TabIndex = 1;
ResyncTimeOption.Value = new decimal(new int[] { 1, 0, 0, 0 });
//
// FrameShiftOption
//
FrameShiftOption.Location = new Point(200, 80);
FrameShiftOption.Maximum = new decimal(new int[] { 60, 0, 0, 0 });
FrameShiftOption.Minimum = new decimal(new int[] { 60, 0, 0, int.MinValue });
FrameShiftOption.Name = "FrameShiftOption";
FrameShiftOption.Size = new Size(50, 23);
FrameShiftOption.TabIndex = 2;
//
// FrameSkipOption
//
FrameSkipOption.Location = new Point(200, 22);
FrameSkipOption.Maximum = new decimal(new int[] { 10, 0, 0, 0 });
FrameSkipOption.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
FrameSkipOption.Name = "FrameSkipOption";
FrameSkipOption.Size = new Size(50, 23);
FrameSkipOption.TabIndex = 0;
FrameSkipOption.Value = new decimal(new int[] { 1, 0, 0, 0 });
//
// AdvancedSettingsForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(636, 540);
Controls.Add(PlaybackGroupBox);
Controls.Add(CancelButton);
Controls.Add(SaveButton);
Controls.Add(SkitListView);
Controls.Add(ShowSelectorAssignmentGroupBox);
Controls.Add(ShowSelectorGroupBox);
Controls.Add(PlaylistPlaybackGroupBox);
FormBorderStyle = FormBorderStyle.FixedDialog;
MaximizeBox = false;
Name = "AdvancedSettingsForm";
Text = "Advanced Settings";
PlaylistPlaybackGroupBox.ResumeLayout(false);
PlaylistPlaybackGroupBox.PerformLayout();
((System.ComponentModel.ISupportInitialize)IntermissionTimeCounter).EndInit();
ShowSelectorGroupBox.ResumeLayout(false);
ShowSelectorGroupBox.PerformLayout();
((System.ComponentModel.ISupportInitialize)CooldownTimeCounter).EndInit();
ShowSelectorAssignmentGroupBox.ResumeLayout(false);
ShowSelectorAssignmentGroupBox.PerformLayout();
AssignmentPanel.ResumeLayout(false);
SkitContextMenu.ResumeLayout(false);
PlaybackGroupBox.ResumeLayout(false);
PlaybackGroupBox.PerformLayout();
((System.ComponentModel.ISupportInitialize)ResyncTimeOption).EndInit();
((System.ComponentModel.ISupportInitialize)FrameShiftOption).EndInit();
((System.ComponentModel.ISupportInitialize)FrameSkipOption).EndInit();
ResumeLayout(false);
}
#endregion
private GroupBox PlaylistPlaybackGroupBox;
private Label label1;
private ComboBox PlaylistStartedDropDown;
private ComboBox ShowEndedDropDown;
private ComboBox IntermissionUnitDropDown;
private NumericUpDown IntermissionTimeCounter;
private CheckBox IntermissionCheckBox;
private Label label2;
private GroupBox ShowSelectorGroupBox;
private ComboBox CooldownUnitDropDown;
private NumericUpDown CooldownTimeCounter;
private CheckBox CooldownCheckBox;
private Label label3;
private ComboBox SelectedShowEndDropDown;
private Label label4;
private ComboBox ButtonPressDropDown;
private Label label5;
private ComboBox AlreadyPlayingDropDown;
private CheckBox SkitCheckBox;
private Button AddSkitButton;
private GroupBox ShowSelectorAssignmentGroupBox;
private Label label14;
private ComboBox ButtonAssignDropDown12;
private Label label15;
private ComboBox ButtonAssignDropDown11;
private Label label16;
private ComboBox ButtonAssignDropDown10;
private Label label17;
private ComboBox ButtonAssignDropDown9;
private Label label10;
private ComboBox ButtonAssignDropDown8;
private Label label11;
private ComboBox ButtonAssignDropDown7;
private Label label12;
private ComboBox ButtonAssignDropDown6;
private Label label13;
private ComboBox ButtonAssignDropDown5;
private Label label8;
private ComboBox ButtonAssignDropDown4;
private Label label9;
private ComboBox ButtonAssignDropDown3;
private Label label7;
private ComboBox ButtonAssignDropDown2;
private Label label6;
private ComboBox ButtonAssignDropDown1;
private ListView SkitListView;
private ColumnHeader NameColumnHeader;
private ColumnHeader LengthColumnHeader;
private Button SaveButton;
private Button CancelButton;
private ContextMenuStrip SkitContextMenu;
private ToolStripMenuItem RemoveButton;
private OpenFileDialog SelectShowFileDialog;
private Panel AssignmentPanel;
private CheckBox LoopCheckBox;
private GroupBox PlaybackGroupBox;
private Label label18;
private NumericUpDown ResyncTimeOption;
private NumericUpDown FrameShiftOption;
private NumericUpDown FrameSkipOption;
private Label label20;
private Label label19;
}
}

View file

@ -0,0 +1,146 @@
namespace PC3Player
{
public partial class AdvancedSettingsForm : Form
{
public PlaylistConfig EditingObject { get; set; }
public AdvancedSettingsForm(PlaylistConfig playlist)
{
InitializeComponent();
EditingObject = playlist;
PlaylistStartedDropDown.SelectedIndex = EditingObject.PlaylistStartOption;
ShowEndedDropDown.SelectedIndex = EditingObject.PlaylistShowEndOption;
IntermissionCheckBox.Checked = EditingObject.PlaylistIntermissionOption;
IntermissionTimeCounter.Value = EditingObject.PlaylistIntermissionTimeOption;
IntermissionUnitDropDown.SelectedIndex = EditingObject.PlaylistIntermissionUnitOption;
LoopCheckBox.Checked = EditingObject.PlaylistLoopOption;
ButtonPressDropDown.SelectedIndex = EditingObject.SelectorButtonPressOption;
AlreadyPlayingDropDown.SelectedIndex = EditingObject.SelectorShowAlreadyPlayingOption;
SelectedShowEndDropDown.SelectedIndex = EditingObject.SelectorShowEndOption;
CooldownCheckBox.Checked = EditingObject.SelectorCooldownOption;
CooldownTimeCounter.Value = EditingObject.SelectorCooldownTimeOption;
CooldownUnitDropDown.SelectedIndex = EditingObject.SelectorCooldownUnitOption;
SkitCheckBox.Checked = EditingObject.SelectorPlaySkitOption;
FrameSkipOption.Value = EditingObject.FramesPerTick;
FrameShiftOption.Value = EditingObject.FrameShift;
ResyncTimeOption.Value = EditingObject.ResyncSeconds;
IntermissionTimeCounter.Enabled = IntermissionCheckBox.Checked;
IntermissionUnitDropDown.Enabled = IntermissionCheckBox.Checked;
CooldownTimeCounter.Enabled = CooldownCheckBox.Checked;
CooldownUnitDropDown.Enabled = CooldownCheckBox.Checked;
int i = 0;
foreach (ComboBox c in AssignmentPanel.Controls)
{
foreach (PlaylistShow s in EditingObject.Shows) c.Items.Add(s.Name);
if (EditingObject.SelectorAssignments[i] == null) c.SelectedIndex = 0;
else c.SelectedIndex = (int)EditingObject.SelectorAssignments[i] + 1;
i++;
}
UpdateListView();
}
private void UpdateListView()
{
SkitListView.Items.Clear();
foreach (PlaylistShow s in EditingObject.Skits) SkitListView.Items.Add(new ListViewItem(new[] { s.Name, s.Length }));
SkitCheckBox.Enabled = EditingObject.Skits.Count != 0;
if (EditingObject.Skits.Count == 0) SkitCheckBox.Checked = false;
}
private void IntermissionCheckBox_CheckedChanged(object sender, EventArgs e)
{
IntermissionTimeCounter.Enabled = IntermissionCheckBox.Checked;
IntermissionUnitDropDown.Enabled = IntermissionCheckBox.Checked;
}
private void CooldownCheckBox_CheckedChanged(object sender, EventArgs e)
{
CooldownTimeCounter.Enabled = CooldownCheckBox.Checked;
CooldownUnitDropDown.Enabled = CooldownCheckBox.Checked;
}
private void RemoveButton_Click(object sender, EventArgs e)
{
if (SkitListView.SelectedIndices.Count == 0) return;
EditingObject.Skits.RemoveAt(SkitListView.SelectedIndices[0]);
UpdateListView();
}
private void AddSkitButton_Click(object sender, EventArgs e)
{
if (!MainForm.ChannelMappingLoaded)
{
MessageBox.Show("You must load a channel mapping first.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (SelectShowFileDialog.ShowDialog() == DialogResult.OK)
{
string tempUSTData = File.ReadAllText(SelectShowFileDialog.FileName);
if (!tempUSTData.StartsWith("UST,2,"))
{
MessageBox.Show("Selected showtape is not a UST version 2 showtape.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string[] headerData = tempUSTData.Split(';')[0].Split(',');
string[] stringyBits = tempUSTData.Split(';')[1].Split(',');
TimeSpan time = TimeSpan.FromSeconds(stringyBits.Length / 60);
string formattedLength = time.ToString(@"hh\:mm\:ss");
tempUSTData = null;
stringyBits = null;
if (headerData[3] != EditingObject.Mapping.Type)
{
MessageBox.Show(
$"Selected showtape type does not match the loaded Channel Map." +
$"\nLoaded Channel Map Type: {EditingObject.Mapping.Type}" +
$"\nShowtape Type: {headerData[3]}"
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
EditingObject.Skits.Add(new PlaylistShow(headerData[2], formattedLength, headerData[3], SelectShowFileDialog.FileName));
UpdateListView();
}
}
private void SaveButton_Click(object sender, EventArgs e)
{
EditingObject.PlaylistStartOption = PlaylistStartedDropDown.SelectedIndex;
EditingObject.PlaylistShowEndOption = ShowEndedDropDown.SelectedIndex;
EditingObject.PlaylistIntermissionOption = IntermissionCheckBox.Checked;
EditingObject.PlaylistIntermissionTimeOption = (int)IntermissionTimeCounter.Value;
EditingObject.PlaylistIntermissionUnitOption = IntermissionUnitDropDown.SelectedIndex;
EditingObject.PlaylistLoopOption = LoopCheckBox.Checked;
EditingObject.SelectorButtonPressOption = ButtonPressDropDown.SelectedIndex;
EditingObject.SelectorShowAlreadyPlayingOption = AlreadyPlayingDropDown.SelectedIndex;
EditingObject.SelectorShowEndOption = SelectedShowEndDropDown.SelectedIndex;
EditingObject.SelectorCooldownOption = CooldownCheckBox.Checked;
EditingObject.SelectorCooldownTimeOption = (int)CooldownTimeCounter.Value;
EditingObject.SelectorCooldownUnitOption = CooldownUnitDropDown.SelectedIndex;
EditingObject.SelectorPlaySkitOption = SkitCheckBox.Checked;
EditingObject.ResyncSeconds = (int)ResyncTimeOption.Value;
EditingObject.FrameShift = (int)FrameShiftOption.Value;
EditingObject.FramesPerTick = (int)FrameSkipOption.Value;
int i = 0;
foreach (ComboBox c in AssignmentPanel.Controls)
{
if (c.SelectedIndex == 0) EditingObject.SelectorAssignments[i] = null;
else EditingObject.SelectorAssignments[i] = c.SelectedIndex - 1;
i++;
}
}
}
}

View file

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="SkitContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>51, 28</value>
</metadata>
<metadata name="SelectShowFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>215, 23</value>
</metadata>
</root>

View file

@ -0,0 +1 @@
PC3MAPPING,2,Beach Bear/Jasper,Rockafire Explosion/3-Stage;58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;0

View file

@ -0,0 +1 @@
PC3MAPPING,2,Billy Bob,Rockafire Explosion/3-Stage;91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,0,0,0,0,0,0,0,0,0,0,0,0;0

View file

@ -0,0 +1 @@
PC3MAPPING,2,Cyberamic Chuck E.,Cyberamics;1,2,3,4,5,6,7,8;0

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1 @@
PC3MAPPING,2,Dook/Pasqually,Rockafire Explosion/3-Stage;74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;0

View file

@ -0,0 +1 @@
PC3MAPPING,2,Fatz/Munch,Rockafire Explosion/3-Stage;42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;0

View file

@ -0,0 +1 @@
PC3MAPPING,2,Mitzi/Helen,Rockafire Explosion/3-Stage;23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,0,0,0,0,0,0,0,0,0,0,0,0,0;0

View file

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

View file

@ -0,0 +1,73 @@
using System.Diagnostics.Eventing.Reader;
namespace PC3Player
{
public class PlaylistShow
{
public PlaylistShow(string name, string length, string type, string filePath)
{
Name = name;
Type = type;
Length = length;
FilePath = filePath;
}
public string Name { get; set; }
public string Type { get; set; }
public string Length { get; set; }
public string FilePath { get; set; }
}
public class ChannelMapping
{
public ChannelMapping(string name, string type, int[] bits, int[] invertedBits)
{
Name = name;
Type = type;
Bits = bits;
InvertedBits = invertedBits;
}
public string Name { get; set; }
public string Type { get; set; }
public int[] Bits { get; set; }
public int[] InvertedBits { get; set; }
}
public class PlaylistConfig
{
public int PlaylistStartOption { get; set; } = 0;
public int PlaylistShowEndOption { get; set; } = 0;
public bool PlaylistIntermissionOption { get; set; } = false;
public int PlaylistIntermissionTimeOption { get; set; } = 8;
public int PlaylistIntermissionUnitOption { get; set; } = 0;
public bool PlaylistLoopOption { get; set; } = true;
public int SelectorButtonPressOption { get; set; } = 0;
public int SelectorShowAlreadyPlayingOption { get; set; } = 0;
public int SelectorShowEndOption { get; set; } = 0;
public bool SelectorCooldownOption { get; set; } = false;
public int SelectorCooldownTimeOption { get; set; } = 30;
public int SelectorCooldownUnitOption { get; set; } = 1;
public bool SelectorPlaySkitOption { get; set; } = false;
public int?[] SelectorAssignments { get; set; } = new int?[12];
public int FramesPerTick { get; set; } = 6;
public int ResyncSeconds { get; set; } = 1;
public int FrameShift { get; set; } = 0;
public ChannelMapping Mapping { get; set; }
public List<PlaylistShow> Shows { get; set; } = new List<PlaylistShow>();
public List<PlaylistShow> Skits { get; set; } = new List<PlaylistShow>();
}
public enum StartMethod
{
PlaylistStart,
PlaylistShowEnd,
SelectorPress,
SelectorShowEnd
}
}

414
PC3Player/PC3Player/MainForm.Designer.cs generated Normal file
View file

@ -0,0 +1,414 @@
namespace PC3Player
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
ControllerGroupBox = new GroupBox();
ControllerSelectSerialPortButton = new Button();
ControllerAutoDetectButton = new Button();
PlaybackControlsGroupBox = new GroupBox();
TimeLabel = new Label();
StopButton = new Button();
SkipButton = new Button();
PauseButton = new Button();
StartButton = new Button();
ShowSelectorGroupBox = new GroupBox();
ShowSelectorSelectPortButton = new Button();
ShowSelectorAutoDetectButton = new Button();
PlaylistGroupBox = new GroupBox();
AdvancedSettingsButton = new Button();
AddShowButton = new Button();
LoadPlaylistButton = new Button();
SavePlaylistButton = new Button();
ChannelMappingGroupBox = new GroupBox();
LoadChannelMapButton = new Button();
PlaylistListView = new ListView();
NameColumnHeader = new ColumnHeader();
LengthColumnHeader = new ColumnHeader();
ShowContextMenu = new ContextMenuStrip(components);
MoveUpButton = new ToolStripMenuItem();
MoveDownButton = new ToolStripMenuItem();
RemoveButton = new ToolStripMenuItem();
SelectShowFileDialog = new OpenFileDialog();
SelectMappingFileDialog = new OpenFileDialog();
SavePlaylistFileDialog = new SaveFileDialog();
OpenPlaylistFileDialog = new OpenFileDialog();
NewPlaylistButton = new Button();
ControllerGroupBox.SuspendLayout();
PlaybackControlsGroupBox.SuspendLayout();
ShowSelectorGroupBox.SuspendLayout();
PlaylistGroupBox.SuspendLayout();
ChannelMappingGroupBox.SuspendLayout();
ShowContextMenu.SuspendLayout();
SuspendLayout();
//
// ControllerGroupBox
//
ControllerGroupBox.Controls.Add(ControllerSelectSerialPortButton);
ControllerGroupBox.Controls.Add(ControllerAutoDetectButton);
ControllerGroupBox.Location = new Point(12, 12);
ControllerGroupBox.Name = "ControllerGroupBox";
ControllerGroupBox.Size = new Size(256, 84);
ControllerGroupBox.TabIndex = 0;
ControllerGroupBox.TabStop = false;
ControllerGroupBox.Text = "Controller: Not Connected";
//
// ControllerSelectSerialPortButton
//
ControllerSelectSerialPortButton.Location = new Point(6, 53);
ControllerSelectSerialPortButton.Name = "ControllerSelectSerialPortButton";
ControllerSelectSerialPortButton.Size = new Size(244, 25);
ControllerSelectSerialPortButton.TabIndex = 1;
ControllerSelectSerialPortButton.Text = "Select Serial Port";
ControllerSelectSerialPortButton.UseVisualStyleBackColor = true;
ControllerSelectSerialPortButton.Click += ControllerSelectSerialPortButton_Click;
//
// ControllerAutoDetectButton
//
ControllerAutoDetectButton.Location = new Point(6, 22);
ControllerAutoDetectButton.Name = "ControllerAutoDetectButton";
ControllerAutoDetectButton.Size = new Size(244, 25);
ControllerAutoDetectButton.TabIndex = 0;
ControllerAutoDetectButton.Text = "Auto Detect";
ControllerAutoDetectButton.UseVisualStyleBackColor = true;
ControllerAutoDetectButton.Click += ControllerAutoDetectButton_Click;
//
// PlaybackControlsGroupBox
//
PlaybackControlsGroupBox.Controls.Add(TimeLabel);
PlaybackControlsGroupBox.Controls.Add(StopButton);
PlaybackControlsGroupBox.Controls.Add(SkipButton);
PlaybackControlsGroupBox.Controls.Add(PauseButton);
PlaybackControlsGroupBox.Controls.Add(StartButton);
PlaybackControlsGroupBox.Location = new Point(12, 376);
PlaybackControlsGroupBox.Name = "PlaybackControlsGroupBox";
PlaybackControlsGroupBox.Size = new Size(256, 99);
PlaybackControlsGroupBox.TabIndex = 4;
PlaybackControlsGroupBox.TabStop = false;
PlaybackControlsGroupBox.Text = "Controls: Not Playing";
//
// TimeLabel
//
TimeLabel.AutoSize = true;
TimeLabel.Location = new Point(6, 81);
TimeLabel.Name = "TimeLabel";
TimeLabel.Size = new Size(104, 15);
TimeLabel.TabIndex = 4;
TimeLabel.Text = "(00:00:00/00:00:00)";
//
// StopButton
//
StopButton.Enabled = false;
StopButton.Location = new Point(131, 53);
StopButton.Name = "StopButton";
StopButton.Size = new Size(119, 25);
StopButton.TabIndex = 3;
StopButton.Text = "Stop";
StopButton.UseVisualStyleBackColor = true;
StopButton.Click += StopButton_Click;
//
// SkipButton
//
SkipButton.Enabled = false;
SkipButton.Location = new Point(6, 53);
SkipButton.Name = "SkipButton";
SkipButton.Size = new Size(119, 25);
SkipButton.TabIndex = 2;
SkipButton.Text = "Skip";
SkipButton.UseVisualStyleBackColor = true;
SkipButton.Click += SkipButton_Click;
//
// PauseButton
//
PauseButton.Enabled = false;
PauseButton.Location = new Point(131, 22);
PauseButton.Name = "PauseButton";
PauseButton.Size = new Size(119, 25);
PauseButton.TabIndex = 1;
PauseButton.Text = "Pause";
PauseButton.UseVisualStyleBackColor = true;
PauseButton.Click += PauseButton_Click;
//
// StartButton
//
StartButton.Location = new Point(6, 22);
StartButton.Name = "StartButton";
StartButton.Size = new Size(119, 25);
StartButton.TabIndex = 0;
StartButton.Text = "Start Playlist";
StartButton.UseVisualStyleBackColor = true;
StartButton.Click += StartButton_Click;
//
// ShowSelectorGroupBox
//
ShowSelectorGroupBox.Controls.Add(ShowSelectorSelectPortButton);
ShowSelectorGroupBox.Controls.Add(ShowSelectorAutoDetectButton);
ShowSelectorGroupBox.Enabled = false;
ShowSelectorGroupBox.Location = new Point(12, 102);
ShowSelectorGroupBox.Name = "ShowSelectorGroupBox";
ShowSelectorGroupBox.Size = new Size(256, 84);
ShowSelectorGroupBox.TabIndex = 1;
ShowSelectorGroupBox.TabStop = false;
ShowSelectorGroupBox.Text = "Show Selector: Not Connected";
//
// ShowSelectorSelectPortButton
//
ShowSelectorSelectPortButton.Location = new Point(6, 53);
ShowSelectorSelectPortButton.Name = "ShowSelectorSelectPortButton";
ShowSelectorSelectPortButton.Size = new Size(244, 25);
ShowSelectorSelectPortButton.TabIndex = 1;
ShowSelectorSelectPortButton.Text = "Select Serial Port";
ShowSelectorSelectPortButton.UseVisualStyleBackColor = true;
ShowSelectorSelectPortButton.Click += ShowSelectorSelectPortButton_Click;
//
// ShowSelectorAutoDetectButton
//
ShowSelectorAutoDetectButton.Location = new Point(6, 22);
ShowSelectorAutoDetectButton.Name = "ShowSelectorAutoDetectButton";
ShowSelectorAutoDetectButton.Size = new Size(244, 25);
ShowSelectorAutoDetectButton.TabIndex = 0;
ShowSelectorAutoDetectButton.Text = "Auto Detect";
ShowSelectorAutoDetectButton.UseVisualStyleBackColor = true;
ShowSelectorAutoDetectButton.Click += ShowSelectorAutoDetectButton_Click;
//
// PlaylistGroupBox
//
PlaylistGroupBox.Controls.Add(NewPlaylistButton);
PlaylistGroupBox.Controls.Add(AdvancedSettingsButton);
PlaylistGroupBox.Controls.Add(AddShowButton);
PlaylistGroupBox.Controls.Add(LoadPlaylistButton);
PlaylistGroupBox.Controls.Add(SavePlaylistButton);
PlaylistGroupBox.Location = new Point(12, 254);
PlaylistGroupBox.Name = "PlaylistGroupBox";
PlaylistGroupBox.Size = new Size(256, 116);
PlaylistGroupBox.TabIndex = 3;
PlaylistGroupBox.TabStop = false;
PlaylistGroupBox.Text = "Playlist: Unsaved";
//
// AdvancedSettingsButton
//
AdvancedSettingsButton.Location = new Point(131, 22);
AdvancedSettingsButton.Name = "AdvancedSettingsButton";
AdvancedSettingsButton.Size = new Size(119, 25);
AdvancedSettingsButton.TabIndex = 1;
AdvancedSettingsButton.Text = "Advanced";
AdvancedSettingsButton.UseVisualStyleBackColor = true;
AdvancedSettingsButton.Click += AdvancedSettingsButton_Click;
//
// AddShowButton
//
AddShowButton.Location = new Point(6, 22);
AddShowButton.Name = "AddShowButton";
AddShowButton.Size = new Size(119, 25);
AddShowButton.TabIndex = 0;
AddShowButton.Text = "Add Show";
AddShowButton.UseVisualStyleBackColor = true;
AddShowButton.Click += AddShowButton_Click;
//
// LoadPlaylistButton
//
LoadPlaylistButton.Location = new Point(131, 53);
LoadPlaylistButton.Name = "LoadPlaylistButton";
LoadPlaylistButton.Size = new Size(119, 25);
LoadPlaylistButton.TabIndex = 3;
LoadPlaylistButton.Text = "Load Playlist";
LoadPlaylistButton.UseVisualStyleBackColor = true;
LoadPlaylistButton.Click += LoadPlaylistButton_Click;
//
// SavePlaylistButton
//
SavePlaylistButton.Location = new Point(6, 53);
SavePlaylistButton.Name = "SavePlaylistButton";
SavePlaylistButton.Size = new Size(119, 25);
SavePlaylistButton.TabIndex = 2;
SavePlaylistButton.Text = "Save Playlist";
SavePlaylistButton.UseVisualStyleBackColor = true;
SavePlaylistButton.Click += SavePlaylistButton_Click;
//
// ChannelMappingGroupBox
//
ChannelMappingGroupBox.Controls.Add(LoadChannelMapButton);
ChannelMappingGroupBox.Location = new Point(12, 192);
ChannelMappingGroupBox.Name = "ChannelMappingGroupBox";
ChannelMappingGroupBox.Size = new Size(256, 56);
ChannelMappingGroupBox.TabIndex = 2;
ChannelMappingGroupBox.TabStop = false;
ChannelMappingGroupBox.Text = "Channel Map: None Loaded";
//
// LoadChannelMapButton
//
LoadChannelMapButton.Location = new Point(6, 22);
LoadChannelMapButton.Name = "LoadChannelMapButton";
LoadChannelMapButton.Size = new Size(244, 25);
LoadChannelMapButton.TabIndex = 0;
LoadChannelMapButton.Text = "Load Channel Map";
LoadChannelMapButton.UseVisualStyleBackColor = true;
LoadChannelMapButton.Click += LoadChannelMapButton_Click;
//
// PlaylistListView
//
PlaylistListView.AutoArrange = false;
PlaylistListView.Columns.AddRange(new ColumnHeader[] { NameColumnHeader, LengthColumnHeader });
PlaylistListView.ContextMenuStrip = ShowContextMenu;
PlaylistListView.GridLines = true;
PlaylistListView.HeaderStyle = ColumnHeaderStyle.Nonclickable;
PlaylistListView.Location = new Point(274, 12);
PlaylistListView.MultiSelect = false;
PlaylistListView.Name = "PlaylistListView";
PlaylistListView.Size = new Size(400, 463);
PlaylistListView.TabIndex = 5;
PlaylistListView.UseCompatibleStateImageBehavior = false;
PlaylistListView.View = View.Details;
//
// NameColumnHeader
//
NameColumnHeader.Text = "Show Name";
NameColumnHeader.Width = 310;
//
// LengthColumnHeader
//
LengthColumnHeader.Text = "Length";
//
// ShowContextMenu
//
ShowContextMenu.Items.AddRange(new ToolStripItem[] { MoveUpButton, MoveDownButton, RemoveButton });
ShowContextMenu.Name = "ShowContextMenu";
ShowContextMenu.Size = new Size(139, 70);
//
// MoveUpButton
//
MoveUpButton.Name = "MoveUpButton";
MoveUpButton.Size = new Size(138, 22);
MoveUpButton.Text = "Move Up";
MoveUpButton.Click += MoveUpButton_Click;
//
// MoveDownButton
//
MoveDownButton.Name = "MoveDownButton";
MoveDownButton.Size = new Size(138, 22);
MoveDownButton.Text = "Move Down";
MoveDownButton.Click += MoveDownButton_Click;
//
// RemoveButton
//
RemoveButton.Name = "RemoveButton";
RemoveButton.Size = new Size(138, 22);
RemoveButton.Text = "Remove";
RemoveButton.Click += RemoveButton_Click;
//
// SelectShowFileDialog
//
SelectShowFileDialog.Filter = "UST Showtapes|*.ust";
SelectShowFileDialog.Multiselect = true;
//
// SelectMappingFileDialog
//
SelectMappingFileDialog.Filter = "PinkConnection Channel Map|*.pcm";
//
// SavePlaylistFileDialog
//
SavePlaylistFileDialog.Filter = "PC3Player Playlists (JSON Files)|*.json";
//
// OpenPlaylistFileDialog
//
OpenPlaylistFileDialog.Filter = "PC3Player Playlists (JSON Files)|*.json";
//
// NewPlaylistButton
//
NewPlaylistButton.Location = new Point(6, 84);
NewPlaylistButton.Name = "NewPlaylistButton";
NewPlaylistButton.Size = new Size(244, 25);
NewPlaylistButton.TabIndex = 4;
NewPlaylistButton.Text = "New Playlist";
NewPlaylistButton.UseVisualStyleBackColor = true;
NewPlaylistButton.Click += NewPlaylistButton_Click;
//
// MainForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(686, 487);
Controls.Add(PlaylistListView);
Controls.Add(ChannelMappingGroupBox);
Controls.Add(PlaylistGroupBox);
Controls.Add(ShowSelectorGroupBox);
Controls.Add(PlaybackControlsGroupBox);
Controls.Add(ControllerGroupBox);
FormBorderStyle = FormBorderStyle.FixedSingle;
Icon = (Icon)resources.GetObject("$this.Icon");
MaximizeBox = false;
Name = "MainForm";
Text = "PinkConnection3 Player";
FormClosing += MainForm_FormClosing;
ControllerGroupBox.ResumeLayout(false);
PlaybackControlsGroupBox.ResumeLayout(false);
PlaybackControlsGroupBox.PerformLayout();
ShowSelectorGroupBox.ResumeLayout(false);
PlaylistGroupBox.ResumeLayout(false);
ChannelMappingGroupBox.ResumeLayout(false);
ShowContextMenu.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private GroupBox ControllerGroupBox;
private Button ControllerSelectSerialPortButton;
private Button ControllerAutoDetectButton;
private GroupBox PlaybackControlsGroupBox;
private Button SkipButton;
private Button PauseButton;
private Button StartButton;
private GroupBox ShowSelectorGroupBox;
private Button ShowSelectorSelectPortButton;
private Button ShowSelectorAutoDetectButton;
private GroupBox PlaylistGroupBox;
private Button AddShowButton;
private GroupBox ChannelMappingGroupBox;
private Button LoadChannelMapButton;
private ListView PlaylistListView;
private ColumnHeader NameColumnHeader;
private ColumnHeader LengthColumnHeader;
private Button StopButton;
private Button SavePlaylistButton;
private Button LoadPlaylistButton;
private OpenFileDialog SelectShowFileDialog;
private OpenFileDialog SelectMappingFileDialog;
private Button AdvancedSettingsButton;
private ContextMenuStrip ShowContextMenu;
private ToolStripMenuItem RemoveButton;
private ToolStripMenuItem MoveUpButton;
private ToolStripMenuItem MoveDownButton;
private SaveFileDialog SavePlaylistFileDialog;
private OpenFileDialog OpenPlaylistFileDialog;
private Label TimeLabel;
private Button NewPlaylistButton;
}
}

View file

@ -0,0 +1,900 @@
using SoundFlow.Backends.MiniAudio;
using SoundFlow.Components;
using SoundFlow.Enums;
using SoundFlow.Providers;
using System.Globalization;
using System.IO.Ports;
using System.Numerics;
using System.Text.Json;
using System.Timers;
namespace PC3Player
{
public partial class MainForm : Form
{
static PlaylistConfig Config = new();
static SerialPort ControllerPort;
static SerialPort ShowSelectorPort;
static Random SelectRandom = new Random();
System.Timers.Timer FrameTimer;
System.Timers.Timer ResyncTimer;
System.Timers.Timer GUIUpdateTimer;
SoundPlayer AudioPlayer;
StreamDataProvider dataProvider;
static int ShowtapeIndex = 0;
static int PlaylistIndex = 0;
static int IntermissionSecondsLeft = 0;
static int IntermissionTotalTime = 0;
static int ControllerBits;
static int SelectorButtons;
static bool ControllerConnected = false;
static bool ShowSelectorConnected = false;
public static bool ChannelMappingLoaded = false;
static bool Playing = false;
static bool Paused = false;
static bool InvalidateSave = false;
static bool Intermission;
static string[] ShowtapeFrames;
static PlaylistShow CurrentlyPlaying;
public MainForm()
{
InitializeComponent();
GUIUpdateTimer = new System.Timers.Timer(1000);
GUIUpdateTimer.Elapsed += GUIUpdateTick;
GUIUpdateTimer.AutoReset = true;
MiniAudioEngine audioEngine = new MiniAudioEngine(48000, Capability.Playback);
}
private void UpdateListView()
{
PlaylistListView.Items.Clear();
foreach (PlaylistShow s in Config.Shows) PlaylistListView.Items.Add(new ListViewItem(new[] { s.Name, s.Length }));
}
private void LoadChannelMapButton_Click(object sender, EventArgs e)
{
if (!ControllerConnected)
{
MessageBox.Show("You must connect a Controller first.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (SelectMappingFileDialog.ShowDialog() == DialogResult.OK)
{
string tempMappingData = File.ReadAllText(SelectMappingFileDialog.FileName);
if (!tempMappingData.StartsWith("PC3MAPPING,2,"))
{
MessageBox.Show("Selected mapping file is not a Version 2 PinkConnection channel map.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string[] header = tempMappingData.Split(";")[0].Split(",");
List<int> targetBits = new List<int>();
foreach (string s in tempMappingData.Split(";")[1].Split(","))
{
targetBits.Add(int.Parse(s));
}
if (ChannelMappingLoaded)
{
if (header[3] != Config.Mapping.Type)
{
MessageBox.Show(
$"Selected Channel Map \"{header[2]}\"'s type does not match the old Channel Map's type." +
$"\nOld Channel Map Type: {Config.Mapping.Type}" +
$"\nNew Channel Map Type: {header[3]}"
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
if (targetBits.Count != ControllerBits)
{
MessageBox.Show("The mapped channel count is not equal to the connected controller's bit count.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (targetBits.Count % 4 != 0)
{
MessageBox.Show("The mapped channel count is not divisible by 4.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
List<int> invertedBits = new List<int>();
foreach (string s in tempMappingData.Split(";")[2].Split(","))
{
int ints = int.Parse(s);
if (ints == 0) continue;
invertedBits.Add(ints);
}
Config.Mapping = new ChannelMapping(header[2], header[3], targetBits.ToArray(), invertedBits.ToArray());
ChannelMappingLoaded = true;
ChannelMappingGroupBox.Text = $"Channel Map: {Config.Mapping.Name}";
InvalidateSave = true;
}
}
private void ControllerAutoDetectButton_Click(object sender, EventArgs e)
{
if (ControllerConnected)
{
MessageBox.Show("A Controller is already connected.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
string successPortName = "";
foreach (string portName in SerialPort.GetPortNames())
{
if (ControllerConnected) break;
try
{
SerialPort tempPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
tempPort.Open();
for (int i = 0; i < 10; i++)
{
tempPort.Write("! ");
Thread.Sleep(100);
string readAttempt = tempPort.ReadExisting();
if (readAttempt.Split(",")[0] == "PC3")
{
ControllerBits = int.Parse(readAttempt.Split(",")[1]);
ControllerConnected = true;
tempPort.Close();
ControllerPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
ControllerPort.Open();
successPortName = portName;
break;
}
}
tempPort.Close();
}
catch (Exception) { continue; }
}
if (!ControllerConnected)
{
MessageBox.Show("Could not detect a PinkConnection3 controller on any of your serial ports.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
ControllerGroupBox.Text = $"Controller: {ControllerBits} channel on {successPortName}";
ControllerAutoDetectButton.Enabled = false;
ControllerSelectSerialPortButton.Enabled = false;
}
private void ControllerSelectSerialPortButton_Click(object sender, EventArgs e)
{
if (ControllerConnected)
{
MessageBox.Show("A Controller is already connected.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
SerialPortSelector portDialog = new SerialPortSelector();
if (portDialog.ShowDialog() != DialogResult.OK) return;
string successPortName = "";
try
{
SerialPort tempPort = new SerialPort(portDialog.PortName, 9600, Parity.None, 8, StopBits.One);
tempPort.Open();
for (int i = 0; i < 10; i++)
{
tempPort.Write("! ");
Thread.Sleep(100);
string readAttempt = tempPort.ReadExisting();
if (readAttempt.Split(",")[0] == "PC3")
{
ControllerBits = int.Parse(readAttempt.Split(",")[1]);
ControllerConnected = true;
tempPort.Close();
ControllerPort = new SerialPort(portDialog.PortName, 9600, Parity.None, 8, StopBits.One);
ControllerPort.Open();
successPortName = portDialog.PortName;
break;
}
}
tempPort.Close();
if (!ControllerConnected)
{
MessageBox.Show("Could not detect a PinkConnection3 controller on the specified serial port.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
catch (Exception ex)
{
MessageBox.Show("Could not detect a PinkConnection3 controller on the specified serial port.\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
ControllerGroupBox.Text = $"Controller: {ControllerBits} channel on {successPortName}";
ControllerAutoDetectButton.Enabled = false;
ControllerSelectSerialPortButton.Enabled = false;
}
private void AddShowButton_Click(object sender, EventArgs e)
{
if (!ChannelMappingLoaded)
{
MessageBox.Show("You must load a channel mapping first.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (SelectShowFileDialog.ShowDialog() == DialogResult.OK)
{
foreach (string showFilePath in SelectShowFileDialog.FileNames)
{
string tempUSTData = File.ReadAllText(showFilePath);
if (!tempUSTData.StartsWith("UST,2,"))
{
MessageBox.Show($"Selected showtape \"{Path.GetFileNameWithoutExtension(showFilePath)}\" is not a UST version 2 showtape.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string[] headerData = tempUSTData.Split(';')[0].Split(',');
string[] stringyBits = tempUSTData.Split(';')[1].Split(',');
TimeSpan time = TimeSpan.FromSeconds(stringyBits.Length / 60);
string formattedLength = time.ToString(@"hh\:mm\:ss");
tempUSTData = null;
stringyBits = null;
if (headerData[3] != Config.Mapping.Type)
{
MessageBox.Show(
$"Selected Show \"{headerData[2]}\"'s type does not match the loaded Channel Map." +
$"\nLoaded Channel Map Type: {Config.Mapping.Type}" +
$"\nShow Type: {headerData[3]}"
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Config.Shows.Add(new PlaylistShow(headerData[2], formattedLength, headerData[3], showFilePath));
}
UpdateListView();
InvalidateSave = true;
}
}
private void RemoveButton_Click(object sender, EventArgs e)
{
if (PlaylistListView.SelectedIndices.Count == 0) return;
Config = RemoveShowAt(PlaylistListView.SelectedIndices[0], Config);
UpdateListView();
InvalidateSave = true;
}
private void MoveUpButton_Click(object sender, EventArgs e)
{
if (PlaylistListView.SelectedIndices.Count == 0) return;
int selectedIndex = PlaylistListView.SelectedIndices[0];
if (selectedIndex == 0) return;
int assindex = 0;
foreach (int? assignment in Config.SelectorAssignments)
{
if (assignment == null) continue;
if (assignment == selectedIndex) Config.SelectorAssignments[assindex]--;
if (assignment == selectedIndex - 1) Config.SelectorAssignments[assindex]++;
assindex++;
}
PlaylistShow temp = Config.Shows[selectedIndex];
Config.Shows.RemoveAt(selectedIndex);
Config.Shows.Insert(selectedIndex - 1, temp);
UpdateListView();
InvalidateSave = true;
}
private void MoveDownButton_Click(object sender, EventArgs e)
{
if (PlaylistListView.SelectedIndices.Count == 0) return;
int selectedIndex = PlaylistListView.SelectedIndices[0];
if (selectedIndex >= PlaylistListView.Items.Count - 1) return;
int assindex = 0;
foreach (int? assignment in Config.SelectorAssignments)
{
if (assignment == null) continue;
if (assignment == selectedIndex) Config.SelectorAssignments[assindex]++;
if (assignment == selectedIndex + 1) Config.SelectorAssignments[assindex]--;
assindex++;
}
PlaylistShow temp = Config.Shows[selectedIndex];
Config.Shows.RemoveAt(selectedIndex);
Config.Shows.Insert(selectedIndex + 1, temp);
UpdateListView();
InvalidateSave = true;
}
private void AdvancedSettingsButton_Click(object sender, EventArgs e)
{
AdvancedSettingsForm advancedSettingsForm = new AdvancedSettingsForm(Config);
if (Config != advancedSettingsForm.EditingObject) InvalidateSave = true;
if (advancedSettingsForm.ShowDialog() == DialogResult.OK) Config = advancedSettingsForm.EditingObject;
}
private void ShowSelectorAutoDetectButton_Click(object sender, EventArgs e)
{
if (ShowSelectorConnected)
{
MessageBox.Show("A Show Selector is already connected.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
string successPortName = "";
foreach (string portName in SerialPort.GetPortNames())
{
if (ShowSelectorConnected) break;
try
{
SerialPort tempPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
tempPort.Open();
for (int i = 0; i < 10; i++)
{
tempPort.Write("\" ");
Thread.Sleep(100);
string readAttempt = tempPort.ReadExisting();
if (readAttempt.Split(",")[0] == "PCSELECTOR")
{
SelectorButtons = int.Parse(readAttempt.Split(",")[1]);
ShowSelectorConnected = true;
tempPort.Close();
ShowSelectorPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
ShowSelectorPort.Open();
successPortName = portName;
break;
}
}
tempPort.Close();
}
catch (Exception) { continue; }
}
if (!ShowSelectorConnected)
{
MessageBox.Show("Could not detect a PinkConnection Show Selector on any of your serial ports.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
ShowSelectorGroupBox.Text = $"{SelectorButtons} button on {successPortName}";
ShowSelectorAutoDetectButton.Enabled = false;
ShowSelectorSelectPortButton.Enabled = false;
}
private void ShowSelectorSelectPortButton_Click(object sender, EventArgs e)
{
if (ShowSelectorConnected)
{
MessageBox.Show("A Show Selector is already connected.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
SerialPortSelector portDialog = new SerialPortSelector();
if (portDialog.ShowDialog() != DialogResult.OK) return;
string successPortName = "";
try
{
SerialPort tempPort = new SerialPort(portDialog.PortName, 9600, Parity.None, 8, StopBits.One);
tempPort.Open();
for (int i = 0; i < 10; i++)
{
tempPort.Write("\" ");
Thread.Sleep(100);
string readAttempt = tempPort.ReadExisting();
if (readAttempt.Split(",")[0] == "PCSELECTOR")
{
SelectorButtons = int.Parse(readAttempt.Split(",")[1]);
ShowSelectorConnected = true;
tempPort.Close();
ShowSelectorPort = new SerialPort(portDialog.PortName, 9600, Parity.None, 8, StopBits.One);
ShowSelectorPort.Open();
successPortName = portDialog.PortName;
break;
}
}
tempPort.Close();
if (!ShowSelectorConnected)
{
MessageBox.Show("Could not detect a PinkConnection Show Selector on the specified serial port.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
catch (Exception ex)
{
MessageBox.Show("Could not detect a PinkConnection Show Selector on the specified serial port.\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
ShowSelectorGroupBox.Text = $"Show Selector: {SelectorButtons} button on {successPortName}";
ShowSelectorAutoDetectButton.Enabled = false;
ShowSelectorSelectPortButton.Enabled = false;
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (Playing) Stop();
if (InvalidateSave)
if (MessageBox.Show(
"You have an unsaved Playlist!\nDo you still want to exit?",
"Unsaved Playlist",
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation
) != DialogResult.Yes)
e.Cancel = true;
}
private void SavePlaylistButton_Click(object sender, EventArgs e)
{
if (SavePlaylistFileDialog.ShowDialog() == DialogResult.OK)
{
File.WriteAllText(SavePlaylistFileDialog.FileName, JsonSerializer.Serialize<PlaylistConfig>(Config));
InvalidateSave = false;
PlaylistGroupBox.Text = "Playlist: " + Path.GetFileNameWithoutExtension(SavePlaylistFileDialog.FileName);
}
}
private void LoadPlaylistButton_Click(object sender, EventArgs e)
{
if (Playing)
{
if (MessageBox.Show(
"A show is currently playing!\nPerforming this action will stop it.\nAre you sure?",
"Show Playing",
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation
) != DialogResult.Yes)
return;
Stop();
}
if (!ControllerConnected)
{
MessageBox.Show("You must connect a Controller first.");
return;
}
if (InvalidateSave)
if (MessageBox.Show(
"You have an unsaved Playlist!\nDo you still want to load another?",
"Unsaved Playlist",
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation
) != DialogResult.Yes)
return;
if (OpenPlaylistFileDialog.ShowDialog() == DialogResult.OK)
{
PlaylistConfig? tempConfig;
try
{
tempConfig = JsonSerializer.Deserialize<PlaylistConfig>(File.ReadAllText(OpenPlaylistFileDialog.FileName));
}
catch (Exception ex)
{
MessageBox.Show("Could not read the selected Playlist file.\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (tempConfig == null)
{
MessageBox.Show("Could not read the selected Playlist file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (tempConfig.Mapping != null)
{
if (tempConfig.Mapping.Bits.Length % 4 != 0)
{
MessageBox.Show("The mapped channel count is not divisible by 4.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
ChannelMappingGroupBox.Text = $"Channel Map: {tempConfig.Mapping.Name}";
ChannelMappingLoaded = true;
}
int showIndex = 0;
foreach (PlaylistShow show in tempConfig.Shows)
{
if (tempConfig.Mapping == null)
{
MessageBox.Show(
"The Playlist does not have a loaded Channel Map" +
"\nNo Shows or Skits will be loaded."
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
break;
}
if (!File.Exists(show.FilePath))
{
if (MessageBox.Show(
$"Could not locate the file for the Show {show.Name}" +
$"\nWould you like to relocate it?",
"Could not find Show file",
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation
) == DialogResult.Yes)
{
if (SelectShowFileDialog.ShowDialog() == DialogResult.OK)
{
tempConfig.Shows[showIndex].FilePath = SelectShowFileDialog.FileName;
}
else tempConfig = RemoveShowAt(showIndex, tempConfig);
}
else tempConfig = RemoveShowAt(showIndex, tempConfig);
}
if (show.Type != tempConfig.Mapping.Type)
{
MessageBox.Show(
$"Show \"{show.Name}\"'s type does not match the Playlist's Channel Map." +
$"\nIt will be removed from the playlist." +
$"\nLoaded Channel Map Type: {tempConfig.Mapping.Type}" +
$"\nShow Type: {show.Type}"
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
tempConfig = RemoveShowAt(showIndex, tempConfig);
}
showIndex++;
}
int skitIndex = 0;
foreach (PlaylistShow skit in tempConfig.Skits)
{
if (tempConfig.Mapping == null) break;
if (!File.Exists(skit.FilePath))
{
if (MessageBox.Show(
$"Could not locate the file for the Skit {skit.Name}" +
$"\nWould you like to relocate it?",
"Could not find Skit file",
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation
) == DialogResult.Yes)
{
if (SelectShowFileDialog.ShowDialog() == DialogResult.OK)
{
tempConfig.Skits[skitIndex].FilePath = SelectShowFileDialog.FileName;
}
else tempConfig.Skits.RemoveAt(skitIndex);
}
else tempConfig.Skits.RemoveAt(skitIndex);
}
if (skit.Type != tempConfig.Mapping.Type)
{
MessageBox.Show(
$"Skit \"{skit.Name}\"'s type does not match the Playlist's Channel Map." +
$"\nIt will be removed from the playlist." +
$"\nLoaded Channel Map Type: {tempConfig.Mapping.Type}" +
$"\nSkit Type: {skit.Type}"
, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
tempConfig.Skits.RemoveAt(skitIndex);
}
skitIndex++;
}
Config = tempConfig;
PlaylistGroupBox.Text = "Playlist: " + Path.GetFileNameWithoutExtension(OpenPlaylistFileDialog.FileName);
UpdateListView();
InvalidateSave = false;
}
}
private PlaylistConfig RemoveShowAt(int position, PlaylistConfig pcfg)
{
int assindex = 0;
foreach (int? assignment in pcfg.SelectorAssignments)
{
if (assignment == null) continue;
if (assignment == position) pcfg.SelectorAssignments[assindex] = null;
if (assignment > position) pcfg.SelectorAssignments[assindex]--;
assindex++;
}
pcfg.Shows.RemoveAt(position);
return pcfg;
}
private void LoadNextShowtape()
{
string tempUSTData = File.ReadAllText(CurrentlyPlaying.FilePath);
if (!tempUSTData.StartsWith("UST,2,"))
{
MessageBox.Show($"Selected showtape \"{Path.GetFileNameWithoutExtension(CurrentlyPlaying.FilePath)}\" is not a UST version 2 showtape.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
string[] stringyBits = tempUSTData.Split(';')[1].Split(',');
if (File.Exists("pc3playertempaudio.tmp")) File.Delete("pc3playertempaudio.tmp");
File.WriteAllBytes("pc3playertempaudio.tmp", Convert.FromBase64String(tempUSTData.Split(';')[2]));
tempUSTData = null;
List<string> tempShowData = new List<string>();
foreach (string stringyFrame in stringyBits)
{
BigInteger frame = BigInteger.Parse(stringyFrame, NumberStyles.HexNumber);
int selectBit = 0;
char[] frameStringOut = new char[64];
for (int i = 0; i < Config.Mapping.Bits.Count() / 4; i++)
{
byte quartet = 64;
for (int j = 0; j < 4; j++)
{
if (Config.Mapping.Bits[selectBit] == 0) continue;
if (Config.Mapping.InvertedBits.Contains(Config.Mapping.Bits[selectBit])) { if (!((frame & BigInteger.Pow(2, Config.Mapping.Bits[selectBit] - 1)) == BigInteger.Pow(2, Config.Mapping.Bits[selectBit] - 1))) quartet += (byte)Math.Pow(2, j); }
else { if ((frame & BigInteger.Pow(2, Config.Mapping.Bits[selectBit] - 1)) == BigInteger.Pow(2, Config.Mapping.Bits[selectBit] - 1)) quartet += (byte)Math.Pow(2, j); }
selectBit++;
}
frameStringOut[i] = (char)quartet;
}
tempShowData.Add(new string(frameStringOut).Trim());
}
ShowtapeFrames = tempShowData.ToArray();
}
private void SelectNextShowtape(StartMethod method)
{
ShowtapeFrames = [];
ShowtapeIndex = 0;
if (Config.Shows.Count() == 0)
{
MessageBox.Show("There are no shows in the playlist.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
bool willStartShow = false;
bool bypassIntermission = false;
if (Intermission)
{
Intermission = false;
bypassIntermission = true;
GUIUpdateTimer.Stop();
}
switch (method)
{
case StartMethod.PlaylistStart:
switch (Config.PlaylistStartOption)
{
case 0:
PlaylistIndex = 0;
willStartShow = true;
break;
case 1:
PlaylistIndex = SelectRandom.Next(Config.Shows.Count());
willStartShow = true;
break;
}
break;
case StartMethod.PlaylistShowEnd:
if (Config.PlaylistIntermissionOption && (!bypassIntermission))
{
Intermission = true;
IntermissionTotalTime = IntermissionSecondsLeft = Config.PlaylistIntermissionTimeOption * ((Config.PlaylistIntermissionUnitOption == 1) ? 1 : 60);
SkipButton.Enabled = true;
StopButton.Enabled = true;
PauseButton.Enabled = true;
Invoke(delegate { PlaybackControlsGroupBox.Text = "Controls: Intermission"; });
GUIUpdateTimer.Start();
}
else
{
switch (Config.PlaylistShowEndOption)
{
case 0:
PlaylistIndex++;
if (PlaylistIndex >= Config.Shows.Count())
{
if (Config.PlaylistLoopOption)
{
PlaylistIndex = 0;
willStartShow = true;
}
}
else willStartShow = true;
break;
case 1:
PlaylistIndex = SelectRandom.Next(Config.Shows.Count());
willStartShow = true;
break;
case 2:
willStartShow = true;
break;
case 3:
break;
}
}
break;
}
if (willStartShow)
{
CurrentlyPlaying = Config.Shows[PlaylistIndex];
LoadNextShowtape();
FrameTimer = new System.Timers.Timer((1000d / 60d) * Config.FramesPerTick);
FrameTimer.Elapsed += PlayFrame;
FrameTimer.AutoReset = true;
ResyncTimer = new System.Timers.Timer(Config.ResyncSeconds * 1000);
ResyncTimer.Elapsed += Resync;
ResyncTimer.AutoReset = true;
dataProvider = new StreamDataProvider(File.OpenRead("pc3playertempaudio.tmp"));
AudioPlayer = new SoundPlayer(dataProvider);
Invoke(delegate { PlaybackControlsGroupBox.Text = $"Controls: Playing {CurrentlyPlaying.Name}"; });
Mixer.Master.AddComponent(AudioPlayer);
Playing = true;
AudioPlayer.Play();
FrameTimer.Start();
ResyncTimer.Start();
GUIUpdateTimer.Start();
PauseButton.Enabled = true;
StopButton.Enabled = true;
SkipButton.Enabled = true;
}
}
void GUIUpdateTick(object sender, ElapsedEventArgs e)
{
if (Playing)
{
Invoke(delegate { TimeLabel.Text = $"({TimeSpan.FromSeconds(AudioPlayer.Time).ToString(@"hh\:mm\:ss")}/{CurrentlyPlaying.Length})"; });
}
if (Intermission)
{
if (IntermissionSecondsLeft == 0) SelectNextShowtape(StartMethod.PlaylistShowEnd);
Invoke(delegate { TimeLabel.Text = $"({TimeSpan.FromSeconds(IntermissionTotalTime - IntermissionSecondsLeft).ToString(@"hh\:mm\:ss")}/{TimeSpan.FromSeconds(IntermissionTotalTime).ToString(@"hh\:mm\:ss")})"; });
if (!Paused) IntermissionSecondsLeft--;
}
}
void PlayFrame(object sender, ElapsedEventArgs e)
{
if (ShowtapeIndex + Config.FrameShift >= ShowtapeFrames.Length)
{
Stop();
SelectNextShowtape(StartMethod.PlaylistShowEnd);
return;
}
ControllerPort.Write(ShowtapeFrames[ShowtapeIndex + Config.FrameShift]);
ShowtapeIndex += Config.FramesPerTick;
}
void Resync(object sender, ElapsedEventArgs e)
{
ShowtapeIndex = (int)(AudioPlayer.Time * 60f);
}
private void PauseButton_Click(object sender, EventArgs e)
{
if (Paused)
{
Paused = false;
PauseButton.Text = "Pause";
if (Playing)
{
FrameTimer.Start();
ResyncTimer.Start();
AudioPlayer.Seek((float)(((float)ShowtapeIndex) / 60.0));
AudioPlayer.Play();
}
}
else
{
Paused = true;
PauseButton.Text = "Unpause";
if (Playing)
{
FrameTimer.Stop();
ResyncTimer.Stop();
AudioPlayer.Pause();
}
}
}
private void StopButton_Click(object sender, EventArgs e)
{
Stop();
}
private void SkipButton_Click(object sender, EventArgs e)
{
if (Playing) Stop();
SelectNextShowtape(StartMethod.PlaylistShowEnd);
}
private void StartButton_Click(object sender, EventArgs e)
{
if (Playing)
{
if (MessageBox.Show(
"A show is currently playing!\nPerforming this action will stop it.\nAre you sure?",
"Show Playing",
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation
) != DialogResult.Yes)
return;
Stop();
}
SelectNextShowtape(StartMethod.PlaylistStart);
}
void Stop()
{
Playing = false;
AudioPlayer.Stop();
FrameTimer.Stop();
ResyncTimer.Stop();
GUIUpdateTimer.Stop();
ResyncTimer.Dispose();
FrameTimer.Dispose();
PauseButton.Enabled = false;
StopButton.Enabled = false;
SkipButton.Enabled = false;
if (Playing) Mixer.Master.RemoveComponent(AudioPlayer);
Paused = false;
Invoke(delegate
{
PlaybackControlsGroupBox.Text = "Controls: Not Playing";
PauseButton.Text = "Pause";
TimeLabel.Text = "(00:00:00/00:00:00)";
});
dataProvider.Dispose();
if (File.Exists("pc3playertempaudio.tmp")) File.Delete("pc3playertempaudio.tmp");
ShowtapeFrames = [];
ShowtapeIndex = 0;
}
private void NewPlaylistButton_Click(object sender, EventArgs e)
{
if (Playing)
{
if (MessageBox.Show(
"A show is currently playing!\nPerforming this action will stop it.\nAre you sure?",
"Show Playing",
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation
) != DialogResult.Yes)
return;
Stop();
}
if (InvalidateSave)
if (MessageBox.Show(
"You have an unsaved Playlist!\nDo you still want to create a new one?",
"Unsaved Playlist",
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation
) != DialogResult.Yes)
return;
Config = new PlaylistConfig();
ChannelMappingGroupBox.Text = "Channel Map: None Loaded";
PlaylistGroupBox.Text = "Playlist: Unsaved";
UpdateListView();
InvalidateSave = false;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Content Include="icon.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SoundFlow" Version="1.1.1" />
<PackageReference Include="System.IO.Ports" Version="9.0.6" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_LastSelectedProfileId>C:\Users\Persephone\source\repos\PC3Player\PC3Player\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
</PropertyGroup>
<ItemGroup>
<Compile Update="AdvancedSettingsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="SerialPortSelector.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project>

View file

@ -0,0 +1,17 @@
namespace PC3Player
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new MainForm());
}
}
}

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\net8.0-windows\publish\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net8.0-windows</TargetFramework>
<SelfContained>false</SelfContained>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<History>True|2025-07-08T03:32:00.3108399Z||;True|2025-07-07T16:13:43.3420483-07:00||;</History>
<LastFailureDetails />
</PropertyGroup>
</Project>

View file

@ -0,0 +1,114 @@
namespace PC3Player
{
partial class SerialPortSelector
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
label1 = new Label();
PortDropDown = new ComboBox();
CancelButton = new Button();
OKButton = new Button();
panel1 = new Panel();
panel1.SuspendLayout();
SuspendLayout();
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(12, 15);
label1.Name = "label1";
label1.Size = new Size(29, 15);
label1.TabIndex = 0;
label1.Text = "Port";
//
// PortDropDown
//
PortDropDown.DropDownStyle = ComboBoxStyle.DropDownList;
PortDropDown.FormattingEnabled = true;
PortDropDown.Location = new Point(47, 12);
PortDropDown.Name = "PortDropDown";
PortDropDown.Size = new Size(191, 23);
PortDropDown.TabIndex = 1;
//
// CancelButton
//
CancelButton.DialogResult = DialogResult.Cancel;
CancelButton.Location = new Point(82, 13);
CancelButton.Name = "CancelButton";
CancelButton.Size = new Size(75, 25);
CancelButton.TabIndex = 2;
CancelButton.Text = "Cancel";
CancelButton.UseVisualStyleBackColor = true;
//
// OKButton
//
OKButton.DialogResult = DialogResult.OK;
OKButton.Location = new Point(163, 13);
OKButton.Name = "OKButton";
OKButton.Size = new Size(75, 25);
OKButton.TabIndex = 3;
OKButton.Text = "OK";
OKButton.UseVisualStyleBackColor = true;
OKButton.Click += OKButton_Click;
//
// panel1
//
panel1.BackColor = SystemColors.MenuBar;
panel1.Controls.Add(OKButton);
panel1.Controls.Add(CancelButton);
panel1.Location = new Point(0, 50);
panel1.Name = "panel1";
panel1.Size = new Size(250, 50);
panel1.TabIndex = 4;
//
// SerialPortSelector
//
AcceptButton = OKButton;
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(250, 100);
Controls.Add(panel1);
Controls.Add(PortDropDown);
Controls.Add(label1);
FormBorderStyle = FormBorderStyle.FixedDialog;
Name = "SerialPortSelector";
Text = "Select a Serial Port";
Load += SerialPortSelector_Load;
panel1.ResumeLayout(false);
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label label1;
private ComboBox PortDropDown;
private Button CancelButton;
private Button OKButton;
private Panel panel1;
}
}

View file

@ -0,0 +1,24 @@
using System.IO.Ports;
namespace PC3Player
{
public partial class SerialPortSelector : Form
{
public string PortName { get; set; }
public SerialPortSelector()
{
InitializeComponent();
}
private void SerialPortSelector_Load(object sender, EventArgs e)
{
PortDropDown.Items.Clear();
foreach (string port in SerialPort.GetPortNames()) PortDropDown.Items.Add(port);
}
private void OKButton_Click(object sender, EventArgs e)
{
PortName = (string)PortDropDown.SelectedItem;
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

View file

@ -1,3 +1,3 @@
# PinkConnection2
# PinkConnection
Software for use with PinkConnection2 Animatronic Controllers
Software for use with PinkConnection Animatronic Controllers

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;