diff --git a/Makefile b/Makefile index 93cd52d..86115c7 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ DEBUGOBJDIR = tmp/$(OSDIRNAME)/debug LIBDIR = lib/$(OSDIRNAME) BINDIR = bin/$(OSDIRNAME) -CXXFLAGS = -std=c++11 -I include -isystem /usr/include -I$(SRCDIR) -I$(RESDIR) +CXXFLAGS = -std=c++11 -I include -I /usr/include -I$(SRCDIR) -I$(RESDIR) LDFLAGS = $(wildcard $(LIBDIR)/*.a) -lm -lpng -lz -lXfixes -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lX11 -lXpm -lXrender RELEASEFLAGS = -DNDEBUG -O3 -flto -march=native diff --git a/TODO.md b/TODO.md index 11b8c64..a490287 100644 --- a/TODO.md +++ b/TODO.md @@ -1,7 +1,6 @@ # To Do * **Add:** Undo + Redo -* **Add:** Add + remove metatiles * **Fix:** incorrect sidebar size when resizing window (sometimes) @@ -10,7 +9,7 @@ * More color schemes than just Day, Nite, and Indoor * Change color schemes for an already-open map * Swap tilesets for an already-open map -* Use IFileOpenDialog, not SHBrowseForFolder, for new maps +* Use IFileOpenDialog, not SHBrowseForFolder, for new maps (Windows only) ## Never diff --git a/src/main-window.cpp b/src/main-window.cpp index 42fd93b..ef75bff 100644 --- a/src/main-window.cpp +++ b/src/main-window.cpp @@ -584,8 +584,43 @@ void Main_Window::open_map(const char *directory, const char *filename) { redraw(); } -void Main_Window::add_sub_metatiles(int n) { - // TODO: add/remove blocks +void Main_Window::add_sub_metatiles(size_t n) { + size_t s = _metatileset.size(); + if (n == s) { return; } + _metatileset.size(n); + int ms = metatile_size(); + + if (n > s) { + // add metatiles + for (int i = (int)s; i < n; i++) { + int x = ms * (i % METATILES_PER_ROW), y = ms * (i / METATILES_PER_ROW); + Metatile_Button *mtb = new Metatile_Button(_sidebar->x() + x, _sidebar->y() + y, ms, (uint8_t)i); + mtb->callback((Fl_Callback *)select_metatile_cb, this); + _sidebar->add(mtb); + _metatile_buttons[i] = mtb; + } + } + else if (n < s) { + // remove metatiles + if (_selected->id() >= n) { + _selected = _metatile_buttons[0]; + _selected->setonly(); + _sidebar->scroll_to(0, 0); + } + for (int i = (int)n; i < s; i++) { + _sidebar->remove((int)n); + _metatile_buttons[i] = NULL; + } + } + + _sidebar->size(ms * METATILES_PER_ROW + Fl::scrollbar_size(), _sidebar->h()); + _sidebar->init_sizes(); + _sidebar->contents(ms * METATILES_PER_ROW, ms * (((int)_metatileset.size() + METATILES_PER_ROW - 1) / METATILES_PER_ROW)); + + update_labels(); + update_status(NULL); + + redraw(); } void Main_Window::resize_map(int w, int h) { @@ -1008,8 +1043,9 @@ void Main_Window::redo_cb(Fl_Widget *, Main_Window *) { void Main_Window::add_sub_cb(Fl_Widget *, Main_Window *mw) { if (!mw->_map.size()) { return; } - mw->_add_sub_dialog->num_metatiles((uint8_t)mw->_metatileset.size()); + mw->_add_sub_dialog->num_metatiles(mw->_metatileset.size()); mw->_add_sub_dialog->show(mw); + if (mw->_add_sub_dialog->canceled()) { return; } if (mw->_add_sub_dialog->num_metatiles() != mw->_metatileset.size()) { mw->add_sub_metatiles((int)mw->_add_sub_dialog->num_metatiles()); } @@ -1019,6 +1055,7 @@ void Main_Window::resize_cb(Fl_Widget *, Main_Window *mw) { if (!mw->_map.size()) { return; } mw->_resize_dialog->map_size(mw->_map.width(), mw->_map.height()); mw->_resize_dialog->show(mw); + if (mw->_resize_dialog->canceled()) { return; } if (mw->_resize_dialog->map_width() != mw->_map.width() || mw->_resize_dialog->map_height() != mw->_map.height()) { mw->resize_map(mw->_resize_dialog->map_width(), mw->_resize_dialog->map_height()); } diff --git a/src/main-window.h b/src/main-window.h index dc5bbdc..c1a0c37 100644 --- a/src/main-window.h +++ b/src/main-window.h @@ -77,7 +77,7 @@ class Main_Window : public Fl_Double_Window { void open_map(const char *filename); private: void open_map(const char *directory, const char *filename); - void add_sub_metatiles(int n); + void add_sub_metatiles(size_t n); void resize_map(int w, int h); bool save_map(void); bool save_metatileset(void); diff --git a/src/metatileset.cpp b/src/metatileset.cpp index a9109f9..4ceaaf4 100644 --- a/src/metatileset.cpp +++ b/src/metatileset.cpp @@ -29,19 +29,35 @@ void Metatileset::clear() { _modified = false; } +void Metatileset::size(size_t n) { + size_t low = MIN(n, _num_metatiles), high = MAX(n, _num_metatiles); + for (size_t i = low; i < high; i++) { + _metatiles[i]->clear(); + } + _num_metatiles = n; + _modified = true; +} + void Metatileset::draw_metatile(int x, int y, uint8_t id, bool z) const { - Metatile *mt = _metatiles[id]; - int s = TILE_SIZE * (z ? ZOOM_FACTOR : 1); - int d = NUM_CHANNELS * (z ? 1 : ZOOM_FACTOR); - int ld = LINE_BYTES * (z ? 1 : ZOOM_FACTOR); - for (int ty = 0; ty < METATILE_SIZE; ty++) { - for (int tx = 0; tx < METATILE_SIZE; tx++) { - uint8_t tid = mt->tile_id(tx, ty); - const Tile *t = _tileset.tile(tid); - const uchar *rgb = t->rgb(); - fl_draw_image(rgb, x + tx * s, y + ty * s, s, s, d, ld); + if (id < size()) { + Metatile *mt = _metatiles[id]; + int s = TILE_SIZE * (z ? ZOOM_FACTOR : 1); + int d = NUM_CHANNELS * (z ? 1 : ZOOM_FACTOR); + int ld = LINE_BYTES * (z ? 1 : ZOOM_FACTOR); + for (int ty = 0; ty < METATILE_SIZE; ty++) { + for (int tx = 0; tx < METATILE_SIZE; tx++) { + uint8_t tid = mt->tile_id(tx, ty); + const Tile *t = _tileset.tile(tid); + const uchar *rgb = t->rgb(); + fl_draw_image(rgb, x + tx * s, y + ty * s, s, s, d, ld); + } } } + else { + int s = TILE_SIZE * METATILE_SIZE * (z ? ZOOM_FACTOR : 1); + fl_color(EMPTY_RGB); + fl_rectf(x, y, s, s); + } } uchar *Metatileset::print_rgb(const Map &map) const { diff --git a/src/metatileset.h b/src/metatileset.h index 57019ce..5c05e79 100644 --- a/src/metatileset.h +++ b/src/metatileset.h @@ -21,6 +21,7 @@ class Metatileset { Metatileset(); ~Metatileset(); inline size_t size(void) const { return _num_metatiles; } + void size(size_t n); inline Tileset *tileset(void) { return &_tileset; } inline Metatile *metatile(uint8_t id) { return _metatiles[id]; } inline Result result(void) const { return _result; } diff --git a/src/tileset.cpp b/src/tileset.cpp index da2a9e9..308116e 100644 --- a/src/tileset.cpp +++ b/src/tileset.cpp @@ -1,8 +1,10 @@ #include "tiled-image.h" #include "tileset.h" +const uchar empty_rgb[NUM_CHANNELS] = {EMPTY_RGB}; + // Tileset.Lighting x Palette_Map.Palette x Tile.Hue x RGB -static const uchar tileset_colors[3][9][4][3] = { +static const uchar tileset_colors[3][9][4][NUM_CHANNELS] = { { // DAY // WHITE, DARK, LIGHT, BLACK {{8*27, 8*31, 8*27}, {8*13, 8*13, 8*13}, {8*21, 8*21, 8*21}, {8* 7, 8* 7, 8* 7}}, // GRAY @@ -13,7 +15,7 @@ static const uchar tileset_colors[3][9][4][3] = { {{8*27, 8*31, 8*27}, {8*20, 8*15, 8* 3}, {8*24, 8*18, 8* 7}, {8* 7, 8* 7, 8* 7}}, // BROWN {{8*27, 8*31, 8*27}, {8* 5, 8*17, 8*31}, {8*15, 8*31, 8*31}, {8* 7, 8* 7, 8* 7}}, // ROOF {{8*31, 8*31, 8*16}, {8*14, 8* 9, 8* 0}, {8*31, 8*31, 8*16}, {8* 0, 8* 0, 8* 0}}, // TEXT - {{0xAB, 0xCD, 0xEF}, {0xAB, 0xCD, 0xEF}, {0xAB, 0xCD, 0xEF}, {0xAB, 0xCD, 0xEF}}, // UNDEFINED + {{EMPTY_RGB}, {EMPTY_RGB}, {EMPTY_RGB}, {EMPTY_RGB} }, // UNDEFINED }, { // NITE // WHITE, DARK, LIGHT, BLACK @@ -25,7 +27,7 @@ static const uchar tileset_colors[3][9][4][3] = { {{8*15, 8*14, 8*24}, {8* 8, 8* 4, 8* 5}, {8*12, 8* 9, 8*15}, {8* 0, 8* 0, 8* 0}}, // BROWN {{8*15, 8*14, 8*24}, {8*11, 8* 9, 8*20}, {8*13, 8*12, 8*23}, {8* 0, 8* 0, 8* 0}}, // ROOF {{8*31, 8*31, 8*16}, {8*14, 8* 9, 8* 0}, {8*31, 8*31, 8*16}, {8* 0, 8* 0, 8* 0}}, // TEXT - {{0xAB, 0xCD, 0xEF}, {0xAB, 0xCD, 0xEF}, {0xAB, 0xCD, 0xEF}, {0xAB, 0xCD, 0xEF}}, // UNDEFINED + {{EMPTY_RGB}, {EMPTY_RGB}, {EMPTY_RGB}, {EMPTY_RGB} }, // UNDEFINED }, { // INDOOR // WHITE, DARK, LIGHT, BLACK @@ -37,7 +39,7 @@ static const uchar tileset_colors[3][9][4][3] = { {{8*26, 8*24, 8*17}, {8*16, 8*13, 8* 3}, {8*21, 8*17, 8* 7}, {8* 7, 8* 7, 8* 7}}, // BROWN {{8*30, 8*28, 8*26}, {8*14, 8*16, 8*31}, {8*17, 8*19, 8*31}, {8* 7, 8* 7, 8* 7}}, // ROOF {{8*31, 8*31, 8*16}, {8*14, 8* 9, 8* 0}, {8*31, 8*31, 8*16}, {8* 0, 8* 0, 8* 0}}, // TEXT - {{0xAB, 0xCD, 0xEF}, {0xAB, 0xCD, 0xEF}, {0xAB, 0xCD, 0xEF}, {0xAB, 0xCD, 0xEF}}, // UNDEFINED + {{EMPTY_RGB}, {EMPTY_RGB}, {EMPTY_RGB}, {EMPTY_RGB} }, // UNDEFINED }, }; diff --git a/src/tileset.h b/src/tileset.h index 0966f1e..e655508 100644 --- a/src/tileset.h +++ b/src/tileset.h @@ -7,11 +7,14 @@ #include "palette-map.h" #include "utils.h" +#define EMPTY_RGB 0xAB, 0xCD, 0xEF // intentionally leave out parentheses or brackets + class Tileset { public: enum Lighting { DAY, NITE, INDOOR }; enum Result { GFX_OK, GFX_NO_PALETTE, GFX_BAD_FILE, GFX_BAD_EXT, GFX_BAD_DIMS, GFX_TOO_SHORT, GFX_TOO_LARGE, GFX_NOT_GRAYSCALE, GFX_BAD_CMD, GFX_NULL }; + static const uchar empty_rgb[NUM_CHANNELS]; private: std::string _name; Palette_Map _palette_map; diff --git a/src/version.h b/src/version.h index 8968d1a..de783b4 100644 --- a/src/version.h +++ b/src/version.h @@ -1,11 +1,11 @@ #ifndef VERSION_H #define VERSION_H -#define PROGRAM_VERSION 1,4,1 +#define PROGRAM_VERSION 1,4,2 #ifdef _DEBUG -#define PROGRAM_VERSION_STRING "1.4.1 [DEBUG]" +#define PROGRAM_VERSION_STRING "1.4.2 [DEBUG]" #else -#define PROGRAM_VERSION_STRING "1.4.1" +#define PROGRAM_VERSION_STRING "1.4.2" #endif #define PROGRAM_NAME "Polished Map"