diff options
| author | XaviDCR92 <xavi.dcr@gmail.com> | 2018-01-02 06:43:54 +0100 |
|---|---|---|
| committer | XaviDCR92 <xavi.dcr@gmail.com> | 2018-01-02 06:43:54 +0100 |
| commit | b094335404446183954eb1ccaba33f5f4888eacf (patch) | |
| tree | 14e87f4a12f174dc66cad0ab4010efb2858fdd12 /Source | |
| parent | e53faffaead15f0aa6c323d0b0dbed05eaf5b4d4 (diff) | |
| download | airport-b094335404446183954eb1ccaba33f5f4888eacf.tar.gz | |
* Aircraft.c: taxiing speed has been doubled.
* Game.c: GameRenderLevel() renamed to GameRenderTerrain().
* Game.c: GameRenderTerrainPrecalculations() has been created to perform some calculations which are stored in tables to be then looked up by GameRenderTerrain(). This should save us some calculation time during rendering process.
* Camera.c: added new CameraApplyCoordinatesToCartesianPos() prototype.
* GameGui.c: AircraftDataGPoly4 RGB data is now only calculated on startup.
Diffstat (limited to 'Source')
| -rw-r--r-- | Source/Aircraft.c | 2 | ||||
| -rw-r--r-- | Source/Camera.c | 10 | ||||
| -rw-r--r-- | Source/Camera.h | 5 | ||||
| -rw-r--r-- | Source/Exe/AIRPORT.elf | bin | 327820 -> 330072 bytes | |||
| -rw-r--r-- | Source/Exe/AIRPORT.iso | bin | 1474560 -> 1478656 bytes | |||
| -rw-r--r-- | Source/Game.c | 422 | ||||
| -rw-r--r-- | Source/Game.h | 11 | ||||
| -rw-r--r-- | Source/GameGui.c | 34 | ||||
| -rw-r--r-- | Source/GameStructures.h | 20 | ||||
| -rw-r--r-- | Source/Gfx.c | 16 | ||||
| -rw-r--r-- | Source/Gfx.h | 8 | ||||
| -rw-r--r-- | Source/Makefile | 2 | ||||
| -rw-r--r-- | Source/MapEditor/MapEditor.pro.user | 2 | ||||
| -rw-r--r-- | Source/MapEditor/settings.ini | 2 | ||||
| -rw-r--r-- | Source/Menu.c | 189 |
15 files changed, 488 insertions, 235 deletions
diff --git a/Source/Aircraft.c b/Source/Aircraft.c index 7ecd8af..87685ba 100644 --- a/Source/Aircraft.c +++ b/Source/Aircraft.c @@ -65,7 +65,7 @@ static void* GameFileDest[] = { (GsSprite*)&ArrowSpr }; static uint8_t AircraftFlightDataIdx_HashTable[GAME_MAX_AIRCRAFT];
static const fix16_t AircraftSpeedsTable[] = { [AIRCRAFT_SPEED_IDLE] = 0,
- [AIRCRAFT_SPEED_GROUND] = 0x6666,
+ [AIRCRAFT_SPEED_GROUND] = 0x9999,
[AIRCRAFT_SPEED_TAKEOFF] = 0x20000,
[AIRCRAFT_SPEED_FINAL] = 0x10000,
[AIRCRAFT_SPEED_FINAL_Z] = 0x4000 };
diff --git a/Source/Camera.c b/Source/Camera.c index f55ee4f..d9cd26e 100644 --- a/Source/Camera.c +++ b/Source/Camera.c @@ -40,18 +40,24 @@ void CameraInit(TYPE_PLAYER* ptrPlayer) Camera_Max_Y_Offset = GameGetLevelColumns() * TILE_SIZE_H; } -void CameraApplyCoordinatesToSprite(TYPE_PLAYER* ptrPlayer, GsSprite * spr) +void CameraApplyCoordinatesToSprite(TYPE_PLAYER* ptrPlayer, GsSprite* spr) { spr->x += (short)ptrPlayer->Camera.X_Offset; spr->y += (short)ptrPlayer->Camera.Y_Offset; } -void CameraApplyCoordinatesToRectangle(TYPE_PLAYER* ptrPlayer, GsRectangle * rect) +void CameraApplyCoordinatesToRectangle(TYPE_PLAYER* ptrPlayer, GsRectangle* rect) { rect->x += (short)ptrPlayer->Camera.X_Offset; rect->y += (short)ptrPlayer->Camera.Y_Offset; } +void CameraApplyCoordinatesToCartesianPos(TYPE_PLAYER* ptrPlayer, TYPE_CARTESIAN_POS* pos) +{ + pos->x += (short)ptrPlayer->Camera.X_Offset; + pos->y += (short)ptrPlayer->Camera.Y_Offset; +} + void CameraUpdateSpeed(TYPE_PLAYER* ptrPlayer) { if (ptrPlayer->PadDirectionKeyPressed_Callback() != false) diff --git a/Source/Camera.h b/Source/Camera.h index 9d958ed..d1b4d29 100644 --- a/Source/Camera.h +++ b/Source/Camera.h @@ -15,8 +15,9 @@ * *************************************/ void CameraInit(TYPE_PLAYER* ptrPlayer); void CameraHandler(TYPE_PLAYER* ptrPlayer); -void CameraApplyCoordinatesToSprite(TYPE_PLAYER* ptrPlayer, GsSprite * spr); -void CameraApplyCoordinatesToRectangle(TYPE_PLAYER* ptrPlayer, GsRectangle * rect); +void CameraApplyCoordinatesToSprite(TYPE_PLAYER* ptrPlayer, GsSprite* spr); +void CameraApplyCoordinatesToRectangle(TYPE_PLAYER* ptrPlayer, GsRectangle* rect); +void CameraApplyCoordinatesToCartesianPos(TYPE_PLAYER* ptrPlayer, TYPE_CARTESIAN_POS* pos); TYPE_ISOMETRIC_POS CameraGetIsoPos(TYPE_PLAYER* ptrPlayer); void CameraMoveToIsoPos(TYPE_PLAYER* ptrPlayer, TYPE_ISOMETRIC_POS IsoPos); diff --git a/Source/Exe/AIRPORT.elf b/Source/Exe/AIRPORT.elf Binary files differindex e6ed20b..bae28c4 100644 --- a/Source/Exe/AIRPORT.elf +++ b/Source/Exe/AIRPORT.elf diff --git a/Source/Exe/AIRPORT.iso b/Source/Exe/AIRPORT.iso Binary files differindex 763da1a..7e7b4cf 100644 --- a/Source/Exe/AIRPORT.iso +++ b/Source/Exe/AIRPORT.iso diff --git a/Source/Game.c b/Source/Game.c index 4389e5f..866c6ed 100644 --- a/Source/Game.c +++ b/Source/Game.c @@ -17,7 +17,6 @@ * Defines * *************************************/ -#define GAME_MAX_MAP_SIZE 0x400 #define GAME_MAX_RUNWAYS 16 #define GAME_MAX_AIRCRAFT_PER_TILE 4 #define FLIGHT_DATA_INVALID_IDX 0xFF @@ -60,6 +59,12 @@ typedef struct t_buildingdata short v; // Building Y offset inside texture page }TYPE_BUILDING_DATA; +typedef struct t_GameLevelBuffer_UVData +{ + short u; + short v; +}TYPE_TILE_UV_DATA; + enum { MOUSE_W = 8, @@ -150,9 +155,10 @@ enum * Local Prototypes * *************************************/ -static void GameInit(void); +static void GameInit(TYPE_GAME_CONFIGURATION* pGameCfg); +static void GameInitTileUVTable(void); static bool GameExit(void); -static void GameLoadLevel(void); +static void GameLoadLevel(const char* path); static bool GamePause(void); static void GameFinished(uint8_t i); static void GameEmergencyMode(void); @@ -161,7 +167,8 @@ static void GamePlayerHandler(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFligh static void GamePlayerAddWaypoint(TYPE_PLAYER* ptrPlayer); static void GamePlayerAddWaypoint_Ex(TYPE_PLAYER* ptrPlayer, uint16_t tile); static void GameGraphics(void); -static void GameRenderLevel(TYPE_PLAYER* ptrPlayer); +static void GameRenderTerrainPrecalculations(TYPE_PLAYER* ptrPlayer); +static void GameRenderTerrain(TYPE_PLAYER* ptrPlayer); static void GameClock(void); static void GameClockFlights(uint8_t i); static void GameAircraftState(uint8_t i); @@ -226,6 +233,8 @@ static uint8_t GameAircraftCollisionIdx; static TYPE_BUILDING_DATA GameBuildingData[MAX_BUILDING_ID]; static uint8_t GameAircraftTilemap[GAME_MAX_MAP_SIZE][GAME_MAX_AIRCRAFT_PER_TILE]; +static TYPE_TILE_UV_DATA GameLevelBuffer_UVData[GAME_MAX_MAP_SIZE]; + // Radio chatter static SsVag ApproachSnds[MAX_RADIO_CHATTER_SOUNDS]; static SsVag TowerFinalSnds[MAX_RADIO_CHATTER_SOUNDS]; @@ -263,10 +272,8 @@ static void* GameFileDest[] = { (GsSprite*)&GameTilesetSpr , (GsSprite*)&CityBg1Spr , (SsVag*)&BeepSnd }; -static const char* GamePlt[] = { "cdrom:\\DATA\\LEVELS\\LEVEL2.PLT;1" }; static void* GamePltDest[] = {(TYPE_FLIGHT_DATA*)&FlightData }; -static char* GameLevelList[] = {"cdrom:\\DATA\\LEVELS\\LEVEL2.LVL;1"}; static uint16_t GameLevelBuffer[GAME_MAX_MAP_SIZE]; static uint8_t GameLevelColumns; @@ -286,7 +293,7 @@ bool GameFinishedFlag; /* *************************************************************************************** * - * @name: void Game(bool two_players) + * @name: void Game(TYPE_GAME_CONFIGURATION* pGameCfg) * * @author: Xavier Del Campo * @@ -297,10 +304,10 @@ bool GameFinishedFlag; * * ***************************************************************************************/ -void Game(bool two_players) +void Game(TYPE_GAME_CONFIGURATION* pGameCfg) { - TwoPlayersActive = two_players; - GameInit(); + TwoPlayersActive = pGameCfg->TwoPlayers; + GameInit(pGameCfg); while (1) { @@ -434,7 +441,7 @@ bool GamePause(void) * * ***************************************************************************************/ -void GameInit(void) +void GameInit(TYPE_GAME_CONFIGURATION* pGameCfg) { uint8_t i; uint32_t track; @@ -452,20 +459,20 @@ void GameInit(void) sizeof(GameFileDest) /sizeof(void*) ); } - LoadMenu( GamePlt, + LoadMenu( &pGameCfg->PLTPath, GamePltDest, - sizeof(GamePlt) / sizeof(GamePlt[0]), + sizeof(char), sizeof(GamePltDest) / sizeof(GamePltDest[0]) ); - GameLoadLevel(); + GameLoadLevel(pGameCfg->LVLPath); GameGuiInit(); GameBuildingsInit(); - memset(GameRwy,0,GAME_MAX_RUNWAYS * sizeof(uint16_t) ); + memset(GameRwy, 0, GAME_MAX_RUNWAYS * sizeof(uint16_t) ); - memset(GameUsedRwy,0,GAME_MAX_RUNWAYS * sizeof(uint16_t) ); + memset(GameUsedRwy, 0, GAME_MAX_RUNWAYS * sizeof(uint16_t) ); PlayerData[PLAYER_ONE].Active = true; PlayerData[PLAYER_ONE].PadKeyPressed_Callback = &PadOneKeyPressed; @@ -485,6 +492,7 @@ void GameInit(void) PlayerData[PLAYER_ONE].Unboarding = false; memset(PlayerData[PLAYER_ONE].UnboardingSequence, 0, GAME_MAX_SEQUENCE_KEYS * sizeof(unsigned short) ); + memset(PlayerData[PLAYER_ONE].TileData, 0, GAME_MAX_MAP_SIZE * sizeof(TYPE_TILE_DATA)); PlayerData[PLAYER_TWO].Active = TwoPlayersActive? true : false; @@ -507,6 +515,7 @@ void GameInit(void) PlayerData[PLAYER_TWO].Unboarding = false; memset(PlayerData[PLAYER_TWO].UnboardingSequence, 0, GAME_MAX_SEQUENCE_KEYS * sizeof(unsigned short) ); + memset(PlayerData[PLAYER_TWO].TileData, 0, GAME_MAX_MAP_SIZE * sizeof(TYPE_TILE_DATA)); // On 2-player mode, one player controls departure flights and // other player controls arrival flights. @@ -566,6 +575,8 @@ void GameInit(void) GameFinishedFlag = false; + GameInitTileUVTable(); + AircraftInit(); LoadMenuEnd(); @@ -858,8 +869,6 @@ void GameGetAircraftTilemap(uint8_t i) } GameAircraftTilemap[tileNr][j] = i; - - //Serial_printf("GameAircraftTileMap[%d][%d] = %d\n", tileNr, j, GameAircraftTilemap[tileNr][j]); } /* *************************************************************************************** @@ -953,6 +962,7 @@ void GamePlayerHandler(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData) GameStateSelectTaxiwayParking(ptrPlayer, ptrFlightData); GameStateShowAircraft(ptrPlayer, ptrFlightData); CameraHandler(ptrPlayer); + GameRenderTerrainPrecalculations(ptrPlayer); GameGuiActiveAircraftPage(ptrPlayer, ptrFlightData); GameSelectAircraftFromList(ptrPlayer, ptrFlightData); } @@ -1095,7 +1105,7 @@ void GameGraphics(void) // Then ground tiles must be rendered. - GameRenderLevel(ptrPlayer); + GameRenderTerrain(ptrPlayer); // Ground tiles are now rendered. Now, depending on building/aircraft // positions, determine in what order they should be rendered. @@ -1426,7 +1436,7 @@ void GameRenderBuildingAircraft(TYPE_PLAYER* ptrPlayer) * * *******************************************************************/ -void GameLoadLevel(void) +void GameLoadLevel(const char* path) { uint8_t i = 0; uint8_t* ptrBuffer; @@ -1437,7 +1447,7 @@ void GameLoadLevel(void) // Header treatment (magic number, map size, map title...) should be done // using System's file buffer. - if (SystemLoadFile(GameLevelList[0]) == false) + if (SystemLoadFile((char*)path) == false) { return; } @@ -1601,9 +1611,25 @@ void GameAircraftState(uint8_t i) } } +void GameInitTileUVTable(void) +{ + uint16_t i; + + memset(GameLevelBuffer_UVData, 0, sizeof(GameLevelBuffer_UVData)); + + for (i = 0 ; i < GameLevelSize; i++) + { + uint8_t CurrentTile = (uint8_t)(GameLevelBuffer[i] & 0x007F); // Remove building data + // and mirror flag. + + GameLevelBuffer_UVData[i].u = (short)(CurrentTile % COLUMNS_PER_TILESET) << TILE_SIZE_BIT_SHIFT; + GameLevelBuffer_UVData[i].v = (short)(CurrentTile / COLUMNS_PER_TILESET) * TILE_SIZE_H; + } +} + /* ****************************************************************************************** * - * @name: void GameRenderLevel(TYPE_PLAYER* ptrPlayer) + * @name: void GameRenderTerrainPrecalculations(TYPE_PLAYER* ptrPlayer) * * @author: Xavier Del Campo * @@ -1611,43 +1637,41 @@ void GameAircraftState(uint8_t i) * TYPE_PLAYER* ptrPlayer: * Pointer to a player structure * - * * @brief: - * Draws all tiles depending on GameLevelBuffer configuration. + * Reads current player states, precalculates RGB/XY/visibilty data and saves it into + * lookup tables which will be then used on GameRenderTerrain(). * * @remarks: * Tiles are usually rendered with normal RGB values unless parking/runway is busy * or ptrPlayer->InvalidPath != false. * * ******************************************************************************************/ -void GameRenderLevel(TYPE_PLAYER* ptrPlayer) +void GameRenderTerrainPrecalculations(TYPE_PLAYER* ptrPlayer) { - uint16_t i; - uint8_t columns = 0; - uint8_t rows = 0; - bool flip_id; - bool used_rwy = SystemContains_u16(ptrPlayer->RwyArray[0], GameUsedRwy, GAME_MAX_RUNWAYS); - uint8_t aux_id; - GsSprite * ptrTileset; - unsigned char rwy_sine = SystemGetSineValue(); - TYPE_ISOMETRIC_POS tileIsoPos; - TYPE_CARTESIAN_POS tileCartPos; + uint16_t i; + uint8_t rows = 0; + uint8_t columns = 0; + unsigned char rwy_sine = SystemGetSineValue(); + bool used_rwy = SystemContains_u16(ptrPlayer->RwyArray[0], GameUsedRwy, GAME_MAX_RUNWAYS); - for (i = 0 ; i < GameLevelSize; i++) + for (i = 0 ; i < GameLevelSize; i++) { - // GameLevelBuffer bits explanation: - // X X X X X X X X X X X X X X X X - // | | | | | | | | | | | | | | | | - // | | | | | | | | | | | | | | | V - // | | | | | | | | | | | | | | V Tile, bit 0 - // | | | | | | | | | | | | | V Tile, bit 1 - // | | | | | | | | | | | | V Tile, bit 2 - // | | | | | | | | | | | V Tile, bit 3 - // | | | | | | | | | | V Tile, bit 4 - // | | | | | | | | | V Tile, bit 5 - // | | | | | | | | V Tile, bit 6 - // | | | | | | | V Tile mirror flag - // | | | | | | V Building, bit 0 + TYPE_ISOMETRIC_POS tileIsoPos; + + // GameLevelBuffer bits explanation: + // X X X X X X X X X X X X X X X X + // | | | | | | | | | | | | | | | | + // | | | | | | | | | | | | | | | V + // | | | | | | | | | | | | | | V Tile, bit 0 + // | | | | | | | | | | | | | V Tile, bit 1 + // | | | | | | | | | | | | V Tile, bit 2 + // | | | | | | | | | | | V Tile, bit 3 + // | | | | | | | | | | V Tile, bit 4 + // | | | | | | | | | V Tile, bit 5 + // | | | | | | | | V Tile, bit 6 + // | | | | | | | | Tile mirror flag + // | | | | | | | V + // | | | | | | V Building, bit 0 // | | | | | V Building, bit 1 // | | | | V Building, bit 2 // | | | V Building, bit 3 @@ -1655,65 +1679,17 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer) // | V Building, bit 5 // V Building, bit 6 // Building, bit 7 - - uint8_t CurrentTile = (uint8_t)(GameLevelBuffer[i] & 0x00FF); + uint8_t CurrentTile = (uint8_t)(GameLevelBuffer[i] & 0x007F); // Remove building data + // and mirror flag. // Isometric -> Cartesian conversion tileIsoPos.x = columns << (TILE_SIZE_BIT_SHIFT); tileIsoPos.y = rows << (TILE_SIZE_BIT_SHIFT); tileIsoPos.z = 0; - tileCartPos = GfxIsometricToCartesian(&tileIsoPos); + ptrPlayer->TileData[i].CartPos = GfxIsometricToCartesian(&tileIsoPos); - // Flipped tiles have bit 7 set. - if (CurrentTile & TILE_MIRROR_FLAG) - { - flip_id = true; - aux_id = CurrentTile; - CurrentTile &= ~(TILE_MIRROR_FLAG); - } - else - { - flip_id = false; - } - - if (CurrentTile <= LAST_TILE_TILESET1) - { - // Draw using GameTilesetSpr - ptrTileset = &GameTilesetSpr; - } - else if ( (CurrentTile > LAST_TILE_TILESET1) - && - (CurrentTile <= LAST_TILE_TILESET2) ) - { - // Draw using GameTileset2Spr - ptrTileset = &GameTileset2Spr; - } - else - { - ptrTileset = NULL; - - continue; - -// if (flip_id == false) -// { -// continue; -// } - } - - ptrTileset->w = TILE_SIZE; - ptrTileset->h = TILE_SIZE_H; - - ptrTileset->x = tileCartPos.x; - ptrTileset->y = tileCartPos.y; - - // Set coordinate origin to left upper corner - ptrTileset->x -= TILE_SIZE >> 1; - //ptrTileset->y -= TILE_SIZE_H >> 2; - - CameraApplyCoordinatesToSprite(ptrPlayer, ptrTileset); - - if (columns < (GameLevelColumns - 1) ) + if (columns < (GameLevelColumns - 1) ) { columns++; } @@ -1723,14 +1699,25 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer) columns = 0; } - if (GfxIsSpriteInsideScreenArea(ptrTileset) == false) - { - continue; - } + // Set coordinate origin to left upper corner. + ptrPlayer->TileData[i].CartPos.x -= TILE_SIZE >> 1; + + CameraApplyCoordinatesToCartesianPos(ptrPlayer, &ptrPlayer->TileData[i].CartPos); + + if (GfxIsInsideScreenArea( ptrPlayer->TileData[i].CartPos.x, + ptrPlayer->TileData[i].CartPos.y, + TILE_SIZE, + TILE_SIZE_H ) == false) + { + ptrPlayer->TileData[i].ShowTile = false; + continue; + } + + ptrPlayer->TileData[i].ShowTile = true; - ptrTileset->r = NORMAL_LUMINANCE; - ptrTileset->g = NORMAL_LUMINANCE; - ptrTileset->b = NORMAL_LUMINANCE; + ptrPlayer->TileData[i].r = NORMAL_LUMINANCE; + ptrPlayer->TileData[i].g = NORMAL_LUMINANCE; + ptrPlayer->TileData[i].b = NORMAL_LUMINANCE; if (i != 0) { @@ -1740,15 +1727,15 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer) { if (used_rwy != false) { - ptrTileset->r = rwy_sine; - ptrTileset->b = NORMAL_LUMINANCE >> 2; - ptrTileset->g = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].r = rwy_sine; + ptrPlayer->TileData[i].b = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].g = NORMAL_LUMINANCE >> 2; } else { - ptrTileset->r = NORMAL_LUMINANCE >> 2; - ptrTileset->g = NORMAL_LUMINANCE >> 2; - ptrTileset->b = rwy_sine; + ptrPlayer->TileData[i].r = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].g = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].b = rwy_sine; } } } @@ -1756,7 +1743,7 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer) || (ptrPlayer->SelectTaxiwayRunway != false) ) { - if (( (SystemContains_u16(i, ptrPlayer->Waypoints, PLAYER_MAX_WAYPOINTS) != false) + if (( (SystemContains_u16(i, ptrPlayer->Waypoints, ptrPlayer->WaypointIdx) != false) || (i == ptrPlayer->SelectedTile) ) && @@ -1764,15 +1751,15 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer) { if (ptrPlayer->InvalidPath != false) { - ptrTileset->r = rwy_sine; - ptrTileset->b = NORMAL_LUMINANCE >> 2; - ptrTileset->g = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].r = rwy_sine; + ptrPlayer->TileData[i].b = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].g = NORMAL_LUMINANCE >> 2; } else { - ptrTileset->r = NORMAL_LUMINANCE >> 2; - ptrTileset->g = NORMAL_LUMINANCE >> 2; - ptrTileset->b = rwy_sine; + ptrPlayer->TileData[i].r = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].g = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].b = rwy_sine; } } else if ( (ptrPlayer->SelectTaxiwayRunway != false) @@ -1781,9 +1768,9 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer) || (CurrentTile == TILE_RWY_HOLDING_POINT_2) ) ) { - ptrTileset->r = NORMAL_LUMINANCE >> 2; - ptrTileset->g = rwy_sine; - ptrTileset->b = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].r = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].g = rwy_sine; + ptrPlayer->TileData[i].b = NORMAL_LUMINANCE >> 2; } else if ( (ptrPlayer->SelectTaxiwayParking != false) && @@ -1791,39 +1778,114 @@ void GameRenderLevel(TYPE_PLAYER* ptrPlayer) || (CurrentTile == TILE_PARKING_2) ) ) { - ptrTileset->r = NORMAL_LUMINANCE >> 2; - ptrTileset->g = rwy_sine; - ptrTileset->b = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].r = NORMAL_LUMINANCE >> 2; + ptrPlayer->TileData[i].g = rwy_sine; + ptrPlayer->TileData[i].b = NORMAL_LUMINANCE >> 2; } } } + } +} - if (ptrTileset != NULL) - { - if (flip_id != false) - { - ptrTileset->attribute |= H_FLIP; - } - } +/* ****************************************************************************************** + * + * @name: void GameRenderTerrain(TYPE_PLAYER* ptrPlayer) + * + * @author: Xavier Del Campo + * + * @param: + * TYPE_PLAYER* ptrPlayer: + * Pointer to a player structure + * + * + * @brief: + * Draws all tiles depending on GameLevelBuffer configuration. + * + * @remarks: + * Tiles are usually rendered with normal RGB values unless parking/runway is busy + * or ptrPlayer->InvalidPath != false. + * + * ******************************************************************************************/ +void GameRenderTerrain(TYPE_PLAYER* ptrPlayer) +{ + uint16_t i; + uint8_t aux_id; - ptrTileset->u = (short)(CurrentTile % COLUMNS_PER_TILESET) << TILE_SIZE_BIT_SHIFT; - ptrTileset->v = (short)(CurrentTile / COLUMNS_PER_TILESET) * TILE_SIZE_H; + for (i = 0 ; i < GameLevelSize; i++) + { + if (ptrPlayer->TileData[i].ShowTile != false) + { + bool flip_id; + GsSprite* ptrTileset; - ptrTileset->mx = ptrTileset->u + (TILE_SIZE >> 1); - ptrTileset->my = ptrTileset->v + (TILE_SIZE_H >> 1); + uint8_t CurrentTile = (uint8_t)(GameLevelBuffer[i] & 0x00FF); - if (flip_id != false) - { - flip_id = false; - CurrentTile = aux_id; - } + // Flipped tiles have bit 7 set. + if (CurrentTile & TILE_MIRROR_FLAG) + { + flip_id = true; + aux_id = CurrentTile; + CurrentTile &= ~(TILE_MIRROR_FLAG); + } + else + { + flip_id = false; + } - GfxSortSprite(ptrTileset); + if (CurrentTile <= LAST_TILE_TILESET1) + { + // Draw using GameTilesetSpr + ptrTileset = &GameTilesetSpr; + } + else if ( (CurrentTile > LAST_TILE_TILESET1) + && + (CurrentTile <= LAST_TILE_TILESET2) ) + { + // Draw using GameTileset2Spr + ptrTileset = &GameTileset2Spr; + } + else + { + ptrTileset = NULL; + continue; + } - if (ptrTileset->attribute & H_FLIP) - { - ptrTileset->attribute &= ~(H_FLIP); - } + // Apply {X, Y} data from precalculated lookup tables. + ptrTileset->x = ptrPlayer->TileData[i].CartPos.x; + ptrTileset->y = ptrPlayer->TileData[i].CartPos.y; + + // Apply RGB data from precalculated lookup tables. + ptrTileset->r = ptrPlayer->TileData[i].r; + ptrTileset->g = ptrPlayer->TileData[i].g; + ptrTileset->b = ptrPlayer->TileData[i].b; + + if (flip_id != false) + { + ptrTileset->attribute |= H_FLIP; + } + + ptrTileset->w = TILE_SIZE; + ptrTileset->h = TILE_SIZE_H; + + ptrTileset->u = GameLevelBuffer_UVData[i].u; + ptrTileset->v = GameLevelBuffer_UVData[i].v; + + ptrTileset->mx = ptrTileset->u + (TILE_SIZE >> 1); + ptrTileset->my = ptrTileset->v + (TILE_SIZE_H >> 1); + + if (flip_id != false) + { + flip_id = false; + CurrentTile = aux_id; + } + + GfxSortSprite(ptrTileset); + + if (ptrTileset->attribute & H_FLIP) + { + ptrTileset->attribute &= ~(H_FLIP); + } + } } } @@ -2124,7 +2186,6 @@ void GameStateSelectTaxiwayRunway(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrF * @remarks: * * **************************************************************************************************/ - void GameStateSelectTaxiwayParking(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData) { TYPE_ISOMETRIC_POS IsoPos = CameraGetIsoPos(ptrPlayer); @@ -2232,7 +2293,6 @@ void GameStateSelectTaxiwayParking(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptr * @remarks: * * **************************************************************************************************/ - void GameStateSelectRunway(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData) { uint8_t i; @@ -2323,7 +2383,6 @@ void GameStateSelectRunway(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightDa * Do not confuse GameRwy with GameRwyArray, which are used for completely different purposes. * * **************************************************************************************************/ - void GameGetRunwayArray(void) { uint16_t i; @@ -2484,11 +2543,6 @@ void GameSelectAircraftFromList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFli * **************************************************************************************************/ DIRECTION GameGetParkingDirection(uint16_t parkingTile) { - DEBUG_PRINT_VAR(parkingTile); - DEBUG_PRINT_VAR(TILE_PARKING); - DEBUG_PRINT_VAR(TILE_PARKING | TILE_MIRROR_FLAG); - DEBUG_PRINT_VAR(TILE_PARKING_2); - DEBUG_PRINT_VAR(TILE_PARKING_2 | TILE_MIRROR_FLAG); switch (parkingTile) { case TILE_PARKING: @@ -2602,6 +2656,7 @@ void GameGetSelectedRunwayArray(uint16_t rwyHeader, uint16_t* rwyArray, size_t s if (dir == NO_DIRECTION) { + Serial_printf("rwyHeader = %d returned NO_DIRECTION\n", rwyHeader); return; } } @@ -2651,6 +2706,7 @@ void GameGetSelectedRunwayArray(uint16_t rwyHeader, uint16_t* rwyArray, size_t s // Fall through default: Serial_printf("Invalid runway direction.\n"); + DEBUG_PRINT_VAR(rwyHeader); return; } @@ -2761,7 +2817,7 @@ void GameAssignRunwaytoAircraft(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFli } else if (ptrFlightData->State[aircraftIndex] == STATE_HOLDING_RWY) { - TYPE_RWY_ENTRY_DATA rwyEntryData; + TYPE_RWY_ENTRY_DATA rwyEntryData = {0}; GameGetRunwayEntryTile(aircraftIndex, &rwyEntryData); @@ -3624,22 +3680,18 @@ void GameCreateTakeoffWaypoints(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFli switch(aircraftDir) { case DIR_EAST: - //Serial_printf("EAST\n"); rwyStep = 1; break; case DIR_WEST: - //Serial_printf("WEST\n"); rwyStep = -1; break; case DIR_NORTH: - //Serial_printf("NORTH\n"); rwyStep = -GameLevelColumns; break; case DIR_SOUTH: - //Serial_printf("SOUTH\n"); rwyStep = GameLevelColumns; break; @@ -3648,9 +3700,9 @@ void GameCreateTakeoffWaypoints(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFli } for (currentTile = (AircraftGetTileFromFlightDataIndex(aircraftIdx) + rwyStep); - (GameLevelBuffer[currentTile] != TILE_RWY_START_1) + ((GameLevelBuffer[currentTile] & ~(TILE_MIRROR_FLAG)) != TILE_RWY_START_1) && - (GameLevelBuffer[currentTile] != TILE_RWY_START_2); + ((GameLevelBuffer[currentTile] & ~(TILE_MIRROR_FLAG)) != TILE_RWY_START_2); currentTile -= rwyStep ) { // Calculate new currentTile value until conditions are invalid. @@ -3665,9 +3717,9 @@ void GameCreateTakeoffWaypoints(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFli } } - for (currentTile = (AircraftGetTileFromFlightDataIndex(aircraftIdx) + rwyStep); - GameLevelBuffer[currentTile] != TILE_RWY_EXIT; - currentTile += rwyStep ) + for ( currentTile = (AircraftGetTileFromFlightDataIndex(aircraftIdx) + rwyStep); + (GameLevelBuffer[currentTile] & ~(TILE_MIRROR_FLAG)) != TILE_RWY_EXIT; + currentTile += rwyStep ) { } @@ -3699,7 +3751,7 @@ void GameCreateTakeoffWaypoints(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFli void GameGetRunwayEntryTile(uint8_t aircraftIdx, TYPE_RWY_ENTRY_DATA* ptrRwyEntry) { // Look for aircraft direction by searching TILE_RWY_EXIT - uint16_t currentTile = AircraftGetTileFromFlightDataIndex(aircraftIdx); + uint16_t currentTile = AircraftGetTileFromFlightDataIndex(aircraftIdx) & (uint16_t)~(TILE_MIRROR_FLAG); int16_t step = 0; uint16_t i; @@ -3707,28 +3759,36 @@ void GameGetRunwayEntryTile(uint8_t aircraftIdx, TYPE_RWY_ENTRY_DATA* ptrRwyEntr && ( (currentTile + GameLevelColumns) < GameLevelSize) ) { - if (GameLevelBuffer[currentTile + 1] == TILE_RWY_EXIT) + if ( ((GameLevelBuffer[currentTile + 1] & ~(TILE_MIRROR_FLAG)) == TILE_RWY_EXIT) + || + ((GameLevelBuffer[currentTile + 1] & ~(TILE_MIRROR_FLAG)) == TILE_RWY_EXIT_2) ) { ptrRwyEntry->Direction = DIR_EAST; ptrRwyEntry->rwyStep = GameLevelColumns; - step = -1; + step = 1; } - else if (GameLevelBuffer[currentTile - 1] == TILE_RWY_EXIT) + else if ( ((GameLevelBuffer[currentTile - 1] & ~(TILE_MIRROR_FLAG) ) == TILE_RWY_EXIT) + || + ((GameLevelBuffer[currentTile - 1] & ~(TILE_MIRROR_FLAG)) == TILE_RWY_EXIT_2) ) { ptrRwyEntry->Direction = DIR_WEST; - ptrRwyEntry->rwyStep = -GameLevelColumns; - step = 1; + ptrRwyEntry->rwyStep = GameLevelColumns; + step = -1; } - else if (GameLevelBuffer[currentTile + GameLevelColumns] == TILE_RWY_EXIT) + else if ( ((GameLevelBuffer[currentTile + GameLevelColumns] & ~(TILE_MIRROR_FLAG)) == TILE_RWY_EXIT) + || + ((GameLevelBuffer[currentTile + GameLevelColumns] & ~(TILE_MIRROR_FLAG)) == TILE_RWY_EXIT_2) ) { ptrRwyEntry->Direction = DIR_SOUTH; ptrRwyEntry->rwyStep = 1; step = GameLevelColumns; } - else if (GameLevelBuffer[currentTile - GameLevelColumns] == TILE_RWY_EXIT) + else if ( ((GameLevelBuffer[currentTile - GameLevelColumns] & ~(TILE_MIRROR_FLAG)) == TILE_RWY_EXIT) + || + ((GameLevelBuffer[currentTile - GameLevelColumns] & ~(TILE_MIRROR_FLAG)) == TILE_RWY_EXIT_2) ) { ptrRwyEntry->Direction = DIR_NORTH; - ptrRwyEntry->rwyStep = -1; + ptrRwyEntry->rwyStep = 1; step = -GameLevelColumns; } else @@ -3736,7 +3796,7 @@ void GameGetRunwayEntryTile(uint8_t aircraftIdx, TYPE_RWY_ENTRY_DATA* ptrRwyEntr ptrRwyEntry->rwyEntryTile = 0; ptrRwyEntry->Direction = NO_DIRECTION; ptrRwyEntry->rwyStep = 0; - Serial_printf("GameCreateTakeoffWaypoints(): could not determine aircraft direction.\n"); + Serial_printf("GameGetRunwayEntryTile(): could not determine aircraft direction.\n"); return; } @@ -3744,24 +3804,26 @@ void GameGetRunwayEntryTile(uint8_t aircraftIdx, TYPE_RWY_ENTRY_DATA* ptrRwyEntr i = ptrRwyEntry->rwyEntryTile; - while ( (GameLevelBuffer[i] != TILE_RWY_START_1) + while ( ((GameLevelBuffer[i] & ~TILE_MIRROR_FLAG) != TILE_RWY_START_1) && - (GameLevelBuffer[i] != TILE_RWY_START_2) + ((GameLevelBuffer[i] & ~TILE_MIRROR_FLAG) != TILE_RWY_START_2) && (i > ptrRwyEntry->rwyStep) && ((i - ptrRwyEntry->rwyStep) < GameLevelSize ) ) { + DEBUG_PRINT_VAR(i); i -= ptrRwyEntry->rwyStep; } ptrRwyEntry->rwyHeader = i; - DEBUG_PRINT_VAR(ptrRwyEntry->rwyHeader); + DEBUG_PRINT_VAR(ptrRwyEntry->rwyHeader); + DEBUG_PRINT_VAR(ptrRwyEntry->rwyEntryTile); } else { - Serial_printf("GameCreateTakeoffWaypoints(): Invalid index for tile.\n"); + Serial_printf("GameGetRunwayEntryTile(): Invalid index for tile.\n"); } } diff --git a/Source/Game.h b/Source/Game.h index b5a191e..fce2fb1 100644 --- a/Source/Game.h +++ b/Source/Game.h @@ -21,6 +21,14 @@ /* ************************************* * Structs and enums * *************************************/ + +typedef struct t_gameConfiguration +{ + bool TwoPlayers; + const char* LVLPath; + const char* PLTPath; +}TYPE_GAME_CONFIGURATION; + /* ************************************* * Global variables * *************************************/ @@ -29,7 +37,8 @@ extern bool GameStartupFlag; /* ************************************* * Global prototypes * *************************************/ -void Game(bool two_players); + +void Game(TYPE_GAME_CONFIGURATION* pGameCfg); void GameSetTime(uint8_t hour, uint8_t minutes); bool GameTwoPlayersActive(void); uint8_t GameGetLevelColumns(void); diff --git a/Source/GameGui.c b/Source/GameGui.c index ec40b1a..bda17c2 100644 --- a/Source/GameGui.c +++ b/Source/GameGui.c @@ -301,6 +301,23 @@ void GameGuiInit(void) ShowAircraftPassengersTimer = TimerCreate(20, true, GameGuiClearPassengersLeft);
+ // Prepare RGB data and (X,Y) coordinates for aircraft
+ // data list request rectangle.
+ AircraftDataGPoly4.r[0] = AIRCRAFT_DATA_GSGPOLY4_R0;
+ AircraftDataGPoly4.r[1] = AIRCRAFT_DATA_GSGPOLY4_R1;
+ AircraftDataGPoly4.r[2] = AIRCRAFT_DATA_GSGPOLY4_R2;
+ AircraftDataGPoly4.r[3] = AIRCRAFT_DATA_GSGPOLY4_R3;
+
+ AircraftDataGPoly4.g[0] = AIRCRAFT_DATA_GSGPOLY4_G0;
+ AircraftDataGPoly4.g[1] = AIRCRAFT_DATA_GSGPOLY4_G1;
+ AircraftDataGPoly4.g[2] = AIRCRAFT_DATA_GSGPOLY4_G2;
+ AircraftDataGPoly4.g[3] = AIRCRAFT_DATA_GSGPOLY4_G3;
+
+ AircraftDataGPoly4.b[0] = AIRCRAFT_DATA_GSGPOLY4_B0;
+ AircraftDataGPoly4.b[1] = AIRCRAFT_DATA_GSGPOLY4_B1;
+ AircraftDataGPoly4.b[2] = AIRCRAFT_DATA_GSGPOLY4_B2;
+ AircraftDataGPoly4.b[3] = AIRCRAFT_DATA_GSGPOLY4_B3;
+
slowScore = 0;
GameGuiBubbleShowFlag = false;
@@ -461,23 +478,6 @@ void GameGuiAircraftList(TYPE_PLAYER* ptrPlayer, TYPE_FLIGHT_DATA* ptrFlightData if (ptrPlayer->ShowAircraftData != false)
{
- // Prepare RGB data and (X,Y) coordinates for aircraft
- // data list request rectangle.
- AircraftDataGPoly4.r[0] = AIRCRAFT_DATA_GSGPOLY4_R0;
- AircraftDataGPoly4.r[1] = AIRCRAFT_DATA_GSGPOLY4_R1;
- AircraftDataGPoly4.r[2] = AIRCRAFT_DATA_GSGPOLY4_R2;
- AircraftDataGPoly4.r[3] = AIRCRAFT_DATA_GSGPOLY4_R3;
-
- AircraftDataGPoly4.g[0] = AIRCRAFT_DATA_GSGPOLY4_G0;
- AircraftDataGPoly4.g[1] = AIRCRAFT_DATA_GSGPOLY4_G1;
- AircraftDataGPoly4.g[2] = AIRCRAFT_DATA_GSGPOLY4_G2;
- AircraftDataGPoly4.g[3] = AIRCRAFT_DATA_GSGPOLY4_G3;
-
- AircraftDataGPoly4.b[0] = AIRCRAFT_DATA_GSGPOLY4_B0;
- AircraftDataGPoly4.b[1] = AIRCRAFT_DATA_GSGPOLY4_B1;
- AircraftDataGPoly4.b[2] = AIRCRAFT_DATA_GSGPOLY4_B2;
- AircraftDataGPoly4.b[3] = AIRCRAFT_DATA_GSGPOLY4_B3;
-
AircraftDataGPoly4.attribute |= ENABLE_TRANS | TRANS_MODE(0);
if (GameTwoPlayersActive() != false)
diff --git a/Source/GameStructures.h b/Source/GameStructures.h index 115255f..17fee7a 100644 --- a/Source/GameStructures.h +++ b/Source/GameStructures.h @@ -9,6 +9,7 @@ #define GAME_MAX_CHARACTERS 8
#define GAME_MAX_PARKING 32
#define GAME_MAX_RWY_LENGTH 16
+#define GAME_MAX_MAP_SIZE 0x400
#define CHEAT_ARRAY_SIZE 16
#define AIRCRAFT_MAX_TARGETS 48
#define PLAYER_MAX_WAYPOINTS AIRCRAFT_MAX_TARGETS
@@ -78,6 +79,15 @@ typedef struct t_cartpos short y;
}TYPE_CARTESIAN_POS;
+typedef struct t_tileData
+{ + bool ShowTile;
+ TYPE_CARTESIAN_POS CartPos;
+ unsigned char r;
+ unsigned char g;
+ unsigned char b; +}TYPE_TILE_DATA;
+
typedef struct t_flightData
{
FL_DIR FlightDirection[GAME_MAX_AIRCRAFT];
@@ -192,14 +202,20 @@ typedef struct uint8_t UnboardingSequenceIdx;
// Show passengers left
uint8_t PassengersLeftSelectedAircraft;
+ // Lookup tables defined on GameRenderTerrainPrecalculations() to be later used on
+ // GameRenderTerrain().
+ TYPE_TILE_DATA TileData[GAME_MAX_MAP_SIZE];
+ // Player camera instance.
+ TYPE_CAMERA Camera;
+ // Array of tiles which will change their RGB values when displayed under certain player states.
+ uint16_t RwyArray[GAME_MAX_RWY_LENGTH];
+ // Pad callbacks.
bool (*PadKeyPressed_Callback)(unsigned short);
bool (*PadKeyReleased_Callback)(unsigned short);
bool (*PadKeySinglePress_Callback)(unsigned short);
bool (*PadDirectionKeyPressed_Callback)(void);
unsigned short (*PadLastKeySinglePressed_Callback)(void);
- TYPE_CAMERA Camera;
- uint16_t RwyArray[GAME_MAX_RWY_LENGTH];
}TYPE_PLAYER;
typedef enum t_fontflags
diff --git a/Source/Gfx.c b/Source/Gfx.c index 42ea352..879ec37 100644 --- a/Source/Gfx.c +++ b/Source/Gfx.c @@ -309,7 +309,7 @@ void GfxDrawScene_Slow(void) /* ********************************************************************** * - * @name: void GfxSortSprite(GsSprite * spr) + * @name: void GfxSortSprite(GsSprite* spr) * * @author: Xavier Del Campo * @@ -323,7 +323,7 @@ void GfxDrawScene_Slow(void) * if you need to skip this check. * * **********************************************************************/ -void GfxSortSprite(GsSprite * spr) +void GfxSortSprite(GsSprite* spr) { uint8_t aux_r = spr->r; uint8_t aux_g = spr->g; @@ -423,7 +423,7 @@ void GfxSortSprite(GsSprite * spr) /* ********************************************************************** * - * @name: void GfxSortSprite(GsSprite * spr) + * @name: void GfxSortSprite(GsSprite* spr) * * @author: Xavier Del Campo * @@ -512,7 +512,7 @@ bool GfxIsGPUBusy(void) /* ********************************************************************** * - * @name: bool GfxSpriteFromFile(char* fname, GsSprite * spr) + * @name: bool GfxSpriteFromFile(char* fname, GsSprite* spr) * * @author: Xavier Del Campo * @@ -524,7 +524,7 @@ bool GfxIsGPUBusy(void) * false if an error happened, true otherwise. * * **********************************************************************/ -bool GfxSpriteFromFile(char* fname, GsSprite * spr) +bool GfxSpriteFromFile(char* fname, GsSprite* spr) { GsImage gsi; @@ -611,7 +611,7 @@ bool GfxIsInsideScreenArea(short x, short y, short w, short h) /* ********************************************************************** * - * @name: bool GfxIsSpriteInsideScreenArea(GsSprite * spr) + * @name: bool GfxIsSpriteInsideScreenArea(GsSprite* spr) * * @author: Xavier Del Campo * @@ -619,7 +619,7 @@ bool GfxIsInsideScreenArea(short x, short y, short w, short h) * true if sprite is inside screen area, false otherwise. * * **********************************************************************/ -bool GfxIsSpriteInsideScreenArea(GsSprite * spr) +bool GfxIsSpriteInsideScreenArea(GsSprite* spr) { return GfxIsInsideScreenArea(spr->x, spr->y, spr->w, spr->h); } @@ -809,7 +809,7 @@ bool Gfx2HzFlash(void) return five_hundred_ms_show; } -bool GfxTPageOffsetFromVRAMPosition(GsSprite * spr, short x, short y) +bool GfxTPageOffsetFromVRAMPosition(GsSprite* spr, short x, short y) { if ( (x >= VRAM_W) || (x < 0) || (y >= VRAM_H) || (y < 0) ) { diff --git a/Source/Gfx.h b/Source/Gfx.h index 48cc2db..1f8111e 100644 --- a/Source/Gfx.h +++ b/Source/Gfx.h @@ -51,7 +51,7 @@ void GfxDrawScene_Fast(void); bool GfxReadyForDMATransfer(void); // Fills a GsSprite structure with information from a TIM file. -bool GfxSpriteFromFile(char* fname, GsSprite * spr); +bool GfxSpriteFromFile(char* fname, GsSprite* spr); // Reportedly, loads CLUT data from a TIM image (image data is discarded) bool GfxCLUTFromFile(char* fname); @@ -60,14 +60,14 @@ bool GfxCLUTFromFile(char* fname); bool GfxIsInsideScreenArea(short x, short y, short w, short h); // Function overload for GsSprite structures. -bool GfxIsSpriteInsideScreenArea(GsSprite * spr); +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); +void GfxSortSprite(GsSprite* spr); uint8_t GfxGetGlobalLuminance(void); @@ -97,7 +97,7 @@ 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); +bool GfxTPageOffsetFromVRAMPosition(GsSprite* spr, short x, short y); void GfxSetSplitScreen(uint8_t playerIndex); diff --git a/Source/Makefile b/Source/Makefile index 667d415..6d906ad 100644 --- a/Source/Makefile +++ b/Source/Makefile @@ -76,7 +76,7 @@ SOUND_OBJECTS = $(addprefix $(OBJ_SOUNDS_DIR)/, BELL.VAG \ # Level objects: SRC_LEVELS_DIR = $(PROJECT_DIR)/Levels OBJ_LEVELS_DIR = $(CDROM_ROOT)/DATA/LEVELS -LEVEL_OBJECTS = $(addprefix $(OBJ_LEVELS_DIR)/, LEVEL1.LVL LEVEL2.LVL LEVEL2.PLT LEVEL1.PLT) +LEVEL_OBJECTS = $(addprefix $(OBJ_LEVELS_DIR)/, LEVEL1.LVL LEVEL2.LVL LEVEL2.PLT LEVEL1.PLT EASY.PLT) # Sprite objects: BMP2TIM = bmp2tim diff --git a/Source/MapEditor/MapEditor.pro.user b/Source/MapEditor/MapEditor.pro.user index 91bb581..aaf3a0c 100644 --- a/Source/MapEditor/MapEditor.pro.user +++ b/Source/MapEditor/MapEditor.pro.user @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
-<!-- Written by QtCreator 4.0.3, 2017-12-29T17:58:10. -->
+<!-- Written by QtCreator 4.0.3, 2018-01-01T07:36:40. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
diff --git a/Source/MapEditor/settings.ini b/Source/MapEditor/settings.ini index dc943fa..af1583e 100644 --- a/Source/MapEditor/settings.ini +++ b/Source/MapEditor/settings.ini @@ -1,2 +1,2 @@ [app_settings]
-last_dir=C:/cygwin/home/Xavier/Airport/Levels/LEVEL2_.LVL
+last_dir=C:/cygwin/home/Xavier/Airport/Levels/LEVEL2.LVL
diff --git a/Source/Menu.c b/Source/Menu.c index e51515d..325c0c4 100644 --- a/Source/Menu.c +++ b/Source/Menu.c @@ -27,6 +27,19 @@ * Structs and enums * * *************************************/ +typedef enum t_levelId +{ + LEVEL1 = 0, + LEVEL2, + MAX_LEVELS = LEVEL2 +}LEVEL_ID; + +typedef struct t_lvlpltdata +{ + LEVEL_ID levelID; + const char** fileNames[]; +}TYPE_LVL_PLT_DATA; + typedef enum { PLAY_OPTIONS_LEVEL, @@ -133,6 +146,9 @@ static TYPE_CHEAT StackCheckCheat; static TYPE_CHEAT DevMenuCheat; static TYPE_CHEAT SerialCheat; static volatile bool BcnGWSpr_set; +static LEVEL_ID SelectedLevel; +static uint8_t SelectedPlt; +static bool isLevelSelected; static const char* MainMenuFiles[] = { "cdrom:\\DATA\\SPRITES\\MAINMENU.TIM;1" , "cdrom:\\DATA\\SOUNDS\\BELL.VAG;1" , @@ -149,18 +165,15 @@ static const char* MainMenuFiles[] = { "cdrom:\\DATA\\SPRITES\\MAINMENU.TIM;1" , #endif // NO_INTRO }; -enum -{ - LEVEL1, - LEVEL2 -}; - static const char* MainMenuLevelList[] = { [LEVEL1] = "cdrom:\\DATA\\LEVELS\\LEVEL1.LVL;1" , [LEVEL2] = "cdrom:\\DATA\\LEVELS\\LEVEL2.LVL;1" }; -static const char* MainMenuLevelPltList[][] = { [LEVEL1] = {"cdrom:\\DATA\\LEVELS\\LEVEL1.PLT;1"}, - [LEVEL2] = {"cdrom:\\DATA\\LEVELS\\LEVEL2.PLT;1"} }; +static const char* MainMenuLevel1Plt[] = {"cdrom:\\DATA\\LEVELS\\LEVEL1.PLT;1", "cdrom:\\DATA\\LEVELS\\EASY.PLT;1", NULL}; +static const char* MainMenuLevel2Plt[] = {"cdrom:\\DATA\\LEVELS\\LEVEL2.PLT;1", NULL}; + +static const char** MainMenuPltList[] = {[LEVEL1] = MainMenuLevel1Plt, [LEVEL2] = MainMenuLevel2Plt}; +static TYPE_GAME_CONFIGURATION GameCfg; static void* MainMenuDest[] = { (GsSprite*)&MenuSpr , (SsVag*)&BellSnd , @@ -211,6 +224,7 @@ void OptionsMenu(void) void OnePlayerMenu(void) { menuLevel = LEVEL_LIST_LEVEL; + GameCfg.TwoPlayers = false; //EndAnimation(); //Game(false /* One Player Only */); } @@ -218,6 +232,7 @@ void OnePlayerMenu(void) void TwoPlayerMenu(void) { menuLevel = LEVEL_LIST_LEVEL; + GameCfg.TwoPlayers = true; //EndAnimation(); //Game(true /* Two players */); } @@ -270,6 +285,8 @@ void MainMenuInit(void) MenuStarSpr.my = MenuStarSpr.h >> 1; MenuStarSpr.rotate = 0; + SelectedLevel = LEVEL1; + MenuCheatInit(); LoadMenuEnd(); @@ -407,9 +424,21 @@ void MainMenuRenderLevelList(void) { LEVEL_LIST_TEXT_X = LEVEL_LIST_RECT_X + 8, LEVEL_LIST_TEXT_Y = LEVEL_LIST_RECT_Y + 8, + + LEVEL_LIST_PLT_TEXT_X = LEVEL_LIST_PLT_RECT_X + 8, + LEVEL_LIST_PLT_TEXT_Y = LEVEL_LIST_PLT_RECT_Y + 8, + }; + + enum + { + LEVEL_LIST_SELECTION_RECT_X = LEVEL_LIST_TEXT_X, + LEVEL_LIST_SELECTION_RECT_Y = LEVEL_LIST_TEXT_Y, + LEVEL_LIST_SELECTION_RECT_W = LEVEL_LIST_RECT_W - 16, + LEVEL_LIST_SELECTION_RECT_H = 8, }; GsGPoly4 levelListRect = {0}; + GsGPoly4 levelListSelectionRect = {0}; uint8_t i; levelListRect.x[0] = LEVEL_LIST_RECT_X; @@ -446,6 +475,33 @@ void MainMenuRenderLevelList(void) GsSortGPoly4(&levelListRect); + levelListSelectionRect.x[0] = LEVEL_LIST_SELECTION_RECT_X; + levelListSelectionRect.x[1] = LEVEL_LIST_SELECTION_RECT_X + LEVEL_LIST_SELECTION_RECT_W; + levelListSelectionRect.x[2] = levelListSelectionRect.x[0]; + levelListSelectionRect.x[3] = levelListSelectionRect.x[1]; + + levelListSelectionRect.y[0] = LEVEL_LIST_SELECTION_RECT_Y + (short)(SelectedLevel << 3); + levelListSelectionRect.y[1] = levelListSelectionRect.y[0]; + levelListSelectionRect.y[2] = LEVEL_LIST_SELECTION_RECT_Y + LEVEL_LIST_SELECTION_RECT_H + (short)(SelectedLevel << 3); + levelListSelectionRect.y[3] = levelListSelectionRect.y[2]; + + levelListSelectionRect.r[0] = LEVEL_LIST_RECT_B0; + levelListSelectionRect.r[1] = LEVEL_LIST_RECT_B1; + levelListSelectionRect.r[2] = LEVEL_LIST_RECT_B2; + levelListSelectionRect.r[3] = LEVEL_LIST_RECT_B3; + + levelListSelectionRect.g[0] = LEVEL_LIST_RECT_B0; + levelListSelectionRect.g[1] = LEVEL_LIST_RECT_B1; + levelListSelectionRect.g[2] = LEVEL_LIST_RECT_B2; + levelListSelectionRect.g[3] = LEVEL_LIST_RECT_B3; + + levelListSelectionRect.b[0] = LEVEL_LIST_RECT_B0; + levelListSelectionRect.b[1] = LEVEL_LIST_RECT_B1; + levelListSelectionRect.b[2] = LEVEL_LIST_RECT_B2; + levelListSelectionRect.b[3] = LEVEL_LIST_RECT_B3; + + levelListSelectionRect.attribute |= ENABLE_TRANS | TRANS_MODE(0); + for (i = 0; i < (sizeof(MainMenuLevelList) / sizeof(MainMenuLevelList[0])); i++) { char baseName[32]; @@ -456,15 +512,40 @@ void MainMenuRenderLevelList(void) FontPrintText(&SmallFont, LEVEL_LIST_TEXT_X, LEVEL_LIST_TEXT_Y + (i << 3), baseName); - for (j = 0; j < (sizeof(MainMenuLevelPltList[i]) / sizeof(MainMenuLevelPltList[i][0])); j++) + if (i == SelectedLevel) { + for (j = 0; j < (sizeof(MainMenuPltList) / sizeof(MainMenuPltList[0])); j++) + { + if (MainMenuPltList[i][j] != NULL) + { + // Update "baseName" with file name + extension. + SystemGetFileBasename(MainMenuPltList[i][j], baseName, sizeof(baseName) / sizeof(baseName[0])); + FontPrintText(&SmallFont, LEVEL_LIST_PLT_TEXT_X, LEVEL_LIST_PLT_TEXT_Y + (j << 3), baseName); + } + } } } + + if (isLevelSelected == false) + { + GsSortGPoly4(&levelListSelectionRect); + } + else + { + levelListSelectionRect.y[0] = LEVEL_LIST_PLT_TEXT_Y + (short)(SelectedPlt << 3); + levelListSelectionRect.y[1] = levelListSelectionRect.y[0]; + levelListSelectionRect.y[2] = LEVEL_LIST_PLT_TEXT_Y + LEVEL_LIST_SELECTION_RECT_H + (short)(SelectedPlt << 3); + levelListSelectionRect.y[3] = levelListSelectionRect.y[2]; + + GsSortGPoly4(&levelListSelectionRect); + } } void MainMenuRestoreInitValues(void) { + uint8_t i; + menuLevel = PLAY_OPTIONS_LEVEL; MainMenuMinimumBtn = PLAY_BUTTON_INDEX; @@ -484,6 +565,16 @@ void MainMenuRestoreInitValues(void) MainMenuBtn[TWO_PLAYER_BUTTON_INDEX].was_selected = false; MainMenuBtn[TWO_PLAYER_BUTTON_INDEX].timer = 0; + SelectedLevel = LEVEL1; + SelectedPlt = 0; + + memset(&GameCfg, 0, sizeof(TYPE_GAME_CONFIGURATION)); + + for (i = 0; i < MAIN_MENU_BUTTONS_MAX; i++) + { + MainMenuBtn[i].was_selected = false; + } + GfxSetGlobalLuminance(NORMAL_LUMINANCE); SfxPlayTrack(INTRO_TRACK); @@ -493,7 +584,7 @@ void MainMenuButtonHandler(void) { static uint8_t btn_selected = PLAY_BUTTON_INDEX; static uint8_t previous_btn_selected = 0; - uint8_t max_buttons; + uint8_t max_buttons = 0; if (PadOneAnyKeyPressed() != false) { @@ -538,6 +629,56 @@ void MainMenuButtonHandler(void) break; + case LEVEL_LIST_LEVEL: + if (PadOneKeySinglePress(PAD_UP) != false) + { + if (isLevelSelected == false) + { + if (SelectedLevel > 0) + { + SelectedLevel--; + SelectedPlt = 0; + } + } + else + { + if (SelectedPlt > 0) + { + SelectedPlt--; + } + } + } + else if (PadOneKeySinglePress(PAD_DOWN) != false) + { + if (isLevelSelected == false) + { + if (SelectedLevel < MAX_LEVELS) + { + SelectedLevel++; + SelectedPlt = 0; + } + } + else + { + if (MainMenuPltList[SelectedLevel][SelectedPlt + 1] != NULL) + { + SelectedPlt++; + } + } + } + else if (PadOneKeySinglePress(PAD_TRIANGLE) != false) + { + if (isLevelSelected == true) + { + isLevelSelected = false; + } + else + { + MainMenuRestoreInitValues(); + } + } + break; + default: max_buttons = 0; break; @@ -578,13 +719,31 @@ void MainMenuButtonHandler(void) if (PadOneKeySinglePress(PAD_CROSS) ) { - if(0)MainMenuRestoreInitValues(); - MainMenuBtn[btn_selected].f(); - - if (menuLevel == ONE_TWO_PLAYERS_LEVEL) + if (menuLevel == LEVEL_LIST_LEVEL) { - btn_selected = PLAY_BUTTON_INDEX; + if (isLevelSelected == false) + { + isLevelSelected = true; + } + else + { + GameCfg.LVLPath = MainMenuLevelList[SelectedLevel]; + GameCfg.PLTPath = MainMenuPltList[SelectedLevel][SelectedPlt]; + + EndAnimation(); + + // Start gameplay! + Game(&GameCfg); + + MainMenuRestoreInitValues(); + btn_selected = PLAY_BUTTON_INDEX; + isLevelSelected = false; + } } + else + { + MainMenuBtn[btn_selected].f(); + } } MainMenuBtn[btn_selected].selected = true; |
