浏览代码

Build new maps in memory, rather than immediately writing to files

Marcus Huderle 6 年前
父节点
当前提交
5c0f628f0d
共有 5 个文件被更改,包括 249 次插入132 次删除
  1. 2
    0
      mainwindow.cpp
  2. 1
    1
      map.cpp
  3. 2
    0
      map.h
  4. 237
    131
      project.cpp
  5. 7
    0
      project.h

+ 2
- 0
mainwindow.cpp 查看文件

@@ -391,6 +391,8 @@ void MainWindow::onAddNewMapToGroupClick(QAction* triggeredAction)
391 391
     int numMapsInGroup = groupItem->rowCount();
392 392
     QStandardItem *newMapItem = createMapItem(newMapName, groupNum, numMapsInGroup);
393 393
     groupItem->appendRow(newMapItem);
394
+
395
+    setMap(newMapName);
394 396
 }
395 397
 
396 398
 void MainWindow::on_mapList_activated(const QModelIndex &index)

+ 1
- 1
map.cpp 查看文件

@@ -732,5 +732,5 @@ void Map::addEvent(Event *event) {
732 732
 }
733 733
 
734 734
 bool Map::hasUnsavedChanges() {
735
-    return !history.isSaved();
735
+    return !history.isSaved() || !isPersistedToFile;
736 736
 }

+ 2
- 0
map.h 查看文件

@@ -103,6 +103,8 @@ public:
103 103
 
104 104
     Blockdata* blockdata = NULL;
105 105
 
106
+    bool isPersistedToFile = true;
107
+
106 108
 public:
107 109
     void setName(QString mapName);
108 110
     static QString mapConstantFromName(QString mapName);

+ 237
- 131
project.cpp 查看文件

@@ -35,9 +35,15 @@ QString Project::getProjectTitle() {
35 35
 }
36 36
 
37 37
 Map* Project::loadMap(QString map_name) {
38
-    Map *map = new Map;
38
+    // New maps are saved to actual files yet, so we need to fetch their data from the map_cache.
39
+    Map *map;
40
+    if (map_cache->contains(map_name) && !map_cache->value(map_name)->isPersistedToFile) {
41
+        map = map_cache->value(map_name);
42
+    } else {
43
+        map = new Map;
44
+        map->setName(map_name);
45
+    }
39 46
 
40
-    map->setName(map_name);
41 47
     readMapHeader(map);
42 48
     readMapAttributes(map);
43 49
     getTilesets(map);
@@ -53,6 +59,10 @@ Map* Project::loadMap(QString map_name) {
53 59
 }
54 60
 
55 61
 void Project::loadMapConnections(Map *map) {
62
+    if (!map->isPersistedToFile) {
63
+        return;
64
+    }
65
+
56 66
     map->connections.clear();
57 67
     if (!map->connections_label.isNull()) {
58 68
         QString path = root + QString("/data/maps/%1/connections.inc").arg(map->name);
@@ -85,6 +95,10 @@ void Project::loadMapConnections(Map *map) {
85 95
     }
86 96
 }
87 97
 
98
+void Project::setNewMapConnections(Map *map) {
99
+    map->connections.clear();
100
+}
101
+
88 102
 QList<QStringList>* Project::getLabelMacros(QList<QStringList> *list, QString label) {
89 103
     bool in_label = false;
90 104
     QList<QStringList> *new_list = new QList<QStringList>;
@@ -128,6 +142,10 @@ QStringList* Project::getLabelValues(QList<QStringList> *list, QString label) {
128 142
 }
129 143
 
130 144
 void Project::readMapHeader(Map* map) {
145
+    if (!map->isPersistedToFile) {
146
+        return;
147
+    }
148
+
131 149
     QString label = map->name;
132 150
     Asm *parser = new Asm;
133 151
 
@@ -151,6 +169,22 @@ void Project::readMapHeader(Map* map) {
151 169
     map->battle_scene = header->value(12);
152 170
 }
153 171
 
172
+void Project::setNewMapHeader(Map* map, int mapIndex) {
173
+    map->attributes_label = QString("%1_MapAttributes").arg(map->name);
174
+    map->events_label = QString("%1_MapEvents").arg(map->name);;
175
+    map->scripts_label = QString("%1_MapScripts").arg(map->name);;
176
+    map->connections_label = "0x0";
177
+    map->song = "BGM_DAN02";
178
+    map->index = mapIndex;
179
+    map->location = "0";
180
+    map->visibility = "0";
181
+    map->weather = "2";
182
+    map->type = "1";
183
+    map->unknown = "0";
184
+    map->show_location = "1";
185
+    map->battle_scene = "0";
186
+}
187
+
154 188
 void Project::saveMapHeader(Map *map) {
155 189
     QString label = map->name;
156 190
     QString header_path = root + "/data/maps/" + label + "/header.inc";
@@ -220,6 +254,10 @@ QString Project::getMapAttributesTableFilepath() {
220 254
 }
221 255
 
222 256
 void Project::readMapAttributes(Map* map) {
257
+    if (!map->isPersistedToFile) {
258
+        return;
259
+    }
260
+
223 261
     Asm *parser = new Asm;
224 262
 
225 263
     QString assets_text = readTextFile(root + "/data/maps/_assets.inc");
@@ -235,6 +273,15 @@ void Project::readMapAttributes(Map* map) {
235 273
     map->tileset_secondary_label = attributes->value(5);
236 274
 }
237 275
 
276
+void Project::setNewMapAttributes(Map* map) {
277
+    map->width = "20";
278
+    map->height = "20";
279
+    map->border_label = QString("%1_MapBorder").arg(map->name);
280
+    map->blockdata_label = QString("%1_MapBlockdata").arg(map->name);
281
+    map->tileset_primary_label = "gTileset_General";
282
+    map->tileset_secondary_label = "gTileset_Petalburg";
283
+}
284
+
238 285
 void Project::getTilesets(Map* map) {
239 286
     map->tileset_primary = getTileset(map->tileset_primary_label);
240 287
     map->tileset_secondary = getTileset(map->tileset_secondary_label);
@@ -287,15 +334,40 @@ QString Project::getMapBorderPath(Map *map) {
287 334
 }
288 335
 
289 336
 void Project::loadBlockdata(Map* map) {
337
+    if (!map->isPersistedToFile) {
338
+        return;
339
+    }
340
+
290 341
     QString path = getBlockdataPath(map);
291 342
     map->blockdata = readBlockdata(path);
292 343
 }
293 344
 
345
+void Project::setNewMapBlockdata(Map* map) {
346
+    Blockdata *blockdata = new Blockdata;
347
+    for (int i = 0; i < map->getWidth() * map->getHeight(); i++) {
348
+        blockdata->addBlock(qint16(0x3001));
349
+    }
350
+    map->blockdata = blockdata;
351
+}
352
+
294 353
 void Project::loadMapBorder(Map *map) {
354
+    if (!map->isPersistedToFile) {
355
+        return;
356
+    }
357
+
295 358
     QString path = getMapBorderPath(map);
296 359
     map->border = readBlockdata(path);
297 360
 }
298 361
 
362
+void Project::setNewMapBorder(Map *map) {
363
+    Blockdata *blockdata = new Blockdata;
364
+    blockdata->addBlock(qint16(0x01D4));
365
+    blockdata->addBlock(qint16(0x01D5));
366
+    blockdata->addBlock(qint16(0x01DC));
367
+    blockdata->addBlock(qint16(0x01DD));
368
+    map->border = blockdata;
369
+}
370
+
299 371
 void Project::saveBlockdata(Map* map) {
300 372
     QString path = getBlockdataPath(map);
301 373
     writeBlockdata(path, map->blockdata);
@@ -616,138 +688,154 @@ void Project::addNewMapToGroup(QString mapName, int groupNum) {
616 688
     int mapIndex = mapAttributesTable->count() + 1;
617 689
     mapAttributesTable->insert(mapIndex, mapName);
618 690
 
619
-    QString dataDir = QString("%1/data/").arg(root);
620
-    QString dataMapsDir = QString("%1maps/").arg(dataDir);
621
-    QString newMapDataDir = QString("%1%2/").arg(dataMapsDir).arg(mapName);
622
-
623
-    // 1. Create directory data/maps/<map_name>/
624
-    if (!QDir::root().mkdir(newMapDataDir)) {
625
-        qDebug() << "Error: failed to create directory for new map. " << newMapDataDir;
626
-        return;
627
-    }
628
-
629
-    // 2. Create file data/maps/<map_name>/border.bin
630
-    QFile borderFile(newMapDataDir + "border.bin");
631
-    borderFile.open(QIODevice::WriteOnly);
632
-    QDataStream borderStream(&borderFile);
633
-    borderStream.setByteOrder(QDataStream::LittleEndian);
634
-    borderStream << qint16(0x01D4) << qint16(0x01D5) << qint16(0x01DC) << qint16(0x01DD);
635
-    borderFile.close();
636
-
637
-    // 3. Create file data/maps/<map_name>/header.inc
638
-    QFile headerFile(newMapDataDir + "header.inc");
639
-    headerFile.open(QIODevice::WriteOnly);
640
-    QTextStream headerStream(&headerFile);
641
-    headerStream << mapName << "::" << endl
642
-                 << "\t.4byte " << mapName << "_MapAttributes" << endl
643
-                 << "\t.4byte " << mapName << "_MapEvents" << endl
644
-                 << "\t.4byte " << mapName << "_MapScripts" << endl
645
-                 << "\t.4byte 0x0" << endl
646
-                 << "\t.2byte BGM_DAN02" << endl
647
-                 << "\t.2byte " << mapIndex << endl
648
-                 << "\t.byte 0" << endl
649
-                 << "\t.byte 0" << endl
650
-                 << "\t.byte 11" << endl
651
-                 << "\t.byte 4" << endl
652
-                 << "\t.2byte 0" << endl
653
-                 << "\t.byte 1" << endl
654
-                 << "\t.byte 0" << endl;
655
-    headerFile.close();
656
-
657
-    // 4. Create file data/maps/<map_name>/map.bin
658
-    QFile mapFile(newMapDataDir + "map.bin");
659
-    mapFile.open(QIODevice::WriteOnly);
660
-    QDataStream mapStream(&mapFile);
661
-    mapStream.setByteOrder(QDataStream::LittleEndian);
662
-    for (int i = 0; i < 20 * 20; i++) {
663
-        mapStream << qint16(0x3001);
664
-    }
665
-    mapFile.close();
666
-
667
-    // 5. Create file data/maps/events/<map_name>.inc
668
-    QFile eventsFile(dataMapsDir + "events/" + mapName + ".inc");
669
-    eventsFile.open(QIODevice::WriteOnly);
670
-    QTextStream eventsStream(&eventsFile);
671
-    eventsStream << mapName << "_MapEvents::" << endl
672
-                 << "\tmap_events 0x0, 0x0, 0x0, 0x0" << endl;
673
-    eventsFile.close();
674
-
675
-    // 6. Create file data/scripts/maps/<map_name>.inc
676
-    QFile scriptsFile(dataDir + "scripts/maps/" + mapName + ".inc");
677
-    scriptsFile.open(QIODevice::WriteOnly);
678
-    QTextStream scriptsStream(&scriptsFile);
679
-    scriptsStream << mapName << "_MapScripts::" << endl
680
-                  << "\t.byte 0" << endl;
681
-    scriptsFile.close();
682
-
683
-    // 7. Create file data/text/maps/<map_name>.inc
684
-    QFile textFile(dataDir + "text/maps/" + mapName + ".inc");
685
-    textFile.open(QIODevice::WriteOnly);
686
-    QTextStream textStream(&textFile);
687
-    textStream << endl;
688
-    textFile.close();
689
-
690
-    // 8. Modify data/event_scripts.s:
691
-    QFile eventScriptsFile(dataDir + "event_scripts.s");
692
-    eventScriptsFile.open(QIODevice::Append);
693
-    QTextStream eventScriptsStream(&eventScriptsFile);
694
-    eventScriptsStream << endl
695
-                       << "\t.include \"data/scripts/maps/" << mapName << ".inc\"" << endl
696
-                       << "\t.include \"data/text/maps/" << mapName << ".inc\"" << endl;
697
-    eventScriptsFile.close();
698
-
699
-    // 9. Modify data/map_events.s:
700
-    QFile mapEventsFile(dataDir + "map_events.s");
701
-    mapEventsFile.open(QIODevice::Append);
702
-    QTextStream mapEventsStream(&mapEventsFile);
703
-    mapEventsStream << endl
704
-                    << "\t.include \"data/maps/events/" << mapName << ".inc\"" << endl;
705
-    mapEventsFile.close();
706
-
707
-    // 10. Modify data/maps/_assets.inc
708
-    QFile assetsFile(dataMapsDir + "_assets.inc");
709
-    assetsFile.open(QIODevice::Append);
710
-    QTextStream assetsStream(&assetsFile);
711
-    assetsStream << endl
712
-                 << mapName << "_MapBorder::" << endl
713
-                 << "\t.incbin \"data/maps/" << mapName << "/border.bin\"" << endl
714
-                 << endl
715
-                 << mapName << "_MapBlockdata::" << endl
716
-                 << "\t.incbin \"data/maps/" << mapName << "/map.bin\"" << endl
717
-                 << endl
718
-                 << "\t.align 2" << endl
719
-                 << mapName << "_MapAttributes::" << endl
720
-                 << "\t.4byte 0x14" << endl
721
-                 << "\t.4byte 0x14" << endl
722
-                 << "\t.4byte " << mapName << "_MapBorder" << endl
723
-                 << "\t.4byte " << mapName << "_MapBlockdata" << endl
724
-                 << "\t.4byte gTileset_General" << endl
725
-                 << "\t.4byte gTileset_Pacifidlog" << endl
726
-                 << endl;
727
-    assetsFile.close();
728
-
729
-    // 11. Modify data/maps/_groups.inc
730
-    // TODO:
731
-
732
-    // 12. Modify data/maps/attributes_table.inc
733
-    QFile attributesFile(dataMapsDir + "attributes_table.inc");
734
-    attributesFile.open(QIODevice::Append);
735
-    QTextStream attributesStream(&attributesFile);
736
-    attributesStream << endl
737
-                    << "\t.4byte " << mapName << "_MapAttributes" << endl;
738
-    attributesFile.close();
739
-
740
-    // 13. Modify data/maps/headers.inc
741
-    QFile headersFile(dataMapsDir + "headers.inc");
742
-    headersFile.open(QIODevice::Append);
743
-    QTextStream headersStream(&headersFile);
744
-    headersStream << endl
745
-                    << "\t.include \"data/maps/" << mapName << "/header.inc\"" << endl;
746
-    headersFile.close();
747
-
691
+    // Setup new map in memory, but don't write to file until map is actually saved later.
748 692
     mapNames->append(mapName);
749 693
     map_groups->insert(mapName, groupNum);
750 694
     groupedMapNames->value(groupNum)->append(mapName);
695
+
696
+    Map *map = new Map;
697
+    map->isPersistedToFile = false;
698
+    map->setName(mapName);
699
+    setNewMapHeader(map, mapIndex);
700
+    setNewMapAttributes(map);
701
+    getTilesets(map);
702
+    setNewMapBlockdata(map);
703
+    setNewMapBorder(map);
704
+    setNewMapEvents(map);
705
+    setNewMapConnections(map);
706
+    map->commit();
707
+    map->history.save();
708
+    map_cache->insert(mapName, map);
709
+
710
+
711
+//    QString dataDir = QString("%1/data/").arg(root);
712
+//    QString dataMapsDir = QString("%1maps/").arg(dataDir);
713
+//    QString newMapDataDir = QString("%1%2/").arg(dataMapsDir).arg(mapName);
714
+
715
+//    // 1. Create directory data/maps/<map_name>/
716
+//    if (!QDir::root().mkdir(newMapDataDir)) {
717
+//        qDebug() << "Error: failed to create directory for new map. " << newMapDataDir;
718
+//        return;
719
+//    }
720
+
721
+//    // 2. Create file data/maps/<map_name>/border.bin
722
+//    QFile borderFile(newMapDataDir + "border.bin");
723
+//    borderFile.open(QIODevice::WriteOnly);
724
+//    QDataStream borderStream(&borderFile);
725
+//    borderStream.setByteOrder(QDataStream::LittleEndian);
726
+//    borderStream << qint16(0x01D4) << qint16(0x01D5) << qint16(0x01DC) << qint16(0x01DD);
727
+//    borderFile.close();
728
+
729
+//    // 3. Create file data/maps/<map_name>/header.inc
730
+//    QFile headerFile(newMapDataDir + "header.inc");
731
+//    headerFile.open(QIODevice::WriteOnly);
732
+//    QTextStream headerStream(&headerFile);
733
+//    headerStream << mapName << "::" << endl
734
+//                 << "\t.4byte " << mapName << "_MapAttributes" << endl
735
+//                 << "\t.4byte " << mapName << "_MapEvents" << endl
736
+//                 << "\t.4byte " << mapName << "_MapScripts" << endl
737
+//                 << "\t.4byte 0x0" << endl
738
+//                 << "\t.2byte BGM_DAN02" << endl
739
+//                 << "\t.2byte " << mapIndex << endl
740
+//                 << "\t.byte 0" << endl
741
+//                 << "\t.byte 0" << endl
742
+//                 << "\t.byte 11" << endl
743
+//                 << "\t.byte 4" << endl
744
+//                 << "\t.2byte 0" << endl
745
+//                 << "\t.byte 1" << endl
746
+//                 << "\t.byte 0" << endl;
747
+//    headerFile.close();
748
+
749
+//    // 4. Create file data/maps/<map_name>/map.bin
750
+//    QFile mapFile(newMapDataDir + "map.bin");
751
+//    mapFile.open(QIODevice::WriteOnly);
752
+//    QDataStream mapStream(&mapFile);
753
+//    mapStream.setByteOrder(QDataStream::LittleEndian);
754
+//    for (int i = 0; i < 20 * 20; i++) {
755
+//        mapStream << qint16(0x3001);
756
+//    }
757
+//    mapFile.close();
758
+
759
+//    // 5. Create file data/maps/events/<map_name>.inc
760
+//    QFile eventsFile(dataMapsDir + "events/" + mapName + ".inc");
761
+//    eventsFile.open(QIODevice::WriteOnly);
762
+//    QTextStream eventsStream(&eventsFile);
763
+//    eventsStream << mapName << "_MapEvents::" << endl
764
+//                 << "\tmap_events 0x0, 0x0, 0x0, 0x0" << endl;
765
+//    eventsFile.close();
766
+
767
+//    // 6. Create file data/scripts/maps/<map_name>.inc
768
+//    QFile scriptsFile(dataDir + "scripts/maps/" + mapName + ".inc");
769
+//    scriptsFile.open(QIODevice::WriteOnly);
770
+//    QTextStream scriptsStream(&scriptsFile);
771
+//    scriptsStream << mapName << "_MapScripts::" << endl
772
+//                  << "\t.byte 0" << endl;
773
+//    scriptsFile.close();
774
+
775
+//    // 7. Create file data/text/maps/<map_name>.inc
776
+//    QFile textFile(dataDir + "text/maps/" + mapName + ".inc");
777
+//    textFile.open(QIODevice::WriteOnly);
778
+//    QTextStream textStream(&textFile);
779
+//    textStream << endl;
780
+//    textFile.close();
781
+
782
+//    // 8. Modify data/event_scripts.s:
783
+//    QFile eventScriptsFile(dataDir + "event_scripts.s");
784
+//    eventScriptsFile.open(QIODevice::Append);
785
+//    QTextStream eventScriptsStream(&eventScriptsFile);
786
+//    eventScriptsStream << endl
787
+//                       << "\t.include \"data/scripts/maps/" << mapName << ".inc\"" << endl
788
+//                       << "\t.include \"data/text/maps/" << mapName << ".inc\"" << endl;
789
+//    eventScriptsFile.close();
790
+
791
+//    // 9. Modify data/map_events.s:
792
+//    QFile mapEventsFile(dataDir + "map_events.s");
793
+//    mapEventsFile.open(QIODevice::Append);
794
+//    QTextStream mapEventsStream(&mapEventsFile);
795
+//    mapEventsStream << endl
796
+//                    << "\t.include \"data/maps/events/" << mapName << ".inc\"" << endl;
797
+//    mapEventsFile.close();
798
+
799
+//    // 10. Modify data/maps/_assets.inc
800
+//    QFile assetsFile(dataMapsDir + "_assets.inc");
801
+//    assetsFile.open(QIODevice::Append);
802
+//    QTextStream assetsStream(&assetsFile);
803
+//    assetsStream << endl
804
+//                 << mapName << "_MapBorder::" << endl
805
+//                 << "\t.incbin \"data/maps/" << mapName << "/border.bin\"" << endl
806
+//                 << endl
807
+//                 << mapName << "_MapBlockdata::" << endl
808
+//                 << "\t.incbin \"data/maps/" << mapName << "/map.bin\"" << endl
809
+//                 << endl
810
+//                 << "\t.align 2" << endl
811
+//                 << mapName << "_MapAttributes::" << endl
812
+//                 << "\t.4byte 0x14" << endl
813
+//                 << "\t.4byte 0x14" << endl
814
+//                 << "\t.4byte " << mapName << "_MapBorder" << endl
815
+//                 << "\t.4byte " << mapName << "_MapBlockdata" << endl
816
+//                 << "\t.4byte gTileset_General" << endl
817
+//                 << "\t.4byte gTileset_Pacifidlog" << endl
818
+//                 << endl;
819
+//    assetsFile.close();
820
+
821
+//    // 11. Modify data/maps/_groups.inc
822
+//    // TODO:
823
+
824
+//    // 12. Modify data/maps/attributes_table.inc
825
+//    QFile attributesFile(dataMapsDir + "attributes_table.inc");
826
+//    attributesFile.open(QIODevice::Append);
827
+//    QTextStream attributesStream(&attributesFile);
828
+//    attributesStream << endl
829
+//                    << "\t.4byte " << mapName << "_MapAttributes" << endl;
830
+//    attributesFile.close();
831
+
832
+//    // 13. Modify data/maps/headers.inc
833
+//    QFile headersFile(dataMapsDir + "headers.inc");
834
+//    headersFile.open(QIODevice::Append);
835
+//    QTextStream headersStream(&headersFile);
836
+//    headersStream << endl
837
+//                    << "\t.include \"data/maps/" << mapName << "/header.inc\"" << endl;
838
+//    headersFile.close();
751 839
 }
752 840
 
753 841
 QString Project::getNewMapName() {
@@ -1036,6 +1124,10 @@ void Project::saveMapEvents(Map *map) {
1036 1124
 }
1037 1125
 
1038 1126
 void Project::readMapEvents(Map *map) {
1127
+    if (!map->isPersistedToFile) {
1128
+        return;
1129
+    }
1130
+
1039 1131
     // lazy
1040 1132
     QString path = root + QString("/data/maps/events/%1.inc").arg(map->name);
1041 1133
     QString text = readTextFile(path);
@@ -1198,6 +1290,20 @@ void Project::readMapEvents(Map *map) {
1198 1290
     }
1199 1291
 }
1200 1292
 
1293
+void Project::setNewMapEvents(Map *map) {
1294
+    map->object_events_label = "0x0";
1295
+    map->warps_label = "0x0";
1296
+    map->coord_events_label = "0x0";
1297
+    map->bg_events_label = "0x0";
1298
+    map->events["object"].clear();
1299
+    map->events["warp"].clear();
1300
+    map->events["trap"].clear();
1301
+    map->events["trap_weather"].clear();
1302
+    map->events["sign"].clear();
1303
+    map->events["event_hidden_item"].clear();
1304
+    map->events["event_secret_base"].clear();
1305
+}
1306
+
1201 1307
 QStringList Project::readCArray(QString text, QString label) {
1202 1308
     QStringList list;
1203 1309
 

+ 7
- 0
project.h 查看文件

@@ -48,6 +48,13 @@ public:
48 48
     void getTilesets(Map*);
49 49
     void loadTilesetAssets(Tileset*);
50 50
 
51
+    void setNewMapHeader(Map* map, int mapIndex);
52
+    void setNewMapAttributes(Map* map);
53
+    void setNewMapBlockdata(Map* map);
54
+    void setNewMapBorder(Map *map);
55
+    void setNewMapEvents(Map *map);
56
+    void setNewMapConnections(Map *map);
57
+
51 58
     QString getBlockdataPath(Map*);
52 59
     void saveBlockdata(Map*);
53 60
     void writeBlockdata(QString, Blockdata*);