2017-02-04 14:49:08 +01:00
|
|
|
/* *************************************
|
|
|
|
* Includes
|
|
|
|
* *************************************/
|
|
|
|
|
|
|
|
#include "Aircraft.h"
|
|
|
|
|
|
|
|
/* *************************************
|
|
|
|
* Defines
|
|
|
|
* *************************************/
|
2017-05-22 07:06:17 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
#define AIRCRAFT_SIZE 16
|
|
|
|
|
|
|
|
/* *************************************
|
|
|
|
* Structs and enums
|
|
|
|
* *************************************/
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
AIRCRAFT_SPRITE_SIZE = 24,
|
|
|
|
AIRCRAFT_SPRITE_VRAM_X = 800,
|
|
|
|
AIRCRAFT_SPRITE_VRAM_Y = 304,
|
2017-05-24 07:15:38 +02:00
|
|
|
};
|
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
PHX_LIVERY_CLUT_X = 384,
|
|
|
|
PHX_LIVERY_CLUT_Y = 497,
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef enum t_aircraftSpeeds
|
|
|
|
{
|
|
|
|
AIRCRAFT_SPEED_IDLE = 0,
|
2017-05-28 22:57:01 +02:00
|
|
|
AIRCRAFT_SPEED_GROUND,
|
2017-02-04 14:49:08 +01:00
|
|
|
AIRCRAFT_SPEED_APPROACH,
|
|
|
|
AIRCRAFT_SPEED_TAKEOFF,
|
2017-05-24 07:15:38 +02:00
|
|
|
AIRCRAFT_SPEED_FINAL,
|
|
|
|
AIRCRAFT_SPEED_FINAL_Z,
|
2017-02-04 14:49:08 +01:00
|
|
|
}AIRCRAFT_SPEEDS;
|
|
|
|
|
|
|
|
/* *************************************
|
|
|
|
* Local variables
|
|
|
|
* *************************************/
|
|
|
|
|
|
|
|
static TYPE_AIRCRAFT_DATA AircraftData[GAME_MAX_AIRCRAFT];
|
|
|
|
static uint8_t AircraftIndex;
|
|
|
|
static GsSprite AircraftSpr;
|
|
|
|
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};
|
2017-05-24 07:15:38 +02:00
|
|
|
static const fix16_t AircraftSpeedsTable[] = { [AIRCRAFT_SPEED_IDLE] = 0,
|
2017-05-28 22:57:01 +02:00
|
|
|
[AIRCRAFT_SPEED_GROUND] = 0x6666,
|
2017-05-24 07:15:38 +02:00
|
|
|
[AIRCRAFT_SPEED_TAKEOFF] = 0x20000,
|
|
|
|
[AIRCRAFT_SPEED_FINAL] = 0x10000,
|
|
|
|
[AIRCRAFT_SPEED_FINAL_Z] = 0x4000 };
|
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
/* *************************************
|
|
|
|
* Local prototypes
|
|
|
|
* *************************************/
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
static void AircraftDirection(TYPE_AIRCRAFT_DATA* ptrAircraft);
|
2017-02-04 14:49:08 +01:00
|
|
|
static AIRCRAFT_LIVERY AircraftLiveryFromFlightNumber(char * strFlightNumber);
|
2017-05-01 23:05:51 +02:00
|
|
|
static void AircraftAttitude(TYPE_AIRCRAFT_DATA* ptrAircraft);
|
|
|
|
static void AircraftUpdateSpriteFromData(TYPE_AIRCRAFT_DATA* ptrAircraft);
|
2017-05-05 23:55:15 +02:00
|
|
|
static void AircraftSpeed(TYPE_AIRCRAFT_DATA* ptrAircraft);
|
2017-02-04 14:49:08 +01:00
|
|
|
|
|
|
|
void AircraftInit(void)
|
|
|
|
{
|
|
|
|
bzero(AircraftData, GAME_MAX_AIRCRAFT * sizeof(TYPE_AIRCRAFT_DATA));
|
|
|
|
AircraftIndex = 0;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftSpr.x = 0;
|
|
|
|
AircraftSpr.y = 0;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftSpr.attribute = COLORMODE(COLORMODE_8BPP);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftSpr.cx = PHX_LIVERY_CLUT_X;
|
|
|
|
AircraftSpr.cy = PHX_LIVERY_CLUT_Y;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftSpr.w = AIRCRAFT_SPRITE_SIZE;
|
|
|
|
AircraftSpr.h = AIRCRAFT_SPRITE_SIZE;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
/*AircraftSpr.tpage = 28;
|
|
|
|
AircraftSpr.u = 64;
|
|
|
|
AircraftSpr.v = 48;*/
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
GfxTPageOffsetFromVRAMPosition(&AircraftSpr, AIRCRAFT_SPRITE_VRAM_X, AIRCRAFT_SPRITE_VRAM_Y);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftCenterIsoPos.x = AIRCRAFT_SIZE >> 1;
|
|
|
|
AircraftCenterIsoPos.y = AIRCRAFT_SIZE >> 1;
|
|
|
|
AircraftCenterIsoPos.z = 0;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftCenterPos = GfxIsometricToCartesian(&AircraftCenterIsoPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AircraftAddNew( TYPE_FLIGHT_DATA * ptrFlightData,
|
|
|
|
uint8_t FlightDataIndex,
|
2017-05-24 07:15:38 +02:00
|
|
|
uint16_t* targets )
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2017-05-01 23:05:51 +02:00
|
|
|
TYPE_AIRCRAFT_DATA* ptrAircraft = &AircraftData[AircraftIndex];
|
2017-02-04 14:49:08 +01:00
|
|
|
uint8_t level_columns = GameGetLevelColumns();
|
|
|
|
uint8_t i;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
if(AircraftIndex >= GAME_MAX_AIRCRAFT)
|
|
|
|
{
|
|
|
|
dprintf("Exceeded maximum aircraft capacity!\n");
|
|
|
|
return false;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
memcpy(ptrAircraft->Target, targets, sizeof(uint16_t) * AIRCRAFT_MAX_TARGETS);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
ptrAircraft->TargetIdx = 0;
|
|
|
|
ptrAircraft->Livery = AircraftLiveryFromFlightNumber(ptrFlightData->strFlightNumber[FlightDataIndex]);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
ptrAircraft->FlightDataIdx = FlightDataIndex;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
if(ptrFlightData->FlightDirection[FlightDataIndex] == ARRIVAL)
|
|
|
|
{
|
|
|
|
ptrAircraft->IsoPos.x = 0;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
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);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
ptrAircraft->IsoPos.z = targets[0] % level_columns;
|
|
|
|
ptrAircraft->IsoPos.z <<= TILE_SIZE_BIT_SHIFT - 1;
|
|
|
|
ptrAircraft->IsoPos.z = fix16_from_int(ptrAircraft->IsoPos.z);
|
|
|
|
}
|
2017-05-01 23:05:51 +02:00
|
|
|
else if(ptrFlightData->FlightDirection[FlightDataIndex] == DEPARTURE)
|
|
|
|
{
|
|
|
|
ptrAircraft->IsoPos.x = GameGetXFromTile(ptrFlightData->Parking[FlightDataIndex]);
|
|
|
|
ptrAircraft->IsoPos.y = GameGetYFromTile(ptrFlightData->Parking[FlightDataIndex]);
|
|
|
|
ptrAircraft->IsoPos.z = 0;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
ptrAircraft->State = ptrFlightData->State[FlightDataIndex];
|
2017-05-24 07:15:38 +02:00
|
|
|
|
|
|
|
ptrAircraft->Direction = AIRCRAFT_DIR_NORTH; // Default to north direction
|
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
dprintf("\nAircraft Data:\n");
|
|
|
|
dprintf("\tTargets:");
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
for(i = 0; i < AIRCRAFT_MAX_TARGETS; i++)
|
|
|
|
{
|
|
|
|
if(ptrAircraft->Target[i] == 0)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
dprintf(" %d", ptrAircraft->Target[i]);
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
dprintf("\nLivery: %d\n", ptrAircraft->Livery );
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
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) );
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftIndex++;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
AIRCRAFT_LIVERY AircraftLiveryFromFlightNumber(char * strFlightNumber)
|
|
|
|
{
|
|
|
|
int32_t liveryIndex;
|
|
|
|
char strLivery[4];
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
memset(strLivery, 0, 4 * sizeof(char) );
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
strncpy(strLivery, strFlightNumber, 3);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
liveryIndex = SystemIndexOfStringArray(strLivery, AircraftLiveryNamesTable);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
if(liveryIndex == -1)
|
|
|
|
{
|
|
|
|
return AIRCRAFT_LIVERY_UNKNOWN;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
return AircraftLiveryTable[liveryIndex];
|
|
|
|
}
|
|
|
|
|
2017-05-27 17:10:15 +02:00
|
|
|
bool AircraftRemove(uint8_t aircraftIdx)
|
|
|
|
{
|
|
|
|
uint8_t i;
|
|
|
|
|
|
|
|
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
|
|
|
{
|
|
|
|
TYPE_AIRCRAFT_DATA* ptrAircraft = &AircraftData[i];
|
|
|
|
|
|
|
|
if(ptrAircraft->FlightDataIdx == aircraftIdx)
|
|
|
|
{
|
|
|
|
ptrAircraft->State = STATE_IDLE;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
void AircraftHandler(void)
|
|
|
|
{
|
|
|
|
uint8_t i;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
|
|
|
{
|
2017-05-27 17:10:15 +02:00
|
|
|
TYPE_AIRCRAFT_DATA* ptrAircraft = &AircraftData[i];
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
if(ptrAircraft->State == STATE_IDLE)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2017-05-28 22:57:01 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftDirection(ptrAircraft);
|
|
|
|
AircraftAttitude(ptrAircraft);
|
2017-05-05 23:55:15 +02:00
|
|
|
AircraftSpeed(ptrAircraft);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
|
|
|
ptrAircraft->State = GameGetFlightDataStateFromIdx(ptrAircraft->FlightDataIdx);
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-05 23:55:15 +02:00
|
|
|
void AircraftSpeed(TYPE_AIRCRAFT_DATA* ptrAircraft)
|
|
|
|
{
|
|
|
|
switch(ptrAircraft->State)
|
|
|
|
{
|
|
|
|
case STATE_FINAL:
|
2017-05-24 07:15:38 +02:00
|
|
|
ptrAircraft->Speed = AircraftSpeedsTable[AIRCRAFT_SPEED_FINAL];
|
2017-05-05 23:55:15 +02:00
|
|
|
break;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-05 23:55:15 +02:00
|
|
|
case STATE_TAKEOFF:
|
2017-05-28 22:57:01 +02:00
|
|
|
// Fall through
|
|
|
|
case STATE_CLIMBING:
|
2017-05-05 23:55:15 +02:00
|
|
|
ptrAircraft->Speed = AircraftSpeedsTable[AIRCRAFT_SPEED_TAKEOFF];
|
|
|
|
break;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-05 23:55:15 +02:00
|
|
|
case STATE_TAXIING:
|
2017-05-28 04:22:03 +02:00
|
|
|
// Fall through
|
2017-05-28 22:57:01 +02:00
|
|
|
case STATE_HOLDING_RWY:
|
|
|
|
// Fall through
|
2017-05-28 04:22:03 +02:00
|
|
|
case STATE_READY_FOR_TAKEOFF:
|
2017-05-28 22:57:01 +02:00
|
|
|
ptrAircraft->Speed = AircraftSpeedsTable[AIRCRAFT_SPEED_GROUND];
|
2017-05-05 23:55:15 +02:00
|
|
|
break;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-05 23:55:15 +02:00
|
|
|
case STATE_UNBOARDING:
|
2017-05-24 07:15:38 +02:00
|
|
|
// Fall through
|
2017-05-05 23:55:15 +02:00
|
|
|
case STATE_IDLE:
|
2017-05-24 07:15:38 +02:00
|
|
|
// Fall through
|
2017-05-05 23:55:15 +02:00
|
|
|
case STATE_LANDED:
|
2017-05-24 07:15:38 +02:00
|
|
|
// Fall through
|
2017-05-05 23:55:15 +02:00
|
|
|
default:
|
|
|
|
ptrAircraft->Speed = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AircraftRender(TYPE_PLAYER* ptrPlayer)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2017-05-01 23:05:51 +02:00
|
|
|
TYPE_AIRCRAFT_DATA* ptrAircraft;
|
2017-02-04 14:49:08 +01:00
|
|
|
TYPE_CARTESIAN_POS cartPos;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
uint8_t i;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
|
|
|
{
|
|
|
|
ptrAircraft = &AircraftData[i];
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
if(ptrAircraft->State == STATE_IDLE)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
cartPos = GfxIsometricFix16ToCartesian(&ptrAircraft->IsoPos);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
// Aircraft position is referred to aircraft center
|
|
|
|
AircraftSpr.x = cartPos.x - (AircraftSpr.w >> 1);
|
|
|
|
AircraftSpr.y = cartPos.y - (AircraftSpr.h >> 1);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftUpdateSpriteFromData(ptrAircraft);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
CameraApplyCoordinatesToSprite(ptrPlayer, &AircraftSpr);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
AircraftSpr.r = NORMAL_LUMINANCE;
|
|
|
|
AircraftSpr.g = NORMAL_LUMINANCE;
|
|
|
|
AircraftSpr.b = NORMAL_LUMINANCE;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
GfxSortSprite(&AircraftSpr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
void AircraftDirection(TYPE_AIRCRAFT_DATA* ptrAircraft)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
|
|
|
TYPE_ISOMETRIC_FIX16_POS targetPos;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-28 22:57:01 +02:00
|
|
|
if(ptrAircraft->State != STATE_CLIMBING)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
if(ptrAircraft->Target[ptrAircraft->TargetIdx] == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-28 22:57:01 +02:00
|
|
|
targetPos.x = GameGetXFromTile(ptrAircraft->Target[ptrAircraft->TargetIdx]);
|
|
|
|
targetPos.y = GameGetYFromTile(ptrAircraft->Target[ptrAircraft->TargetIdx]);
|
|
|
|
targetPos.z = 0;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-28 22:57:01 +02:00
|
|
|
ptrAircraft->TargetReached = false;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-28 22:57:01 +02:00
|
|
|
if(targetPos.y == ptrAircraft->IsoPos.y)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
if(targetPos.x > ptrAircraft->IsoPos.x)
|
2017-05-24 07:15:38 +02:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
if(targetPos.x <= (ptrAircraft->IsoPos.x + ptrAircraft->Speed) )
|
|
|
|
{
|
|
|
|
ptrAircraft->TargetReached = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptrAircraft->Direction = AIRCRAFT_DIR_EAST;
|
|
|
|
ptrAircraft->IsoPos.x += ptrAircraft->Speed;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
}
|
2017-05-28 22:57:01 +02:00
|
|
|
else if(targetPos.x < ptrAircraft->IsoPos.x)
|
2017-05-24 07:15:38 +02:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
if(targetPos.x >= (ptrAircraft->IsoPos.x - ptrAircraft->Speed) )
|
|
|
|
{
|
|
|
|
ptrAircraft->TargetReached = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptrAircraft->Direction = AIRCRAFT_DIR_WEST;
|
|
|
|
ptrAircraft->IsoPos.x -= ptrAircraft->Speed;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
ptrAircraft->TargetReached = true;
|
2017-05-24 07:15:38 +02:00
|
|
|
}
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
2017-05-28 22:57:01 +02:00
|
|
|
else if(targetPos.x == ptrAircraft->IsoPos.x)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
if(targetPos.y > ptrAircraft->IsoPos.y)
|
2017-05-24 07:15:38 +02:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
if(targetPos.y <= (ptrAircraft->IsoPos.y + ptrAircraft->Speed) )
|
|
|
|
{
|
|
|
|
ptrAircraft->TargetReached = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptrAircraft->Direction = AIRCRAFT_DIR_SOUTH;
|
|
|
|
ptrAircraft->IsoPos.y += ptrAircraft->Speed;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
}
|
2017-05-28 22:57:01 +02:00
|
|
|
else if(targetPos.y < ptrAircraft->IsoPos.y)
|
2017-05-24 07:15:38 +02:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
if(targetPos.y >= (ptrAircraft->IsoPos.y - ptrAircraft->Speed) )
|
|
|
|
{
|
|
|
|
ptrAircraft->TargetReached = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ptrAircraft->Direction = AIRCRAFT_DIR_NORTH;
|
|
|
|
ptrAircraft->IsoPos.y -= ptrAircraft->Speed;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
}
|
2017-05-28 22:57:01 +02:00
|
|
|
else
|
2017-05-24 07:15:38 +02:00
|
|
|
{
|
|
|
|
ptrAircraft->TargetReached = true;
|
|
|
|
}
|
2017-05-28 22:57:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(ptrAircraft->TargetReached == true)
|
|
|
|
{
|
|
|
|
ptrAircraft->IsoPos.x = targetPos.x;
|
|
|
|
ptrAircraft->IsoPos.y = targetPos.y;
|
|
|
|
|
|
|
|
if(ptrAircraft->Target[++ptrAircraft->TargetIdx] == 0)
|
2017-05-24 07:15:38 +02:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
dprintf("All targets reached!\n");
|
|
|
|
ptrAircraft->State = GameTargetsReached(ptrAircraft->Target[0], ptrAircraft->FlightDataIdx);
|
2017-05-24 07:15:38 +02:00
|
|
|
}
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
2017-05-28 22:57:01 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// STATE_CLIMBING
|
|
|
|
switch(ptrAircraft->Direction)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
case AIRCRAFT_DIR_EAST:
|
|
|
|
ptrAircraft->IsoPos.x += ptrAircraft->Speed;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AIRCRAFT_DIR_WEST:
|
|
|
|
ptrAircraft->IsoPos.x -= ptrAircraft->Speed;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AIRCRAFT_DIR_NORTH:
|
|
|
|
ptrAircraft->IsoPos.y -= ptrAircraft->Speed;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AIRCRAFT_DIR_SOUTH:
|
|
|
|
ptrAircraft->IsoPos.y += ptrAircraft->Speed;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case AIRCRAFT_DIR_NO_DIRECTION:
|
|
|
|
// Fall through
|
|
|
|
default:
|
|
|
|
return;
|
2017-05-24 07:15:38 +02:00
|
|
|
}
|
|
|
|
|
2017-05-28 22:57:01 +02:00
|
|
|
ptrAircraft->IsoPos.z += AircraftSpeedsTable[AIRCRAFT_SPEED_FINAL_Z];
|
|
|
|
|
|
|
|
if(GameInsideLevelFromIsoPos(&ptrAircraft->IsoPos) == true)
|
2017-05-24 07:15:38 +02:00
|
|
|
{
|
2017-05-28 22:57:01 +02:00
|
|
|
dprintf("Flight %d removed\n", ptrAircraft->FlightDataIdx);
|
|
|
|
GameRemoveFlight(ptrAircraft->FlightDataIdx);
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
void AircraftUpdateSpriteFromData(TYPE_AIRCRAFT_DATA* ptrAircraft)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
|
|
|
switch(ptrAircraft->Livery)
|
|
|
|
{
|
|
|
|
case AIRCRAFT_LIVERY_0:
|
|
|
|
AircraftSpr.cx = PHX_LIVERY_CLUT_X;
|
|
|
|
AircraftSpr.cy = PHX_LIVERY_CLUT_Y;
|
|
|
|
break;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
case AIRCRAFT_LIVERY_UNKNOWN:
|
|
|
|
// Fall through
|
|
|
|
default:
|
|
|
|
dprintf("Unknown livery %d!\n", ptrAircraft->Livery);
|
|
|
|
break;
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
// Reset TPAGE and {U, V} offset first.
|
|
|
|
GfxTPageOffsetFromVRAMPosition(&AircraftSpr, AIRCRAFT_SPRITE_VRAM_X, AIRCRAFT_SPRITE_VRAM_Y);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
switch(ptrAircraft->Direction)
|
|
|
|
{
|
|
|
|
case AIRCRAFT_DIR_NORTH:
|
|
|
|
AircraftSpr.v += AircraftSpr.w;
|
|
|
|
AircraftSpr.attribute |= H_FLIP;
|
|
|
|
break;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
case AIRCRAFT_DIR_SOUTH:
|
|
|
|
AircraftSpr.v += 0;
|
|
|
|
AircraftSpr.attribute |= H_FLIP;
|
|
|
|
break;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
case AIRCRAFT_DIR_EAST:
|
|
|
|
AircraftSpr.v += 0;
|
|
|
|
AircraftSpr.attribute &= ~(H_FLIP);
|
|
|
|
break;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
case AIRCRAFT_DIR_WEST:
|
|
|
|
AircraftSpr.v += AircraftSpr.w;
|
|
|
|
AircraftSpr.attribute &= ~(H_FLIP);
|
|
|
|
break;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
|
|
|
case AIRCRAFT_DIR_NO_DIRECTION:
|
|
|
|
// Fall through
|
|
|
|
default:
|
|
|
|
break;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
void AircraftAttitude(TYPE_AIRCRAFT_DATA* ptrAircraft)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
|
|
|
if(ptrAircraft->State == STATE_FINAL)
|
|
|
|
{
|
|
|
|
if(ptrAircraft->IsoPos.z > 0)
|
|
|
|
{
|
2017-05-24 07:15:38 +02:00
|
|
|
ptrAircraft->IsoPos.z -= AircraftSpeedsTable[AIRCRAFT_SPEED_FINAL_Z];
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2017-05-01 23:05:51 +02:00
|
|
|
TYPE_ISOMETRIC_FIX16_POS fix16IsoPos = AircraftFromFlightDataIndex(FlightDataIdx)->IsoPos;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
retIsoPos.x = (short)fix16_to_int(fix16IsoPos.x);
|
|
|
|
retIsoPos.y = (short)fix16_to_int(fix16IsoPos.y);
|
|
|
|
retIsoPos.z = (short)fix16_to_int(fix16IsoPos.z);
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-02-04 14:49:08 +01:00
|
|
|
return retIsoPos;
|
|
|
|
}
|
|
|
|
|
2017-05-24 07:15:38 +02:00
|
|
|
void AircraftAddTargets(TYPE_AIRCRAFT_DATA* ptrAircraft, uint16_t* targets)
|
|
|
|
{
|
2017-02-04 14:49:08 +01:00
|
|
|
memcpy(ptrAircraft->Target, targets, sizeof(uint16_t) * AIRCRAFT_MAX_TARGETS);
|
2017-05-28 22:57:01 +02:00
|
|
|
ptrAircraft->TargetIdx = 0;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
uint16_t AircraftGetTileFromFlightDataIndex(uint8_t index)
|
|
|
|
{
|
|
|
|
TYPE_ISOMETRIC_POS isoPos = AircraftGetIsoPos(index);
|
|
|
|
return GameGetTileFromIsoPosition(&isoPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
TYPE_AIRCRAFT_DATA* AircraftFromFlightDataIndex(uint8_t index)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
2017-05-01 23:05:51 +02:00
|
|
|
uint8_t i;
|
|
|
|
TYPE_AIRCRAFT_DATA* ptrAircraft;
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
for(i = 0; i < GAME_MAX_AIRCRAFT; i++)
|
|
|
|
{
|
|
|
|
ptrAircraft = &AircraftData[i];
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
if(ptrAircraft->FlightDataIdx == index)
|
|
|
|
{
|
|
|
|
return ptrAircraft;
|
|
|
|
}
|
|
|
|
}
|
2017-05-24 07:15:38 +02:00
|
|
|
|
2017-05-01 23:05:51 +02:00
|
|
|
return NULL;
|
2017-02-04 14:49:08 +01:00
|
|
|
}
|
|
|
|
|
2017-05-24 07:15:38 +02:00
|
|
|
void AircraftFromFlightDataIndexAddTargets(uint8_t index, uint16_t* targets)
|
2017-02-04 14:49:08 +01:00
|
|
|
{
|
|
|
|
AircraftAddTargets(AircraftFromFlightDataIndex(index), targets);
|
|
|
|
}
|
2017-05-28 04:22:03 +02:00
|
|
|
|
|
|
|
AIRCRAFT_DIRECTION AircraftGetDirection(TYPE_AIRCRAFT_DATA* ptrAircraft)
|
|
|
|
{
|
|
|
|
return ptrAircraft->Direction;
|
|
|
|
}
|
|
|
|
|