diff --git a/Bin/AIRPORT.bin b/Bin/AIRPORT.bin index a1332db..c02354b 100644 Binary files a/Bin/AIRPORT.bin and b/Bin/AIRPORT.bin differ diff --git a/Concepts/.directory b/Concepts/.directory index fb42877..eee9ca1 100644 --- a/Concepts/.directory +++ b/Concepts/.directory @@ -1,3 +1,4 @@ [Dolphin] PreviewsShown=true -Timestamp=2016,5,19,18,57,13 +Timestamp=2018,11,25,20,0,16 +Version=4 diff --git a/Levels/LEVEL1.LVL b/Levels/LEVEL1.LVL index 84591f8..dfb0751 100644 Binary files a/Levels/LEVEL1.LVL and b/Levels/LEVEL1.LVL differ diff --git a/Levels/LEVEL2.LVL b/Levels/LEVEL2.LVL index 1d08d3d..34361d3 100644 Binary files a/Levels/LEVEL2.LVL and b/Levels/LEVEL2.LVL differ diff --git a/Levels/LEVEL3.LVL b/Levels/LEVEL3.LVL index bd729fd..ec8a357 100644 Binary files a/Levels/LEVEL3.LVL and b/Levels/LEVEL3.LVL differ diff --git a/Source/Airport.geany b/Source/Airport.geany index 76ee5f8..3603a32 100644 --- a/Source/Airport.geany +++ b/Source/Airport.geany @@ -28,36 +28,36 @@ long_line_behaviour=1 long_line_column=120 [files] -current_page=16 +current_page=4 FILE_NAME_0=29974;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FAircraft.c;0;4 -FILE_NAME_1=5814;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FCamera.c;0;4 +FILE_NAME_1=5265;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FCamera.c;0;4 FILE_NAME_2=4555;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FEndAnimation.c;0;4 FILE_NAME_3=6794;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FFont.c;0;4 -FILE_NAME_4=131182;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGame.c;0;4 +FILE_NAME_4=29884;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGame.c;0;4 FILE_NAME_5=43334;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGameGui.c;0;4 -FILE_NAME_6=19750;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGfx.c;0;4 +FILE_NAME_6=3129;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGfx.c;0;4 FILE_NAME_7=14837;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FLoadMenu.c;0;4 FILE_NAME_8=717;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2Fmain.c;0;4 FILE_NAME_9=745;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FMainMenuBtnAni.c;0;4 FILE_NAME_10=30632;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FMemCard.c;0;4 -FILE_NAME_11=24291;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FMenu.c;0;4 +FILE_NAME_11=20468;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FMenu.c;0;4 FILE_NAME_12=3904;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FMessage.c;0;4 FILE_NAME_13=11137;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FPad.c;0;4 -FILE_NAME_14=7538;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FPltParser.c;0;4 +FILE_NAME_14=10976;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FPltParser.c;0;4 FILE_NAME_15=9894;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FPSXSDKIntro.c;0;4 -FILE_NAME_16=1144;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FSerial.c;0;4 +FILE_NAME_16=1091;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FSerial.c;0;4 FILE_NAME_17=2669;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FSfx.c;0;4 FILE_NAME_18=2662;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FSystem.c;0;4 FILE_NAME_19=3753;C;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FTimer.c;0;4 FILE_NAME_20=1270;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FAircraft.h;0;4 -FILE_NAME_21=913;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FCamera.h;0;4 +FILE_NAME_21=392;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FCamera.h;0;4 FILE_NAME_22=529;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FEndAnimation.h;0;4 FILE_NAME_23=1145;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FFont.h;0;4 FILE_NAME_24=1682;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGameGui.h;0;4 -FILE_NAME_25=1854;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGame.h;0;4 -FILE_NAME_26=7318;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGameStructures.h;0;4 +FILE_NAME_25=390;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGame.h;0;4 +FILE_NAME_26=294;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGameStructures.h;0;4 FILE_NAME_27=3576;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGfx.h;0;4 -FILE_NAME_28=709;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGlobal_Inc.h;0;4 +FILE_NAME_28=424;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FGlobal_Inc.h;0;4 FILE_NAME_29=630;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FLoadMenu.h;0;4 FILE_NAME_30=559;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FMainMenuBtnAni.h;0;4 FILE_NAME_31=4622;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FMemCard.h;0;4 @@ -70,7 +70,7 @@ FILE_NAME_37=490;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FSerial FILE_NAME_38=815;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FSfx.h;0;4 FILE_NAME_39=4207;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FSystem.h;0;4 FILE_NAME_40=1066;C++;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FTimer.h;0;4 -FILE_NAME_41=521;Make;0;EUTF-8;1;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FMakefile;0;4 +FILE_NAME_41=3168;Make;0;EUTF-8;1;1;0;%2Fhome%2Fxavier%2FAirport%2FSource%2FMakefile;0;4 FILE_NAME_42=319;None;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FLevels%2FLEVEL3.PLT;0;4 FILE_NAME_43=319;None;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FLevels%2FEASY.PLT;0;4 FILE_NAME_44=319;None;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2FAirport%2FLevels%2FLEVEL1.PLT;0;4 @@ -119,9 +119,10 @@ FILE_NAME_86=0;ASM;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2Fpsxsdk-20150729%2Flibpsx%2F FILE_NAME_87=70;ASM;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2Fpsxsdk-20150729%2Flibpsx%2Fsrc%2Fexc1.s;0;4 FILE_NAME_88=2629;ASM;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2Fpsxsdk-20150729%2Flibpsx%2Fsrc%2Fsyscalls.s;0;4 FILE_NAME_89=647;ASM;0;EUTF-8;0;1;0;%2Fhome%2Fxavier%2Fpsxsdk-20150729%2Flibpsx%2Fsrc%2Fstart%2Fstart.s;0;4 +FILE_NAME_90=1488;C++;0;EUTF-8;0;1;0;%2Fusr%2Flocal%2Fpsxsdk%2Finclude%2Fstdio.h;0;4 [VTE] -last_dir=/home/xavier +last_dir=/home/xavier/Airport/Bin [build-menu] NF_01_LB=Make Custom _Target... diff --git a/Source/Camera.c b/Source/Camera.c index e23a54f..5892218 100644 --- a/Source/Camera.c +++ b/Source/Camera.c @@ -185,7 +185,6 @@ void CameraHandler(TYPE_PLAYER* const ptrPlayer) { if ((ptrPlayer->Camera.X_Offset + ptrPlayer->Camera.X_Speed) <= Camera_Min_X_Limit) { - DEBUG_PRINT_VAR(ptrPlayer->Camera.X_Offset); if (ptrPlayer->Camera.X_Speed < 0) { limitAchieved = true; @@ -208,9 +207,6 @@ void CameraHandler(TYPE_PLAYER* const ptrPlayer) } ptrPlayer->Camera.Y_Offset += ptrPlayer->Camera.Y_Speed; - - //~ DEBUG_PRINT_VAR(ptrPlayer->Camera.X_Offset); - //~ DEBUG_PRINT_VAR(ptrPlayer->Camera.Y_Offset); } bool CameraSpecialConditions(TYPE_PLAYER* const ptrPlayer) diff --git a/Source/Exe/AIRPORT.elf b/Source/Exe/AIRPORT.elf index 759910d..ac15fd6 100755 Binary files a/Source/Exe/AIRPORT.elf and b/Source/Exe/AIRPORT.elf differ diff --git a/Source/Exe/AIRPORT.iso b/Source/Exe/AIRPORT.iso index 4ac4e41..7d4ae09 100644 Binary files a/Source/Exe/AIRPORT.iso and b/Source/Exe/AIRPORT.iso differ diff --git a/Source/Game.c b/Source/Game.c index 71267d3..ecaff3a 100644 --- a/Source/Game.c +++ b/Source/Game.c @@ -49,17 +49,6 @@ typedef struct t_rwyentrydata uint16_t rwyHeader; }TYPE_RWY_ENTRY_DATA; -typedef struct t_buildingdata -{ - TYPE_ISOMETRIC_POS IsoPos; // Offset inside tile - short orig_x; // Coordinate X origin inside building sprite - short orig_y; // Coordinate Y origin inside building sprite - short w; // Building width - short h; // Building height - short u; // Building X offset inside texture page - short v; // Building Y offset inside texture page -}TYPE_BUILDING_DATA; - typedef struct t_GameLevelBuffer_UVData { short u; @@ -94,21 +83,6 @@ enum UNBOARDING_PASSENGERS_PER_SEQUENCE = 100 }; -enum -{ - BUILDING_NONE, - BUILDING_HANGAR, - BUILDING_ILS, - BUILDING_ATC_TOWER, - BUILDING_ATC_LOC, - BUILDING_TERMINAL, - BUILDING_TERMINAL_2, - BUILDING_GATE, - - LAST_BUILDING = BUILDING_GATE, - MAX_BUILDING_ID -}; - enum { TILE_GRASS, @@ -1106,6 +1080,21 @@ void GameDrawBackground(TYPE_PLAYER* const ptrPlayer) void GameRenderBuildingAircraft(TYPE_PLAYER* const ptrPlayer) { + enum + { + BUILDING_NONE, + BUILDING_HANGAR, + BUILDING_ILS, + BUILDING_ATC_TOWER, + BUILDING_ATC_LOC, + BUILDING_TERMINAL, + BUILDING_TERMINAL_2, + BUILDING_GATE, + + LAST_BUILDING = BUILDING_GATE, + MAX_BUILDING_ID + }; + enum { BUILDING_ATC_LOC_OFFSET_X = TILE_SIZE >> 1, @@ -1120,6 +1109,12 @@ void GameRenderBuildingAircraft(TYPE_PLAYER* const ptrPlayer) BUILDING_HANGAR_OFFSET_X = 4, BUILDING_HANGAR_OFFSET_Y = TILE_SIZE >> 1, + BUILDING_TERMINAL_OFFSET_X = 0, + BUILDING_TERMINAL_OFFSET_Y = TILE_SIZE >> 1, + + BUILDING_TERMINAL_2_OFFSET_X = BUILDING_TERMINAL_OFFSET_X, + BUILDING_TERMINAL_2_OFFSET_Y = BUILDING_TERMINAL_OFFSET_Y, + BUILDING_ATC_TOWER_OFFSET_X = TILE_SIZE >> 2, BUILDING_ATC_TOWER_OFFSET_Y = TILE_SIZE >> 1, }; @@ -1137,9 +1132,19 @@ void GameRenderBuildingAircraft(TYPE_PLAYER* const ptrPlayer) BUILDING_GATE_H = 25, BUILDING_HANGAR_U = 0, - BUILDING_HANGAR_V = 34, - BUILDING_HANGAR_W = 51, - BUILDING_HANGAR_H = 36, + BUILDING_HANGAR_V = 0, + BUILDING_HANGAR_W = 34, + BUILDING_HANGAR_H = 28, + + BUILDING_TERMINAL_U = 0, + BUILDING_TERMINAL_V = 34, + BUILDING_TERMINAL_W = 51, + BUILDING_TERMINAL_H = 36, + + BUILDING_TERMINAL_2_U = 51, + BUILDING_TERMINAL_2_V = BUILDING_TERMINAL_V, + BUILDING_TERMINAL_2_W = BUILDING_TERMINAL_W, + BUILDING_TERMINAL_2_H = BUILDING_TERMINAL_H, BUILDING_ATC_TOWER_U = 58, BUILDING_ATC_TOWER_V = 0, @@ -1155,14 +1160,29 @@ void GameRenderBuildingAircraft(TYPE_PLAYER* const ptrPlayer) BUILDING_GATE_ORIGIN_X = 20, BUILDING_GATE_ORIGIN_Y = 8, - BUILDING_HANGAR_ORIGIN_X = 20, - BUILDING_HANGAR_ORIGIN_Y = 11, + BUILDING_TERMINAL_ORIGIN_X = 20, + BUILDING_TERMINAL_ORIGIN_Y = 11, + + BUILDING_TERMINAL_2_ORIGIN_X = BUILDING_TERMINAL_ORIGIN_X, + BUILDING_TERMINAL_2_ORIGIN_Y = BUILDING_TERMINAL_ORIGIN_Y, + + BUILDING_HANGAR_ORIGIN_X = 16, + BUILDING_HANGAR_ORIGIN_Y = 12, BUILDING_ATC_TOWER_ORIGIN_X = 12, BUILDING_ATC_TOWER_ORIGIN_Y = 20, }; - static const TYPE_BUILDING_DATA GameBuildingData[MAX_BUILDING_ID] = + static const struct + { + TYPE_ISOMETRIC_POS IsoPos; // Offset inside tile + short orig_x; // Coordinate X origin inside building sprite + short orig_y; // Coordinate Y origin inside building sprite + short w; // Building width + short h; // Building height + short u; // Building X offset inside texture page + short v; // Building Y offset inside texture page + } GameBuildingData[MAX_BUILDING_ID] = { [BUILDING_GATE] = { @@ -1210,6 +1230,34 @@ void GameRenderBuildingAircraft(TYPE_PLAYER* const ptrPlayer) .h = BUILDING_HANGAR_H, }, + [BUILDING_TERMINAL] = + { + // BUILDING_TERMINAL coordinates inside tile. + .IsoPos.x = BUILDING_TERMINAL_OFFSET_X, + .IsoPos.y = BUILDING_TERMINAL_OFFSET_Y, + // z coordinate set to 0 by default. + .orig_x = BUILDING_TERMINAL_ORIGIN_X, + .orig_y = BUILDING_TERMINAL_ORIGIN_Y, + .u = BUILDING_TERMINAL_U, + .v = BUILDING_TERMINAL_V, + .w = BUILDING_TERMINAL_W, + .h = BUILDING_TERMINAL_H, + }, + + [BUILDING_TERMINAL_2] = + { + // BUILDING_TERMINAL_2 coordinates inside tile. + .IsoPos.x = BUILDING_TERMINAL_2_OFFSET_X, + .IsoPos.y = BUILDING_TERMINAL_2_OFFSET_Y, + // z coordinate set to 0 by default. + .orig_x = BUILDING_TERMINAL_2_ORIGIN_X, + .orig_y = BUILDING_TERMINAL_2_ORIGIN_Y, + .u = BUILDING_TERMINAL_2_U, + .v = BUILDING_TERMINAL_2_V, + .w = BUILDING_TERMINAL_2_W, + .h = BUILDING_TERMINAL_2_H, + }, + [BUILDING_ATC_TOWER] = { // BUILDING_ATC_TOWER coordinates inside tile. @@ -1230,7 +1278,13 @@ void GameRenderBuildingAircraft(TYPE_PLAYER* const ptrPlayer) .IsoPos.x = BUILDING_GATE_OFFSET_X, .IsoPos.y = BUILDING_GATE_OFFSET_Y, // z coordinate set to 0 by default. - } + .orig_x = BUILDING_GATE_ORIGIN_X, + .orig_y = BUILDING_GATE_ORIGIN_Y, + .u = BUILDING_GATE_U, + .v = BUILDING_GATE_V, + .w = BUILDING_GATE_W, + .h = BUILDING_GATE_H, + }, }; uint16_t tileNr; @@ -1305,9 +1359,12 @@ void GameRenderBuildingAircraft(TYPE_PLAYER* const ptrPlayer) short orig_u = GameBuildingSpr.u; short orig_v = GameBuildingSpr.v; - TYPE_ISOMETRIC_POS buildingIsoPos = { .x = (columns << (TILE_SIZE_BIT_SHIFT)) + x_bldg_offset, - .y = (rows << (TILE_SIZE_BIT_SHIFT)) + y_bldg_offset, - .z = z_bldg_offset }; + TYPE_ISOMETRIC_POS buildingIsoPos = + { + .x = (columns << (TILE_SIZE_BIT_SHIFT)) + x_bldg_offset, + .y = (rows << (TILE_SIZE_BIT_SHIFT)) + y_bldg_offset, + .z = z_bldg_offset + }; // Isometric -> Cartesian conversion TYPE_CARTESIAN_POS buildingCartPos = GfxIsometricToCartesian(&buildingIsoPos); @@ -1446,15 +1503,31 @@ static void GameLoadLevel(const char* path) Serial_printf("Game level title: %s\n",GameLevelTitle); - DEBUG_PRINT_VAR(GameLevelSize); - i += LEVEL_TITLE_SIZE; memset(levelBuffer, 0, GAME_MAX_MAP_SIZE); i = LEVEL_HEADER_SIZE; - memcpy(levelBuffer, &ptrBuffer[i], GameLevelSize * sizeof (uint16_t)); // 2 bytes per tile + { + size_t j; + size_t k; + + for (j = LEVEL_HEADER_SIZE, k = 0; k < GameLevelSize; j += sizeof (uint16_t), k++) + { + levelBuffer[k] = ptrBuffer[j + 1]; + levelBuffer[k] |= (ptrBuffer[j] << 8); + } + } + + { + size_t i; + + for (i = 0; i < (GameLevelSize * sizeof (uint16_t)); i++) + { + Serial_printf("levelBuffer[%d] = 0x%02X\n", i, levelBuffer[i]); + } + } } /* ****************************************************************************************** @@ -2699,12 +2772,8 @@ void GameGetSelectedRunwayArray(uint16_t rwyHeader, uint16_t* rwyArray, size_t s } } - //DEBUG_PRINT_VAR(i); - rwyArray[i++] = last_tile; - //DEBUG_PRINT_VAR(rwyArray[i -1]); - switch(dir) { case DIR_EAST: @@ -2727,7 +2796,6 @@ 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; } diff --git a/Source/MapEditor/MapEditor.pro.user b/Source/MapEditor/MapEditor.pro.user index 2ef5a22..a31f63f 100644 --- a/Source/MapEditor/MapEditor.pro.user +++ b/Source/MapEditor/MapEditor.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/Source/MapEditor/buildings.ini b/Source/MapEditor/buildings.ini new file mode 100644 index 0000000..5eb7823 --- /dev/null +++ b/Source/MapEditor/buildings.ini @@ -0,0 +1,4 @@ +[buildings] +path = "../../Sprites/BLDNGS1.bmp" +building0 = "Nothing" +building1 = "Hangar" diff --git a/Source/MapEditor/mainwindow.cpp b/Source/MapEditor/mainwindow.cpp index e641a4d..923fca4 100644 --- a/Source/MapEditor/mainwindow.cpp +++ b/Source/MapEditor/mainwindow.cpp @@ -50,17 +50,37 @@ MainWindow::~MainWindow() void MainWindow::loadBuildingData(void) { - const QString filePath = "./buildings.ini"; + const QString path = "./buildings.ini"; - QFile f(filePath); + QSettings settings(path, QSettings::IniFormat); - if (f.open(QFile::ReadOnly)) + if (QFile(path).exists()) { + settings.beginGroup("buildings"); + buildingPath = settings.value("path").toString(); + + int i = 0; + + while (1) + { + QString buildingNumber = "building" + QString::number(i); + QString buildingName = settings.value(buildingNumber, "").toString(); + + if (buildingName.isEmpty() ) + { + break; + } + + buildingData.insert(i++, buildingName); + ui.buildingList->addItem(buildingName); + } + + settings.endGroup(); } else { - showError(tr("Could not open file ") + filePath); + showError(path + tr(" could not be found")); } } @@ -102,8 +122,8 @@ void MainWindow::onListItemSelected(void) { if (selected_item != -1) { - const int map_buffer_pos = static_cast((DATA_HEADER_SIZE + 1) - + (static_cast(selected_item) * sizeof(quint16))); + const int map_buffer_pos = static_cast(DATA_HEADER_SIZE + + (static_cast(selected_item + 1) * sizeof(quint16))); //map_buffer_pos++; // MSB: building data, LSB: terrain data. if (map_buffer_pos < map_buffer.count()) @@ -255,14 +275,11 @@ void MainWindow::processMapFile(const QByteArray& data) && not tilesetPaths[1].isEmpty()) { - QPixmap tile1(tilesetPaths[0]); - QPixmap tile2(tilesetPaths[1]); - const int expected_filesize = (DATA_HEADER_SIZE + (level_size * level_size)); if (data.count() >= expected_filesize) { - parseMapData(ds, tile1, tile2); + parseMapData(ds); } else { @@ -277,7 +294,7 @@ void MainWindow::processMapFile(const QByteArray& data) } } -void MainWindow::parseMapData(QDataStream& ds, const QPixmap& tileSet, const QPixmap& tileSet2) +void MainWindow::parseMapData(QDataStream& ds) { char airportName[0x1A]; @@ -285,91 +302,229 @@ void MainWindow::parseMapData(QDataStream& ds, const QPixmap& tileSet, const QPi ui.airportName_Label->setText(QString(airportName)); - ds.skipRawData(0x3B - 0x1A); + ds.skipRawData(0x3C - 0x1A); gscene.clear(); gscene.clearFocus(); + QList buildingData; + + for (int j = 0; j < level_size; j++) { for (int i = 0; i < level_size; i++) { - enum - { - TILE_GRASS = 0, - TILE_ASPHALT_WITH_BORDERS, - TILE_WATER, - TILE_ASPHALT, - - TILE_RWY_MID, - TILE_RWY_START_1, - TILE_RWY_START_2, - TILE_PARKING, - - TILE_PARKING_2, - TILE_TAXIWAY_INTERSECT_GRASS, - TILE_TAXIWAY_GRASS, - TILE_TAXIWAY_CORNER_GRASS, - - TILE_HALF_WATER_1, - TILE_HALF_WATER_2, - TILE_RWY_HOLDING_POINT, - TILE_RWY_HOLDING_POINT_2, - - TILE_RWY_EXIT, - TILE_TAXIWAY_CORNER_GRASS_2, - TILE_TAXIWAY_4WAY_CROSSING, - TILE_RWY_EXIT_2, - - LAST_TILE_TILESET1 = TILE_RWY_EXIT_2, - - TILE_UNUSED_1, - TILE_TAXIWAY_CORNER_GRASS_3, - - FIRST_TILE_TILESET2 = TILE_UNUSED_1, - LAST_TILE_TILESET2 = TILE_TAXIWAY_CORNER_GRASS_3 - }; - - int u; - int v; char byte[2]; ds.readRawData(byte, 2); - quint8 CurrentTile = static_cast(byte[1]); - quint8 CurrentBuilding = static_cast(byte[0]); - quint8 buildingNoMirror = CurrentBuilding & 0x7F; - quint8 tileNoMirror = CurrentTile & 0x7F; - const QPixmap* p = nullptr; - if (tileNoMirror <= LAST_TILE_TILESET1) + qDebug() << "i = " + QString::number(i); + qDebug() << "j = " + QString::number(j); + qDebug() << QString::number(byte[0]); + qDebug() << QString::number(byte[1]); + qDebug() << ""; + + buildingData.append(static_cast(byte[0])); + addTile(static_cast(byte[1]), i, j); + } + } + + for (int j = 0; j < level_size; j++) + { + for (int i = 0; i < level_size; i++) + { + addBuilding(buildingData.at(i + (j* level_size)), i, j); + } + } + + ui.graphicsView->setScene(&gscene); + ui.graphicsView->show(); + ui.graphicsView->centerOn(QPointF(320, 480)); +} + +#define NODATA \ +{ \ + false, \ + { \ + 0, \ + 0, \ + 0 \ + }, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0, \ + 0 \ +} + +#define BUILDING_DATA(building) \ +{ \ + true, \ + { \ + building##_OFFSET_X, \ + building##_OFFSET_Y, \ + 0 \ + }, \ + building##_ORIGIN_X, \ + building##_ORIGIN_Y, \ + building##_W, \ + building##_H, \ + building##_U, \ + building##_V \ +} + +void MainWindow::addBuilding(quint8 CurrentBuilding, const int i, const int j) +{ + if (CurrentBuilding) + { + enum + { + BUILDING_NONE, + BUILDING_HANGAR, + BUILDING_ILS, + BUILDING_ATC_TOWER, + BUILDING_ATC_LOC, + BUILDING_TERMINAL, + BUILDING_TERMINAL_2, + BUILDING_GATE, + + LAST_BUILDING = BUILDING_GATE, + MAX_BUILDING_ID + }; + + enum + { + BUILDING_ATC_LOC_OFFSET_X = TILE_SIZE >> 1, + BUILDING_ATC_LOC_OFFSET_Y = TILE_SIZE >> 1, + + BUILDING_ILS_OFFSET_X = 0, + BUILDING_ILS_OFFSET_Y = 0, + + BUILDING_GATE_OFFSET_X = (TILE_SIZE >> 1) - 4, + BUILDING_GATE_OFFSET_Y = 0, + + BUILDING_HANGAR_OFFSET_X = 4, + BUILDING_HANGAR_OFFSET_Y = TILE_SIZE >> 1, + + BUILDING_TERMINAL_OFFSET_X = 0, + BUILDING_TERMINAL_OFFSET_Y = TILE_SIZE >> 1, + + BUILDING_TERMINAL_2_OFFSET_X = BUILDING_TERMINAL_OFFSET_X, + BUILDING_TERMINAL_2_OFFSET_Y = BUILDING_TERMINAL_OFFSET_Y, + + BUILDING_ATC_TOWER_OFFSET_X = TILE_SIZE >> 2, + BUILDING_ATC_TOWER_OFFSET_Y = TILE_SIZE >> 1, + }; + + enum + { + BUILDING_ILS_U = 34, + BUILDING_ILS_V = 0, + BUILDING_ILS_W = 24, + BUILDING_ILS_H = 34, + + BUILDING_GATE_U = 0, + BUILDING_GATE_V = 70, + BUILDING_GATE_W = 28, + BUILDING_GATE_H = 25, + + BUILDING_HANGAR_U = 0, + BUILDING_HANGAR_V = 0, + BUILDING_HANGAR_W = 34, + BUILDING_HANGAR_H = 28, + + BUILDING_TERMINAL_U = 0, + BUILDING_TERMINAL_V = 34, + BUILDING_TERMINAL_W = 51, + BUILDING_TERMINAL_H = 36, + + BUILDING_TERMINAL_2_U = 51, + BUILDING_TERMINAL_2_V = BUILDING_TERMINAL_V, + BUILDING_TERMINAL_2_W = BUILDING_TERMINAL_W, + BUILDING_TERMINAL_2_H = BUILDING_TERMINAL_H, + + BUILDING_ATC_TOWER_U = 58, + BUILDING_ATC_TOWER_V = 0, + BUILDING_ATC_TOWER_W = 29, + BUILDING_ATC_TOWER_H = 34, + }; + + enum + { + BUILDING_ILS_ORIGIN_X = 10, + BUILDING_ILS_ORIGIN_Y = 22, + + BUILDING_GATE_ORIGIN_X = 20, + BUILDING_GATE_ORIGIN_Y = 8, + + BUILDING_TERMINAL_ORIGIN_X = 20, + BUILDING_TERMINAL_ORIGIN_Y = 11, + + BUILDING_TERMINAL_2_ORIGIN_X = BUILDING_TERMINAL_ORIGIN_X, + BUILDING_TERMINAL_2_ORIGIN_Y = BUILDING_TERMINAL_ORIGIN_Y, + + BUILDING_HANGAR_ORIGIN_X = 16, + BUILDING_HANGAR_ORIGIN_Y = 12, + + BUILDING_ATC_TOWER_ORIGIN_X = 12, + BUILDING_ATC_TOWER_ORIGIN_Y = 20, + }; + + static const struct + { + bool init; + IsometricPos IsoPos; // Offset inside tile + short orig_x; // Coordinate X origin inside building sprite + short orig_y; // Coordinate Y origin inside building sprite + short w; // Building width + short h; // Building height + short u; // Building X offset inside texture page + short v; // Building Y offset inside texture page + } GameBuildingData[MAX_BUILDING_ID] = + { + NODATA, + BUILDING_DATA(BUILDING_HANGAR), + BUILDING_DATA(BUILDING_ILS), + BUILDING_DATA(BUILDING_ATC_TOWER), + NODATA, + BUILDING_DATA(BUILDING_TERMINAL), + BUILDING_DATA(BUILDING_TERMINAL_2), + BUILDING_DATA(BUILDING_GATE), + }; + + enum + { + TILE_SIZE_BIT_SHIFT = 6 + }; + + const quint8 CurrentBuildingNoMirror = CurrentBuilding & 0x7F; + + if (CurrentBuildingNoMirror < MAX_BUILDING_ID) + { + if (GameBuildingData[CurrentBuildingNoMirror].init) { - p = &tileSet; - } - else if (tileNoMirror <= LAST_TILE_TILESET2) - { - p = &tileSet2; - CurrentTile -= FIRST_TILE_TILESET2; - tileNoMirror -= FIRST_TILE_TILESET2; - } + // Determine rendering order depending on Y value. + const short x_bldg_offset = GameBuildingData[CurrentBuildingNoMirror].IsoPos.x; + const short y_bldg_offset = GameBuildingData[CurrentBuildingNoMirror].IsoPos.y; + const short z_bldg_offset = GameBuildingData[CurrentBuildingNoMirror].IsoPos.z; - if (p != nullptr) - { - if (CurrentTile & TILE_MIRROR_FLAG) - { - u = static_cast((tileNoMirror % 4) * 64); - v = static_cast((tileNoMirror / 4) * 48); - } - else - { - u = static_cast((CurrentTile % 4) * 64); - v = static_cast((CurrentTile / 4) * 48); - } + IsometricPos buildingIsoPos; - QImage cropped = p->copy(u, v, 64, 48).toImage(); + buildingIsoPos.x = static_cast(i << TILE_SIZE_BIT_SHIFT) + x_bldg_offset; + buildingIsoPos.y = static_cast(j << TILE_SIZE_BIT_SHIFT) - y_bldg_offset; + buildingIsoPos.z = z_bldg_offset; - if (CurrentTile & TILE_MIRROR_FLAG) - { - cropped = cropped.mirrored(true, false); - } + // Isometric -> Cartesian conversion + CartesianPos buildingCartPos = isometricToCartesian(buildingIsoPos); + + QPixmap p = QPixmap(buildingPath); + + QImage cropped = p.copy(GameBuildingData[CurrentBuildingNoMirror].u, + GameBuildingData[CurrentBuildingNoMirror].v, + GameBuildingData[CurrentBuildingNoMirror].w, + GameBuildingData[CurrentBuildingNoMirror].h).toImage(); + + cropped = cropped.convertToFormat(QImage::Format_ARGB32); // or maybe other format bool selected = false; @@ -410,35 +565,161 @@ void MainWindow::parseMapData(QDataStream& ds, const QPixmap& tileSet, const QPi if (it != nullptr) { - const int x = ((i * TILE_SIZE) - (i * (TILE_SIZE / 2))) - (j * (TILE_SIZE / 2)); - const int y = (j * (TILE_SIZE / 4)) + (i * (TILE_SIZE / 4)); + // Define new coordinates for building. + const int x = buildingCartPos.x - GameBuildingData[CurrentBuilding].orig_x; + const int y = buildingCartPos.y - GameBuildingData[CurrentBuilding].orig_y; it->setX(x); it->setY(y); - - if (ui.showNumbers_Checkbox->isChecked() ) - { - QGraphicsTextItem* const io = new QGraphicsTextItem(); - - if (io != nullptr) - { - io->setPos(x + (TILE_SIZE / 4), y); - io->setPlainText(QString::number(i + (j * level_size))); - - gscene.addItem(io); - - /* Append pointer to the list so it can be - * safely removed on the constructor. */ - textItems.append(io); - } - } } } } } +} +#undef NODATA +#undef BUILDING_DATA - ui.graphicsView->setScene(&gscene); - ui.graphicsView->show(); +void MainWindow::addTile(quint8 CurrentTile, const int i, const int j) +{ + enum + { + TILE_GRASS, + TILE_ASPHALT_WITH_BORDERS, + TILE_WATER, + TILE_ASPHALT, + + TILE_RWY_MID, + TILE_RWY_START_1, + TILE_RWY_START_2, + TILE_PARKING, + + TILE_PARKING_2, + TILE_TAXIWAY_INTERSECT_GRASS, + TILE_TAXIWAY_GRASS, + TILE_TAXIWAY_CORNER_GRASS, + + TILE_HALF_WATER_1, + TILE_HALF_WATER_2, + TILE_RWY_HOLDING_POINT, + TILE_RWY_HOLDING_POINT_2, + + TILE_RWY_EXIT, + TILE_TAXIWAY_CORNER_GRASS_2, + TILE_TAXIWAY_4WAY_CROSSING, + TILE_RWY_EXIT_2, + + LAST_TILE_TILESET1 = TILE_RWY_EXIT_2, + + TILE_UNUSED_1, + TILE_TAXIWAY_CORNER_GRASS_3, + + FIRST_TILE_TILESET2 = TILE_UNUSED_1, + LAST_TILE_TILESET2 = TILE_TAXIWAY_CORNER_GRASS_3 + }; + + const QPixmap tileset(tilesetPaths[0]); + const QPixmap tileset2(tilesetPaths[1]); + + quint8 tileNoMirror = CurrentTile & 0x7F; + const QPixmap* p = nullptr; + + if (tileNoMirror <= LAST_TILE_TILESET1) + { + p = &tileset; + } + else if (tileNoMirror <= LAST_TILE_TILESET2) + { + p = &tileset2; + CurrentTile -= FIRST_TILE_TILESET2; + tileNoMirror -= FIRST_TILE_TILESET2; + } + + if (p != nullptr) + { + int u; + int v; + + if (CurrentTile & TILE_MIRROR_FLAG) + { + u = static_cast((tileNoMirror % 4) * 64); + v = static_cast((tileNoMirror / 4) * 48); + } + else + { + u = static_cast((CurrentTile % 4) * 64); + v = static_cast((CurrentTile / 4) * 48); + } + + QImage cropped = p->copy(u, v, 64, 48).toImage(); + + if (CurrentTile & TILE_MIRROR_FLAG) + { + cropped = cropped.mirrored(true, false); + } + + bool selected = false; + + if (selected_item != -1) + { + if (selected_item == ((j * level_size) + i)) + { + selected = true; + } + } + + cropped = cropped.convertToFormat(QImage::Format_ARGB32); // or maybe other format + + for (int i = 0; i < cropped.width(); i++) + { + for (int j = 0; j < cropped.height(); j++) + { + QColor rgb = cropped.pixel(i, j); + + if (rgb == QColor(Qt::magenta)) + { + cropped.setPixel(i, j, qRgba(0,0,0,0)); + } + else if (selected ) + { + QColor c = cropped.pixelColor(i, j); + + c.setRed(255 - c.red()); + c.setBlue(255 - c.blue()); + c.setGreen(255 - c.green()); + + cropped.setPixel(i, j, qRgb(c.red(), c.green(), c.blue())); + } + } + } + + QGraphicsPixmapItem* const it = gscene.addPixmap(QPixmap::fromImage(cropped)); + + if (it != nullptr) + { + const int x = ((i * TILE_SIZE) - (i * (TILE_SIZE / 2))) - (j * (TILE_SIZE / 2)); + const int y = (j * (TILE_SIZE / 4)) + (i * (TILE_SIZE / 4)); + + it->setX(x); + it->setY(y); + + if (ui.showNumbers_Checkbox->isChecked() ) + { + QGraphicsTextItem* const io = new QGraphicsTextItem(); + + if (io != nullptr) + { + io->setPos(x + (TILE_SIZE / 4), y); + io->setPlainText(QString::number(i + (j * level_size))); + + gscene.addItem(io); + + /* Append pointer to the list so it can be + * safely removed on the constructor. */ + textItems.append(io); + } + } + } + } } bool MainWindow::checkFile(QFile& f, QFile::OpenModeFlag flags) @@ -486,9 +767,7 @@ void MainWindow::loadTilesetData(void) { const QString filePath = "./tileset.ini"; - QFile f(filePath); - - if (f.exists()) + if (QFile(filePath).exists()) { QSettings tilesetFile("./tileset.ini", QSettings::IniFormat); QStringList tilesets_to_check; diff --git a/Source/MapEditor/mainwindow.h b/Source/MapEditor/mainwindow.h index 97e39ef..6b27128 100644 --- a/Source/MapEditor/mainwindow.h +++ b/Source/MapEditor/mainwindow.h @@ -33,11 +33,39 @@ public: void closeEvent(QCloseEvent*); private: + struct IsometricPos + { + short x; + short y; + short z; + }; + + struct CartesianPos + { + short x; + short y; + }; + bool checkFile(QFile &f, QFile::OpenModeFlag flags = QFile::ReadOnly); void appSettings(void); void loadTilesetData(void); void loadBuildingData(void); - void parseMapData(QDataStream &ds, const QPixmap &tileSet, const QPixmap &tileSet2); + void parseMapData(QDataStream &ds); + void addTile(quint8 CurrentTile, const int i, const int j); + void addBuilding(quint8 CurrentBuilding, const int i, const int j); + CartesianPos isometricToCartesian(const IsometricPos& ptrIsoPos) const + { + CartesianPos retCartPos; + + retCartPos.x = ptrIsoPos.x - (ptrIsoPos.x >> 1); + retCartPos.x -= ptrIsoPos.y >> 1; + + retCartPos.y = ptrIsoPos.y >> 2; + retCartPos.y += ptrIsoPos.x >> 2; + retCartPos.y -= ptrIsoPos.z; + + return retCartPos; + } Ui::MainWindow ui; QString _last_dir; @@ -46,10 +74,12 @@ private: QByteArray map_buffer; int selected_item; QHash tilesetData; + QHash buildingData; QList textItems; QShortcut tileSet; QShortcut tileMoveUp; QString tilesetPaths[2]; + QString buildingPath; private slots: void loadMap(void); diff --git a/Source/MapEditor/settings.ini b/Source/MapEditor/settings.ini index 4300b90..5ad5294 100644 --- a/Source/MapEditor/settings.ini +++ b/Source/MapEditor/settings.ini @@ -1,3 +1,3 @@ [app_settings] last_dir=/home/xavier/Airport/Levels/LEVEL3.LVL -window_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\x5U\0\0\x2\xdb\0\0\0\xaa\0\0\0P\0\0\x4\x41\0\0\x2\xd7\0\0\0\0\x2\0\0\0\x5V\0\0\0\0\0\0\0\x1d\0\0\x5U\0\0\x2\xdb) +window_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\x5U\0\0\x2\xdb\0\0\0\xa5\0\0\0\x1d\0\0\x4<\0\0\x2\xa4\0\0\0\0\x2\0\0\0\x5V\0\0\0\0\0\0\0\x1d\0\0\x5U\0\0\x2\xdb) diff --git a/Sprites/.directory b/Sprites/.directory index 538e082..e833710 100644 --- a/Sprites/.directory +++ b/Sprites/.directory @@ -1,3 +1,4 @@ [Dolphin] -Timestamp=2017,9,16,12,34,20 -Version=3 +PreviewsShown=true +Timestamp=2018,11,25,18,45,48 +Version=4 diff --git a/Sprites/CITYBG1.bmp b/Sprites/CITYBG1.bmp deleted file mode 100644 index 8b315f8..0000000 Binary files a/Sprites/CITYBG1.bmp and /dev/null differ diff --git a/Sprites/CITYBG1.flags b/Sprites/CITYBG1.flags deleted file mode 100644 index 7bde953..0000000 --- a/Sprites/CITYBG1.flags +++ /dev/null @@ -1 +0,0 @@ -16 -org=896,0 -mpink diff --git a/cdimg/DATA/LEVELS/LEVEL1.LVL b/cdimg/DATA/LEVELS/LEVEL1.LVL index 84591f8..dfb0751 100644 Binary files a/cdimg/DATA/LEVELS/LEVEL1.LVL and b/cdimg/DATA/LEVELS/LEVEL1.LVL differ diff --git a/cdimg/DATA/LEVELS/LEVEL2.LVL b/cdimg/DATA/LEVELS/LEVEL2.LVL index 1d08d3d..34361d3 100644 Binary files a/cdimg/DATA/LEVELS/LEVEL2.LVL and b/cdimg/DATA/LEVELS/LEVEL2.LVL differ