1265 lines
43 KiB
C
1265 lines
43 KiB
C
/* *************************************
|
|
* Includes
|
|
* *************************************/
|
|
|
|
#include "GameGui.h"
|
|
#include "System.h"
|
|
#include "Gfx.h"
|
|
#include "Game.h"
|
|
#include "LoadMenu.h"
|
|
#include "Timer.h"
|
|
|
|
/* *************************************
|
|
* Defines
|
|
* *************************************/
|
|
|
|
#define GAME_GUI_AIRCRAFT_DATA_MAX_PAGE 4
|
|
#define SLOW_SCORE_HIGH_SPEED 10
|
|
|
|
/* **************************************
|
|
* Structs and enums *
|
|
* *************************************/
|
|
|
|
enum
|
|
{
|
|
BUBBLE_SPRITE_X = 298,
|
|
BUBBLE_SPRITE_Y = 32,
|
|
BUBBLE_SPRITE_RAND_MIN = -3,
|
|
BUBBLE_SPRITE_RAND_MAX = 3,
|
|
|
|
NOTIFICATION_BUTTON_X = BUBBLE_SPRITE_X + 24,
|
|
NOTIFICATION_BUTTON_Y = BUBBLE_SPRITE_Y + 16
|
|
};
|
|
|
|
enum
|
|
{
|
|
PAUSE_DIALOG_X = 92,
|
|
PAUSE_DIALOG_Y = 28,
|
|
PAUSE_DIALOG_W = 200,
|
|
PAUSE_DIALOG_H = 184,
|
|
|
|
PAUSE_DIALOG_R0 = 0,
|
|
PAUSE_DIALOG_R1 = PAUSE_DIALOG_R0,
|
|
PAUSE_DIALOG_R2 = 0,
|
|
PAUSE_DIALOG_R3 = PAUSE_DIALOG_R2,
|
|
|
|
PAUSE_DIALOG_G0 = NORMAL_LUMINANCE,
|
|
PAUSE_DIALOG_G1 = PAUSE_DIALOG_G0,
|
|
PAUSE_DIALOG_G2 = 0,
|
|
PAUSE_DIALOG_G3 = PAUSE_DIALOG_G2,
|
|
|
|
PAUSE_DIALOG_B0 = 40,
|
|
PAUSE_DIALOG_B1 = PAUSE_DIALOG_B0,
|
|
PAUSE_DIALOG_B2 = 0,
|
|
PAUSE_DIALOG_B3 = PAUSE_DIALOG_B2,
|
|
};
|
|
|
|
enum
|
|
{
|
|
AIRCRAFT_DATA_GSGPOLY4_R0 = 0,
|
|
AIRCRAFT_DATA_GSGPOLY4_R1 = AIRCRAFT_DATA_GSGPOLY4_R0,
|
|
AIRCRAFT_DATA_GSGPOLY4_R2 = 0,
|
|
AIRCRAFT_DATA_GSGPOLY4_R3 = AIRCRAFT_DATA_GSGPOLY4_R2,
|
|
|
|
AIRCRAFT_DATA_GSGPOLY4_G0 = NORMAL_LUMINANCE,
|
|
AIRCRAFT_DATA_GSGPOLY4_G1 = AIRCRAFT_DATA_GSGPOLY4_G0,
|
|
AIRCRAFT_DATA_GSGPOLY4_G2 = 0,
|
|
AIRCRAFT_DATA_GSGPOLY4_G3 = AIRCRAFT_DATA_GSGPOLY4_G2,
|
|
|
|
AIRCRAFT_DATA_GSGPOLY4_B0 = 40,
|
|
AIRCRAFT_DATA_GSGPOLY4_B1 = AIRCRAFT_DATA_GSGPOLY4_B0,
|
|
AIRCRAFT_DATA_GSGPOLY4_B2 = 0,
|
|
AIRCRAFT_DATA_GSGPOLY4_B3 = AIRCRAFT_DATA_GSGPOLY4_B2,
|
|
|
|
AIRCRAFT_DATA_GSGPOLY4_X0 = (X_SCREEN_RESOLUTION >> 1) - 88,
|
|
AIRCRAFT_DATA_GSGPOLY4_X1 = (X_SCREEN_RESOLUTION >> 1) + 88,
|
|
AIRCRAFT_DATA_GSGPOLY4_X2 = AIRCRAFT_DATA_GSGPOLY4_X0,
|
|
AIRCRAFT_DATA_GSGPOLY4_X3 = AIRCRAFT_DATA_GSGPOLY4_X1,
|
|
|
|
AIRCRAFT_DATA_GSGPOLY4_Y0 = (Y_SCREEN_RESOLUTION >> 1) - 96,
|
|
AIRCRAFT_DATA_GSGPOLY4_Y1 = AIRCRAFT_DATA_GSGPOLY4_Y0,
|
|
AIRCRAFT_DATA_GSGPOLY4_Y2 = (Y_SCREEN_RESOLUTION >> 1) + 96,
|
|
AIRCRAFT_DATA_GSGPOLY4_Y3 = AIRCRAFT_DATA_GSGPOLY4_Y2,
|
|
|
|
AIRCRAFT_DATA_GSGPOLY4_X0_2PLAYER = 24,
|
|
AIRCRAFT_DATA_GSGPOLY4_X1_2PLAYER = 168,
|
|
AIRCRAFT_DATA_GSGPOLY4_X2_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_X0_2PLAYER,
|
|
AIRCRAFT_DATA_GSGPOLY4_X3_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_X1_2PLAYER,
|
|
|
|
AIRCRAFT_DATA_GSGPOLY4_Y0_2PLAYER = 24,
|
|
AIRCRAFT_DATA_GSGPOLY4_Y1_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_Y0_2PLAYER,
|
|
AIRCRAFT_DATA_GSGPOLY4_Y2_2PLAYER = 208,
|
|
AIRCRAFT_DATA_GSGPOLY4_Y3_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_Y2_2PLAYER,
|
|
};
|
|
|
|
enum
|
|
{
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R0 = NORMAL_LUMINANCE,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R1 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R0,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R2 = 0,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R3 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R2,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G0 = NORMAL_LUMINANCE,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G1 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G0,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G2 = 0,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G3 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G2,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B0 = NORMAL_LUMINANCE,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B1 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B0,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B2 = 0,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B3 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B2,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP = 8,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0 = AIRCRAFT_DATA_GSGPOLY4_X0 + 24,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1 = AIRCRAFT_DATA_GSGPOLY4_X1 - 24,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X2 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X3 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H = 42,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0 = AIRCRAFT_DATA_GSGPOLY4_Y0 + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y1 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0 + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y3 = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_X0_2PLAYER + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_X1_2PLAYER - AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X2_2PLAYER = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0_2PLAYER,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X3_2PLAYER = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1_2PLAYER,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_Y0_2PLAYER + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y1_2PLAYER = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0_2PLAYER,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2_2PLAYER = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0_2PLAYER + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H,
|
|
AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y3_2PLAYER = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2_2PLAYER
|
|
};
|
|
|
|
enum
|
|
{
|
|
AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_X = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0 + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0 + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_X_2PLAYER = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0_2PLAYER + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y_2PLAYER = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0_2PLAYER + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
|
|
AIRCRAFT_DATA_DIRECTION_X = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_X,
|
|
AIRCRAFT_DATA_DIRECTION_Y = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
|
|
AIRCRAFT_DATA_DIRECTION_X_2PLAYER = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_X_2PLAYER,
|
|
AIRCRAFT_DATA_DIRECTION_Y_2PLAYER = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y_2PLAYER + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
|
|
AIRCRAFT_DATA_PASSENGERS_X = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_X + 64,
|
|
AIRCRAFT_DATA_PASSENGERS_Y = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y,
|
|
|
|
AIRCRAFT_DATA_PASSENGERS_X_2PLAYER = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_X_2PLAYER + 64,
|
|
AIRCRAFT_DATA_PASSENGERS_Y_2PLAYER = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y_2PLAYER,
|
|
|
|
AIRCRAFT_DATA_REMAINING_TIME_X = AIRCRAFT_DATA_DIRECTION_X + 24,
|
|
AIRCRAFT_DATA_REMAINING_TIME_Y = AIRCRAFT_DATA_DIRECTION_Y + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
|
|
AIRCRAFT_DATA_REMAINING_TIME_X_2PLAYER = AIRCRAFT_DATA_DIRECTION_X_2PLAYER + 24,
|
|
AIRCRAFT_DATA_REMAINING_TIME_Y_2PLAYER = AIRCRAFT_DATA_DIRECTION_Y_2PLAYER + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP,
|
|
};
|
|
|
|
enum
|
|
{
|
|
AIRCRAFT_DEPARTURE_ARRIVAL_ICON_SIZE = 16,
|
|
AIRCRAFT_ARRIVAL_ICON_U = 0,
|
|
AIRCRAFT_DEPARTURE_ICON_U = 16
|
|
};
|
|
|
|
enum
|
|
{
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_X = 112,
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_Y = 112,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_X_2PLAYER = 48,
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_Y_2PLAYER = 112,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_UP_X = 260,
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_UP_Y = AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_Y,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_UP_X_2PLAYER = 128,
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_UP_Y_2PLAYER = AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_Y_2PLAYER,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_UP_U = 16,
|
|
AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_U = 0,
|
|
|
|
AIRCRAFT_DATA_FLIGHT_PAGEUPDN_SIZE = 16
|
|
};
|
|
|
|
enum
|
|
{
|
|
GAME_GUI_SECOND_DISPLAY_X = 384,
|
|
GAME_GUI_SECOND_DISPLAY_Y = 256,
|
|
GAME_GUI_SECOND_DISPLAY_TPAGE = 22,
|
|
};
|
|
|
|
/* **************************************
|
|
* Local prototypes *
|
|
* *************************************/
|
|
|
|
static void GameGuiShowAircraftData(TYPE_PLAYER* const ptrPlayer, TYPE_FLIGHT_DATA* const ptrFlightData);
|
|
static void GameGuiClearPassengersLeft(void);
|
|
static void GameGuiBubbleStop(void);
|
|
static void GameGuiBubbleStopVibration(void);
|
|
|
|
/* **************************************
|
|
* Local variables *
|
|
* *************************************/
|
|
|
|
static GsSprite BubbleSpr;
|
|
static GsGPoly4 AircraftDataGPoly4;
|
|
static GsGPoly4 SelectedAircraftGPoly4 =
|
|
{
|
|
.r[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R0,
|
|
.r[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R1,
|
|
.r[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R2,
|
|
.r[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R3,
|
|
|
|
.g[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G0,
|
|
.g[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G1,
|
|
.g[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G2,
|
|
.g[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G3,
|
|
|
|
.b[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B0,
|
|
.b[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B1,
|
|
.b[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B2,
|
|
.b[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B3,
|
|
|
|
.attribute = ENABLE_TRANS | TRANS_MODE(0)
|
|
};
|
|
|
|
static const GsGPoly4 PauseRect =
|
|
{
|
|
.x[0] = PAUSE_DIALOG_X,
|
|
.x[1] = PAUSE_DIALOG_X + PAUSE_DIALOG_W,
|
|
.x[2] = PAUSE_DIALOG_X,
|
|
.x[3] = PAUSE_DIALOG_X + PAUSE_DIALOG_W,
|
|
|
|
.y[0] = PAUSE_DIALOG_Y,
|
|
.y[1] = PAUSE_DIALOG_Y,
|
|
.y[2] = PAUSE_DIALOG_Y + PAUSE_DIALOG_H,
|
|
.y[3] = PAUSE_DIALOG_Y + PAUSE_DIALOG_H,
|
|
|
|
.r[0] = PAUSE_DIALOG_R0,
|
|
.r[1] = PAUSE_DIALOG_R1,
|
|
.r[2] = PAUSE_DIALOG_R2,
|
|
.r[3] = PAUSE_DIALOG_R3,
|
|
|
|
.b[0] = PAUSE_DIALOG_B0,
|
|
.b[1] = PAUSE_DIALOG_B1,
|
|
.b[2] = PAUSE_DIALOG_B2,
|
|
.b[3] = PAUSE_DIALOG_B3,
|
|
|
|
.g[0] = PAUSE_DIALOG_G0,
|
|
.g[1] = PAUSE_DIALOG_G1,
|
|
.g[2] = PAUSE_DIALOG_G2,
|
|
.g[3] = PAUSE_DIALOG_G3,
|
|
|
|
.attribute = ENABLE_TRANS | TRANS_MODE(0)
|
|
};
|
|
|
|
static GsSprite SecondDisplay;
|
|
static GsSprite DepArrSpr;
|
|
static GsSprite PageUpDownSpr;
|
|
static TYPE_TIMER* ShowAircraftPassengersTimer;
|
|
static bool GameGuiClearPassengersLeft_Flag;
|
|
static bool showBubble;
|
|
static bool bubbleVibration;
|
|
|
|
static const char* GameFileList[] = { "DATA\\SPRITES\\BUBBLE.TIM" ,
|
|
"DATA\\FONTS\\FONT_1.FNT" ,
|
|
"DATA\\SPRITES\\DEPARR.TIM" ,
|
|
"DATA\\SPRITES\\PAGEUPDN.TIM" };
|
|
|
|
static void* GameFileDest[] = { (GsSprite*)&BubbleSpr ,
|
|
(TYPE_FONT*)&RadioFont ,
|
|
(GsSprite*)&DepArrSpr ,
|
|
(GsSprite*)&PageUpDownSpr };
|
|
|
|
static uint32_t slowScore; // It will update slowly to actual score value
|
|
|
|
/* ***************************************************************************************
|
|
*
|
|
* @name: void GameGuiInit(void)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Reportedly, GameGui module initialization.
|
|
*
|
|
* ***************************************************************************************/
|
|
void GameGuiInit(void)
|
|
{
|
|
enum
|
|
{
|
|
RADIO_FONT_SPACING = 12
|
|
};
|
|
|
|
static bool initialised;
|
|
|
|
if (initialised == false)
|
|
{
|
|
initialised = true;
|
|
|
|
LOAD_FILES(GameFileList, GameFileDest);
|
|
ShowAircraftPassengersTimer = TimerCreate(20, true, GameGuiClearPassengersLeft);
|
|
}
|
|
|
|
PageUpDownSpr.w = AIRCRAFT_DATA_FLIGHT_PAGEUPDN_SIZE;
|
|
|
|
// Prepare RGB data and (X,Y) coordinates for aircraft
|
|
// data list request rectangle.
|
|
AircraftDataGPoly4.r[0] = AIRCRAFT_DATA_GSGPOLY4_R0;
|
|
AircraftDataGPoly4.r[1] = AIRCRAFT_DATA_GSGPOLY4_R1;
|
|
AircraftDataGPoly4.r[2] = AIRCRAFT_DATA_GSGPOLY4_R2;
|
|
AircraftDataGPoly4.r[3] = AIRCRAFT_DATA_GSGPOLY4_R3;
|
|
|
|
AircraftDataGPoly4.g[0] = AIRCRAFT_DATA_GSGPOLY4_G0;
|
|
AircraftDataGPoly4.g[1] = AIRCRAFT_DATA_GSGPOLY4_G1;
|
|
AircraftDataGPoly4.g[2] = AIRCRAFT_DATA_GSGPOLY4_G2;
|
|
AircraftDataGPoly4.g[3] = AIRCRAFT_DATA_GSGPOLY4_G3;
|
|
|
|
AircraftDataGPoly4.b[0] = AIRCRAFT_DATA_GSGPOLY4_B0;
|
|
AircraftDataGPoly4.b[1] = AIRCRAFT_DATA_GSGPOLY4_B1;
|
|
AircraftDataGPoly4.b[2] = AIRCRAFT_DATA_GSGPOLY4_B2;
|
|
AircraftDataGPoly4.b[3] = AIRCRAFT_DATA_GSGPOLY4_B3;
|
|
|
|
slowScore = 0;
|
|
|
|
showBubble = false;
|
|
|
|
FontSetSpacing(&RadioFont, RADIO_FONT_SPACING);
|
|
}
|
|
|
|
/* ***************************************************************************************
|
|
*
|
|
* @name: bool GameGuiPauseDialog(const TYPE_PLAYER* const ptrPlayer)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Checks for pause event (player presses START button). If true, it traps the game
|
|
* on a while loop, waiting for user action.
|
|
*
|
|
* @remarks:
|
|
* Blocking function!
|
|
*
|
|
* ***************************************************************************************/
|
|
bool GameGuiPauseDialog(const TYPE_PLAYER* const ptrPlayer)
|
|
{
|
|
GfxSaveDisplayData(&SecondDisplay);
|
|
|
|
GfxSetGlobalLuminance(NORMAL_LUMINANCE);
|
|
|
|
while (GfxIsGPUBusy());
|
|
|
|
do
|
|
{
|
|
if (ptrPlayer->PadKeySinglePress_Callback(PAD_CROSS))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
GfxSortSprite(&SecondDisplay);
|
|
|
|
GsSortGPoly4(&PauseRect);
|
|
|
|
GfxDrawScene_Slow();
|
|
|
|
} while (ptrPlayer->PadKeySinglePress_Callback(PAD_START) == false);
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/* ******************************************************************************************************
|
|
*
|
|
* @name: void GameGuiCalculateNextAircraftTime(TYPE_PLAYER* const ptrPlayer, TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Updates ptrPlayer->NextAircraftTime with next aircraft remaining time.
|
|
*
|
|
* ******************************************************************************************************/
|
|
void GameGuiCalculateNextAircraftTime(TYPE_PLAYER* const ptrPlayer, TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
{
|
|
uint8_t i;
|
|
uint16_t minRemainingTime = USHRT_MAX;
|
|
|
|
for (i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
|
{
|
|
if ( (ptrFlightData->State[i] == STATE_IDLE)
|
|
&&
|
|
( (ptrPlayer->FlightDirection & ptrFlightData->FlightDirection[i]) != 0)
|
|
&&
|
|
( (ptrFlightData->Hours[i] != 0)
|
|
||
|
|
(ptrFlightData->Minutes[i] != 0) ) )
|
|
{
|
|
const uint16_t seconds = (ptrFlightData->Hours[i] * 60) + (ptrFlightData->Minutes[i]);
|
|
|
|
if (seconds < minRemainingTime)
|
|
{
|
|
minRemainingTime = seconds;
|
|
}
|
|
}
|
|
}
|
|
|
|
ptrPlayer->NextAircraftTime = minRemainingTime;
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiActiveAircraftPage(TYPE_PLAYER* const ptrPlayer, TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Updates ptrPlayer->SelectedAircraft and ptrPlayer->FlightDataPage when new aircraft are
|
|
* added/removed. On the other hand, it also updates ptrPlayer->SelectedAircraft depending on
|
|
* user interaction.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiActiveAircraftPage(TYPE_PLAYER* const ptrPlayer, TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
{
|
|
if (ptrPlayer->ActiveAircraft != 0)
|
|
{
|
|
while (ptrPlayer->ActiveAircraft <= ptrPlayer->SelectedAircraft)
|
|
{
|
|
ptrPlayer->SelectedAircraft--;
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
if (ptrPlayer->PadKeySinglePress_Callback(PAD_DOWN))
|
|
{
|
|
if ( ( (ptrPlayer->SelectedAircraft + 1) < ptrPlayer->ActiveAircraft)
|
|
&&
|
|
( (ptrPlayer->SelectedAircraft + 1) < ( (ptrPlayer->FlightDataPage + 1) * GAME_GUI_AIRCRAFT_DATA_MAX_PAGE) ) )
|
|
{
|
|
ptrPlayer->SelectedAircraft++;
|
|
}
|
|
}
|
|
|
|
if (ptrPlayer->PadKeySinglePress_Callback(PAD_UP))
|
|
{
|
|
if (ptrPlayer->SelectedAircraft > ( (ptrPlayer->FlightDataPage) * GAME_GUI_AIRCRAFT_DATA_MAX_PAGE) )
|
|
{
|
|
ptrPlayer->SelectedAircraft--;
|
|
}
|
|
}
|
|
|
|
if (ptrPlayer->PadKeySinglePress_Callback(PAD_RIGHT))
|
|
{
|
|
if (ptrPlayer->ActiveAircraft > (GAME_GUI_AIRCRAFT_DATA_MAX_PAGE * (ptrPlayer->FlightDataPage + 1) ) )
|
|
{
|
|
ptrPlayer->FlightDataPage++;
|
|
ptrPlayer->SelectedAircraft = ptrPlayer->FlightDataPage * GAME_GUI_AIRCRAFT_DATA_MAX_PAGE;
|
|
Serial_printf("Selected Aircraft = %d\n",ptrPlayer->SelectedAircraft);
|
|
}
|
|
}
|
|
|
|
if (ptrPlayer->PadKeySinglePress_Callback(PAD_LEFT))
|
|
{
|
|
if (ptrPlayer->FlightDataPage != 0)
|
|
{
|
|
ptrPlayer->FlightDataPage--;
|
|
ptrPlayer->SelectedAircraft = ptrPlayer->FlightDataPage * GAME_GUI_AIRCRAFT_DATA_MAX_PAGE;
|
|
Serial_printf("Selected Aircraft = %d\n",ptrPlayer->SelectedAircraft);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiAircraftList(TYPE_PLAYER* const ptrPlayer, TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Draws aircraft list for current player when ptrPlayer->ShowAircraftData state is active.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiAircraftList(TYPE_PLAYER* const ptrPlayer, TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
{
|
|
short y_offset;
|
|
uint8_t page_aircraft;
|
|
short orig_pageupdn_u;
|
|
|
|
enum
|
|
{
|
|
GAME_GUI_REMAINING_AIRCRAFT_X = AIRCRAFT_DATA_GSGPOLY4_X0 + 16,
|
|
GAME_GUI_REMAINING_AIRCRAFT_Y = AIRCRAFT_DATA_GSGPOLY4_Y2 - 16,
|
|
GAME_GUI_REMAINING_AIRCRAFT_X_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_X0_2PLAYER + 4,
|
|
GAME_GUI_REMAINING_AIRCRAFT_Y_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_Y2_2PLAYER - 16
|
|
};
|
|
|
|
enum
|
|
{
|
|
GAME_GUI_NEXT_AIRCRAFT_TIME_X = GAME_GUI_REMAINING_AIRCRAFT_X,
|
|
GAME_GUI_NEXT_AIRCRAFT_TIME_Y = GAME_GUI_REMAINING_AIRCRAFT_Y + 8,
|
|
GAME_GUI_NEXT_AIRCRAFT_TIME_X_2PLAYER = GAME_GUI_REMAINING_AIRCRAFT_X_2PLAYER,
|
|
GAME_GUI_NEXT_AIRCRAFT_TIME_Y_2PLAYER = GAME_GUI_REMAINING_AIRCRAFT_Y_2PLAYER + 8,
|
|
};
|
|
|
|
enum
|
|
{
|
|
AIRCRAFT_STOP_X = 32,
|
|
AIRCRAFT_STOP_TEXT_X = AIRCRAFT_STOP_X + 32,
|
|
AIRCRAFT_STOP_Y = 224,
|
|
AIRCRAFT_STOP_TEXT_Y = AIRCRAFT_STOP_Y + 4
|
|
};
|
|
|
|
if (ptrPlayer->ShowAircraftData)
|
|
{
|
|
AircraftDataGPoly4.attribute |= ENABLE_TRANS | TRANS_MODE(0);
|
|
|
|
if (GameTwoPlayersActive())
|
|
{
|
|
AircraftDataGPoly4.x[0] = AIRCRAFT_DATA_GSGPOLY4_X0_2PLAYER;
|
|
AircraftDataGPoly4.x[1] = AIRCRAFT_DATA_GSGPOLY4_X1_2PLAYER;
|
|
AircraftDataGPoly4.x[2] = AIRCRAFT_DATA_GSGPOLY4_X2_2PLAYER;
|
|
AircraftDataGPoly4.x[3] = AIRCRAFT_DATA_GSGPOLY4_X3_2PLAYER;
|
|
|
|
AircraftDataGPoly4.y[0] = AIRCRAFT_DATA_GSGPOLY4_Y0_2PLAYER;
|
|
AircraftDataGPoly4.y[1] = AIRCRAFT_DATA_GSGPOLY4_Y1_2PLAYER;
|
|
AircraftDataGPoly4.y[2] = AIRCRAFT_DATA_GSGPOLY4_Y2_2PLAYER;
|
|
AircraftDataGPoly4.y[3] = AIRCRAFT_DATA_GSGPOLY4_Y3_2PLAYER;
|
|
}
|
|
else
|
|
{
|
|
AircraftDataGPoly4.x[0] = AIRCRAFT_DATA_GSGPOLY4_X0;
|
|
AircraftDataGPoly4.x[1] = AIRCRAFT_DATA_GSGPOLY4_X1;
|
|
AircraftDataGPoly4.x[2] = AIRCRAFT_DATA_GSGPOLY4_X2;
|
|
AircraftDataGPoly4.x[3] = AIRCRAFT_DATA_GSGPOLY4_X3;
|
|
|
|
AircraftDataGPoly4.y[0] = AIRCRAFT_DATA_GSGPOLY4_Y0;
|
|
AircraftDataGPoly4.y[1] = AIRCRAFT_DATA_GSGPOLY4_Y1;
|
|
AircraftDataGPoly4.y[2] = AIRCRAFT_DATA_GSGPOLY4_Y2;
|
|
AircraftDataGPoly4.y[3] = AIRCRAFT_DATA_GSGPOLY4_Y3;
|
|
}
|
|
|
|
GsSortGPoly4(&AircraftDataGPoly4);
|
|
|
|
const struct
|
|
{
|
|
struct pos
|
|
{
|
|
short x;
|
|
short y;
|
|
} remainingTime;
|
|
|
|
struct pos aircraftTime;
|
|
} posData =
|
|
{
|
|
.remainingTime =
|
|
{
|
|
.x = GameTwoPlayersActive() ?
|
|
GAME_GUI_REMAINING_AIRCRAFT_X_2PLAYER
|
|
: GAME_GUI_REMAINING_AIRCRAFT_X,
|
|
.y = GameTwoPlayersActive() ?
|
|
GAME_GUI_REMAINING_AIRCRAFT_Y_2PLAYER
|
|
:GAME_GUI_REMAINING_AIRCRAFT_Y
|
|
},
|
|
|
|
.aircraftTime =
|
|
{
|
|
.x = GameTwoPlayersActive() ?
|
|
GAME_GUI_NEXT_AIRCRAFT_TIME_X_2PLAYER
|
|
: GAME_GUI_NEXT_AIRCRAFT_TIME_X,
|
|
.y = GameTwoPlayersActive() ?
|
|
GAME_GUI_NEXT_AIRCRAFT_TIME_Y_2PLAYER
|
|
: GAME_GUI_NEXT_AIRCRAFT_TIME_Y
|
|
},
|
|
};
|
|
|
|
if (ptrPlayer->RemainingAircraft
|
|
&&
|
|
(ptrPlayer->NextAircraftTime != USHRT_MAX))
|
|
{
|
|
FontPrintText(&SmallFont,
|
|
posData.remainingTime.x,
|
|
posData.remainingTime.y,
|
|
"Remaining aircraft: %d",
|
|
ptrPlayer->RemainingAircraft);
|
|
|
|
FontPrintText(&SmallFont,
|
|
posData.aircraftTime.x,
|
|
posData.aircraftTime.y,
|
|
"Next aircraft: %d sec",
|
|
ptrPlayer->NextAircraftTime);
|
|
}
|
|
else
|
|
{
|
|
FontPrintText(&SmallFont,
|
|
posData.remainingTime.x,
|
|
posData.remainingTime.y,
|
|
"No aircraft left");
|
|
}
|
|
|
|
if (ptrPlayer->ActiveAircraft != 0)
|
|
{
|
|
if (GameTwoPlayersActive())
|
|
{
|
|
SelectedAircraftGPoly4.x[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0_2PLAYER;
|
|
SelectedAircraftGPoly4.x[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1_2PLAYER;
|
|
SelectedAircraftGPoly4.x[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X2_2PLAYER;
|
|
SelectedAircraftGPoly4.x[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X3_2PLAYER;
|
|
}
|
|
else
|
|
{
|
|
SelectedAircraftGPoly4.x[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0;
|
|
SelectedAircraftGPoly4.x[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1;
|
|
SelectedAircraftGPoly4.x[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X2;
|
|
SelectedAircraftGPoly4.x[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X3;
|
|
}
|
|
|
|
page_aircraft = (ptrPlayer->SelectedAircraft) - (ptrPlayer->FlightDataPage * GAME_GUI_AIRCRAFT_DATA_MAX_PAGE);
|
|
|
|
y_offset = (short)(page_aircraft * AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H);
|
|
|
|
if (GameTwoPlayersActive())
|
|
{
|
|
SelectedAircraftGPoly4.y[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0_2PLAYER;
|
|
SelectedAircraftGPoly4.y[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y1_2PLAYER;
|
|
SelectedAircraftGPoly4.y[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2_2PLAYER;
|
|
SelectedAircraftGPoly4.y[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y3_2PLAYER;
|
|
}
|
|
else
|
|
{
|
|
SelectedAircraftGPoly4.y[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0;
|
|
SelectedAircraftGPoly4.y[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y1;
|
|
SelectedAircraftGPoly4.y[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2;
|
|
SelectedAircraftGPoly4.y[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y3;
|
|
}
|
|
|
|
SelectedAircraftGPoly4.y[0] += y_offset;
|
|
SelectedAircraftGPoly4.y[1] += y_offset;
|
|
SelectedAircraftGPoly4.y[2] += y_offset;
|
|
SelectedAircraftGPoly4.y[3] += y_offset;
|
|
|
|
GsSortGPoly4(&SelectedAircraftGPoly4);
|
|
|
|
PageUpDownSpr.attribute |= GFX_2HZ_FLASH;
|
|
|
|
if (ptrPlayer->ActiveAircraft > (GAME_GUI_AIRCRAFT_DATA_MAX_PAGE * (ptrPlayer->FlightDataPage + 1) ) )
|
|
{
|
|
orig_pageupdn_u = PageUpDownSpr.u;
|
|
|
|
PageUpDownSpr.u = orig_pageupdn_u + AIRCRAFT_DATA_FLIGHT_PAGE_UP_U;
|
|
|
|
if (GameTwoPlayersActive())
|
|
{
|
|
PageUpDownSpr.x = AIRCRAFT_DATA_FLIGHT_PAGE_UP_X_2PLAYER;
|
|
PageUpDownSpr.y = AIRCRAFT_DATA_FLIGHT_PAGE_UP_Y_2PLAYER;
|
|
}
|
|
else
|
|
{
|
|
PageUpDownSpr.x = AIRCRAFT_DATA_FLIGHT_PAGE_UP_X;
|
|
PageUpDownSpr.y = AIRCRAFT_DATA_FLIGHT_PAGE_UP_Y;
|
|
}
|
|
|
|
GfxSortSprite(&PageUpDownSpr);
|
|
|
|
PageUpDownSpr.u = orig_pageupdn_u;
|
|
}
|
|
|
|
if (ptrPlayer->FlightDataPage != 0)
|
|
{
|
|
orig_pageupdn_u = PageUpDownSpr.u;
|
|
|
|
PageUpDownSpr.u = orig_pageupdn_u + AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_U;
|
|
|
|
if (GameTwoPlayersActive())
|
|
{
|
|
PageUpDownSpr.x = AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_X_2PLAYER;
|
|
PageUpDownSpr.y = AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_Y_2PLAYER;
|
|
}
|
|
else
|
|
{
|
|
PageUpDownSpr.x = AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_X;
|
|
PageUpDownSpr.y = AIRCRAFT_DATA_FLIGHT_PAGE_DOWN_Y;
|
|
}
|
|
|
|
GfxSortSprite(&PageUpDownSpr);
|
|
|
|
PageUpDownSpr.u = orig_pageupdn_u;
|
|
}
|
|
|
|
GameGuiShowAircraftData(ptrPlayer, ptrFlightData);
|
|
|
|
if (ptrFlightData->State[ptrPlayer->FlightDataSelectedAircraft] == STATE_USER_STOPPED)
|
|
{
|
|
GfxDrawButton(AIRCRAFT_STOP_X, AIRCRAFT_STOP_Y, PAD_L1);
|
|
FontPrintText(&SmallFont, AIRCRAFT_STOP_TEXT_X, AIRCRAFT_STOP_TEXT_Y, "Resume taxiing");
|
|
}
|
|
else if (ptrFlightData->State[ptrPlayer->FlightDataSelectedAircraft] == STATE_TAXIING)
|
|
{
|
|
GfxDrawButton(AIRCRAFT_STOP_X, AIRCRAFT_STOP_Y, PAD_L1);
|
|
FontPrintText(&SmallFont, AIRCRAFT_STOP_TEXT_X, AIRCRAFT_STOP_TEXT_Y, "Stop immediately");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GameTwoPlayersActive())
|
|
{
|
|
FontPrintText( &SmallFont,
|
|
AIRCRAFT_DATA_GSGPOLY4_X0_2PLAYER +
|
|
( (AIRCRAFT_DATA_GSGPOLY4_X1_2PLAYER - AIRCRAFT_DATA_GSGPOLY4_X0_2PLAYER) >> 2),
|
|
AIRCRAFT_DATA_GSGPOLY4_Y0_2PLAYER +
|
|
( (AIRCRAFT_DATA_GSGPOLY4_Y2_2PLAYER - AIRCRAFT_DATA_GSGPOLY4_Y0_2PLAYER) >> 1),
|
|
"No flights!" );
|
|
}
|
|
else
|
|
{
|
|
FontPrintText( &SmallFont,
|
|
AIRCRAFT_DATA_GSGPOLY4_X0 +
|
|
( (AIRCRAFT_DATA_GSGPOLY4_X1 - AIRCRAFT_DATA_GSGPOLY4_X0) >> 2),
|
|
AIRCRAFT_DATA_GSGPOLY4_Y0 +
|
|
( (AIRCRAFT_DATA_GSGPOLY4_Y2 - AIRCRAFT_DATA_GSGPOLY4_Y0) >> 1),
|
|
"No flights!" );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiBubbleShow(void)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Handler for GameGuiBubbleTimer.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiBubbleShow(void)
|
|
{
|
|
static TYPE_TIMER* GameGuiBubbleTimer;
|
|
|
|
if (GameGuiBubbleTimer == NULL)
|
|
{
|
|
GameGuiBubbleTimer = TimerCreate(50, false, &GameGuiBubbleStop);
|
|
}
|
|
else
|
|
{
|
|
TimerRestart(GameGuiBubbleTimer);
|
|
}
|
|
|
|
showBubble = true;
|
|
bubbleVibration = true;
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiBubble(TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* When a new aircraft is spawned, a bubble is temporarily shown on screen to notify players.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiBubble(TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
{
|
|
static bool GameGuiBubbleShowFlagOld;
|
|
|
|
if (showBubble)
|
|
{
|
|
static TYPE_TIMER* GameGuiBubbleVibrationTimer = NULL;
|
|
|
|
if (GameGuiBubbleShowFlagOld == false)
|
|
{
|
|
if (GameGuiBubbleVibrationTimer == NULL)
|
|
{
|
|
Serial_printf("Started GameGuiBubbleVibrationTimer...\n");
|
|
GameGuiBubbleVibrationTimer = TimerCreate(20, false, &GameGuiBubbleStopVibration);
|
|
}
|
|
else
|
|
{
|
|
TimerRestart(GameGuiBubbleVibrationTimer);
|
|
}
|
|
}
|
|
|
|
BubbleSpr.x = BUBBLE_SPRITE_X;
|
|
BubbleSpr.y = BUBBLE_SPRITE_Y;
|
|
|
|
if (bubbleVibration)
|
|
{
|
|
BubbleSpr.x += SystemRand(BUBBLE_SPRITE_RAND_MIN, BUBBLE_SPRITE_RAND_MAX);
|
|
BubbleSpr.y += SystemRand(BUBBLE_SPRITE_RAND_MIN, BUBBLE_SPRITE_RAND_MAX);
|
|
}
|
|
|
|
GfxSortSprite(&BubbleSpr);
|
|
FontSetFlags(&SmallFont, FONT_CENTERED);
|
|
FontPrintText(&SmallFont,BubbleSpr.x + 8 , BubbleSpr.y + 2, "%d", ptrFlightData->ActiveAircraft);
|
|
|
|
GfxDrawButton(NOTIFICATION_BUTTON_X, NOTIFICATION_BUTTON_Y, PAD_CIRCLE);
|
|
}
|
|
|
|
GameGuiBubbleShowFlagOld = showBubble;
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiClock(uint8_t hour, uint8_t min)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Shows clock time on screen.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiClock(uint8_t hour, uint8_t min)
|
|
{
|
|
enum
|
|
{
|
|
CLOCK_X = 16,
|
|
CLOCK_Y = 4
|
|
};
|
|
|
|
static char strClock[6]; // HH:MM + \0 (6 characters needed)
|
|
|
|
if (GameStartupFlag || System1SecondTick())
|
|
{
|
|
memset(strClock, 0, 6);
|
|
snprintf(strClock,6,"%02d:%02d",hour, min);
|
|
}
|
|
|
|
RadioFont.max_ch_wrap = 0;
|
|
FontSetFlags(&RadioFont, FONT_NOFLAGS);
|
|
FontPrintText(&RadioFont,CLOCK_X,CLOCK_Y,strClock);
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiShowPassengersLeft(TYPE_PLAYER* const ptrPlayer)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* TODO
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiShowPassengersLeft(TYPE_PLAYER* const ptrPlayer)
|
|
{
|
|
if (GameGuiClearPassengersLeft_Flag)
|
|
{
|
|
// Reset flag
|
|
GameGuiClearPassengersLeft_Flag = false;
|
|
ptrPlayer->PassengersLeftSelectedAircraft = 0;
|
|
}
|
|
|
|
if (ptrPlayer->PassengersLeftSelectedAircraft != 0)
|
|
{
|
|
if (GameTwoPlayersActive())
|
|
{
|
|
FontPrintText(&SmallFont, 48, Y_SCREEN_RESOLUTION - 64, "%d passengers left", ptrPlayer->PassengersLeftSelectedAircraft);
|
|
}
|
|
else
|
|
{
|
|
FontPrintText(&SmallFont, 128, Y_SCREEN_RESOLUTION - 64, "%d pax. left", ptrPlayer->PassengersLeftSelectedAircraft);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiShowAircraftData(TYPE_PLAYER* const ptrPlayer, TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Reportedly, renders all aircraft data from a list on screen for a given TYPE_PLAYER and
|
|
* TYPE_FLIGHT_DATA instances.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiShowAircraftData(TYPE_PLAYER* const ptrPlayer, TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
{
|
|
uint8_t init_flight = ptrPlayer->FlightDataPage * GAME_GUI_AIRCRAFT_DATA_MAX_PAGE;
|
|
uint8_t i;
|
|
uint8_t j;
|
|
short AircraftDataDirection_X;
|
|
short AircraftDataDirection_Y;
|
|
short AircraftDataFlightNumber_X;
|
|
short AircraftDataFlightNumber_Y;
|
|
//short AircraftDataPassengers_X;
|
|
//short AircraftDataPassengers_Y;
|
|
short AircraftDataState_X_Offset;
|
|
short AircraftDataRemainingTime_X;
|
|
short AircraftDataRemainingTime_Y;
|
|
short orig_DepArr_u = DepArrSpr.u;
|
|
|
|
if (GameTwoPlayersActive())
|
|
{
|
|
AircraftDataDirection_X = AIRCRAFT_DATA_DIRECTION_X_2PLAYER;
|
|
AircraftDataDirection_Y = AIRCRAFT_DATA_DIRECTION_Y_2PLAYER;
|
|
AircraftDataFlightNumber_X = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_X_2PLAYER;
|
|
AircraftDataFlightNumber_Y = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y_2PLAYER;
|
|
//AircraftDataPassengers_X = AIRCRAFT_DATA_PASSENGERS_X_2PLAYER;
|
|
//AircraftDataPassengers_Y = AIRCRAFT_DATA_PASSENGERS_Y_2PLAYER;
|
|
AircraftDataState_X_Offset = 24;
|
|
AircraftDataRemainingTime_X = AIRCRAFT_DATA_REMAINING_TIME_X_2PLAYER;
|
|
AircraftDataRemainingTime_Y = AIRCRAFT_DATA_REMAINING_TIME_Y_2PLAYER;
|
|
}
|
|
else
|
|
{
|
|
AircraftDataDirection_X = AIRCRAFT_DATA_DIRECTION_X;
|
|
AircraftDataDirection_Y = AIRCRAFT_DATA_DIRECTION_Y;
|
|
AircraftDataFlightNumber_X = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_X;
|
|
AircraftDataFlightNumber_Y = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y;
|
|
//AircraftDataPassengers_X = AIRCRAFT_DATA_PASSENGERS_X;
|
|
//AircraftDataPassengers_Y = AIRCRAFT_DATA_PASSENGERS_Y;
|
|
AircraftDataState_X_Offset = 24;
|
|
AircraftDataRemainingTime_X = AIRCRAFT_DATA_REMAINING_TIME_X;
|
|
AircraftDataRemainingTime_Y = AIRCRAFT_DATA_REMAINING_TIME_Y;
|
|
}
|
|
|
|
FontSetFlags(&SmallFont,FONT_NOFLAGS);
|
|
|
|
for (i = init_flight ; i < ptrPlayer->ActiveAircraft ; i++)
|
|
{
|
|
static const char* const strAircraftArray[MAX_STATES] =
|
|
{
|
|
[STATE_APPROACH] = "Approach",
|
|
[STATE_READY_FOR_TAKEOFF] = "Takeoff",
|
|
[STATE_LANDED] = "Landed",
|
|
[STATE_PARKED] = "Parked",
|
|
[STATE_UNBOARDING] = "Unboard",
|
|
[STATE_HOLDING_RWY] = "Holding",
|
|
[STATE_USER_STOPPED] = "Stopped",
|
|
[STATE_AUTO_STOPPED] = "Stopped"
|
|
};
|
|
|
|
FL_STATE aircraftState;
|
|
const char* strState;
|
|
|
|
j = i - init_flight;
|
|
|
|
if (j >= GAME_GUI_AIRCRAFT_DATA_MAX_PAGE)
|
|
{
|
|
break;
|
|
}
|
|
|
|
FontPrintText( &SmallFont,
|
|
AircraftDataFlightNumber_X,
|
|
AircraftDataFlightNumber_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j),
|
|
ptrFlightData->strFlightNumber[ptrPlayer->ActiveAircraftList[i]] );
|
|
|
|
DepArrSpr.x = AircraftDataDirection_X;
|
|
DepArrSpr.y = AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j);
|
|
DepArrSpr.w = AIRCRAFT_DEPARTURE_ARRIVAL_ICON_SIZE;
|
|
|
|
switch(ptrFlightData->FlightDirection[ptrPlayer->ActiveAircraftList[i]])
|
|
{
|
|
case ARRIVAL:
|
|
DepArrSpr.u = orig_DepArr_u + AIRCRAFT_ARRIVAL_ICON_U;
|
|
break;
|
|
case DEPARTURE:
|
|
DepArrSpr.u = orig_DepArr_u + AIRCRAFT_DEPARTURE_ICON_U;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
GfxSortSprite(&DepArrSpr);
|
|
|
|
DepArrSpr.u = orig_DepArr_u;
|
|
|
|
FontSetFlags(&SmallFont, FONT_2HZ_FLASH);
|
|
|
|
aircraftState = ptrFlightData->State[ptrPlayer->ActiveAircraftList[i]];
|
|
|
|
strState = strAircraftArray[aircraftState];
|
|
|
|
if (strState != NULL)
|
|
{
|
|
FontPrintText( &SmallFont,
|
|
AircraftDataDirection_X + AircraftDataState_X_Offset,
|
|
AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j),
|
|
(char*)strState );
|
|
}
|
|
|
|
FontSetFlags(&SmallFont, FONT_NOFLAGS);
|
|
|
|
FontPrintText( &SmallFont,
|
|
AircraftDataRemainingTime_X,
|
|
AircraftDataRemainingTime_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j),
|
|
"%ds",
|
|
ptrFlightData->RemainingTime[ptrPlayer->ActiveAircraftList[i]] );
|
|
}
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: bool GameGuiShowAircraftDataSpecialConditions(TYPE_PLAYER* const ptrPlayer)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Tells under what conditions aircraft list data should not be shown.
|
|
*
|
|
* @return:
|
|
* true if we are inside a special condition which must NOT allow showing aircraft data.
|
|
* false otherwise.
|
|
*
|
|
* **********************************************************************************************/
|
|
bool GameGuiShowAircraftDataSpecialConditions(TYPE_PLAYER* const ptrPlayer)
|
|
{
|
|
// Aircraft list data cannot be shown under these conditions.
|
|
|
|
if ( (ptrPlayer->SelectRunway)
|
|
||
|
|
(ptrPlayer->SelectTaxiwayParking)
|
|
||
|
|
(ptrPlayer->SelectTaxiwayRunway) )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiCalculateSlowScore(void)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Reportedly, it calculates a fake score which increments or decrements depending on actual
|
|
* score, which is immediately calculated. This "slow score" is then rendered on screen by
|
|
* calling GameGuiShowScore().
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiCalculateSlowScore(void)
|
|
{
|
|
uint32_t currentScore = GameGetScore();
|
|
uint32_t scoreSpeed;
|
|
|
|
enum
|
|
{
|
|
SLOW_SCORE_LOW_SPEED_MARGIN = 100
|
|
};
|
|
|
|
if (abs(slowScore - currentScore) < SLOW_SCORE_LOW_SPEED_MARGIN)
|
|
{
|
|
enum
|
|
{
|
|
SLOW_SCORE_LOW_SPEED = 5
|
|
};
|
|
|
|
scoreSpeed = SLOW_SCORE_LOW_SPEED;
|
|
|
|
if (abs(slowScore - currentScore) < SLOW_SCORE_LOW_SPEED)
|
|
{
|
|
slowScore = currentScore;
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
scoreSpeed = SLOW_SCORE_HIGH_SPEED;
|
|
}
|
|
|
|
slowScore = (slowScore > currentScore)? (slowScore - scoreSpeed) : (slowScore + scoreSpeed);
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiShowScore(void)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Reportedly, it draws current score on screen.
|
|
*
|
|
* @remarks:
|
|
* "slowScore", which increments or decrements depending on actual score, is shown.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiShowScore(void)
|
|
{
|
|
enum
|
|
{
|
|
SCORE_X = (X_SCREEN_RESOLUTION >> 1) - 64,
|
|
SCORE_Y = 4,
|
|
};
|
|
|
|
FontPrintText( &RadioFont,
|
|
SCORE_X,
|
|
SCORE_Y,
|
|
"Score:%d", slowScore );
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiDrawUnboardingSequence(TYPE_PLAYER* const ptrPlayer)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* When player is unboarding passengers from an aircraft, this function renders unboarding
|
|
* button sequence on screen.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiDrawUnboardingSequence(TYPE_PLAYER* const ptrPlayer)
|
|
{
|
|
uint8_t i;
|
|
|
|
if (ptrPlayer->Unboarding)
|
|
{
|
|
for (i = ptrPlayer->UnboardingSequenceIdx; i < GAME_MAX_SEQUENCE_KEYS; i++)
|
|
{
|
|
if (ptrPlayer->UnboardingSequence[i] == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
// TODO: Draw above the plane
|
|
if (GameTwoPlayersActive())
|
|
{
|
|
GfxDrawButton(48 + (16*i), Y_SCREEN_RESOLUTION - 32, ptrPlayer->UnboardingSequence[i]);
|
|
}
|
|
else
|
|
{
|
|
GfxDrawButton(128 + (16*i), Y_SCREEN_RESOLUTION - 32, ptrPlayer->UnboardingSequence[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void GameGuiClearPassengersLeft(void)
|
|
{
|
|
GameGuiClearPassengersLeft_Flag = true;
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: bool GameGuiFinishedDialog(TYPE_PLAYER* const ptrPlayer)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Executed when all aircraft has been dispatched and level has been finished.
|
|
*
|
|
* @return:
|
|
* true if player has pressed PAD_CROSS so gameplay is exited.
|
|
*
|
|
* **********************************************************************************************/
|
|
bool GameGuiFinishedDialog(TYPE_PLAYER* const ptrPlayer)
|
|
{
|
|
GfxSaveDisplayData(&SecondDisplay);
|
|
|
|
GfxSetGlobalLuminance(NORMAL_LUMINANCE);
|
|
|
|
do
|
|
{
|
|
if (ptrPlayer->PadKeySinglePress_Callback(PAD_CROSS))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
GfxSortSprite(&SecondDisplay);
|
|
|
|
GsSortGPoly4(&PauseRect);
|
|
|
|
FontPrintText( &SmallFont,
|
|
AIRCRAFT_DATA_GSGPOLY4_X0 +
|
|
( (AIRCRAFT_DATA_GSGPOLY4_X1 - AIRCRAFT_DATA_GSGPOLY4_X0) >> 2),
|
|
AIRCRAFT_DATA_GSGPOLY4_Y0 +
|
|
( (AIRCRAFT_DATA_GSGPOLY4_Y2 - AIRCRAFT_DATA_GSGPOLY4_Y0) >> 1),
|
|
"Level finished!" );
|
|
|
|
GfxDrawScene_Slow();
|
|
|
|
} while (ptrPlayer->PadKeySinglePress_Callback(PAD_START) == false);
|
|
|
|
return false;
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiAircraftCollision(TYPE_PLAYER* const ptrPlayer)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* When two or more aircraft collide, this function is called to show a "Game over"-like
|
|
* message on screen. Gameplay is finished at this point.
|
|
*
|
|
* @remarks:
|
|
* Blocking function.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiAircraftCollision(TYPE_PLAYER* const ptrPlayer)
|
|
{
|
|
GfxSaveDisplayData(&SecondDisplay);
|
|
|
|
GfxSetGlobalLuminance(NORMAL_LUMINANCE);
|
|
|
|
do
|
|
{
|
|
GfxSortSprite(&SecondDisplay);
|
|
|
|
GsSortGPoly4(&PauseRect);
|
|
|
|
FontPrintText( &SmallFont,
|
|
AIRCRAFT_DATA_GSGPOLY4_X0 + 8,
|
|
AIRCRAFT_DATA_GSGPOLY4_Y0 +
|
|
( (AIRCRAFT_DATA_GSGPOLY4_Y2 - AIRCRAFT_DATA_GSGPOLY4_Y0) >> 1),
|
|
"Collision between aircraft!" );
|
|
|
|
GfxDrawScene_Slow();
|
|
|
|
} while (ptrPlayer->PadKeySinglePress_Callback(PAD_CROSS) == false);
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiBubbleStop(void)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Callback executed when bubble must not be shown because of bubble timer timeout.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiBubbleStop(void)
|
|
{
|
|
showBubble = false;
|
|
}
|
|
|
|
/* **********************************************************************************************
|
|
*
|
|
* @name: void GameGuiBubbleStopVibration(void)
|
|
*
|
|
* @author: Xavier Del Campo
|
|
*
|
|
* @brief:
|
|
* Callback executed when bubble vibration must be stopped.
|
|
*
|
|
* **********************************************************************************************/
|
|
void GameGuiBubbleStopVibration(void)
|
|
{
|
|
bubbleVibration = false;
|
|
}
|