diff --git a/Source/Aircraft.c b/Source/Aircraft.c index fb2b516..3b3dab8 100644 --- a/Source/Aircraft.c +++ b/Source/Aircraft.c @@ -13,14 +13,14 @@ /* ************************************* * Structs and enums * *************************************/ - + enum { AIRCRAFT_SPRITE_SIZE = 24, AIRCRAFT_SPRITE_VRAM_X = 800, AIRCRAFT_SPRITE_VRAM_Y = 304, -}; - +}; + enum { PHX_LIVERY_CLUT_X = 384, @@ -33,7 +33,8 @@ typedef enum t_aircraftSpeeds AIRCRAFT_SPEED_TAXIING, AIRCRAFT_SPEED_APPROACH, AIRCRAFT_SPEED_TAKEOFF, - AIRCRAFT_SPEED_DESCENT, + AIRCRAFT_SPEED_FINAL, + AIRCRAFT_SPEED_FINAL_Z, }AIRCRAFT_SPEEDS; /* ************************************* @@ -47,12 +48,12 @@ static TYPE_ISOMETRIC_POS AircraftCenterIsoPos; static TYPE_CARTESIAN_POS AircraftCenterPos; static char * AircraftLiveryNamesTable[] = {"PHX", NULL}; static AIRCRAFT_LIVERY AircraftLiveryTable[] = {AIRCRAFT_LIVERY_0, AIRCRAFT_LIVERY_UNKNOWN}; -static const fix16_t AircraftSpeedsTable[] = { 0 /* IDLE */ , - 0x3333 /* TAXIING */ , - 0x00010000 /* APPROACH */ , - 0x20000 /* TAKEOFF */ , - 0x8000 /* DESCENT */ }; - +static const fix16_t AircraftSpeedsTable[] = { [AIRCRAFT_SPEED_IDLE] = 0, + [AIRCRAFT_SPEED_TAXIING] = 0x6666, + [AIRCRAFT_SPEED_TAKEOFF] = 0x20000, + [AIRCRAFT_SPEED_FINAL] = 0x10000, + [AIRCRAFT_SPEED_FINAL_Z] = 0x4000 }; + /* ************************************* * Local prototypes * *************************************/ @@ -67,61 +68,61 @@ void AircraftInit(void) { bzero(AircraftData, GAME_MAX_AIRCRAFT * sizeof(TYPE_AIRCRAFT_DATA)); AircraftIndex = 0; - + AircraftSpr.x = 0; AircraftSpr.y = 0; - + AircraftSpr.attribute = COLORMODE(COLORMODE_8BPP); - + AircraftSpr.cx = PHX_LIVERY_CLUT_X; AircraftSpr.cy = PHX_LIVERY_CLUT_Y; - + AircraftSpr.w = AIRCRAFT_SPRITE_SIZE; AircraftSpr.h = AIRCRAFT_SPRITE_SIZE; - + /*AircraftSpr.tpage = 28; AircraftSpr.u = 64; AircraftSpr.v = 48;*/ - + GfxTPageOffsetFromVRAMPosition(&AircraftSpr, AIRCRAFT_SPRITE_VRAM_X, AIRCRAFT_SPRITE_VRAM_Y); - + AircraftCenterIsoPos.x = AIRCRAFT_SIZE >> 1; AircraftCenterIsoPos.y = AIRCRAFT_SIZE >> 1; AircraftCenterIsoPos.z = 0; - + AircraftCenterPos = GfxIsometricToCartesian(&AircraftCenterIsoPos); } bool AircraftAddNew( TYPE_FLIGHT_DATA * ptrFlightData, uint8_t FlightDataIndex, - uint16_t * targets ) + uint16_t* targets ) { TYPE_AIRCRAFT_DATA* ptrAircraft = &AircraftData[AircraftIndex]; uint8_t level_columns = GameGetLevelColumns(); uint8_t i; - + if(AircraftIndex >= GAME_MAX_AIRCRAFT) { dprintf("Exceeded maximum aircraft capacity!\n"); return false; } - + memcpy(ptrAircraft->Target, targets, sizeof(uint16_t) * AIRCRAFT_MAX_TARGETS); - + ptrAircraft->TargetIdx = 0; ptrAircraft->Livery = AircraftLiveryFromFlightNumber(ptrFlightData->strFlightNumber[FlightDataIndex]); - + ptrAircraft->FlightDataIdx = FlightDataIndex; - + if(ptrFlightData->FlightDirection[FlightDataIndex] == ARRIVAL) { ptrAircraft->IsoPos.x = 0; - + ptrAircraft->IsoPos.y = targets[0] / level_columns; ptrAircraft->IsoPos.y <<= TILE_SIZE_BIT_SHIFT; ptrAircraft->IsoPos.y += TILE_SIZE >> 1; // Adjust to tile center ptrAircraft->IsoPos.y = fix16_from_int(ptrAircraft->IsoPos.y); - + ptrAircraft->IsoPos.z = targets[0] % level_columns; ptrAircraft->IsoPos.z <<= TILE_SIZE_BIT_SHIFT - 1; ptrAircraft->IsoPos.z = fix16_from_int(ptrAircraft->IsoPos.z); @@ -132,31 +133,33 @@ bool AircraftAddNew( TYPE_FLIGHT_DATA * ptrFlightData, ptrAircraft->IsoPos.y = GameGetYFromTile(ptrFlightData->Parking[FlightDataIndex]); ptrAircraft->IsoPos.z = 0; } - + ptrAircraft->State = ptrFlightData->State[FlightDataIndex]; - + + ptrAircraft->Direction = AIRCRAFT_DIR_NORTH; // Default to north direction + dprintf("\nAircraft Data:\n"); dprintf("\tTargets:"); - + for(i = 0; i < AIRCRAFT_MAX_TARGETS; i++) { if(ptrAircraft->Target[i] == 0) { break; } - + dprintf(" %d", ptrAircraft->Target[i]); } - + dprintf("\nLivery: %d\n", ptrAircraft->Livery ); - + dprintf("Aircraft position: {%d, %d, %d}\n", fix16_to_int(ptrAircraft->IsoPos.x), fix16_to_int(ptrAircraft->IsoPos.y), fix16_to_int(ptrAircraft->IsoPos.z) ); - + AircraftIndex++; - + return true; } @@ -164,18 +167,18 @@ AIRCRAFT_LIVERY AircraftLiveryFromFlightNumber(char * strFlightNumber) { int32_t liveryIndex; char strLivery[4]; - + memset(strLivery, 0, 4 * sizeof(char) ); - + strncpy(strLivery, strFlightNumber, 3); - + liveryIndex = SystemIndexOfStringArray(strLivery, AircraftLiveryNamesTable); - + if(liveryIndex == -1) { return AIRCRAFT_LIVERY_UNKNOWN; } - + return AircraftLiveryTable[liveryIndex]; } @@ -183,19 +186,21 @@ void AircraftHandler(void) { TYPE_AIRCRAFT_DATA* ptrAircraft; uint8_t i; - + for(i = 0; i < GAME_MAX_AIRCRAFT; i++) { ptrAircraft = &AircraftData[i]; - + if(ptrAircraft->State == STATE_IDLE) { continue; } - + AircraftDirection(ptrAircraft); AircraftAttitude(ptrAircraft); AircraftSpeed(ptrAircraft); + + ptrAircraft->State = GameGetFlightDataStateFromIdx(ptrAircraft->FlightDataIdx); } } @@ -204,20 +209,23 @@ void AircraftSpeed(TYPE_AIRCRAFT_DATA* ptrAircraft) switch(ptrAircraft->State) { case STATE_FINAL: - ptrAircraft->Speed = AircraftSpeedsTable[AIRCRAFT_SPEED_DESCENT]; + ptrAircraft->Speed = AircraftSpeedsTable[AIRCRAFT_SPEED_FINAL]; break; - + case STATE_TAKEOFF: ptrAircraft->Speed = AircraftSpeedsTable[AIRCRAFT_SPEED_TAKEOFF]; break; - + case STATE_TAXIING: ptrAircraft->Speed = AircraftSpeedsTable[AIRCRAFT_SPEED_TAXIING]; break; - + case STATE_UNBOARDING: + // Fall through case STATE_IDLE: + // Fall through case STATE_LANDED: + // Fall through default: ptrAircraft->Speed = 0; break; @@ -228,32 +236,32 @@ void AircraftRender(TYPE_PLAYER* ptrPlayer) { TYPE_AIRCRAFT_DATA* ptrAircraft; TYPE_CARTESIAN_POS cartPos; - + uint8_t i; - + for(i = 0; i < GAME_MAX_AIRCRAFT; i++) { ptrAircraft = &AircraftData[i]; - + if(ptrAircraft->State == STATE_IDLE) { continue; } - + cartPos = GfxIsometricFix16ToCartesian(&ptrAircraft->IsoPos); - + // Aircraft position is referred to aircraft center AircraftSpr.x = cartPos.x - (AircraftSpr.w >> 1); AircraftSpr.y = cartPos.y - (AircraftSpr.h >> 1); - + AircraftUpdateSpriteFromData(ptrAircraft); - + CameraApplyCoordinatesToSprite(ptrPlayer, &AircraftSpr); - + AircraftSpr.r = NORMAL_LUMINANCE; AircraftSpr.g = NORMAL_LUMINANCE; AircraftSpr.b = NORMAL_LUMINANCE; - + GfxSortSprite(&AircraftSpr); } } @@ -261,62 +269,90 @@ void AircraftRender(TYPE_PLAYER* ptrPlayer) void AircraftDirection(TYPE_AIRCRAFT_DATA* ptrAircraft) { TYPE_ISOMETRIC_FIX16_POS targetPos; - + if(ptrAircraft->Target[ptrAircraft->TargetIdx] == 0) { return; } - + targetPos.x = GameGetXFromTile(ptrAircraft->Target[ptrAircraft->TargetIdx]); targetPos.y = GameGetYFromTile(ptrAircraft->Target[ptrAircraft->TargetIdx]); targetPos.z = 0; - + ptrAircraft->TargetReached = false; - + if(targetPos.y == ptrAircraft->IsoPos.y) { if(targetPos.x > ptrAircraft->IsoPos.x) { - ptrAircraft->Direction = AIRCRAFT_DIR_EAST; - ptrAircraft->IsoPos.x += ptrAircraft->Speed; + if(targetPos.x <= (ptrAircraft->IsoPos.x + ptrAircraft->Speed) ) + { + ptrAircraft->TargetReached = true; + } + else + { + ptrAircraft->Direction = AIRCRAFT_DIR_EAST; + ptrAircraft->IsoPos.x += ptrAircraft->Speed; + } } else if(targetPos.x < ptrAircraft->IsoPos.x) { - ptrAircraft->Direction = AIRCRAFT_DIR_WEST; - ptrAircraft->IsoPos.x -= ptrAircraft->Speed; + if(targetPos.x >= (ptrAircraft->IsoPos.x - ptrAircraft->Speed) ) + { + ptrAircraft->TargetReached = true; + } + else + { + ptrAircraft->Direction = AIRCRAFT_DIR_WEST; + ptrAircraft->IsoPos.x -= ptrAircraft->Speed; + } } else { ptrAircraft->TargetReached = true; - - if(ptrAircraft->Target[++ptrAircraft->TargetIdx] == 0) - { - dprintf("All targets reached!\n"); - GameTargetsReached(ptrAircraft->FlightDataIdx); - } } } else if(targetPos.x == ptrAircraft->IsoPos.x) { if(targetPos.y > ptrAircraft->IsoPos.y) { - ptrAircraft->Direction = AIRCRAFT_DIR_SOUTH; - ptrAircraft->IsoPos.y += ptrAircraft->Speed; + if(targetPos.y <= (ptrAircraft->IsoPos.y + ptrAircraft->Speed) ) + { + ptrAircraft->TargetReached = true; + } + else + { + ptrAircraft->Direction = AIRCRAFT_DIR_SOUTH; + ptrAircraft->IsoPos.y += ptrAircraft->Speed; + } } else if(targetPos.y < ptrAircraft->IsoPos.y) { - ptrAircraft->Direction = AIRCRAFT_DIR_NORTH; - ptrAircraft->IsoPos.y -= ptrAircraft->Speed; + if(targetPos.y >= (ptrAircraft->IsoPos.y - ptrAircraft->Speed) ) + { + ptrAircraft->TargetReached = true; + } + else + { + ptrAircraft->Direction = AIRCRAFT_DIR_NORTH; + ptrAircraft->IsoPos.y -= ptrAircraft->Speed; + } } else { ptrAircraft->TargetReached = true; - - if(ptrAircraft->Target[++ptrAircraft->TargetIdx] == 0) - { - dprintf("All targets reached!\n"); - ptrAircraft->State = GameTargetsReached(ptrAircraft->FlightDataIdx); - } + } + } + + if(ptrAircraft->TargetReached == true) + { + ptrAircraft->IsoPos.x = targetPos.x; + ptrAircraft->IsoPos.y = targetPos.y; + + if(ptrAircraft->Target[++ptrAircraft->TargetIdx] == 0) + { + dprintf("All targets reached!\n"); + ptrAircraft->State = GameTargetsReached(ptrAircraft->FlightDataIdx); } } } @@ -329,35 +365,43 @@ void AircraftUpdateSpriteFromData(TYPE_AIRCRAFT_DATA* ptrAircraft) AircraftSpr.cx = PHX_LIVERY_CLUT_X; AircraftSpr.cy = PHX_LIVERY_CLUT_Y; break; - + case AIRCRAFT_LIVERY_UNKNOWN: // Fall through default: dprintf("Unknown livery %d!\n", ptrAircraft->Livery); break; } - + // Reset TPAGE and {U, V} offset first. GfxTPageOffsetFromVRAMPosition(&AircraftSpr, AIRCRAFT_SPRITE_VRAM_X, AIRCRAFT_SPRITE_VRAM_Y); - + switch(ptrAircraft->Direction) { case AIRCRAFT_DIR_NORTH: AircraftSpr.v += AircraftSpr.w; AircraftSpr.attribute |= H_FLIP; break; + case AIRCRAFT_DIR_SOUTH: AircraftSpr.v += 0; AircraftSpr.attribute |= H_FLIP; break; + case AIRCRAFT_DIR_EAST: AircraftSpr.v += 0; AircraftSpr.attribute &= ~(H_FLIP); break; + case AIRCRAFT_DIR_WEST: AircraftSpr.v += AircraftSpr.w; AircraftSpr.attribute &= ~(H_FLIP); break; + + case AIRCRAFT_DIR_NO_DIRECTION: + // Fall through + default: + break; } } @@ -367,7 +411,7 @@ void AircraftAttitude(TYPE_AIRCRAFT_DATA* ptrAircraft) { if(ptrAircraft->IsoPos.z > 0) { - ptrAircraft->IsoPos.z -= AircraftSpeedsTable[AIRCRAFT_SPEED_DESCENT]; + ptrAircraft->IsoPos.z -= AircraftSpeedsTable[AIRCRAFT_SPEED_FINAL_Z]; } } } @@ -378,16 +422,16 @@ TYPE_ISOMETRIC_POS AircraftGetIsoPos(uint8_t FlightDataIdx) // So we must perform a conversion first for convenience. TYPE_ISOMETRIC_POS retIsoPos; TYPE_ISOMETRIC_FIX16_POS fix16IsoPos = AircraftFromFlightDataIndex(FlightDataIdx)->IsoPos; - + retIsoPos.x = (short)fix16_to_int(fix16IsoPos.x); retIsoPos.y = (short)fix16_to_int(fix16IsoPos.y); retIsoPos.z = (short)fix16_to_int(fix16IsoPos.z); - + 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); } @@ -401,21 +445,21 @@ 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) +void AircraftFromFlightDataIndexAddTargets(uint8_t index, uint16_t* targets) { AircraftAddTargets(AircraftFromFlightDataIndex(index), targets); } diff --git a/Source/Aircraft.h b/Source/Aircraft.h index e32a64a..5f80960 100644 --- a/Source/Aircraft.h +++ b/Source/Aircraft.h @@ -18,12 +18,12 @@ void AircraftInit(void); void AircraftHandler(void); void AircraftRender(TYPE_PLAYER* ptrPlayer); 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 AircraftFromFlightDataIndexAddTargets(uint8_t index, 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 ); + uint16_t* targets ); #endif //__AIRCRAFT_HEADER__ diff --git a/Source/Camera.c b/Source/Camera.c index f0f637f..db01dec 100644 --- a/Source/Camera.c +++ b/Source/Camera.c @@ -12,6 +12,7 @@ #define MAX_CAMERA_SPEED 5 #define MIN_CAMERA_SPEED 1 #define CAMERA_INITIAL_X_OFFSET (X_SCREEN_RESOLUTION >> 1) +#define CAMERA_INITIAL_X_OFFSET_2PLAYER (X_SCREEN_RESOLUTION >> 2) /* ************************************* * Local Prototypes @@ -41,7 +42,7 @@ void CameraApplyCoordinatesToRectangle(TYPE_PLAYER* ptrPlayer, GsRectangle * rec dprintf("Rectangle {%d, %d}\n", rect->x, rect->y ); - + rect->x += (short)ptrPlayer->Camera.X_Offset; rect->y += (short)ptrPlayer->Camera.Y_Offset; } @@ -61,7 +62,7 @@ void CameraUpdateSpeed(TYPE_PLAYER* ptrPlayer) ptrPlayer->Camera.X_Speed++; } } - + if(ptrPlayer->PadKeyPressed_Callback(PAD_UP) == true) { if(ptrPlayer->Camera.Y_Speed < 0) @@ -73,7 +74,7 @@ void CameraUpdateSpeed(TYPE_PLAYER* ptrPlayer) ptrPlayer->Camera.Y_Speed++; } } - + if(ptrPlayer->PadKeyPressed_Callback(PAD_DOWN) == true) { if(ptrPlayer->Camera.Y_Speed > 0) @@ -85,7 +86,7 @@ void CameraUpdateSpeed(TYPE_PLAYER* ptrPlayer) ptrPlayer->Camera.Y_Speed--; } } - + if(ptrPlayer->PadKeyPressed_Callback(PAD_RIGHT) == true) { if(ptrPlayer->Camera.X_Speed > 0) @@ -112,11 +113,11 @@ void CameraUpdateSpeed(TYPE_PLAYER* ptrPlayer) ptrPlayer->Camera.X_Speed++; } } - + if( (ptrPlayer->PadKeyPressed_Callback(PAD_UP) == false) && (ptrPlayer->PadKeyPressed_Callback(PAD_DOWN) == false) ) - { + { if(ptrPlayer->Camera.Y_Speed > 0) { ptrPlayer->Camera.Y_Speed--; @@ -136,7 +137,7 @@ void CameraHandler(TYPE_PLAYER* ptrPlayer) ptrPlayer->Camera.Y_Speed = 0; return; } - + if(ptrPlayer->Camera.Speed_Timer < SPEED_CALCULATION_TIME) { ptrPlayer->Camera.Speed_Timer++; @@ -146,7 +147,7 @@ void CameraHandler(TYPE_PLAYER* ptrPlayer) ptrPlayer->Camera.Speed_Timer = 0; CameraUpdateSpeed(ptrPlayer); } - + ptrPlayer->Camera.X_Offset += ptrPlayer->Camera.X_Speed; ptrPlayer->Camera.Y_Offset += ptrPlayer->Camera.Y_Speed; } @@ -158,10 +159,10 @@ bool CameraSpecialConditions(TYPE_PLAYER* ptrPlayer) (ptrPlayer->SelectRunway == true) ) { // Camera cannot be handled when these states are activated - + return true; } - + return false; } @@ -169,21 +170,29 @@ TYPE_ISOMETRIC_POS CameraGetIsoPos(TYPE_PLAYER* ptrPlayer) { TYPE_ISOMETRIC_POS IsoPos; TYPE_CARTESIAN_POS CartPos; - - CartPos.x = CAMERA_INITIAL_X_OFFSET - ptrPlayer->Camera.X_Offset; - CartPos.y = (Y_SCREEN_RESOLUTION >> 1) - ptrPlayer->Camera.Y_Offset; - + + if(GameTwoPlayersActive() == true) + { + CartPos.x = CAMERA_INITIAL_X_OFFSET_2PLAYER - ptrPlayer->Camera.X_Offset; + CartPos.y = (Y_SCREEN_RESOLUTION >> 1) - ptrPlayer->Camera.Y_Offset; + } + else + { + CartPos.x = CAMERA_INITIAL_X_OFFSET - ptrPlayer->Camera.X_Offset; + CartPos.y = (Y_SCREEN_RESOLUTION >> 1) - ptrPlayer->Camera.Y_Offset; + } + /*dprintf("CartPos = {%d, %d}\n", CartPos.x, CartPos.y);*/ - + IsoPos = GfxCartesianToIsometric(&CartPos); - + return IsoPos; } void CameraMoveToIsoPos(TYPE_PLAYER* ptrPlayer, TYPE_ISOMETRIC_POS IsoPos) { TYPE_CARTESIAN_POS CartPos = GfxIsometricToCartesian(&IsoPos); - + /*dprintf("Isometric pos = {%d, %d, %d}, " "Cartesian pos = {%d, %d}\n", IsoPos.x, @@ -191,10 +200,18 @@ void CameraMoveToIsoPos(TYPE_PLAYER* ptrPlayer, TYPE_ISOMETRIC_POS IsoPos) IsoPos.z, CartPos.x, CartPos.y );*/ - - ptrPlayer->Camera.X_Offset = CAMERA_INITIAL_X_OFFSET - CartPos.x; - ptrPlayer->Camera.Y_Offset = (Y_SCREEN_RESOLUTION >> 1) - CartPos.y; - + + if(GameTwoPlayersActive() == true) + { + ptrPlayer->Camera.X_Offset = CAMERA_INITIAL_X_OFFSET_2PLAYER - CartPos.x; + ptrPlayer->Camera.Y_Offset = (Y_SCREEN_RESOLUTION >> 1) - CartPos.y; + } + else + { + ptrPlayer->Camera.X_Offset = CAMERA_INITIAL_X_OFFSET - CartPos.x; + ptrPlayer->Camera.Y_Offset = (Y_SCREEN_RESOLUTION >> 1) - CartPos.y; + } + /*dprintf("Moving camera to {%d, %d}\n", ptrPlayer->Camera.X_Offset, ptrPlayer->Camera.Y_Offset );*/ diff --git a/Source/Camera.h b/Source/Camera.h index 887113d..3b622d4 100644 --- a/Source/Camera.h +++ b/Source/Camera.h @@ -9,6 +9,7 @@ #include "System.h" #include "Pad.h" #include "GameStructures.h" +#include "Game.h" /* ************************************* * Defines @@ -23,6 +24,6 @@ void CameraHandler(TYPE_PLAYER* ptrPlayer); void CameraApplyCoordinatesToSprite(TYPE_PLAYER* ptrPlayer, GsSprite * spr); void CameraApplyCoordinatesToRectangle(TYPE_PLAYER* ptrPlayer, GsRectangle * rect); TYPE_ISOMETRIC_POS CameraGetIsoPos(TYPE_PLAYER* ptrPlayer); -void CameraMoveToIsoPos(TYPE_PLAYER* ptrPlayer, TYPE_ISOMETRIC_POS ptrIsoPos); +void CameraMoveToIsoPos(TYPE_PLAYER* ptrPlayer, TYPE_ISOMETRIC_POS IsoPos); #endif //__CAM_HEADER__ diff --git a/Source/Game.c b/Source/Game.c index bdb49f1..1aa3fdc 100644 --- a/Source/Game.c +++ b/Source/Game.c @@ -107,13 +107,13 @@ static void GameSelectAircraftFromList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA static void GameStateSelectRunway(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData); 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); +static void GameStateLockTarget(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData); static void GameSelectAircraft(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 GameGuiShowAircraftDataSpecialConditions(TYPE_PLAYER* ptrPlayer); static bool GamePathToTile(TYPE_PLAYER* ptrPlayer); +static void GameDrawMouse(TYPE_PLAYER* ptrPlayer); /* ************************************* * Global Variables @@ -267,7 +267,6 @@ void GameInit(void) PlayerData[PLAYER_ONE].PadKeySinglePress_Callback = &PadOneKeySinglePress; PlayerData[PLAYER_ONE].PadDirectionKeyPressed_Callback = &PadOneDirectionKeyPressed; PlayerData[PLAYER_ONE].FlightDataPage = 0; - PlayerData[PLAYER_ONE].Id = PLAYER_ONE; PlayerData[PLAYER_TWO].Active = TwoPlayersActive? true : false; @@ -283,7 +282,6 @@ void GameInit(void) // other player controls arrival flights. PlayerData[PLAYER_ONE].FlightDirection = DEPARTURE; PlayerData[PLAYER_TWO].FlightDirection = ARRIVAL; - PlayerData[PLAYER_TWO].Id = PLAYER_TWO; } else { @@ -309,13 +307,13 @@ void GameInit(void) if(GameTwoPlayersActive() == true) { - GameMouseSpr.x = MOUSE_X; - GameMouseSpr.y = MOUSE_Y; + GameMouseSpr.x = MOUSE_X_2PLAYER; + GameMouseSpr.y = MOUSE_Y_2PLAYER; } else { - GameMouseSpr.x = MOUSE_X_2PLAYER; - GameMouseSpr.y = MOUSE_Y_2PLAYER; + GameMouseSpr.x = MOUSE_X; + GameMouseSpr.y = MOUSE_Y; } GameMouseSpr.w = MOUSE_W; @@ -506,7 +504,7 @@ void GamePlayerHandler(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData) // which use this are currently active. ptrPlayer->InvalidPath = false; // Do the same thing for "InvalidPath". - GameStateLockTarget(ptrPlayer); + GameStateLockTarget(ptrPlayer, ptrFlightData); GameStateSelectRunway(ptrPlayer, ptrFlightData); GameStateSelectTaxiwayRunway(ptrPlayer, ptrFlightData); GameStateSelectTaxiwayParking(ptrPlayer, ptrFlightData); @@ -576,6 +574,7 @@ void GameGraphics(void) if(GfxGetGlobalLuminance() < NORMAL_LUMINANCE) { + // Fading from black effect on startup. GfxIncreaseGlobalLuminance(1); } @@ -588,16 +587,30 @@ void GameGraphics(void) GfxSetSplitScreen(i); } + // Draw half split screen for each player + // only if 2-player mode is active. Else, render + // the whole screen as usual. + GsSortCls(0,0,GfxGetGlobalLuminance() >> 1); GameRenderLevel(&PlayerData[i]); + AircraftRender(&PlayerData[i]); GameGuiAircraftList(&PlayerData[i], &FlightData); + + GameDrawMouse(&PlayerData[i]); } } - GfxDisableSplitScreen(); + // Avoid changing drawing environment twice on 1-player mode + // as it doesn't make any sense. + if(split_screen == true) + { + GfxDisableSplitScreen(); + } + + // Draw common elements for both players (messages, clock...) GameGuiAircraftNotificationRequest(&FlightData); @@ -611,7 +624,7 @@ void GameGraphics(void) void GameLoadLevel(void) { uint8_t i = 0; - uint8_t * ptrBuffer; + uint8_t* ptrBuffer; char LevelHeader[LEVEL_MAGIC_NUMBER_SIZE + 1]; /* TODO - Very important */ @@ -945,13 +958,6 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer) } } - if( (ptrPlayer->SelectTaxiwayParking == true) - || - (ptrPlayer->SelectTaxiwayRunway == true) ) - { - GfxSortSprite(&GameMouseSpr); - } - /*if(PadOneKeyReleased(PAD_CROSS) == true) { for(i = 0; i < GameLevelSize; i++) @@ -990,18 +996,6 @@ void GameStateShowAircraft(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightD { ptrPlayer->ShowAircraftData = false; } - else if(ptrPlayer->PadKeySinglePress_Callback(PAD_SQUARE) == true) - { - dprintf("Aircraft state = %d. STATE_IDLE = %d\n", - ptrFlightData->State[ptrPlayer->SelectedAircraft], - STATE_IDLE); - - if(ptrFlightData->State[ptrPlayer->SelectedAircraft] != STATE_IDLE) - { - ptrPlayer->LockTarget = true; - ptrPlayer->LockedAircraft = ptrPlayer->SelectedAircraft; - } - } } if(ptrPlayer->PadKeySinglePress_Callback(PAD_CIRCLE) == true) @@ -1014,13 +1008,38 @@ void GameStateShowAircraft(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightD } } -void GameStateLockTarget(TYPE_PLAYER* ptrPlayer) +void GameStateLockTarget(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData) { + uint8_t AircraftIdx = ptrPlayer->ActiveAircraftList[ptrPlayer->SelectedAircraft]; + if(ptrPlayer->LockTarget == true) { CameraMoveToIsoPos(ptrPlayer, AircraftGetIsoPos(ptrPlayer->LockedAircraft) ); - - if(ptrPlayer->PadKeySinglePress_Callback(PAD_SQUARE) == true) + } + + if(ptrPlayer->PadKeySinglePress_Callback(PAD_SQUARE) == true) + { + if(ptrPlayer->LockTarget == false) + { + if( (ptrFlightData->State[AircraftIdx] != STATE_IDLE) + && + (ptrFlightData->State[AircraftIdx] != STATE_APPROACH) ) + { + ptrPlayer->LockTarget = true; + ptrPlayer->LockedAircraft = AircraftIdx; + } + } + else + { + ptrPlayer->LockTarget = false; + ptrPlayer->LockedAircraft = 0; + } + } + else if(ptrPlayer->PadDirectionKeyPressed_Callback() == true) + { + if( (ptrPlayer->LockTarget == true) + && + (ptrPlayer->ShowAircraftData == false) ) { ptrPlayer->LockTarget = false; ptrPlayer->LockedAircraft = 0; @@ -1194,13 +1213,18 @@ void GameStateSelectRunway(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightD { uint8_t i; bool success; + TYPE_ISOMETRIC_POS IsoPos = { GameGetXFromTile_short(GameRwy[ptrPlayer->SelectedRunway]), + GameGetYFromTile_short(GameRwy[ptrPlayer->SelectedRunway]), + 0 }; if(ptrPlayer->SelectRunway == true) - { + { // Under this mode, always reset locking target. ptrPlayer->LockTarget = false; ptrPlayer->LockedAircraft = 0; + CameraMoveToIsoPos(ptrPlayer, IsoPos); + if(ptrPlayer->PadKeySinglePress_Callback(PAD_TRIANGLE) == true) { ptrPlayer->SelectRunway = false; @@ -1243,7 +1267,7 @@ void GameStateSelectRunway(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightD } else if(ptrPlayer->PadKeySinglePress_Callback(PAD_RIGHT) == true) { - if(ptrPlayer->SelectedRunway < GAME_MAX_RUNWAYS) + if(ptrPlayer->SelectedRunway < (GAME_MAX_RUNWAYS - 1)) { if(GameRwy[ptrPlayer->SelectedRunway + 1] != 0) { @@ -1287,7 +1311,8 @@ void GameGetRunwayArray(void) void GameSelectAircraftFromList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData) { - FL_STATE aircraftState = ptrFlightData->State[ptrPlayer->SelectedAircraft]; + uint8_t AircraftIdx = ptrPlayer->ActiveAircraftList[ptrPlayer->SelectedAircraft]; + FL_STATE aircraftState = ptrFlightData->State[AircraftIdx]; if(ptrPlayer->ShowAircraftData == true) { @@ -1323,6 +1348,9 @@ void GameSelectAircraftFromList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFl break; } } + + dprintf("aircraftState = %d\n", aircraftState); + dprintf("AircraftIdx = %d\n", AircraftIdx); } } } @@ -1470,9 +1498,9 @@ void GameAssignRunwaytoAircraft(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFl } } -fix16_t GameGetXFromTile(uint16_t tile) +short GameGetXFromTile_short(uint16_t tile) { - fix16_t retVal; + short retVal; tile %= GameLevelColumns; @@ -1481,14 +1509,12 @@ fix16_t GameGetXFromTile(uint16_t tile) // Always point to tile center retVal += TILE_SIZE >> 1; - retVal = fix16_from_int(retVal); - return retVal; } -fix16_t GameGetYFromTile(uint16_t tile) +short GameGetYFromTile_short(uint16_t tile) { - fix16_t retVal; + short retVal; tile /= GameLevelColumns; @@ -1497,11 +1523,19 @@ fix16_t GameGetYFromTile(uint16_t tile) // Always point to tile center retVal += TILE_SIZE >> 1; - retVal = fix16_from_int(retVal); - return retVal; } +fix16_t GameGetXFromTile(uint16_t tile) +{ + return fix16_from_int(GameGetXFromTile_short(tile)); +} + +fix16_t GameGetYFromTile(uint16_t tile) +{ + return fix16_from_int(GameGetYFromTile_short(tile)); +} + FL_STATE GameTargetsReached(uint8_t index) { FL_STATE retState = STATE_IDLE; @@ -1523,22 +1557,6 @@ FL_STATE GameTargetsReached(uint8_t index) return retState; } -bool GameGuiShowAircraftDataSpecialConditions(TYPE_PLAYER* ptrPlayer) -{ - // Aircraft list data cannot be shown under these conditions. - - if( (ptrPlayer->SelectRunway == true) - || - (ptrPlayer->SelectTaxiwayParking == true) - || - (ptrPlayer->SelectTaxiwayRunway == true) ) - { - return true; - } - - return false; -} - uint16_t GameGetTileFromIsoPosition(TYPE_ISOMETRIC_POS * IsoPos) { uint16_t tile; @@ -1824,7 +1842,8 @@ bool GamePathToTile(TYPE_PLAYER* ptrPlayer) void GameSelectAircraft(TYPE_PLAYER* ptrPlayer) { - TYPE_ISOMETRIC_POS IsoPos = AircraftGetIsoPos(ptrPlayer->SelectedAircraft); + uint8_t AircraftIdx = ptrPlayer->ActiveAircraftList[ptrPlayer->SelectedAircraft]; + TYPE_ISOMETRIC_POS IsoPos = AircraftGetIsoPos(AircraftIdx); CameraMoveToIsoPos(ptrPlayer, IsoPos); @@ -1837,3 +1856,23 @@ bool GameTwoPlayersActive(void) { return TwoPlayersActive; } + +void GameDrawMouse(TYPE_PLAYER* ptrPlayer) +{ + if( (ptrPlayer->SelectTaxiwayParking == true) + || + (ptrPlayer->SelectTaxiwayRunway == true) ) + { + GfxSortSprite(&GameMouseSpr); + } +} + +FL_STATE GameGetFlightDataStateFromIdx(uint8_t FlightDataIdx) +{ + if(FlightDataIdx >= GAME_MAX_AIRCRAFT) + { + return STATE_IDLE; // Error: could cause buffer overrun + } + + return FlightData.State[FlightDataIdx]; +} diff --git a/Source/Game.h b/Source/Game.h index 6e74aee..fb8c12c 100644 --- a/Source/Game.h +++ b/Source/Game.h @@ -44,7 +44,10 @@ uint8_t GameGetLastActiveAircraft(void); uint8_t GameGetLevelColumns(void); fix16_t GameGetXFromTile(uint16_t tile); fix16_t GameGetYFromTile(uint16_t tile); +short GameGetXFromTile_short(uint16_t tile); +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); #endif //__GAME_HEADER__ diff --git a/Source/GameGui.c b/Source/GameGui.c index d3855f9..94d3dce 100644 --- a/Source/GameGui.c +++ b/Source/GameGui.c @@ -123,6 +123,14 @@ enum AIRCRAFT_DATA_GSGPOLY4_Y3_2PLAYER = AIRCRAFT_DATA_GSGPOLY4_Y2_2PLAYER, }; +enum +{ + AIRCRAFT_LOCK_TARGET_X = 32, + AIRCRAFT_LOCK_TARGET_TEXT_X = AIRCRAFT_LOCK_TARGET_X + 16, + AIRCRAFT_LOCK_TARGET_Y = 224, + AIRCRAFT_LOCK_TARGET_TEXT_Y = AIRCRAFT_LOCK_TARGET_Y + 4, +}; + enum { AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R0 = NORMAL_LUMINANCE, @@ -388,19 +396,22 @@ void GameGuiActiveAircraftList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFli uint8_t i; uint8_t j = 0; - // Clear all pointers for aircraft data first. - // Then, rebuild aircraft list for player. - memset(ptrPlayer->ActiveAircraftList, 0, GAME_MAX_AIRCRAFT); - ptrPlayer->ActiveAircraft = 0; - - for(i = 0; i < GAME_MAX_AIRCRAFT; i++) + if(ptrPlayer->ShowAircraftData == true) { - if( (ptrFlightData->State[i] != STATE_IDLE) - && - (ptrFlightData->FlightDirection[i] & ptrPlayer->FlightDirection) ) + // Clear all pointers for aircraft data first. + // Then, rebuild aircraft list for player. + memset(ptrPlayer->ActiveAircraftList, 0, GAME_MAX_AIRCRAFT); + ptrPlayer->ActiveAircraft = 0; + + for(i = 0; i < GAME_MAX_AIRCRAFT; i++) { - ptrPlayer->ActiveAircraftList[j++] = i; - ptrPlayer->ActiveAircraft++; + if( (ptrFlightData->State[i] != STATE_IDLE) + && + (ptrFlightData->FlightDirection[i] & ptrPlayer->FlightDirection) ) + { + ptrPlayer->ActiveAircraftList[j++] = i; + ptrPlayer->ActiveAircraft++; + } } } } @@ -496,14 +507,6 @@ void GameGuiAircraftList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightDat AircraftDataGPoly4.y[1] = AIRCRAFT_DATA_GSGPOLY4_Y1_2PLAYER; AircraftDataGPoly4.y[2] = AIRCRAFT_DATA_GSGPOLY4_Y2_2PLAYER; AircraftDataGPoly4.y[3] = AIRCRAFT_DATA_GSGPOLY4_Y3_2PLAYER; - - if(ptrPlayer->Id == PLAYER_TWO) - { - AircraftDataGPoly4.x[0] += X_SCREEN_RESOLUTION >> 1; - AircraftDataGPoly4.x[1] += X_SCREEN_RESOLUTION >> 1; - AircraftDataGPoly4.x[2] += X_SCREEN_RESOLUTION >> 1; - AircraftDataGPoly4.x[3] += X_SCREEN_RESOLUTION >> 1; - } } else { @@ -520,105 +523,127 @@ void GameGuiAircraftList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightDat GsSortGPoly4(&AircraftDataGPoly4); - if(ptrPlayer->ActiveAircraft != 0) + if(ptrPlayer->ActiveAircraft != 0) + { + SelectedAircraftGPoly4.r[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R0; + SelectedAircraftGPoly4.r[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R1; + SelectedAircraftGPoly4.r[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R2; + SelectedAircraftGPoly4.r[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R3; + + SelectedAircraftGPoly4.g[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G0; + SelectedAircraftGPoly4.g[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G1; + SelectedAircraftGPoly4.g[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G2; + SelectedAircraftGPoly4.g[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G3; + + SelectedAircraftGPoly4.b[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B0; + SelectedAircraftGPoly4.b[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B1; + SelectedAircraftGPoly4.b[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B2; + SelectedAircraftGPoly4.b[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B3; + + SelectedAircraftGPoly4.attribute |= ENABLE_TRANS | TRANS_MODE(0); + + if(GameTwoPlayersActive() == true) { - SelectedAircraftGPoly4.r[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R0; - SelectedAircraftGPoly4.r[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R1; - SelectedAircraftGPoly4.r[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R2; - SelectedAircraftGPoly4.r[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_R3; + SelectedAircraftGPoly4.x[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0_2PLAYER; + SelectedAircraftGPoly4.x[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1_2PLAYER; + SelectedAircraftGPoly4.x[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X2_2PLAYER; + SelectedAircraftGPoly4.x[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X3_2PLAYER; + } + else + { + SelectedAircraftGPoly4.x[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0; + SelectedAircraftGPoly4.x[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1; + SelectedAircraftGPoly4.x[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X2; + SelectedAircraftGPoly4.x[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X3; + } + + page_aircraft = (ptrPlayer->SelectedAircraft) - (ptrPlayer->FlightDataPage * GAME_GUI_AIRCRAFT_DATA_MAX_PAGE); + + y_offset = (short)(page_aircraft * AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H); + + /*dprintf("ptrPlayer->ActiveAircraft = %d\n",ptrPlayer->ActiveAircraft); + dprintf("ptrPlayer->SelectedAircraft = %d\n",ptrPlayer->SelectedAircraft); + dprintf("ptrPlayer->FlightDataPage = %d\n",ptrPlayer->FlightDataPage); + dprintf("y_offset = %d\n",y_offset);*/ + + if(GameTwoPlayersActive() == true) + { + SelectedAircraftGPoly4.y[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0_2PLAYER; + SelectedAircraftGPoly4.y[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y1_2PLAYER; + SelectedAircraftGPoly4.y[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2_2PLAYER; + SelectedAircraftGPoly4.y[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y3_2PLAYER; + } + else + { + SelectedAircraftGPoly4.y[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0; + SelectedAircraftGPoly4.y[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y1; + SelectedAircraftGPoly4.y[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2; + SelectedAircraftGPoly4.y[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y3; + } + + SelectedAircraftGPoly4.y[0] += y_offset; + SelectedAircraftGPoly4.y[1] += y_offset; + SelectedAircraftGPoly4.y[2] += y_offset; + SelectedAircraftGPoly4.y[3] += y_offset; + + GsSortGPoly4(&SelectedAircraftGPoly4); + + if(ptrPlayer->ActiveAircraft > (GAME_GUI_AIRCRAFT_DATA_MAX_PAGE * (ptrPlayer->FlightDataPage + 1) ) ) + { + ArrowsSpr.x = AIRCRAFT_DATA_FLIGHT_RIGHT_ARROW_X; + ArrowsSpr.y = AIRCRAFT_DATA_FLIGHT_RIGHT_ARROW_Y; - SelectedAircraftGPoly4.g[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G0; - SelectedAircraftGPoly4.g[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G1; - SelectedAircraftGPoly4.g[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G2; - SelectedAircraftGPoly4.g[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_G3; + ArrowsSpr.attribute |= GFX_1HZ_FLASH; - SelectedAircraftGPoly4.b[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B0; - SelectedAircraftGPoly4.b[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B1; - SelectedAircraftGPoly4.b[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B2; - SelectedAircraftGPoly4.b[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_B3; + ArrowsSpr.u = AIRCRAFT_DATA_FLIGHT_RIGHT_ARROW_U; + ArrowsSpr.v = AIRCRAFT_DATA_FLIGHT_RIGHT_ARROW_V; - SelectedAircraftGPoly4.attribute |= ENABLE_TRANS | TRANS_MODE(0); + ArrowsSpr.w = AIRCRAFT_DATA_FLIGHT_ARROWS_SIZE; + ArrowsSpr.h = AIRCRAFT_DATA_FLIGHT_ARROWS_SIZE; - if(GameTwoPlayersActive() == true) - { - SelectedAircraftGPoly4.x[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0_2PLAYER; - SelectedAircraftGPoly4.x[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1_2PLAYER; - SelectedAircraftGPoly4.x[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X2_2PLAYER; - SelectedAircraftGPoly4.x[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X3_2PLAYER; - } - else - { - SelectedAircraftGPoly4.x[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X0; - SelectedAircraftGPoly4.x[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X1; - SelectedAircraftGPoly4.x[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X2; - SelectedAircraftGPoly4.x[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_X3; - } + GfxSortSprite(&ArrowsSpr); + } + + if(ptrPlayer->FlightDataPage != 0) + { + ArrowsSpr.x = AIRCRAFT_DATA_FLIGHT_LEFT_ARROW_X; + ArrowsSpr.y = AIRCRAFT_DATA_FLIGHT_LEFT_ARROW_Y; - page_aircraft = (ptrPlayer->SelectedAircraft) - (ptrPlayer->FlightDataPage * GAME_GUI_AIRCRAFT_DATA_MAX_PAGE); + ArrowsSpr.attribute |= GFX_1HZ_FLASH; - y_offset = (short)(page_aircraft * AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H); - - /*dprintf("ptrPlayer->ActiveAircraft = %d\n",ptrPlayer->ActiveAircraft); - dprintf("ptrPlayer->SelectedAircraft = %d\n",ptrPlayer->SelectedAircraft); - dprintf("ptrPlayer->FlightDataPage = %d\n",ptrPlayer->FlightDataPage); - dprintf("y_offset = %d\n",y_offset);*/ + ArrowsSpr.u = AIRCRAFT_DATA_FLIGHT_LEFT_ARROW_U; + ArrowsSpr.v = AIRCRAFT_DATA_FLIGHT_LEFT_ARROW_V; - if(GameTwoPlayersActive() == true) - { - SelectedAircraftGPoly4.y[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0_2PLAYER; - SelectedAircraftGPoly4.y[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y1_2PLAYER; - SelectedAircraftGPoly4.y[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2_2PLAYER; - SelectedAircraftGPoly4.y[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y3_2PLAYER; - } - else - { - SelectedAircraftGPoly4.y[0] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y0; - SelectedAircraftGPoly4.y[1] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y1; - SelectedAircraftGPoly4.y[2] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y2; - SelectedAircraftGPoly4.y[3] = AIRCRAFT_DATA_FLIGHT_GSGPOLY4_Y3; - } + ArrowsSpr.w = AIRCRAFT_DATA_FLIGHT_ARROWS_SIZE; + ArrowsSpr.h = AIRCRAFT_DATA_FLIGHT_ARROWS_SIZE; - SelectedAircraftGPoly4.y[0] += y_offset; - SelectedAircraftGPoly4.y[1] += y_offset; - SelectedAircraftGPoly4.y[2] += y_offset; - SelectedAircraftGPoly4.y[3] += y_offset; - - GsSortGPoly4(&SelectedAircraftGPoly4); - - if(ptrPlayer->ActiveAircraft > (GAME_GUI_AIRCRAFT_DATA_MAX_PAGE * (ptrPlayer->FlightDataPage + 1) ) ) - { - ArrowsSpr.x = AIRCRAFT_DATA_FLIGHT_RIGHT_ARROW_X; - ArrowsSpr.y = AIRCRAFT_DATA_FLIGHT_RIGHT_ARROW_Y; - - ArrowsSpr.attribute |= GFX_1HZ_FLASH; - - ArrowsSpr.u = AIRCRAFT_DATA_FLIGHT_RIGHT_ARROW_U; - ArrowsSpr.v = AIRCRAFT_DATA_FLIGHT_RIGHT_ARROW_V; - - ArrowsSpr.w = AIRCRAFT_DATA_FLIGHT_ARROWS_SIZE; - ArrowsSpr.h = AIRCRAFT_DATA_FLIGHT_ARROWS_SIZE; - - GfxSortSprite(&ArrowsSpr); - } - - if(ptrPlayer->FlightDataPage != 0) - { - ArrowsSpr.x = AIRCRAFT_DATA_FLIGHT_LEFT_ARROW_X; - ArrowsSpr.y = AIRCRAFT_DATA_FLIGHT_LEFT_ARROW_Y; - - ArrowsSpr.attribute |= GFX_1HZ_FLASH; - - ArrowsSpr.u = AIRCRAFT_DATA_FLIGHT_LEFT_ARROW_U; - ArrowsSpr.v = AIRCRAFT_DATA_FLIGHT_LEFT_ARROW_V; - - ArrowsSpr.w = AIRCRAFT_DATA_FLIGHT_ARROWS_SIZE; - ArrowsSpr.h = AIRCRAFT_DATA_FLIGHT_ARROWS_SIZE; - - GfxSortSprite(&ArrowsSpr); - } - - GameGuiShowAircraftData(ptrPlayer, ptrFlightData); - } + GfxSortSprite(&ArrowsSpr); + } + + GameGuiShowAircraftData(ptrPlayer, ptrFlightData); + + GfxDrawButton(AIRCRAFT_LOCK_TARGET_X, AIRCRAFT_LOCK_TARGET_Y, PAD_SQUARE); + + if(ptrPlayer->LockTarget == true) + { + FontPrintText(&SmallFont, AIRCRAFT_LOCK_TARGET_TEXT_X, AIRCRAFT_LOCK_TARGET_TEXT_Y, "Unlock target"); + } + else + { + FontPrintText(&SmallFont, AIRCRAFT_LOCK_TARGET_TEXT_X, AIRCRAFT_LOCK_TARGET_TEXT_Y, "Lock target"); + } + } + else + { + if(GameTwoPlayersActive() == true) + { + FontPrintText( &SmallFont, + AIRCRAFT_DATA_GSGPOLY4_X0_2PLAYER + + ( (AIRCRAFT_DATA_GSGPOLY4_X1_2PLAYER - AIRCRAFT_DATA_GSGPOLY4_X0_2PLAYER) >> 2), + AIRCRAFT_DATA_GSGPOLY4_Y0_2PLAYER + + ( (AIRCRAFT_DATA_GSGPOLY4_Y2_2PLAYER - AIRCRAFT_DATA_GSGPOLY4_Y0_2PLAYER) >> 1), + "No flights!" ); + } else { FontPrintText( &SmallFont, @@ -628,6 +653,7 @@ void GameGuiAircraftList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightDat ( (AIRCRAFT_DATA_GSGPOLY4_Y2 - AIRCRAFT_DATA_GSGPOLY4_Y0) >> 1), "No flights!" ); } + } } } @@ -740,6 +766,7 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh short AircraftDataFlightNumber_Y; short AircraftDataPassengers_X; short AircraftDataPassengers_Y; + short AircraftDataState_X_Offset; if(GameTwoPlayersActive() == true) { @@ -749,6 +776,7 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh AircraftDataFlightNumber_Y = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y_2PLAYER; AircraftDataPassengers_X = AIRCRAFT_DATA_PASSENGERS_X_2PLAYER; AircraftDataPassengers_Y = AIRCRAFT_DATA_PASSENGERS_Y_2PLAYER; + AircraftDataState_X_Offset = 54; } else { @@ -758,6 +786,7 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh AircraftDataFlightNumber_Y = AIRCRAFT_DATA_FLIGHT_NUMBER_TEXT_Y; AircraftDataPassengers_X = AIRCRAFT_DATA_PASSENGERS_X; AircraftDataPassengers_Y = AIRCRAFT_DATA_PASSENGERS_Y; + AircraftDataState_X_Offset = 88; } FontSetFlags(&SmallFont,FONT_NOFLAGS); @@ -774,9 +803,9 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh FontPrintText( &SmallFont, AircraftDataFlightNumber_X, AircraftDataFlightNumber_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), - ptrFlightData->strFlightNumber[i] ); + ptrFlightData->strFlightNumber[ptrPlayer->ActiveAircraftList[i]] ); - switch(ptrFlightData->FlightDirection[i]) + switch(ptrFlightData->FlightDirection[ptrPlayer->ActiveAircraftList[i]]) { case ARRIVAL: FontPrintText( &SmallFont, @@ -785,10 +814,20 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh "Arrival" ); break; case DEPARTURE: - FontPrintText( &SmallFont, - AircraftDataDirection_X, - AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), - "Departure" ); + if(GameTwoPlayersActive() == true) + { + FontPrintText( &SmallFont, + AircraftDataDirection_X, + AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), + "Depart." ); + } + else + { + FontPrintText( &SmallFont, + AircraftDataDirection_X, + AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), + "Departure" ); + } break; default: break; @@ -796,32 +835,39 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh FontSetFlags(&SmallFont, FONT_2HZ_FLASH); - switch(ptrFlightData->State[i]) + switch(ptrFlightData->State[ptrPlayer->ActiveAircraftList[i]]) { + case STATE_APPROACH: + FontPrintText( &SmallFont, + AircraftDataDirection_X + AircraftDataState_X_Offset, + AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), + "Approach" ); + break; + case STATE_FINAL: FontPrintText( &SmallFont, - AircraftDataDirection_X + 88, + AircraftDataDirection_X + AircraftDataState_X_Offset, AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), "Landing" ); break; case STATE_LANDED: FontPrintText( &SmallFont, - AircraftDataDirection_X + 88, + AircraftDataDirection_X + AircraftDataState_X_Offset, AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), "Arrived" ); break; case STATE_PARKED: FontPrintText( &SmallFont, - AircraftDataDirection_X + 88, + AircraftDataDirection_X + AircraftDataState_X_Offset, AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), "Parked" ); break; case STATE_UNBOARDING: FontPrintText( &SmallFont, - AircraftDataDirection_X + 88, + AircraftDataDirection_X + AircraftDataState_X_Offset, AircraftDataDirection_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), "Unboard" ); break; @@ -836,6 +882,22 @@ void GameGuiShowAircraftData(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFligh AircraftDataPassengers_X, AircraftDataPassengers_Y + (AIRCRAFT_DATA_FLIGHT_GSGPOLY4_H * j), "%d pax.", - ptrFlightData->Passengers[i] ); + ptrFlightData->Passengers[ptrPlayer->ActiveAircraftList[i]] ); } } + +bool GameGuiShowAircraftDataSpecialConditions(TYPE_PLAYER* ptrPlayer) +{ + // Aircraft list data cannot be shown under these conditions. + + if( (ptrPlayer->SelectRunway == true) + || + (ptrPlayer->SelectTaxiwayParking == true) + || + (ptrPlayer->SelectTaxiwayRunway == true) ) + { + return true; + } + + return false; +} diff --git a/Source/GameGui.h b/Source/GameGui.h index 160b06a..319e58b 100644 --- a/Source/GameGui.h +++ b/Source/GameGui.h @@ -29,6 +29,7 @@ void GameGuiInit(void); bool GameGuiPauseDialog(TYPE_PLAYER* ptrPlayer); +bool GameGuiShowAircraftDataSpecialConditions(TYPE_PLAYER* ptrPlayer); void GameGuiAircraftNotificationRequest(TYPE_FLIGHT_DATA * ptrFlightData); void GameGuiBubble(TYPE_FLIGHT_DATA * ptrFlightData); void GameGuiAircraftList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA * ptrFlightData); diff --git a/Source/GameStructures.h b/Source/GameStructures.h index 355ec33..4a6b563 100644 --- a/Source/GameStructures.h +++ b/Source/GameStructures.h @@ -84,10 +84,11 @@ typedef enum t_livery typedef enum t_direction { - AIRCRAFT_DIR_NORTH = 0, + AIRCRAFT_DIR_NO_DIRECTION = 0, + AIRCRAFT_DIR_NORTH, AIRCRAFT_DIR_SOUTH, AIRCRAFT_DIR_EAST, - AIRCRAFT_DIR_WEST + AIRCRAFT_DIR_WEST, }AIRCRAFT_DIRECTION; typedef enum t_aircraftAttitude @@ -114,6 +115,10 @@ typedef struct t_aircraftData fix16_t Speed; short TargetSpeed; bool TargetReached; + // Used for target reached detection + fix16_t XPos_Old; + // Used for target reached detection + fix16_t YPos_Old; }TYPE_AIRCRAFT_DATA; typedef struct @@ -135,6 +140,7 @@ typedef struct bool LockTarget; // Stores indexes for player-specific active aircraft + // Used to relate SelectedAircraft agains FlightData index uint8_t ActiveAircraftList[GAME_MAX_AIRCRAFT]; // Flight direction to be managed by player (see 2-player mode) FL_DIR FlightDirection; @@ -157,8 +163,6 @@ typedef struct uint8_t WaypointIdx; // Another internal index to keep last desired selected point by user when defining a path. uint8_t LastWaypointIdx; - // Player ID (PLAYER_ONE = 0, PLAYER_TWO = 1) - uint8_t Id; bool (*PadKeyPressed_Callback)(unsigned short); bool (*PadKeyReleased_Callback)(unsigned short); diff --git a/Source/MemCard.h b/Source/MemCard.h index a7ddcf8..880886b 100644 --- a/Source/MemCard.h +++ b/Source/MemCard.h @@ -96,7 +96,7 @@ typedef struct t_MemCard uint8_t Icons[MEMCARD_NUMBER_OF_ICONS][MEMCARD_ICON_SIZE]; uint8_t CLUT[MEMCARD_NUMBER_OF_ICONS][MEMCARD_CLUT_SIZE]; - uint8_t * Data; // Buffer pointed to by "Data" must be 128 KB or higher! + uint8_t* Data; // Buffer pointed to by "Data" must be 128 KB or higher! GsTPoly4 IconTPoly; }TYPE_BLOCK_DATA; diff --git a/Source/Menu.c b/Source/Menu.c index 0a922c4..da69137 100644 --- a/Source/Menu.c +++ b/Source/Menu.c @@ -320,6 +320,8 @@ void MainMenuRestoreInitValues(void) MainMenuBtn[TWO_PLAYER_BUTTON_INDEX].selected = false; MainMenuBtn[TWO_PLAYER_BUTTON_INDEX].was_selected = false; MainMenuBtn[TWO_PLAYER_BUTTON_INDEX].timer = 0; + + GfxSetGlobalLuminance(NORMAL_LUMINANCE); } void MainMenuButtonHandler(void) diff --git a/Source/System.c b/Source/System.c index 6eeaf15..8005fa8 100644 --- a/Source/System.c +++ b/Source/System.c @@ -269,7 +269,7 @@ void SystemCheckTimer(bool * timer, uint64_t * last_timer, uint8_t step) } } -bool SystemLoadFileToBuffer(char * fname, uint8_t * buffer, uint32_t szBuffer) +bool SystemLoadFileToBuffer(char * fname, uint8_t* buffer, uint32_t szBuffer) { FILE *f; int32_t size; @@ -329,7 +329,7 @@ bool SystemLoadFile(char *fname) return SystemLoadFileToBuffer(fname,file_buffer,sizeof(file_buffer)); } -uint8_t * SystemGetBufferAddress(void) +uint8_t* SystemGetBufferAddress(void) { return file_buffer; } @@ -361,7 +361,7 @@ volatile bool SystemIsBusy(void) return system_busy; } -bool SystemContains_u8(uint8_t value, uint8_t * buffer, size_t sz) +bool SystemContains_u8(uint8_t value, uint8_t* buffer, size_t sz) { size_t i = 0; @@ -376,7 +376,7 @@ bool SystemContains_u8(uint8_t value, uint8_t * buffer, size_t sz) return false; } -bool SystemContains_u16(uint16_t value, uint16_t * buffer, size_t sz) +bool SystemContains_u16(uint16_t value, uint16_t* buffer, size_t sz) { size_t i = 0; @@ -567,7 +567,7 @@ int32_t SystemIndexOfStringArray(char * str, char ** array) return -1; } -int32_t SystemIndexOf_U16(uint16_t value, uint16_t * array, uint32_t sz) +int32_t SystemIndexOf_U16(uint16_t value, uint16_t* array, uint32_t sz) { int32_t i; @@ -582,7 +582,7 @@ int32_t SystemIndexOf_U16(uint16_t value, uint16_t * array, uint32_t sz) return -1; } -int32_t SystemIndexOf_U8(uint8_t value, uint8_t * array, uint32_t from, uint32_t sz) +int32_t SystemIndexOf_U8(uint8_t value, uint8_t* array, uint32_t from, uint32_t sz) { int32_t i; diff --git a/Source/System.h b/Source/System.h index 61ce6e2..dda7c01 100644 --- a/Source/System.h +++ b/Source/System.h @@ -37,13 +37,13 @@ bool SystemRefreshNeeded(void); bool SystemLoadFile(char *fname); // Loads a file into desired buffer -bool SystemLoadFileToBuffer(char * fname, uint8_t * buffer, uint32_t szBuffer); +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); +uint8_t* SystemGetBufferAddress(void); // Tells whether srand() has been called using a pseudo-random value bool SystemIsRandSeedSet(void); @@ -82,10 +82,10 @@ uint64_t SystemGetGlobalTimer(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); +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); +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(). @@ -119,10 +119,10 @@ void SystemCheckStack(void); 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); +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); +int32_t SystemIndexOf_U8(uint8_t value, uint8_t* array, uint32_t from, uint32_t sz); void SystemCyclicHandler(void);