"Es - Configure.H" "Es - Framework.H" "Updateoled.H" "Projectile.H" "Spaceship.H" "Enemyship.H" "Gameplay.H"

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 12

/****************************************************************************

Module
UpdateOLED.c

Revision
1.0.1

Description
This is a Service to update the OLED screen

Notes

History
When Who What/Why
-------------- --- --------
10/30/20 EM Created File
****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
/* include header files for this state machine as well as any machines at the
next lower level in the hierarchy that are sub-machines to this machine
*/
#include "ES_Configure.h"
#include "ES_Framework.h"
#include "UpdateOLED.h"
#include "Projectile.h"
#include "Spaceship.h"
#include "EnemyShip.h"
#include "Gameplay.h"

// u8g2 files
#include "../u8g2Headers/u8g2TestHarness_main.h"
#include "../u8g2Headers/common.h"
#include "../u8g2Headers/spi_master.h"
#include "../u8g2Headers/u8g2.h"
#include "../u8g2Headers/u8x8.h"

/*----------------------------- Module Defines ----------------------------*/


#define OLED_TEST
//#define SPACESHIP 1
//#define PROJECTILE 2
//#define ENEMY_SHIP 3

#define LENGTH_OF_SCREEN 128


#define WIDTH_OF_SCREEN 64
#define TIME_STEP 50 // originally 200

/*---------------------------- Module Functions ---------------------------*/


/* prototypes for private functions for this machine.They should be functions
relevant to the behavior of this state machine
*/
void writeOLED(uint8_t);
void writeGameOLED(void);
void writeTitleOLED(void);
void writeEndOLED(void);
void updateAll(void);
void initOLED(void);
bool CheckOLEDStatus(void);
/*---------------------------- Module Variables ---------------------------*/
// everybody needs a state variable, you may need others as well.
// type of state variable should match htat of enum in header file
extern uint8_t u8x8_pic32_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
*arg_ptr);
extern uint8_t u8x8_byte_pic32_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void
*arg_ptr);

static u8g2_t u8g2;

static uint8_t GameMode;

static OLEDState_t CurrentState;


static OLEDState_t OLEDLastState;

// with the introduction of Gen2, we need a module level Priority var as well
static uint8_t MyPriority;

static enemyArray_t enemyPositions;


static uint8_t spaceshipPosition;

//add one to give a buffer of sorts for the while loop, last element will always be false
static ProjectileLoc ProjectilePosition[MAX_PROJECTILE_COUNT+1];
static uint8_t score;
static uint8_t scoreBoard[3];

static const uint8_t upperLeftRowPixel[X_WING_ROWS] = {3, 15, 27, 39};


static const uint8_t upperLeftColPixel[X_WING_COLS] = {6, 18, 30, 42, 54, 66, 78, 90, 102,
114};

//random edit for xml

/*------------------------------ Module Code ------------------------------*/


/****************************************************************************
Function
InitUpdateOLED

Parameters
uint8_t : the priorty of this service

Returns
bool, false if error in initialization, true otherwise

Description
Saves away the priority, sets up the initial transition and does any
other required initialization for this state machine
Notes

Author
J. Edward Carryer, 10/23/11, 18:55
****************************************************************************/
bool InitUpdateOLED(uint8_t Priority)
{
ES_Event_t ThisEvent;

MyPriority = Priority;
// put us into the Initial PseudoState
CurrentState = InitOLEDState;

uint8_t i;
for(i = 0; i < 3; i++)
{
scoreBoard[i] = 0;
}

// post the initial transition event


ThisEvent.EventType = ES_INIT;
if (ES_PostToService(MyPriority, ThisEvent) == true)
{
return true;
}
else
{
return false;
}
}

/****************************************************************************
Function
PostUpdateOLED

Parameters
EF_Event_t ThisEvent , the event to post to the queue

Returns
boolean False if the Enqueue operation failed, True otherwise

Description
Posts an event to this state machine's queue
Notes

Author
J. Edward Carryer, 10/23/11, 19:25
****************************************************************************/
bool PostUpdateOLED(ES_Event_t ThisEvent)
{
return ES_PostToService(MyPriority, ThisEvent);
}

/****************************************************************************
Function
RunUpdateOLED

Parameters
ES_Event_t : the event to process

Returns
ES_Event_t, ES_NO_EVENT if no error ES_ERROR otherwise
Description
add your description here
Notes
uses nested switch/case to implement the machine.
Author
J. Edward Carryer, 01/15/12, 15:23
****************************************************************************/
ES_Event_t RunUpdateOLED(ES_Event_t ThisEvent)
{
ES_Event_t ReturnEvent;
ReturnEvent.EventType = ES_NO_EVENT; // assume no errors

switch (ThisEvent.EventType)
{
case ES_INIT:
{
// Initializes settings for game
initOLED();
ES_Timer_InitTimer(OLED_REFRESH_TIMER, TIME_STEP);

CurrentState = OLEDTitle;
}
break;

case ES_START_GAME:
{
updateAll();
CurrentState = OLEDGame;

}
break;

case ES_JOYSTICK:
{
GameMode = ThisEvent.EventParam;
}
break;

case ES_UPDATE_OLED:
{
switch(ThisEvent.EventParam)
{
case titlescreenID:
{
CurrentState = OLEDTitle;
}break;
case gameoverID:
{
score = QueryGameplayScore();

uint8_t i;
for(i = 0; i < 3; i++)
{
if(score > scoreBoard[i])
{
uint8_t j;
for(j = 2; j > i; j--)
{
scoreBoard[j] = scoreBoard[j-1];
}

scoreBoard[i] = score;
break;
}
}

CurrentState = OLEDEnd;

}break;
case scoreboardID:
{
// Changes CurrentState to OLEDScoreBoard
CurrentState = OLEDScoreBoard;
}break;
case projectileID:
{
// Creates a projectile array and updates it
ProjectileLoc *projArray;
projArray = ProjectilePosition;
QueryProjectilePosition(projArray); //pass a pointer to our array,
function will update array
//writeGameOLED();
//CurrentState = OLEDGame;

}break;
case spaceshipID:
{
spaceshipPosition = QuerySpaceshipPosition();

//writeGameOLED();
//CurrentState = OLEDGame;

}break;
case enemyshipID:
{
enemyArray_t *enemyPosArray;
enemyPosArray = &enemyPositions;
QueryEnemyShipPosition(enemyPosArray);//pass a pointer to our array,
function will update array
score = QueryGameplayScore();

//puts("\rEnemy Ships Updated\r\n");

//CurrentState = OLEDGame;
//writeGameOLED();

}break;
default:
{}
break;
}

}
break;
case ES_TIMEOUT:
{
if(ThisEvent.EventParam == OLED_REFRESH_TIMER){
ES_Timer_InitTimer(OLED_REFRESH_TIMER, TIME_STEP);
switch (CurrentState){
case OLEDTitle: // Displays title screen
{
// Displays the Title Screen, along with difficulty
// levels
char *titleBuffer = "GALAGA";
char *easyTitle = "Easy";
char *mediumTitle = "Medium";
char *hardTitle = "Hard";
u8g2_ClearBuffer(&u8g2);
u8g2_DrawStr(&u8g2, 0, 16, titleBuffer);
u8g2_DrawStr(&u8g2, 16, 32, easyTitle);
u8g2_DrawStr(&u8g2, 16, 48, mediumTitle);
u8g2_DrawStr(&u8g2, 16, 64, hardTitle);

// Draws triangle pointing to selected difficulty level


uint8_t posTri = 30 + GameMode * 16;
u8g2_DrawTriangle(&u8g2, 2, posTri-8, 2, posTri, 12, posTri-4);

u8g2_SendBuffer(&u8g2);

}break;
case OLEDEnd:
{
// Displays Game Over, tells you score and whether you've
// won/lost

// Creates strings to be displayed on the OLED


char *endBuffer = "GAME OVER";

char *gameStatus = "You Lose";

if(QueryGameplayCollisions() >= MAX_COLLISIONS){


gameStatus = "You Win ";
}

char scoreNum[20];
sprintf(scoreNum, "Score: %d", score);

// Displays on OLED screen


u8g2_ClearBuffer(&u8g2);
u8g2_DrawStr(&u8g2, 0, 20, endBuffer);
u8g2_DrawStr(&u8g2, 0, 37, gameStatus);
u8g2_DrawStr(&u8g2, 0, 55, scoreNum);
u8g2_SendBuffer(&u8g2);
}break;
case OLEDScoreBoard: // Displays scoreboard
{
// Creates string "Leaderboard"
char *endBuffer = "Leaderboard";

u8g2_ClearBuffer(&u8g2);
u8g2_DrawStr(&u8g2, 0, 16, endBuffer);

// Displays the top 3 scores


uint8_t i;
for(i = 0; i < 3; i++)
{
char scoreNum[20];
sprintf(scoreNum, "#%d: %d", i+1, scoreBoard[i]);
u8g2_DrawStr(&u8g2, 16, (i+2)*16, scoreNum);
}

u8g2_SendBuffer(&u8g2);

}break;
case OLEDGame:
{
// Displays all active elements on the screen (TIE fighter, X-Wings,
projectiles)
// Draws TIE fighter icon
u8g2_ClearBuffer(&u8g2);
u8g2_DrawCircle(&u8g2, spaceshipPosition, WIDTH_OF_SCREEN-8, 1,
U8G2_DRAW_ALL);
u8g2_DrawCircle(&u8g2, spaceshipPosition, WIDTH_OF_SCREEN-8, 3,
U8G2_DRAW_ALL);
// Tie Fighter right wing
u8g2_DrawLine(&u8g2, spaceshipPosition+1, WIDTH_OF_SCREEN-8,
spaceshipPosition+6, WIDTH_OF_SCREEN-8);
u8g2_DrawLine(&u8g2, spaceshipPosition+6, WIDTH_OF_SCREEN-8,
spaceshipPosition+4, WIDTH_OF_SCREEN-14);
u8g2_DrawLine(&u8g2, spaceshipPosition+6, WIDTH_OF_SCREEN-8,
spaceshipPosition+4, WIDTH_OF_SCREEN-2);
// Tie fighter left wing
u8g2_DrawLine(&u8g2, spaceshipPosition-1, WIDTH_OF_SCREEN-8,
spaceshipPosition-6, WIDTH_OF_SCREEN-8);
u8g2_DrawLine(&u8g2, spaceshipPosition-6, WIDTH_OF_SCREEN-8,
spaceshipPosition-4, WIDTH_OF_SCREEN-14);
u8g2_DrawLine(&u8g2, spaceshipPosition-6, WIDTH_OF_SCREEN-8,
spaceshipPosition-4, WIDTH_OF_SCREEN-2);

// Draws projectiles
uint16_t idx = 0;
while(ProjectilePosition[idx].status){
u8g2_DrawLine(&u8g2, ProjectilePosition[idx].xpos,
ProjectilePosition[idx].ypos, ProjectilePosition[idx].xpos,
ProjectilePosition[idx].ypos+3);
idx++;
}

// Draws all enemy X-Wings on the screen through nested


// for loops
uint8_t col;
uint8_t row;
for(row=0; row<X_WING_ROWS; row++){
for(col=0; col<X_WING_COLS; col++){
if(enemyPositions[row][col]){
uint8_t topY = upperLeftRowPixel[row];
uint8_t bottomY = topY+8;
uint8_t leftX = upperLeftColPixel[col];
uint8_t rightX = leftX+8;

// X-Wing icons
u8g2_DrawLine(&u8g2, leftX, bottomY-5, rightX, bottomY-5);
u8g2_DrawLine(&u8g2, leftX+3, topY, leftX+3, bottomY-3);
u8g2_DrawLine(&u8g2, rightX-3, topY, rightX-3, bottomY-3);
u8g2_DrawLine(&u8g2, leftX+4, topY+1, leftX+4, bottomY);

u8g2_DrawLine(&u8g2, leftX, topY+3, leftX+3, topY+1);


u8g2_DrawLine(&u8g2, rightX, topY+3, rightX-3, topY+1);
u8g2_DrawLine(&u8g2, leftX, topY+3, leftX, bottomY-2);
u8g2_DrawLine(&u8g2, rightX, topY+3, rightX, bottomY-2);
}
}
}

u8g2_SendBuffer(&u8g2);

}break;
default:
{}break;
}
}
}
break;
default:
{}
break;
}

return ReturnEvent;
}

/****************************************************************************
Function
QueryTemplateSM

Parameters
None

Returns
TemplateState_t The current state of the Template state machine

Description
returns the current state of the Template state machine
Notes

Author
J. Edward Carryer, 10/23/11, 19:21
****************************************************************************/
OLEDState_t QueryUpdateOLED(void)
{
return CurrentState;
}

/***************************************************************************
private functions
***************************************************************************/

void initOLED(void){
SPI_Init();
// build up the u8g2 structure with the proper values for our display
// use the next 5 lines verbatim in your initialization
u8g2_Setup_ssd1306_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_pic32_hw_spi,
u8x8_pic32_gpio_and_delay);
// pass all that stuff on to the display to initialize it
u8g2_InitDisplay(&u8g2);
// turn off power save so that the display will be on
u8g2_SetPowerSave(&u8g2, 0);
// choose the font. this one is mono-spaced and has a reasonable size
u8g2_SetFont(&u8g2, u8g2_font_t0_18_mr);
// overwrite the background color of newly written characters
u8g2_SetFontMode(&u8g2, 0);

GameMode = 0;

#ifdef DEBUG_OLED
puts("\rOLED Initialized\r");
#endif
}

/****************************************************************************
Function
CheckOLEDBusy
Parameters
None
Returns
bool: true if the OLED has become available
Description
checks to see if the OLED is available
Notes

Author
J. Edward Carryer, 08/06/13, 13:48
****************************************************************************/
bool CheckOLEDStatus(void)
{
uint8_t newState;
bool ReturnVal = false;

//check is the transmit buffer is empty


newState = u8g2_NextPage(&u8g2); //1 if not ready
// check for state empty AND different from last time
// do the check for difference first so that you don't bother with a test
// of a port/variable that is not going to matter, since it hasn't changed
if ((newState != OLEDLastState) &&
(!newState)) // event detected, so post detected event
{
ES_Event_t ThisEvent;
ThisEvent.EventType = ES_OLED_NOT_BUSY;
ThisEvent.EventParam = 1;
// this could be any of the service post functions, ES_PostListx or
PostUpdateOLED(ThisEvent);
ReturnVal = true;
}
OLEDLastState = newState; // update the state for next time

return ReturnVal;
}

void writeGameOLED(void){

// set up for a screen update always start an update with u8g2_FirstPage


u8g2_FirstPage(&u8g2);

// offset (2nd param) determines where the first character will be placed
// 0 is far left, 118 is first position on the right
// 37 is the horizontal starting position(3rd param). This puts it in the
// middle of the display

//REPLACE WITH ACTUAL GRAPHICS


//u8g2_DrawStr(&u8g2, 0, 37, buffer);
puts("\rUPDATED POSITION INFO\r\n");
printf("\rSpaceship position on X axis: %d\r\n", spaceshipPosition);
int idx = 0;
while(ProjectilePosition[idx].status){
printf("\rProjectile position X,Y: %d, %d\r\n", ProjectilePosition[idx].xpos,
ProjectilePosition[idx].ypos);
idx++;
}
printf("\rEnemy position by row: \r\n");
uint8_t i;
uint8_t j;
for(i=0; i<7; i++){
for(j=0; j<16; j++){
printf("%d ", enemyPositions[i][j]);
}
printf("\r\n\r");
}

OLEDLastState = 1;
//

/*
void writeTitleOLED(void){

// set up for a screen update always start an update with u8g2_FirstPage


u8g2_FirstPage(&u8g2);

// offset (2nd param) determines where the first character will be placed
// 0 is far left, 118 is first position on the right
// 37 is the horizontal starting position(3rd param). This puts it in the
// middle of the display
char *title = "GALAGA";

u8g2_DrawStr(&u8g2, 0, 37, title);

OLEDLastState = 1;

puts("\rTITLE SCREEN\r\n");
//

}
*/

void writeEndOLED(void){
// set up for a screen update always start an update with u8g2_FirstPage
u8g2_FirstPage(&u8g2);

// offset (2nd param) determines where the first character will be placed
// 0 is far left, 118 is first position on the right
// 37 is the horizontal starting position(3rd param). This puts it in the
// middle of the display
char *gameOver = "GAME OVER";
//char *finalScore = "Final Score: " + score;

u8g2_DrawStr(&u8g2, 0, 37, gameOver);


//u8g2_DrawStr(&u8g2)

OLEDLastState = 1;
puts("\rGAME OVER SCREEN\r\n");

void updateAll(void){
ProjectileLoc *projArray;
projArray = ProjectilePosition;
QueryProjectilePosition(projArray);

spaceshipPosition = QuerySpaceshipPosition();

enemyArray_t *enemyPosArray;
enemyPosArray = &enemyPositions;
QueryEnemyShipPosition(enemyPosArray);//pass a pointer to our array, function will
update array
score = QueryGameplayScore();
}

You might also like