瀏覽代碼

Merge pull request #50 from huderlem/layouts

Support new map organization
yenatch 6 年之前
父節點
當前提交
9c2cf84983
No account linked to committer's email address
共有 7 個文件被更改,包括 335 次插入422 次删除
  1. 7
    7
      editor.cpp
  2. 2
    2
      editor.h
  3. 3
    2
      mainwindow.cpp
  4. 71
    74
      map.cpp
  5. 39
    25
      map.h
  6. 199
    297
      project.cpp
  7. 14
    15
      project.h

+ 7
- 7
editor.cpp 查看文件

@@ -349,14 +349,14 @@ void Editor::displayMap() {
349 349
     connect(map_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,MapPixmapItem*)),
350 350
             this, SLOT(mouseEvent_map(QGraphicsSceneMouseEvent*,MapPixmapItem*)));
351 351
 
352
-    map_item->draw();
352
+    map_item->draw(true);
353 353
     scene->addItem(map_item);
354 354
 
355 355
     collision_item = new CollisionPixmapItem(map);
356 356
     connect(collision_item, SIGNAL(mouseEvent(QGraphicsSceneMouseEvent*,CollisionPixmapItem*)),
357 357
             this, SLOT(mouseEvent_collision(QGraphicsSceneMouseEvent*,CollisionPixmapItem*)));
358 358
 
359
-    collision_item->draw();
359
+    collision_item->draw(true);
360 360
     scene->addItem(collision_item);
361 361
 
362 362
     events_group = new EventGroup;
@@ -1077,9 +1077,9 @@ void MapPixmapItem::select(QGraphicsSceneMouseEvent *event) {
1077 1077
     }
1078 1078
 }
1079 1079
 
1080
-void MapPixmapItem::draw() {
1080
+void MapPixmapItem::draw(bool ignoreCache) {
1081 1081
     if (map) {
1082
-        setPixmap(map->render());
1082
+        setPixmap(map->render(ignoreCache));
1083 1083
     }
1084 1084
 }
1085 1085
 
@@ -1104,7 +1104,7 @@ void MapPixmapItem::updateCurHoveredTile(QPointF pos) {
1104 1104
     if (x < 0 || x >= map->getWidth() || y < 0 || y >= map->getHeight()) {
1105 1105
         map->clearHoveredTile();
1106 1106
     } else {
1107
-        int tile = map->blockdata->blocks->at(blockIndex).tile;
1107
+        int tile = map->layout->blockdata->blocks->at(blockIndex).tile;
1108 1108
         map->hoveredTileChanged(x, y, tile);
1109 1109
     }
1110 1110
 }
@@ -1141,9 +1141,9 @@ void CollisionPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
1141 1141
     emit mouseEvent(event, this);
1142 1142
 }
1143 1143
 
1144
-void CollisionPixmapItem::draw() {
1144
+void CollisionPixmapItem::draw(bool ignoreCache) {
1145 1145
     if (map) {
1146
-        setPixmap(map->renderCollision());
1146
+        setPixmap(map->renderCollision(ignoreCache));
1147 1147
     }
1148 1148
 }
1149 1149
 

+ 2
- 2
editor.h 查看文件

@@ -237,7 +237,7 @@ public:
237 237
     virtual void select(QGraphicsSceneMouseEvent*);
238 238
     virtual void undo();
239 239
     virtual void redo();
240
-    virtual void draw();
240
+    virtual void draw(bool ignoreCache = false);
241 241
 
242 242
 private:
243 243
     void updateCurHoveredTile(QPointF pos);
@@ -266,7 +266,7 @@ public:
266 266
     virtual void paint(QGraphicsSceneMouseEvent*);
267 267
     virtual void floodFill(QGraphicsSceneMouseEvent*);
268 268
     virtual void pick(QGraphicsSceneMouseEvent*);
269
-    virtual void draw();
269
+    virtual void draw(bool ignoreCache = false);
270 270
 
271 271
 signals:
272 272
     void mouseEvent(QGraphicsSceneMouseEvent *, CollisionPixmapItem *);

+ 3
- 2
mainwindow.cpp 查看文件

@@ -285,8 +285,8 @@ void MainWindow::on_checkBox_ShowLocation_clicked(bool checked)
285 285
 
286 286
 void MainWindow::loadDataStructures() {
287 287
     Project *project = editor->project;
288
-    project->readMapAttributesTable();
289
-    project->readAllMapAttributes();
288
+    project->readMapLayoutsTable();
289
+    project->readAllMapLayouts();
290 290
     project->readItemNames();
291 291
     project->readFlagNames();
292 292
     project->readVarNames();
@@ -761,6 +761,7 @@ void MainWindow::onLoadMapRequested(QString mapName, QString fromMapName) {
761 761
 }
762 762
 
763 763
 void MainWindow::onMapChanged(Map *map) {
764
+    map->layout->has_unsaved_changes = true;
764 765
     updateMapList();
765 766
 }
766 767
 

+ 71
- 74
map.cpp 查看文件

@@ -8,10 +8,6 @@
8 8
 
9 9
 Map::Map(QObject *parent) : QObject(parent)
10 10
 {
11
-    blockdata = new Blockdata;
12
-    cached_blockdata = new Blockdata;
13
-    cached_collision = new Blockdata;
14
-    cached_border = new Blockdata;
15 11
     paint_tile_index = 1;
16 12
     paint_collision = 0;
17 13
     paint_elevation = 3;
@@ -36,29 +32,29 @@ QString Map::mapConstantFromName(QString mapName) {
36 32
 }
37 33
 
38 34
 int Map::getWidth() {
39
-    return width.toInt(nullptr, 0);
35
+    return layout->width.toInt(nullptr, 0);
40 36
 }
41 37
 
42 38
 int Map::getHeight() {
43
-    return height.toInt(nullptr, 0);
39
+    return layout->height.toInt(nullptr, 0);
44 40
 }
45 41
 
46 42
 Tileset* Map::getBlockTileset(int metatile_index) {
47
-    int primary_size = 0x200;//tileset_primary->metatiles->length();
43
+    int primary_size = 0x200;
48 44
     if (metatile_index < primary_size) {
49
-        return tileset_primary;
45
+        return layout->tileset_primary;
50 46
     } else {
51
-        return tileset_secondary;
47
+        return layout->tileset_secondary;
52 48
     }
53 49
 }
54 50
 
55 51
 QList<QList<QRgb>> Map::getBlockPalettes(int metatile_index) {
56 52
     QList<QList<QRgb>> palettes;
57 53
     for (int i = 0; i < 6; i++) {
58
-        palettes.append(tileset_primary->palettes->at(i));
54
+        palettes.append(layout->tileset_primary->palettes->at(i));
59 55
     }
60
-    for (int i = 6; i < tileset_secondary->palettes->length(); i++) {
61
-        palettes.append(tileset_secondary->palettes->at(i));
56
+    for (int i = 6; i < layout->tileset_secondary->palettes->length(); i++) {
57
+        palettes.append(layout->tileset_secondary->palettes->at(i));
62 58
     }
63 59
     return palettes;
64 60
 }
@@ -73,18 +69,18 @@ int Map::getBlockIndex(int index) {
73 69
 }
74 70
 
75 71
 int Map::getSelectedBlockIndex(int index) {
76
-    if (index < tileset_primary->metatiles->length()) {
72
+    if (index < layout->tileset_primary->metatiles->length()) {
77 73
         return index;
78 74
     } else {
79
-        return 0x200 + (index - tileset_primary->metatiles->length());
75
+        return 0x200 + (index - layout->tileset_primary->metatiles->length());
80 76
     }
81 77
 }
82 78
 
83 79
 int Map::getDisplayedBlockIndex(int index) {
84
-    if (index < tileset_primary->metatiles->length()) {
80
+    if (index < layout->tileset_primary->metatiles->length()) {
85 81
         return index;
86 82
     } else {
87
-        return index - 0x200 + tileset_primary->metatiles->length();
83
+        return index - 0x200 + layout->tileset_primary->metatiles->length();
88 84
     }
89 85
 }
90 86
 
@@ -205,58 +201,58 @@ bool Map::blockChanged(int i, Blockdata *cache) {
205 201
     if (cache == NULL || cache == nullptr) {
206 202
         return true;
207 203
     }
208
-    if (blockdata == NULL || blockdata == nullptr) {
204
+    if (layout->blockdata == NULL || layout->blockdata == nullptr) {
209 205
         return true;
210 206
     }
211 207
     if (cache->blocks == NULL || cache->blocks == nullptr) {
212 208
         return true;
213 209
     }
214
-    if (blockdata->blocks == NULL || blockdata->blocks == nullptr) {
210
+    if (layout->blockdata->blocks == NULL || layout->blockdata->blocks == nullptr) {
215 211
         return true;
216 212
     }
217 213
     if (cache->blocks->length() <= i) {
218 214
         return true;
219 215
     }
220
-    if (blockdata->blocks->length() <= i) {
216
+    if (layout->blockdata->blocks->length() <= i) {
221 217
         return true;
222 218
     }
223
-    return blockdata->blocks->value(i) != cache->blocks->value(i);
219
+    return layout->blockdata->blocks->value(i) != cache->blocks->value(i);
224 220
 }
225 221
 
226 222
 void Map::cacheBorder() {
227
-    if (cached_border) delete cached_border;
228
-    cached_border = new Blockdata;
229
-    if (border && border->blocks) {
230
-        for (int i = 0; i < border->blocks->length(); i++) {
231
-            Block block = border->blocks->value(i);
232
-            cached_border->blocks->append(block);
223
+    if (layout->cached_border) delete layout->cached_border;
224
+    layout->cached_border = new Blockdata;
225
+    if (layout->border && layout->border->blocks) {
226
+        for (int i = 0; i < layout->border->blocks->length(); i++) {
227
+            Block block = layout->border->blocks->value(i);
228
+            layout->cached_border->blocks->append(block);
233 229
         }
234 230
     }
235 231
 }
236 232
 
237 233
 void Map::cacheBlockdata() {
238
-    if (cached_blockdata) delete cached_blockdata;
239
-    cached_blockdata = new Blockdata;
240
-    if (blockdata && blockdata->blocks) {
241
-        for (int i = 0; i < blockdata->blocks->length(); i++) {
242
-            Block block = blockdata->blocks->value(i);
243
-            cached_blockdata->blocks->append(block);
234
+    if (layout->cached_blockdata) delete layout->cached_blockdata;
235
+    layout->cached_blockdata = new Blockdata;
236
+    if (layout->blockdata && layout->blockdata->blocks) {
237
+        for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
238
+            Block block = layout->blockdata->blocks->value(i);
239
+            layout->cached_blockdata->blocks->append(block);
244 240
         }
245 241
     }
246 242
 }
247 243
 
248 244
 void Map::cacheCollision() {
249
-    if (cached_collision) delete cached_collision;
250
-    cached_collision = new Blockdata;
251
-    if (blockdata && blockdata->blocks) {
252
-        for (int i = 0; i < blockdata->blocks->length(); i++) {
253
-            Block block = blockdata->blocks->value(i);
254
-            cached_collision->blocks->append(block);
245
+    if (layout->cached_collision) delete layout->cached_collision;
246
+    layout->cached_collision = new Blockdata;
247
+    if (layout->blockdata && layout->blockdata->blocks) {
248
+        for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
249
+            Block block = layout->blockdata->blocks->value(i);
250
+            layout->cached_collision->blocks->append(block);
255 251
         }
256 252
     }
257 253
 }
258 254
 
259
-QPixmap Map::renderCollision() {
255
+QPixmap Map::renderCollision(bool ignoreCache) {
260 256
     bool changed_any = false;
261 257
     int width_ = getWidth();
262 258
     int height_ = getHeight();
@@ -268,17 +264,17 @@ QPixmap Map::renderCollision() {
268 264
         collision_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
269 265
         changed_any = true;
270 266
     }
271
-    if (!(blockdata && blockdata->blocks && width_ && height_)) {
267
+    if (!(layout->blockdata && layout->blockdata->blocks && width_ && height_)) {
272 268
         collision_pixmap = collision_pixmap.fromImage(collision_image);
273 269
         return collision_pixmap;
274 270
     }
275 271
     QPainter painter(&collision_image);
276
-    for (int i = 0; i < blockdata->blocks->length(); i++) {
277
-        if (cached_collision && !blockChanged(i, cached_collision)) {
272
+    for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
273
+        if (!ignoreCache && layout->cached_collision && !blockChanged(i, layout->cached_collision)) {
278 274
             continue;
279 275
         }
280 276
         changed_any = true;
281
-        Block block = blockdata->blocks->value(i);
277
+        Block block = layout->blockdata->blocks->value(i);
282 278
         QImage metatile_image = getMetatileImage(block.tile);
283 279
         QImage collision_metatile_image = getCollisionMetatileImage(block);
284 280
         QImage elevation_metatile_image = getElevationMetatileImage(block);
@@ -324,7 +320,7 @@ QPixmap Map::renderCollision() {
324 320
     return collision_pixmap;
325 321
 }
326 322
 
327
-QPixmap Map::render() {
323
+QPixmap Map::render(bool ignoreCache = false) {
328 324
     bool changed_any = false;
329 325
     int width_ = getWidth();
330 326
     int height_ = getHeight();
@@ -336,18 +332,18 @@ QPixmap Map::render() {
336 332
         image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
337 333
         changed_any = true;
338 334
     }
339
-    if (!(blockdata && blockdata->blocks && width_ && height_)) {
335
+    if (!(layout->blockdata && layout->blockdata->blocks && width_ && height_)) {
340 336
         pixmap = pixmap.fromImage(image);
341 337
         return pixmap;
342 338
     }
343 339
 
344 340
     QPainter painter(&image);
345
-    for (int i = 0; i < blockdata->blocks->length(); i++) {
346
-        if (!blockChanged(i, cached_blockdata)) {
341
+    for (int i = 0; i < layout->blockdata->blocks->length(); i++) {
342
+        if (!ignoreCache && !blockChanged(i, layout->cached_blockdata)) {
347 343
             continue;
348 344
         }
349 345
         changed_any = true;
350
-        Block block = blockdata->blocks->value(i);
346
+        Block block = layout->blockdata->blocks->value(i);
351 347
         QImage metatile_image = getMetatileImage(block.tile);
352 348
         int map_y = width_ ? i / width_ : 0;
353 349
         int map_x = width_ ? i % width_ : 0;
@@ -366,21 +362,21 @@ QPixmap Map::renderBorder() {
366 362
     bool changed_any = false;
367 363
     int width_ = 2;
368 364
     int height_ = 2;
369
-    if (border_image.isNull()) {
370
-        border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
365
+    if (layout->border_image.isNull()) {
366
+        layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
371 367
         changed_any = true;
372 368
     }
373
-    if (!(border && border->blocks)) {
374
-        border_pixmap = border_pixmap.fromImage(border_image);
375
-        return border_pixmap;
369
+    if (!(layout->border && layout->border->blocks)) {
370
+        layout->border_pixmap = layout->border_pixmap.fromImage(layout->border_image);
371
+        return layout->border_pixmap;
376 372
     }
377
-    QPainter painter(&border_image);
378
-    for (int i = 0; i < border->blocks->length(); i++) {
379
-        if (!blockChanged(i, cached_border)) {
373
+    QPainter painter(&layout->border_image);
374
+    for (int i = 0; i < layout->border->blocks->length(); i++) {
375
+        if (!blockChanged(i, layout->cached_border)) {
380 376
             continue;
381 377
         }
382 378
         changed_any = true;
383
-        Block block = border->blocks->value(i);
379
+        Block block = layout->border->blocks->value(i);
384 380
         QImage metatile_image = getMetatileImage(block.tile);
385 381
         int map_y = i / width_;
386 382
         int map_x = i % width_;
@@ -389,9 +385,9 @@ QPixmap Map::renderBorder() {
389 385
     painter.end();
390 386
     if (changed_any) {
391 387
         cacheBorder();
392
-        border_pixmap = border_pixmap.fromImage(border_image);
388
+        layout->border_pixmap = layout->border_pixmap.fromImage(layout->border_image);
393 389
     }
394
-    return border_pixmap;
390
+    return layout->border_pixmap;
395 391
 }
396 392
 
397 393
 QPixmap Map::renderConnection(Connection connection) {
@@ -482,11 +478,12 @@ void Map::drawSelection(int i, int w, int selectionWidth, int selectionHeight, Q
482 478
 }
483 479
 
484 480
 QPixmap Map::renderMetatiles() {
485
-    if (!tileset_primary || !tileset_primary->metatiles || !tileset_secondary || !tileset_secondary->metatiles) {
481
+    if (!layout->tileset_primary || !layout->tileset_primary->metatiles
482
+     || !layout->tileset_secondary || !layout->tileset_secondary->metatiles) {
486 483
         return QPixmap();
487 484
     }
488
-    int primary_length = tileset_primary->metatiles->length();
489
-    int length_ = primary_length + tileset_secondary->metatiles->length();
485
+    int primary_length = layout->tileset_primary->metatiles->length();
486
+    int length_ = primary_length + layout->tileset_secondary->metatiles->length();
490 487
     int width_ = 8;
491 488
     int height_ = length_ / width_;
492 489
     QImage image(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
@@ -510,11 +507,11 @@ QPixmap Map::renderMetatiles() {
510 507
 }
511 508
 
512 509
 Block* Map::getBlock(int x, int y) {
513
-    if (blockdata && blockdata->blocks) {
510
+    if (layout->blockdata && layout->blockdata->blocks) {
514 511
         if (x >= 0 && x < getWidth())
515 512
         if (y >= 0 && y < getHeight()) {
516 513
             int i = y * getWidth() + x;
517
-            return new Block(blockdata->blocks->value(i));
514
+            return new Block(layout->blockdata->blocks->value(i));
518 515
         }
519 516
     }
520 517
     return NULL;
@@ -522,8 +519,8 @@ Block* Map::getBlock(int x, int y) {
522 519
 
523 520
 void Map::_setBlock(int x, int y, Block block) {
524 521
     int i = y * getWidth() + x;
525
-    if (blockdata && blockdata->blocks) {
526
-        blockdata->blocks->replace(i, block);
522
+    if (layout->blockdata && layout->blockdata->blocks) {
523
+        layout->blockdata->blocks->replace(i, block);
527 524
     }
528 525
 }
529 526
 
@@ -660,29 +657,29 @@ void Map::_floodFillCollisionElevation(int x, int y, uint collision, uint elevat
660 657
 
661 658
 
662 659
 void Map::undo() {
663
-    if (blockdata) {
660
+    if (layout->blockdata) {
664 661
         Blockdata *commit = history.back();
665 662
         if (commit != NULL) {
666
-            blockdata->copyFrom(commit);
663
+            layout->blockdata->copyFrom(commit);
667 664
             emit mapChanged(this);
668 665
         }
669 666
     }
670 667
 }
671 668
 
672 669
 void Map::redo() {
673
-    if (blockdata) {
670
+    if (layout->blockdata) {
674 671
         Blockdata *commit = history.next();
675 672
         if (commit != NULL) {
676
-            blockdata->copyFrom(commit);
673
+            layout->blockdata->copyFrom(commit);
677 674
             emit mapChanged(this);
678 675
         }
679 676
     }
680 677
 }
681 678
 
682 679
 void Map::commit() {
683
-    if (blockdata) {
684
-        if (!blockdata->equals(history.current())) {
685
-            Blockdata* commit = blockdata->copy();
680
+    if (layout->blockdata) {
681
+        if (!layout->blockdata->equals(history.current())) {
682
+            Blockdata* commit = layout->blockdata->copy();
686 683
             history.push(commit);
687 684
             emit mapChanged(this);
688 685
         }
@@ -752,7 +749,7 @@ void Map::addEvent(Event *event) {
752 749
 }
753 750
 
754 751
 bool Map::hasUnsavedChanges() {
755
-    return !history.isSaved() || !isPersistedToFile;
752
+    return !history.isSaved() || !isPersistedToFile || layout->has_unsaved_changes;
756 753
 }
757 754
 
758 755
 void Map::hoveredTileChanged(int x, int y, int block) {

+ 39
- 25
map.h 查看文件

@@ -68,6 +68,37 @@ public:
68 68
     QString map_name;
69 69
 };
70 70
 
71
+class MapLayout {
72
+public:
73
+    MapLayout() {}
74
+    int index;
75
+    QString name;
76
+    QString label;
77
+    QString width;
78
+    QString height;
79
+    QString border_label;
80
+    QString border_path;
81
+    QString blockdata_label;
82
+    QString blockdata_path;
83
+    QString tileset_primary_label;
84
+    QString tileset_secondary_label;
85
+    Tileset *tileset_primary = NULL;
86
+    Tileset *tileset_secondary = NULL;
87
+    Blockdata* blockdata = NULL;
88
+    QImage border_image;
89
+    QPixmap border_pixmap;
90
+    Blockdata *border = NULL;
91
+    Blockdata *cached_blockdata = NULL;
92
+    Blockdata *cached_collision = NULL;
93
+    Blockdata *cached_border = NULL;
94
+    bool has_unsaved_changes = false;
95
+public:
96
+    static QString getNameFromLabel(QString label) {
97
+        // ASSUMPTION: strip off "_Layout" from layout label. Directories in 'data/layouts/' must be well-formed.
98
+        return label.replace(label.lastIndexOf("_Layout"), label.length(), "");
99
+    }
100
+};
101
+
71 102
 class Map : public QObject
72 103
 {
73 104
     Q_OBJECT
@@ -78,12 +109,12 @@ public:
78 109
     QString name;
79 110
     QString constantName;
80 111
     QString group_num;
81
-    QString attributes_label;
112
+    QString layout_label;
82 113
     QString events_label;
83 114
     QString scripts_label;
84 115
     QString connections_label;
85 116
     QString song;
86
-    QString index;
117
+    QString layout_id;
87 118
     QString location;
88 119
     QString visibility;
89 120
     QString weather;
@@ -91,18 +122,7 @@ public:
91 122
     QString unknown;
92 123
     QString show_location;
93 124
     QString battle_scene;
94
-
95
-    QString width;
96
-    QString height;
97
-    QString border_label;
98
-    QString blockdata_label;
99
-    QString tileset_primary_label;
100
-    QString tileset_secondary_label;
101
-
102
-    Tileset *tileset_primary = NULL;
103
-    Tileset *tileset_secondary = NULL;
104
-
105
-    Blockdata* blockdata = NULL;
125
+    MapLayout *layout;
106 126
 
107 127
     bool isPersistedToFile = true;
108 128
 
@@ -112,16 +132,16 @@ public:
112 132
     int getWidth();
113 133
     int getHeight();
114 134
     Tileset* getBlockTileset(int);
115
-    int getBlockIndex(int index);
116
-    int getSelectedBlockIndex(int index);
117
-    int getDisplayedBlockIndex(int index);
135
+    int getBlockIndex(int layout_id);
136
+    int getSelectedBlockIndex(int layout_id);
137
+    int getDisplayedBlockIndex(int layout_id);
118 138
     Metatile* getMetatile(int);
119 139
     QImage getMetatileImage(int);
120 140
     QImage getMetatileTile(int);
121
-    QPixmap render();
141
+    QPixmap render(bool ignoreCache);
122 142
     QPixmap renderMetatiles();
123 143
 
124
-    QPixmap renderCollision();
144
+    QPixmap renderCollision(bool ignoreCache);
125 145
     QImage collision_image;
126 146
     QPixmap collision_pixmap;
127 147
     QImage getCollisionMetatileImage(Block);
@@ -134,9 +154,7 @@ public:
134 154
     void drawSelection(int i, int w, int selectionWidth, int selectionHeight, QPainter *painter);
135 155
 
136 156
     bool blockChanged(int, Blockdata*);
137
-    Blockdata* cached_blockdata = NULL;
138 157
     void cacheBlockdata();
139
-    Blockdata* cached_collision = NULL;
140 158
     void cacheCollision();
141 159
     QImage image;
142 160
     QPixmap pixmap;
@@ -185,10 +203,6 @@ public:
185 203
     QList<QGraphicsPixmapItem*> connection_items;
186 204
     QPixmap renderConnection(Connection);
187 205
 
188
-    QImage border_image;
189
-    QPixmap border_pixmap;
190
-    Blockdata *border = NULL;
191
-    Blockdata *cached_border = NULL;
192 206
     QPixmap renderBorder();
193 207
     void cacheBorder();
194 208
 

+ 199
- 297
project.cpp 查看文件

@@ -49,10 +49,7 @@ Map* Project::loadMap(QString map_name) {
49 49
     }
50 50
 
51 51
     readMapHeader(map);
52
-    readMapAttributes(map);
53
-    getTilesets(map);
54
-    loadBlockdata(map);
55
-    loadMapBorder(map);
52
+    readMapLayout(map);
56 53
     readMapEvents(map);
57 54
     loadMapConnections(map);
58 55
     map->commit();
@@ -136,9 +133,12 @@ QStringList* Project::getLabelValues(QList<QStringList> *list, QString label) {
136 133
         QStringList params = list->value(i);
137 134
         QString macro = params.value(0);
138 135
         // Ignore .align
139
-        if (macro == ".align") {
136
+        if (macro == ".align")
137
+            continue;
138
+        if (macro == ".ifdef")
139
+            continue;
140
+        if (macro == ".ifndef")
140 141
             continue;
141
-        }
142 142
         for (int j = 1; j < params.length(); j++) {
143 143
             values->append(params.value(j));
144 144
         }
@@ -159,12 +159,12 @@ void Project::readMapHeader(Map* map) {
159 159
         return;
160 160
     }
161 161
     QStringList *header = getLabelValues(parser->parseAsm(header_text), label);
162
-    map->attributes_label = header->value(0);
162
+    map->layout_label = header->value(0);
163 163
     map->events_label = header->value(1);
164 164
     map->scripts_label = header->value(2);
165 165
     map->connections_label = header->value(3);
166 166
     map->song = header->value(4);
167
-    map->index = header->value(5);
167
+    map->layout_id = header->value(5);
168 168
     map->location = header->value(6);
169 169
     map->visibility = header->value(7);
170 170
     map->weather = header->value(8);
@@ -175,12 +175,12 @@ void Project::readMapHeader(Map* map) {
175 175
 }
176 176
 
177 177
 void Project::setNewMapHeader(Map* map, int mapIndex) {
178
-    map->attributes_label = QString("%1_MapAttributes").arg(map->name);
178
+    map->layout_label = QString("%1_Layout").arg(map->name);
179 179
     map->events_label = QString("%1_MapEvents").arg(map->name);;
180 180
     map->scripts_label = QString("%1_MapScripts").arg(map->name);;
181 181
     map->connections_label = "0x0";
182
-    map->song = "BGM_DAN02";
183
-    map->index = QString("%1").arg(mapIndex);
182
+    map->song = "MUS_DAN02";
183
+    map->layout_id = QString("%1").arg(mapIndex);
184 184
     map->location = "0";
185 185
     map->visibility = "0";
186 186
     map->weather = "2";
@@ -195,7 +195,7 @@ void Project::saveMapHeader(Map *map) {
195 195
     QString header_path = root + "/data/maps/" + label + "/header.inc";
196 196
     QString text = "";
197 197
     text += QString("%1::\n").arg(label);
198
-    text += QString("\t.4byte %1\n").arg(map->attributes_label);
198
+    text += QString("\t.4byte %1\n").arg(map->layout_label);
199 199
     text += QString("\t.4byte %1\n").arg(map->events_label);
200 200
     text += QString("\t.4byte %1\n").arg(map->scripts_label);
201 201
 
@@ -207,7 +207,7 @@ void Project::saveMapHeader(Map *map) {
207 207
     text += QString("\t.4byte %1\n").arg(map->connections_label);
208 208
 
209 209
     text += QString("\t.2byte %1\n").arg(map->song);
210
-    text += QString("\t.2byte %1\n").arg(map->index);
210
+    text += QString("\t.2byte %1\n").arg(map->layout_id);
211 211
     text += QString("\t.byte %1\n").arg(map->location);
212 212
     text += QString("\t.byte %1\n").arg(map->visibility);
213 213
     text += QString("\t.byte %1\n").arg(map->weather);
@@ -260,269 +260,180 @@ void Project::updateMapsWithConnections(Map *map) {
260 260
     }
261 261
 }
262 262
 
263
-void Project::readMapAttributesTable() {
264
-    int curMapIndex = 1;
265
-    QString attributesText = readTextFile(getMapAttributesTableFilepath());
266
-    QList<QStringList>* values = parseAsm(attributesText);
267
-    bool inAttributePointers = false;
263
+void Project::readMapLayoutsTable() {
264
+    int curIndex = 1;
265
+    QString layoutsText = readTextFile(getMapLayoutsTableFilepath());
266
+    QList<QStringList>* values = parseAsm(layoutsText);
267
+    bool inLayoutPointers = false;
268 268
     for (int i = 0; i < values->length(); i++) {
269 269
         QStringList params = values->value(i);
270 270
         QString macro = params.value(0);
271 271
         if (macro == ".label") {
272
-            if (inAttributePointers) {
272
+            if (inLayoutPointers) {
273 273
                 break;
274 274
             }
275
-            if (params.value(1) == "gMapAttributes") {
276
-                inAttributePointers = true;
275
+            if (params.value(1) == "gMapLayouts") {
276
+                inLayoutPointers = true;
277 277
             }
278
-        } else if (macro == ".4byte" && inAttributePointers) {
279
-            QString mapName = params.value(1);
280
-            if (!mapName.contains("UnknownMapAttributes")) {
281
-                // Strip off "_MapAttributes" from the label if it's a real map label.
282
-                mapName = mapName.remove(mapName.length() - 14, 14);
283
-            }
284
-            mapAttributesTable.insert(curMapIndex, mapName);
285
-            curMapIndex++;
278
+        } else if (macro == ".4byte" && inLayoutPointers) {
279
+            QString layoutName = params.value(1);
280
+            mapLayoutsTable.append(layoutName);
286 281
         }
287 282
     }
288 283
 
289 284
     // Deep copy
290
-    mapAttributesTableMaster = mapAttributesTable;
291
-    mapAttributesTableMaster.detach();
285
+    mapLayoutsTableMaster = mapLayoutsTable;
286
+    mapLayoutsTableMaster.detach();
292 287
 }
293 288
 
294
-void Project::saveMapAttributesTable() {
289
+void Project::saveMapLayoutsTable() {
295 290
     QString text = "";
296 291
     text += QString("\t.align 2\n");
297
-    text += QString("gMapAttributes::\n");
298
-    for (int i = 0; i < mapAttributesTableMaster.count(); i++) {
299
-        int mapIndex = i + 1;
300
-        QString mapName = mapAttributesTableMaster.value(mapIndex);
301
-        if (!mapName.contains("UnknownMapAttributes")) {
302
-            text += QString("\t.4byte %1_MapAttributes\n").arg(mapName);
303
-        } else {
304
-            text += QString("\t.4byte %1\n").arg(mapName);
305
-        }
292
+    text += QString("gMapLayouts::\n");
293
+    for (QString layoutName : mapLayoutsTableMaster) {
294
+        text += QString("\t.4byte %1\n").arg(layoutName);
306 295
     }
307
-    saveTextFile(getMapAttributesTableFilepath(), text);
296
+    saveTextFile(getMapLayoutsTableFilepath(), text);
308 297
 }
309 298
 
310
-QString Project::getMapAttributesTableFilepath() {
311
-    return QString("%1/data/maps/attributes_table.inc").arg(root);
299
+QString Project::getMapLayoutsTableFilepath() {
300
+    return QString("%1/data/layouts_table.inc").arg(root);
312 301
 }
313 302
 
314
-void Project::readMapAttributes(Map* map) {
315
-    if (!map->isPersistedToFile) {
316
-        return;
303
+QStringList* Project::readLayoutValues(QString layoutLabel) {
304
+    ParseUtil *parser = new ParseUtil;
305
+
306
+    QString layoutText = readTextFile(getMapLayoutFilepath(layoutLabel));
307
+    if (layoutText.isNull()) {
308
+        return NULL;
317 309
     }
318 310
 
319
-    ParseUtil *parser = new ParseUtil;
311
+    QStringList *layoutValues = getLabelValues(parser->parseAsm(layoutText), layoutLabel);
312
+    QString borderLabel = layoutValues->value(2);
313
+    QString blockdataLabel = layoutValues->value(3);
314
+    QStringList *borderValues = getLabelValues(parser->parseAsm(layoutText), borderLabel);
315
+    QString borderPath = borderValues->value(0).replace("\"", "");
316
+    layoutValues->append(borderPath);
317
+    QStringList *blockdataValues = getLabelValues(parser->parseAsm(layoutText), blockdataLabel);
318
+    QString blockdataPath = blockdataValues->value(0).replace("\"", "");
319
+    layoutValues->append(blockdataPath);
320 320
 
321
-    QString assets_text = readTextFile(getMapAssetsFilepath());
322
-    if (assets_text.isNull()) {
323
-        return;
321
+    if (layoutValues->size() != 8) {
322
+        qDebug() << "Error: Unexpected number of properties in layout '" << layoutLabel << "'";
323
+        return NULL;
324 324
     }
325
-    QStringList *attributes = getLabelValues(parser->parseAsm(assets_text), map->attributes_label);
326
-    map->width = attributes->value(0);
327
-    map->height = attributes->value(1);
328
-    map->border_label = attributes->value(2);
329
-    map->blockdata_label = attributes->value(3);
330
-    map->tileset_primary_label = attributes->value(4);
331
-    map->tileset_secondary_label = attributes->value(5);
332
-}
333 325
 
334
-void Project::readAllMapAttributes() {
335
-    mapAttributes.clear();
326
+    return layoutValues;
327
+}
336 328
 
337
-    ParseUtil *parser = new ParseUtil;
338
-    QString assets_text = readTextFile(getMapAssetsFilepath());
339
-    if (assets_text.isNull()) {
329
+void Project::readMapLayout(Map* map) {
330
+    if (!map->isPersistedToFile) {
340 331
         return;
341 332
     }
342 333
 
343
-    QList<QStringList> *commands = parser->parseAsm(assets_text);
344
-
345
-    // Assume the _assets.inc file is grouped consistently in the order of:
346
-    // 1. <map_name>_MapBorder
347
-    // 2. <map_name>_MapBlockdata
348
-    // 3. <map_name>_MapAttributes
349
-    int i = 0;
350
-    while (i < commands->length()) {
351
-        // Read MapBorder assets.
352
-        QStringList borderParams = commands->value(i++);
353
-        bool isUnknownMapBorder = borderParams.value(1).startsWith("UnknownMapBorder_");
354
-        if (borderParams.value(0) != ".label" || (!borderParams.value(1).endsWith("_MapBorder") && !isUnknownMapBorder)) {
355
-            qDebug() << QString("Expected MapBorder label, but found %1").arg(borderParams.value(1));
356
-            continue;
357
-        }
358
-        QString borderLabel = borderParams.value(1);
359
-        QString mapName;
360
-        if (!isUnknownMapBorder) {
361
-            mapName = borderLabel.remove(borderLabel.length() - 10, 10);
362
-        } else {
363
-            // Unknown map name has to match the MapAttributes label.
364
-            mapName = borderLabel.replace("Border", "Attributes");
334
+    MapLayout *layout;
335
+    if (!mapLayouts.contains(map->layout_label)) {
336
+        QStringList *layoutValues = readLayoutValues(map->layout->label);
337
+        if (layoutValues == NULL) {
338
+            return;
365 339
         }
366 340
 
367
-        mapAttributes[mapName].insert("border_label", borderParams.value(1));
368
-        borderParams = commands->value(i++);
369
-        mapAttributes[mapName].insert("border_filepath", borderParams.value(1).replace("\"", ""));
341
+        layout = new MapLayout();
342
+        mapLayouts.insert(map->layout_label, layout);
343
+        layout->name = MapLayout::getNameFromLabel(map->layout_label);
344
+        layout->label = map->layout_label;
345
+        layout->width = layoutValues->value(0);
346
+        layout->height = layoutValues->value(1);
347
+        layout->border_label = layoutValues->value(2);
348
+        layout->blockdata_label = layoutValues->value(3);
349
+        layout->tileset_primary_label = layoutValues->value(4);
350
+        layout->tileset_secondary_label = layoutValues->value(5);
351
+        layout->border_path = layoutValues->value(6);
352
+        layout->blockdata_path = layoutValues->value(7);
353
+        map->layout = layout;
354
+    } else {
355
+        map->layout = mapLayouts[map->layout_label];
356
+    }
370 357
 
371
-        // Read MapBlockData assets.
372
-        QStringList blockDataParams = commands->value(i++);
373
-        bool isUnknownMapBlockdata = blockDataParams.value(1).startsWith("UnknownMapBlockdata_");
374
-        if (blockDataParams.value(0) != ".label" || (!blockDataParams.value(1).endsWith("_MapBlockdata") && !isUnknownMapBlockdata)) {
375
-            qDebug() << QString("Expected MapBlockdata label, but found %1").arg(blockDataParams.value(1));
376
-            continue;
377
-        }
378
-        QString blockDataLabel = blockDataParams.value(1);
379
-        mapAttributes[mapName].insert("blockdata_label", blockDataLabel);
380
-        blockDataParams = commands->value(i++);
381
-        mapAttributes[mapName].insert("blockdata_filepath", blockDataParams.value(1).replace("\"", ""));
382
-
383
-        // Read MapAttributes assets.
384
-        i++; // skip .align
385
-        // Maps can share MapAttributes, so  gather a list of them.
386
-        QStringList attributeMapLabels;
387
-        QStringList attributesParams;
388
-        QStringList* sharedAttrMaps = new QStringList;
389
-        while (i < commands->length()) {
390
-            attributesParams = commands->value(i);
391
-            if (attributesParams.value(0) != ".label") {
392
-                break;
393
-            }
394
-            QString attrLabel = attributesParams.value(1);
395
-            attributeMapLabels.append(attrLabel);
396
-            sharedAttrMaps->append(attrLabel);
397
-            i++;
398
-        }
358
+    getTilesets(map);
359
+    loadBlockdata(map);
360
+    loadMapBorder(map);
361
+}
399 362
 
400
-        // Apply the map attributes to each of the shared maps.
401
-        QString attrWidth = commands->value(i++).value(1);
402
-        QString attrHeight = commands->value(i++).value(1);
403
-        QString attrBorderLabel = commands->value(i++).value(1);
404
-        QString attrBlockdataLabel = commands->value(i++).value(1);
405
-        QString attrTilesetPrimary = commands->value(i++).value(1);
406
-        QString attrTilesetSecondary = commands->value(i++).value(1);
407
-        for (QString attributeMapLabel: attributeMapLabels) {
408
-            QString altMapName = attributeMapLabel;
409
-            if (!altMapName.startsWith("UnknownMapAttributes_")) {
410
-                altMapName.remove(altMapName.length() - 14, 14);
411
-            }
412
-            if (!mapAttributes.contains(altMapName)) {
413
-                mapAttributes.insert(altMapName, QMap<QString, QString>());
414
-            }
415
-            mapAttributes[altMapName].insert("attributes_label", attributeMapLabel);
416
-            mapAttributes[altMapName].insert("width", attrWidth);
417
-            mapAttributes[altMapName].insert("height", attrHeight);
418
-            mapAttributes[altMapName].insert("border_label", attrBorderLabel);
419
-            mapAttributes[altMapName].insert("blockdata_label", attrBlockdataLabel);
420
-            mapAttributes[altMapName].insert("tileset_primary", attrTilesetPrimary);
421
-            mapAttributes[altMapName].insert("tileset_secondary", attrTilesetSecondary);
422
-
423
-            if (sharedAttrMaps->length() > 1) {
424
-                mapAttributes[altMapName].insert("shared_attr_maps", sharedAttrMaps->join(":"));
425
-            }
363
+void Project::readAllMapLayouts() {
364
+    mapLayouts.clear();
365
+
366
+    for (int i = 0; i < mapLayoutsTable.size(); i++) {
367
+        QString layoutLabel = mapLayoutsTable[i];
368
+        QStringList *layoutValues = readLayoutValues(layoutLabel);
369
+        if (layoutValues == NULL) {
370
+            return;
426 371
         }
372
+
373
+        MapLayout *layout = new MapLayout();
374
+        layout->name = MapLayout::getNameFromLabel(layoutLabel);
375
+        layout->label = layoutLabel;
376
+        layout->index = i;
377
+        layout->width = layoutValues->value(0);
378
+        layout->height = layoutValues->value(1);
379
+        layout->border_label = layoutValues->value(2);
380
+        layout->blockdata_label = layoutValues->value(3);
381
+        layout->tileset_primary_label = layoutValues->value(4);
382
+        layout->tileset_secondary_label = layoutValues->value(5);
383
+        layout->border_path = layoutValues->value(6);
384
+        layout->blockdata_path = layoutValues->value(7);
385
+        mapLayouts.insert(layoutLabel, layout);
427 386
     }
428 387
 
429 388
     // Deep copy
430
-    mapAttributesMaster = mapAttributes;
431
-    mapAttributesMaster.detach();
389
+    mapLayoutsMaster = mapLayouts;
390
+    mapLayoutsMaster.detach();
432 391
 }
433 392
 
434
-void Project::saveAllMapAttributes() {
435
-    QString text = "";
436
-    for (int i = 0; i < mapAttributesTableMaster.count(); i++) {
437
-        int mapIndex = i + 1;
438
-        QString mapName = mapAttributesTableMaster.value(mapIndex);
439
-        QMap<QString, QString> attrs = mapAttributesMaster.value(mapName);
440
-
441
-        // Find the map attributes object that contains the border data.
442
-        QMap<QString, QString> attrsWithBorder;
443
-        if (attrs.contains("border_filepath")) {
444
-            attrsWithBorder = attrs;
445
-        } else {
446
-            QStringList labels = attrs.value("shared_attr_maps").split(":");
447
-            for (QString label : labels) {
448
-                label.remove(label.length() - 14, 14);
449
-                if (mapAttributesMaster.contains(label) && mapAttributesMaster.value(label).contains("border_filepath")) {
450
-                    attrsWithBorder = mapAttributesMaster.value(label);
451
-                    break;
452
-                }
453
-            }
454
-        }
455
-        if (!attrsWithBorder.isEmpty()) {
456
-            text += QString("%1::\n").arg(attrsWithBorder.value("border_label"));
457
-            text += QString("\t.incbin \"%1\"\n").arg(attrsWithBorder.value("border_filepath"));
458
-            text += QString("\n");
459
-        }
460
-
461
-        // Find the map attributes object that contains the blockdata.
462
-        QMap<QString, QString> attrsWithBlockdata;
463
-        if (attrs.contains("blockdata_filepath")) {
464
-            attrsWithBlockdata = attrs;
465
-        } else {
466
-            QStringList labels = attrs["shared_attr_maps"].split(":");
467
-            for (QString label : labels) {
468
-                label.remove(label.length() - 14, 14);
469
-                if (mapAttributesMaster.contains(label) && mapAttributesMaster.value(label).contains("blockdata_filepath")) {
470
-                    attrsWithBlockdata = mapAttributesMaster.value(label);
471
-                    break;
472
-                }
473
-            }
474
-        }
475
-        if (!attrsWithBlockdata.isEmpty()) {
476
-            text += QString("%1::\n").arg(attrsWithBlockdata.value("blockdata_label"));
477
-            text += QString("\t.incbin \"%1\"\n").arg(attrsWithBorder.value("blockdata_filepath"));
478
-            text += QString("\n");
479
-        }
480
-
393
+void Project::saveAllMapLayouts() {
394
+    for (QString layoutName : mapLayoutsTableMaster) {
395
+        MapLayout *layout = mapLayouts.value(layoutName);
396
+        QString text = QString("%1::\n").arg(layout->border_label);
397
+        text += QString("\t.incbin \"%1\"\n").arg(layout->border_path);
398
+        text += QString("\n");
399
+        text += QString("%1::\n").arg(layout->blockdata_label);
400
+        text += QString("\t.incbin \"%1\"\n").arg(layout->blockdata_path);
401
+        text += QString("\n");
481 402
         text += QString("\t.align 2\n");
482
-        if (attrs.contains("shared_attr_maps")) {
483
-            QStringList labels = attrs.value("shared_attr_maps").split(":");
484
-            for (QString label : labels) {
485
-                text += QString("%1::\n").arg(label);
486
-            }
487
-        } else {
488
-            text += QString("%1::\n").arg(attrs.value("attributes_label"));
489
-        }
490
-        text += QString("\t.4byte %1\n").arg(attrs.value("width"));
491
-        text += QString("\t.4byte %1\n").arg(attrs.value("height"));
492
-        text += QString("\t.4byte %1\n").arg(attrs.value("border_label"));
493
-        text += QString("\t.4byte %1\n").arg(attrs.value("blockdata_label"));
494
-        text += QString("\t.4byte %1\n").arg(attrs.value("tileset_primary"));
495
-        text += QString("\t.4byte %1\n").arg(attrs.value("tileset_secondary"));
403
+        text += QString("%1::\n").arg(layoutName);
404
+        text += QString("\t.4byte %1\n").arg(layout->width);
405
+        text += QString("\t.4byte %1\n").arg(layout->height);
406
+        text += QString("\t.4byte %1\n").arg(layout->border_label);
407
+        text += QString("\t.4byte %1\n").arg(layout->blockdata_label);
408
+        text += QString("\t.4byte %1\n").arg(layout->tileset_primary_label);
409
+        text += QString("\t.4byte %1\n").arg(layout->tileset_secondary_label);
496 410
         text += QString("\n");
411
+        saveTextFile(getMapLayoutFilepath(layout->label), text);
497 412
     }
498
-
499
-    saveTextFile(getMapAssetsFilepath(), text);
500 413
 }
501 414
 
502
-QString Project::getMapAssetsFilepath() {
503
-    return root + "/data/maps/_assets.inc";
415
+QString Project::getMapLayoutFilepath(QString layoutLabel) {
416
+    return QString("%1/data/layouts/%2/layout.inc").arg(root).arg(MapLayout::getNameFromLabel(layoutLabel));
504 417
 }
505 418
 
506
-void Project::setNewMapAttributes(Map* map) {
507
-    map->width = "20";
508
-    map->height = "20";
509
-    map->border_label = QString("%1_MapBorder").arg(map->name);
510
-    map->blockdata_label = QString("%1_MapBlockdata").arg(map->name);
511
-    map->tileset_primary_label = "gTileset_General";
512
-    map->tileset_secondary_label = "gTileset_Petalburg";
419
+void Project::setNewMapLayout(Map* map) {
420
+    MapLayout *layout = new MapLayout();
421
+    layout->label = QString("%1_Layout").arg(map->name);
422
+    layout->name = MapLayout::getNameFromLabel(layout->label);
423
+    layout->width = "20";
424
+    layout->height = "20";
425
+    layout->border_label = QString("%1_MapBorder").arg(map->name);
426
+    layout->border_path = QString("data/layouts/%1/border.bin").arg(map->name);
427
+    layout->blockdata_label = QString("%1_MapBlockdata").arg(map->name);
428
+    layout->blockdata_path = QString("data/layouts/%1/map.bin").arg(map->name);
429
+    layout->tileset_primary_label = "gTileset_General";
430
+    layout->tileset_secondary_label = "gTileset_Petalburg";
431
+    map->layout = layout;
432
+    map->layout_label = layout->label;
513 433
 
514
-    // Insert new entry into the global map attributes.
515
-    QMap<QString, QString> attrs;
516
-    attrs.insert("border_label", QString("%1_MapBorder").arg(map->name));
517
-    attrs.insert("border_filepath", QString("data/maps/%1/border.bin").arg(map->name));
518
-    attrs.insert("blockdata_label", QString("%1_MapBlockdata").arg(map->name));
519
-    attrs.insert("blockdata_filepath", QString("data/maps/%1/map.bin").arg(map->name));
520
-    attrs.insert("attributes_label", QString("%1_MapAttributes").arg(map->name));
521
-    attrs.insert("width", map->width);
522
-    attrs.insert("height", map->height);
523
-    attrs.insert("tileset_primary", map->tileset_primary_label);
524
-    attrs.insert("tileset_secondary", map->tileset_secondary_label);
525
-    mapAttributes.insert(map->name, attrs);
434
+    // Insert new entry into the global map layouts.
435
+    mapLayouts.insert(layout->label, layout);
436
+    mapLayoutsTable.append(layout->label);
526 437
 }
527 438
 
528 439
 void Project::saveMapGroupsTable() {
@@ -544,7 +455,7 @@ void Project::saveMapGroupsTable() {
544 455
         text += QString("\t.4byte gMapGroup%1\n").arg(i);
545 456
     }
546 457
 
547
-    saveTextFile(root + "/data/maps/_groups.inc", text);
458
+    saveTextFile(root + "/data/maps/groups.inc", text);
548 459
 }
549 460
 
550 461
 void Project::saveMapConstantsHeader() {
@@ -585,8 +496,12 @@ void Project::saveMapConstantsHeader() {
585 496
 }
586 497
 
587 498
 void Project::getTilesets(Map* map) {
588
-    map->tileset_primary = getTileset(map->tileset_primary_label);
589
-    map->tileset_secondary = getTileset(map->tileset_secondary_label);
499
+    if (map->layout->has_unsaved_changes) {
500
+        return;
501
+    }
502
+
503
+    map->layout->tileset_primary = getTileset(map->layout->tileset_primary_label);
504
+    map->layout->tileset_secondary = getTileset(map->layout->tileset_secondary_label);
590 505
 }
591 506
 
592 507
 Tileset* Project::loadTileset(QString label) {
@@ -611,37 +526,13 @@ Tileset* Project::loadTileset(QString label) {
611 526
     return tileset;
612 527
 }
613 528
 
614
-QString Project::getBlockdataPath(Map* map) {
615
-    QString text = readTextFile(getMapAssetsFilepath());
616
-    QStringList *values = getLabelValues(parseAsm(text), map->blockdata_label);
617
-    QString path;
618
-    if (!values->isEmpty()) {
619
-        path = root + "/" + values->value(0).section('"', 1, 1);
620
-    } else {
621
-        path = root + "/data/maps/" + map->name + "/map.bin";
622
-    }
623
-    return path;
624
-}
625
-
626
-QString Project::getMapBorderPath(Map *map) {
627
-    QString text = readTextFile(getMapAssetsFilepath());
628
-    QStringList *values = getLabelValues(parseAsm(text), map->border_label);
629
-    QString path;
630
-    if (!values->isEmpty()) {
631
-        path = root + "/" + values->value(0).section('"', 1, 1);
632
-    } else {
633
-        path = root + "/data/maps/" + map->name + "/border.bin";
634
-    }
635
-    return path;
636
-}
637
-
638 529
 void Project::loadBlockdata(Map* map) {
639
-    if (!map->isPersistedToFile) {
530
+    if (!map->isPersistedToFile || map->layout->has_unsaved_changes) {
640 531
         return;
641 532
     }
642 533
 
643
-    QString path = getBlockdataPath(map);
644
-    map->blockdata = readBlockdata(path);
534
+    QString path = QString("%1/%2").arg(root).arg(map->layout->blockdata_path);
535
+    map->layout->blockdata = readBlockdata(path);
645 536
 }
646 537
 
647 538
 void Project::setNewMapBlockdata(Map* map) {
@@ -649,16 +540,16 @@ void Project::setNewMapBlockdata(Map* map) {
649 540
     for (int i = 0; i < map->getWidth() * map->getHeight(); i++) {
650 541
         blockdata->addBlock(qint16(0x3001));
651 542
     }
652
-    map->blockdata = blockdata;
543
+    map->layout->blockdata = blockdata;
653 544
 }
654 545
 
655 546
 void Project::loadMapBorder(Map *map) {
656
-    if (!map->isPersistedToFile) {
547
+    if (!map->isPersistedToFile || map->layout->has_unsaved_changes) {
657 548
         return;
658 549
     }
659 550
 
660
-    QString path = getMapBorderPath(map);
661
-    map->border = readBlockdata(path);
551
+    QString path = QString("%1/%2").arg(root).arg(map->layout->border_path);
552
+    map->layout->border = readBlockdata(path);
662 553
 }
663 554
 
664 555
 void Project::setNewMapBorder(Map *map) {
@@ -667,17 +558,17 @@ void Project::setNewMapBorder(Map *map) {
667 558
     blockdata->addBlock(qint16(0x01D5));
668 559
     blockdata->addBlock(qint16(0x01DC));
669 560
     blockdata->addBlock(qint16(0x01DD));
670
-    map->border = blockdata;
561
+    map->layout->border = blockdata;
671 562
 }
672 563
 
673 564
 void Project::saveMapBorder(Map *map) {
674
-    QString path = getMapBorderPath(map);
675
-    writeBlockdata(path, map->border);
565
+    QString path = QString("%1/%2").arg(root).arg(map->layout->border_path);
566
+    writeBlockdata(path, map->layout->border);
676 567
 }
677 568
 
678 569
 void Project::saveBlockdata(Map* map) {
679
-    QString path = getBlockdataPath(map);
680
-    writeBlockdata(path, map->blockdata);
570
+    QString path = QString("%1/%2").arg(root).arg(map->layout->blockdata_path);
571
+    writeBlockdata(path, map->layout->blockdata);
681 572
     map->history.save();
682 573
 }
683 574
 
@@ -686,6 +577,8 @@ void Project::writeBlockdata(QString path, Blockdata *blockdata) {
686 577
     if (file.open(QIODevice::WriteOnly)) {
687 578
         QByteArray data = blockdata->serialize();
688 579
         file.write(data);
580
+    } else {
581
+        qDebug() << "Failed to open blockdata file for writing: '" << path << "'";
689 582
     }
690 583
 }
691 584
 
@@ -706,26 +599,35 @@ void Project::saveMap(Map *map) {
706 599
             qDebug() << "Error: failed to create directory for new map. " << newMapDataDir;
707 600
         }
708 601
 
602
+        QString newLayoutDir = QString(root + "/data/layouts/%1").arg(map->name);
603
+        if (!QDir::root().mkdir(newLayoutDir)) {
604
+            qDebug() << "Error: failed to create directory for new layout. " << newLayoutDir;
605
+        }
606
+
709 607
         // TODO: In the future, these files needs more structure to allow for proper parsing/saving.
710
-        // Create file data/scripts/maps/<map_name>.inc
608
+        // Create file data/maps/<map_name>/scripts.inc
711 609
         QString text = QString("%1_MapScripts::\n\t.byte 0\n").arg(map->name);
712
-        saveTextFile(root + "/data/scripts/maps/" + map->name + ".inc", text);
610
+        saveTextFile(root + "/data/maps/" + map->name + "/scripts.inc", text);
713 611
 
714
-        // Create file data/text/maps/<map_name>.inc
715
-        saveTextFile(root + "/data/text/maps/" + map->name + ".inc", "\n");
612
+        // Create file data/maps/<map_name>/text.inc
613
+        saveTextFile(root + "/data/maps/" + map->name + "/text.inc", "\n");
716 614
 
717 615
         // Simply append to data/event_scripts.s.
718
-        text = QString("\n\t.include \"data/scripts/maps/%1.inc\"\n").arg(map->name);
719
-        text += QString("\t.include \"data/text/maps/%1.inc\"\n").arg(map->name);
616
+        text = QString("\n\t.include \"data/maps/%1/scripts.inc\"\n").arg(map->name);
617
+        text += QString("\t.include \"data/maps/%1/text.inc\"\n").arg(map->name);
720 618
         appendTextFile(root + "/data/event_scripts.s", text);
721 619
 
722 620
         // Simply append to data/map_events.s.
723
-        text = QString("\n\t.include \"data/maps/events/%1.inc\"\n").arg(map->name);
621
+        text = QString("\n\t.include \"data/maps/%1/events.inc\"\n").arg(map->name);
724 622
         appendTextFile(root + "/data/map_events.s", text);
725 623
 
726 624
         // Simply append to data/maps/headers.inc.
727 625
         text = QString("\t.include \"data/maps/%1/header.inc\"\n").arg(map->name);
728 626
         appendTextFile(root + "/data/maps/headers.inc", text);
627
+
628
+        // Simply append to data/layouts.inc.
629
+        text = QString("\t.include \"data/layouts/%1/layout.inc\"\n").arg(map->layout->name);
630
+        appendTextFile(root + "/data/layouts.inc", text);
729 631
     }
730 632
 
731 633
     saveMapBorder(map);
@@ -735,25 +637,27 @@ void Project::saveMap(Map *map) {
735 637
     saveMapEvents(map);
736 638
 
737 639
     // Update global data structures with current map data.
738
-    updateMapAttributes(map);
640
+    updateMapLayout(map);
739 641
 
740 642
     map->isPersistedToFile = true;
643
+    map->layout->has_unsaved_changes = false;
741 644
 }
742 645
 
743
-void Project::updateMapAttributes(Map* map) {
744
-    if (!mapAttributesTableMaster.contains(map->index.toInt())) {
745
-        mapAttributesTableMaster.insert(map->index.toInt(), map->name);
646
+void Project::updateMapLayout(Map* map) {
647
+    if (!mapLayoutsTableMaster.contains(map->layout_label)) {
648
+        mapLayoutsTableMaster.append(map->layout_label);
746 649
     }
747 650
 
748 651
     // Deep copy
749
-    QMap<QString, QString> attrs = mapAttributes.value(map->name);
750
-    attrs.detach();
751
-    mapAttributesMaster.insert(map->name, attrs);
652
+    MapLayout *layout = mapLayouts.value(map->layout_label);
653
+    MapLayout *newLayout = new MapLayout();
654
+    *newLayout = *layout;
655
+    mapLayoutsMaster.insert(map->layout_label, newLayout);
752 656
 }
753 657
 
754 658
 void Project::saveAllDataStructures() {
755
-    saveMapAttributesTable();
756
-    saveAllMapAttributes();
659
+    saveMapLayoutsTable();
660
+    saveAllMapLayouts();
757 661
     saveMapGroupsTable();
758 662
     saveMapConstantsHeader();
759 663
     saveMapsWithConnections();
@@ -828,7 +732,6 @@ void Project::loadTilesetAssets(Tileset* tileset) {
828 732
     tileset->tiles = tiles;
829 733
 
830 734
     // metatiles
831
-    //qDebug() << metatiles_path;
832 735
     QFile metatiles_file(metatiles_path);
833 736
     if (metatiles_file.open(QIODevice::ReadOnly)) {
834 737
         QByteArray data = metatiles_file.readAll();
@@ -895,9 +798,9 @@ void Project::loadTilesetAssets(Tileset* tileset) {
895 798
             for (int j = 0; j < 16; j++) {
896 799
                 palette.append(qRgb(j * 16, j * 16, j * 16));
897 800
             }
898
-            qDebug() << QString("Could not open '%1'").arg(path);
801
+            qDebug() << QString("Could not open palette path '%1'").arg(path);
899 802
         }
900
-        //qDebug() << path;
803
+
901 804
         palettes->append(palette);
902 805
     }
903 806
     tileset->palettes = palettes;
@@ -905,7 +808,6 @@ void Project::loadTilesetAssets(Tileset* tileset) {
905 808
 
906 809
 Blockdata* Project::readBlockdata(QString path) {
907 810
     Blockdata *blockdata = new Blockdata;
908
-    //qDebug() << path;
909 811
     QFile file(path);
910 812
     if (file.open(QIODevice::ReadOnly)) {
911 813
         QByteArray data = file.readAll();
@@ -913,7 +815,10 @@ Blockdata* Project::readBlockdata(QString path) {
913 815
             uint16_t word = (data[i] & 0xff) + ((data[i + 1] & 0xff) << 8);
914 816
             blockdata->addBlock(word);
915 817
         }
818
+    } else {
819
+        qDebug() << "Failed to open blockdata path '" << path << "'";
916 820
     }
821
+
917 822
     return blockdata;
918 823
 }
919 824
 
@@ -976,7 +881,7 @@ void Project::deleteFile(QString path) {
976 881
 }
977 882
 
978 883
 void Project::readMapGroups() {
979
-    QString text = readTextFile(root + "/data/maps/_groups.inc");
884
+    QString text = readTextFile(root + "/data/maps/groups.inc");
980 885
     if (text.isNull()) {
981 886
         return;
982 887
     }
@@ -1039,9 +944,6 @@ void Project::readMapGroups() {
1039 944
 }
1040 945
 
1041 946
 Map* Project::addNewMapToGroup(QString mapName, int groupNum) {
1042
-    int mapIndex = mapAttributesTable.count() + 1;
1043
-    mapAttributesTable.insert(mapIndex, mapName);
1044
-
1045 947
     // Setup new map in memory, but don't write to file until map is actually saved later.
1046 948
     mapNames->append(mapName);
1047 949
     map_groups->insert(mapName, groupNum);
@@ -1052,8 +954,8 @@ Map* Project::addNewMapToGroup(QString mapName, int groupNum) {
1052 954
     map->setName(mapName);
1053 955
     mapConstantsToMapNames->insert(map->constantName, map->name);
1054 956
     mapNamesToMapConstants->insert(map->name, map->constantName);
1055
-    setNewMapHeader(map, mapIndex);
1056
-    setNewMapAttributes(map);
957
+    setNewMapHeader(map, mapLayoutsTable.size() + 1);
958
+    setNewMapLayout(map);
1057 959
     getTilesets(map);
1058 960
     setNewMapBlockdata(map);
1059 961
     setNewMapBorder(map);
@@ -1200,7 +1102,7 @@ QStringList Project::getSongNames() {
1200 1102
     QString text = readTextFile(root + "/include/constants/songs.h");
1201 1103
     if (!text.isNull()) {
1202 1104
         QStringList songDefinePrefixes;
1203
-        songDefinePrefixes << "SE_" << "BGM_";
1105
+        songDefinePrefixes << "SE_" << "MUS_";
1204 1106
         QMap<QString, int> songDefines = readCDefines(text, songDefinePrefixes);
1205 1107
         names = songDefines.keys();
1206 1108
     }
@@ -1283,7 +1185,7 @@ void Project::loadEventPixmaps(QList<Event*> objects) {
1283 1185
 }
1284 1186
 
1285 1187
 void Project::saveMapEvents(Map *map) {
1286
-    QString path = root + QString("/data/maps/events/%1.inc").arg(map->name);
1188
+    QString path = root + QString("/data/maps/%1/events.inc").arg(map->name);
1287 1189
     QString text = "";
1288 1190
 
1289 1191
     if (map->events["object"].length() > 0) {
@@ -1397,7 +1299,7 @@ void Project::readMapEvents(Map *map) {
1397 1299
     }
1398 1300
 
1399 1301
     // lazy
1400
-    QString path = root + QString("/data/maps/events/%1.inc").arg(map->name);
1302
+    QString path = root + QString("/data/maps/%1/events.inc").arg(map->name);
1401 1303
     QString text = readTextFile(path);
1402 1304
     if (text.isNull()) {
1403 1305
         return;

+ 14
- 15
project.h 查看文件

@@ -19,10 +19,10 @@ public:
19 19
     QStringList *mapNames = NULL;
20 20
     QMap<QString, QString>* mapConstantsToMapNames;
21 21
     QMap<QString, QString>* mapNamesToMapConstants;
22
-    QMap<int, QString> mapAttributesTable;
23
-    QMap<int, QString> mapAttributesTableMaster;
24
-    QMap<QString, QMap<QString, QString>> mapAttributes;
25
-    QMap<QString, QMap<QString, QString>> mapAttributesMaster;
22
+    QList<QString> mapLayoutsTable;
23
+    QList<QString> mapLayoutsTableMaster;
24
+    QMap<QString, MapLayout*> mapLayouts;
25
+    QMap<QString, MapLayout*> mapLayoutsMaster;
26 26
     QStringList *itemNames = NULL;
27 27
     QStringList *flagNames = NULL;
28 28
     QStringList *varNames = NULL;
@@ -52,21 +52,21 @@ public:
52 52
     QList<QStringList>* getLabelMacros(QList<QStringList>*, QString);
53 53
     QStringList* getLabelValues(QList<QStringList>*, QString);
54 54
     void readMapHeader(Map*);
55
-    void readMapAttributesTable();
56
-    void readAllMapAttributes();
57
-    void readMapAttributes(Map*);
55
+    void readMapLayoutsTable();
56
+    void readAllMapLayouts();
57
+    QStringList* readLayoutValues(QString layoutName);
58
+    void readMapLayout(Map*);
58 59
     void readMapsWithConnections();
59 60
     void getTilesets(Map*);
60 61
     void loadTilesetAssets(Tileset*);
61 62
 
62
-    QString getBlockdataPath(Map*);
63 63
     void saveBlockdata(Map*);
64 64
     void saveMapBorder(Map*);
65 65
     void writeBlockdata(QString, Blockdata*);
66 66
     void saveAllMaps();
67 67
     void saveMap(Map*);
68 68
     void saveAllDataStructures();
69
-    void saveAllMapAttributes();
69
+    void saveAllMapLayouts();
70 70
     void saveMapGroupsTable();
71 71
     void saveMapConstantsHeader();
72 72
 
@@ -89,7 +89,6 @@ public:
89 89
     void loadMapConnections(Map *map);
90 90
 
91 91
     void loadMapBorder(Map *map);
92
-    QString getMapBorderPath(Map *map);
93 92
 
94 93
     void saveMapEvents(Map *map);
95 94
 
@@ -97,19 +96,19 @@ public:
97 96
     QString readCIncbin(QString text, QString label);
98 97
     QMap<QString, int> readCDefines(QString text, QStringList prefixes);
99 98
 private:
100
-    QString getMapAttributesTableFilepath();
101
-    QString getMapAssetsFilepath();
99
+    QString getMapLayoutsTableFilepath();
100
+    QString getMapLayoutFilepath(QString);
102 101
     void saveMapHeader(Map*);
103 102
     void saveMapConnections(Map*);
104 103
     void updateMapsWithConnections(Map*);
105 104
     void saveMapsWithConnections();
106
-    void saveMapAttributesTable();
107
-    void updateMapAttributes(Map* map);
105
+    void saveMapLayoutsTable();
106
+    void updateMapLayout(Map*);
108 107
     void readCDefinesSorted(QString, QStringList, QStringList*);
109 108
     void readCDefinesSorted(QString, QStringList, QStringList*, QString, int);
110 109
 
111 110
     void setNewMapHeader(Map* map, int mapIndex);
112
-    void setNewMapAttributes(Map* map);
111
+    void setNewMapLayout(Map* map);
113 112
     void setNewMapBlockdata(Map* map);
114 113
     void setNewMapBorder(Map *map);
115 114
     void setNewMapEvents(Map *map);