diff options
| author | XaviDCR92 <xavi.dcr@gmail.com> | 2017-05-01 23:05:51 +0200 |
|---|---|---|
| committer | XaviDCR92 <xavi.dcr@gmail.com> | 2017-05-01 23:05:51 +0200 |
| commit | 83b4684d7cb9934371909b522d6daa0f16cc0396 (patch) | |
| tree | 39fa1ca99061b12203dae50898a2b3dec3b5f276 /Source | |
| parent | 8629c228db1fe1f206d409356ad75995060a0ca8 (diff) | |
| download | airport-83b4684d7cb9934371909b522d6daa0f16cc0396.tar.gz | |
* 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.
Diffstat (limited to 'Source')
| -rw-r--r-- | Source/Aircraft.c | 51 | ||||
| -rw-r--r-- | Source/Aircraft.h | 5 | ||||
| -rw-r--r-- | Source/Game.c | 208 | ||||
| -rw-r--r-- | Source/Game.h | 1 | ||||
| -rw-r--r-- | Source/GameGui.c | 27 | ||||
| -rw-r--r-- | Source/GameStructures.h | 1 | ||||
| -rw-r--r-- | Source/Gfx.c | 71 | ||||
| -rw-r--r-- | Source/Gfx.h | 30 | ||||
| -rw-r--r-- | Source/Makefile | 2 | ||||
| -rw-r--r-- | Source/Menu.c | 26 | ||||
| -rw-r--r-- | Source/Pad.c | 10 | ||||
| -rw-r--r-- | Source/Pad.h | 3 | ||||
| -rw-r--r-- | Source/System.c | 145 | ||||
| -rw-r--r-- | Source/System.h | 40 |
14 files changed, 485 insertions, 135 deletions
diff --git a/Source/Aircraft.c b/Source/Aircraft.c index aed8793..5ddc4b8 100644 --- a/Source/Aircraft.c +++ b/Source/Aircraft.c @@ -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)
+{
+ TYPE_ISOMETRIC_POS isoPos = AircraftGetIsoPos(index);
+ return GameGetTileFromIsoPosition(&isoPos);
+}
+
+TYPE_AIRCRAFT_DATA* AircraftFromFlightDataIndex(uint8_t index)
{
- return &AircraftData[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)
diff --git a/Source/Aircraft.h b/Source/Aircraft.h index 2c64422..d941a13 100644 --- a/Source/Aircraft.h +++ b/Source/Aircraft.h @@ -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 );
diff --git a/Source/Game.c b/Source/Game.c index 88d2b75..bb7e6c3 100644 --- a/Source/Game.c +++ b/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); + + GameGuiAircraftNotificationRequest(&FlightData); - for(i = 0; i < MAX_PLAYERS ; i++) - { - GameGuiAircraftList(&PlayerData[i], &FlightData); + GameGuiBubble(&FlightData); + + GameGuiClock(GameHour,GameMinutes); + + /*for(i = 0; i < MAX_PLAYERS ; i++) + {*/ + GameGuiAircraftList(&PlayerData[i], &FlightData); + //} + + GfxDrawScene_Fast(); + while(GfxIsGPUBusy() == true); + } } - 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); - - 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; + 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; - 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? + } } } diff --git a/Source/Game.h b/Source/Game.h index 8bccf63..712c404 100644 --- a/Source/Game.h +++ b/Source/Game.h @@ -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__ diff --git a/Source/GameGui.c b/Source/GameGui.c index 47d6c37..dc13e6c 100644 --- a/Source/GameGui.c +++ b/Source/GameGui.c @@ -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;
}
diff --git a/Source/GameStructures.h b/Source/GameStructures.h index 4baa03a..3efe573 100644 --- a/Source/GameStructures.h +++ b/Source/GameStructures.h @@ -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;
diff --git a/Source/Gfx.c b/Source/Gfx.c index a976b00..329ba19 100644 --- a/Source/Gfx.c +++ b/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); +} diff --git a/Source/Gfx.h b/Source/Gfx.h index b9984ee..68c0f5b 100644 --- a/Source/Gfx.h +++ b/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); diff --git a/Source/Makefile b/Source/Makefile index 3e96e0b..96c3f7d 100644 --- a/Source/Makefile +++ b/Source/Makefile @@ -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) diff --git a/Source/Menu.c b/Source/Menu.c index 411c276..32d0e45 100644 --- a/Source/Menu.c +++ b/Source/Menu.c @@ -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) { diff --git a/Source/Pad.c b/Source/Pad.c index 7fc08a2..2a84304 100644 --- a/Source/Pad.c +++ b/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); diff --git a/Source/Pad.h b/Source/Pad.h index 3e0ff69..5e5588b 100644 --- a/Source/Pad.h +++ b/Source/Pad.h @@ -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); diff --git a/Source/System.c b/Source/System.c index b158004..833c80f 100644 --- a/Source/System.c +++ b/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); +} diff --git a/Source/System.h b/Source/System.h index cbb22ea..b6ed48b 100644 --- a/Source/System.h +++ b/Source/System.h @@ -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 * * **************************************/ |
