aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Levels/LEVEL1.PLT8
-rw-r--r--Source/Game.c156
-rw-r--r--Source/Game.h1
-rw-r--r--Source/GameGui.c85
-rw-r--r--Source/GameGui.h3
-rw-r--r--Source/GameStructures.h10
-rw-r--r--Source/Pad.c32
-rw-r--r--Source/Pad.h3
-rw-r--r--Source/PltParser.c30
-rw-r--r--Source/System.c4
-rw-r--r--cdimg/DATA/LEVELS/LEVEL1.PLT8
11 files changed, 297 insertions, 43 deletions
diff --git a/Levels/LEVEL1.PLT b/Levels/LEVEL1.PLT
index 952c08f..e740156 100644
--- a/Levels/LEVEL1.PLT
+++ b/Levels/LEVEL1.PLT
@@ -1,10 +1,10 @@
-#DEPARTURE/ARRIVAL;Flight number;Passengers;HH:MM;Parking (departure only)
+#DEPARTURE/ARRIVAL;Flight number;Passengers;HH:MM;Parking (departure only);Remaining time
#This is a comment example.
#If DEPARTURE, parking must be set
#If ARRIVAL, set parking to zero
#First line must set initial time
#For example:
-10:30
+14:55
#Aircraft arrival (or departure) must be set relative to initial time, in HH:MM format.
-ARRIVAL;PHX1002;40;00:05;0
-DEPARTURE;PHX1000;100;00:05;19
+ARRIVAL;PHX1002;40;00:05;0;60
+DEPARTURE;PHX1000;100;00:05;19;180
diff --git a/Source/Game.c b/Source/Game.c
index 1aa3fdc..4d30212 100644
--- a/Source/Game.c
+++ b/Source/Game.c
@@ -82,6 +82,23 @@ enum
MOUSE_Y_2PLAYER = (Y_SCREEN_RESOLUTION >> 1)
};
+enum
+{
+ LOST_FLIGHT_PENALTY = 4000,
+ SCORE_REWARD_TAXIING = 200,
+ SCORE_REWARD_FINAL = 400,
+ SCORE_REWARD_UNLOADING = 300,
+ SCORE_REWARD_FINISH_FLIGHT = 1000
+};
+
+enum
+{
+ UNBOARDING_KEY_SEQUENCE_EASY = 4,
+ UNBOARDING_KEY_SEQUENCE_MEDIUM = 6,
+ UNBOARDING_KEY_SEQUENCE_HARD = GAME_MAX_SEQUENCE_KEYS,
+ UNBOARDING_PASSENGERS_PER_SEQUENCE = 25
+};
+
/* *************************************
* Local Prototypes
* *************************************/
@@ -108,18 +125,22 @@ static void GameStateSelectRunway(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptr
static void GameStateSelectTaxiwayRunway(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData);
static void GameStateSelectTaxiwayParking(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData);
static void GameStateLockTarget(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData);
-static void GameSelectAircraft(TYPE_PLAYER* ptrPlayer);
+static TYPE_ISOMETRIC_POS GameSelectAircraft(TYPE_PLAYER* ptrPlayer);
+static void GameSelectAircraftWaypoint(TYPE_PLAYER* ptrPlayer);
static void GameGetRunwayArray(void);
static void GameGetSelectedRunwayArray(uint16_t rwyHeader);
static void GameAssignRunwaytoAircraft(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData);
static bool GamePathToTile(TYPE_PLAYER* ptrPlayer);
static void GameDrawMouse(TYPE_PLAYER* ptrPlayer);
+static void GameStateUnboarding(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData);
+static void GameGenerateUnboardingSequence(TYPE_PLAYER* ptrPlayer);
/* *************************************
* Global Variables
* *************************************/
bool GameStartupFlag;
+uint32_t GameScore;
/* *************************************
* Local Variables
@@ -266,7 +287,11 @@ void GameInit(void)
PlayerData[PLAYER_ONE].PadKeyReleased_Callback = &PadOneKeyReleased;
PlayerData[PLAYER_ONE].PadKeySinglePress_Callback = &PadOneKeySinglePress;
PlayerData[PLAYER_ONE].PadDirectionKeyPressed_Callback = &PadOneDirectionKeyPressed;
+ PlayerData[PLAYER_ONE].PadLastKeySinglePressed_Callback = &PadOneGetLastKeySinglePressed;
PlayerData[PLAYER_ONE].FlightDataPage = 0;
+ PlayerData[PLAYER_ONE].UnboardingSequenceIdx = 0;
+
+ memset(PlayerData[PLAYER_ONE].UnboardingSequence, 0, GAME_MAX_SEQUENCE_KEYS * sizeof(unsigned short) );
PlayerData[PLAYER_TWO].Active = TwoPlayersActive? true : false;
@@ -277,6 +302,10 @@ void GameInit(void)
PlayerData[PLAYER_TWO].PadDirectionKeyPressed_Callback = &PadTwoDirectionKeyPressed;
PlayerData[PLAYER_TWO].FlightDataPage = 0;
PlayerData[PLAYER_TWO].PadKeySinglePress_Callback = &PadTwoKeySinglePress;
+ PlayerData[PLAYER_TWO].PadLastKeySinglePressed_Callback = &PadTwoGetLastKeySinglePressed;
+ PlayerData[PLAYER_TWO].UnboardingSequenceIdx = 0;
+
+ memset(PlayerData[PLAYER_TWO].UnboardingSequence, 0, GAME_MAX_SEQUENCE_KEYS * sizeof(unsigned short) );
// On 2-player mode, one player controls departure flights and
// other player controls arrival flights.
@@ -322,6 +351,8 @@ void GameInit(void)
GameMouseSpr.r = NORMAL_LUMINANCE;
GameMouseSpr.g = NORMAL_LUMINANCE;
GameMouseSpr.b = NORMAL_LUMINANCE;
+
+ GameScore = 0;
GameGetRunwayArray();
@@ -386,6 +417,7 @@ void GameCalculations(void)
GameAircraftState();
GameActiveAircraft();
GameFirstLastAircraftIndex();
+ GameGuiCalculateSlowScore();
AircraftHandler();
for(i = 0 ; i < MAX_PLAYERS ; i++)
@@ -397,20 +429,10 @@ void GameCalculations(void)
}
}
- if(PadOneKeyReleased(PAD_CIRCLE) == true)
+ /*if(PadOneKeyReleased(PAD_CIRCLE) == true)
{
for(i = 0; i < FlightData.nAircraft ; i++)
- {
- /*typedef struct
- {
- FL_DIR FlightDirection[GAME_MAX_AIRCRAFT];
- char strFlightNumber[GAME_MAX_AIRCRAFT][GAME_MAX_CHARACTERS];
- uint8_t Passengers[GAME_MAX_AIRCRAFT];
- uint8_t Hours[GAME_MAX_AIRCRAFT];
- uint8_t Minutes[GAME_MAX_AIRCRAFT];
- uint8_t Parking[GAME_MAX_AIRCRAFT];
- }TYPE_FLIGHT_DATA;*/
-
+ {
dprintf("\n*****************\n");
dprintf("\tAIRCRAFT %d\n",i);
dprintf("*****************\n");
@@ -465,7 +487,7 @@ void GameCalculations(void)
}
dprintf("Active aircraft: %d\n",FlightData.ActiveAircraft);
- }
+ }*/
}
@@ -513,6 +535,7 @@ void GamePlayerHandler(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData)
GameGuiActiveAircraftList(ptrPlayer, ptrFlightData);
GameGuiActiveAircraftPage(ptrPlayer, ptrFlightData);
GameSelectAircraftFromList(ptrPlayer, ptrFlightData);
+ GameStateUnboarding(ptrPlayer, ptrFlightData);
}
void GameClock(void)
@@ -556,6 +579,13 @@ void GameClockFlights(void)
{
FlightData.Minutes[i]--;
}
+
+ if( (FlightData.State[i] != STATE_IDLE)
+ &&
+ (FlightData.RemainingTime[i] > 0) )
+ {
+ FlightData.RemainingTime[i]--;
+ }
}
}
}
@@ -600,6 +630,8 @@ void GameGraphics(void)
GameGuiAircraftList(&PlayerData[i], &FlightData);
GameDrawMouse(&PlayerData[i]);
+
+ GameGuiDrawUnboardingSequence(&PlayerData[i]);
}
}
@@ -617,6 +649,8 @@ void GameGraphics(void)
GameGuiBubble(&FlightData);
GameGuiClock(GameHour,GameMinutes);
+
+ GameGuiShowScore();
GfxDrawScene();
}
@@ -707,7 +741,9 @@ void GameAircraftState(void)
&&
(FlightData.Minutes[i] == 0)
&&
- (FlightData.State[i] == STATE_IDLE) )
+ (FlightData.State[i] == STATE_IDLE)
+ &&
+ (FlightData.RemainingTime[i] > 0) )
{
if(FlightData.FlightDirection[i] == DEPARTURE)
{
@@ -731,6 +767,15 @@ void GameAircraftState(void)
// Create notification request for incoming aircraft
FlightData.NotificationRequest[i] = true;
}
+
+ if( (FlightData.State[i] != STATE_IDLE)
+ &&
+ (FlightData.RemainingTime[i] == 0) )
+ {
+ // Player(s) lost a flight!
+ FlightData.State[i] = STATE_IDLE;
+ GameScore = (GameScore < LOST_FLIGHT_PENALTY)? 0 : (GameScore - LOST_FLIGHT_PENALTY);
+ }
}
}
@@ -1119,6 +1164,7 @@ void GameStateSelectTaxiwayRunway(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptr
ptrPlayer->LastWaypointIdx = 0;
ptrFlightData->State[ptrPlayer->LockedAircraft] = STATE_TAXIING;
+ GameScore += SCORE_REWARD_TAXIING;
break;
default:
@@ -1203,6 +1249,7 @@ void GameStateSelectTaxiwayParking(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * pt
ptrPlayer->LastWaypointIdx = 0;
ptrFlightData->State[ptrPlayer->LockedAircraft] = STATE_TAXIING;
+ GameScore += SCORE_REWARD_TAXIING;
}
}
}
@@ -1330,13 +1377,22 @@ void GameSelectAircraftFromList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFl
case STATE_PARKED:
ptrPlayer->SelectTaxiwayRunway = true;
- GameSelectAircraft(ptrPlayer);
+ // Move camera to selected aircraft and add first waypoint.
+ GameSelectAircraftWaypoint(ptrPlayer);
break;
case STATE_LANDED:
ptrPlayer->SelectTaxiwayParking = true;
// Move camera to selected aircraft and add first waypoint.
+ GameSelectAircraftWaypoint(ptrPlayer);
+ break;
+
+ case STATE_UNBOARDING:
+ ptrPlayer->Unboarding = true;
+ // Move camera to selected aircraft.
GameSelectAircraft(ptrPlayer);
+ // Generate first unboarding key sequence
+ GameGenerateUnboardingSequence(ptrPlayer);
break;
default:
@@ -1459,6 +1515,7 @@ void GameAssignRunwaytoAircraft(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFl
if(ptrFlightData->State[aircraftIndex] == STATE_APPROACH)
{
ptrFlightData->State[aircraftIndex] = STATE_FINAL;
+ GameScore += SCORE_REWARD_FINAL;
GameGetSelectedRunwayArray(assignedRwy);
@@ -1840,13 +1897,20 @@ bool GamePathToTile(TYPE_PLAYER* ptrPlayer)
return true;
}
-void GameSelectAircraft(TYPE_PLAYER* ptrPlayer)
+TYPE_ISOMETRIC_POS GameSelectAircraft(TYPE_PLAYER* ptrPlayer)
{
uint8_t AircraftIdx = ptrPlayer->ActiveAircraftList[ptrPlayer->SelectedAircraft];
TYPE_ISOMETRIC_POS IsoPos = AircraftGetIsoPos(AircraftIdx);
CameraMoveToIsoPos(ptrPlayer, IsoPos);
+ return IsoPos;
+}
+
+void GameSelectAircraftWaypoint(TYPE_PLAYER* ptrPlayer)
+{
+ TYPE_ISOMETRIC_POS IsoPos = GameSelectAircraft(ptrPlayer);
+
ptrPlayer->SelectedTile = GameGetTileFromIsoPosition(&IsoPos);
GamePlayerAddWaypoint(ptrPlayer);
@@ -1876,3 +1940,61 @@ FL_STATE GameGetFlightDataStateFromIdx(uint8_t FlightDataIdx)
return FlightData.State[FlightDataIdx];
}
+
+uint32_t GameGetScore(void)
+{
+ return GameScore;
+}
+
+void GameStateUnboarding(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData)
+{
+ if(ptrPlayer->Unboarding == true)
+ {
+ if(ptrPlayer->PadKeySinglePress_Callback(PAD_CIRCLE) == true)
+ {
+ ptrPlayer->Unboarding = false;
+ ptrPlayer->UnboardingSequenceIdx = 0; // Player will need to repeat sequence
+ // if he/she decides to leave without finishing
+ }
+
+ if(SystemContains_u16(ptrPlayer->PadLastKeySinglePressed_Callback(), ptrPlayer->UnboardingSequence, GAME_MAX_SEQUENCE_KEYS) == true)
+ {
+ if(++ptrPlayer->UnboardingSequenceIdx >= UNBOARDING_KEY_SEQUENCE_MEDIUM)
+ {
+ if(ptrFlightData->Passengers[ptrPlayer->ActiveAircraftList[ptrPlayer->SelectedAircraft]] > UNBOARDING_PASSENGERS_PER_SEQUENCE)
+ {
+ ptrFlightData->Passengers[ptrPlayer->ActiveAircraftList[ptrPlayer->SelectedAircraft]] -= UNBOARDING_PASSENGERS_PER_SEQUENCE;
+ GameScore += SCORE_REWARD_UNLOADING;
+ }
+ else
+ {
+ ptrFlightData->Passengers[ptrPlayer->ActiveAircraftList[ptrPlayer->SelectedAircraft]] = 0;
+ ptrFlightData->State[ptrPlayer->ActiveAircraftList[ptrPlayer->SelectedAircraft]] = STATE_IDLE;
+
+ GameScore += SCORE_REWARD_FINISH_FLIGHT;
+ }
+
+ ptrPlayer->UnboardingSequenceIdx = 0;
+ }
+ }
+ }
+}
+
+void GameGenerateUnboardingSequence(TYPE_PLAYER* ptrPlayer)
+{
+ uint8_t i;
+ unsigned short keyTable[] = { PAD_CROSS, PAD_SQUARE, PAD_TRIANGLE, PAD_L1,
+ PAD_L2, PAD_R1, PAD_R2 };
+
+ memset(ptrPlayer->UnboardingSequence, 0, GAME_MAX_SEQUENCE_KEYS * sizeof(unsigned short) );
+
+ ptrPlayer->UnboardingSequenceIdx = 0;
+
+ // Only medium level implemented. TODO: Implement other levels
+ for(i = 0; i < UNBOARDING_KEY_SEQUENCE_MEDIUM; i++)
+ {
+ uint8_t randNr = SystemRand(0, (sizeof(keyTable) / sizeof(keyTable[0])));
+
+ ptrPlayer->UnboardingSequence[i] = randNr;
+ }
+}
diff --git a/Source/Game.h b/Source/Game.h
index fb8c12c..6273a56 100644
--- a/Source/Game.h
+++ b/Source/Game.h
@@ -49,5 +49,6 @@ short GameGetYFromTile_short(uint16_t tile);
FL_STATE GameTargetsReached(uint8_t index);
uint16_t GameGetTileFromIsoPosition(TYPE_ISOMETRIC_POS * IsoPos);
FL_STATE GameGetFlightDataStateFromIdx(uint8_t FlightDataIdx);
+uint32_t GameGetScore(void);
#endif //__GAME_HEADER__
diff --git a/Source/GameGui.c b/Source/GameGui.c
index 94d3dce..b5fc3f4 100644
--- a/Source/GameGui.c
+++ b/Source/GameGui.c
@@ -13,6 +13,10 @@
#define NOTIFICATION_BUFFER_SIZE 200
#define GAME_GUI_AIRCRAFT_DATA_MAX_PAGE 5
+#define SLOW_SCORE_LOW_SPEED_MARGIN 100
+#define SLOW_SCORE_LOW_SPEED 5
+#define SLOW_SCORE_HIGH_SPEED 10
+
/* **************************************
* Structs and enums *
* *************************************/
@@ -87,6 +91,12 @@ enum
enum
{
+ SCORE_X = (X_SCREEN_RESOLUTION >> 1) - 64,
+ SCORE_Y = 16,
+};
+
+enum
+{
AIRCRAFT_DATA_GSGPOLY4_R0 = 0,
AIRCRAFT_DATA_GSGPOLY4_R1 = AIRCRAFT_DATA_GSGPOLY4_R0,
AIRCRAFT_DATA_GSGPOLY4_R2 = 0,
@@ -154,7 +164,7 @@ enum
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 = 32,
+ 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,
@@ -189,7 +199,13 @@ enum
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_PASSENGERS_Y_2PLAYER = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y_2PLAYER,
+
+ AIRCRAFT_DATA_REMAINING_TIME_X = AIRCRAFT_DATA_DIRECTION_X,
+ 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,
+ AIRCRAFT_DATA_REMAINING_TIME_Y_2PLAYER = AIRCRAFT_DATA_DIRECTION_Y_2PLAYER + AIRCRAFT_DATA_FLIGHT_GSGPOLY4_GAP
};
enum
@@ -244,6 +260,7 @@ static void * GameFileDest[] = {(GsSprite*)&BubbleSpr ,
(GsSprite*)&ArrowsSpr };
static char strNotificationRequest[NOTIFICATION_BUFFER_SIZE];
+static uint32_t slowScore; // It will update slowly to actual score value
void GameGuiInit(void)
{
@@ -278,6 +295,8 @@ void GameGuiInit(void)
PauseRect.g[3] = PAUSE_DIALOG_G3;
PauseRect.attribute |= ENABLE_TRANS | TRANS_MODE(0);
+
+ slowScore = 0;
}
void GameGuiAircraftNotificationRequest(TYPE_FLIGHT_DATA * ptrFlightData)
@@ -767,6 +786,8 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh
short AircraftDataPassengers_X;
short AircraftDataPassengers_Y;
short AircraftDataState_X_Offset;
+ short AircraftDataRemainingTime_X;
+ short AircraftDataRemainingTime_Y;
if(GameTwoPlayersActive() == true)
{
@@ -777,6 +798,8 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh
AircraftDataPassengers_X = AIRCRAFT_DATA_PASSENGERS_X_2PLAYER;
AircraftDataPassengers_Y = AIRCRAFT_DATA_PASSENGERS_Y_2PLAYER;
AircraftDataState_X_Offset = 54;
+ AircraftDataRemainingTime_X = AIRCRAFT_DATA_REMAINING_TIME_X_2PLAYER;
+ AircraftDataRemainingTime_Y = AIRCRAFT_DATA_REMAINING_TIME_Y_2PLAYER;
}
else
{
@@ -787,6 +810,8 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh
AircraftDataPassengers_X = AIRCRAFT_DATA_PASSENGERS_X;
AircraftDataPassengers_Y = AIRCRAFT_DATA_PASSENGERS_Y;
AircraftDataState_X_Offset = 88;
+ AircraftDataRemainingTime_X = AIRCRAFT_DATA_REMAINING_TIME_X;
+ AircraftDataRemainingTime_Y = AIRCRAFT_DATA_REMAINING_TIME_Y;
}
FontSetFlags(&SmallFont,FONT_NOFLAGS);
@@ -883,6 +908,12 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh
AircraftDataPassengers_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j),
"%d pax.",
ptrFlightData->Passengers[ptrPlayer->ActiveAircraftList[i]] );
+
+ FontPrintText( &SmallFont,
+ AircraftDataRemainingTime_X,
+ AircraftDataRemainingTime_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j),
+ "Time: %d sec.",
+ ptrFlightData->RemainingTime[ptrPlayer->ActiveAircraftList[i]] );
}
}
@@ -901,3 +932,53 @@ bool GameGuiShowAircraftDataSpecialConditions(TYPE_PLAYER* ptrPlayer)
return false;
}
+
+void GameGuiCalculateSlowScore(void)
+{
+ uint32_t currentScore = GameGetScore();
+ uint32_t scoreSpeed;
+
+ if(abs(slowScore - currentScore) < SLOW_SCORE_LOW_SPEED_MARGIN)
+ {
+ 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);
+}
+
+void GameGuiShowScore(void)
+{
+ FontPrintText( &RadioFont,
+ SCORE_X,
+ SCORE_Y,
+ "Score: %d", slowScore );
+}
+
+void GameGuiDrawUnboardingSequence(TYPE_PLAYER* ptrPlayer)
+{
+ uint8_t i;
+
+ if(ptrPlayer->Unboarding == true)
+ {
+ for(i = ptrPlayer->UnboardingSequenceIdx; i < GAME_MAX_SEQUENCE_KEYS; i++)
+ {
+ if(ptrPlayer->UnboardingSequence[i] == 0)
+ {
+ break;
+ }
+
+ // TODO: Draw above the plane
+ GfxDrawButton(64, Y_SCREEN_RESOLUTION - 32, ptrPlayer->UnboardingSequence[i]);
+ }
+ }
+}
diff --git a/Source/GameGui.h b/Source/GameGui.h
index 319e58b..5b2489d 100644
--- a/Source/GameGui.h
+++ b/Source/GameGui.h
@@ -36,5 +36,8 @@ void GameGuiAircraftList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightDat
void GameGuiClock(uint8_t hour, uint8_t min);
void GameGuiActiveAircraftList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData);
void GameGuiActiveAircraftPage(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData);
+void GameGuiCalculateSlowScore(void);
+void GameGuiShowScore(void);
+void GameGuiDrawUnboardingSequence(TYPE_PLAYER* ptrPlayer);
#endif //__GAME_GUI_HEADER__
diff --git a/Source/GameStructures.h b/Source/GameStructures.h
index 4a6b563..4a66748 100644
--- a/Source/GameStructures.h
+++ b/Source/GameStructures.h
@@ -10,6 +10,7 @@
#define CHEAT_ARRAY_SIZE 16
#define AIRCRAFT_MAX_TARGETS 32
#define PLAYER_MAX_WAYPOINTS AIRCRAFT_MAX_TARGETS
+#define GAME_MAX_SEQUENCE_KEYS 12
/* *************************************
* Structs and enums
@@ -70,6 +71,7 @@ typedef struct t_flightData
uint8_t Hours[GAME_MAX_AIRCRAFT];
uint8_t Minutes[GAME_MAX_AIRCRAFT];
uint8_t Parking[GAME_MAX_AIRCRAFT];
+ uint16_t RemainingTime[GAME_MAX_AIRCRAFT];
uint8_t nAircraft;
uint8_t ActiveAircraft;
FL_STATE State[GAME_MAX_AIRCRAFT];
@@ -138,6 +140,8 @@ typedef struct
bool InvalidPath;
// Player has locked the camera at a determined aircraft
bool LockTarget;
+ // Player is unboarding passengers
+ bool Unboarding;
// Stores indexes for player-specific active aircraft
// Used to relate SelectedAircraft agains FlightData index
@@ -163,11 +167,17 @@ typedef struct
uint8_t WaypointIdx;
// Another internal index to keep last desired selected point by user when defining a path.
uint8_t LastWaypointIdx;
+ // If player is unboarding passengers, then a sequence of keys is generated to make unboarding
+ // process a bit more difficult and challenging.
+ unsigned short UnboardingSequence[GAME_MAX_SEQUENCE_KEYS];
+ // Index inside UnboardingSequence[]
+ uint8_t UnboardingSequenceIdx;
bool (*PadKeyPressed_Callback)(unsigned short);
bool (*PadKeyReleased_Callback)(unsigned short);
bool (*PadKeySinglePress_Callback)(unsigned short);
bool (*PadDirectionKeyPressed_Callback)(void);
+ unsigned short (*PadLastKeySinglePressed_Callback)(void);
TYPE_CAMERA Camera;
}TYPE_PLAYER;
diff --git a/Source/Pad.c b/Source/Pad.c
index 1606535..5fd313c 100644
--- a/Source/Pad.c
+++ b/Source/Pad.c
@@ -80,6 +80,10 @@ static uint8_t pad2_small_vibration_force;
// Timers for each key pressed (used for PadXXKeyRepeat() )
static uint8_t pad1_keys_repeat[NUMBER_OF_KEYS];
static uint8_t pad2_keys_repeat[NUMBER_OF_KEYS];
+
+static unsigned short pad1_last_key_single_pressed;
+static unsigned short pad2_last_key_single_pressed;
+
// These arrays include last 16 buttons pressed by user and keeps them
// for cheating purposes. They are cleaned if no keys are pressed during
// PAD_CHEAT_TIMEOUT milliseconds.
@@ -179,12 +183,26 @@ bool PadTwoKeyPressed(unsigned short key)
bool PadOneKeySinglePress(unsigned short key)
{
- return (bool)( !(previous_pad1 & key) && (pad1 & key) );
+ bool singlePress = (bool)( !(previous_pad1 & key) && (pad1 & key) );
+
+ if(singlePress == true)
+ {
+ pad1_last_key_single_pressed = key;
+ }
+
+ return singlePress;
}
bool PadTwoKeySinglePress(unsigned short key)
{
- return (bool)( !(previous_pad2 & key) && (pad2 & key) );
+ bool singlePress = (bool)( !(previous_pad2 & key) && (pad2 & key) );
+
+ if(singlePress == true)
+ {
+ pad2_last_key_single_pressed = key;
+ }
+
+ return singlePress;
}
bool PadOneKeyRepeat(unsigned short key, uint8_t time)
@@ -496,3 +514,13 @@ unsigned short* PadGetPlayerOneCheatArray(void)
{
return pad1_cheat_array;
}
+
+unsigned short PadOneGetLastKeySinglePressed(void)
+{
+ return pad1_last_key_single_pressed;
+}
+
+unsigned short PadTwoGetLastKeySinglePressed(void)
+{
+ return pad2_last_key_single_pressed;
+}
diff --git a/Source/Pad.h b/Source/Pad.h
index d887f86..5b5fa1d 100644
--- a/Source/Pad.h
+++ b/Source/Pad.h
@@ -39,6 +39,9 @@ bool PadTwoKeyReleased(unsigned short key);
bool PadOneKeySinglePress(unsigned short key);
bool PadTwoKeySinglePress(unsigned short key);
+unsigned short PadOneGetLastKeySinglePressed(void);
+unsigned short PadTwoGetLastKeySinglePressed(void);
+
bool PadOneDirectionKeyPressed(void);
bool PadTwoDirectionKeyPressed(void);
diff --git a/Source/PltParser.c b/Source/PltParser.c
index fe59e91..0ee9fd8 100644
--- a/Source/PltParser.c
+++ b/Source/PltParser.c
@@ -7,9 +7,8 @@
/* *************************************
* Defines
* *************************************/
-
-#define PLT_BUFFER_SIZE 0x2800
-#define LINE_MAX 100
+
+#define LINE_MAX_CHARACTERS 100
/* **************************************
* Structs and enums *
@@ -21,7 +20,8 @@ enum
FLIGHT_NUMBER_INDEX,
PASSENGERS_INDEX,
HOURS_MINUTES_INDEX,
- PARKING_INDEX
+ PARKING_INDEX,
+ REMAINING_TIME_INDEX
};
enum
@@ -35,8 +35,6 @@ enum
* Local Variables
* *************************************/
-static char strPltBuffer[PLT_BUFFER_SIZE];
-
/* *************************************
* Local Prototypes
* *************************************/
@@ -49,23 +47,26 @@ bool PltParserLoadFile(char * strPath, TYPE_FLIGHT_DATA * ptrFlightData)
uint8_t aircraftIndex;
bool first_line_read = false;
char * buffer;
- char lineBuffer[LINE_MAX];
+ char lineBuffer[LINE_MAX_CHARACTERS];
char * lineBufferPtr;
char * pltBufferSavePtr;
char strHour[PLT_HOUR_MINUTE_CHARACTERS];
char strMinutes[PLT_HOUR_MINUTE_CHARACTERS];
-
- if(SystemLoadFileToBuffer(strPath,(uint8_t*)strPltBuffer,PLT_BUFFER_SIZE) == false)
+ uint8_t* strPltBuffer;
+
+ if(SystemLoadFile(strPath) == false)
{
dprintf("Error loading file %s!\n",strPath);
return false;
}
+
+ strPltBuffer = SystemGetBufferAddress();
PltParserResetBuffers(ptrFlightData);
// Now, buffer shall be read from line to line
- buffer = strtok_r(strPltBuffer,"\n",&pltBufferSavePtr);
+ buffer = strtok_r((char*)strPltBuffer,"\n",&pltBufferSavePtr);
aircraftIndex = 0;
@@ -123,7 +124,7 @@ bool PltParserLoadFile(char * strPath, TYPE_FLIGHT_DATA * ptrFlightData)
else
{
// File header (initial game time) has already been read
- strncpy(lineBuffer, buffer, LINE_MAX);
+ strncpy(lineBuffer, buffer, LINE_MAX_CHARACTERS);
lineBufferPtr = strtok(lineBuffer,";");
@@ -140,7 +141,8 @@ bool PltParserLoadFile(char * strPath, TYPE_FLIGHT_DATA * ptrFlightData)
FLIGHT_NUMBER_INDEX,
PASSENGERS_INDEX,
HOURS_MINUTES_INDEX,
- PARKING_INDEX
+ PARKING_INDEX,
+ REMAINING_TIME_INDEX
};*/
switch(i)
{
@@ -206,6 +208,10 @@ bool PltParserLoadFile(char * strPath, TYPE_FLIGHT_DATA * ptrFlightData)
ptrFlightData->Hours[aircraftIndex],
ptrFlightData->Minutes[aircraftIndex] );
break;
+
+ case REMAINING_TIME_INDEX:
+ ptrFlightData->RemainingTime[aircraftIndex] = (uint8_t)atoi(lineBufferPtr);
+ break;
default:
diff --git a/Source/System.c b/Source/System.c
index 8005fa8..5ecafbb 100644
--- a/Source/System.c
+++ b/Source/System.c
@@ -249,9 +249,9 @@ void SystemRunTimers(void)
#ifdef _PAL_MODE_
SystemCheckTimer(&hundred_ms_timer, &last_100_ms_tick, 2 /* 2 * 50 ms = 100 ms */);
SystemCheckTimer(&five_hundred_ms_timer, &last_500_ms_tick, 10 /* 10 * 50 ms = 500 ms */);
-#else
+#else // _PAL_MODE_
SystemCheckTimer(&hundred_ms_timer, &last_100_ms_tick, 3);
-#endif //VMODE_PAL
+#endif // _PAL_MODE_
}
diff --git a/cdimg/DATA/LEVELS/LEVEL1.PLT b/cdimg/DATA/LEVELS/LEVEL1.PLT
index 952c08f..e740156 100644
--- a/cdimg/DATA/LEVELS/LEVEL1.PLT
+++ b/cdimg/DATA/LEVELS/LEVEL1.PLT
@@ -1,10 +1,10 @@
-#DEPARTURE/ARRIVAL;Flight number;Passengers;HH:MM;Parking (departure only)
+#DEPARTURE/ARRIVAL;Flight number;Passengers;HH:MM;Parking (departure only);Remaining time
#This is a comment example.
#If DEPARTURE, parking must be set
#If ARRIVAL, set parking to zero
#First line must set initial time
#For example:
-10:30
+14:55
#Aircraft arrival (or departure) must be set relative to initial time, in HH:MM format.
-ARRIVAL;PHX1002;40;00:05;0
-DEPARTURE;PHX1000;100;00:05;19
+ARRIVAL;PHX1002;40;00:05;0;60
+DEPARTURE;PHX1000;100;00:05;19;180