* Added some comments on System.
* New routine PadOneKeySinglePress() and PadTwoKeySinglePress(). * Temp waypoints now turn red when colliding with an aircraft or with a previously existing waypoint. * When loading files, GPU operation is finishedbefore calling fopen. Also, I_MASK is disabled just in case. * For PLT files, actual tile needs to be set instead of parking number.
This commit is contained in:
parent
8629c228db
commit
83b4684d7c
|
@ -7,4 +7,4 @@
|
|||
10:30
|
||||
#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;2
|
||||
DEPARTURE;PHX1000;100;00:05;19
|
||||
|
|
|
@ -58,10 +58,10 @@ static const fix16_t AircraftSpeedsTable[] = { 0 /* IDLE */ ,
|
|||
* Local prototypes
|
||||
* *************************************/
|
||||
|
||||
static void AircraftDirection(TYPE_AIRCRAFT_DATA * ptrAircraft);
|
||||
static void AircraftDirection(TYPE_AIRCRAFT_DATA* ptrAircraft);
|
||||
static AIRCRAFT_LIVERY AircraftLiveryFromFlightNumber(char * strFlightNumber);
|
||||
static void AircraftAttitude(TYPE_AIRCRAFT_DATA * ptrAircraft);
|
||||
static void AircraftUpdateSpriteFromData(TYPE_AIRCRAFT_DATA * ptrAircraft);
|
||||
static void AircraftAttitude(TYPE_AIRCRAFT_DATA* ptrAircraft);
|
||||
static void AircraftUpdateSpriteFromData(TYPE_AIRCRAFT_DATA* ptrAircraft);
|
||||
|
||||
void AircraftInit(void)
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ bool AircraftAddNew( TYPE_FLIGHT_DATA * ptrFlightData,
|
|||
uint8_t FlightDataIndex,
|
||||
uint16_t * targets )
|
||||
{
|
||||
TYPE_AIRCRAFT_DATA * ptrAircraft = &AircraftData[AircraftIndex];
|
||||
TYPE_AIRCRAFT_DATA* ptrAircraft = &AircraftData[AircraftIndex];
|
||||
uint8_t level_columns = GameGetLevelColumns();
|
||||
uint8_t i;
|
||||
|
||||
|
@ -128,6 +128,12 @@ bool AircraftAddNew( TYPE_FLIGHT_DATA * ptrFlightData,
|
|||
|
||||
ptrAircraft->Speed = AircraftSpeedsTable[AIRCRAFT_SPEED_APPROACH];
|
||||
}
|
||||
else if(ptrFlightData->FlightDirection[FlightDataIndex] == DEPARTURE)
|
||||
{
|
||||
ptrAircraft->IsoPos.x = GameGetXFromTile(ptrFlightData->Parking[FlightDataIndex]);
|
||||
ptrAircraft->IsoPos.y = GameGetYFromTile(ptrFlightData->Parking[FlightDataIndex]);
|
||||
ptrAircraft->IsoPos.z = 0;
|
||||
}
|
||||
|
||||
ptrAircraft->State = ptrFlightData->State[FlightDataIndex];
|
||||
|
||||
|
@ -177,7 +183,7 @@ AIRCRAFT_LIVERY AircraftLiveryFromFlightNumber(char * strFlightNumber)
|
|||
|
||||
void AircraftHandler(void)
|
||||
{
|
||||
TYPE_AIRCRAFT_DATA * ptrAircraft;
|
||||
TYPE_AIRCRAFT_DATA* ptrAircraft;
|
||||
uint8_t i;
|
||||
|
||||
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
||||
|
@ -196,7 +202,7 @@ void AircraftHandler(void)
|
|||
|
||||
void AircraftRender(TYPE_PLAYER * ptrPlayer)
|
||||
{
|
||||
TYPE_AIRCRAFT_DATA * ptrAircraft;
|
||||
TYPE_AIRCRAFT_DATA* ptrAircraft;
|
||||
TYPE_CARTESIAN_POS cartPos;
|
||||
|
||||
uint8_t i;
|
||||
|
@ -228,7 +234,7 @@ void AircraftRender(TYPE_PLAYER * ptrPlayer)
|
|||
}
|
||||
}
|
||||
|
||||
void AircraftDirection(TYPE_AIRCRAFT_DATA * ptrAircraft)
|
||||
void AircraftDirection(TYPE_AIRCRAFT_DATA* ptrAircraft)
|
||||
{
|
||||
TYPE_ISOMETRIC_FIX16_POS targetPos;
|
||||
|
||||
|
@ -291,7 +297,7 @@ void AircraftDirection(TYPE_AIRCRAFT_DATA * ptrAircraft)
|
|||
}
|
||||
}
|
||||
|
||||
void AircraftUpdateSpriteFromData(TYPE_AIRCRAFT_DATA * ptrAircraft)
|
||||
void AircraftUpdateSpriteFromData(TYPE_AIRCRAFT_DATA* ptrAircraft)
|
||||
{
|
||||
switch(ptrAircraft->Livery)
|
||||
{
|
||||
|
@ -331,7 +337,7 @@ void AircraftUpdateSpriteFromData(TYPE_AIRCRAFT_DATA * ptrAircraft)
|
|||
}
|
||||
}
|
||||
|
||||
void AircraftAttitude(TYPE_AIRCRAFT_DATA * ptrAircraft)
|
||||
void AircraftAttitude(TYPE_AIRCRAFT_DATA* ptrAircraft)
|
||||
{
|
||||
if(ptrAircraft->State == STATE_FINAL)
|
||||
{
|
||||
|
@ -347,7 +353,7 @@ TYPE_ISOMETRIC_POS AircraftGetIsoPos(uint8_t FlightDataIdx)
|
|||
// Aircraft position data is stored in fix16_t data type instead of "short" data type.
|
||||
// So we must perform a conversion first for convenience.
|
||||
TYPE_ISOMETRIC_POS retIsoPos;
|
||||
TYPE_ISOMETRIC_FIX16_POS fix16IsoPos = AircraftData[FlightDataIdx].IsoPos;
|
||||
TYPE_ISOMETRIC_FIX16_POS fix16IsoPos = AircraftFromFlightDataIndex(FlightDataIdx)->IsoPos;
|
||||
|
||||
retIsoPos.x = (short)fix16_to_int(fix16IsoPos.x);
|
||||
retIsoPos.y = (short)fix16_to_int(fix16IsoPos.y);
|
||||
|
@ -356,14 +362,33 @@ TYPE_ISOMETRIC_POS AircraftGetIsoPos(uint8_t FlightDataIdx)
|
|||
return retIsoPos;
|
||||
}
|
||||
|
||||
void AircraftAddTargets(TYPE_AIRCRAFT_DATA * ptrAircraft, uint16_t * targets)
|
||||
void AircraftAddTargets(TYPE_AIRCRAFT_DATA* ptrAircraft, uint16_t * targets)
|
||||
{
|
||||
memcpy(ptrAircraft->Target, targets, sizeof(uint16_t) * AIRCRAFT_MAX_TARGETS);
|
||||
}
|
||||
|
||||
TYPE_AIRCRAFT_DATA * AircraftFromFlightDataIndex(uint8_t index)
|
||||
uint16_t AircraftGetTileFromFlightDataIndex(uint8_t index)
|
||||
{
|
||||
return &AircraftData[index];
|
||||
TYPE_ISOMETRIC_POS isoPos = AircraftGetIsoPos(index);
|
||||
return GameGetTileFromIsoPosition(&isoPos);
|
||||
}
|
||||
|
||||
TYPE_AIRCRAFT_DATA* AircraftFromFlightDataIndex(uint8_t index)
|
||||
{
|
||||
uint8_t i;
|
||||
TYPE_AIRCRAFT_DATA* ptrAircraft;
|
||||
|
||||
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
||||
{
|
||||
ptrAircraft = &AircraftData[i];
|
||||
|
||||
if(ptrAircraft->FlightDataIdx == index)
|
||||
{
|
||||
return ptrAircraft;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AircraftFromFlightDataIndexAddTargets(uint8_t index, uint16_t * targets)
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
void AircraftInit(void);
|
||||
void AircraftHandler(void);
|
||||
void AircraftRender(TYPE_PLAYER * ptrPlayer);
|
||||
TYPE_AIRCRAFT_DATA * AircraftFromFlightDataIndex(uint8_t index);
|
||||
TYPE_AIRCRAFT_DATA* AircraftFromFlightDataIndex(uint8_t index);
|
||||
void AircraftFromFlightDataIndexAddTargets(uint8_t index, uint16_t * targets);
|
||||
void AircraftAddTargets(TYPE_AIRCRAFT_DATA * ptrAircraft, uint16_t * targets);
|
||||
void AircraftAddTargets(TYPE_AIRCRAFT_DATA* ptrAircraft, uint16_t * targets);
|
||||
TYPE_ISOMETRIC_POS AircraftGetIsoPos(uint8_t FlightDataIdx);
|
||||
uint16_t AircraftGetTileFromFlightDataIndex(uint8_t index);
|
||||
bool AircraftAddNew( TYPE_FLIGHT_DATA * ptrFlightData,
|
||||
uint8_t FlightDataIndex,
|
||||
uint16_t * targets );
|
||||
|
|
208
Source/Game.c
208
Source/Game.c
|
@ -111,7 +111,6 @@ static void GameGetRunwayArray(void);
|
|||
static void GameGetSelectedRunwayArray(uint16_t rwyHeader);
|
||||
static void GameAssignRunwaytoAircraft(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData);
|
||||
static bool GameGuiShowAircraftDataSpecialConditions(TYPE_PLAYER * ptrPlayer);
|
||||
static uint16_t GameGetTileFromIsoPosition(TYPE_ISOMETRIC_POS * IsoPos);
|
||||
static bool GamePathToTile(TYPE_PLAYER * ptrPlayer);
|
||||
|
||||
/* *************************************
|
||||
|
@ -195,6 +194,8 @@ void Game(bool two_players)
|
|||
}
|
||||
}
|
||||
|
||||
GfxDisableSplitScreen();
|
||||
|
||||
EndAnimation();
|
||||
|
||||
SfxPlayTrack(INTRO_TRACK);
|
||||
|
@ -217,8 +218,8 @@ bool GamePause(void)
|
|||
// Run player-specific functions for each player
|
||||
if(ptrPlayer->Active == true)
|
||||
{
|
||||
//dprintf("Released callback = 0x%08X\n", ptrPlayer->PadKeyReleased_Callback);
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_START) == true)
|
||||
//dprintf("Released callback = 0x%08X\n", ptrPlayer->PadKeySinglePress_Callback);
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_START) == true)
|
||||
{
|
||||
dprintf("Player %d set pause_flag to true!\n",i);
|
||||
pause_flag = true;
|
||||
|
@ -261,6 +262,7 @@ void GameInit(void)
|
|||
PlayerData[PLAYER_ONE].Active = true;
|
||||
PlayerData[PLAYER_ONE].PadKeyPressed_Callback = &PadOneKeyPressed;
|
||||
PlayerData[PLAYER_ONE].PadKeyReleased_Callback = &PadOneKeyReleased;
|
||||
PlayerData[PLAYER_ONE].PadKeySinglePress_Callback = &PadOneKeySinglePress;
|
||||
PlayerData[PLAYER_ONE].PadDirectionKeyPressed_Callback = &PadOneDirectionKeyPressed;
|
||||
PlayerData[PLAYER_ONE].FlightDataPage = 0;
|
||||
|
||||
|
@ -272,6 +274,7 @@ void GameInit(void)
|
|||
PlayerData[PLAYER_TWO].PadKeyReleased_Callback = &PadTwoKeyReleased;
|
||||
PlayerData[PLAYER_TWO].PadDirectionKeyPressed_Callback = &PadTwoDirectionKeyPressed;
|
||||
PlayerData[PLAYER_TWO].FlightDataPage = 0;
|
||||
PlayerData[PLAYER_TWO].PadKeySinglePress_Callback = &PadTwoKeySinglePress;
|
||||
|
||||
// On 2-player mode, one player controls departure flights and
|
||||
// other player controls arrival flights.
|
||||
|
@ -549,12 +552,18 @@ void GameClockFlights(void)
|
|||
void GameGraphics(void)
|
||||
{
|
||||
int i;
|
||||
bool split_screen = false;
|
||||
|
||||
while( (GfxIsGPUBusy() == true)
|
||||
||
|
||||
(SystemRefreshNeeded() == false) );
|
||||
|
||||
GsSortCls(0,0,NORMAL_LUMINANCE >> 1);
|
||||
|
||||
if( (PlayerData[PLAYER_ONE].Active == true)
|
||||
&&
|
||||
(PlayerData[PLAYER_TWO].Active == true) )
|
||||
{
|
||||
split_screen = true;
|
||||
}
|
||||
|
||||
if(GfxGetGlobalLuminance() < NORMAL_LUMINANCE)
|
||||
{
|
||||
|
@ -564,24 +573,34 @@ void GameGraphics(void)
|
|||
for(i = 0; i < MAX_PLAYERS ; i++)
|
||||
{
|
||||
if(PlayerData[i].Active == true)
|
||||
{
|
||||
{
|
||||
if(split_screen == true)
|
||||
{
|
||||
GfxSetSplitScreen(i);
|
||||
}
|
||||
|
||||
GsSortCls(0,0,GfxGetGlobalLuminance() >> 1);
|
||||
|
||||
GameRenderLevel(&PlayerData[i]);
|
||||
AircraftRender(&PlayerData[i]);
|
||||
|
||||
GameGuiAircraftNotificationRequest(&FlightData);
|
||||
|
||||
GameGuiBubble(&FlightData);
|
||||
|
||||
GameGuiClock(GameHour,GameMinutes);
|
||||
|
||||
/*for(i = 0; i < MAX_PLAYERS ; i++)
|
||||
{*/
|
||||
GameGuiAircraftList(&PlayerData[i], &FlightData);
|
||||
//}
|
||||
|
||||
GfxDrawScene_Fast();
|
||||
while(GfxIsGPUBusy() == true);
|
||||
}
|
||||
}
|
||||
|
||||
GameGuiAircraftNotificationRequest(&FlightData);
|
||||
|
||||
GameGuiBubble(&FlightData);
|
||||
|
||||
GameGuiClock(GameHour,GameMinutes);
|
||||
|
||||
for(i = 0; i < MAX_PLAYERS ; i++)
|
||||
{
|
||||
GameGuiAircraftList(&PlayerData[i], &FlightData);
|
||||
}
|
||||
|
||||
GfxDrawScene();
|
||||
SystemCyclicHandler();
|
||||
}
|
||||
|
||||
void GameLoadLevel(void)
|
||||
|
@ -658,6 +677,11 @@ char* GetGameLevelTitle(void)
|
|||
void GameAircraftState(void)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t target[2] = {0};
|
||||
// Arrays are copied to AircraftAddNew, so we create a first and only
|
||||
// target which is the parking tile itself, and the second element
|
||||
// is just the NULL character.
|
||||
// Not an ideal solution, but the best one currently available.
|
||||
|
||||
for(i = 0; i < FlightData.nAircraft ; i++)
|
||||
{
|
||||
|
@ -670,6 +694,16 @@ void GameAircraftState(void)
|
|||
if(FlightData.FlightDirection[i] == DEPARTURE)
|
||||
{
|
||||
FlightData.State[i] = STATE_PARKED;
|
||||
|
||||
target[0] = FlightData.Parking[i];
|
||||
|
||||
dprintf("Target assigned = %d", target[0]);
|
||||
|
||||
if(AircraftAddNew(&FlightData, i, target) == false)
|
||||
{
|
||||
dprintf("Exceeded maximum aircraft number!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(FlightData.FlightDirection[i] == ARRIVAL)
|
||||
{
|
||||
|
@ -947,11 +981,11 @@ void GameStateShowAircraft(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFlight
|
|||
{
|
||||
if(ptrPlayer->ShowAircraftData == true)
|
||||
{
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_TRIANGLE) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_TRIANGLE) == true)
|
||||
{
|
||||
ptrPlayer->ShowAircraftData = false;
|
||||
}
|
||||
else if(ptrPlayer->PadKeyReleased_Callback(PAD_SQUARE) == true)
|
||||
else if(ptrPlayer->PadKeySinglePress_Callback(PAD_SQUARE) == true)
|
||||
{
|
||||
dprintf("Aircraft state = %d. STATE_IDLE = %d\n",
|
||||
ptrFlightData->State[ptrPlayer->SelectedAircraft],
|
||||
|
@ -965,7 +999,7 @@ void GameStateShowAircraft(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFlight
|
|||
}
|
||||
}
|
||||
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_CIRCLE) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_CIRCLE) == true)
|
||||
{
|
||||
if(GameGuiShowAircraftDataSpecialConditions(ptrPlayer) == false)
|
||||
{
|
||||
|
@ -981,7 +1015,7 @@ void GameStateLockTarget(TYPE_PLAYER * ptrPlayer)
|
|||
{
|
||||
CameraMoveToIsoPos(ptrPlayer, AircraftGetIsoPos(ptrPlayer->LockedAircraft) );
|
||||
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_SQUARE) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_SQUARE) == true)
|
||||
{
|
||||
ptrPlayer->LockTarget = false;
|
||||
ptrPlayer->LockedAircraft = 0;
|
||||
|
@ -1010,7 +1044,7 @@ void GameStateSelectTaxiwayRunway(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * pt
|
|||
ptrPlayer->InvalidPath = true;
|
||||
}
|
||||
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_TRIANGLE) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_TRIANGLE) == true)
|
||||
{
|
||||
// State exit.
|
||||
ptrPlayer->SelectTaxiwayRunway = false;
|
||||
|
@ -1019,7 +1053,7 @@ void GameStateSelectTaxiwayRunway(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * pt
|
|||
ptrPlayer->WaypointIdx = 0;
|
||||
ptrPlayer->LastWaypointIdx = 0;
|
||||
}
|
||||
else if(ptrPlayer->PadKeyReleased_Callback(PAD_CROSS) == true)
|
||||
else if(ptrPlayer->PadKeySinglePress_Callback(PAD_CROSS) == true)
|
||||
{
|
||||
if(ptrPlayer->InvalidPath == false)
|
||||
{
|
||||
|
@ -1035,32 +1069,36 @@ void GameStateSelectTaxiwayRunway(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * pt
|
|||
|
||||
target_tile = GameLevelBuffer[ptrPlayer->Waypoints[ptrPlayer->LastWaypointIdx]];
|
||||
|
||||
if( (target_tile == TILE_RWY_START_1)
|
||||
||
|
||||
(target_tile == (TILE_RWY_START_1 | TILE_MIRROR_FLAG) )
|
||||
||
|
||||
(target_tile == TILE_RWY_START_2)
|
||||
||
|
||||
(target_tile == (TILE_RWY_START_2 | TILE_MIRROR_FLAG) ) )
|
||||
switch(target_tile)
|
||||
{
|
||||
// TODO: Assign path to aircraft
|
||||
AircraftFromFlightDataIndexAddTargets(ptrPlayer->LockedAircraft, ptrPlayer->Waypoints);
|
||||
dprintf("Added these targets to aircraft %d:\n", ptrPlayer->LockedAircraft);
|
||||
case TILE_RWY_START_1:
|
||||
// Fall through
|
||||
case TILE_RWY_START_1 | TILE_MIRROR_FLAG:
|
||||
// Fall through
|
||||
case TILE_RWY_START_2:
|
||||
// Fall through
|
||||
case TILE_RWY_START_2 | TILE_MIRROR_FLAG:
|
||||
AircraftFromFlightDataIndexAddTargets(ptrPlayer->LockedAircraft, ptrPlayer->Waypoints);
|
||||
dprintf("Added these targets to aircraft %d:\n", ptrPlayer->LockedAircraft);
|
||||
|
||||
for(i = 0; i < PLAYER_MAX_WAYPOINTS; i++)
|
||||
{
|
||||
dprintf("%d ",ptrPlayer->Waypoints[i]);
|
||||
}
|
||||
|
||||
dprintf("\n");
|
||||
|
||||
ptrPlayer->SelectTaxiwayParking = false;
|
||||
// Clear waypoints array.
|
||||
memset(ptrPlayer->Waypoints, 0, sizeof(uint16_t) * PLAYER_MAX_WAYPOINTS);
|
||||
ptrPlayer->WaypointIdx = 0;
|
||||
ptrPlayer->LastWaypointIdx = 0;
|
||||
|
||||
ptrFlightData->State[ptrPlayer->LockedAircraft] = STATE_TAXIING;
|
||||
break;
|
||||
|
||||
for(i = 0; i < PLAYER_MAX_WAYPOINTS; i++)
|
||||
{
|
||||
dprintf("%d ",ptrPlayer->Waypoints[i]);
|
||||
}
|
||||
|
||||
dprintf("\n");
|
||||
|
||||
ptrPlayer->SelectTaxiwayParking = false;
|
||||
// Clear waypoints array.
|
||||
memset(ptrPlayer->Waypoints, 0, sizeof(uint16_t) * PLAYER_MAX_WAYPOINTS);
|
||||
ptrPlayer->WaypointIdx = 0;
|
||||
ptrPlayer->LastWaypointIdx = 0;
|
||||
|
||||
ptrFlightData->State[ptrPlayer->LockedAircraft] = STATE_TAXIING;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1086,7 +1124,7 @@ void GameStateSelectTaxiwayParking(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * p
|
|||
ptrPlayer->InvalidPath = true;
|
||||
}
|
||||
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_TRIANGLE) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_TRIANGLE) == true)
|
||||
{
|
||||
// State exit.
|
||||
ptrPlayer->SelectTaxiwayParking = false;
|
||||
|
@ -1095,7 +1133,7 @@ void GameStateSelectTaxiwayParking(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * p
|
|||
ptrPlayer->WaypointIdx = 0;
|
||||
ptrPlayer->LastWaypointIdx = 0;
|
||||
}
|
||||
else if(ptrPlayer->PadKeyReleased_Callback(PAD_CROSS) == true)
|
||||
else if(ptrPlayer->PadKeySinglePress_Callback(PAD_CROSS) == true)
|
||||
{
|
||||
if(ptrPlayer->InvalidPath == false)
|
||||
{
|
||||
|
@ -1158,11 +1196,11 @@ void GameStateSelectRunway(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFlight
|
|||
ptrPlayer->LockTarget = false;
|
||||
ptrPlayer->LockedAircraft = 0;
|
||||
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_TRIANGLE) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_TRIANGLE) == true)
|
||||
{
|
||||
ptrPlayer->SelectRunway = false;
|
||||
}
|
||||
else if(ptrPlayer->PadKeyReleased_Callback(PAD_CROSS) == true)
|
||||
else if(ptrPlayer->PadKeySinglePress_Callback(PAD_CROSS) == true)
|
||||
{
|
||||
ptrPlayer->SelectRunway = false;
|
||||
|
||||
|
@ -1191,14 +1229,14 @@ void GameStateSelectRunway(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFlight
|
|||
}
|
||||
}
|
||||
}
|
||||
else if(ptrPlayer->PadKeyReleased_Callback(PAD_LEFT) == true)
|
||||
else if(ptrPlayer->PadKeySinglePress_Callback(PAD_LEFT) == true)
|
||||
{
|
||||
if(ptrPlayer->SelectedRunway != 0)
|
||||
{
|
||||
ptrPlayer->SelectedRunway--;
|
||||
}
|
||||
}
|
||||
else if(ptrPlayer->PadKeyReleased_Callback(PAD_RIGHT) == true)
|
||||
else if(ptrPlayer->PadKeySinglePress_Callback(PAD_RIGHT) == true)
|
||||
{
|
||||
if(ptrPlayer->SelectedRunway < GAME_MAX_RUNWAYS)
|
||||
{
|
||||
|
@ -1248,7 +1286,7 @@ void GameSelectAircraftFromList(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrF
|
|||
|
||||
if(ptrPlayer->ShowAircraftData == true)
|
||||
{
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_CROSS) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_CROSS) == true)
|
||||
{
|
||||
if(ptrPlayer->ActiveAircraft != 0)
|
||||
{
|
||||
|
@ -1467,6 +1505,10 @@ void GameTargetsReached(uint8_t index)
|
|||
FlightData.State[index] = STATE_LANDED;
|
||||
break;
|
||||
|
||||
case STATE_TAXIING:
|
||||
FlightData.State[index] = STATE_PARKED;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1492,6 +1534,11 @@ uint16_t GameGetTileFromIsoPosition(TYPE_ISOMETRIC_POS * IsoPos)
|
|||
{
|
||||
uint16_t tile;
|
||||
|
||||
if(IsoPos == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( (IsoPos->x < 0) || (IsoPos->y < 0) )
|
||||
{
|
||||
return GAME_INVALID_TILE_SELECTION; // Invalid XYZ position
|
||||
|
@ -1613,8 +1660,20 @@ bool GamePathToTile(TYPE_PLAYER * ptrPlayer)
|
|||
|
||||
if(SystemContains_u16(temp_tile, ptrPlayer->Waypoints, PLAYER_MAX_WAYPOINTS) == false)
|
||||
{
|
||||
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
||||
{
|
||||
if(temp_tile == AircraftGetTileFromFlightDataIndex(i))
|
||||
{
|
||||
return false; // Check pending!
|
||||
}
|
||||
}
|
||||
|
||||
GamePlayerAddWaypoint_Ex(ptrPlayer, temp_tile);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false; // Tile is already included in the list of temporary tiles?
|
||||
}
|
||||
}
|
||||
|
||||
while( (y_diff--) > 0)
|
||||
|
@ -1631,8 +1690,21 @@ bool GamePathToTile(TYPE_PLAYER * ptrPlayer)
|
|||
|
||||
if(SystemContains_u16(temp_tile, ptrPlayer->Waypoints, PLAYER_MAX_WAYPOINTS) == false)
|
||||
{
|
||||
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
||||
{
|
||||
if(temp_tile == AircraftGetTileFromFlightDataIndex(i))
|
||||
{
|
||||
return false; // Check pending!
|
||||
}
|
||||
}
|
||||
|
||||
GamePlayerAddWaypoint_Ex(ptrPlayer, temp_tile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TEST - Check pending!
|
||||
return false; // Tile is already included in the list of temporary tiles?
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1651,8 +1723,21 @@ bool GamePathToTile(TYPE_PLAYER * ptrPlayer)
|
|||
|
||||
if(SystemContains_u16(temp_tile, ptrPlayer->Waypoints, PLAYER_MAX_WAYPOINTS) == false)
|
||||
{
|
||||
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
||||
{
|
||||
if(temp_tile == AircraftGetTileFromFlightDataIndex(i))
|
||||
{
|
||||
return false; // Check pending!
|
||||
}
|
||||
}
|
||||
|
||||
GamePlayerAddWaypoint_Ex(ptrPlayer, temp_tile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TEST - Check pending!
|
||||
return false; // Tile is already included in the list of temporary tiles?
|
||||
}
|
||||
}
|
||||
|
||||
while( (x_diff--) > 0)
|
||||
|
@ -1669,8 +1754,21 @@ bool GamePathToTile(TYPE_PLAYER * ptrPlayer)
|
|||
|
||||
if(SystemContains_u16(temp_tile, ptrPlayer->Waypoints, PLAYER_MAX_WAYPOINTS) == false)
|
||||
{
|
||||
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
||||
{
|
||||
if(temp_tile == AircraftGetTileFromFlightDataIndex(i))
|
||||
{
|
||||
return false; // Check pending!
|
||||
}
|
||||
}
|
||||
|
||||
GamePlayerAddWaypoint_Ex(ptrPlayer, temp_tile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TEST - Check pending!
|
||||
return false; // Tile is already included in the list of temporary tiles?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,5 +44,6 @@ uint8_t GameGetLevelColumns(void);
|
|||
fix16_t GameGetXFromTile(uint16_t tile);
|
||||
fix16_t GameGetYFromTile(uint16_t tile);
|
||||
void GameTargetsReached(uint8_t index);
|
||||
uint16_t GameGetTileFromIsoPosition(TYPE_ISOMETRIC_POS * IsoPos);
|
||||
|
||||
#endif //__GAME_HEADER__
|
||||
|
|
|
@ -336,7 +336,7 @@ bool GameGuiPauseDialog(TYPE_PLAYER * ptrPlayer)
|
|||
|
||||
do
|
||||
{
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_CROSS) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_CROSS) == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ bool GameGuiPauseDialog(TYPE_PLAYER * ptrPlayer)
|
|||
|
||||
GfxDrawScene_Slow();
|
||||
|
||||
}while(ptrPlayer->PadKeyReleased_Callback(PAD_START) == false);
|
||||
}while(ptrPlayer->PadKeySinglePress_Callback(PAD_START) == false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -388,7 +388,7 @@ void GameGuiActiveAircraftPage(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFl
|
|||
|
||||
if(ptrPlayer->ShowAircraftData == true)
|
||||
{
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_DOWN) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_DOWN) == true)
|
||||
{
|
||||
if( ( (ptrPlayer->SelectedAircraft + 1) < ptrPlayer->ActiveAircraft)
|
||||
&&
|
||||
|
@ -398,7 +398,7 @@ void GameGuiActiveAircraftPage(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFl
|
|||
}
|
||||
}
|
||||
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_UP) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_UP) == true)
|
||||
{
|
||||
if(ptrPlayer->SelectedAircraft > ( (ptrPlayer->FlightDataPage) * GAME_GUI_AIRCRAFT_DATA_MAX_PAGE) )
|
||||
{
|
||||
|
@ -406,7 +406,7 @@ void GameGuiActiveAircraftPage(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFl
|
|||
}
|
||||
}
|
||||
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_RIGHT) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_RIGHT) == true)
|
||||
{
|
||||
if(ptrPlayer->ActiveAircraft > (GAME_GUI_AIRCRAFT_DATA_MAX_PAGE * (ptrPlayer->FlightDataPage + 1) ) )
|
||||
{
|
||||
|
@ -416,7 +416,7 @@ void GameGuiActiveAircraftPage(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFl
|
|||
}
|
||||
}
|
||||
|
||||
if(ptrPlayer->PadKeyReleased_Callback(PAD_LEFT) == true)
|
||||
if(ptrPlayer->PadKeySinglePress_Callback(PAD_LEFT) == true)
|
||||
{
|
||||
if(ptrPlayer->FlightDataPage != 0)
|
||||
{
|
||||
|
@ -544,7 +544,7 @@ void GameGuiAircraftList(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightDa
|
|||
{
|
||||
FontPrintText( &SmallFont,
|
||||
AIRCRAFT_DATA_GSGPOLY4_X0 +
|
||||
( (AIRCRAFT_DATA_GSGPOLY4_X1 - AIRCRAFT_DATA_GSGPOLY4_X0) >> 1),
|
||||
( (AIRCRAFT_DATA_GSGPOLY4_X1 - AIRCRAFT_DATA_GSGPOLY4_X0) >> 2),
|
||||
AIRCRAFT_DATA_GSGPOLY4_Y0 +
|
||||
( (AIRCRAFT_DATA_GSGPOLY4_Y2 - AIRCRAFT_DATA_GSGPOLY4_Y0) >> 1),
|
||||
"No flights!" );
|
||||
|
@ -696,25 +696,32 @@ void GameGuiShowAircraftData(TYPE_PLAYER * ptrPlayer, TYPE_FLIGHT_DATA * ptrFlig
|
|||
{
|
||||
case STATE_FINAL:
|
||||
FontPrintText( &SmallFont,
|
||||
AIRCRAFT_DATA_DIRECTION_X + 64,
|
||||
AIRCRAFT_DATA_DIRECTION_X + 88,
|
||||
AIRCRAFT_DATA_DIRECTION_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j),
|
||||
"Landing" );
|
||||
break;
|
||||
|
||||
case STATE_TAXIING:
|
||||
FontPrintText( &SmallFont,
|
||||
AIRCRAFT_DATA_DIRECTION_X + 64,
|
||||
AIRCRAFT_DATA_DIRECTION_X + 88,
|
||||
AIRCRAFT_DATA_DIRECTION_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j),
|
||||
"Taxiing" );
|
||||
break;
|
||||
|
||||
case STATE_LANDED:
|
||||
FontPrintText( &SmallFont,
|
||||
AIRCRAFT_DATA_DIRECTION_X + 64,
|
||||
AIRCRAFT_DATA_DIRECTION_X + 88,
|
||||
AIRCRAFT_DATA_DIRECTION_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j),
|
||||
"Arrived" );
|
||||
break;
|
||||
|
||||
case STATE_PARKED:
|
||||
FontPrintText( &SmallFont,
|
||||
AIRCRAFT_DATA_DIRECTION_X + 88,
|
||||
AIRCRAFT_DATA_DIRECTION_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j),
|
||||
"Parked" );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -159,6 +159,7 @@ typedef struct
|
|||
|
||||
bool (*PadKeyPressed_Callback)(unsigned short);
|
||||
bool (*PadKeyReleased_Callback)(unsigned short);
|
||||
bool (*PadKeySinglePress_Callback)(unsigned short);
|
||||
bool (*PadDirectionKeyPressed_Callback)(void);
|
||||
TYPE_CAMERA Camera;
|
||||
}TYPE_PLAYER;
|
||||
|
|
71
Source/Gfx.c
71
Source/Gfx.c
|
@ -13,6 +13,7 @@
|
|||
#define UPLOAD_IMAGE_FLAG 1
|
||||
#define MAX_LUMINANCE 0xFF
|
||||
#define ROTATE_BIT_SHIFT 12
|
||||
#define GPUSTAT (*(unsigned int*)0x1F801814)
|
||||
|
||||
/* *************************************
|
||||
* Structs and enums
|
||||
|
@ -87,7 +88,6 @@ void GfxSwapBuffers(void)
|
|||
GsSetDispEnv(&DispEnv);
|
||||
GsSetDrawEnv(&DrawEnv);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,34 +122,20 @@ void GfxDrawScene_Fast(void)
|
|||
GsDrawList();
|
||||
}
|
||||
|
||||
bool GfxReadyForDMATransfer(void)
|
||||
{
|
||||
return (GPUSTAT & 1<<28);
|
||||
}
|
||||
|
||||
void GfxDrawScene(void)
|
||||
{
|
||||
while( (SystemRefreshNeeded() == false)
|
||||
||
|
||||
(GsIsDrawing() == true)
|
||||
||
|
||||
(SystemDMAReady() == false) );
|
||||
(GfxIsGPUBusy() == true) );
|
||||
|
||||
GfxDrawScene_Fast();
|
||||
|
||||
if(UpdatePads() == false)
|
||||
{
|
||||
SystemSetEmergencyMode(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemSetEmergencyMode(false);
|
||||
}
|
||||
|
||||
SystemRunTimers();
|
||||
|
||||
SystemUserTimersHandler();
|
||||
|
||||
SystemDisableScreenRefresh();
|
||||
|
||||
MemCardHandler();
|
||||
|
||||
SystemCheckStack();
|
||||
SystemCyclicHandler();
|
||||
}
|
||||
|
||||
void GfxDrawScene_Slow(void)
|
||||
|
@ -283,7 +269,7 @@ int GfxRotateFromDegrees(int deg)
|
|||
|
||||
bool GfxIsGPUBusy(void)
|
||||
{
|
||||
return (GsIsDrawing() || gfx_busy || SystemDMABusy() );
|
||||
return (GsIsDrawing() || gfx_busy || (GfxReadyForDMATransfer() == false) );
|
||||
}
|
||||
|
||||
bool GfxSpriteFromFile(char * fname, GsSprite * spr)
|
||||
|
@ -416,6 +402,8 @@ void GfxDrawButton(short x, short y, unsigned short btn)
|
|||
|
||||
void GfxSaveDisplayData(GsSprite *spr)
|
||||
{
|
||||
while(GfxIsGPUBusy() == true);
|
||||
|
||||
MoveImage( DispEnv.x,
|
||||
DispEnv.y,
|
||||
GFX_SECOND_DISPLAY_X,
|
||||
|
@ -524,3 +512,40 @@ TYPE_ISOMETRIC_POS GfxCartesianToIsometric(TYPE_CARTESIAN_POS * ptrCartPos)
|
|||
|
||||
return IsoPos;
|
||||
}
|
||||
|
||||
void GfxSetSplitScreen(uint8_t playerIndex)
|
||||
{
|
||||
|
||||
switch(playerIndex)
|
||||
{
|
||||
case 0:
|
||||
// PLAYER_ONE
|
||||
DrawEnv.x = 0;
|
||||
DrawEnv.w = X_SCREEN_RESOLUTION >> 1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// PLAYER_TWO
|
||||
DrawEnv.x = X_SCREEN_RESOLUTION >> 1;
|
||||
DrawEnv.w = X_SCREEN_RESOLUTION >> 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dprintf("Player idx = %d, x = %d, w = %d\n",
|
||||
playerIndex,
|
||||
DrawEnv.x,
|
||||
DrawEnv.w);
|
||||
|
||||
GsSetDrawEnv(&DrawEnv);
|
||||
}
|
||||
|
||||
void GfxDisableSplitScreen(void)
|
||||
{
|
||||
DrawEnv.x = 0;
|
||||
DrawEnv.w = X_SCREEN_RESOLUTION;
|
||||
|
||||
GsSetDrawEnv(&DrawEnv);
|
||||
}
|
||||
|
|
30
Source/Gfx.h
30
Source/Gfx.h
|
@ -32,43 +32,73 @@
|
|||
void GfxInitDrawEnv(void);
|
||||
void GfxInitDispEnv(void);
|
||||
void GfxSetPrimitiveList(void);
|
||||
|
||||
// Renders new scene. Use this function unless you know what you are doing!
|
||||
void GfxDrawScene(void);
|
||||
|
||||
// Blocking version. Calls GfxDrawScene() and then adds a while(GfxIsBusy() )
|
||||
// after it.
|
||||
void GfxDrawScene_Slow(void);
|
||||
|
||||
// Only renders screen and does not update any pad data or timer data.
|
||||
// To be used in ISR!
|
||||
void GfxDrawScene_Fast(void);
|
||||
|
||||
// Repotedly, tells is GPU is ready for a DMA transfer.
|
||||
bool GfxReadyForDMATransfer(void);
|
||||
|
||||
// Fills a GsSprite structure with information from a TIM file.
|
||||
bool GfxSpriteFromFile(char * fname, GsSprite * spr);
|
||||
|
||||
// Reportedly, loads CLUT data from a TIM image (image data is discarded)
|
||||
bool GfxCLUTFromFile(char * fname);
|
||||
|
||||
// Returns true if current object is within screen limits, false otherwise.
|
||||
bool GfxIsInsideScreenArea(short x, short y, short w, short h);
|
||||
|
||||
// Function overload for GsSprite structures.
|
||||
bool GfxIsSpriteInsideScreenArea(GsSprite * spr);
|
||||
|
||||
// Used to know whether GPU operation can be done.
|
||||
bool GfxIsGPUBusy(void);
|
||||
|
||||
// Draws a sprite on screen. First, it checks whether sprite is inside
|
||||
// screen limits.
|
||||
void GfxSortSprite(GsSprite * spr);
|
||||
|
||||
uint8_t GfxGetGlobalLuminance(void);
|
||||
|
||||
void GfxSetGlobalLuminance(uint8_t value);
|
||||
|
||||
void GfxIncreaseGlobalLuminance(int8_t step);
|
||||
|
||||
int GfxRotateFromDegrees(int deg);
|
||||
|
||||
void GfxDrawButton(short x, short y, unsigned short btn);
|
||||
|
||||
// Sends current display data on a specific VRAM section and fills
|
||||
// sprite structure pointed to by "spr".
|
||||
void GfxSaveDisplayData(GsSprite *spr);
|
||||
|
||||
TYPE_CARTESIAN_POS GfxIsometricToCartesian(TYPE_ISOMETRIC_POS * ptrIsoPos);
|
||||
// Function overload for fixed-point 16.16 data type.
|
||||
|
||||
TYPE_CARTESIAN_POS GfxIsometricFix16ToCartesian(TYPE_ISOMETRIC_FIX16_POS * ptrIso16Pos);
|
||||
|
||||
// Transforms cartesian position to isometric position. Z axis is assumed to be zero!
|
||||
TYPE_ISOMETRIC_POS GfxCartesianToIsometric(TYPE_CARTESIAN_POS * ptrCartPos);
|
||||
|
||||
// Fills GsSprite structure pointed to by "spr" with texture page and U/V
|
||||
// offset data given a position in VRAM.
|
||||
bool GfxTPageOffsetFromVRAMPosition(GsSprite * spr, short x, short y);
|
||||
|
||||
void GfxSetSplitScreen(uint8_t playerIndex);
|
||||
|
||||
void GfxDisableSplitScreen(void);
|
||||
|
||||
// Switches between true and false every 1 exact second (used for flashing effects)
|
||||
bool Gfx1HzFlash(void);
|
||||
|
||||
// Switches between true and false every 500 milliseconds (used for flashing effects)
|
||||
bool Gfx2HzFlash(void);
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
|
|||
$(CC) $< -o $@ $(DEFINE) $(CC_FLAGS)
|
||||
|
||||
$(PROJECT).elf:
|
||||
$(LINKER) Obj/*.o -o Exe/$(PROJECT).elf $(LIBS)
|
||||
$(LINKER) Obj/*.o -o Exe/$(PROJECT).elf $(LIBS) -Wl,--gc-sections
|
||||
|
||||
$(PROJECT).exe:
|
||||
$(ELF2EXE) Exe/$(PROJECT).elf Exe/$(PROJECT).exe $(ELF2EXE_FLAGS)
|
||||
|
|
|
@ -121,10 +121,13 @@ static char * MainMenuFiles[] = { "cdrom:\\DATA\\SPRITES\\MAINMENU.TIM;1" ,
|
|||
"cdrom:\\DATA\\SPRITES\\PSXDISK.TIM;1" ,
|
||||
"cdrom:\\DATA\\SPRITES\\INTROFNT.TIM;1" ,
|
||||
"cdrom:\\DATA\\SPRITES\\BUTTONS.TIM;1" ,
|
||||
#ifndef NO_INTRO
|
||||
"cdrom:\\DATA\\SPRITES\\GPL.TIM;1" ,
|
||||
"cdrom:\\DATA\\SPRITES\\OPENSRC.TIM;1" ,
|
||||
"cdrom:\\DATA\\SOUNDS\\TRAYCL.VAG;1" ,
|
||||
"cdrom:\\DATA\\SOUNDS\\SPINDISK.VAG;1" };
|
||||
"cdrom:\\DATA\\SOUNDS\\SPINDISK.VAG;1"
|
||||
#endif // NO_INTRO
|
||||
};
|
||||
|
||||
static void * MainMenuDest[] = { (GsSprite*)&MenuSpr ,
|
||||
(SsVag*)&BellSnd ,
|
||||
|
@ -132,10 +135,13 @@ static void * MainMenuDest[] = { (GsSprite*)&MenuSpr ,
|
|||
(GsSprite*)&PsxDisk ,
|
||||
(GsSprite*)&PSXSDKIntroFont ,
|
||||
(GsSprite*)&PSXButtons ,
|
||||
#ifndef NO_INTRO
|
||||
(GsSprite*)&GPL_Logo ,
|
||||
(GsSprite*)&OpenSource_Logo ,
|
||||
(SsVag*)&TrayClSnd ,
|
||||
(SsVag*)&SpinDiskSnd };
|
||||
(SsVag*)&SpinDiskSnd
|
||||
#endif // NO_INTRO
|
||||
};
|
||||
|
||||
static TYPE_MMBtn MainMenuBtn[MAIN_MENU_BUTTONS_MAX];
|
||||
static MainMenuLevel menuLevel;
|
||||
|
@ -254,12 +260,13 @@ void MainMenu(void)
|
|||
|
||||
while(1)
|
||||
{
|
||||
while(GfxIsGPUBusy() == true);
|
||||
|
||||
MainMenuButtonHandler();
|
||||
|
||||
switch(menuLevel)
|
||||
{
|
||||
case PLAY_OPTIONS_LEVEL:
|
||||
while(SystemDMAReady() == false);
|
||||
|
||||
GsSortCls(0,0,40);
|
||||
MainMenuDrawButton(&MainMenuBtn[PLAY_BUTTON_INDEX]);
|
||||
|
@ -269,7 +276,6 @@ void MainMenu(void)
|
|||
break;
|
||||
|
||||
case ONE_TWO_PLAYERS_LEVEL:
|
||||
while(SystemDMAReady() == false);
|
||||
|
||||
GsSortCls(0,0,40);
|
||||
MainMenuDrawButton(&MainMenuBtn[ONE_PLAYER_BUTTON_INDEX]);
|
||||
|
@ -320,9 +326,9 @@ void MainMenuButtonHandler(void)
|
|||
}
|
||||
}
|
||||
|
||||
if( (PadOneKeyReleased(PAD_CROSS) == true)
|
||||
if( (PadOneKeySinglePress(PAD_CROSS) == true)
|
||||
||
|
||||
(PadOneKeyReleased(PAD_TRIANGLE) == true) )
|
||||
(PadOneKeySinglePress(PAD_TRIANGLE) == true) )
|
||||
{
|
||||
SfxPlaySound(&AcceptSnd);
|
||||
}
|
||||
|
@ -335,7 +341,7 @@ void MainMenuButtonHandler(void)
|
|||
|
||||
case ONE_TWO_PLAYERS_LEVEL:
|
||||
max_buttons = MAIN_MENU_ONE_TWO_PLAYERS_LEVEL_BUTTONS;
|
||||
if(PadOneKeyReleased(PAD_TRIANGLE) == true)
|
||||
if(PadOneKeySinglePress(PAD_TRIANGLE) == true)
|
||||
{
|
||||
menuLevel = PLAY_OPTIONS_LEVEL;
|
||||
MainMenuMinimumBtn = PLAY_BUTTON_INDEX;
|
||||
|
@ -351,14 +357,14 @@ void MainMenuButtonHandler(void)
|
|||
MainMenuBtn[previous_btn_selected].was_selected = MainMenuBtn[previous_btn_selected].selected;
|
||||
MainMenuBtn[btn_selected].was_selected = MainMenuBtn[btn_selected].selected;
|
||||
|
||||
if(PadOneKeyReleased(PAD_LEFT) && (btn_selected > 0) )
|
||||
if(PadOneKeySinglePress(PAD_LEFT) && (btn_selected > 0) )
|
||||
{
|
||||
MainMenuBtn[btn_selected].selected = false;
|
||||
previous_btn_selected = btn_selected;
|
||||
btn_selected--;
|
||||
SfxPlaySound(&BellSnd);
|
||||
}
|
||||
else if(PadOneKeyReleased(PAD_RIGHT)
|
||||
else if(PadOneKeySinglePress(PAD_RIGHT)
|
||||
&&
|
||||
(btn_selected < (max_buttons - 1 + MainMenuMinimumBtn) ) )
|
||||
{
|
||||
|
@ -379,7 +385,7 @@ void MainMenuButtonHandler(void)
|
|||
btn_selected = (max_buttons - 1 + MainMenuMinimumBtn);
|
||||
}
|
||||
|
||||
if(PadOneKeyReleased(PAD_CROSS) )
|
||||
if(PadOneKeySinglePress(PAD_CROSS) )
|
||||
{
|
||||
if(menuLevel == ONE_TWO_PLAYERS_LEVEL)
|
||||
{
|
||||
|
|
10
Source/Pad.c
10
Source/Pad.c
|
@ -177,6 +177,16 @@ bool PadTwoKeyPressed(unsigned short key)
|
|||
return (bool)( pad2 & key );
|
||||
}
|
||||
|
||||
bool PadOneKeySinglePress(unsigned short key)
|
||||
{
|
||||
return (bool)( !(previous_pad1 & key) && (pad1 & key) );
|
||||
}
|
||||
|
||||
bool PadTwoKeySinglePress(unsigned short key)
|
||||
{
|
||||
return (bool)( !(previous_pad2 & key) && (pad2 & key) );
|
||||
}
|
||||
|
||||
bool PadOneKeyRepeat(unsigned short key, uint8_t time)
|
||||
{
|
||||
uint8_t key_index = PadGetKeyIndex(key);
|
||||
|
|
|
@ -36,6 +36,9 @@ bool PadTwoKeyRepeat(unsigned short key, uint8_t time);
|
|||
bool PadOneKeyReleased(unsigned short key);
|
||||
bool PadTwoKeyReleased(unsigned short key);
|
||||
|
||||
bool PadOneKeySinglePress(unsigned short key);
|
||||
bool PadTwoKeySinglePress(unsigned short key);
|
||||
|
||||
bool PadOneDirectionKeyPressed(void);
|
||||
bool PadTwoDirectionKeyPressed(void);
|
||||
|
||||
|
|
145
Source/System.c
145
Source/System.c
|
@ -14,6 +14,7 @@
|
|||
#define END_STACK_PATTERN (uint32_t) 0x18022015
|
||||
#define BEGIN_STACK_ADDRESS (uint32_t*) 0x801FFF00
|
||||
#define STACK_SIZE 0x1000
|
||||
#define I_MASK (*(unsigned int*)0x1F801074)
|
||||
|
||||
/* *************************************
|
||||
* Local Prototypes
|
||||
|
@ -21,6 +22,8 @@
|
|||
|
||||
static void SystemCheckTimer(bool * timer, uint64_t * last_timer, uint8_t step);
|
||||
static void SystemSetStackPattern(void);
|
||||
static void SystemEnableVBlankInterrupt(void);
|
||||
static void SystemDisableVBlankInterrupt(void);
|
||||
|
||||
/* *************************************
|
||||
* Local Variables
|
||||
|
@ -41,16 +44,21 @@ static bool five_hundred_ms_timer;
|
|||
//Emergency mode flag. Toggled on pad connected/disconnected
|
||||
static bool emergency_mode;
|
||||
//Critical section is entered (i.e.: when accessing fopen() or other BIOS functions
|
||||
static bool system_busy;
|
||||
static volatile bool system_busy;
|
||||
//Timer array.
|
||||
static TYPE_TIMER timer_array[SYSTEM_MAX_TIMERS];
|
||||
|
||||
/* *************************************
|
||||
/* *******************************************************************
|
||||
*
|
||||
* @name: void SystemInit(void)
|
||||
* @date: 19/05/2016
|
||||
*
|
||||
* @author: Xavier Del Campo
|
||||
* @brief:
|
||||
* *************************************/
|
||||
*
|
||||
* @brief: Calls main intialization routines.
|
||||
*
|
||||
* @remarks: To be called before main loop.
|
||||
*
|
||||
* *******************************************************************/
|
||||
|
||||
void SystemInit(void)
|
||||
{
|
||||
|
@ -97,6 +105,22 @@ void SystemInit(void)
|
|||
StartRCnt(RCntCNT2);
|
||||
}
|
||||
|
||||
/* *******************************************************************
|
||||
*
|
||||
* @name: void SystemInit(void)
|
||||
*
|
||||
* @author: Xavier Del Campo
|
||||
*
|
||||
* @brief:
|
||||
* Calls srand() while avoiding multiple calls by setting internal
|
||||
* variable rand_seed to true. Internal variable "global_timer" is
|
||||
* used to generate the new seed.
|
||||
*
|
||||
* @remarks:
|
||||
* It is recommended to call it once user has pressed any key.
|
||||
*
|
||||
* *******************************************************************/
|
||||
|
||||
void SystemSetRandSeed(void)
|
||||
{
|
||||
if(rand_seed == false)
|
||||
|
@ -109,32 +133,81 @@ void SystemSetRandSeed(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* *******************************************************************
|
||||
*
|
||||
* @name: bool SystemIsRandSeedSet(void)
|
||||
*
|
||||
* @author: Xavier Del Campo
|
||||
*
|
||||
* @brief:
|
||||
* Reportedly, returns whether rand seed has already been set.
|
||||
*
|
||||
* @remarks:
|
||||
*
|
||||
* @return:
|
||||
* Reportedly, returns whether rand seed has already been set.
|
||||
*
|
||||
* *******************************************************************/
|
||||
|
||||
bool SystemIsRandSeedSet(void)
|
||||
{
|
||||
return rand_seed;
|
||||
}
|
||||
|
||||
bool SystemDMAReady(void)
|
||||
{
|
||||
return (*((unsigned int*)0x1F801814) & 1<<28);
|
||||
}
|
||||
|
||||
bool SystemDMABusy(void)
|
||||
{
|
||||
return !SystemDMAReady();
|
||||
}
|
||||
/* *******************************************************************
|
||||
*
|
||||
* @name: bool SystemRefreshNeeded(void)
|
||||
*
|
||||
* @author: Xavier Del Campo
|
||||
*
|
||||
* @brief:
|
||||
*
|
||||
* @remarks:
|
||||
*
|
||||
* @return:
|
||||
* Returns whether VSync flag has been enabled.
|
||||
*
|
||||
* *******************************************************************/
|
||||
|
||||
bool SystemRefreshNeeded(void)
|
||||
{
|
||||
return refresh_needed;
|
||||
}
|
||||
|
||||
/* *******************************************************************
|
||||
*
|
||||
* @name: void ISR_SystemDefaultVBlank(void)
|
||||
*
|
||||
* @author: Xavier Del Campo
|
||||
*
|
||||
* @brief:
|
||||
*
|
||||
* @remarks:
|
||||
* Called from VSync interrupt. Called 50 times a second in PAL mode,
|
||||
* 60 times a second in NTSC mode.
|
||||
*
|
||||
* *******************************************************************/
|
||||
|
||||
void ISR_SystemDefaultVBlank(void)
|
||||
{
|
||||
refresh_needed = true;
|
||||
SystemIncreaseGlobalTimer();
|
||||
}
|
||||
|
||||
/* *******************************************************************
|
||||
*
|
||||
* @name: void SystemIncreaseGlobalTimer(void)
|
||||
*
|
||||
* @author: Xavier Del Campo
|
||||
*
|
||||
* @brief:
|
||||
* Increases internal variable responsible for time handling.
|
||||
*
|
||||
* @remarks:
|
||||
* Usually called from ISR_SystemDefaultVBlank().
|
||||
*
|
||||
* *******************************************************************/
|
||||
|
||||
void SystemIncreaseGlobalTimer(void)
|
||||
{
|
||||
global_timer++;
|
||||
|
@ -201,6 +274,9 @@ bool SystemLoadFileToBuffer(char * fname, uint8_t * buffer, uint32_t szBuffer)
|
|||
FILE *f;
|
||||
int32_t size;
|
||||
|
||||
// Wait for possible previous operation from the GPU before entering this section.
|
||||
while( (SystemIsBusy() == true) || (GfxIsGPUBusy() == true) );
|
||||
|
||||
if(fname == NULL)
|
||||
{
|
||||
dprintf("SystemLoadFile: NULL fname!\n");
|
||||
|
@ -210,6 +286,9 @@ bool SystemLoadFileToBuffer(char * fname, uint8_t * buffer, uint32_t szBuffer)
|
|||
memset(buffer,0,szBuffer);
|
||||
|
||||
system_busy = true;
|
||||
|
||||
SystemDisableVBlankInterrupt();
|
||||
|
||||
f = fopen(fname, "r");
|
||||
|
||||
if(f == NULL)
|
||||
|
@ -219,7 +298,7 @@ bool SystemLoadFileToBuffer(char * fname, uint8_t * buffer, uint32_t szBuffer)
|
|||
return false;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
fseek(f, 0, SEEK_END);
|
||||
|
||||
size = ftell(f);
|
||||
|
||||
|
@ -236,6 +315,8 @@ bool SystemLoadFileToBuffer(char * fname, uint8_t * buffer, uint32_t szBuffer)
|
|||
|
||||
fclose(f);
|
||||
|
||||
SystemEnableVBlankInterrupt();
|
||||
|
||||
system_busy = false;
|
||||
|
||||
dprintf("File \"%s\" loaded successfully!\n",fname);
|
||||
|
@ -275,7 +356,7 @@ bool SystemGetEmergencyMode(void)
|
|||
return emergency_mode;
|
||||
}
|
||||
|
||||
bool SystemIsBusy(void)
|
||||
volatile bool SystemIsBusy(void)
|
||||
{
|
||||
return system_busy;
|
||||
}
|
||||
|
@ -515,3 +596,35 @@ int32_t SystemIndexOf_U8(uint8_t value, uint8_t * array, uint32_t from, uint32_t
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SystemCyclicHandler(void)
|
||||
{
|
||||
if(UpdatePads() == false)
|
||||
{
|
||||
SystemSetEmergencyMode(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemSetEmergencyMode(false);
|
||||
}
|
||||
|
||||
SystemRunTimers();
|
||||
|
||||
SystemUserTimersHandler();
|
||||
|
||||
SystemDisableScreenRefresh();
|
||||
|
||||
MemCardHandler();
|
||||
|
||||
SystemCheckStack();
|
||||
}
|
||||
|
||||
void SystemDisableVBlankInterrupt(void)
|
||||
{
|
||||
I_MASK &= ~(0x0001);
|
||||
}
|
||||
|
||||
void SystemEnableVBlankInterrupt(void)
|
||||
{
|
||||
I_MASK |= (0x0001);
|
||||
}
|
||||
|
|
|
@ -23,78 +23,108 @@
|
|||
|
||||
// Calls PSXSDK init routines
|
||||
void SystemInit(void);
|
||||
|
||||
// Sets default VSync (only sets flag to true and increases global_timer)
|
||||
void ISR_SystemDefaultVBlank(void);
|
||||
|
||||
// Calls srand() using current global_timer value as seed
|
||||
void SystemSetRandSeed(void);
|
||||
|
||||
// Returns VSync flag value
|
||||
bool SystemRefreshNeeded(void);
|
||||
// Tells whether CPU->GPU DMA transfer is ready
|
||||
bool SystemDMAReady(void);
|
||||
// Tells whether CPU->GPU DMA transfer is busy
|
||||
bool SystemDMABusy(void);
|
||||
|
||||
// Loads a file into system's internal buffer
|
||||
bool SystemLoadFile(char *fname);
|
||||
|
||||
// Loads a file into desired buffer
|
||||
bool SystemLoadFileToBuffer(char * fname, uint8_t * buffer, uint32_t szBuffer);
|
||||
|
||||
// Clears VSync flag after each frame
|
||||
void SystemDisableScreenRefresh(void);
|
||||
|
||||
// Returns file buffer address
|
||||
uint8_t * SystemGetBufferAddress(void);
|
||||
|
||||
// Tells whether srand() has been called using a pseudo-random value
|
||||
bool SystemIsRandSeedSet(void);
|
||||
|
||||
// Stops program flow during X cycles
|
||||
void SystemWaitCycles(uint32_t cycles);
|
||||
|
||||
// To be called from GfxDrawScene after each cycle
|
||||
void SystemRunTimers(void);
|
||||
|
||||
// 1 cycle-length flag with a frequency of 1 Hz
|
||||
bool System1SecondTick(void);
|
||||
|
||||
// 1 cycle-length flag with a frequency of 2 Hz
|
||||
bool System500msTick(void);
|
||||
|
||||
// 1 cycle-length flag with a frequency of 10 Hz
|
||||
bool System100msTick(void);
|
||||
|
||||
// Returns random value between given minimum and maximum values
|
||||
uint32_t SystemRand(uint32_t min, uint32_t max);
|
||||
|
||||
// Increases global timer by 1 step
|
||||
void SystemIncreaseGlobalTimer(void);
|
||||
|
||||
// Sets value to emergency mode flag
|
||||
void SystemSetEmergencyMode(bool value);
|
||||
|
||||
// Returns emergency mode flag state
|
||||
bool SystemGetEmergencyMode(void);
|
||||
|
||||
// (Experimental)
|
||||
uint64_t SystemGetGlobalTimer(void);
|
||||
|
||||
// Returns whether critical section of code is being entered
|
||||
bool SystemIsBusy(void);
|
||||
volatile bool SystemIsBusy(void);
|
||||
|
||||
// Returns whether indicated value is contained inside buffer
|
||||
bool SystemContains_u8(uint8_t value, uint8_t * buffer, size_t sz);
|
||||
|
||||
// Overload for uint16_t
|
||||
bool SystemContains_u16(uint16_t value, uint16_t * buffer, size_t sz);
|
||||
|
||||
// Creates a timer instance wiht a determined value and associates it to a callback
|
||||
// Once time expires, callback is automatically called right after GfxDrawScene().
|
||||
TYPE_TIMER * SystemCreateTimer(uint32_t seconds, bool rf, void (*timer_callback)(void) );
|
||||
|
||||
// Reportedly, sets all timer data to zero.
|
||||
void SystemResetTimers(void);
|
||||
|
||||
// To be called every cycle (i.e.: inside GfxDrawScene() ).
|
||||
void SystemUserTimersHandler(void);
|
||||
|
||||
// Sets timer remaining time to initial value.
|
||||
void SystemTimerRestart(TYPE_TIMER * timer);
|
||||
|
||||
// Flushes a timer pointed to by timer.
|
||||
void SystemTimerRemove(TYPE_TIMER * timer);
|
||||
|
||||
// Compares two arrays of unsigned short type.
|
||||
bool SystemArrayCompare(unsigned short * arr1, unsigned short * arr2, size_t sz);
|
||||
|
||||
// Prints stack pointer address using dprintf()
|
||||
void SystemPrintStackPointerAddress(void);
|
||||
|
||||
// Checks if a 32-bit pattern set at the end of the stack has been
|
||||
// accidentally modified by program flow.
|
||||
void SystemCheckStack(void);
|
||||
|
||||
// Looks for string "str" inside a string array pointed to by "array".
|
||||
// Returns index inside string array on success, -1 if not found.
|
||||
int32_t SystemIndexOfStringArray(char * str, char ** array);
|
||||
|
||||
// Function overload for uint16_t data type.
|
||||
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);
|
||||
|
||||
void SystemCyclicHandler(void);
|
||||
|
||||
/* **************************************
|
||||
* Global Variables *
|
||||
* **************************************/
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
10:30
|
||||
#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;2
|
||||
DEPARTURE;PHX1000;100;00:05;19
|
||||
|
|
Loading…
Reference in New Issue