+ Documentation about sound sources.

* Sine-like effect used for runways now moved to SystemCalculateSine().
* Bugfix: ptrPlayer->FlightDataPage is now decreased if there aren't enough active aircraft.
* On main menu, 2 players option is now disabled if pad 2 is disconnected.
* More work on FPS measurement (not working yet).
* Number of used SPU voices is now returned on SfxUploadSound().
This commit is contained in:
XaviDCR92 2017-08-14 14:29:04 +02:00
parent f97f48ca7c
commit db8bc5f9e3
12 changed files with 394 additions and 78 deletions

11
Sounds/SOUND_SOURCES Normal file
View File

@ -0,0 +1,11 @@
Bell sound obtained from:
http://freesound.org/people/InspectorJ/sounds/339812/
Radio chatter obtained from:
http://freesound.org/people/digifishmusic/sounds/55022/
Tray close sound obtained from:
http://freesound.org/people/Hard3eat/sounds/351780/
CD sound obtained from:
http://freesound.org/people/cmorris035/sounds/207276/

View File

@ -355,9 +355,46 @@ void AircraftRender(TYPE_PLAYER* ptrPlayer, uint8_t aircraftIdx)
CameraApplyCoordinatesToSprite(ptrPlayer, &AircraftSpr);
AircraftSpr.r = NORMAL_LUMINANCE;
AircraftSpr.g = NORMAL_LUMINANCE;
AircraftSpr.b = NORMAL_LUMINANCE;
if( (ptrPlayer->FlightDataSelectedAircraft == aircraftIdx)
&&
(ptrPlayer->ShowAircraftData == true) )
{
static uint8_t aircraft_sine;
static bool aircraft_sine_decrease;
if(aircraft_sine_decrease == false)
{
if(aircraft_sine < 240)
{
aircraft_sine += 24;
}
else
{
aircraft_sine_decrease = true;
}
}
else
{
if(aircraft_sine > 24)
{
aircraft_sine -= 24;
}
else
{
aircraft_sine_decrease = false;
}
}
AircraftSpr.r = NORMAL_LUMINANCE >> 2;
AircraftSpr.g = NORMAL_LUMINANCE >> 2;
AircraftSpr.b = aircraft_sine;
}
else
{
AircraftSpr.r = NORMAL_LUMINANCE;
AircraftSpr.g = NORMAL_LUMINANCE;
AircraftSpr.b = NORMAL_LUMINANCE;
}
GfxSortSprite(&AircraftSpr);
}

View File

@ -17,6 +17,13 @@
#define CAMERA_INITIAL_X_OFFSET (X_SCREEN_RESOLUTION >> 1)
#define CAMERA_INITIAL_X_OFFSET_2PLAYER (X_SCREEN_RESOLUTION >> 2)
/* *************************************
* Local Variables
* *************************************/
static int32_t Camera_Max_X_Offset;
static int32_t Camera_Max_Y_Offset;
/* *************************************
* Local Prototypes
* *************************************/
@ -32,6 +39,9 @@ void CameraInit(TYPE_PLAYER* ptrPlayer)
ptrPlayer->Camera.X_Speed = 0;
ptrPlayer->Camera.Y_Speed = 0;
ptrPlayer->Camera.Speed_Timer = SPEED_CALCULATION_TIME;
Camera_Max_X_Offset = GameGetLevelColumns() << TILE_SIZE_BIT_SHIFT;
Camera_Max_Y_Offset = GameGetLevelColumns() * TILE_SIZE_H;
}
void CameraApplyCoordinatesToSprite(TYPE_PLAYER* ptrPlayer, GsSprite * spr)
@ -149,6 +159,9 @@ void CameraHandler(TYPE_PLAYER* ptrPlayer)
ptrPlayer->Camera.X_Offset += ptrPlayer->Camera.X_Speed;
ptrPlayer->Camera.Y_Offset += ptrPlayer->Camera.Y_Speed;
//DEBUG_PRINT_VAR(ptrPlayer->Camera.X_Offset);
//DEBUG_PRINT_VAR(ptrPlayer->Camera.Y_Offset);
}
bool CameraSpecialConditions(TYPE_PLAYER* ptrPlayer)

View File

@ -203,7 +203,6 @@ static uint16_t GameRwy[GAME_MAX_RUNWAYS];
static TYPE_FLIGHT_DATA FlightData;
static uint16_t GameUsedRwy[GAME_MAX_RUNWAYS];
static uint16_t GameSelectedTile;
static bool firstLevelRender; // Used to avoid reentrance issues on GameRenderLevel()
static TYPE_TIMER* GameSpawnMinTime;
static bool spawnMinTimeFlag;
static bool GameAircraftCreatedFlag;
@ -213,7 +212,7 @@ static TYPE_BUILDING_DATA GameBuildingData[MAX_BUILDING_ID];
static uint8_t GameAircraftTilemap[GAME_MAX_MAP_SIZE][GAME_MAX_AIRCRAFT_PER_TILE];
// Instances for player-specific data
TYPE_PLAYER PlayerData[MAX_PLAYERS];
static TYPE_PLAYER PlayerData[MAX_PLAYERS];
static char* GameFileList[] = { "cdrom:\\DATA\\SPRITES\\TILESET1.TIM;1" ,
"cdrom:\\DATA\\SPRITES\\GAMEPLN.TIM;1" ,
@ -655,6 +654,7 @@ void GameBuildingsInit(void)
void GameEmergencyMode(void)
{
uint8_t i;
uint8_t disconnected_players = 0x00;
bool (*PadXConnected[MAX_PLAYERS])(void) = { [PLAYER_ONE] = &PadOneConnected,
[PLAYER_TWO] = &PadTwoConnected };
@ -670,9 +670,18 @@ void GameEmergencyMode(void)
ERROR_RECT_G = 32,
ERROR_RECT_B = NORMAL_LUMINANCE
};
enum
{
PAD_DISCONNECTED_TEXT_X = 48,
PAD_DISCONNECTED_TEXT_Y = 48,
PAD_DISCONNECTED_TEXT_Y_OFFSET_BITSHIFT = 5
};
while(SystemGetEmergencyMode() == true)
do
{
bool enabled = false;
GsRectangle errorRct = {.x = ERROR_RECT_X,
.w = ERROR_RECT_W,
.y = ERROR_RECT_Y,
@ -681,12 +690,27 @@ void GameEmergencyMode(void)
.g = ERROR_RECT_G,
.b = ERROR_RECT_B };
// Pad one has been disconnected during gameplay
// Show an error screen until it is disconnected again.
GsSortCls(0,0,0);
GsSortRectangle(&errorRct);
if(SystemGetEmergencyMode() == true)
{
// One of the pads has been disconnected during gameplay
// Show an error screen until it is disconnected again.
GsSortCls(0,0,0);
GsSortRectangle(&errorRct);
for(i = 0; i < MAX_PLAYERS; i++)
{
if(disconnected_players & (1<<i) )
{
FontPrintText( &SmallFont,
PAD_DISCONNECTED_TEXT_X,
PAD_DISCONNECTED_TEXT_Y + (i << PAD_DISCONNECTED_TEXT_Y_OFFSET_BITSHIFT),
"Pad %s disconnected", i? "right" : "left" );
}
}
GfxDrawScene_Slow();
}
for(i = 0; i < MAX_PLAYERS; i++)
{
@ -696,14 +720,19 @@ void GameEmergencyMode(void)
{
if(PadXConnected[i]() == false)
{
FontPrintText(&SmallFont, 48, 48 + (i << 5), "Pad %d disconnected", i);
SystemSetEmergencyMode(true);
enabled = true;
disconnected_players |= 1<<i;
}
else
{
disconnected_players &= ~(1<<i);
}
}
}
GfxDrawScene_Slow();
}
SystemSetEmergencyMode(enabled);
}while(SystemGetEmergencyMode() == true);
}
/* ***************************************************************************************
@ -837,6 +866,13 @@ void GamePlayerHandler(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData)
CameraMoveToIsoPos(ptrPlayer, IsoPos);
}
if(System1SecondTick() == true)
{
dprintf("ptrPlayer = 0x%08X\n", ptrPlayer);
DEBUG_PRINT_VAR(ptrPlayer->ActiveAircraft);
DEBUG_PRINT_VAR(ptrPlayer->FlightDataPage);
}
GameActiveAircraftList(ptrPlayer, ptrFlightData);
GameStateUnboarding(ptrPlayer, ptrFlightData);
GameStateLockTarget(ptrPlayer, ptrFlightData);
@ -946,9 +982,11 @@ void GameGraphics(void)
{
int i;
bool split_screen = false;
SystemAcknowledgeFrame();
while( (SystemRefreshNeeded() == false) || (GfxIsGPUBusy() == true) );
if(TwoPlayersActive == true)
{
split_screen = true;
@ -960,14 +998,16 @@ void GameGraphics(void)
GfxIncreaseGlobalLuminance(1);
}
firstLevelRender = true;
GsSortCls(0,0,GfxGetGlobalLuminance() >> 1);
while(GsIsDrawing());
for(i = 0; i < MAX_PLAYERS ; i++)
{
TYPE_PLAYER* ptrPlayer = &PlayerData[i];
if(ptrPlayer->Active == true)
{
{
if(split_screen == true)
{
GfxSetSplitScreen(i);
@ -976,8 +1016,6 @@ void GameGraphics(void)
// Draw half split screen for each player
// only if 2-player mode is active. Else, render
// the whole screen as usual.
GsSortCls(0,0,GfxGetGlobalLuminance() >> 1);
// Ground tiles must be rendered first.
@ -1415,9 +1453,7 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer)
bool used_rwy = SystemContains_u16(ptrPlayer->RwyArray[0], GameUsedRwy, GAME_MAX_RUNWAYS);
uint8_t aux_id;
GsSprite * ptrTileset;
const uint8_t rwy_sine_step = 24;
static unsigned char rwy_sine = rwy_sine_step;
static bool rwy_sine_decrease = false;
unsigned char rwy_sine = SystemGetSineValue();
TYPE_ISOMETRIC_POS tileIsoPos;
TYPE_CARTESIAN_POS tileCartPos;
@ -1437,36 +1473,6 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer)
Serial_printf("\n");*/
}
if(firstLevelRender == true)
{
// Avoid re-entrance.
firstLevelRender = false;
if(rwy_sine_decrease == false)
{
if(rwy_sine < 240)
{
rwy_sine += rwy_sine_step;
}
else
{
rwy_sine_decrease = true;
}
}
else
{
if(rwy_sine > rwy_sine_step)
{
rwy_sine -= rwy_sine_step;
}
else
{
rwy_sine_decrease = false;
}
}
}
for(i = 0 ; i < GameLevelSize; i++)
{
@ -3191,6 +3197,21 @@ void GameDrawMouse(TYPE_PLAYER* ptrPlayer)
}
}
/* ********************************************************************************
*
* @name: FL_STATE GameGetFlightDataStateFromIdx(uint8_t FlightDataIdx)
*
* @author: Xavier Del Campo
*
* @param:
* uint8_t FlightDataIdx:
* Index from FlightData.
*
* @return:
* Returns .State variable given offset from FlightData.
*
* ********************************************************************************/
FL_STATE GameGetFlightDataStateFromIdx(uint8_t FlightDataIdx)
{
if(FlightDataIdx >= FlightData.nAircraft)
@ -3201,13 +3222,43 @@ FL_STATE GameGetFlightDataStateFromIdx(uint8_t FlightDataIdx)
return FlightData.State[FlightDataIdx];
}
/* ********************************************************************************
*
* @name: uint32_t GameGetScore(void)
*
* @author: Xavier Del Campo
*
* @return:
* Returns game score to other modules.
*
* ********************************************************************************/
uint32_t GameGetScore(void)
{
return GameScore;
}
/* *******************************************************************************************
*
* @name: void GameStateUnboarding(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData)
*
* @author: Xavier Del Campo
*
* @param:
* TYPE_PLAYER* ptrPlayer:
* Pointer to a player structure
*
* TYPE_FLIGHT_DATA* ptrFlightData:
* In the end, pointer to FlightData data table, which contains
* information about all available flights.
*
* @brief:
* Handler for StateUnboarding.
*
* *******************************************************************************************/
void GameStateUnboarding(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData)
{
{
if(ptrPlayer->Unboarding == true)
{
if(ptrPlayer->PadKeySinglePress_Callback(PAD_CIRCLE) == true)
@ -3254,6 +3305,25 @@ void GameStateUnboarding(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData
}
}
/* *******************************************************************************************
*
* @name: void GameStateUnboarding(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData)
*
* @author: Xavier Del Campo
*
* @param:
* TYPE_PLAYER* ptrPlayer:
* Pointer to a player structure
*
* @brief:
* Modifies ptrPlayer->UnboardingSequence creating a random sequence of numbers
* using SystemRand().
*
* @todo:
* Maximum number of sequence keys should be adjusted according to difficulty.
*
* *******************************************************************************************/
void GameGenerateUnboardingSequence(TYPE_PLAYER* ptrPlayer)
{
uint8_t i;
@ -3292,22 +3362,22 @@ void GameCreateTakeoffWaypoints(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFli
switch(aircraftDir)
{
case AIRCRAFT_DIR_EAST:
Serial_printf("EAST\n");
//Serial_printf("EAST\n");
rwyStep = 1;
break;
case AIRCRAFT_DIR_WEST:
Serial_printf("WEST\n");
//Serial_printf("WEST\n");
rwyStep = -1;
break;
case AIRCRAFT_DIR_NORTH:
Serial_printf("NORTH\n");
//Serial_printf("NORTH\n");
rwyStep = -GameLevelColumns;
break;
case AIRCRAFT_DIR_SOUTH:
Serial_printf("SOUTH\n");
//Serial_printf("SOUTH\n");
rwyStep = GameLevelColumns;
break;

View File

@ -25,7 +25,6 @@
* *************************************/
extern bool GameStartupFlag;
extern TYPE_PLAYER PlayerData[];
/* *************************************
* Global prototypes

View File

@ -335,11 +335,19 @@ void GameGuiActiveAircraftPage(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlig
ptrPlayer->SelectedAircraft--;
}
}
while(ptrPlayer->ActiveAircraft < (uint8_t)(GAME_GUI_AIRCRAFT_DATA_MAX_PAGE * ptrPlayer->FlightDataPage) )
{
ptrPlayer->FlightDataPage--;
}
if(ptrPlayer->ActiveAircraft != 0)
{
while(ptrPlayer->ActiveAircraft <= (uint8_t)(GAME_GUI_AIRCRAFT_DATA_MAX_PAGE * ptrPlayer->FlightDataPage) )
{
ptrPlayer->FlightDataPage--;
}
}
while(ptrPlayer->SelectedAircraft > (uint8_t)(GAME_GUI_AIRCRAFT_DATA_MAX_PAGE * (ptrPlayer->FlightDataPage + 1)) )
{
ptrPlayer->FlightDataPage++;
}
if(ptrPlayer->ShowAircraftData == true)
{

View File

@ -17,8 +17,8 @@
#define UPLOAD_IMAGE_FLAG 1
#define MAX_LUMINANCE 0xFF
#define ROTATE_BIT_SHIFT 12
#define GPUSTAT (*(unsigned int*)0x1F801814)
#define D2_CHCR (*(unsigned int*)0x1F8010A8)
#define GPUSTAT (*(volatile unsigned int*)0x1F801814)
#define D2_CHCR (*(volatile unsigned int*)0x1F8010A8)
/* *************************************
* Structs and enums
@ -179,8 +179,18 @@ void GfxSetPrimitiveList(void)
void GfxDrawScene_Fast(void)
{
enum
{
FPS_INFO_X = 16,
FPS_INFO_Y = 16
};
SystemDevMenu();
FontSetFlags(&SmallFont, FONT_NOFLAGS);
FontPrintText(&SmallFont, FPS_INFO_X, FPS_INFO_Y, "%d/%d", SystemGetFPS(), REFRESH_FREQUENCY);
if(System1SecondTick() == true)
{
one_second_show = one_second_show? false:true;
@ -302,7 +312,7 @@ void GfxSortSprite(GsSprite * spr)
spr->x = aux_x;
}
else
{
{
GsSortSprite(spr);
}

View File

@ -261,11 +261,29 @@ void ISR_LoadMenuVBlank(void)
uint8_t i;
SystemIncreaseGlobalTimer();
if(SystemIsBusy() == true)
{
dprintf("SystemIsBusy...\n");
return;
}
if((GfxIsGPUBusy() == true))
{
dprintf("(GfxIsGPUBusy() == true)\n");
return;
}
if(SerialIsBusy() == true)
{
dprintf("Serialisbusy\n");
return;
}
if( (SystemIsBusy() == true) || (GfxIsGPUBusy() == true) || (SerialIsBusy() == true) )
/*if( (SystemIsBusy() == true) || (GfxIsGPUBusy() == true) || (SerialIsBusy() == true) )
{
return;
}
}*/
if(startup_flag == true)
{
@ -456,8 +474,6 @@ void LoadMenuLoadFileList( char* fileList[], void* dest[],
for(fileLoadedCount = 0; fileLoadedCount < szFileList ; fileLoadedCount++)
{
DEBUG_PRINT_VAR(fileLoadedCount);
strCurrentFile = fileList[fileLoadedCount];
if(strCurrentFile == NULL)

View File

@ -39,6 +39,7 @@ enum
{
MAIN_MENU_PLAY_OPTIONS_LEVEL_BUTTONS = 2,
MAIN_MENU_ONE_TWO_PLAYERS_LEVEL_BUTTONS = 2,
MAIN_MENU_ONE_TWO_PLAYERS_LEVEL_BUTTONS_PAD_TWO_DISCONNECTED = 1,
MAIN_MENU_OPTIONS_LEVEL_BUTTONS = 1
};
@ -398,19 +399,33 @@ void MainMenuButtonHandler(void)
break;
case ONE_TWO_PLAYERS_LEVEL:
max_buttons = MAIN_MENU_ONE_TWO_PLAYERS_LEVEL_BUTTONS;
if( (btn_selected == TWO_PLAYER_BUTTON_INDEX)
&&
(PadTwoConnected() == false) )
{
max_buttons = MAIN_MENU_ONE_TWO_PLAYERS_LEVEL_BUTTONS_PAD_TWO_DISCONNECTED;
}
else
{
max_buttons = MAIN_MENU_ONE_TWO_PLAYERS_LEVEL_BUTTONS;
}
if(PadOneKeySinglePress(PAD_TRIANGLE) == true)
{
menuLevel = PLAY_OPTIONS_LEVEL;
MainMenuMinimumBtn = PLAY_BUTTON_INDEX;
btn_selected = PLAY_BUTTON_INDEX;
}
break;
default:
max_buttons = 0;
break;
}
//DEBUG_PRINT_VAR(btn_selected);
MainMenuBtn[previous_btn_selected].was_selected = MainMenuBtn[previous_btn_selected].selected;
MainMenuBtn[btn_selected].was_selected = MainMenuBtn[btn_selected].selected;
@ -428,7 +443,7 @@ void MainMenuButtonHandler(void)
{
MainMenuBtn[btn_selected].selected = false;
previous_btn_selected = btn_selected;
btn_selected++;
btn_selected++;
SfxPlaySound(&BellSnd);
}
@ -447,10 +462,11 @@ void MainMenuButtonHandler(void)
{
if(menuLevel == ONE_TWO_PLAYERS_LEVEL)
{
MainMenuBtn[btn_selected].f();
// Once gameplay has finished, turn back to first level
MainMenuRestoreInitValues();
btn_selected = PLAY_BUTTON_INDEX;
// Start gameplay!
MainMenuBtn[btn_selected].f();
// Once gameplay has finished, turn back to first level
MainMenuRestoreInitValues();
btn_selected = PLAY_BUTTON_INDEX;
}
else
{
@ -536,6 +552,15 @@ void MainMenuDrawButton(TYPE_MMBtn * btn)
MenuSpr.y = MAIN_MENU_TWO_PLAYER_BUTTON_Y - MainMenuBtnAni[btn->timer];
MenuSpr.u += btn->offset_u;
MenuSpr.v += btn->offset_v;
// Exception: turn option dimmer if second player pad isn't connected
if(PadTwoConnected() == false)
{
MenuSpr.r = NORMAL_LUMINANCE >> 1;
MenuSpr.g = NORMAL_LUMINANCE >> 1;
MenuSpr.b = NORMAL_LUMINANCE >> 1;
}
GsSortSprite(&MenuSpr);
break;

View File

@ -47,7 +47,10 @@ bool SfxUploadSound(char* file_path, SsVag * vag)
SsUploadVag(vag);
vag->cur_voice = voiceIndex;
voiceIndex++;
Serial_printf("SPU voices used = %d\n", voiceIndex);
}
else
{

View File

@ -41,6 +41,9 @@ static volatile uint64_t global_timer;
static bool rand_seed;
//Screen refresh flag (called by interrupt)
static volatile bool refresh_needed;
// Frames per second measurement
static volatile uint8_t fps;
static volatile uint8_t temp_fps;
//Timers
static bool one_second_timer;
static bool hundred_ms_timer;
@ -52,6 +55,8 @@ static volatile bool system_busy;
// When true, it draws a rectangle on top of all primitives with
// information for development purposes.
static bool devmenu_flag;
// Used for sine-like effect.
static unsigned char sine_counter;
/* *******************************************************************
*
@ -111,6 +116,8 @@ void SystemInit(void)
system_busy = false;
//Development menu flag
devmenu_flag = false;
//Emergency mode flag
emergency_mode = false;
GfxSetGlobalLuminance(NORMAL_LUMINANCE);
@ -218,9 +225,99 @@ bool SystemRefreshNeeded(void)
void ISR_SystemDefaultVBlank(void)
{
if(System1SecondTick() == true)
{
fps = temp_fps;
temp_fps = 0;
}
refresh_needed = true;
}
/* *******************************************************************
*
* @name: void SystemAcknowledgeFrame(void)
*
* @author: Xavier Del Campo
*
* @brief:
*
* @remarks:
* Called by Game module in order to calculate frames per second.
*
* *******************************************************************/
void SystemAcknowledgeFrame(void)
{
temp_fps++;
}
/* *******************************************************************
*
* @name: void SystemAcknowledgeFrame(void)
*
* @author: Xavier Del Campo
*
* @brief:
* Creates a sine-line (more exactly, a parabola-like) effect and
* stores its value into a variable.
*
* @remarks:
* To be called only once, preferibly on SystemCyclic().
*
* *******************************************************************/
void SystemCalculateSine(void)
{
enum
{
SINE_EFFECT_STEP = 24,
SINE_EFFECT_MAX = 240
};
static bool sine_decrease = false;
if(sine_decrease == false)
{
if(sine_counter < SINE_EFFECT_MAX)
{
sine_counter += SINE_EFFECT_STEP;
}
else
{
sine_decrease = true;
}
}
else
{
if(sine_counter > SINE_EFFECT_STEP)
{
sine_counter -= SINE_EFFECT_STEP;
}
else
{
sine_decrease = false;
}
}
}
/* *******************************************************************
*
* @name: unsigned char SystemGetSineValue(void)
*
* @author: Xavier Del Campo
*
* @return:
* Returns a value which oscillates like a sine (more exactly, like
* a parabola) function to be used wherever you want.
*
* *******************************************************************/
unsigned char SystemGetSineValue(void)
{
return sine_counter;
}
/* *******************************************************************
*
* @name: void SystemIncreaseGlobalTimer(void)
@ -862,6 +959,21 @@ int32_t SystemIndexOf_U8(uint8_t value, uint8_t* array, uint32_t from, uint32_t
return -1;
}
/* ****************************************************************************************
*
* @name volatile uint8_t SystemGetFPS(void)
*
* @author: Xavier Del Campo
*
* @return: Frames per second
*
* ****************************************************************************************/
volatile uint8_t SystemGetFPS(void)
{
return fps;
}
/* ****************************************************************************************
*
* @name void SystemCyclicHandler(void)
@ -886,6 +998,8 @@ void SystemCyclicHandler(void)
SystemDisableScreenRefresh();
MemCardHandler();
SystemCalculateSine();
SystemCheckStack();
}

View File

@ -105,6 +105,12 @@ int32_t SystemIndexOf_U16(uint16_t value, uint16_t* array, uint32_t sz);
// Function overload for uint8_t data type.
int32_t SystemIndexOf_U8(uint8_t value, uint8_t* array, uint32_t from, uint32_t sz);
// Returns frames per second.
volatile uint8_t SystemGetFPS(void);
// Increase temp_fps in order to calculate frame rate.
void SystemAcknowledgeFrame(void);
void SystemCyclicHandler(void);
void SystemClearBuffer(void);
@ -123,6 +129,10 @@ void SystemDevMenuToggle(void);
void SystemDevMenu(void);
void SystemCalculateSine(void);
unsigned char SystemGetSineValue(void);
/* **************************************
* Global Variables *
* **************************************/