Browse Source

Add ability to change map border

Marcus Huderle 5 years ago
parent
commit
5bd88e6fef
12 changed files with 294 additions and 143 deletions
  1. 51
    0
      editor.cpp
  2. 20
    0
      editor.h
  3. 3
    0
      mainwindow.cpp
  4. 91
    7
      mainwindow.ui
  5. 4
    103
      map.cpp
  6. 0
    7
      map.h
  7. 0
    6
      metatile.cpp
  8. 0
    16
      metatile.h
  9. 0
    2
      pretmap.pro
  10. 0
    1
      project.cpp
  11. 106
    0
      tileset.cpp
  12. 19
    1
      tileset.h

+ 51
- 0
editor.cpp View File

@@ -301,6 +301,10 @@ void Editor::onConnectionDirectionChanged(QString newDirection) {
301 301
     ui->comboBox_ConnectionDirection->blockSignals(false);
302 302
 }
303 303
 
304
+void Editor::onBorderMetatilesChanged() {
305
+    displayMapBorder();
306
+}
307
+
304 308
 void Editor::setConnectionsVisibility(bool visible) {
305 309
     for (QGraphicsPixmapItem* item : map->connection_items) {
306 310
         item->setVisible(visible);
@@ -383,6 +387,7 @@ void Editor::displayMap() {
383 387
     );
384 388
 
385 389
     displayMetatiles();
390
+    displayBorderMetatiles();
386 391
     displayCollisionMetatiles();
387 392
     displayElevationMetatiles();
388 393
     displayMapEvents();
@@ -398,6 +403,15 @@ void Editor::displayMetatiles() {
398 403
     scene_metatiles->addItem(metatiles_item);
399 404
 }
400 405
 
406
+void Editor::displayBorderMetatiles() {
407
+    scene_selected_border_metatiles = new QGraphicsScene;
408
+    selected_border_metatiles_item = new BorderMetatilesPixmapItem(map);
409
+    selected_border_metatiles_item->draw();
410
+    scene_selected_border_metatiles->addItem(selected_border_metatiles_item);
411
+
412
+    connect(selected_border_metatiles_item, SIGNAL(borderMetatilesChanged()), this, SLOT(onBorderMetatilesChanged()));
413
+}
414
+
401 415
 void Editor::displayCollisionMetatiles() {
402 416
     scene_collision_metatiles = new QGraphicsScene;
403 417
     collision_metatiles_item = new CollisionMetatilesPixmapItem(map);
@@ -792,6 +806,43 @@ void MetatilesPixmapItem::updateSelection(QPointF pos, Qt::MouseButton button) {
792 806
     }
793 807
 }
794 808
 
809
+void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
810
+    QPointF pos = event->pos();
811
+    int x = ((int)pos.x()) / 16;
812
+    int y = ((int)pos.y()) / 16;
813
+
814
+    for (int i = 0; i < map->paint_tile_width && (i + x) < 2; i++) {
815
+        for (int j = 0; j < map->paint_tile_height && (j + y) < 2; j++) {
816
+            int blockIndex = (j + y) * 2 + (i + x);
817
+            int tile = map->getSelectedBlockIndex(map->paint_tile_index + i + (j * 8));
818
+            (*map->layout->border->blocks)[blockIndex].tile = tile;
819
+        }
820
+    }
821
+
822
+    draw();
823
+    emit borderMetatilesChanged();
824
+}
825
+
826
+void BorderMetatilesPixmapItem::draw() {
827
+    QImage image(32, 32, QImage::Format_RGBA8888);
828
+    QPainter painter(&image);
829
+    QList<Block> *blocks = map->layout->border->blocks;
830
+
831
+    for (int i = 0; i < 2; i++)
832
+    for (int j = 0; j < 2; j++)
833
+    {
834
+        int x = i * 16;
835
+        int y = j * 16;
836
+        int index = j * 2 + i;
837
+        QImage metatile_image = Metatile::getMetatileImage(blocks->value(index).tile, map->layout->tileset_primary, map->layout->tileset_secondary);
838
+        QPoint metatile_origin = QPoint(x, y);
839
+        painter.drawImage(metatile_origin, metatile_image);
840
+    }
841
+
842
+    painter.end();
843
+    setPixmap(QPixmap::fromImage(image));
844
+}
845
+
795 846
 void MovementPermissionsPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent* event) {
796 847
     QPointF pos = event->pos();
797 848
     int x = ((int)pos.x()) / 16;

+ 20
- 0
editor.h View File

@@ -16,6 +16,7 @@ class MapPixmapItem;
16 16
 class CollisionPixmapItem;
17 17
 class ConnectionPixmapItem;
18 18
 class MetatilesPixmapItem;
19
+class BorderMetatilesPixmapItem;
19 20
 class CollisionMetatilesPixmapItem;
20 21
 class ElevationMetatilesPixmapItem;
21 22
 
@@ -36,6 +37,7 @@ public:
36 37
     void setMap(QString map_name);
37 38
     void displayMap();
38 39
     void displayMetatiles();
40
+    void displayBorderMetatiles();
39 41
     void displayCollisionMetatiles();
40 42
     void displayElevationMetatiles();
41 43
     void displayMapEvents();
@@ -78,9 +80,11 @@ public:
78 80
     QList<QGraphicsPixmapItem*> borderItems;
79 81
 
80 82
     QGraphicsScene *scene_metatiles = NULL;
83
+    QGraphicsScene *scene_selected_border_metatiles = NULL;
81 84
     QGraphicsScene *scene_collision_metatiles = NULL;
82 85
     QGraphicsScene *scene_elevation_metatiles = NULL;
83 86
     MetatilesPixmapItem *metatiles_item = NULL;
87
+    BorderMetatilesPixmapItem *selected_border_metatiles_item = NULL;
84 88
     CollisionMetatilesPixmapItem *collision_metatiles_item = NULL;
85 89
     ElevationMetatilesPixmapItem *elevation_metatiles_item = NULL;
86 90
 
@@ -123,6 +127,7 @@ private slots:
123 127
     void onConnectionItemSelected(ConnectionPixmapItem* connectionItem);
124 128
     void onConnectionItemDoubleClicked(ConnectionPixmapItem* connectionItem);
125 129
     void onConnectionDirectionChanged(QString newDirection);
130
+    void onBorderMetatilesChanged();
126 131
 
127 132
 signals:
128 133
     void objectsChanged();
@@ -351,6 +356,21 @@ protected:
351 356
     void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
352 357
 };
353 358
 
359
+class BorderMetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
360
+    Q_OBJECT
361
+public:
362
+    BorderMetatilesPixmapItem(Map *map_) {
363
+        map = map_;
364
+        setAcceptHoverEvents(true);
365
+    }
366
+    Map* map = NULL;
367
+    virtual void draw();
368
+signals:
369
+    void borderMetatilesChanged();
370
+protected:
371
+    void mousePressEvent(QGraphicsSceneMouseEvent*);
372
+};
373
+
354 374
 class MovementPermissionsPixmapItem : public MetatilesPixmapItem {
355 375
     Q_OBJECT
356 376
 public:

+ 3
- 0
mainwindow.cpp View File

@@ -166,6 +166,9 @@ void MainWindow::setMap(QString map_name) {
166 166
     //ui->graphicsView_Metatiles->setSceneRect(editor->scene_metatiles->sceneRect());
167 167
     ui->graphicsView_Metatiles->setFixedSize(editor->metatiles_item->pixmap().width() + 2, editor->metatiles_item->pixmap().height() + 2);
168 168
 
169
+    ui->graphicsView_BorderMetatile->setScene(editor->scene_selected_border_metatiles);
170
+    ui->graphicsView_BorderMetatile->setFixedSize(editor->selected_border_metatiles_item->pixmap().width() + 2, editor->selected_border_metatiles_item->pixmap().height() + 2);
171
+
169 172
     ui->graphicsView_Collision->setScene(editor->scene_collision_metatiles);
170 173
     //ui->graphicsView_Collision->setSceneRect(editor->scene_collision_metatiles->sceneRect());
171 174
     ui->graphicsView_Collision->setFixedSize(editor->collision_metatiles_item->pixmap().width() + 2, editor->collision_metatiles_item->pixmap().height() + 2);

+ 91
- 7
mainwindow.ui View File

@@ -60,7 +60,7 @@
60 60
         </sizepolicy>
61 61
        </property>
62 62
        <property name="currentIndex">
63
-        <number>1</number>
63
+        <number>0</number>
64 64
        </property>
65 65
        <property name="tabsClosable">
66 66
         <bool>false</bool>
@@ -290,7 +290,7 @@
290 290
                     <rect>
291 291
                      <x>0</x>
292 292
                      <y>0</y>
293
-                     <width>614</width>
293
+                     <width>475</width>
294 294
                      <height>621</height>
295 295
                     </rect>
296 296
                    </property>
@@ -478,8 +478,8 @@
478 478
                      <rect>
479 479
                       <x>0</x>
480 480
                       <y>0</y>
481
-                      <width>180</width>
482
-                      <height>629</height>
481
+                      <width>358</width>
482
+                      <height>612</height>
483 483
                      </rect>
484 484
                     </property>
485 485
                     <property name="sizePolicy">
@@ -488,7 +488,10 @@
488 488
                       <verstretch>0</verstretch>
489 489
                      </sizepolicy>
490 490
                     </property>
491
-                    <layout class="QGridLayout" name="gridLayout_5" rowstretch="0" columnstretch="0">
491
+                    <layout class="QGridLayout" name="gridLayout_5" rowstretch="0,0" columnstretch="0">
492
+                     <property name="sizeConstraint">
493
+                      <enum>QLayout::SetDefaultConstraint</enum>
494
+                     </property>
492 495
                      <property name="leftMargin">
493 496
                       <number>0</number>
494 497
                      </property>
@@ -501,16 +504,97 @@
501 504
                      <property name="bottomMargin">
502 505
                       <number>0</number>
503 506
                      </property>
504
-                     <property name="spacing">
507
+                     <property name="horizontalSpacing">
505 508
                       <number>0</number>
506 509
                      </property>
510
+                     <property name="verticalSpacing">
511
+                      <number>8</number>
512
+                     </property>
507 513
                      <item row="0" column="0">
514
+                      <widget class="QFrame" name="frame_10">
515
+                       <property name="sizePolicy">
516
+                        <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
517
+                         <horstretch>0</horstretch>
518
+                         <verstretch>0</verstretch>
519
+                        </sizepolicy>
520
+                       </property>
521
+                       <property name="frameShape">
522
+                        <enum>QFrame::NoFrame</enum>
523
+                       </property>
524
+                       <property name="frameShadow">
525
+                        <enum>QFrame::Raised</enum>
526
+                       </property>
527
+                       <layout class="QHBoxLayout" name="horizontalLayout_5">
528
+                        <property name="spacing">
529
+                         <number>6</number>
530
+                        </property>
531
+                        <property name="sizeConstraint">
532
+                         <enum>QLayout::SetDefaultConstraint</enum>
533
+                        </property>
534
+                        <item>
535
+                         <widget class="QLabel" name="label_16">
536
+                          <property name="sizePolicy">
537
+                           <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
538
+                            <horstretch>0</horstretch>
539
+                            <verstretch>0</verstretch>
540
+                           </sizepolicy>
541
+                          </property>
542
+                          <property name="text">
543
+                           <string>Border</string>
544
+                          </property>
545
+                         </widget>
546
+                        </item>
547
+                        <item>
548
+                         <widget class="QGraphicsView" name="graphicsView_BorderMetatile">
549
+                          <property name="sizePolicy">
550
+                           <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
551
+                            <horstretch>0</horstretch>
552
+                            <verstretch>0</verstretch>
553
+                           </sizepolicy>
554
+                          </property>
555
+                          <property name="maximumSize">
556
+                           <size>
557
+                            <width>16777215</width>
558
+                            <height>48</height>
559
+                           </size>
560
+                          </property>
561
+                          <property name="frameShape">
562
+                           <enum>QFrame::StyledPanel</enum>
563
+                          </property>
564
+                          <property name="frameShadow">
565
+                           <enum>QFrame::Sunken</enum>
566
+                          </property>
567
+                          <property name="verticalScrollBarPolicy">
568
+                           <enum>Qt::ScrollBarAsNeeded</enum>
569
+                          </property>
570
+                         </widget>
571
+                        </item>
572
+                        <item>
573
+                         <spacer name="horizontalSpacer_12">
574
+                          <property name="orientation">
575
+                           <enum>Qt::Horizontal</enum>
576
+                          </property>
577
+                          <property name="sizeType">
578
+                           <enum>QSizePolicy::Maximum</enum>
579
+                          </property>
580
+                          <property name="sizeHint" stdset="0">
581
+                           <size>
582
+                            <width>40</width>
583
+                            <height>20</height>
584
+                           </size>
585
+                          </property>
586
+                         </spacer>
587
+                        </item>
588
+                       </layout>
589
+                      </widget>
590
+                     </item>
591
+                     <item row="1" column="0">
508 592
                       <widget class="QGraphicsView" name="graphicsView_Metatiles">
509 593
                        <property name="enabled">
510 594
                         <bool>true</bool>
511 595
                        </property>
512 596
                        <property name="sizePolicy">
513
-                        <sizepolicy hsizetype="Ignored" vsizetype="Ignored">
597
+                        <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
514 598
                          <horstretch>0</horstretch>
515 599
                          <verstretch>0</verstretch>
516 600
                         </sizepolicy>

+ 4
- 103
map.cpp View File

@@ -59,35 +59,6 @@ int Map::getHeight() {
59 59
     return layout->height.toInt(nullptr, 0);
60 60
 }
61 61
 
62
-Tileset* Map::getBlockTileset(int metatile_index) {
63
-    int primary_size = 0x200;
64
-    if (metatile_index < primary_size) {
65
-        return layout->tileset_primary;
66
-    } else {
67
-        return layout->tileset_secondary;
68
-    }
69
-}
70
-
71
-QList<QList<QRgb>> Map::getBlockPalettes(int metatile_index) {
72
-    QList<QList<QRgb>> palettes;
73
-    for (int i = 0; i < 6; i++) {
74
-        palettes.append(layout->tileset_primary->palettes->at(i));
75
-    }
76
-    for (int i = 6; i < layout->tileset_secondary->palettes->length(); i++) {
77
-        palettes.append(layout->tileset_secondary->palettes->at(i));
78
-    }
79
-    return palettes;
80
-}
81
-
82
-int Map::getBlockIndex(int index) {
83
-    int primary_size = 0x200;
84
-    if (index < primary_size) {
85
-        return index;
86
-    } else {
87
-        return index - primary_size;
88
-    }
89
-}
90
-
91 62
 int Map::getSelectedBlockIndex(int index) {
92 63
     if (index < layout->tileset_primary->metatiles->length()) {
93 64
         return index;
@@ -104,25 +75,6 @@ int Map::getDisplayedBlockIndex(int index) {
104 75
     }
105 76
 }
106 77
 
107
-QImage Map::getMetatileTile(int tile) {
108
-    Tileset *tileset = getBlockTileset(tile);
109
-    int local_index = getBlockIndex(tile);
110
-    if (!tileset || !tileset->tiles) {
111
-        return QImage();
112
-    }
113
-    return tileset->tiles->value(local_index, QImage());
114
-}
115
-
116
-Metatile* Map::getMetatile(int index) {
117
-    Tileset *tileset = getBlockTileset(index);
118
-    int local_index = getBlockIndex(index);
119
-    if (!tileset || !tileset->metatiles) {
120
-        return NULL;
121
-    }
122
-    Metatile *metatile = tileset->metatiles->value(local_index, NULL);
123
-    return metatile;
124
-}
125
-
126 78
 QImage Map::getCollisionMetatileImage(Block block) {
127 79
     return getCollisionMetatileImage(block.collision);
128 80
 }
@@ -166,57 +118,6 @@ QImage Map::getElevationMetatileImage(int elevation) {
166 118
     return metatile_image;
167 119
 }
168 120
 
169
-QImage Map::getMetatileImage(int tile) {
170
-
171
-    QImage metatile_image(16, 16, QImage::Format_RGBA8888);
172
-
173
-    Metatile* metatile = getMetatile(tile);
174
-    if (!metatile || !metatile->tiles) {
175
-        metatile_image.fill(0xffffffff);
176
-        return metatile_image;
177
-    }
178
-
179
-    Tileset* blockTileset = getBlockTileset(tile);
180
-    if (!blockTileset) {
181
-        metatile_image.fill(0xffffffff);
182
-        return metatile_image;
183
-    }
184
-    QList<QList<QRgb>> palettes = getBlockPalettes(tile);
185
-
186
-    QPainter metatile_painter(&metatile_image);
187
-    for (int layer = 0; layer < 2; layer++)
188
-    for (int y = 0; y < 2; y++)
189
-    for (int x = 0; x < 2; x++) {
190
-        Tile tile_ = metatile->tiles->value((y * 2) + x + (layer * 4));
191
-        QImage tile_image = getMetatileTile(tile_.tile);
192
-        if (tile_image.isNull()) {
193
-            // Some metatiles specify tiles that are outside the valid range.
194
-            // These are treated as completely transparent, so they can be skipped without
195
-            // being drawn.
196
-            continue;
197
-        }
198
-
199
-        // Colorize the metatile tiles with its palette.
200
-        QList<QRgb> palette = palettes.value(tile_.palette);
201
-        for (int j = 0; j < palette.length(); j++) {
202
-            tile_image.setColor(j, palette.value(j));
203
-        }
204
-
205
-        // The top layer of the metatile has its last color displayed at transparent.
206
-        if (layer > 0) {
207
-            QColor color(tile_image.color(15));
208
-            color.setAlpha(0);
209
-            tile_image.setColor(15, color.rgba());
210
-        }
211
-
212
-        QPoint origin = QPoint(x*8, y*8);
213
-        metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1));
214
-    }
215
-    metatile_painter.end();
216
-
217
-    return metatile_image;
218
-}
219
-
220 121
 bool Map::blockChanged(int i, Blockdata *cache) {
221 122
     if (cache == NULL || cache == nullptr) {
222 123
         return true;
@@ -295,7 +196,7 @@ QPixmap Map::renderCollision(bool ignoreCache) {
295 196
         }
296 197
         changed_any = true;
297 198
         Block block = layout->blockdata->blocks->value(i);
298
-        QImage metatile_image = getMetatileImage(block.tile);
199
+        QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary);
299 200
         QImage collision_metatile_image = getCollisionMetatileImage(block);
300 201
         QImage elevation_metatile_image = getElevationMetatileImage(block);
301 202
         int map_y = width_ ? i / width_ : 0;
@@ -364,7 +265,7 @@ QPixmap Map::render(bool ignoreCache = false) {
364 265
         }
365 266
         changed_any = true;
366 267
         Block block = layout->blockdata->blocks->value(i);
367
-        QImage metatile_image = getMetatileImage(block.tile);
268
+        QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary);
368 269
         int map_y = width_ ? i / width_ : 0;
369 270
         int map_x = width_ ? i % width_ : 0;
370 271
         QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
@@ -397,7 +298,7 @@ QPixmap Map::renderBorder() {
397 298
         }
398 299
         changed_any = true;
399 300
         Block block = layout->border->blocks->value(i);
400
-        QImage metatile_image = getMetatileImage(block.tile);
301
+        QImage metatile_image = Metatile::getMetatileImage(block.tile, layout->tileset_primary, layout->tileset_secondary);
401 302
         int map_y = i / width_;
402 303
         int map_x = i % width_;
403 304
         painter.drawImage(QPoint(map_x * 16, map_y * 16), metatile_image);
@@ -513,7 +414,7 @@ QPixmap Map::renderMetatiles() {
513 414
         if (i >= primary_length) {
514 415
             tile += 0x200 - primary_length;
515 416
         }
516
-        QImage metatile_image = getMetatileImage(tile);
417
+        QImage metatile_image = Metatile::getMetatileImage(tile, layout->tileset_primary, layout->tileset_secondary);
517 418
         int map_y = i / width_;
518 419
         int map_x = i % width_;
519 420
         QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);

+ 0
- 7
map.h View File

@@ -135,13 +135,8 @@ public:
135 135
     static QString bgEventsLabelFromName(QString mapName);
136 136
     int getWidth();
137 137
     int getHeight();
138
-    Tileset* getBlockTileset(int);
139
-    int getBlockIndex(int);
140 138
     int getSelectedBlockIndex(int);
141 139
     int getDisplayedBlockIndex(int);
142
-    Metatile* getMetatile(int);
143
-    QImage getMetatileImage(int);
144
-    QImage getMetatileTile(int);
145 140
     QPixmap render(bool ignoreCache);
146 141
     QPixmap renderMetatiles();
147 142
 
@@ -214,8 +209,6 @@ public:
214 209
     void hoveredElevationTileChanged(int elevation);
215 210
     void clearHoveredElevationTile();
216 211
 
217
-    QList<QList<QRgb> > getBlockPalettes(int metatile_index);
218
-
219 212
 signals:
220 213
     void paintTileChanged(Map *map);
221 214
     void paintCollisionChanged(Map *map);

+ 0
- 6
metatile.cpp View File

@@ -1,6 +0,0 @@
1
-#include "metatile.h"
2
-
3
-Metatile::Metatile()
4
-{
5
-    tiles = new QList<Tile>;
6
-}

+ 0
- 16
metatile.h View File

@@ -1,16 +0,0 @@
1
-#ifndef METATILE_H
2
-#define METATILE_H
3
-
4
-#include "tile.h"
5
-#include <QList>
6
-
7
-class Metatile
8
-{
9
-public:
10
-    Metatile();
11
-public:
12
-    QList<Tile> *tiles = NULL;
13
-    int attr;
14
-};
15
-
16
-#endif // METATILE_H

+ 0
- 2
pretmap.pro View File

@@ -19,7 +19,6 @@ SOURCES += main.cpp\
19 19
     blockdata.cpp \
20 20
     block.cpp \
21 21
     tileset.cpp \
22
-    metatile.cpp \
23 22
     tile.cpp \
24 23
     event.cpp \
25 24
     editor.cpp \
@@ -34,7 +33,6 @@ HEADERS  += mainwindow.h \
34 33
     blockdata.h \
35 34
     block.h \
36 35
     tileset.h \
37
-    metatile.h \
38 36
     tile.h \
39 37
     event.h \
40 38
     editor.h \

+ 0
- 1
project.cpp View File

@@ -2,7 +2,6 @@
2 2
 #include "project.h"
3 3
 #include "tile.h"
4 4
 #include "tileset.h"
5
-#include "metatile.h"
6 5
 #include "event.h"
7 6
 
8 7
 #include <QDebug>

+ 106
- 0
tileset.cpp View File

@@ -1,6 +1,112 @@
1 1
 #include "tileset.h"
2 2
 
3
+#include <QPainter>
4
+#include <QImage>
5
+
3 6
 Tileset::Tileset()
4 7
 {
5 8
 
6 9
 }
10
+
11
+Metatile::Metatile()
12
+{
13
+    tiles = new QList<Tile>;
14
+}
15
+
16
+QImage Metatile::getMetatileImage(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) {
17
+    QImage metatile_image(16, 16, QImage::Format_RGBA8888);
18
+
19
+    Metatile* metatile = Metatile::getMetatile(tile, primaryTileset, secondaryTileset);
20
+    if (!metatile || !metatile->tiles) {
21
+        metatile_image.fill(0xffffffff);
22
+        return metatile_image;
23
+    }
24
+
25
+    Tileset* blockTileset = Metatile::getBlockTileset(tile, primaryTileset, secondaryTileset);
26
+    if (!blockTileset) {
27
+        metatile_image.fill(0xffffffff);
28
+        return metatile_image;
29
+    }
30
+    QList<QList<QRgb>> palettes = Metatile::getBlockPalettes(primaryTileset, secondaryTileset);
31
+
32
+    QPainter metatile_painter(&metatile_image);
33
+    for (int layer = 0; layer < 2; layer++)
34
+    for (int y = 0; y < 2; y++)
35
+    for (int x = 0; x < 2; x++) {
36
+        Tile tile_ = metatile->tiles->value((y * 2) + x + (layer * 4));
37
+        QImage tile_image = Metatile::getMetatileTile(tile_.tile, primaryTileset, secondaryTileset);
38
+        if (tile_image.isNull()) {
39
+            // Some metatiles specify tiles that are outside the valid range.
40
+            // These are treated as completely transparent, so they can be skipped without
41
+            // being drawn.
42
+            continue;
43
+        }
44
+
45
+        // Colorize the metatile tiles with its palette.
46
+        QList<QRgb> palette = palettes.value(tile_.palette);
47
+        for (int j = 0; j < palette.length(); j++) {
48
+            tile_image.setColor(j, palette.value(j));
49
+        }
50
+
51
+        // The top layer of the metatile has its last color displayed at transparent.
52
+        if (layer > 0) {
53
+            QColor color(tile_image.color(15));
54
+            color.setAlpha(0);
55
+            tile_image.setColor(15, color.rgba());
56
+        }
57
+
58
+        QPoint origin = QPoint(x*8, y*8);
59
+        metatile_painter.drawImage(origin, tile_image.mirrored(tile_.xflip == 1, tile_.yflip == 1));
60
+    }
61
+    metatile_painter.end();
62
+
63
+    return metatile_image;
64
+}
65
+
66
+Metatile* Metatile::getMetatile(int index, Tileset *primaryTileset, Tileset *secondaryTileset) {
67
+    Tileset *tileset = Metatile::getBlockTileset(index, primaryTileset, secondaryTileset);
68
+    int local_index = Metatile::getBlockIndex(index);
69
+    if (!tileset || !tileset->metatiles) {
70
+        return NULL;
71
+    }
72
+    Metatile *metatile = tileset->metatiles->value(local_index, NULL);
73
+    return metatile;
74
+}
75
+
76
+QImage Metatile::getMetatileTile(int tile, Tileset *primaryTileset, Tileset *secondaryTileset) {
77
+    Tileset *tileset = Metatile::getBlockTileset(tile, primaryTileset, secondaryTileset);
78
+    int local_index = Metatile::getBlockIndex(tile);
79
+    if (!tileset || !tileset->tiles) {
80
+        return QImage();
81
+    }
82
+    return tileset->tiles->value(local_index, QImage());
83
+}
84
+
85
+Tileset* Metatile::getBlockTileset(int metatile_index, Tileset *primaryTileset, Tileset *secondaryTileset) {
86
+    int primary_size = 0x200;
87
+    if (metatile_index < primary_size) {
88
+        return primaryTileset;
89
+    } else {
90
+        return secondaryTileset;
91
+    }
92
+}
93
+
94
+int Metatile::getBlockIndex(int index) {
95
+    int primary_size = 0x200;
96
+    if (index < primary_size) {
97
+        return index;
98
+    } else {
99
+        return index - primary_size;
100
+    }
101
+}
102
+
103
+QList<QList<QRgb>> Metatile::getBlockPalettes(Tileset *primaryTileset, Tileset *secondaryTileset) {
104
+    QList<QList<QRgb>> palettes;
105
+    for (int i = 0; i < 6; i++) {
106
+        palettes.append(primaryTileset->palettes->at(i));
107
+    }
108
+    for (int i = 6; i < secondaryTileset->palettes->length(); i++) {
109
+        palettes.append(secondaryTileset->palettes->at(i));
110
+    }
111
+    return palettes;
112
+}

+ 19
- 1
tileset.h View File

@@ -1,9 +1,11 @@
1 1
 #ifndef TILESET_H
2 2
 #define TILESET_H
3 3
 
4
-#include "metatile.h"
4
+#include "tile.h"
5 5
 #include <QImage>
6 6
 
7
+class Metatile;
8
+
7 9
 class Tileset
8 10
 {
9 11
 public:
@@ -24,4 +26,20 @@ public:
24 26
     QList<QList<QRgb>> *palettes = NULL;
25 27
 };
26 28
 
29
+class Metatile
30
+{
31
+public:
32
+    Metatile();
33
+public:
34
+    QList<Tile> *tiles = NULL;
35
+    int attr;
36
+
37
+    static QImage getMetatileImage(int, Tileset*, Tileset*);
38
+    static Metatile* getMetatile(int, Tileset*, Tileset*);
39
+    static QImage getMetatileTile(int, Tileset*, Tileset*);
40
+    static Tileset* getBlockTileset(int, Tileset*, Tileset*);
41
+    static int getBlockIndex(int);
42
+    static QList<QList<QRgb>> getBlockPalettes(Tileset*, Tileset*);
43
+};
44
+
27 45
 #endif // TILESET_H