Skeeball Racer Functions
/************************************************************************
ME218A Project: SkeeBall
Racer
Date: Fall Quarter 2007
Team Members: Derrick Jue,
Ji Heun Lee, Stephanie Lue, Nathan Parkhill
File Name: Skeeball_Racer_Functions.c
Description: SkeeBall
Racer Function Declarations
************************************************************************/
#include <stdio.h>
#include <ME218_C32.h>
#include <timers12.h>
#include <string.h>
#include "PWMS12.h"
#include "ADS12.h"
#include "SkeeBall_Racer.h"
#include "seven_segment_display.h"
#include "Laps_Left_Display.h"
#include "LED.h"
/*************************** function
declarations **********************/
/************************************************************************
Function Prototype: void InitializeGame(void)
Returns: nothing
Parameters: none
Description: Initializes all C32 ports,
timers globals, etc in preparation
of game start.
************************************************************************/
void InitializeGame(void)
{
signed char setperiod;
char ADportIO[] = AD_INIT; // declare active A/D ports
TMRS12_Init(TMRS12_RATE_1MS); // initiate timere @ 1ms/tick
PWMS12_Init(); // initiate C32 for PWM output
setperiod =
PWMS12_SetPeriod(PWMS12_20000US, PWMS12_GRP1);
PTM =
PORTM_INIT;
// initiate PortM
pins
PTT =
PORTT_INIT;
// initiate PortT
pins
DDRM
= DATADIRECTIONM_INIT;
// initiate PortM
data directions
DDRT
= DATADIRECTIONT_INIT;
// initiate PortT
data directions
DisplayInit(); // initialize 7 segment
display (gas) //initialize 7 segmant display
ClearDisplay(); // clear 7 segment display
(gas)
LapsDisplayInit(); // initialize 7 segment display (laps)
LapsClearDisplay(); // Clear 7 segment display (laps)
LEDInit(); // initialize display LEDs
ClearLED(); // clear LEDs
PWMS12_SetDuty(3, PWMS12_CHAN2); // initialize speedometer servo
if (ADS12_Init(ADportIO) !=
ADS12_OK) // check for clean
A/D initialization
{
printf("Error
in A/D initialization. \r\n"); // if there is an error print error message
}
}
/************************************************************************
Function Prototype: void CheckforPenny(void)
Returns: nothing
Parameters: none
Description: This function BLOCKS the main
code until a penny is found.
Once a penny is found, the game can continue.
************************************************************************/
void CheckforPenny(void)
{
while((PTIAD & PENNY_BIT) != PENNY_FOUND); // wait in this while loop until a
penny is found
}
/************************************************************************
Function Prototype: unsigned int RunRace(void)
Returns: unsigned char (winner)
Parameters: none
Description: This function starts and runs
the race. This function
contains the events and services framework necessary
to run the game.
************************************************************************/
unsigned char RunRace(void)
{
unsigned char difficulty;
unsigned char shotsleft = 15;
unsigned char pacerspeed;
unsigned char userspeed =
USER_START_SPEED;
unsigned char speedometer;
signed char setduty;
unsigned int i
= 0;
unsigned int TimeofCurrentHit;
unsigned int TimeofCurrentLaunch;
unsigned int VibrateCurrent;
unsigned int VibrateDone;
unsigned char PlayerLapsLeft =
PLAYER_TOTAL_LAPS;
unsigned char PacerLapsLeft =
PACER_TOTAL_LAPS;
unsigned int PlayerTimeofCurrentLap;
unsigned int PacerTimeofCurrentLap;
static unsigned int TimeofLastHit = 0;
static unsigned int VibrateStart;
static unsigned int PlayerTimeofLastLap = 0;
static unsigned char OutOfGasSign
= 0;
static unsigned int TimeofLastLaunch = 0;
static unsigned int PacerTimeofLastLap = 0;
/****
initializing difficulty settings ********************************/
difficulty = SetDifficulty(); // set the difficulty
if(difficulty == EASY)
{ // if easy
mode
shotsleft = EASY_SHOTS_LEFT; // set shots left
pacerspeed = EASY_PACER_SPEED; // set pacer speed
printf("Set
constants for easy difficulty.\r\n");
}
else if(difficulty == MEDIUM) // if medium mode
{
shotsleft = MEDIUM_SHOTS_LEFT; // set shots left
pacerspeed = MEDIUM_PACER_SPEED; // set pacer speed
printf("Set
constants for med difficulty.\r\n");
}
else // else hard mode
{ // if hard
mode
shotsleft = HARD_SHOTS_LEFT; // set shots left
pacerspeed = HARD_PACER_SPEED; // set pacer speed
printf("Set
constants for hard difficulty.\r\n");
}
ShowShotsLeft(shotsleft); //
show shots left
ShowLapsLeft(PlayerLapsLeft); // show player laps left
/****
checking for false start *****************************************/
delayLED(1000);
/*
show "Gentlemen Start Your Engines" msg */
TurnOnLED(START_ENGINE_SIGN);
printf("Turned
on Start engine sign \r\n");
if(CheckStart(START_ENGINE_WAIT_TIME)
== FALSE_START) // if there is a
false start
return PACER_WINS; //
the pacer wins
/*
show "On Your Marks" msg */
TurnOnLED(ON_YOUR_MARKS_SIGN);
printf("Turned
on On your marks sign \r\n");
if(CheckStart(ON_YOUR_MARKS_WAIT_TIME)
== FALSE_START) // if there is a false
start
return PACER_WINS; //
the pacer wins
/*
show "Get Set" msg */
TurnOnLED(GET_SET_SIGN);
printf("Turned
on Get Set sign \r\n");
if(CheckStart(GET_SET_WAIT_TIME)
== FALSE_START) // if there is a
false start
return PACER_WINS; //
the pacer wins
/*
show "GO!!!!" msg */
TurnOnLED(GO_SIGN);
printf("Turned
on GO \r\n");
/****
let the races begin *********************************************/
printf("Pacer
started at: %i\r\n", pacerspeed);
StartPacer(pacerspeed); //
start pacer car at speed set by difficult level
while(1) {
if((PTT & PACER_FINISH_BIT) !=
PACER_LAP_NOT_FINISHED) // if pacer
completes a lap
{
PacerTimeofCurrentLap = TMRS12_GetTime();
if((PacerTimeofCurrentLap - PacerTimeofLastLap) > DEBOUNCE_TIME)
{
printf("Pacer went around one lap. \r\n");
PacerLapsLeft--;
//decrement number of laps left for pacer
PacerTimeofLastLap = PacerTimeofCurrentLap;
}
}
if((PTT & PLAYER_FINISH_BIT) !=
PLAYER_LAP_NOT_FINISHED) // if player
completes a lap
{
PlayerTimeofCurrentLap = TMRS12_GetTime();
if((PlayerTimeofCurrentLap - PlayerTimeofLastLap) > DEBOUNCE_TIME)
{
printf("Player went around one lap. \r\n");
PlayerLapsLeft--; // decrement number of laps left for
player
ShowLapsLeft(PlayerLapsLeft); // display number of laps left for
player
PlayerTimeofLastLap = PlayerTimeofCurrentLap;
}
}
if (PacerLapsLeft == NO_LAPS_LEFT)
// if pacer finishes
all laps first
{
OutOfGasSign = 0;
return PACER_WINS;
}
else if (PlayerLapsLeft ==
NO_LAPS_LEFT) // if player
finishes all laps first
{
OutOfGasSign = 0;
return PLAYER_WINS;
}
else
{
}
if((PTIAD & BALL_LAUNCHER_BIT) != BALL_NOT_LAUNCHED ) // if a ball is launched
{
TimeofCurrentLaunch = TMRS12_GetTime();
if ((TimeofCurrentLaunch - TimeofLastLaunch) > DEBOUNCE_TIME)
{
shotsleft--; //
decrement number of shots left
if (shotsleft >=
10) // if shotsleft tries to be > 10 set shots (b/c shots left is
an unsigned int)
{
shotsleft = 0; // set shotsleft to zero
}
ShowShotsLeft(shotsleft); // display updated number of
shots left
TimeofLastLaunch = TimeofCurrentLaunch;
}
}
if(shotsleft == 0){ // if there are no shots
left
if(OutOfGasSign ==0){ // if Out of Gas sign is
not turned on
printf("Out of gas. \r\n");
TurnOnLED (OUT_OF_GAS_SIGN); // display out of gas message
OutOfGasSign = 1;
}
}
if(((PTIAD & SLOW_DOWN_SWITCH_BIT) == SLOW_DOWN_HIT)
&& (OutOfGasSign == 0) ) //ball in slow down hole & gas left
{
TimeofCurrentHit = TMRS12_GetTime();
if ((TimeofCurrentHit
- TimeofLastHit) > DEBOUNCE_TIME)
{
printf("Slow down hit. \r\n");
if (userspeed >=
(SLOW_DOWN_DECREMENT + USER_START_SPEED)) //
make sure userspeed cannot go negative
{
userspeed -=
SLOW_DOWN_DECREMENT; // slow down player car speed
if (userspeed > MAX_DUTY_CYCLE) // if userspeed is greater than max duty cycle
{
userspeed = MAX_DUTY_CYCLE; //
set userspeed to max duty cycle
}
}
else
{
userspeed =
USER_START_SPEED; //
otherwise, keep user speed the same
//(decrementing
will make it negative)
}
printf("user motor speed: %i\r\n",
userspeed);
TimeofLastHit = TimeofCurrentHit;
}
}
if (((PTIAD & SMALL_SPEED_UP_SWITCH_BIT) ==
SMALL_SPEED_UP_HIT) && (OutOfGasSign == 0))
// ball in sm. speed up hole
{
TimeofCurrentHit = TMRS12_GetTime();
if ((TimeofCurrentHit
- TimeofLastHit)>DEBOUNCE_TIME) {
printf("small speed up. \r\n");
userspeed = userspeed + SMALL_SPEED_UP_INCREMENT; // increase userspeed
if (userspeed >
MAX_DUTY_CYCLE) // if userspeed
is greater than max duty cycle
{
userspeed =
MAX_DUTY_CYCLE; // set userspeed
to max duty cycle
}
printf("user motor speed: %i\r\n",
userspeed);
TimeofLastHit
= TimeofCurrentHit;
}
VibrateDone = SMALL_SPEED_UP_FEEDBACK; //
set length of vibrating feedback
VibrateStart = TMRS12_GetTime();
PTT |= BIT3HI; //turn on vibrate feedback motor
}
if (((PTIAD & LARGE_SPEED_UP_SWITCH_BIT) ==
LARGE_SPEED_UP_HIT) && (OutOfGasSign == 0)//
ball in large speed up hole
{
TimeofCurrentHit = TMRS12_GetTime();
if ((TimeofCurrentHit
- TimeofLastHit) > DEBOUNCE_TIME){
printf("Large speed up. \r\n");
userspeed = userspeed + LARGE_SPEED_UP_INCREMENT;
// increase user speed
if (userspeed >
MAX_DUTY_CYCLE) // if userspeed is
greater than max duty cycle
{
userspeed =
MAX_DUTY_CYCLE; // set userspeed to
max duty cycle
}
printf("user motor speed: %i\r\n",
userspeed);
TimeofLastHit = TimeofCurrentHit;
}
VibrateDone = LARGE_SPEED_UP_FEEDBACK; // set length of vibrating
feedback
VibrateStart = TMRS12_GetTime();
PTT |= BIT3HI; //
turn on vibrate feedback motor
}
VibrateCurrent = TMRS12_GetTime();
if ((VibrateCurrent - VibrateStart) > VibrateDone) {
PTT
&= BIT3LO; //
turn off vibrating motor
} //
set up prevents it from being blocking code
UserCarSpeed(userspeed); //
change user car speed to appropriate set speed (from above)
speedometer = (userspeed/5) - 10; // servo takes PWM dutycycle
range 3-12
setduty = PWMS12_SetDuty(speedometer, PWMS12_CHAN2); // adjust speedometer
}
}
/************************************************************************
Function Prototype: void Set Difficulty(void)
Returns: unsigned char difficulty level
Parameters: none
Description: This function Reads the
potentiometer in the AD port .
************************************************************************/
unsigned char SetDifficulty(void)
{
short Difficulty;
Difficulty = ADS12_ReadADPin(DIFFICULTY_PIN); //
read in difficulty from analog signal
printf("Difficulty:
%d\r\n", Difficulty);
if (Difficulty < EASY_HI) // if
difficulty easy
{
printf("EASY MODE SELECTED.\r\n");
return EASY;
}
else if (Difficulty <MEDIUM_HI) //
difficulty medium
{
printf("MEDIUM MODE SELECTED.\r\n");
return MEDIUM;
}
else // difficulty
hard
{
printf("HARD MODE SELECTED.\r\n");
return HARD;
}
}
/************************************************************************
Function Prototype: unsigned char CheckStart(unsigned
int WaitTime)
Returns: unsigned char
Parameters: unsigned int
WaitTime
Description: This function checks for a false
start event for the number
seconds specified by wait time.
************************************************************************/
unsigned char CheckStart(unsigned
int WaitTime)
{
unsigned int CurrentTime;
unsigned int StartTime;
WaitTime = WaitTime*1000; // converts WaitTime
(seconds) into milliseconds
StartTime = TMRS12_GetTime();
CurrentTime = TMRS12_GetTime();
printf("waiting
for %i\r\n", WaitTime);
while ((CurrentTime - StartTime)<= WaitTime)
{
CurrentTime =
TMRS12_GetTime();
if ((PTIAD & BALL_LAUNCHER_BIT) != BALL_NOT_LAUNCHED) { // check for false start
printf("false
start detected. \r\n");
TurnOnLED (FALSE_START_SIGN);
return FALSE_START;
}
}
}
/************************************************************************
Function Prototype: void StartPacer(unsigned char pacerspeed)
Returns: nothing
Parameters: unsigned char pacerspeed
Description: Sets / changes the speed of the
pace car.
************************************************************************/
void StartPacer(unsigned
char pacerspeed){
char DutyStatus = 0;
DutyStatus = PWMS12_SetDuty(pacerspeed, PWMS12_CHAN0); //
start pacer car at difficulty speed
if (DutyStatus == PWMS12_ERR) // if an error occurs
in the setting
{
printf("Error
occured while setting pacer duty cycle.
\r\n");
}
}
/************************************************************************
Function Prototype: void ShowShotsLeft(unsigned char shotsleft)
Returns: nothing
Parameters: unsigned int
shotsleft
Description: Displays the number of balls
left on 7 segment LED display.
************************************************************************/
void ShowShotsLeft(unsigned
char shotsleft)
{
Display(shotsleft); // display shots left
on 7 segment display
printf("Shots
Left: %i\r\n", shotsleft);
}
/************************************************************************
Function Prototype: void ShowLapsLeft(unsigned char lapsleft)
Returns: nothing
Parameters: unsigned char lapslefft
Description: Displays the number of balls
left on 7 segmant LED display.
************************************************************************/
void ShowLapsLeft(unsigned
char lapsleft)
{
LapsDisplay(lapsleft); //
display laps left on 7 segment display
printf("Laps
Left: %i\r\n", lapsleft);
}
/************************************************************************
Function Prototype: void UserCarSpeed(unsigned char userspeed)
Returns: nothing
Parameters: unsigned char userspeed
Description: Changes the user car's speed
*************************************************************************/
void UserCarSpeed(unsigned
char userspeed)
{
char DutyStatus = 0;
DutyStatus = PWMS12_SetDuty(userspeed, PWMS12_CHAN1); //
set user car motor PWM speed
if(DutyStatus == PWMS12_ERR)
{
printf("Error
occured while setting user duty cycle.
\r\n");
}
}
/************************************************************************
Function Prototype: void GameOver(unsigned char
winner)
Returns: nothing
Parameters: unsigned char
Description: This function runs the winner
specific game over sequence
************************************************************************/
void GameOver(unsigned
char winner){
PTT &= BIT3LO; // ensure that
vibrating motor off
UserCarSpeed(0);
// stop player
car
StartPacer(0); // stop pace car
if (winner == PLAYER_WINS) //
if player wins, turn on you win sign
{
TurnOnLED
(YOU_WIN_SIGN);
delayLED(750);
}
else if (winner == PACER_WINS) // if player loses, turn on you lose sign
{
TurnOnLED(YOU_LOSE_SIGN);
delayLED(750);
printf("You
lose sign should be turned on \r\n");
}
else
{
printf("winner
error in GameOver \r\n");
}
}
/************************************************************************
Function Prototype: void DispenseGoodies(unsigned char
winner)
Returns: nothing
Parameters: unsigned char
Description: This function dispenses the
winner specific goodies.
************************************************************************/
void DispenseGoodies(unsigned
char winner){
unsigned int StartTime;
unsigned int CurrentTime;
unsigned char swag_state;
if (winner == PLAYER_WINS) //
if player wins
{
swag_state = PTT |SWAG_MOTOR_BIT; // turn on swag motor
PTT = swag_state;
while((PTT & SWAG_SWITCH_BIT) !=
SWAG_SWITCH_NOT_TRIGGERED); // while
switch is triggered
StartTime = TMRS12_GetTime();
CurrentTime = TMRS12_GetTime();
while((CurrentTime - StartTime) < SWITCH_DEBOUNCE_TIME) //wait while switch is bouncing
{
CurrentTime = TMRS12_GetTime();
}
while((PTT & SWAG_SWITCH_BIT) ==
SWAG_SWITCH_NOT_TRIGGERED); // wait while swtich is NOT triggered
while((PTT & SWAG_SWITCH_BIT) !=
SWAG_SWITCH_NOT_TRIGGERED); // wait again while switch is triggered
PTT &= SWAG_MOTOR_BIT_LO;
// stop motor, prize is now
dispensed
printf("prize
dispensed. game over\r\n");
} else{
printf("pacer
won. no prize for you. game
over\r\n") ;
}
}
/************************************************************************
Function Prototype: void Reset(unsigned
char winner)
Returns: nothing
Parameters: unsigned char
Description: This function resets both cars
to the start line.
************************************************************************/
void Reset(unsigned char winner){
if (winner == PLAYER_WINS) { //
if player wins
UserCarSpeed(STOP); // stop user car
StartPacer(PACER_TO_START_SPEED); //
start pace car to bring up to finish line
while((PTT & PACER_FINISH_BIT) ==
PACER_LAP_NOT_FINISHED); // bring pacer
up to finish line (and player car)
StartPacer(STOP);
UserCarSpeed(PLAYER_TO_START_SPEED); //move player and pace car up
to start line
StartPacer(PACER_TO_START_SPEED);
delayLED(75);
UserCarSpeed(STOP); // player and pace are now at start line
StartPacer(STOP);
}
else { //
if pace car wins
UserCarSpeed(PLAYER_TO_START_SPEED); // start player car and bring
up to finish line
StartPacer(STOP); // ensure pace
car is stopped
while((PTT & PLAYER_FINISH_BIT) ==
PACER_LAP_NOT_FINISHED); // bring player
up to finish line (and pace car)
UserCarSpeed(STOP);
UserCarSpeed(PLAYER_TO_START_SPEED); // move player and pace car up
to start line
StartPacer(PACER_TO_START_SPEED);
delayLED(75);
UserCarSpeed(STOP); // player and pace
are now at start line
StartPacer(STOP);
}
}