Skip to content

Commit

Permalink
New V01.00 master merged
Browse files Browse the repository at this point in the history
  • Loading branch information
ff committed Dec 12, 2023
2 parents 26cded2 + b15298f commit ac9edad
Show file tree
Hide file tree
Showing 36 changed files with 2,298 additions and 309 deletions.
26 changes: 24 additions & 2 deletions APC.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2093,7 +2093,7 @@ void AddBlinkLamp(byte Lamp, unsigned int Period) {
BlinkTimers++; // increase the number of blink timers
BlinkTimer[x] = ActivateTimer(Period, x, BlinkLamps);}}} // start a timer and store it's number

void RemoveBlinkLamp(byte LampNo) { // stop the lamp from blinking
void RemoveBlinkLamp(byte LampNo) { // stop the blinking of LampNo
byte a = 0;
byte b = 0;
byte x = 0;
Expand All @@ -2103,7 +2103,7 @@ void RemoveBlinkLamp(byte LampNo) { // stop the lamp from blin
y = 0;
if (BlinkTimer[x]) { // blink timer in use found?
a++; // increase the number of active blink timers found
while (b < BlinkingNo[x]){ // check the list of lamps controlled by this timer
while (b < BlinkingNo[x]) { // check the list of lamps controlled by this timer
if (BlinkingLamps[x][y]) { // active lamp found?
b++; // increase the number of active lamps found for this blink timer
if (BlinkingLamps[x][y] == LampNo) { // is it the lamp to be removed?
Expand All @@ -2122,6 +2122,28 @@ void RemoveBlinkLamp(byte LampNo) { // stop the lamp from blin
if (x > 64) { // max 64 blink timers possible (starting from 1)
ErrorHandler(8,0,LampNo);}}} // show error 8

void StopAllBlinkLamps() { // stop the blinking of all lamps
byte x = 0;
byte y = 0;
while (BlinkTimers) { // search all active blink timers
y = 0;
if (BlinkTimer[x]) { // blink timer in use found?
while (BlinkingNo[x]) { // check the list of lamps controlled by this timer
if (BlinkingLamps[x][y]) { // active lamp found?
TurnOffLamp(BlinkingLamps[x][y]); // turn it off
BlinkingLamps[x][y] = 0; // delete it from the list
BlinkingNo[x]--; // decrease the number of lamps controlled by this timer
if (!BlinkingNo[x]) { // = 0?
KillTimer(BlinkTimer[x]); // kill the timer
BlinkTimer[x] = 0; // delete it from the list
BlinkTimers--;}} // decrease the number of blink timers
y++; // increase the counter for the list of this blink timer
if (y > 64) { // max 64 lamps existing (starting from 1)
ErrorHandler(12,BlinkTimer[x],0);}}} // show error 7
x++; // increase the counter for the list of active blink timers
if (x > 64) { // max 64 blink timers possible (starting from 1)
ErrorHandler(13,0,0);}}} // show error 8

void ErrorHandler(unsigned int Error, unsigned int Number2, unsigned int Number3) {
WriteUpper2("ERROR "); // Show Error Message
WriteLower2(" ");
Expand Down
280 changes: 268 additions & 12 deletions BlackKnight.ino
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ void BK_AttractNumCycle(byte Step) {
Timer0 = ActivateTimer(3000, Step, BK_AttractNumCycle);} // come back for the next 'page'

void BK_AttractDisplayCycle(byte Step) {
static byte Count = 0;
static byte Timer0 = 0;
static byte Timer1 = 0;
static byte Timer2 = 0;
Expand All @@ -360,15 +361,33 @@ void BK_AttractDisplayCycle(byte Step) {
RemoveBlinkLamp(6);
return;
case 1: // attract mode title 'page'
WriteUpper2(" THE ");
Timer1 = ActivateTimer(50, 5, BK_AttractDisplayCycle);
Timer3 = ActivateTimer(900, 7, BK_AttractDisplayCycle);
WriteLower2(" BLACK KNIGHT ");
Timer2 = ActivateTimer(1400, 6, BK_AttractDisplayCycle);
if (NoPlayers) { // if there were no games before skip the next step
Step++;}
if (Count == 2) {
if (APC_settings[Volume]) { // system set to digital volume control?
analogWrite(VolumePin,255-APC_settings[Volume]);} // adjust PWM to volume setting
else {
digitalWrite(VolumePin,HIGH);} // turn off the digital volume control
Count++;
Step = 0;
Timer0 = 0;
ShowLampPatterns(0); // stop lamp animations
BK_AttractDisplayCycle(0); // stop display animations
for (byte i=0; i< 8; i++) {
LampColumns[i] = 0;}
LampPattern = LampColumns;
BK_RulesDisplay(1);
Count = 0;
return;}
else {
Step = 3;}
Count++;
WriteUpper2(" THE ");
Timer1 = ActivateTimer(50, 5, BK_AttractDisplayCycle);
Timer3 = ActivateTimer(900, 7, BK_AttractDisplayCycle);
WriteLower2(" BLACK KNIGHT ");
Timer2 = ActivateTimer(1400, 6, BK_AttractDisplayCycle);
if (NoPlayers) { // if there were no games before skip the next step
Step++;}
else {
Step = 3;}}
break;
case 2: // show scores of previous game
WriteUpper2(" "); // erase display
Expand Down Expand Up @@ -448,10 +467,11 @@ void BK_AttractModeSW(byte Event) { // Attract Mode switch beh
RemoveBlinkLamp(6); // stop blinking of Highest Score lamp
StrobeLights(0);
ShowLampPatterns(0); // stop lamp animations
if (APC_settings[0]) { // check display setting
BK_AttractNumCycle(0);} // stop Sys7 standard animation
else { // it's the 4Alpha + Credit display
BK_AttractDisplayCycle(0);} // stop animation
if (APC_settings[0]) { // check display setting
BK_AttractNumCycle(0);} // stop Sys7 standard animation
else { // it's the 4Alpha + Credit display
BK_AttractDisplayCycle(0);} // stop animation
BK_RulesDisplay(0);
BK_TestMode_Enter();
break;
case 3: // start game
Expand All @@ -468,6 +488,7 @@ void BK_AttractModeSW(byte Event) { // Attract Mode switch beh
BK_AttractNumCycle(0);} // stop Sys7 standard animation
else { // it's the 4Alpha + Credit display
BK_AttractDisplayCycle(0);} // stop animation
BK_RulesDisplay(0);
if (APC_settings[Volume]) { // system set to digital volume control?
analogWrite(VolumePin,255-APC_settings[Volume]);} // adjust PWM to volume setting
else {
Expand Down Expand Up @@ -2085,6 +2106,241 @@ void BK_HandleVolumeSetting(bool change) {
PlayMusic(50, "BK_M01.snd");}
analogWrite(VolumePin,255-APC_settings[Volume]-SettingsPointer[AppByte]);}} // adjust PWM to volume setting

void BK_RulesEffect(byte State) {
const byte Pattern[22] = {4,0,4,8,12,9,12,11,44,11,108,11,124,43,125,59,125,187,127,187,127,191};
for (byte i=0; i<15; i++) {
if (i == 7) {
continue;}
if (!(*(DisplayUpper+2+2*i)) && !(*(DisplayUpper+3+2*i))) {
continue;}
if (State < 11) {
*(DisplayUpper+2+2*i) = *(DisplayUpper+2+2*i) | Pattern[2*State];
*(DisplayUpper+3+2*i) = *(DisplayUpper+3+2*i) | Pattern[2*State+1];}
else {
*(DisplayUpper+2+2*i) = *(DisplayUpper+2+2*i) & (255 - Pattern[2*(State-11)]);
*(DisplayUpper+3+2*i) = *(DisplayUpper+3+2*i) & (255 - Pattern[2*(State-11)+1]);}}
if (State < 22) {
ActivateTimer(30, State+1, BK_RulesEffect);}}

void BK_RulesDisplay(byte State) {
static byte Timer = 0;
switch(State) {
case 0:
if (Timer) {
KillTimer(Timer);}
Timer = 0;
StopAllBlinkLamps();
ReleaseSolenoid(11);
break;
case 1:
if (Timer) {
return;}
ActivateSolenoid(0, 11);
/* no break */
case 3:
case 5:
case 7:
WriteUpper(" BLACK KNIGHT ");
WriteLower("RULES-- ");
PlaySound(50, "0_6f.snd");
Timer = ActivateTimer(300, State+1, BK_RulesDisplay);
break;
case 9:
WriteUpper(" BLACK KNIGHT ");
WriteLower("RULES-- ");
PlaySound(50, "0_6f.snd");
Timer = ActivateTimer(2000, State+1, BK_RulesDisplay);
break;
case 2:
case 4:
case 6:
case 8:
case 10:
WriteUpper(" ");
WriteLower(" ");
Timer = ActivateTimer(300, State+1, BK_RulesDisplay);
break;
case 11:
digitalWrite(VolumePin,HIGH); // mute sound
WriteUpper(" DROP TARGETS");
WriteLower(" ");
for (byte i=0; i<4; i++) {
AddBlinkLamp(17+i, 100);}
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 12:
WriteUpper(" LITE ");
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 13:
WriteUpper(" ARROWS AND ");
for (byte i=0; i<3; i++) {
AddBlinkLamp(25+i, 100);
AddBlinkLamp(29+i, 100);
AddBlinkLamp(33+i, 100);
AddBlinkLamp(37+i, 100);}
for (byte i=0; i<4; i++) {
RemoveBlinkLamp(17+i);}
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 14:
WriteUpper(" MAGNA SAVE ");
*(DisplayUpper+13*2) = 128 | *(DisplayUpper+13*2);
*(DisplayUpper+13*2+1) = 64 | *(DisplayUpper+13*2+1); // add a dot in column 12
AddBlinkLamp(9, 100);
AddBlinkLamp(10, 100);
for (byte i=0; i<3; i++) {
RemoveBlinkLamp(25+i);
RemoveBlinkLamp(29+i);
RemoveBlinkLamp(33+i);
RemoveBlinkLamp(37+i);}
Timer = ActivateTimer(2700, State+1, BK_RulesDisplay);
break;
case 15:
Timer = ActivateTimer(800, State+1, BK_RulesDisplay);
BK_RulesEffect(0);
break;
case 16:
WriteUpper(" ALL UPPER ");
for (byte i=0; i<3; i++) {
AddBlinkLamp(33+i, 100);
AddBlinkLamp(37+i, 100);}
RemoveBlinkLamp(9);
RemoveBlinkLamp(10);
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 17:
WriteUpper(" OR LOWER ");
WriteLower(" ARROWS ");
for (byte i=0; i<3; i++) {
AddBlinkLamp(25+i, 100);
AddBlinkLamp(29+i, 100);
RemoveBlinkLamp(33+i);
RemoveBlinkLamp(37+i);}
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 18:
WriteUpper(" LITE ");
WriteLower(" ");
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 19:
WriteUpper(" EXTRA BALL ");
*(DisplayUpper+14*2) = 128 | *(DisplayUpper+14*2);
*(DisplayUpper+14*2+1) = 64 | *(DisplayUpper+14*2+1); // add a dot in column 13
AddBlinkLamp(22, 100);
AddBlinkLamp(41, 100);
for (byte i=0; i<3; i++) {
RemoveBlinkLamp(25+i);
RemoveBlinkLamp(29+i);}
Timer = ActivateTimer(2700, State+1, BK_RulesDisplay);
break;
case 20:
Timer = ActivateTimer(800, State+1, BK_RulesDisplay);
BK_RulesEffect(0);
break;
case 21:
WriteUpper(" LOCK 2 BALLS ");
AddBlinkLamp(24, 100);
RemoveBlinkLamp(22);
RemoveBlinkLamp(41);
BK_LockChaseLight(1);
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 22:
WriteUpper(" FOR DOUBLE ");
AddBlinkLamp(28, 100);
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 23:
WriteUpper(" AND 3 BALLS ");
RemoveBlinkLamp(24);
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 24:
WriteUpper("FOR 3X SCORE ");
*(DisplayUpper+14*2) = 128 | *(DisplayUpper+14*2);
*(DisplayUpper+14*2+1) = 64 | *(DisplayUpper+14*2+1); // add a dot in column 13
AddBlinkLamp(32, 100);
RemoveBlinkLamp(28);
BK_LockChaseLight(0);
TurnOffLamp(21);
TurnOffLamp(40);
TurnOffLamp(42);
Timer = ActivateTimer(2700, State+1, BK_RulesDisplay);
break;
case 25:
if (game_settings[BK_MultiballJackpot]) {
Timer = ActivateTimer(800, State+1, BK_RulesDisplay);}
else {
Timer = ActivateTimer(800, 42, BK_RulesDisplay);}
BK_RulesEffect(0);
break;
case 26:
WriteUpper(" DURING ");
RemoveBlinkLamp(32);
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 27:
WriteUpper(" MULTIBALL ");
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 28:
WriteUpper(" EJECT HOLE ");
AddBlinkLamp(24, 100);
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 29:
WriteUpper(" LITES JACKPOT");
*(DisplayUpper+15*2) = 128 | *(DisplayUpper+15*2);
*(DisplayUpper+15*2+1) = 64 | *(DisplayUpper+15*2+1); // add a dot in column 14
Timer = ActivateTimer(2700, State+1, BK_RulesDisplay);
break;
case 30:
Timer = ActivateTimer(800, State+1, BK_RulesDisplay);
BK_RulesEffect(0);
break;
case 31:
WriteUpper(" SHOOT LOCK ");
RemoveBlinkLamp(24);
BK_LockChaseLight(1);
Timer = ActivateTimer(2500, State+1, BK_RulesDisplay);
break;
case 33:
case 35:
case 37:
case 39:
WriteUpper(" FOR ");
Timer = ActivateTimer(500, State+1, BK_RulesDisplay);
break;
case 32:
case 34:
case 36:
case 38:
case 40:
WriteUpper(" FOR ");
DisplayScore(2, game_settings[BK_MultiballJackpot]*500000);
Timer = ActivateTimer(500, State+1, BK_RulesDisplay);
break;
case 41:
*(DisplayUpper+15*2) = 128 | *(DisplayUpper+15*2);
*(DisplayUpper+15*2+1) = 64 | *(DisplayUpper+15*2+1); // add a dot in column 14
Timer = ActivateTimer(2700, State+1, BK_RulesDisplay);
break;
case 42:
Timer = ActivateTimer(800, State+1, BK_RulesDisplay);
BK_LockChaseLight(0);
TurnOffLamp(21);
TurnOffLamp(40);
TurnOffLamp(42);
BK_RulesEffect(0);
break;
case 43:
Timer = 0;
ReleaseSolenoid(11);
BK_AttractMode();
break;}}

// Test mode

void BK_TestMode_Enter() {
Expand Down
2 changes: 1 addition & 1 deletion DOC/BlackKnight.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ The same needs to be done for the High Score table feature. In this case the nam
| 7 | Restore Default | - | - | - | No setting - restores the default settings |
| 8 | Exit Settings | - | - | - | No setting - exits the settings mode and writes the new setting to an SD card if present |

Check the [settings page](https://github.com/AmokSolderer/APC/blob/V00.31/DOC/Settings.md#using-the-settings-menu) if you're not sure how to use these game settings.
Check the [settings page](https://github.com/AmokSolderer/APC/blob/master/DOC/Settings.md#using-the-settings-menu) if you're not sure how to use these game settings.
## Things to do

* The Jackpot still needs some sound effects.
12 changes: 11 additions & 1 deletion DOC/Changes.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
# APC News and Changelog

## TDB
## December 2023

### New SW Version V1.00

* Exception rules for System 3 Disco Fever have been added. [Sound files for Disco Fever are also available](https://github.com/AmokSolderer/APC/blob/master/DOC/PinMame.md)
* Exception rules for System 6 Alien Poker have been added. [Sound files for Alien Poker are also available](https://github.com/AmokSolderer/APC/blob/master/DOC/PinMame.md)
* Bugfix -> if a sound/music file was invoked immediately after another, the first one was dropped regardless of the priority.
* Bugfix -> Controlling the original audio boards of System 3 - 6 games has been fixed.
* Support for single ball games added to BaseCode
* Solenoid latches are updated every ms instead of on request which will revoke any accidental state change of solenoids. This can happen in heavily distorted environments when the distortion spikes are strong enough to trigger the latches. Distortion levels like these usually mean that something is wrong in your machine, e.g. a broken free-wheeling diode can cause this.
* System watchdog implemented. If the timer interrupt controlling the HW should not occur for 2s the system will restart.
* System 3 game adjustments implemented. You can now use the settings system of the APC to do the adjustments of System 3 games.
* New command StopAllBlinkLamps() implemented

### Misc

* Page for [installation frames](https://github.com/AmokSolderer/APC/blob/master/DOC/Frames.md) started. These make it easier to mount an APC in your backbox.

* PinMame Sound how-tos added to make it more clear what to do to let the APC play the original sounds

## March 2023

Expand Down
Loading

0 comments on commit ac9edad

Please sign in to comment.