After a frantic few days clearing the decks in "the real world", I spent almost two solid days in total tackling the Undo/Redo functions. My logic seemed impeccable, but problems occurred when the user switched to a different Layer. After repeatedly tracing through the code step by painstaking step, it became apparent that an extra step needed to be inserted.
When a project is first started (or loaded), the first action performed will also save out the initial state of the current Layer; thus, when Undo is triggered, the user can step back to the start. With me so far? Now, this is all well and good until the user changes Layers and then makes an edit; using Undo to step back caused the program to miss out a critical step, that of saving the initial state of the Layer that was just activated. And then, of course, the Undo and Redo routines need to be told to ignore this extra step under certain circumstances.
To cut a very long and tedious story short, and after re-writing the routine more times than I care to remember, I finally got everything working (a number of bugs crept in, but this was down to the various Tool routines not calling the Undo Store function properly).
Once this was done, I removed a small piece of code I'd added to allow the user to change the number of Undos; after careful thought, I decided to fix the number at 99, as the invisible steps stored by the program also count towards the total and things could potentially get a bit confusing (especially for me!). Next came the task of checking all Drawing Modes to ensure that the Undo calls were in their correct spots, then another couple of tweaks to ensure that the precise screen/Layer co-ordinates are saved and restored as part of the Undo process.
With the heavyweight tasks out of the way, I set to work on a number of little tweaks and housekeeping chores: first came a small bug in the Update Map routine, which caused the program to crash if the user used drawing tools on a Layer with no Tileset loaded. Next I added the Circle Mode and Circle Fill Mode to the Tools menu (something of an oversight on my part), and updated the documentation accordingly.
The file and I/O routines underwent some tweaks, first in the form of an Undo Reset function, called whenever a Project is loaded or the user chooses New, for example. While digging through the I/O code, I noticed that the Map Set loading routine fails to accommodate maps that might be smaller or larger than the current ones (something of a throwback to the way the Editor worked in the early days). A few quick tweaks later, and the oversight was rectified.
As well as finalising the Project I/O, the final job of the night involved adding some checks to the Map loading code, allowing the user to Undo if a map file is accidentally loaded over the current Layer (this only works for Map files / single Layers, as opposed to Map Set files which load over all Layers, but is an extremely useful addition).
With just a handful of minor things to tackle tomorrow, including a new Demo Version and putting together the installer, it looks like the light at the end of the tunnel is finally here...
