452 lines
11 KiB
C
452 lines
11 KiB
C
/* *************************************
|
|
* Includes
|
|
* *************************************/
|
|
|
|
#include "PltParser.h"
|
|
#include "System.h"
|
|
#include "Game.h"
|
|
#include "Message.h"
|
|
|
|
/* *************************************
|
|
* Defines
|
|
* *************************************/
|
|
|
|
#define LINE_MAX_CHARACTERS MAX_MESSAGE_STR_SIZE
|
|
#define MESSAGE_HEADER_STR "MESSAGE"
|
|
|
|
/* **************************************
|
|
* Structs and enums *
|
|
* *************************************/
|
|
|
|
/* *************************************
|
|
* Local Variables
|
|
* *************************************/
|
|
|
|
/* *************************************
|
|
* Local Prototypes
|
|
* *************************************/
|
|
|
|
static void PltParserResetBuffers(TYPE_FLIGHT_DATA* const ptrFlightData);
|
|
|
|
bool PltParserLoadFile(const char* strPath, TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
{
|
|
enum
|
|
{
|
|
PLT_HOUR_MINUTE_CHARACTERS = 2,
|
|
PLT_FIRST_LINE_CHARACTERS = 5,
|
|
PLT_COLON_POSITION = 2
|
|
};
|
|
|
|
uint8_t i;
|
|
uint8_t j;
|
|
uint8_t aircraftIndex;
|
|
bool first_line_read = false;
|
|
char* buffer;
|
|
char lineBuffer[LINE_MAX_CHARACTERS];
|
|
char* lineBufferPtr;
|
|
char* pltBufferSavePtr;
|
|
char strHour[PLT_HOUR_MINUTE_CHARACTERS] = {'\0'};
|
|
char strMinutes[PLT_HOUR_MINUTE_CHARACTERS] = {'\0'};;
|
|
uint8_t* strPltBuffer;
|
|
|
|
if (SystemLoadFile(strPath) == false)
|
|
{
|
|
Serial_printf("Error loading file %s!\n",strPath);
|
|
return false;
|
|
}
|
|
|
|
strPltBuffer = SystemGetBufferAddress();
|
|
|
|
PltParserResetBuffers(ptrFlightData);
|
|
|
|
// Now, buffer shall be read from line to line
|
|
|
|
buffer = strtok_r((char*)strPltBuffer,"\n",&pltBufferSavePtr);
|
|
|
|
aircraftIndex = 0;
|
|
|
|
while (buffer != NULL)
|
|
{
|
|
if (buffer[0] == '#')
|
|
{
|
|
// Comment line
|
|
buffer = strtok_r(NULL,"\n",&pltBufferSavePtr);
|
|
continue;
|
|
}
|
|
|
|
if (first_line_read == false)
|
|
{
|
|
// First (non-comment) line should indicate level time
|
|
// i.e.: 10:30, or 22:45
|
|
first_line_read = true;
|
|
|
|
if (strlen(buffer) != PLT_FIRST_LINE_CHARACTERS)
|
|
{
|
|
int k;
|
|
|
|
printf("Buffer: ");
|
|
|
|
for (k = 0; k < strlen(buffer); k++)
|
|
{
|
|
printf("0x%02X ", buffer[k]);
|
|
}
|
|
// Format should always be HH:MM (5 characters)
|
|
// Treat any other combination as possible error
|
|
Serial_printf( "Invalid first line length: %d, expected %d characters.\n",
|
|
strlen(buffer),
|
|
PLT_FIRST_LINE_CHARACTERS );
|
|
return false;
|
|
}
|
|
|
|
if (buffer[PLT_COLON_POSITION] != ':')
|
|
{
|
|
// Check whether time format is HH:MM
|
|
Serial_printf("Invalid hour/minute format: %s\n", buffer);
|
|
return false;
|
|
}
|
|
|
|
j = 0;
|
|
|
|
for (i = 0; i < PLT_FIRST_LINE_CHARACTERS ; i++)
|
|
{
|
|
if (i == PLT_COLON_POSITION)
|
|
{
|
|
j = 0;
|
|
continue;
|
|
}
|
|
else if (i < PLT_COLON_POSITION)
|
|
{
|
|
strHour[j++] = buffer[i];
|
|
}
|
|
else
|
|
{
|
|
strMinutes[j++] = buffer[i];
|
|
}
|
|
}
|
|
|
|
GameSetTime((uint8_t)atoi(strHour),(uint8_t)atoi(strMinutes) );
|
|
}
|
|
else
|
|
{
|
|
enum
|
|
{
|
|
MESSAGE_INFO,
|
|
AIRCRAFT_DATA
|
|
} tLine = AIRCRAFT_DATA; // Default value
|
|
TYPE_MESSAGE_DATA tMessage = {0};
|
|
|
|
// File header (initial game time) has already been read
|
|
strncpy(lineBuffer, buffer, LINE_MAX_CHARACTERS);
|
|
|
|
lineBufferPtr = strtok(lineBuffer,";");
|
|
|
|
i = 0;
|
|
|
|
Serial_printf("New line read: %s\n",buffer);
|
|
|
|
while (lineBufferPtr != NULL)
|
|
{
|
|
switch(i)
|
|
{
|
|
enum
|
|
{
|
|
DEPARTURE_ARRIVAL_INDEX = 0,
|
|
FLIGHT_NUMBER_INDEX,
|
|
PASSENGERS_INDEX,
|
|
HOURS_MINUTES_INDEX,
|
|
PARKING_INDEX,
|
|
REMAINING_TIME_INDEX
|
|
};
|
|
|
|
enum
|
|
{
|
|
MESSAGE_HEADER_INDEX = 0,
|
|
MESSAGE_TIMEOUT_INDEX,
|
|
MESSAGE_STR_INDEX
|
|
};
|
|
|
|
//case MESSAGE_HEADER_INDEX:
|
|
// Fall through
|
|
case DEPARTURE_ARRIVAL_INDEX:
|
|
|
|
if (strncmp(lineBufferPtr,"DEPARTURE",strlen("DEPARTURE") ) == 0)
|
|
{
|
|
ptrFlightData->FlightDirection[aircraftIndex] = DEPARTURE;
|
|
Serial_printf("Aircraft %d set to DEPARTURE.\n",aircraftIndex);
|
|
}
|
|
else if (strncmp(lineBufferPtr,"ARRIVAL",strlen("ARRIVAL") ) == 0)
|
|
{
|
|
ptrFlightData->FlightDirection[aircraftIndex] = ARRIVAL;
|
|
Serial_printf("Aircraft %d set to ARRIVAL.\n",aircraftIndex);
|
|
}
|
|
else if (strncmp(lineBufferPtr, MESSAGE_HEADER_STR, strlen(MESSAGE_HEADER_STR) ) == 0)
|
|
{
|
|
tLine = MESSAGE_INFO;
|
|
}
|
|
else
|
|
{
|
|
Serial_printf("Flight direction is not correct!\n");
|
|
}
|
|
break;
|
|
|
|
//case MESSAGE_TIMEOUT_INDEX:
|
|
// Fall through
|
|
case FLIGHT_NUMBER_INDEX:
|
|
|
|
if (tLine == MESSAGE_INFO)
|
|
{
|
|
uint8_t Hours;
|
|
uint8_t Minutes;
|
|
|
|
if ( strlen(lineBufferPtr) != strlen("HH:MM") )
|
|
{
|
|
Serial_printf("Hour minute format is not correct! Read %s\n", lineBufferPtr);
|
|
break;
|
|
}
|
|
|
|
// Copy hour
|
|
strHour[0] = lineBufferPtr[0];
|
|
strHour[1] = lineBufferPtr[1];
|
|
// Copy minutes
|
|
strMinutes[0] = lineBufferPtr[3];
|
|
strMinutes[1] = lineBufferPtr[4];
|
|
|
|
Hours = (uint8_t)atoi(strHour);
|
|
Minutes = (uint8_t)atoi(strMinutes);
|
|
|
|
tMessage.Timeout = (uint32_t)(Hours * 60) + Minutes;
|
|
|
|
Serial_printf("Message timeout: %d seconds.\n", tMessage.Timeout);
|
|
}
|
|
else
|
|
{
|
|
strncpy(ptrFlightData->strFlightNumber[aircraftIndex],lineBufferPtr,GAME_MAX_CHARACTERS);
|
|
ptrFlightData->strFlightNumber[aircraftIndex][GAME_MAX_CHARACTERS - 1] = '\0';
|
|
Serial_printf("Aircraft %d flight number set to %s.\n",aircraftIndex,ptrFlightData->strFlightNumber[aircraftIndex]);
|
|
}
|
|
|
|
break;
|
|
|
|
// case MESSAGE_STR_INDEX:
|
|
// Fall through
|
|
case PASSENGERS_INDEX:
|
|
if (tLine == MESSAGE_INFO)
|
|
{
|
|
strncpy(tMessage.strMessage, lineBufferPtr, MAX_MESSAGE_STR_SIZE);
|
|
MessageCreate(&tMessage);
|
|
|
|
bzero(&tMessage, sizeof (tMessage));
|
|
}
|
|
else
|
|
{
|
|
ptrFlightData->Passengers[aircraftIndex] = atoi(lineBufferPtr);
|
|
Serial_printf("Aircraft %d passengers set to %d.\n",aircraftIndex,ptrFlightData->Passengers[aircraftIndex]);
|
|
}
|
|
break;
|
|
|
|
case PARKING_INDEX:
|
|
if (ptrFlightData->FlightDirection[aircraftIndex] == DEPARTURE)
|
|
{
|
|
ptrFlightData->Parking[aircraftIndex] = atoi(lineBufferPtr);
|
|
}
|
|
else
|
|
{
|
|
ptrFlightData->Parking[aircraftIndex] = 0;
|
|
}
|
|
Serial_printf("Aircraft %d parking set to %d.\n",aircraftIndex,ptrFlightData->Parking[aircraftIndex]);
|
|
break;
|
|
|
|
case HOURS_MINUTES_INDEX:
|
|
if ( strlen(lineBufferPtr) != strlen("HH:MM") )
|
|
{
|
|
Serial_printf("Hour minute format is not correct!\n");
|
|
break;
|
|
}
|
|
|
|
// Copy hour
|
|
strHour[0] = lineBufferPtr[0];
|
|
strHour[1] = lineBufferPtr[1];
|
|
// Copy minutes
|
|
strMinutes[0] = lineBufferPtr[3];
|
|
strMinutes[1] = lineBufferPtr[4];
|
|
|
|
ptrFlightData->Hours[aircraftIndex] = (uint8_t)atoi(strHour);
|
|
ptrFlightData->Minutes[aircraftIndex] = (uint8_t)atoi(strMinutes);
|
|
|
|
Serial_printf("Aircraft %d time set to %02d:%02d.\n", aircraftIndex,
|
|
ptrFlightData->Hours[aircraftIndex],
|
|
ptrFlightData->Minutes[aircraftIndex] );
|
|
break;
|
|
|
|
case REMAINING_TIME_INDEX:
|
|
ptrFlightData->RemainingTime[aircraftIndex] = (uint16_t)atoi(lineBufferPtr);
|
|
Serial_printf("ptrFlightData->RemainingTime[%d] = %d\n", aircraftIndex, ptrFlightData->RemainingTime[aircraftIndex]);
|
|
break;
|
|
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
lineBufferPtr = strtok(NULL,";");
|
|
i++;
|
|
}
|
|
|
|
if (tLine == AIRCRAFT_DATA)
|
|
{
|
|
ptrFlightData->State[aircraftIndex] = STATE_IDLE;
|
|
aircraftIndex++;
|
|
}
|
|
}
|
|
|
|
buffer = strtok_r(NULL,"\n",&pltBufferSavePtr);
|
|
}
|
|
|
|
ptrFlightData->nAircraft = aircraftIndex; //Set total number of aircraft used
|
|
ptrFlightData->ActiveAircraft = 0;
|
|
|
|
Serial_printf("Number of aircraft parsed: %d\n",ptrFlightData->nAircraft);
|
|
|
|
return true;
|
|
}
|
|
|
|
void PltParserResetBuffers(TYPE_FLIGHT_DATA* const ptrFlightData)
|
|
{
|
|
bzero(ptrFlightData, sizeof (TYPE_FLIGHT_DATA));
|
|
#if 0
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < GAME_MAX_AIRCRAFT ; i++)
|
|
{
|
|
memset(ptrFlightData->strFlightNumber[i],'\0',GAME_MAX_CHARACTERS);
|
|
}
|
|
|
|
memset(ptrFlightData->FlightDirection,DEPARTURE,GAME_MAX_AIRCRAFT);
|
|
memset(ptrFlightData->Passengers,0,GAME_MAX_AIRCRAFT);
|
|
memset(ptrFlightData->Hours,0,GAME_MAX_AIRCRAFT);
|
|
memset(ptrFlightData->Minutes,0,GAME_MAX_AIRCRAFT);
|
|
memset(ptrFlightData->State,STATE_IDLE,GAME_MAX_AIRCRAFT);
|
|
memset(ptrFlightData->Parking,0,GAME_MAX_AIRCRAFT);
|
|
memset(ptrFlightData->Finished,0,GAME_MAX_AIRCRAFT);
|
|
#endif
|
|
}
|
|
|
|
uint8_t* PltParserGenerateFile(TYPE_PLT_CONFIG* ptrPltConfig)
|
|
{
|
|
enum
|
|
{
|
|
MIN_AIRCRAFT_TIMELAPSE_MIN_SECONDS_EASY = 3,
|
|
MIN_AIRCRAFT_TIMELAPSE_MAX_SECONDS_EASY = 45,
|
|
MIN_AIRCRAFT_TIMELAPSE_MIN_SECONDS_MEDIUM = 20,
|
|
MIN_AIRCRAFT_TIMELAPSE_MAX_SECONDS_MEDIUM = 30,
|
|
MIN_AIRCRAFT_TIMELAPSE_MIN_SECONDS_HARD = 10,
|
|
MIN_AIRCRAFT_TIMELAPSE_MAX_SECONDS_HARD = 20,
|
|
};
|
|
|
|
enum
|
|
{
|
|
MIN_AIRCRAFT_EASY = 5,
|
|
MAX_AIRCRAFT_EASY = 10,
|
|
MIN_AIRCRAFT_MEDIUM = 10,
|
|
MAX_AIRCRAFT_MEDIUM = GAME_MAX_AIRCRAFT >> 1,
|
|
MIN_AIRCRAFT_HARD = 20,
|
|
MAX_AIRCRAFT_HARD = GAME_MAX_AIRCRAFT,
|
|
};
|
|
|
|
typedef enum t_Hour
|
|
{
|
|
MIN_HOUR = 0,
|
|
MAX_HOUR = 23
|
|
}TYPE_HOUR;
|
|
|
|
typedef enum t_Minute
|
|
{
|
|
MIN_MINUTE = 0,
|
|
MAX_MINUTE = 59
|
|
}TYPE_MINUTE;
|
|
|
|
uint8_t* PltBuffer = SystemGetBufferAddress();
|
|
uint8_t minAircraftTime;
|
|
uint8_t maxAircraftTime;
|
|
uint8_t nAircraft;
|
|
uint8_t i;
|
|
uint8_t j;
|
|
TYPE_HOUR InitialHour;
|
|
TYPE_MINUTE InitialMinutes;
|
|
char auxBuffer[32] = {'\0'};
|
|
|
|
switch(ptrPltConfig->Level)
|
|
{
|
|
case LEVEL_DIFFICULTY_EASY:
|
|
minAircraftTime = MIN_AIRCRAFT_TIMELAPSE_MIN_SECONDS_EASY;
|
|
maxAircraftTime = MIN_AIRCRAFT_TIMELAPSE_MAX_SECONDS_EASY;
|
|
nAircraft = SystemRand(MIN_AIRCRAFT_EASY, MAX_AIRCRAFT_EASY);
|
|
break;
|
|
|
|
case LEVEL_DIFFICULTY_MEDIUM:
|
|
minAircraftTime = MIN_AIRCRAFT_TIMELAPSE_MIN_SECONDS_MEDIUM;
|
|
maxAircraftTime = MIN_AIRCRAFT_TIMELAPSE_MAX_SECONDS_MEDIUM;
|
|
nAircraft = SystemRand(MIN_AIRCRAFT_MEDIUM, MAX_AIRCRAFT_MEDIUM);
|
|
break;
|
|
|
|
case LEVEL_DIFFICULTY_HARD:
|
|
minAircraftTime = MIN_AIRCRAFT_TIMELAPSE_MIN_SECONDS_HARD;
|
|
maxAircraftTime = MIN_AIRCRAFT_TIMELAPSE_MAX_SECONDS_HARD;
|
|
nAircraft = SystemRand(MIN_AIRCRAFT_HARD, MAX_AIRCRAFT_HARD);
|
|
break;
|
|
|
|
default:
|
|
Serial_printf("PltParserGenerateFile(): Undefined level!\n");
|
|
return NULL;
|
|
}
|
|
|
|
#ifndef PSXSDK_DEBUG
|
|
# pragma message ("Remember to remove this")
|
|
printf("%d\n", minAircraftTime);
|
|
printf("%d\n", maxAircraftTime);
|
|
#endif // PSXSDK_DEBUG
|
|
|
|
SystemClearFileBuffer();
|
|
|
|
// At this point, PltBuffer is filled with zeros. Start generating PLT file.
|
|
|
|
InitialHour = SystemRand(MIN_HOUR, MAX_HOUR);
|
|
|
|
InitialMinutes = SystemRand(MIN_MINUTE, MAX_MINUTE);
|
|
|
|
snprintf(auxBuffer, 32, "%d:%d\n", InitialHour, InitialMinutes);
|
|
|
|
for (i = 0; auxBuffer[i] != '\0'; i++)
|
|
{
|
|
// Transfer contents generated from snprintf to main buffer.
|
|
PltBuffer[i] = auxBuffer[i];
|
|
}
|
|
|
|
Serial_printf("%s\n", PltBuffer);
|
|
DEBUG_PRINT_VAR(ptrPltConfig->Level);
|
|
DEBUG_PRINT_VAR(nAircraft);
|
|
DEBUG_PRINT_VAR(minAircraftTime);
|
|
DEBUG_PRINT_VAR(maxAircraftTime);
|
|
|
|
for (j = 0; j < nAircraft; j++)
|
|
{
|
|
uint8_t dep_arr_rand = SystemRand(0,100);
|
|
|
|
if (dep_arr_rand < 50)
|
|
{
|
|
// Set departure flight
|
|
|
|
memmove(&PltBuffer[i], "DEPARTURE", sizeof ("DEPARTURE") * sizeof (uint8_t) );
|
|
i += strlen("DEPARTURE");
|
|
}
|
|
else
|
|
{
|
|
// Set arrival flight
|
|
memmove(&PltBuffer[i], "ARRIVAL", sizeof ("ARRIVAL") * sizeof (uint8_t) );
|
|
i += strlen("ARRIVAL");
|
|
}
|
|
}
|
|
|
|
return PltBuffer;
|
|
}
|