From 5b555f045cf893ff59fdb0bac13237e4f6f026da Mon Sep 17 00:00:00 2001 From: AllyTally Date: Wed, 20 Dec 2023 20:14:09 -0400 Subject: [PATCH 01/10] Add undoing & redoing to the editor It's very easy to make mistakes in VVVVVV's built-in level editor, with no way to undo them. This commit adds an undo and redo system, bound to CTRL+Z for undo and CTRL+Y for redo. The undo and redo stacks don't have any limits, but could easily happen in the future. VVVVVV's data is small enough where this should never be an issue, however. No notes show up for undoing and redoing, because keeping track of what specific action you're doing may bloat the system, and would get annoying for the end-user. Notes are a bit annoying in general, even. --- desktop_version/src/Editor.cpp | 288 +++++++++++++++++++++++++++++++-- desktop_version/src/Editor.h | 30 ++++ 2 files changed, 309 insertions(+), 9 deletions(-) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index 2a04509e7a..6432d0ac3b 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -412,6 +412,8 @@ void editorclass::reset(void) state = EditorState_DRAW; substate = EditorSubState_MAIN; + + undo_buffer.clear(); } void editorclass::show_note(const char* text) @@ -2260,11 +2262,30 @@ void editorclass::add_entity(int rx, int ry, int xp, int yp, int tp, int p1, int entity.p6 = p6; entity.scriptname = ""; + EditorUndoInfo info; + info.room_x = rx; + info.room_y = ry; + info.type = EditorUndoType_ENTITY_ADDED; + info.entity = entity; + info.entity_id = customentities.size(); + undo_buffer.push_back(info); + redo_buffer.clear(); + customentities.push_back(entity); } void editorclass::remove_entity(int t) { + + EditorUndoInfo info; + info.room_x = levx; + info.room_y = levy; + info.type = EditorUndoType_ENTITY_REMOVED; + info.entity_id = t; + info.entity = customentities[t]; + undo_buffer.push_back(info); + redo_buffer.clear(); + customentities.erase(customentities.begin() + t); } @@ -2282,6 +2303,82 @@ int editorclass::get_entity_at(int rx, int ry, int xp, int yp) return -1; } +static void update_old_tiles() +{ + extern editorclass ed; + for (int i = 0; i < SCREEN_WIDTH_TILES * SCREEN_HEIGHT_TILES; i++) + { + const int x = i % SCREEN_WIDTH_TILES; + const int y = i / SCREEN_WIDTH_TILES; + + ed.old_tiles[y * SCREEN_WIDTH_TILES + x] = ed.get_tile(x, y); + } +} + +static void commit_entity(int id) +{ + // We're gonna modify an entity, so save the old version + extern editorclass ed; + + EditorUndoInfo info; + + info.room_x = ed.levx; + info.room_y = ed.levy; + info.type = EditorUndoType_ENTITY_MODIFIED; + info.entity_id = id; + info.entity = customentities[id]; + ed.undo_buffer.push_back(info); + ed.redo_buffer.clear(); +} + +static void commit_tiles() +{ + // We either let go of the mouse button, or we switched rooms, so we need to commit the tiles to the undo buffer + extern editorclass ed; + + EditorUndoInfo info; + + info.room_x = ed.levx; + info.room_y = ed.levy; + info.type = EditorUndoType_TILES; + SDL_memcpy(&info.tiles, &ed.old_tiles, sizeof(ed.old_tiles)); + + ed.undo_buffer.push_back(info); + ed.redo_buffer.clear(); +} + +static void commit_roomdata_change() +{ + extern editorclass ed; + + EditorUndoInfo info; + + info.room_x = ed.levx; + info.room_y = ed.levy; + info.type = EditorUndoType_ROOMDATA; + info.room_data = *cl.getroomprop(ed.levx, ed.levy); + + ed.undo_buffer.push_back(info); + ed.redo_buffer.clear(); +} + +static void commit_roomdata_tiles_change() +{ + extern editorclass ed; + + EditorUndoInfo info; + + info.room_x = ed.levx; + info.room_y = ed.levy; + info.type = EditorUndoType_ROOMDATA_TILES; + update_old_tiles(); + SDL_memcpy(&info.tiles, &ed.old_tiles, sizeof(ed.old_tiles)); + info.room_data = *cl.getroomprop(ed.levx, ed.levy); + + ed.undo_buffer.push_back(info); + ed.redo_buffer.clear(); +} + static void set_tile_interpolated(const int x1, const int x2, const int y1, const int y2, const int tile) { extern editorclass ed; @@ -2446,11 +2543,13 @@ void editorclass::entity_clicked(const int index) { case 1: // Enemies + commit_entity(index); entity->p1 = (entity->p1 + 1) % 4; break; case 2: { // Moving Platforms and Conveyors + commit_entity(index); const bool conveyor = entity->p1 >= 5; entity->p1++; if (conveyor) @@ -2466,6 +2565,7 @@ void editorclass::entity_clicked(const int index) case 10: // Checkpoints // If it's not textured as a checkpoint, then just leave it be + commit_entity(index); if (entity->p1 == 0 || entity->p1 == 1) { entity->p1 = (entity->p1 + 1) % 2; @@ -2474,27 +2574,34 @@ void editorclass::entity_clicked(const int index) case 11: case 16: // Gravity Lines, Start Point + commit_entity(index); entity->p1 = (entity->p1 + 1) % 2; break; case 15: // Crewmates + commit_entity(index); entity->p1 = (entity->p1 + 1) % 6; break; case 17: // Roomtext + commit_entity(index); get_input_line(TEXT_ROOMTEXT, "Enter roomtext:", &entity->scriptname); text_entity = index; break; case 18: // Terminals + commit_entity(index); if (entity->p1 == 0 || entity->p1 == 1) { // Flip the terminal, but if it's not textured as a terminal leave it alone entity->p1 = (entity->p1 + 1) % 2; } - SDL_FALLTHROUGH; + get_input_line(TEXT_SCRIPT, loc::gettext("Enter script name:"), &entity->scriptname); + text_entity = index; + break; case 19: // Script Boxes (and terminals) + commit_entity(index); get_input_line(TEXT_SCRIPT, "Enter script name:", &entity->scriptname); text_entity = index; break; @@ -2517,6 +2624,12 @@ void editorclass::tool_place() { int tile = 0; + if (!placing_tiles) + { + placing_tiles = true; + update_old_tiles(); + } + if (cl.getroomprop(levx, levy)->directmode >= 1) { tile = direct_mode_tile; @@ -2634,17 +2747,22 @@ void editorclass::tool_place() } break; case EditorTool_START_POINT: - //If there is another start point, destroy it + lclickdelay = 1; + //If there is another start point, move it instead for (size_t i = 0; i < customentities.size(); i++) { if (customentities[i].t == 16) { - remove_entity(i); - i--; + commit_entity(i); + customentities[i].rx = levx; + customentities[i].ry = levy; + customentities[i].x = tilex; + customentities[i].y = tiley; + customentities[i].p1 = 0; + return; } } add_entity(levx, levy, tilex, tiley, 16, 0); - lclickdelay = 1; break; default: break; @@ -2997,21 +3115,25 @@ static void handle_draw_input() { if (key.keymap[SDLK_F1]) { + commit_roomdata_tiles_change(); ed.switch_tileset(shift_down); ed.keydelay = 6; } if (key.keymap[SDLK_F2]) { + commit_roomdata_tiles_change(); ed.switch_tilecol(shift_down); ed.keydelay = 6; } if (key.keymap[SDLK_F3]) { + commit_roomdata_change(); ed.switch_enemy(shift_down); ed.keydelay = 6; } if (key.keymap[SDLK_F4]) { + commit_roomdata_change(); ed.keydelay = 6; ed.substate = EditorSubState_DRAW_BOX; ed.box_corner = BoxCorner_FIRST; @@ -3019,6 +3141,7 @@ static void handle_draw_input() } if (key.keymap[SDLK_F5]) { + commit_roomdata_change(); ed.keydelay = 6; ed.substate = EditorSubState_DRAW_BOX; ed.box_corner = BoxCorner_FIRST; @@ -3026,6 +3149,7 @@ static void handle_draw_input() } if (key.keymap[SDLK_F10]) { + commit_roomdata_tiles_change(); if (cl.getroomprop(ed.levx, ed.levy)->directmode == 1) { cl.setroomdirectmode(ed.levx, ed.levy, 0); @@ -3055,11 +3179,13 @@ static void handle_draw_input() if (key.keymap[SDLK_w]) { + commit_roomdata_change(); ed.switch_warpdir(shift_down); ed.keydelay = 6; } if (key.keymap[SDLK_e]) { + commit_roomdata_change(); ed.keydelay = 6; ed.get_input_line(TEXT_ROOMNAME, "Enter new room name:", const_cast(&(cl.getroomprop(ed.levx, ed.levy)->roomname))); game.mapheld = true; @@ -3102,6 +3228,7 @@ static void handle_draw_input() const bool shift = key.keymap[SDLK_LSHIFT] || key.keymap[SDLK_RSHIFT]; if (key.keymap[SDLK_COMMA]) { + commit_roomdata_change(); if (ctrl) { if (shift) @@ -3121,6 +3248,7 @@ static void handle_draw_input() } else if (key.keymap[SDLK_PERIOD]) { + commit_roomdata_change(); if (ctrl) { if (shift) @@ -3192,6 +3320,115 @@ void editorclass::get_input_line(const enum TextMode mode, const std::string& pr old_entity_text = key.keybuffer; } +void process_editor_buffer(const bool undo) +{ + extern editorclass ed; + + std::vector* buffer = undo ? &ed.undo_buffer : &ed.redo_buffer; + + if (buffer->size() == 0) + { + ed.show_note(loc::gettext(undo ? "ERROR: Nothing to undo" : "ERROR: Nothing to redo")); + return; + } + + EditorUndoInfo info = buffer->back(); + buffer->pop_back(); + + ed.levx = info.room_x; + ed.levy = info.room_y; + + EditorUndoInfo new_info; + + new_info.room_x = info.room_x; + new_info.room_y = info.room_y; + new_info.type = info.type; + + switch (info.type) + { + case EditorUndoType_TILES: + for (size_t i = 0; i < SCREEN_WIDTH_TILES * SCREEN_HEIGHT_TILES; i++) + { + const int x = i % SCREEN_WIDTH_TILES; + const int y = i / SCREEN_WIDTH_TILES; + ed.old_tiles[i] = ed.get_tile(x, y); + cl.settile(ed.levx, ed.levy, x, y, info.tiles[i]); + } + + SDL_memcpy(&new_info.tiles, &ed.old_tiles, sizeof(ed.old_tiles)); + + graphics.foregrounddrawn = false; + break; + case EditorUndoType_ENTITY_ADDED: + // Remove the entity + + if (!INBOUNDS_VEC(info.entity_id, customentities)) + { + return; + } + + new_info.type = EditorUndoType_ENTITY_REMOVED; + new_info.entity = customentities[info.entity_id]; + new_info.entity_id = info.entity_id; + customentities.erase(customentities.begin() + info.entity_id); + break; + case EditorUndoType_ENTITY_REMOVED: + // Add the entity back + + customentities.insert(customentities.begin() + info.entity_id, info.entity); + new_info.type = EditorUndoType_ENTITY_ADDED; + new_info.entity_id = info.entity_id; + new_info.entity = info.entity; + break; + case EditorUndoType_ENTITY_MODIFIED: + // Restore the entity + + if (!INBOUNDS_VEC(info.entity_id, customentities)) + { + return; + } + + new_info.entity = customentities[info.entity_id]; + new_info.entity_id = info.entity_id; + customentities[info.entity_id] = info.entity; + break; + case EditorUndoType_ROOMDATA: + new_info.room_data = cl.roomproperties[info.room_x + info.room_y * cl.maxwidth]; + cl.roomproperties[info.room_x + info.room_y * cl.maxwidth] = info.room_data; + graphics.backgrounddrawn = false; + break; + case EditorUndoType_ROOMDATA_TILES: + // Restore the room data + + for (size_t i = 0; i < SCREEN_WIDTH_TILES * SCREEN_HEIGHT_TILES; i++) + { + const int x = i % SCREEN_WIDTH_TILES; + const int y = i / SCREEN_WIDTH_TILES; + ed.old_tiles[i] = ed.get_tile(x, y); + cl.settile(ed.levx, ed.levy, x, y, info.tiles[i]); + } + + SDL_memcpy(&new_info.tiles, &ed.old_tiles, sizeof(ed.old_tiles)); + + new_info.room_data = cl.roomproperties[info.room_x + info.room_y * cl.maxwidth]; + + cl.roomproperties[info.room_x + info.room_y * cl.maxwidth] = info.room_data; + graphics.backgrounddrawn = false; + graphics.foregrounddrawn = false; + ed.updatetiles = true; + break; + } + + if (undo) + { + ed.redo_buffer.push_back(new_info); + } + else + { + ed.undo_buffer.push_back(new_info); + } +} + void editorinput(void) { extern editorclass ed; @@ -3201,6 +3438,12 @@ void editorinput(void) return; } + bool undo_pressed = false; + bool redo_pressed = false; + + bool shift_down = key.keymap[SDLK_LSHIFT] || key.keymap[SDLK_RSHIFT]; + bool ctrl_down = key.keymap[SDLK_LCTRL] || key.keymap[SDLK_RCTRL]; + ed.old_tilex = ed.tilex; ed.old_tiley = ed.tiley; @@ -3226,11 +3469,23 @@ void editorinput(void) { game.press_right = true; } - if (key.isDown(KEYBOARD_z) || key.isDown(KEYBOARD_SPACE) || key.isDown(KEYBOARD_v) || key.isDown(game.controllerButton_flip)) + if ((key.isDown(KEYBOARD_z) && !ctrl_down) || key.isDown(KEYBOARD_SPACE) || key.isDown(KEYBOARD_v) || key.isDown(game.controllerButton_flip)) { game.press_action = true; }; + if (key.isDown(KEYBOARD_z) && ctrl_down && (ed.keydelay == 0)) + { + ed.keydelay = 6; + undo_pressed = true; + } + + if (key.isDown(SDLK_y) && ctrl_down && (ed.keydelay == 0)) + { + ed.keydelay = 6; + redo_pressed = true; + } + if (key.keymap[SDLK_F9] && (ed.keydelay == 0)) { ed.keydelay = 30; ed.show_note(loc::gettext("Reloaded resources")); @@ -3261,9 +3516,6 @@ void editorinput(void) game.mapheld = false; } - bool shift_down = key.keymap[SDLK_LSHIFT] || key.keymap[SDLK_RSHIFT]; - bool ctrl_down = key.keymap[SDLK_LCTRL] || key.keymap[SDLK_RCTRL]; - // Do different things depending on the current state (and substate) switch (ed.state) { @@ -3272,6 +3524,16 @@ void editorinput(void) switch (ed.substate) { case EditorSubState_MAIN: + + if (undo_pressed) + { + process_editor_buffer(true); + } + if (redo_pressed) + { + process_editor_buffer(false); + } + if (escape_pressed) { // We're just in draw mode, so go to the settings menu @@ -3349,6 +3611,9 @@ void editorinput(void) } else { + commit_tiles(); + ed.placing_tiles = false; + ed.updatetiles = true; ed.changeroom = true; graphics.backgrounddrawn = false; @@ -3377,6 +3642,11 @@ void editorinput(void) else if (!key.leftbutton) { ed.lclickdelay = 0; + if (ed.placing_tiles) + { + commit_tiles(); + ed.placing_tiles = false; + } } if (key.rightbutton) diff --git a/desktop_version/src/Editor.h b/desktop_version/src/Editor.h index f9fff57078..a1875bc0e5 100644 --- a/desktop_version/src/Editor.h +++ b/desktop_version/src/Editor.h @@ -133,6 +133,31 @@ struct GhostInfo int frame; // .drawframe }; + +enum EditorUndoTypes +{ + EditorUndoType_TILES, // Tiles modified + EditorUndoType_ROOMDATA, // Room data modified + EditorUndoType_ROOMDATA_TILES, // Room data modified (and stores tiles) + EditorUndoType_ENTITY_ADDED, // Entity added + EditorUndoType_ENTITY_REMOVED, // Entity removed + EditorUndoType_ENTITY_MODIFIED, // Entity properties modified +}; + +struct EditorUndoInfo +{ + EditorUndoTypes type; + int tiles[SCREEN_WIDTH_TILES * SCREEN_HEIGHT_TILES]; + int room_x; + int room_y; + EditorTilesets tileset; + int tilecol; + int entity_id; + CustomEntity entity; + RoomProperty room_data; + +}; + class editorclass { public: @@ -282,6 +307,11 @@ class editorclass std::vector ghosts; int current_ghosts; + + std::vector undo_buffer; + std::vector redo_buffer; + bool placing_tiles = false; + int old_tiles[SCREEN_WIDTH_TILES * SCREEN_HEIGHT_TILES]; }; void editorrender(void); From 37b309143226d4e73f318fcdb9699772526b9cc2 Mon Sep 17 00:00:00 2001 From: AllyTally Date: Wed, 20 Dec 2023 20:29:51 -0400 Subject: [PATCH 02/10] Add level resizing to undo/redo system --- desktop_version/src/Editor.cpp | 56 ++++++++++++++++++++++++---------- desktop_version/src/Editor.h | 4 ++- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index 6432d0ac3b..ebf7c4a2ce 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -3417,6 +3417,14 @@ void process_editor_buffer(const bool undo) graphics.foregrounddrawn = false; ed.updatetiles = true; break; + case EditorUndoType_LEVEL_SIZE: + // Restore the level size + new_info.level_width = cl.mapwidth; + new_info.level_height = cl.mapheight; + + cl.mapwidth = info.level_width; + cl.mapheight = info.level_height; + break; } if (undo) @@ -3582,6 +3590,8 @@ void editorinput(void) } else if (shift_down) { + int old_width = cl.mapwidth; + int old_height = cl.mapheight; if (up_pressed) cl.mapheight--; if (down_pressed) cl.mapheight++; @@ -3591,23 +3601,37 @@ void editorinput(void) cl.mapwidth = SDL_clamp(cl.mapwidth, 1, cl.maxwidth); cl.mapheight = SDL_clamp(cl.mapheight, 1, cl.maxheight); - ed.updatetiles = true; - ed.changeroom = true; - graphics.backgrounddrawn = false; - graphics.foregrounddrawn = false; - - ed.levx = POS_MOD(ed.levx, cl.mapwidth); - ed.levy = POS_MOD(ed.levy, cl.mapheight); - - char buffer[3 * SCREEN_WIDTH_CHARS + 1]; - vformat_buf( - buffer, sizeof(buffer), - loc::gettext("Mapsize is now [{width},{height}]"), - "width:int, height:int", - cl.mapwidth, cl.mapheight - ); + if (old_width != cl.mapwidth || old_height != cl.mapheight) + { - ed.show_note(buffer); + ed.updatetiles = true; + ed.changeroom = true; + graphics.backgrounddrawn = false; + graphics.foregrounddrawn = false; + + ed.levx = POS_MOD(ed.levx, cl.mapwidth); + ed.levy = POS_MOD(ed.levy, cl.mapheight); + + char buffer[3 * SCREEN_WIDTH_CHARS + 1]; + vformat_buf( + buffer, sizeof(buffer), + loc::gettext("Mapsize is now [{width},{height}]"), + "width:int, height:int", + cl.mapwidth, cl.mapheight + ); + + ed.show_note(buffer); + + EditorUndoInfo info; + info.type = EditorUndoType_LEVEL_SIZE; + info.level_width = old_width; + info.level_height = old_height; + info.room_x = ed.levx; + info.room_y = ed.levy; + + ed.undo_buffer.push_back(info); + ed.redo_buffer.clear(); + } } else { diff --git a/desktop_version/src/Editor.h b/desktop_version/src/Editor.h index a1875bc0e5..28f78f4416 100644 --- a/desktop_version/src/Editor.h +++ b/desktop_version/src/Editor.h @@ -142,6 +142,7 @@ enum EditorUndoTypes EditorUndoType_ENTITY_ADDED, // Entity added EditorUndoType_ENTITY_REMOVED, // Entity removed EditorUndoType_ENTITY_MODIFIED, // Entity properties modified + EditorUndoType_LEVEL_SIZE // Level size modified }; struct EditorUndoInfo @@ -155,7 +156,8 @@ struct EditorUndoInfo int entity_id; CustomEntity entity; RoomProperty room_data; - + int level_width; + int level_height; }; class editorclass From b7f9ba5c2d27f255da9384e0e43690b9462d3127 Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Tue, 1 Oct 2024 16:01:05 -0300 Subject: [PATCH 03/10] searchable gettext for undo/redo notes --- desktop_version/src/Editor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index ebf7c4a2ce..9006d0cf4b 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -3328,7 +3328,7 @@ void process_editor_buffer(const bool undo) if (buffer->size() == 0) { - ed.show_note(loc::gettext(undo ? "ERROR: Nothing to undo" : "ERROR: Nothing to redo")); + ed.show_note(undo ? loc::gettext("ERROR: Nothing to undo") : loc::gettext("ERROR: Nothing to redo")); return; } From d31c0f7c47f3acde123a841fca215b58df37ab9e Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Tue, 1 Oct 2024 16:05:43 -0300 Subject: [PATCH 04/10] add undo/redo lines to lang files --- desktop_version/lang/ar/strings.xml | 2 ++ desktop_version/lang/ca/strings.xml | 2 ++ desktop_version/lang/cy/strings.xml | 2 ++ desktop_version/lang/de/strings.xml | 2 ++ desktop_version/lang/en/strings.xml | 2 ++ desktop_version/lang/eo/strings.xml | 2 ++ desktop_version/lang/es/strings.xml | 2 ++ desktop_version/lang/es_419/strings.xml | 2 ++ desktop_version/lang/es_AR/strings.xml | 2 ++ desktop_version/lang/fr/strings.xml | 2 ++ desktop_version/lang/ga/strings.xml | 2 ++ desktop_version/lang/it/strings.xml | 2 ++ desktop_version/lang/ja/strings.xml | 2 ++ desktop_version/lang/ko/strings.xml | 2 ++ desktop_version/lang/nl/strings.xml | 2 ++ desktop_version/lang/pl/strings.xml | 2 ++ desktop_version/lang/pt_BR/strings.xml | 2 ++ desktop_version/lang/pt_PT/strings.xml | 2 ++ desktop_version/lang/ru/strings.xml | 2 ++ desktop_version/lang/szl/strings.xml | 2 ++ desktop_version/lang/tr/strings.xml | 2 ++ desktop_version/lang/uk/strings.xml | 2 ++ desktop_version/lang/zh/strings.xml | 2 ++ desktop_version/lang/zh_TW/strings.xml | 2 ++ 24 files changed, 48 insertions(+) diff --git a/desktop_version/lang/ar/strings.xml b/desktop_version/lang/ar/strings.xml index 7c192c4313..cdf7715b7e 100644 --- a/desktop_version/lang/ar/strings.xml +++ b/desktop_version/lang/ar/strings.xml @@ -636,6 +636,8 @@ + + diff --git a/desktop_version/lang/ca/strings.xml b/desktop_version/lang/ca/strings.xml index fa956d2fad..28ba31c6fa 100644 --- a/desktop_version/lang/ca/strings.xml +++ b/desktop_version/lang/ca/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/cy/strings.xml b/desktop_version/lang/cy/strings.xml index 90b239130a..bd45003907 100644 --- a/desktop_version/lang/cy/strings.xml +++ b/desktop_version/lang/cy/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/de/strings.xml b/desktop_version/lang/de/strings.xml index e869c9db5c..381fee960f 100644 --- a/desktop_version/lang/de/strings.xml +++ b/desktop_version/lang/de/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/en/strings.xml b/desktop_version/lang/en/strings.xml index ee3db7b600..1412989efb 100644 --- a/desktop_version/lang/en/strings.xml +++ b/desktop_version/lang/en/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/eo/strings.xml b/desktop_version/lang/eo/strings.xml index 63fcd00303..33f0ffdb4e 100644 --- a/desktop_version/lang/eo/strings.xml +++ b/desktop_version/lang/eo/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/es/strings.xml b/desktop_version/lang/es/strings.xml index c2cfae353a..30d4e8bd64 100644 --- a/desktop_version/lang/es/strings.xml +++ b/desktop_version/lang/es/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/es_419/strings.xml b/desktop_version/lang/es_419/strings.xml index ea6a1cf929..9db8f63372 100644 --- a/desktop_version/lang/es_419/strings.xml +++ b/desktop_version/lang/es_419/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/es_AR/strings.xml b/desktop_version/lang/es_AR/strings.xml index e9bf98b15f..befb125dfd 100644 --- a/desktop_version/lang/es_AR/strings.xml +++ b/desktop_version/lang/es_AR/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/fr/strings.xml b/desktop_version/lang/fr/strings.xml index b7f69dc427..dc844ba636 100644 --- a/desktop_version/lang/fr/strings.xml +++ b/desktop_version/lang/fr/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/ga/strings.xml b/desktop_version/lang/ga/strings.xml index bb19ca2cfd..f84a0bc074 100644 --- a/desktop_version/lang/ga/strings.xml +++ b/desktop_version/lang/ga/strings.xml @@ -630,6 +630,8 @@ Déan cóip chúltaca, ar eagla na heagla." explanation="translation maintenance + + diff --git a/desktop_version/lang/it/strings.xml b/desktop_version/lang/it/strings.xml index 4a3c32f318..df4c8d1b2c 100644 --- a/desktop_version/lang/it/strings.xml +++ b/desktop_version/lang/it/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/ja/strings.xml b/desktop_version/lang/ja/strings.xml index 0586db9ebe..34daa1d03b 100644 --- a/desktop_version/lang/ja/strings.xml +++ b/desktop_version/lang/ja/strings.xml @@ -664,6 +664,8 @@ Steam Deckには対応していません。" explanation="" max="38*5" max_local + + diff --git a/desktop_version/lang/ko/strings.xml b/desktop_version/lang/ko/strings.xml index 10ff2981ba..45917d6168 100755 --- a/desktop_version/lang/ko/strings.xml +++ b/desktop_version/lang/ko/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/nl/strings.xml b/desktop_version/lang/nl/strings.xml index 09a551ae3c..0b83968eb0 100644 --- a/desktop_version/lang/nl/strings.xml +++ b/desktop_version/lang/nl/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/pl/strings.xml b/desktop_version/lang/pl/strings.xml index c88a28fa81..41c01df085 100644 --- a/desktop_version/lang/pl/strings.xml +++ b/desktop_version/lang/pl/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/pt_BR/strings.xml b/desktop_version/lang/pt_BR/strings.xml index dd5d677b1e..f14c977f02 100644 --- a/desktop_version/lang/pt_BR/strings.xml +++ b/desktop_version/lang/pt_BR/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/pt_PT/strings.xml b/desktop_version/lang/pt_PT/strings.xml index 51ca859bb6..083f57b417 100644 --- a/desktop_version/lang/pt_PT/strings.xml +++ b/desktop_version/lang/pt_PT/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/ru/strings.xml b/desktop_version/lang/ru/strings.xml index 3b310c8842..7d6042ba7b 100644 --- a/desktop_version/lang/ru/strings.xml +++ b/desktop_version/lang/ru/strings.xml @@ -653,6 +653,8 @@ + + diff --git a/desktop_version/lang/szl/strings.xml b/desktop_version/lang/szl/strings.xml index 386402523e..32d41ac697 100644 --- a/desktop_version/lang/szl/strings.xml +++ b/desktop_version/lang/szl/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/tr/strings.xml b/desktop_version/lang/tr/strings.xml index cd98037d58..a2cbb074a9 100644 --- a/desktop_version/lang/tr/strings.xml +++ b/desktop_version/lang/tr/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/uk/strings.xml b/desktop_version/lang/uk/strings.xml index 33c6fa97b5..c6c12521c0 100644 --- a/desktop_version/lang/uk/strings.xml +++ b/desktop_version/lang/uk/strings.xml @@ -628,6 +628,8 @@ + + diff --git a/desktop_version/lang/zh/strings.xml b/desktop_version/lang/zh/strings.xml index a9b83ef0ee..e5fa526a87 100644 --- a/desktop_version/lang/zh/strings.xml +++ b/desktop_version/lang/zh/strings.xml @@ -638,6 +638,8 @@ + + diff --git a/desktop_version/lang/zh_TW/strings.xml b/desktop_version/lang/zh_TW/strings.xml index 9d58c94ec5..62c5e649d7 100644 --- a/desktop_version/lang/zh_TW/strings.xml +++ b/desktop_version/lang/zh_TW/strings.xml @@ -638,6 +638,8 @@ + + From b5520bb940d1b90b3df25900d78136e5c2204183 Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Thu, 3 Oct 2024 21:46:39 -0300 Subject: [PATCH 05/10] A few fixes and cleanup The main fix was how holding right click to remove tiles did not commit an action. --- desktop_version/src/Editor.cpp | 38 +++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index 9006d0cf4b..972c8e4bcb 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -2276,7 +2276,6 @@ void editorclass::add_entity(int rx, int ry, int xp, int yp, int tp, int p1, int void editorclass::remove_entity(int t) { - EditorUndoInfo info; info.room_x = levx; info.room_y = levy; @@ -2308,10 +2307,7 @@ static void update_old_tiles() extern editorclass ed; for (int i = 0; i < SCREEN_WIDTH_TILES * SCREEN_HEIGHT_TILES; i++) { - const int x = i % SCREEN_WIDTH_TILES; - const int y = i / SCREEN_WIDTH_TILES; - - ed.old_tiles[y * SCREEN_WIDTH_TILES + x] = ed.get_tile(x, y); + ed.old_tiles[i] = ed.get_tile(i % SCREEN_WIDTH_TILES, i / SCREEN_WIDTH_TILES); } } @@ -2509,6 +2505,12 @@ void editorclass::handle_tile_placement(const int tile) void editorclass::tool_remove() { + if (!placing_tiles) + { + placing_tiles = true; + update_old_tiles(); + } + switch (current_tool) { case EditorTool_WALLS: @@ -3659,23 +3661,25 @@ void editorinput(void) } // Mouse input - if (key.leftbutton && ed.lclickdelay == 0) + if (key.rightbutton) { - ed.tool_place(); + ed.tool_remove(); } - else if (!key.leftbutton) + else { - ed.lclickdelay = 0; - if (ed.placing_tiles) + if (key.leftbutton && ed.lclickdelay == 0) { - commit_tiles(); - ed.placing_tiles = false; + ed.tool_place(); + } + else if (!key.leftbutton) + { + ed.lclickdelay = 0; + if (ed.placing_tiles) + { + commit_tiles(); + ed.placing_tiles = false; + } } - } - - if (key.rightbutton) - { - ed.tool_remove(); } if (key.middlebutton) From 4745ffc1f348a070ccf9f437ddcd8fc85325f96d Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Thu, 3 Oct 2024 21:51:49 -0300 Subject: [PATCH 06/10] Spikes also need to commit --- desktop_version/src/Editor.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index 972c8e4bcb..c52db32189 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -2649,6 +2649,12 @@ void editorclass::tool_place() break; } case EditorTool_SPIKES: + if (!placing_tiles) + { + placing_tiles = true; + update_old_tiles(); + } + set_tile_interpolated(old_tilex, tilex, old_tiley, tiley, 8); break; case EditorTool_TRINKETS: From f2bb58bba27efe8af3dcdeca4403402d92030485 Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Thu, 3 Oct 2024 22:12:36 -0300 Subject: [PATCH 07/10] Cancelling placing a terminal/script box shouldn't have undo events --- desktop_version/src/Editor.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index c52db32189..a7a191eb86 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -2375,6 +2375,13 @@ static void commit_roomdata_tiles_change() ed.redo_buffer.clear(); } +static void uncommit() +{ + extern editorclass ed; + + ed.undo_buffer.pop_back(); +} + static void set_tile_interpolated(const int x1, const int x2, const int y1, const int y2, const int tile) { extern editorclass ed; @@ -3846,6 +3853,9 @@ void editorinput(void) if (ed.old_entity_text == "") { ed.remove_entity(ed.text_entity); + // Uncommit the past two actions + uncommit(); + uncommit(); } } From 662a86d1cdedc21fd2ec75df3c6c3b1f776e5e78 Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Thu, 3 Oct 2024 22:13:33 -0300 Subject: [PATCH 08/10] Don't commit tile events if removing entities --- desktop_version/src/Editor.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index a7a191eb86..c9fc494fb1 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -2512,19 +2512,23 @@ void editorclass::handle_tile_placement(const int tile) void editorclass::tool_remove() { - if (!placing_tiles) - { - placing_tiles = true; - update_old_tiles(); - } - switch (current_tool) { case EditorTool_WALLS: case EditorTool_BACKING: + if (!placing_tiles) + { + placing_tiles = true; + update_old_tiles(); + } handle_tile_placement(0); break; case EditorTool_SPIKES: + if (!placing_tiles) + { + placing_tiles = true; + update_old_tiles(); + } set_tile_interpolated(old_tilex, tilex, old_tiley, tiley, 0); break; default: From 3494724daa2353c92dd28cb28297bd6b35e40f61 Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Thu, 3 Oct 2024 22:39:18 -0300 Subject: [PATCH 09/10] Clear redo buffer on level load --- desktop_version/src/Editor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index c9fc494fb1..2dbf51c1a6 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -414,6 +414,7 @@ void editorclass::reset(void) substate = EditorSubState_MAIN; undo_buffer.clear(); + redo_buffer.clear(); } void editorclass::show_note(const char* text) From 37fdefea8aec4fe228b0b2d0c3091e3cd3a11da0 Mon Sep 17 00:00:00 2001 From: NyakoFox Date: Fri, 4 Oct 2024 12:55:06 -0300 Subject: [PATCH 10/10] Remove unneeded pointers from memcpy --- desktop_version/src/Editor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp index 2dbf51c1a6..c1279c2999 100644 --- a/desktop_version/src/Editor.cpp +++ b/desktop_version/src/Editor.cpp @@ -2338,7 +2338,7 @@ static void commit_tiles() info.room_x = ed.levx; info.room_y = ed.levy; info.type = EditorUndoType_TILES; - SDL_memcpy(&info.tiles, &ed.old_tiles, sizeof(ed.old_tiles)); + SDL_memcpy(info.tiles, ed.old_tiles, sizeof(ed.old_tiles)); ed.undo_buffer.push_back(info); ed.redo_buffer.clear(); @@ -2369,7 +2369,7 @@ static void commit_roomdata_tiles_change() info.room_y = ed.levy; info.type = EditorUndoType_ROOMDATA_TILES; update_old_tiles(); - SDL_memcpy(&info.tiles, &ed.old_tiles, sizeof(ed.old_tiles)); + SDL_memcpy(info.tiles, ed.old_tiles, sizeof(ed.old_tiles)); info.room_data = *cl.getroomprop(ed.levx, ed.levy); ed.undo_buffer.push_back(info); @@ -3375,7 +3375,7 @@ void process_editor_buffer(const bool undo) cl.settile(ed.levx, ed.levy, x, y, info.tiles[i]); } - SDL_memcpy(&new_info.tiles, &ed.old_tiles, sizeof(ed.old_tiles)); + SDL_memcpy(new_info.tiles, ed.old_tiles, sizeof(ed.old_tiles)); graphics.foregrounddrawn = false; break; @@ -3428,7 +3428,7 @@ void process_editor_buffer(const bool undo) cl.settile(ed.levx, ed.levy, x, y, info.tiles[i]); } - SDL_memcpy(&new_info.tiles, &ed.old_tiles, sizeof(ed.old_tiles)); + SDL_memcpy(new_info.tiles, ed.old_tiles, sizeof(ed.old_tiles)); new_info.room_data = cl.roomproperties[info.room_x + info.room_y * cl.maxwidth];