home   |  video   |  gallery   |  circuitry   |  code   |  schematics   |  bom   |  gems of wisdom  


CODE

Signaling Module:
[Header File]  [Pseudocode]  [C Code]

Timing Module:
[Header File]  [Pseudocode]  [C Code]

Pinout:

[Pinout Diagram]
Game Play Module:
[Header File]  [Pseudocode]  [C Code]

Main Module:
[Header File]  [Pseudocode]  [C Code]

Game Play C Code

/* G Play module for Railroad HandCar arcade game */

/**************************************************/
/* Includes                                       */
/**************************************************/

#include <stdlib.h>
#include <timers12.h>

#include "Signaling.h"
#include "Timing.h"
#include "GamePlay.h"
                     
/**************************************************/
/* Reference Program Variables                    */
/**************************************************/

extern unsigned int  HandCarSpeed;
extern unsigned char VillainPos, Jumping;
                     
/**************************************************/
/* Module Variables                               */
/**************************************************/

static unsigned int DT;
                     
/**************************************************/
/* Functions                                      */
/**************************************************/

/* Get raw handcar velocity to sync w/puppet pump */

unsigned char HandleDiff(void) {
  static unsigned int OldVel, OldPos;
  static char Dir;
  
  unsigned int NewVel, NewPos = HandlePosition();
  int RawVel = NewPos - OldPos;
   
  NewVel = (OldVel + abs(RawVel)) / 2;

  OldVel = NewVel;
  OldPos = NewPos;
  
  if (RawVel >  NOISE) Dir = UP; 		
  if (RawVel < -NOISE) Dir = DN;
  
  Pump(Dir);		
  
  return (unsigned char) (NewVel / 10);
}


/* Calculate the handcar's velocity (range 0-100) */

unsigned char CalculateVelocity(void) {
  static unsigned int AvgSpeed;
  
  if (!Jumping)
    AvgSpeed += HandleDiff();
  
  AvgSpeed = AvgSpeed * 99 / 100;
  
  if (AvgSpeed > 100)
    AvgSpeed = 100;
}

/* Account for the servo's dead-band (hysteresis) */

void CalculateChase(unsigned int Speed) {
  static int Accumulator;
  static char DeadBand;
    
  if (Speed > VILLAIN_SPEED + DeadBand)
     Accumulator--; 
    
  if (Speed < VILLAIN_SPEED - DeadBand)
     Accumulator++;
 
  if (Accumulator > ACCUMULATOR_MAX) {
    AdvanceVillain(FW);
    Accumulator = 0;
  }
  if (Accumulator < -ACCUMULATOR_MAX) {
    AdvanceVillain(BK);
    Accumulator = 0;
  }    
}

/* Step villain left or right relative to handcar */

void AdvanceVillain(char Dir) {
  static char PrevMotionDir = FW,
              CurrentPos = SERVO_MIN;
 
  if (Dir == FW) {
    CurrentPos++;
 
    if(PrevMotionDir == BK)
      CurrentPos += SERVO_HYS;   

    PrevMotionDir = FW;
  } 
  else {
    CurrentPos--;
    
    if (PrevMotionDir == FW)
      CurrentPos -= SERVO_HYS;   

    PrevMotionDir = BK;  
  }
  if (CurrentPos > SERVO_MAX)
    CurrentPos = SERVO_MAX;
  
  if (CurrentPos < SERVO_MIN)
    CurrentPos = SERVO_MIN;
 
  PlaceVillain(CurrentPos);
  VillainPos = CurrentPos;
}

/* Check that villain reached right-most position */

char Caught(void) {
  return (VillainPos == SERVO_MAX); 
}

/* Check if handcar is currently over an obstacle */
/* Index off RECOVER_TIME, which is greather than */
/* COLLIDE_TIME, because the player needs time to */
/* exit obstacle without starting a new collision */

char Colliding(void) {  
  if (AtObstacle() && !Jumping && !Active(RECOVER_TIMER)) {
    TMRS12_InitTimer(COLLIDE_TIMER, COLLIDE_TIME);
    TMRS12_InitTimer(RECOVER_TIMER, RECOVER_TIME);
    
    AdvanceVillain(FW);
  }
  if (Active(COLLIDE_TIMER)) 
    return TRUE;

  return FALSE;  
}