After a couple of days working on other projects, work resumed on the Editor and saw me adding the relevant calls to the "Undo Store" routine from the various tool routines. It became apparent that the Pen and Brush routines needed a little debounce code, mainly because every frame that the mouse button is depressed is counted as a separate edit.
The debounce was relatively simple to write, however, and merely involved incrementing a flag each frame if the button is held, and calling the Undo Store routine if it isn't - now the user can make huge swirling edits with the Pen or Brush, but the Undo Store routine only kicks in when the mouse button is released.
Continued with some housekeeping checks, specifically to stop Brush mode being activated or Brushes being stored if there is no Tileset assigned to the current Layer. Next came the various Tile functions (Copy, Rotate, Clear, etc.), which required a few little tweaks to ensure that empty memory isn't being tinkered with.
Wednesday, December 21, 2005
Sunday, December 18, 2005
Sunday 18th
Today was something of an anti-climax, blog-wise; after about three or four solid days' work invested in the Undo/Redo routine in the past, I managed to sit down and code a new, working routine in the space of an hour! After setting up the buffers and variables, it was merely a case of tackling each bit of functionality in a methodical fashion (I'm certain that looking at old notes or code would have confused me further, and possibly why successful results have eluded me in the past).
Flushed with this success - although extremely sceptical that the routine works at all - I added some extra variables to store the map number, as well as the cursor positions - this way, when the user steps back with Undo, they'll be returned to the relevant layer and screen position.
Turned my attention to the Text Display routine, which seems to flicker in different ways on different machines. Although some chunks of text have flags attached to them (so that the text is only updated if information changes), some didn't, so a small amount of time was devoted to tidying up the code and adding extra checks. The Editor looks exactly the same on my Win2K setup, bt I shall be testing this routine with interest on my laptop.
Next came a small toolbar tweak, with the addition of a Show All option positioned between the Zoom Out and Zoom In icons (something of an oversight, in retrospect).
Flushed with this success - although extremely sceptical that the routine works at all - I added some extra variables to store the map number, as well as the cursor positions - this way, when the user steps back with Undo, they'll be returned to the relevant layer and screen position.
Turned my attention to the Text Display routine, which seems to flicker in different ways on different machines. Although some chunks of text have flags attached to them (so that the text is only updated if information changes), some didn't, so a small amount of time was devoted to tidying up the code and adding extra checks. The Editor looks exactly the same on my Win2K setup, bt I shall be testing this routine with interest on my laptop.
Next came a small toolbar tweak, with the addition of a Show All option positioned between the Zoom Out and Zoom In icons (something of an oversight, in retrospect).
Saturday, December 17, 2005
Saturday 17th
After a couple of sessions with the tried and tested pencil and paper, I already have a few routines plotted out ready to be coded. The past couple of days have been spent tinkering with Symmetry, as it's always been one of my favourite features from Dpaint, and seemed fairly easy - in theory! - to implement.
The first task was to set up some test code in my Pen Mode routine, then convert this into a modular routine which could be used by everything else. It took a little bit of time to get my head around the X and Y Symmetry combined, but after a couple of sessions the code was working properly; all that remained was a few tweaks to the cursor display routine.
Today was spent mostly debugging and testing, as the Symmetry code was applied to as many tools as possible. I also added key checks so that the X/Y lines (axis) can be moved, added the X/Y lines to the MiniMap, and created a Symmetry menu to house all of the various commands (and allow the user to change the line colour).
The final task was to explore the possibility of applying Symmetry to the Brush handling functions; after a little tinkering, I managed to get some progress made, but the sheer number of factors - handling point, rotation, sizes - means that this task will probably wait until after Beta.
The first task was to set up some test code in my Pen Mode routine, then convert this into a modular routine which could be used by everything else. It took a little bit of time to get my head around the X and Y Symmetry combined, but after a couple of sessions the code was working properly; all that remained was a few tweaks to the cursor display routine.
Today was spent mostly debugging and testing, as the Symmetry code was applied to as many tools as possible. I also added key checks so that the X/Y lines (axis) can be moved, added the X/Y lines to the MiniMap, and created a Symmetry menu to house all of the various commands (and allow the user to change the line colour).
The final task was to explore the possibility of applying Symmetry to the Brush handling functions; after a little tinkering, I managed to get some progress made, but the sheer number of factors - handling point, rotation, sizes - means that this task will probably wait until after Beta.
Wednesday, December 14, 2005
Wednesday 14th
Started off today's session by tying up the loose ends in the Project I/O system, writing the code to store the Grab buffers and their thumbnails (as an afterthought, I tweaked the code so that it generates the thumbnails rather than store them - only a saving of 32k to the Project filesize, but every little helps).
It made sense to tackle the New Project routine next, as I'm knee-deep in initialisation code; again, this entailed sifting through the variables and compiling a routine to reset each and every relevant variable. Luckily, this only took about an hour of furious typing, as I could already count on a coupe of existing routines to initialise all of the Map and Tile variables (the remaining initialisations I merely copied 'n' pasted from the Load Project routine).
Thankfully, my New Project window - which appears when the Editor is first loaded - was coded in a way that allowed me to integrate my variable reset routine quite easily; on boot-up, the code sets up the environment accordingly; on selecting New Project, it sets up the environment and resets the relevant flags. Peachy. :)
Did a little housekeeping while I was tinkering with the New Project code, and made sure that all popup windows were deactivated properly (this entails freeing all of the gadgets, buttons, and text labels to ensure that the system resources are freed up properly).
Also took the liberty of updating my Splash Screen, and added some Credits to the Help/About dialogue box. Next came a tweak to the toolbar, as I wanted to add the Project Load/Save icons and space things out a little.
With most of the major functionality now complete, I'm finally starting to see the light at the end of the tunnel. The following tasks remain in my way before Beta:
1. Undo & Redo - I currently have some scribbled notes and flowcharts for this routine; the more I use the Editor, the more I miss having the ability to quickly erase a mistake, so this will be an essential addition.
2. Map Rotate - I have X/Y/Z flipping currently, but I want to add the facility to flip the map 90 degrees in any direction; currently my code for this flatly refuses to work.
3. Tile Duplicates - The biggest problem with this routine is how the data is presented to the user. It's an extremely useful tool to have, however, so I shall be plotting this on paper over the next couple of days.
4. Circle Draw - The current Circle routine is poor to say the least; I need to get my head around the maths and get the routine finished.
5. MiniMap Scrolling - There's a small bug in the MiniMap routine which fails to update the scroll values when the mouse is used to drag the MiniMap window. This, I predict, will be a swine to debug.
6. Test Map - The bulk of the code for this is already in place; I simply need to work on the scroll routine to make it as user-friendly as possible.
Needless to say, if anyone out there has any suggestions on the above tasks, I'd be glad to hear from you!
It made sense to tackle the New Project routine next, as I'm knee-deep in initialisation code; again, this entailed sifting through the variables and compiling a routine to reset each and every relevant variable. Luckily, this only took about an hour of furious typing, as I could already count on a coupe of existing routines to initialise all of the Map and Tile variables (the remaining initialisations I merely copied 'n' pasted from the Load Project routine).
Thankfully, my New Project window - which appears when the Editor is first loaded - was coded in a way that allowed me to integrate my variable reset routine quite easily; on boot-up, the code sets up the environment accordingly; on selecting New Project, it sets up the environment and resets the relevant flags. Peachy. :)
Did a little housekeeping while I was tinkering with the New Project code, and made sure that all popup windows were deactivated properly (this entails freeing all of the gadgets, buttons, and text labels to ensure that the system resources are freed up properly).
Also took the liberty of updating my Splash Screen, and added some Credits to the Help/About dialogue box. Next came a tweak to the toolbar, as I wanted to add the Project Load/Save icons and space things out a little.
With most of the major functionality now complete, I'm finally starting to see the light at the end of the tunnel. The following tasks remain in my way before Beta:
1. Undo & Redo - I currently have some scribbled notes and flowcharts for this routine; the more I use the Editor, the more I miss having the ability to quickly erase a mistake, so this will be an essential addition.
2. Map Rotate - I have X/Y/Z flipping currently, but I want to add the facility to flip the map 90 degrees in any direction; currently my code for this flatly refuses to work.
3. Tile Duplicates - The biggest problem with this routine is how the data is presented to the user. It's an extremely useful tool to have, however, so I shall be plotting this on paper over the next couple of days.
4. Circle Draw - The current Circle routine is poor to say the least; I need to get my head around the maths and get the routine finished.
5. MiniMap Scrolling - There's a small bug in the MiniMap routine which fails to update the scroll values when the mouse is used to drag the MiniMap window. This, I predict, will be a swine to debug.
6. Test Map - The bulk of the code for this is already in place; I simply need to work on the scroll routine to make it as user-friendly as possible.
Needless to say, if anyone out there has any suggestions on the above tasks, I'd be glad to hear from you!
Tuesday, December 13, 2005
Tuesday 13th
Kicked off today's session by tweaking the Zoom function slightly; I figured it'd be nice to see the whole map Zoomed out, not just the current layer, so I added the option to Zoom Current, Zoom Visible, or Zoom All, for maximum flexibility. The Editor chugs a little bit when all 8 layers are visible and zoomed out to their fullest, but as it's intended as purely a visual aid rather than an editing mode, I can live with a little slowdown.
After updating the Project I/O accordingly (every time I add a significant variable I now have to adjust the Project I/O code, which helps keep me organised!), I moved on to a small problemette with the Animation routine, as mentioned a couple of days ago.
Basically, each animation is independent of the Tilesets that might be loaded. For instance, Animation 1 might choose to animate through a sequence of 5 tiles from Tileset 3; Animation 2 might choose to cycle through some frames from Tileset 1. Though this may seem slightly unorthodox, it allows the artist to build up a library of animations based on the current project (indeed, the whole point of the Editor's current layout was to allow everything to be contained in one easy-to-handle chunk). The programmer can then take the animation data and use it accordingly; after all, the Editor may recognise key variables, but in the real world, certain attributes - such as the Tileset - could be ignored.
After getting my head around this, I tweaked the relevant controls and updated the Project I/O code (as well as the standard Animation I/O code) accordingly. Then, I tweaked the various tools and displays to ensure that only animations which affect the currently selected Tileset are displayed. It works beautifully, but I hope it all makes sense to the end user.
Seeing as I was knee-deep in Tileset-related code, I also took the bold step of changing how the Tileset selection works; previously, pressing Tab would increase the Tileset number and thus, change the Tileset for the current Layer. However, this also meant that changing the Tileset in Anim or Grab mode also changed the Tileset for the map. With the new system, the user has to press Ctrl+Tab in order to assign the current Tileset to the current Layer (and thanks to some obscure variable assignments tucked away in my Map Display routine, this took far longer than it should!).
This had a knock-on effect that entailed changing any and every line of code that referenced the Tileset index value, replacing it with the value appropriate to the current map. This was fraught with the potential for screw-ups, but thankfully I managed to escape with just one minor error (and it also allowed me to fix a bug in my Invert Mask routine).
Next came a small change to the Dropper routine, which not only grabs the tile under the cursor, but also now jumps to the appropriate Tileset, too. The final task of the night involved tracking down a couple of bugs in the MiniMap routines, but thankfully these potentially big problems turned out to be minor oversights.
The final task remaining, as far as Project I/O is concerned, relates to the Grab Buffers and images; with this code completed hopefully tomorrow, my To-Do list will comprise just a handful of tasks (bugs and changes aside), and with this in mind I've set myself a deadline of December 31st for the Beta date. Rest assured, if things go badly over the next two weeks I'll pop back and erase this paragraph. :)
After updating the Project I/O accordingly (every time I add a significant variable I now have to adjust the Project I/O code, which helps keep me organised!), I moved on to a small problemette with the Animation routine, as mentioned a couple of days ago.
Basically, each animation is independent of the Tilesets that might be loaded. For instance, Animation 1 might choose to animate through a sequence of 5 tiles from Tileset 3; Animation 2 might choose to cycle through some frames from Tileset 1. Though this may seem slightly unorthodox, it allows the artist to build up a library of animations based on the current project (indeed, the whole point of the Editor's current layout was to allow everything to be contained in one easy-to-handle chunk). The programmer can then take the animation data and use it accordingly; after all, the Editor may recognise key variables, but in the real world, certain attributes - such as the Tileset - could be ignored.
After getting my head around this, I tweaked the relevant controls and updated the Project I/O code (as well as the standard Animation I/O code) accordingly. Then, I tweaked the various tools and displays to ensure that only animations which affect the currently selected Tileset are displayed. It works beautifully, but I hope it all makes sense to the end user.
Seeing as I was knee-deep in Tileset-related code, I also took the bold step of changing how the Tileset selection works; previously, pressing Tab would increase the Tileset number and thus, change the Tileset for the current Layer. However, this also meant that changing the Tileset in Anim or Grab mode also changed the Tileset for the map. With the new system, the user has to press Ctrl+Tab in order to assign the current Tileset to the current Layer (and thanks to some obscure variable assignments tucked away in my Map Display routine, this took far longer than it should!).
This had a knock-on effect that entailed changing any and every line of code that referenced the Tileset index value, replacing it with the value appropriate to the current map. This was fraught with the potential for screw-ups, but thankfully I managed to escape with just one minor error (and it also allowed me to fix a bug in my Invert Mask routine).
Next came a small change to the Dropper routine, which not only grabs the tile under the cursor, but also now jumps to the appropriate Tileset, too. The final task of the night involved tracking down a couple of bugs in the MiniMap routines, but thankfully these potentially big problems turned out to be minor oversights.
The final task remaining, as far as Project I/O is concerned, relates to the Grab Buffers and images; with this code completed hopefully tomorrow, my To-Do list will comprise just a handful of tasks (bugs and changes aside), and with this in mind I've set myself a deadline of December 31st for the Beta date. Rest assured, if things go badly over the next two weeks I'll pop back and erase this paragraph. :)
Monday, December 12, 2005
Monday 12th
Added a couple of new functions to the Tiles menu; the first, Tile Close, allows the user to clear the current Tileset, leaving a "blank" slot (it only became apparent that this was needed thanks to the addition of the Project I/O code - since the Load Project code will load in every defined Tileset, being able to eject a Tileset is useful if it isn't required as part of the Project file).
Also started on the Change Tilesize function, which had been on the back burner for a while, but again came into play once the Project I/O was started (seeing as I'm already writing small routines to initialise changes such as Tilesize, I may as well use them throughout the Editor).
As an afterthought, I added the option to either clear the existing Tilesets, or resize them; though this may become an issue when moving from 16x16 tiles to 128x128 tiles, it does represent a nifty way of generating thumbnails for larger Tilesets, but for the moment I'm not convinced so I've popped this option on the To Do list.
The remainder of today's session was full of non-bugs, those strange quirks which send you scouring old routines for obscure bugs before you realise that the bug is caused by a careless typing mistake. However, the bulk of the Project I/O is now complete, and hopefully I'll be able to finish it completely tomorrow.
Also started on the Change Tilesize function, which had been on the back burner for a while, but again came into play once the Project I/O was started (seeing as I'm already writing small routines to initialise changes such as Tilesize, I may as well use them throughout the Editor).
As an afterthought, I added the option to either clear the existing Tilesets, or resize them; though this may become an issue when moving from 16x16 tiles to 128x128 tiles, it does represent a nifty way of generating thumbnails for larger Tilesets, but for the moment I'm not convinced so I've popped this option on the To Do list.
The remainder of today's session was full of non-bugs, those strange quirks which send you scouring old routines for obscure bugs before you realise that the bug is caused by a careless typing mistake. However, the bulk of the Project I/O is now complete, and hopefully I'll be able to finish it completely tomorrow.
Sunday, December 11, 2005
Sunday 11th
Not much progress today, but I managed to continue with the Project I/O and make a little more progress. Firstly, I tackled a small bug in the Tabber initialisation code, which was causing the wrong Tabber to be activated (this involved popping the existing code into modular routines so that they can be called by the control routine and the I/O code).
While checking other parts of the I/O routine, I noticed that the Animation code fails to take into account what Tileset the animation is supposed to use; I'm in two minds whether or not to include this in the animation data, but it was added to the To Do list nevertheless.
While checking other parts of the I/O routine, I noticed that the Animation code fails to take into account what Tileset the animation is supposed to use; I'm in two minds whether or not to include this in the animation data, but it was added to the To Do list nevertheless.
Friday, December 9, 2005
Friday 9th
After delving into the Tile and Buffer code last night, I kicked off by adding the facility to erase a range of tiles, as opposed to just the current tile - a rather handy feature, and something which only took a couple of minutes to write. Although I enjoy flashes of inspiration and adding features, however, it's high-time I stopped having ideas and finished my To-Do list. :)
As a result, I decided to tackle the Project I/O head-on, after giving the approach some thought last night; the most sensible method seemed to involve splitting the task into chunks (Maps, Tilesets, Masks, etc.), in order to make sure each part of the routine works properly before moving on to the next.
In order to save time creating new dummy data each and every time I added a new chunk of code, I hit upon the idea of writing the Save code first - this way, I could load the existing project data, tweak the options associated with the new chunk of code, save using the updated routine, then return to the code, add the load routine, and check that it loads back in properly.
This enabled me to plough through the routine fairly quickly, each code update adding more data to the project file, allowing me to ensure that every element contained in the file could be checked at any and every stage.
The beauty of sifting through every variable also has the added bonus of giving the code an unintentional Spring Clean; there are a few variables that weren't needed any more, for example, a couple of routines which weren't setting things up properly, and even a routine which was still working on the assumption that there were only six Map layers. By the end of the day, I had the bulk of the work done, and already the Editor has become even more of a joy to use. :)
As a result, I decided to tackle the Project I/O head-on, after giving the approach some thought last night; the most sensible method seemed to involve splitting the task into chunks (Maps, Tilesets, Masks, etc.), in order to make sure each part of the routine works properly before moving on to the next.
In order to save time creating new dummy data each and every time I added a new chunk of code, I hit upon the idea of writing the Save code first - this way, I could load the existing project data, tweak the options associated with the new chunk of code, save using the updated routine, then return to the code, add the load routine, and check that it loads back in properly.
This enabled me to plough through the routine fairly quickly, each code update adding more data to the project file, allowing me to ensure that every element contained in the file could be checked at any and every stage.
The beauty of sifting through every variable also has the added bonus of giving the code an unintentional Spring Clean; there are a few variables that weren't needed any more, for example, a couple of routines which weren't setting things up properly, and even a routine which was still working on the assumption that there were only six Map layers. By the end of the day, I had the bulk of the work done, and already the Editor has become even more of a joy to use. :)
Thursday, December 8, 2005
Thursday 8th
Started off by stripping out the last few bits of code I'd written last night (I wanted the Zoom system to use its own canvas, but for some reason the code wouldn't co-operate so I decided to do it the tried and tested way instead).
Next came the task of adding Zoom control to the two buttons I'd already prepared on the Toolbar; this meant encapsulating all of yesterday's (test) code into a small function which could be called from either the menu or the Toolbar.
At the same time, I also added a small check to prevent the zoom initialisation form taking place if the Zoom level is already at the one currently being selected, as well as a small check to ensure that Zoom mode always returns to the Layer that was previously being edited (this is because most of the controls and drawing tools are disabled in Zoom mode, though it's still possible to mess around with the Tabbers and suchlike).
Next on the list was to tweak the Tile Panel so that animating tiles are displayed properly (I'd forgotten to add this to my ToDo list and thus, slipped through the net when I was developing the animation system last week). I considered adding an option to toggle this new function, but due to the way the animation system works, I think it's pretty important to see which tiles on the tileset have animations assigned to them.
While tinkering with the Tile Panel, I noticed that I'd neglected to add Tile Grab Mode to the toolbar; hastily booted up PhotoShop and added an appropriate icon, then added a few extra checks to the Toolbar routine. There, nobody will ever notice. :)
In another shoddy attempt to avoid tackling the Project I/O, I set up all of the necessary variables to keep track of any edits made throughout the program; currently, each Layer/Map has a small flag associated with it - whenever an edit is made (e.g. drawing a line), the flag is set. Shoudl the user then choose to exit the program, they are alerted that there are unsaved changes (naturally, this flag is cleared if the map/map set is saved).
Essentially, I'd like to expand this system so that any changes, be they Tiles, Animations, Meta Data, Mask Data, Brushes, or Grab Buffers, are automatically logged and the user prompted on exit (or indeed, if they try to load a file over the existing data).
Decided to bite the bull by the scruff of the horns and do some more work on the Project I/O routines, which involved tracing through each and every one of my variables and working out which ones need to be loaded, cleared, or initialised.
The final task of the night was the creation of the Create Tileset function; while playing around with some of the Grab functions, it occurred to me that, for the purpose of grabbing tiles and quickly trying out ideas, it'd be useful to be able to create a blank Tileset (rather than import an existing one). Thankfully, this was straightforward enough to write. :)
Next came the task of adding Zoom control to the two buttons I'd already prepared on the Toolbar; this meant encapsulating all of yesterday's (test) code into a small function which could be called from either the menu or the Toolbar.
At the same time, I also added a small check to prevent the zoom initialisation form taking place if the Zoom level is already at the one currently being selected, as well as a small check to ensure that Zoom mode always returns to the Layer that was previously being edited (this is because most of the controls and drawing tools are disabled in Zoom mode, though it's still possible to mess around with the Tabbers and suchlike).
Next on the list was to tweak the Tile Panel so that animating tiles are displayed properly (I'd forgotten to add this to my ToDo list and thus, slipped through the net when I was developing the animation system last week). I considered adding an option to toggle this new function, but due to the way the animation system works, I think it's pretty important to see which tiles on the tileset have animations assigned to them.
While tinkering with the Tile Panel, I noticed that I'd neglected to add Tile Grab Mode to the toolbar; hastily booted up PhotoShop and added an appropriate icon, then added a few extra checks to the Toolbar routine. There, nobody will ever notice. :)
In another shoddy attempt to avoid tackling the Project I/O, I set up all of the necessary variables to keep track of any edits made throughout the program; currently, each Layer/Map has a small flag associated with it - whenever an edit is made (e.g. drawing a line), the flag is set. Shoudl the user then choose to exit the program, they are alerted that there are unsaved changes (naturally, this flag is cleared if the map/map set is saved).
Essentially, I'd like to expand this system so that any changes, be they Tiles, Animations, Meta Data, Mask Data, Brushes, or Grab Buffers, are automatically logged and the user prompted on exit (or indeed, if they try to load a file over the existing data).
Decided to bite the bull by the scruff of the horns and do some more work on the Project I/O routines, which involved tracing through each and every one of my variables and working out which ones need to be loaded, cleared, or initialised.
The final task of the night was the creation of the Create Tileset function; while playing around with some of the Grab functions, it occurred to me that, for the purpose of grabbing tiles and quickly trying out ideas, it'd be useful to be able to create a blank Tileset (rather than import an existing one). Thankfully, this was straightforward enough to write. :)
Wednesday, December 7, 2005
Wednesday 7th
Decided to kick off tonight's session by tackling the Zoom function, something which I've tried to do on numerous occasions. However, as is typical for programmers, the best way of approaching the routine came to me while I was doing something mundane, as opposed to thinking about the problem in hand.
Essentially, all I need to do is shrink the tileset when the zoom is initiated, and display the map using the shrinky dinky tiles instead of the regular ones.
After a bit of furious typing, the code was working but with unexpected results; I wrongly assumed that every tileset would be the same dimension, so a couple of tweaks later and everything was working propery. With that in place, I also added the animation code to ensure that even the Zoomed map will still animate.
This, rather handily, highlighted a couple of bugs in the Animation routine which only showed themselves because the Debugger was turned on (errors with Databanks rarely crash the PC, but always show themselves in Debug mode).
With the bugs fixed, all that remained was to tweak the control routines and map-boundary checks to ensure that the Zoomed map can be scrolled safely. Amazing that a routine I regarded as a huge task took merely a couple of hours to implement. :)
Essentially, all I need to do is shrink the tileset when the zoom is initiated, and display the map using the shrinky dinky tiles instead of the regular ones.
After a bit of furious typing, the code was working but with unexpected results; I wrongly assumed that every tileset would be the same dimension, so a couple of tweaks later and everything was working propery. With that in place, I also added the animation code to ensure that even the Zoomed map will still animate.
This, rather handily, highlighted a couple of bugs in the Animation routine which only showed themselves because the Debugger was turned on (errors with Databanks rarely crash the PC, but always show themselves in Debug mode).
With the bugs fixed, all that remained was to tweak the control routines and map-boundary checks to ensure that the Zoomed map can be scrolled safely. Amazing that a routine I regarded as a huge task took merely a couple of hours to implement. :)
Friday, December 2, 2005
Friday 2nd
Kicked off by adding the Tile Grab Mode option to the Tools menu (while tinkering with the Editor last night, I noticed I'd forgotten to include it). This also exposed a small oversight in my Tool Tips routine (which meant that tools selected from the menu didn't activate the relevant Tool Tip). Needless to say, this was quickly rectified.
Next came a couple of tweaks to the animation code, which I'd plotted out a couple of nights ago on paper. After much tinkering, however, the code would still not work properly... until it dawned on me that I was checking the code by looking at the animation thumbnail preview which, for some reason, was still using its own temporary piece of animation code. D'oh!
That fixed, I tweaked the code so that all animations are processed and not just the thumbnail preview; up until now, the actual animations on the map and the thumbnail had been animated separately, but this caused speed problems if both were running at the same time (mainly due to speed and delay values being decremented twice per frame).
With that out of the way, I made the final few changes and modifications to the Ping-Pong code; the final tweak came in the form of a couple of additions to the anim I/O, seeing as I'd added flags for each animation to show the animation direction in Ping-Pong mode. That done, the animation system is now - touch wood and all extremities crossed - completely finished. Yay, and indeed, woo.
Next came a couple of tweaks to the animation code, which I'd plotted out a couple of nights ago on paper. After much tinkering, however, the code would still not work properly... until it dawned on me that I was checking the code by looking at the animation thumbnail preview which, for some reason, was still using its own temporary piece of animation code. D'oh!
That fixed, I tweaked the code so that all animations are processed and not just the thumbnail preview; up until now, the actual animations on the map and the thumbnail had been animated separately, but this caused speed problems if both were running at the same time (mainly due to speed and delay values being decremented twice per frame).
With that out of the way, I made the final few changes and modifications to the Ping-Pong code; the final tweak came in the form of a couple of additions to the anim I/O, seeing as I'd added flags for each animation to show the animation direction in Ping-Pong mode. That done, the animation system is now - touch wood and all extremities crossed - completely finished. Yay, and indeed, woo.
Thursday, December 1, 2005
Thursday 1st
Today's brief session saw me tying up the various button controls for the numerous panels; now the user can hold Shift while clicking on certain buttons to increment/decrement the value by 10, as opposed to just 1. Took this a step further and also added it to the Nudge/Scroll tools on the Grab Panel, but increasing in steps of 8 to keep it artist-friendly. ;)
Finished up by adding the tile animation code to the Test Map module - and thanks to the fact that I tightened up to map printing code into a single loop, it also means that the Test Map module now displays and animates all 8 layers, too (all at no extra charge).
Finished up by adding the tile animation code to the Test Map module - and thanks to the fact that I tightened up to map printing code into a single loop, it also means that the Test Map module now displays and animates all 8 layers, too (all at no extra charge).
Tuesday, November 29, 2005
Tuesday 29th
First on today's agenda was the Animation menu, which involved implementing all of the various commands from the actual Animation Tabber - this is often just a case of shoehorning the code into a function, then calling this function from both the menu and the panel code.
Also took the opportunity to finish off the Grab menu, which I'd neglected to do a couple of weeks ago (and for obvious reasons - it's a fairly tedious task).
Made a couple of tweaks to the Map Resize code, too - currently, the map resizing is done at a very specific point in the code loop; it dawned on me that this isn't actually necessary due to the modular way in which the code works, so a couple of tweaks and the whole shebang was working more efficiently (but, as is often the case, it looks exactly the same to the end user!).
Wanted to finish up by adding the Animation toggle button's functionality to the Toolbar code, until I noticed that the Toolbar wasn't working properly. As is the case with the previous two Blitz updates, the Toolbar always seems to break. After a quick visit to the Blitz+ forum, however, it was a relatively simple fix - my favourite kind :).
Next up came a few tweaks to the Grab code to prevent tiles being manipulated when there is no Tileset loaded into the current 'slot' - the error checking for this is relatively simple, but permeates into many different areas of the code (so much so, I'm certain I've probably missed a couple along the way - let's hope my Beta Testers are paying attention).
The final task of the day involved making a start on the Project I/O, which also goes hand-in-hand with the 'New' function. On close inspection, the New function is quite extensive, and needs to reset literally dozens of variables, data banks, and arrays (thankfully, this routine will be used twice, once by the New function and once by the Load function).
I also took the opportunity to add proper error handling to each I/O routine, to ensure that loads and saves are handled properly should the user jab the cancel button or enter an inappropriate filename.
Also took the opportunity to finish off the Grab menu, which I'd neglected to do a couple of weeks ago (and for obvious reasons - it's a fairly tedious task).
Made a couple of tweaks to the Map Resize code, too - currently, the map resizing is done at a very specific point in the code loop; it dawned on me that this isn't actually necessary due to the modular way in which the code works, so a couple of tweaks and the whole shebang was working more efficiently (but, as is often the case, it looks exactly the same to the end user!).
Wanted to finish up by adding the Animation toggle button's functionality to the Toolbar code, until I noticed that the Toolbar wasn't working properly. As is the case with the previous two Blitz updates, the Toolbar always seems to break. After a quick visit to the Blitz+ forum, however, it was a relatively simple fix - my favourite kind :).
Next up came a few tweaks to the Grab code to prevent tiles being manipulated when there is no Tileset loaded into the current 'slot' - the error checking for this is relatively simple, but permeates into many different areas of the code (so much so, I'm certain I've probably missed a couple along the way - let's hope my Beta Testers are paying attention).
The final task of the day involved making a start on the Project I/O, which also goes hand-in-hand with the 'New' function. On close inspection, the New function is quite extensive, and needs to reset literally dozens of variables, data banks, and arrays (thankfully, this routine will be used twice, once by the New function and once by the Load function).
I also took the opportunity to add proper error handling to each I/O routine, to ensure that loads and saves are handled properly should the user jab the cancel button or enter an inappropriate filename.
Monday, November 28, 2005
Monday 28th
Another brief but productive session saw the implementation of the Animation Set I/O (as mentioned yesterday), which allows all animation data to be saved in one fell swoop. I also added a small function to ensure that the Loop and Ping-Pong checkboxes are correctly set when animation data is loaded (one of those small touches that is completely transparent to the user and thus, I'll never get any thanks or recognition for it).
Sunday, November 27, 2005
Sunday 27th
A quick delve into the Editor code saw me tackling the I/O routines for the animation system; essentially, I'd like this to work in much the same way as the Brush I/O, in that a single animation can be quickly saved to disk using a generic filename or given a filename by the user, and the actual Animation "set" (ie. all of the animation data) is loaded and saved in the standard fashion.
The actual routines had already been prototyped back when the Animation system was first written, so all that remained were a few little tweaks here and there.
Hit upon the idea of adding a Shift modifier to some of the buttons, as it became something of a pain to repeatedly click on the +/- buttons - with Shift held, the buttons increase the current index number by 10, instead of just 1, making it much easier to navigate. Now all I need to do is implement this throughout the code.
The actual routines had already been prototyped back when the Animation system was first written, so all that remained were a few little tweaks here and there.
Hit upon the idea of adding a Shift modifier to some of the buttons, as it became something of a pain to repeatedly click on the +/- buttons - with Shift held, the buttons increase the current index number by 10, instead of just 1, making it much easier to navigate. Now all I need to do is implement this throughout the code.
Saturday, November 26, 2005
Saturday 26th
Flushed with yesterday's successes, today I continued implementing a few more bits and pieces connected with the animation system, ostensibly the plotting of animating tiles on the various cursors and tools.
First up came a slight tweak to the main map plotting routine; when I tweaked the code yesterday to add animations, it dawned on me that I could make the main loop tighter and more efficient (and luckily, the whole thing didn't fall apart afterwards).
Next came the tool code, which involved revisiting the various tool functions in order to make sure that animated tiles get plotted. For example, with tile animation activated, it's nice to be able to see the tile animating as you're drawing with it; with the tweaks in place, animations are plotted as you draw lines and boxes (I may make this a toggle-able option just to cater for all tastes).
While delving into the Continuous Box function, I noticed that I'd neglected to include Right Mouse Button control - a few key-taps later and that was rectified, but it also exposed a small cursor-related bug (which, thankfully, was a quick-fix).
The final task of the night was to add animation plotting to Brush Mode, so that any brushes being used will also animate (if they contain animating tiles, of course). That completed, the animation system is virtually complete; all that remains are the I/O routines and a few tweaks to the animation menu, which I'll no doubt tackle tomorrow.
First up came a slight tweak to the main map plotting routine; when I tweaked the code yesterday to add animations, it dawned on me that I could make the main loop tighter and more efficient (and luckily, the whole thing didn't fall apart afterwards).
Next came the tool code, which involved revisiting the various tool functions in order to make sure that animated tiles get plotted. For example, with tile animation activated, it's nice to be able to see the tile animating as you're drawing with it; with the tweaks in place, animations are plotted as you draw lines and boxes (I may make this a toggle-able option just to cater for all tastes).
While delving into the Continuous Box function, I noticed that I'd neglected to include Right Mouse Button control - a few key-taps later and that was rectified, but it also exposed a small cursor-related bug (which, thankfully, was a quick-fix).
The final task of the night was to add animation plotting to Brush Mode, so that any brushes being used will also animate (if they contain animating tiles, of course). That completed, the animation system is virtually complete; all that remains are the I/O routines and a few tweaks to the animation menu, which I'll no doubt tackle tomorrow.
Friday, November 25, 2005
Friday 25th
Spent the last couple of days back in Editor Land, specifically, finishing off the animation system; the Anim panel functionality was developed in conjunction with test variables while I deliberated on the best way to store animations (and, if truth be told, until I fully got my head around using Types).
Thankfully, it dawned on me that I didn't necessarily have to use Types to store the data - simple arrays and DataBanks would be equally effective (and quicker to check when it came to developing the actual screen animation code), and so I decided to get the animation system wiped off my To-Do list for good.
Yesterday's session was pretty mundane, and involved setting up the variables, arrays, and DataBanks, as well as replacing all references to temporary variables with proper ones. With that out of the way, today I set about making sure all the frame addition/removal/import code had the desired effect (this involved tweaking several bits of code, as the test data used arrays while the new system uses a DataBank).
After methodically working through each routine, I finally had the system in and working (I may revisit the code at some point, however, as the logistics of adding a frame seem a bit cumbersome now that I've used it for more than a couple of minutes).
Thus, the next step was to write a routine that animates all of the tiles (ie. increments the frame index variables and triggers loops if appropriate), followed by a graceful way of reading each map tile, checking if it's an animation, and if so, plotting the next tile in the sequence instead of the one stored in the map data.
This was the part I'd been dreading the most, but thankfully it took mere seconds to write; indeed, the hardest part was tracking down why all of the animations wouldn't run at the same time - it suddenly dawned on me that I wasn't actually calling the animation routine (and lo, there was much slapping of the forehead).
Thankfully, it dawned on me that I didn't necessarily have to use Types to store the data - simple arrays and DataBanks would be equally effective (and quicker to check when it came to developing the actual screen animation code), and so I decided to get the animation system wiped off my To-Do list for good.
Yesterday's session was pretty mundane, and involved setting up the variables, arrays, and DataBanks, as well as replacing all references to temporary variables with proper ones. With that out of the way, today I set about making sure all the frame addition/removal/import code had the desired effect (this involved tweaking several bits of code, as the test data used arrays while the new system uses a DataBank).
After methodically working through each routine, I finally had the system in and working (I may revisit the code at some point, however, as the logistics of adding a frame seem a bit cumbersome now that I've used it for more than a couple of minutes).
Thus, the next step was to write a routine that animates all of the tiles (ie. increments the frame index variables and triggers loops if appropriate), followed by a graceful way of reading each map tile, checking if it's an animation, and if so, plotting the next tile in the sequence instead of the one stored in the map data.
This was the part I'd been dreading the most, but thankfully it took mere seconds to write; indeed, the hardest part was tracking down why all of the animations wouldn't run at the same time - it suddenly dawned on me that I wasn't actually calling the animation routine (and lo, there was much slapping of the forehead).
Sunday, October 30, 2005
Sunday 30th
Continued with the Test Map module, adding the fine-scroll code necessary to scroll the map smoothly; I took the liberty of peeking through my Citadel testbed code to see how I'd implemented the scroll routine, and it became apparent that I'd need a different approach for both the game and the Editor.
Essentially, I need a scrolling system which will automatically adapt itself around the player's position (or a given co-ordinate, in the case of the Editor). I also need an intelligent system which will allow the user to scroll the map by using the mouse, which will also call for a little intertia.
With this in mind, I spent a good while scouring the Blitz forums and Blitz Coder archives looking for suitable code to study. Most of the examples on offer all seem to work in a similar way, until I stumbled across a fantastic piece of example code which seemed to fit the bill - I'll be studying this code in detail over the next few days!
Essentially, I need a scrolling system which will automatically adapt itself around the player's position (or a given co-ordinate, in the case of the Editor). I also need an intelligent system which will allow the user to scroll the map by using the mouse, which will also call for a little intertia.
With this in mind, I spent a good while scouring the Blitz forums and Blitz Coder archives looking for suitable code to study. Most of the examples on offer all seem to work in a similar way, until I stumbled across a fantastic piece of example code which seemed to fit the bill - I'll be studying this code in detail over the next few days!
Saturday, October 29, 2005
Saturday 29th
Hit a stumbling block with today's assigned task (rotating the map 90 degrees clockwise and counter-clockwise), so my focus shifted to the Test Map module, which has been on my To-Do list from day one. Essentially, I want a system which allows the user to instantly 'preview' how their map will look, complete with smooth scrolling, parallax layers, animations, etc.
I started off by creating the basic window, canvas, and buttons (to control scrolling speed, parallax speed, and an Exit button to return to the Editor). As an afterthought, I also added visibility checkboxes similar to those already present in the Editor, to allow the user to toggle layers on and off as required.
I started off by creating the basic window, canvas, and buttons (to control scrolling speed, parallax speed, and an Exit button to return to the Editor). As an afterthought, I also added visibility checkboxes similar to those already present in the Editor, to allow the user to toggle layers on and off as required.
Friday, October 28, 2005
Friday 28th
Finished the Tool Tips system by adding the rest of the labels and implementing the calls whenever a new tool is selected. Next, I gave the Fetch Tile routine a purpose in life, and linked it up to the Dropper mode (as an afterthought, I also expanded the functionality to allow Left and Right tiles to be grabbed).
Next came the creation of the Tile Inc and Tile Dec routines; these are based on some code I'd written to increment and decrement the current tile, and intelligently scroll the tile window up or down, depending on whether or not the cursor had moved out of sight. Sticking this code into separate routines allowed me to remove duplicate chunks of code - now all actions which increment or decrement the current tile (ie. the +/- keys, and the +/- buttons on the Anim and Grab panels) are consistent.
Fixed a minor bug in the MiniMap Meta window; variables were being set whenever the pull-down lists were activated, which meant that the Cancel button had no effect - this was naturally a simple tweak to fix. :)
Next up came Move Mode, which had been behaving a little quirky since the addition of a Move icon in the Toolbar. Now you can either click the Toolbar to engage Move Mode permanently (tapping M disengages this), or hold M to activate Mode Mode for as long as needed.
Next I tackled a bug in the Continuous Pen mode, which was causing rogue tiles to be printed when switching from the Tile selector to the main canvas. Far from being an irksome bug that took hours to track down, I managed to fix the problem by flushing the mouse buffer whenever canvases are switched. Simple but very effective!
Next came the creation of the Tile Inc and Tile Dec routines; these are based on some code I'd written to increment and decrement the current tile, and intelligently scroll the tile window up or down, depending on whether or not the cursor had moved out of sight. Sticking this code into separate routines allowed me to remove duplicate chunks of code - now all actions which increment or decrement the current tile (ie. the +/- keys, and the +/- buttons on the Anim and Grab panels) are consistent.
Fixed a minor bug in the MiniMap Meta window; variables were being set whenever the pull-down lists were activated, which meant that the Cancel button had no effect - this was naturally a simple tweak to fix. :)
Next up came Move Mode, which had been behaving a little quirky since the addition of a Move icon in the Toolbar. Now you can either click the Toolbar to engage Move Mode permanently (tapping M disengages this), or hold M to activate Mode Mode for as long as needed.
Next I tackled a bug in the Continuous Pen mode, which was causing rogue tiles to be printed when switching from the Tile selector to the main canvas. Far from being an irksome bug that took hours to track down, I managed to fix the problem by flushing the mouse buffer whenever canvases are switched. Simple but very effective!
Wednesday, October 19, 2005
Wednesday 19th
Tried without success to implement a snap-to-grid system, so my focus switched to the Tool Tips, which involved adding the panel and text labels, and implementing the tabber functionality. Threw in a couple of test labels, and the panel works beautifully - it now takes just a simple glance down at the panel to refresh your memory. :)
Tuesday, October 18, 2005
Tuesday 18th
Finished the Fetch Tile routine today, after banging my head on the desk repeatedly (in actual fact, it was just a process of working on each part of the routine in turn). Now the editor can intelligently display the cursor over the correct tile and adjust the scroll register so that the relevant tile is always in view.
Finished up by tweaking my menu code so that the keyboard shortcuts are justified properly (they used to be right-justified, now they're tabbed, for anyone remotely interested!).
Finished up by tweaking my menu code so that the keyboard shortcuts are justified properly (they used to be right-justified, now they're tabbed, for anyone remotely interested!).
Monday, October 17, 2005
Monday 17th
Fixed a minor bug in the MiniMap code which meant that the code had no default values to work from (and thus, was appearing completely black).
Decided to pluck some small tasks off my To-Do list, specifically the Tool Tips system which will provide prompts on using the various tools (after a suggestion by Muttley). At the moment, the program prints a line of text on the Status line, but this is usually lost whenever another action is performed (the Status area is used continually for prompts and messages).
Then I hit upon the idea of adding an extra panel to the Info / MiniMap area of the screen; whenever the user needs prompts, they simply click the tabber and follow the instructions. Full functionality will come later, but already the panel is fairly intuitive to use.
Addressed a small bug in the Grab Panel, which meant that thumbnail images were being generated in 32x32 tile mode, then started work on the Fetch Tile routine (which will hopefully move the tile selection cursors intelligently).
Decided to pluck some small tasks off my To-Do list, specifically the Tool Tips system which will provide prompts on using the various tools (after a suggestion by Muttley). At the moment, the program prints a line of text on the Status line, but this is usually lost whenever another action is performed (the Status area is used continually for prompts and messages).
Then I hit upon the idea of adding an extra panel to the Info / MiniMap area of the screen; whenever the user needs prompts, they simply click the tabber and follow the instructions. Full functionality will come later, but already the panel is fairly intuitive to use.
Addressed a small bug in the Grab Panel, which meant that thumbnail images were being generated in 32x32 tile mode, then started work on the Fetch Tile routine (which will hopefully move the tile selection cursors intelligently).
Thursday, October 13, 2005
Thursday 13th
Kicked off by tackling the MiniMap / Meta system as mentioned in the previous entry; managed to eventually track down the problem and celebrated by slapping my forehead repeatedly for being so dumb. Basically, I have a eight variables, each of which stores a Flag value - this value gets checked against the Meta data for each tile, and if they match, the tile is printed on the MiniMap in the relevant colour.
However, the values I was assigning to the variables were in the range of 1-16 (eg. 1, 2, 3, 4, 5...), instead of the corresponding bit values (1, 2, 4, 8, 16...). Once I'd slipped in some code to convert these values, the system was working like a dream.
In the process, I tracked down a small bug associated with the Meta Panel which meant that drawing tools wouldn't function properly when the Meta Panel was being displayed. Luckily, it was just a case of moving a little chunk of code into the right set of checks.
Finished up the MiniMap / Meta system by allowing the user to click on the corresponding colour values to change them. The system is now wonderfully flexible: basically, each tile has 16 Flags (Meta Data); the Meta system allows a Flag value to have an associated colour and thus, any tiles which have that particular Flag set will be displayed on the MiniMap in the relevant colour.
Finished up by adding the MiniMap threshold input system, which allows the user to specify a start and end tile - anything in that range is displayed on the MiniMap. Now that all of the functionality is finished, the MiniMap system offers three different ways for the user to customise the MiniMap view (using Mask data, Meta data, or the threshold input). Who says I never cater for all tastes? :)
However, the values I was assigning to the variables were in the range of 1-16 (eg. 1, 2, 3, 4, 5...), instead of the corresponding bit values (1, 2, 4, 8, 16...). Once I'd slipped in some code to convert these values, the system was working like a dream.
In the process, I tracked down a small bug associated with the Meta Panel which meant that drawing tools wouldn't function properly when the Meta Panel was being displayed. Luckily, it was just a case of moving a little chunk of code into the right set of checks.
Finished up the MiniMap / Meta system by allowing the user to click on the corresponding colour values to change them. The system is now wonderfully flexible: basically, each tile has 16 Flags (Meta Data); the Meta system allows a Flag value to have an associated colour and thus, any tiles which have that particular Flag set will be displayed on the MiniMap in the relevant colour.
Finished up by adding the MiniMap threshold input system, which allows the user to specify a start and end tile - anything in that range is displayed on the MiniMap. Now that all of the functionality is finished, the MiniMap system offers three different ways for the user to customise the MiniMap view (using Mask data, Meta data, or the threshold input). Who says I never cater for all tastes? :)
Wednesday, October 12, 2005
Wednesday 12th
Not much time spent coding today, but managed to get the Grab Panel functions finished with the completion of the Strip From Buffer command; in a similar vein to the Strip All function I wrote yesterday, this function strips tiles in a continuous strip starting with the Grab Buffer's current location. This is especially handy if you're grabbing tiles that aren't aligned with the tile 'grid'.
The final function I want to add after Beta will be the facility to grab tiles from the Static image using a similar system to the Brush grabbing function (this may sneak in before Beta, however, depending on how hard it is to code!).
Rounded off the night by investigating my MiniMap code to find out why it fails to read the Meta data properly; the user can have the MiniMap draw tiles only with specific Meta values - currently, however, the code has more bugs than, well, than it should. :)
The final function I want to add after Beta will be the facility to grab tiles from the Static image using a similar system to the Brush grabbing function (this may sneak in before Beta, however, depending on how hard it is to code!).
Rounded off the night by investigating my MiniMap code to find out why it fails to read the Meta data properly; the user can have the MiniMap draw tiles only with specific Meta values - currently, however, the code has more bugs than, well, than it should. :)
Tuesday, October 11, 2005
Tuesday 11th
More thumbnail code on the agenda, specifically the tile rotate and flip functions, although fingers crossed this should be the last bit of thumbnail code I need to write. Subsequently realised I'd spoken too soon, as I needed to implement the Strip commands from the Grab panel (both of which require thumbnail code). D'oh!
The Strip All function will basically start stripping tiles from the Static picture and copy them into the tileset at a given point. With the potential to completely fill the existing tileset, I needed a way to regenerate the entire tileset as a thumbnail image (this causes a slight delay, but the status bar at the bottom of the screen now displays a "Regenerating thumbnails" message to keep the user informed.
The Strip All function will basically start stripping tiles from the Static picture and copy them into the tileset at a given point. With the potential to completely fill the existing tileset, I needed a way to regenerate the entire tileset as a thumbnail image (this causes a slight delay, but the status bar at the bottom of the screen now displays a "Regenerating thumbnails" message to keep the user informed.
Monday, October 10, 2005
Monday 10th
Not much time for code today, but managed to get a few tasks knocked off the agenda. First up was the Tile Save routine, which I'd neglected to finish properly; as discussed in the last entry, the 128x128 tilesets are actually two rows of 128 tiles (as opposed to one continuous strip). As my Tile Save code was based around continuous strips, a minor tweak was required.
The final tasks involved adding thumbnail code to the copy/paste tile/range routines, which was fairly straightforward - however, the sheer number of thumbnail additions is making me wonder if a modular routine might be quicker. Hmmm!
The final tasks involved adding thumbnail code to the copy/paste tile/range routines, which was fairly straightforward - however, the sheer number of thumbnail additions is making me wonder if a modular routine might be quicker. Hmmm!
Friday, October 7, 2005
Friday 7th
First on today's agenda was the tweakage of the Grab functions I've been writing over the last couple of days. It suddenly dawned on me last night that all of the functions are based around a 32x32 Tileset; due to the fact that thumbnail images are used when the Tileset differs from 32x32, I needed to adapt my code so that the Grab buffers are the correct size and that appropriate actions will not only update the current Tileset, but also the thumbnail Tileset.
This was a fairly lengthy process, but relatively straightforward once I knew which areas of the code to change, and after about an hour of changes, checks, and tweaks, everything was working as intended (one of those situations where, after a hard slog changing the code, the program performs exactly as it did before!).
Next came the addition of the I/O routines for saving and loading Buffers and Buffer Sets (the former saves and loads the current Grab buffer, the latter saves and loads all 8 Grab buffers). As this involved tinkering with the Grab Menu, I also took the liberty of tying in some of the menu options with the existing code.
Next I tackled a small bug in my Copy/Paste Range function; essentially, all of the Tilesets are arranged in a long, continuous bitmap file which is one tile high and 256 tiles long. However, the 128x128 Tileset is only 128 tiles long and 2 tiles high, due to the fact that its width would otherwise exceed Windows limitations. As my Copy/Paste code potentially allows the entire Tileset to be copied and pasted, I needed to limit this so that the image size is not exceeded.
After tinkering with the Tile functions, it became apparent that the Tile menu was just too damn big; out came the scissors, and within minutes I'd chopped out the Meta commands and Mask commends and housed them in their own menus. This actually makes a little more sense, as each Panel now has a corresponding Menu.
While writing the I/O routines earlier, the thought occurred to me that the facility to Import and Export a range of tiles would be a nice function (after all, once the range is copied to the buffer it's a single command to save this to disk). Within minutes I'd managed to get the code up and running, though it's apparent that my Menus will need a little bit of tidying up (basically, I'll have to renumber all of the menu commands and their corresponding checks - something of a dog's job but the code will be much more organised as a result).
This was a fairly lengthy process, but relatively straightforward once I knew which areas of the code to change, and after about an hour of changes, checks, and tweaks, everything was working as intended (one of those situations where, after a hard slog changing the code, the program performs exactly as it did before!).
Next came the addition of the I/O routines for saving and loading Buffers and Buffer Sets (the former saves and loads the current Grab buffer, the latter saves and loads all 8 Grab buffers). As this involved tinkering with the Grab Menu, I also took the liberty of tying in some of the menu options with the existing code.
Next I tackled a small bug in my Copy/Paste Range function; essentially, all of the Tilesets are arranged in a long, continuous bitmap file which is one tile high and 256 tiles long. However, the 128x128 Tileset is only 128 tiles long and 2 tiles high, due to the fact that its width would otherwise exceed Windows limitations. As my Copy/Paste code potentially allows the entire Tileset to be copied and pasted, I needed to limit this so that the image size is not exceeded.
After tinkering with the Tile functions, it became apparent that the Tile menu was just too damn big; out came the scissors, and within minutes I'd chopped out the Meta commands and Mask commends and housed them in their own menus. This actually makes a little more sense, as each Panel now has a corresponding Menu.
While writing the I/O routines earlier, the thought occurred to me that the facility to Import and Export a range of tiles would be a nice function (after all, once the range is copied to the buffer it's a single command to save this to disk). Within minutes I'd managed to get the code up and running, though it's apparent that my Menus will need a little bit of tidying up (basically, I'll have to renumber all of the menu commands and their corresponding checks - something of a dog's job but the code will be much more organised as a result).
Thursday, October 6, 2005
Thursday 6th
Kicked off by removing the New and Delete buttons from the Anim panel. After careful thought, rather than allow the user to have as many animations as they want (which is where the buttons in question come into use), I'd have 256 animations already in memory at startup, one for each tile. Should the animation contain more than one frame, it is processed by the animation routine.
The main reason for this approach is partly due to time (I can't waste time perfecting an ideal animation system just for the Editor), and partly due to the fact that deleting and reordering a vast sequence of Types has huge potential for bugs and suchlike. The New and Delete buttons are now Copy and Paste respectively, which is much more useful in my opinion. :)
I also removed the 'Destination' selector from the Anim panel. Essentially, the User would have been able to generate up to 256 animation sequences; the Destination indicator was used to decide which tile on the map would trigger that sequence. While this is ultimately more flexible, again the time factor and bug potential far outweighs the usability; with the new system, the data will be much more regimented and easier for other programmers to strip out what they need.
Next came the addition of the Grab menu, which will compliment the Grab panel (along with the addition of extra commands to Save and Load Buffers and Buffer sets). In order to save memory (and effort!), the various Grab panel functions will be bundled into their own separate routines which my button checks and menu checks will call.
Though making your code portable and modular is something of a prerequisite, more often than not, I tend not to make certain pieces of code modular mainly because it takes so long to set up and call a function, whereas running the code directly within an If...Endif loop is much faster.
The final task of the day involved creating the Copy Range / Paste Range functions for the Tile menu. This was a fairly straightforward task, largely due to the amount of tile copying and manipulation code I've written recently, and once in place turned out to be a rather handy little function.
The main reason for this approach is partly due to time (I can't waste time perfecting an ideal animation system just for the Editor), and partly due to the fact that deleting and reordering a vast sequence of Types has huge potential for bugs and suchlike. The New and Delete buttons are now Copy and Paste respectively, which is much more useful in my opinion. :)
I also removed the 'Destination' selector from the Anim panel. Essentially, the User would have been able to generate up to 256 animation sequences; the Destination indicator was used to decide which tile on the map would trigger that sequence. While this is ultimately more flexible, again the time factor and bug potential far outweighs the usability; with the new system, the data will be much more regimented and easier for other programmers to strip out what they need.
Next came the addition of the Grab menu, which will compliment the Grab panel (along with the addition of extra commands to Save and Load Buffers and Buffer sets). In order to save memory (and effort!), the various Grab panel functions will be bundled into their own separate routines which my button checks and menu checks will call.
Though making your code portable and modular is something of a prerequisite, more often than not, I tend not to make certain pieces of code modular mainly because it takes so long to set up and call a function, whereas running the code directly within an If...Endif loop is much faster.
The final task of the day involved creating the Copy Range / Paste Range functions for the Tile menu. This was a fairly straightforward task, largely due to the amount of tile copying and manipulation code I've written recently, and once in place turned out to be a rather handy little function.
Wednesday, October 5, 2005
Wednesday 5th
Tweaked the Nudge controls I'd added yesterday, as the nudging was one pixel out at the edges - not a big deal to you or I, but you know how stroppy graphic artists can be! :)
Next came a couple of adjustments to the Tile Grab Mode I'd added yesterday; though it's fairly simple to grab a tile from the Static image, and nudge it into position if necessary, I thought it'd also be nice if the user could have a pixel-perfect cursor mode (as opposed to being fixed to an invisible grid). Thankfully it wasn't too awkward to squeeze into the existing code, and the whole system is becoming a joy to use.
Rounded off the day's session by going through the remainder of the menus and so forth in order to work out precisely what tasks are left; in the process, I also decided to make a number of changes to the Animation system, which will be explained as and when they are tackled.
Next came a couple of adjustments to the Tile Grab Mode I'd added yesterday; though it's fairly simple to grab a tile from the Static image, and nudge it into position if necessary, I thought it'd also be nice if the user could have a pixel-perfect cursor mode (as opposed to being fixed to an invisible grid). Thankfully it wasn't too awkward to squeeze into the existing code, and the whole system is becoming a joy to use.
Rounded off the day's session by going through the remainder of the menus and so forth in order to work out precisely what tasks are left; in the process, I also decided to make a number of changes to the Animation system, which will be explained as and when they are tackled.
Tuesday, October 4, 2005
Tuesday 4th
After a brief discussion yesterday with Muttley, one of my test pilots and all-round good egg, we concluded that the SaveImage problem was indeed a problem with Blitz, so today saw me writing a routine that creates a new image, copies across all of the tiles from the AnimImage, then saves out the image file. Phew!
Next came a chunk of code I hadn't particularly been looking forward to; the facility to grab tiles from a Static image. The logic behind the routine was fairly simple, however, and within minutes it was in and working - the user can now jab 'T' to enter Tile Grab Mode. After a couple of tweaks to the code, to check that the cursor wasn't going over the edge of the image, the bulk of the routine was done.
I took the opportunity to limit the number of buffers to 8 - now the user can happily grab tiles to any of these 8 buffers. I finished up by adding the facility to copy from the buffer to the current tile, and vice versa, and then added a Nudge facility so that the buffer contents can be moved in 1-pixel increments for extra precision.
Next came a chunk of code I hadn't particularly been looking forward to; the facility to grab tiles from a Static image. The logic behind the routine was fairly simple, however, and within minutes it was in and working - the user can now jab 'T' to enter Tile Grab Mode. After a couple of tweaks to the code, to check that the cursor wasn't going over the edge of the image, the bulk of the routine was done.
I took the opportunity to limit the number of buffers to 8 - now the user can happily grab tiles to any of these 8 buffers. I finished up by adding the facility to copy from the buffer to the current tile, and vice versa, and then added a Nudge facility so that the buffer contents can be moved in 1-pixel increments for extra precision.
Monday, October 3, 2005
Monday 3rd
Continued with the various tasks required to bring the Grab Panel to life; the good thing about these tasks is that they're all fairly self-contained, allowing me to dip in and code for as little or as long as I want to.
First up came the routine to rotate the tile 90 degrees clockwise - I had planned on using the code from the Brush Rotate function, but this proved problematic due to the way I'd written that particular routine (ie. with no care for anyone else who might want to use it!). Luckily, I managed to shoehorn the code into the existing For...Next loop I'd set up for the Tile Flipping, and after that it was a simple task to add the counter-clockwise code, too.
Next came the Tile Scroll functions, which again were relatively straightforward to add to the existing loop - this means that all of my Tile manipulation gubbins is now contained within a single routine, making it much easier to tweak.
Flushed with the progress I was making, I decided to tackle a few odd tweaks and bugs that had been hanging around (by sliding a bug onto my schedule whenever things are going well I can feed off my enthusiasm and get things done!). First up came the cursor display for the Anim Panel, which required a teensy tweak so that it always displays properly regardless of the Tile size.
Next, I needed to take my Tile thumbnail code - which currently takes any 64x64 Tileset and scales it down to 32x32 for the Anim and Grab Panels - and turn it into a generic routine so that any Tileset being loaded or refreshed has a thumbnail image to accompany it.
Finally came the Tile Save routine, which had been hanging around the To Do list for far too long; now that the Grab Panel is taking shape, however, it seems logical to implement Tile Saving so that any changes made to the Tileset can actually be saved, too. The logic was fairly easy to poach from another routine, but I hit a snag when saving the Tileset - for some reason, the SaveImage command will only save the first Tile in the Tileset. Hmmm. I sense a posting to the Blitz forums coming on!
First up came the routine to rotate the tile 90 degrees clockwise - I had planned on using the code from the Brush Rotate function, but this proved problematic due to the way I'd written that particular routine (ie. with no care for anyone else who might want to use it!). Luckily, I managed to shoehorn the code into the existing For...Next loop I'd set up for the Tile Flipping, and after that it was a simple task to add the counter-clockwise code, too.
Next came the Tile Scroll functions, which again were relatively straightforward to add to the existing loop - this means that all of my Tile manipulation gubbins is now contained within a single routine, making it much easier to tweak.
Flushed with the progress I was making, I decided to tackle a few odd tweaks and bugs that had been hanging around (by sliding a bug onto my schedule whenever things are going well I can feed off my enthusiasm and get things done!). First up came the cursor display for the Anim Panel, which required a teensy tweak so that it always displays properly regardless of the Tile size.
Next, I needed to take my Tile thumbnail code - which currently takes any 64x64 Tileset and scales it down to 32x32 for the Anim and Grab Panels - and turn it into a generic routine so that any Tileset being loaded or refreshed has a thumbnail image to accompany it.
Finally came the Tile Save routine, which had been hanging around the To Do list for far too long; now that the Grab Panel is taking shape, however, it seems logical to implement Tile Saving so that any changes made to the Tileset can actually be saved, too. The logic was fairly easy to poach from another routine, but I hit a snag when saving the Tileset - for some reason, the SaveImage command will only save the first Tile in the Tileset. Hmmm. I sense a posting to the Blitz forums coming on!
Sunday, September 25, 2005
Sunday 25th
Started off by tweaking my Tile Masking colour picker so that the Tileset is automatically refreshed when a new masking colour is chosen. Quickly changed my mind, however, as it was no longer possible to have different colours for different Tilesets. D'oh!
Moved on to the thumbnail code, which generates a smaller (or bigger) version of the Tileset if the tile size is above or below 32x32 - the reason being, the Anim and Grab Panels both rely on tiles of 32x32 in order to fit all of the required information on the relatively small panel. Got the code working, but I need to finish up by tweaking the cursor and ensuring that any Tilesets loaded into the Editor have thumbnails generated automatically.
Implemented the Grab Panel functionality today, and tidied up a few loose ends (label positions, etc.), and also took the liberty of refining my Text Display routine so that only labels currently in use are updated. Also hit upon a way of avoiding flicker on my text labels, which has been sitting on my bug list for way too long.
Started tackling the various functions for the Grab panel, and hit a couple of problems when locking buffers - as it turns out, in operations that involve writing or reading pixels, you need to lock both the source buffer and the destination buffer; with that little quirk sorted, I wrote a copy/paste routine for tiles, then expanded my Brush Rotate code to add flipping and rotation to the tile functions.
Finally came the Clear routines, which allow the user to pick a colour to clear the current tile, or click the Quick button to clear with the last colour you 'picked'.
Moved on to the thumbnail code, which generates a smaller (or bigger) version of the Tileset if the tile size is above or below 32x32 - the reason being, the Anim and Grab Panels both rely on tiles of 32x32 in order to fit all of the required information on the relatively small panel. Got the code working, but I need to finish up by tweaking the cursor and ensuring that any Tilesets loaded into the Editor have thumbnails generated automatically.
Implemented the Grab Panel functionality today, and tidied up a few loose ends (label positions, etc.), and also took the liberty of refining my Text Display routine so that only labels currently in use are updated. Also hit upon a way of avoiding flicker on my text labels, which has been sitting on my bug list for way too long.
Started tackling the various functions for the Grab panel, and hit a couple of problems when locking buffers - as it turns out, in operations that involve writing or reading pixels, you need to lock both the source buffer and the destination buffer; with that little quirk sorted, I wrote a copy/paste routine for tiles, then expanded my Brush Rotate code to add flipping and rotation to the tile functions.
Finally came the Clear routines, which allow the user to pick a colour to clear the current tile, or click the Quick button to clear with the last colour you 'picked'.
Saturday, September 17, 2005
Saturday 17th
Tinkered with PhotoShop today, in an attempt to bash out a design for the Grab Panel. In order to avoid the redesign headaches I had with the Anim Panel, I based the design on that of the Anim Panel (it was a fairly complex layout that worked well, so why deviate too far from a winning solution?). That done, I spent a chunk of time implementing the various gadgets, canvases, and panels, ready to add the functionality next time.
Tuesday, September 13, 2005
Tuesday 13th
After a brief hiatus, I returned to the Editor to tackle a few more jobs. First up was the function to allow the user to change the Mask Tile colour (the Mask Tile is displayed over the top of the tiles if a Tile is masked). The main reason for changing the colour is so that the Mask Tile is clearly distinguishable no matter what colour the Tile may be.
This was actually no easy task; the Mask Tile is a bitmap image and thus, in order to change its colour I needed to physically redraw the image within the bitmap. After a bit of head scratching (and a few crashes due to memory being overwritten), I finally discovered that it's easy enough to specify which frame of an AnimImage you wish to modify (and not using offsets, as I was).
With the code up and running, I took the liberty of tweaking the Tile Load routine to take advantage of this new discovery (and given the potential for writing to the wrong area of memory, I was surprised it'd even worked at all).
Next, I toyed with the idea of displaying the Map as either decimal or hex, which involved creating an alternate Tileset (mainly because printing the tile number using the Text command slows the Editor to a crawl). It seems that there's no graceful solution to this, so it's back to the drawing board for this particular function.
Took the liberty of making a few tweaks here and there, one of which involved changing the display order of the Grid and Brush Grid (for some reason, the Brush outline and cursors were being displayed behind the grids - far from useful).
I rounded off the day by designing the Grab panel, which will be the final big addition to this version of the Editor; the Grab panel will allow the user the grab tiles from the Static Layer, as well as manipulate existing tiles (flipping, rotation, scrolling, etc.). I may even tweak the Brush Grab function to allow chunks of tiles to be grabbed, but this will require a lot of thought and planning in order to avoid screwing up the existing code.
This was actually no easy task; the Mask Tile is a bitmap image and thus, in order to change its colour I needed to physically redraw the image within the bitmap. After a bit of head scratching (and a few crashes due to memory being overwritten), I finally discovered that it's easy enough to specify which frame of an AnimImage you wish to modify (and not using offsets, as I was).
With the code up and running, I took the liberty of tweaking the Tile Load routine to take advantage of this new discovery (and given the potential for writing to the wrong area of memory, I was surprised it'd even worked at all).
Next, I toyed with the idea of displaying the Map as either decimal or hex, which involved creating an alternate Tileset (mainly because printing the tile number using the Text command slows the Editor to a crawl). It seems that there's no graceful solution to this, so it's back to the drawing board for this particular function.
Took the liberty of making a few tweaks here and there, one of which involved changing the display order of the Grid and Brush Grid (for some reason, the Brush outline and cursors were being displayed behind the grids - far from useful).
I rounded off the day by designing the Grab panel, which will be the final big addition to this version of the Editor; the Grab panel will allow the user the grab tiles from the Static Layer, as well as manipulate existing tiles (flipping, rotation, scrolling, etc.). I may even tweak the Brush Grab function to allow chunks of tiles to be grabbed, but this will require a lot of thought and planning in order to avoid screwing up the existing code.
Wednesday, August 31, 2005
Wednesday 31st
Today saw the arrival of a wee message in my Inbox from none other than Mark "I Made Blitz!" Sibly (I'd dropped him a line as nobody seemed to be able to help with my dilemma). Essentially, using certain gadgets, such as checkboxes and buttons, meant that the keyboard focus was lost (and thus, none of the keys would work).
The trick was to use the ActivateGadget command to restore keyboard focus but, rather than call this every frame (as I was doing, to no avail), the command was called only if a button or checkbox was manipulated. After 5 minutes cutting and pasting, full functionality was restored. :)
The trick was to use the ActivateGadget command to restore keyboard focus but, rather than call this every frame (as I was doing, to no avail), the command was called only if a button or checkbox was manipulated. After 5 minutes cutting and pasting, full functionality was restored. :)
Tuesday, August 30, 2005
Tuesday 30th
Eased back into Editor mode with a few minor tweaks and bug fixes. First off was a small bug in the control routine, which made the Editor think that Shift was being held constantly. I then tweaked the tile cursor routine, so that when + and - are used to select a tile, the tile window scrolls accordingly.
Rounded off the night's session by tweaking the Mouse Wheel functionality; previously, the Wheel button was used to grab the tile under the cursor in Pen Mode. I tweaked the code to ensure this function was available in all drawing modes, and also as a way of jumping quickly out of Brush Mode back into Pen Mode.
Rounded off the night's session by tweaking the Mouse Wheel functionality; previously, the Wheel button was used to grab the tile under the cursor in Pen Mode. I tweaked the code to ensure this function was available in all drawing modes, and also as a way of jumping quickly out of Brush Mode back into Pen Mode.
Thursday, August 18, 2005
Thursday 18th
Another day of avoiding the bigger tasks saw me plucking more titbits from the To Do list. First up was the colour selector for the various grids that the User can select (the standard resizeable grid, the Brush grid, and the Tile grid). The main reason I wanted the colours to be user-definable was purely for reasons of clarity (it's not always easy to see a cyan grid if your tiles/map contain mostly blues!). Thankfully, these were easy enough to implement.
Next up came the inclusion of a proper parallax layer, complete with adjustable speeds. The Static layer is a fixed bitmap picture which sits behind the other layers; the parallax layer, as its name suggests, scrolls in parallax, and combined with the Static layer, allows the User to very quickly build up a good representation of how their finished map will look.
I'd experimented with the parallax code previously, so all that remained was to implement the I/O routine, display routine, and speed controls, as well as adding a checkbox to the main display window.
The next task was a fairly simple addition, but something that had been lacking for too long: the ability to change the Layer names (a la PhotoShop). In the end, this was a relatively simple process of reading the User input and changing the relevant Gadget name.
The final couple of tasks on today's agenda involved a simple toggle to display which tiles are currently used/unused, and a menu option to control the way Meta Data is displayed (ie. with or without flag numbers).
Next up came the inclusion of a proper parallax layer, complete with adjustable speeds. The Static layer is a fixed bitmap picture which sits behind the other layers; the parallax layer, as its name suggests, scrolls in parallax, and combined with the Static layer, allows the User to very quickly build up a good representation of how their finished map will look.
I'd experimented with the parallax code previously, so all that remained was to implement the I/O routine, display routine, and speed controls, as well as adding a checkbox to the main display window.
The next task was a fairly simple addition, but something that had been lacking for too long: the ability to change the Layer names (a la PhotoShop). In the end, this was a relatively simple process of reading the User input and changing the relevant Gadget name.
The final couple of tasks on today's agenda involved a simple toggle to display which tiles are currently used/unused, and a menu option to control the way Meta Data is displayed (ie. with or without flag numbers).
Monday, August 15, 2005
Monday 15th
Found a small bug yesterday, while tinkering with the Mini Map code; basically, a couple of values (which relate to the number of tiles that can fit on the screen) weren't being calculated properly, which was causing a few routines to malfunction occasionally.
I tracked the problem down to a section of code that initialises the map - the resize routine - but the code wasn't being called on startup because there was no map to resize. A few slaps of the forehead later, everything was working properly.
While I was knee-deep in setup code, I took the liberty of adding an "Open" button to the startup screen; now the User can choose to set the map dimensions, accept the default values, or load up an existing project.
Another task was plucked off the to-do list, mainly because I fancied coding but didn't want to get too bogged down in a big routine, so I decided to tackle the Mask Colour function (this allows the User to specify which colour will be masked when a Tileset is loaded). The colour picker was easy enough to add, and the code was working beautifully in just a few minutes.
Flushed with that small success, I decided to tweak the Toolbar and add the "Continuous Pen" drawing mode (this basically increments the currently selected Left / Right tiles every time you plot a Tile, allowing you to plot continuous sequences of tiles very easily).
I tracked the problem down to a section of code that initialises the map - the resize routine - but the code wasn't being called on startup because there was no map to resize. A few slaps of the forehead later, everything was working properly.
While I was knee-deep in setup code, I took the liberty of adding an "Open" button to the startup screen; now the User can choose to set the map dimensions, accept the default values, or load up an existing project.
Another task was plucked off the to-do list, mainly because I fancied coding but didn't want to get too bogged down in a big routine, so I decided to tackle the Mask Colour function (this allows the User to specify which colour will be masked when a Tileset is loaded). The colour picker was easy enough to add, and the code was working beautifully in just a few minutes.
Flushed with that small success, I decided to tweak the Toolbar and add the "Continuous Pen" drawing mode (this basically increments the currently selected Left / Right tiles every time you plot a Tile, allowing you to plot continuous sequences of tiles very easily).
Wednesday, August 10, 2005
Wednesday 10th
The past couple of days have been spent hammering away at the Mini Map code, which has never really worked properly since its addition (and subtle changes to the Editor - such as dynamic map sizes - have meant that the Mini Map code needed a severe overhaul anyway).
The Mini Map is basically a thumbnail version of the current Layer; Tiles are represented by different colours, and the user can choose what information is used to generate the Mini Map (e.g. only masked Tiles are shown, only Tiles with certain Meta Data, Tiles within a certain range, etc.).
The first tweak involved the Mini Map scrolling, for maps bigger than the Mini Map window - I spent a good few hours staring blankly at my code trying to get results (and failing miserably), until yesterday I sat down for a quick coding session and managed to rewrite the whole routine from scratch in 20 minutes! Code is like that sometimes. :)
Today saw me tweaking the mouse control, which allows the user to click on the Mini Map and have the main Editor window reflect the change (indeed, it's possible to drag the mouse around to scroll around the Map a little more easily).
As an afterthought, I took the liberty of tweaking the canvas setup code, so the Mini Map now appears neatly in the centre of the relevant panel. I'm nothing if neat. ;)
The Mini Map is basically a thumbnail version of the current Layer; Tiles are represented by different colours, and the user can choose what information is used to generate the Mini Map (e.g. only masked Tiles are shown, only Tiles with certain Meta Data, Tiles within a certain range, etc.).
The first tweak involved the Mini Map scrolling, for maps bigger than the Mini Map window - I spent a good few hours staring blankly at my code trying to get results (and failing miserably), until yesterday I sat down for a quick coding session and managed to rewrite the whole routine from scratch in 20 minutes! Code is like that sometimes. :)
Today saw me tweaking the mouse control, which allows the user to click on the Mini Map and have the main Editor window reflect the change (indeed, it's possible to drag the mouse around to scroll around the Map a little more easily).
As an afterthought, I took the liberty of tweaking the canvas setup code, so the Mini Map now appears neatly in the centre of the relevant panel. I'm nothing if neat. ;)
Monday, August 1, 2005
Monday 1st
Another overhaul for the animation panel was on today's agenda - I just wasn't 100% happy with the version in place, so another stint with PhotoShop saw the creation of a design which (finally) seems to fit the bill. It also included a Tileset selector, something I'd forgotten to include in the original design. I also added a Ping-Pong option checkbox (see below).
Added a Loop Delay system to the animation code, which allows the user to specify a delay before the animation loops back to the start. This also ties in nicely with the Ping-Pong option, which allows the animation to cycle backwards and forwards through the frames (the Loop Delay in this case is the delay at the start and end of the sequence).
Spent the bulk of the evening ironing out a few bugs in the Add/Remove frame code, as well as a couple of quirks when a set of frames is imported.
The remainder of the night was spent tweaking some of the panel/canvas code; since the Meta panel had been changed a few weeks ago, it was still using its own canvas. However, a few tweaks later it was happily sharing its canvas with the Tile panel, thus saving a weensy chunk of video memory.
Added a Loop Delay system to the animation code, which allows the user to specify a delay before the animation loops back to the start. This also ties in nicely with the Ping-Pong option, which allows the animation to cycle backwards and forwards through the frames (the Loop Delay in this case is the delay at the start and end of the sequence).
Spent the bulk of the evening ironing out a few bugs in the Add/Remove frame code, as well as a couple of quirks when a set of frames is imported.
The remainder of the night was spent tweaking some of the panel/canvas code; since the Meta panel had been changed a few weeks ago, it was still using its own canvas. However, a few tweaks later it was happily sharing its canvas with the Tile panel, thus saving a weensy chunk of video memory.
Sunday, July 31, 2005
Sunday 31st
Today saw me redesigning the animation interface for the third time, mainly because the layout wasn't entirely user friendly. The one disadvantage of making a mockup in PhotoShop is that you focus on the look rather than the feel - only when this is translated into Blitz can I actually get a good idea of how it works in practise.
As I'd added some extra buttons, I tweaked the setup code as well as the button detection code to make the whole shebang a little easier for me to get my head around.
Next came the addition of the speed controls, as my animations currently run every vblank (i.e. 70-80 times a second, depending on the monitor refresh rate). The speed control is basically a delay, and counts down to zero before animating the tile; although this isn't everyone's idea of how speed should be implemented, the exported data will be flexible enough to translate into most environments.
Next came the text labels, which show the user key details (current frame number, total number of frames, animation number, tile number, etc.). This always seems like a more arduous task than it actually is, but really helps to bring the Editor to life.
Rounded off the night by adding the import function - this allows the user to import the range of tiles between the current Left Tile and Right Tile selectors, and is a very simple way to generate an animation sequence.
As I'd added some extra buttons, I tweaked the setup code as well as the button detection code to make the whole shebang a little easier for me to get my head around.
Next came the addition of the speed controls, as my animations currently run every vblank (i.e. 70-80 times a second, depending on the monitor refresh rate). The speed control is basically a delay, and counts down to zero before animating the tile; although this isn't everyone's idea of how speed should be implemented, the exported data will be flexible enough to translate into most environments.
Next came the text labels, which show the user key details (current frame number, total number of frames, animation number, tile number, etc.). This always seems like a more arduous task than it actually is, but really helps to bring the Editor to life.
Rounded off the night by adding the import function - this allows the user to import the range of tiles between the current Left Tile and Right Tile selectors, and is a very simple way to generate an animation sequence.
Saturday, July 30, 2005
Saturday 30th
Not much to report for today, apart from a few minor tweaks and bug fixes to the animation code so far. Took the liberty of adding some temporary I/O code, as setting up animations to test the code was taking way too much time - now I can just load in a sequence instantly.
Friday, July 29, 2005
Friday 29th
The last couple of days have been spent laying the foundations for tile animation; I already had a very rough navigation system in place, but today I booted up the trusty PhotoShop and mocked up a more detailed version. There's a lot of information to include, and it's always difficult trying to create an interface that a) is user friendly, and b) ties in with the rest of the package.
A good deal of time - perhaps too much time - was spent sorting out the actual frame navigation, which shows the animation sequence as a continuous strip of tiles. The cursor control logic on this section alone caused more than a few sweary words to fill the air. :)
As well as the navigation, I also added the code which adds or deletes a tile from the sequence and, as a happy extension of this idea, a function to replace the current frame with the current tile (as opposed to adding to the length of the sequence).
To round things off, I wrote a small piece of temporary code to play the animation sequence, as well as plot animated tiles to the map. It's surprising how a tiny little addition can make all the difference, and seeing the animation in action has given me the motivation I need to get this section of the Editor done and dusted.
A good deal of time - perhaps too much time - was spent sorting out the actual frame navigation, which shows the animation sequence as a continuous strip of tiles. The cursor control logic on this section alone caused more than a few sweary words to fill the air. :)
As well as the navigation, I also added the code which adds or deletes a tile from the sequence and, as a happy extension of this idea, a function to replace the current frame with the current tile (as opposed to adding to the length of the sequence).
To round things off, I wrote a small piece of temporary code to play the animation sequence, as well as plot animated tiles to the map. It's surprising how a tiny little addition can make all the difference, and seeing the animation in action has given me the motivation I need to get this section of the Editor done and dusted.
Wednesday, July 27, 2005
Wednesday 27th
Kicked off the day by fixing a small bug in the Meta > Collision routine which I'd started late last night (note to self: don't code when utterly exhausted!). The routine is similar in essence to the Mask > Collision routine, except this takes the Meta Data from the current Left Tile and compares it with each tile on the map.
The routine was easy enough to code, but a small bug in the Meta read/write routines was causing unexpected results; several jabs of the Del key later, everything was working.
The Editor is now pretty much in the final straight heading towards Beta, which was planned for the end of this month (I envisage a few extra days just to tidy things up and write the docs). Once that's done, I'll publicly release the Beta version - possibly with a few feature restrictions - to gain feedback and suggestions, as well as any bugs that people might find.
The routine was easy enough to code, but a small bug in the Meta read/write routines was causing unexpected results; several jabs of the Del key later, everything was working.
The Editor is now pretty much in the final straight heading towards Beta, which was planned for the end of this month (I envisage a few extra days just to tidy things up and write the docs). Once that's done, I'll publicly release the Beta version - possibly with a few feature restrictions - to gain feedback and suggestions, as well as any bugs that people might find.
Monday, July 25, 2005
Monday 25th
Tackled a small bug this morning which was causing some unexpected crashes when maps were resized to make them considerably larger. I narrowed it down to the core of the Undo / Redo routine, which currently works with map buffers of a certain size - naturally I was neglecting to resize these buffers when the maps are resized.
Decided to bite the bullet and finish the map loading completely, specifically the force-load routine which loads a map with dimensions smaller / larger than the current map. I actually had the bulk of the code written already, but kept getting unexpected crashes.
After popping in a Stop command and tracing through using the debugger - something which I never knew was possible until recently - the problem dawned on me in an instant, and now all of the map I/O code is finally wrapped up.
Rounded off the day by tackling the Mask > Collision functionality, which was one of the first ideas I jotted down on my To Do list almost a year ago. Essentially, I wanted the user to have a very quick way to generate collision maps based on the current map (collision maps being 0 for pass-through tiles, and 1 for solid walls and suchlike). This is particularly useful for game engines which don't check the actual tile that the player is colliding with, they check the collision map.
Why? Sometimes it's useful to use collision maps as it allows different entities within the game to react differently to the same tile - specifying the collision properties for each tile takes away such flexibility.
After 20 minutes furious coding, the routine was up and running; choosing the Mask > Collision option now generates a collision map on the currently-selected Layer, with the pass-through tile the currently-selected Right tile, and the solid tile the currently-selected Left tile. Maximum flexibility, easy to use, and extremely useful, even if I do say so myself.
Decided to bite the bullet and finish the map loading completely, specifically the force-load routine which loads a map with dimensions smaller / larger than the current map. I actually had the bulk of the code written already, but kept getting unexpected crashes.
After popping in a Stop command and tracing through using the debugger - something which I never knew was possible until recently - the problem dawned on me in an instant, and now all of the map I/O code is finally wrapped up.
Rounded off the day by tackling the Mask > Collision functionality, which was one of the first ideas I jotted down on my To Do list almost a year ago. Essentially, I wanted the user to have a very quick way to generate collision maps based on the current map (collision maps being 0 for pass-through tiles, and 1 for solid walls and suchlike). This is particularly useful for game engines which don't check the actual tile that the player is colliding with, they check the collision map.
Why? Sometimes it's useful to use collision maps as it allows different entities within the game to react differently to the same tile - specifying the collision properties for each tile takes away such flexibility.
After 20 minutes furious coding, the routine was up and running; choosing the Mask > Collision option now generates a collision map on the currently-selected Layer, with the pass-through tile the currently-selected Right tile, and the solid tile the currently-selected Left tile. Maximum flexibility, easy to use, and extremely useful, even if I do say so myself.
Sunday, July 24, 2005
Sunday 24th
Took some time out to address a bug that had been cropping up occasionally (usually when I'm just playing around with the Editor as opposed to coding). The bug stemmed from the changes I made recently to the Brush code, and it was just a simple case of moving a line of code to prevent the program reading erroneous data off the edge of the map.
This also pushed me in the direction of another bug in the Brush code, which was supposed to prevent masked tiles from being plotted. Essentially, there are two sets of Brush checks, depending on the Brush's handle point (top left or bottom right). In this instance, I'd neglected to copy the working code for the top-left handling to the bottom-right handling. Tsk tsk!
Rounded off today's session by tweaking the Map Set I/O routine to automatically check the map size and resize the project automatically (when loading a single map, the Editor prompts the user to check if they want to resize as it may affect the other Layers - when loading a Map Set, all Layers are being resized and loaded, and thus no need for a prompt). Finished up by adding Map Set Load/Save icons to the toolbar, purely because I was sick of using the menu. :)
This also pushed me in the direction of another bug in the Brush code, which was supposed to prevent masked tiles from being plotted. Essentially, there are two sets of Brush checks, depending on the Brush's handle point (top left or bottom right). In this instance, I'd neglected to copy the working code for the top-left handling to the bottom-right handling. Tsk tsk!
Rounded off today's session by tweaking the Map Set I/O routine to automatically check the map size and resize the project automatically (when loading a single map, the Editor prompts the user to check if they want to resize as it may affect the other Layers - when loading a Map Set, all Layers are being resized and loaded, and thus no need for a prompt). Finished up by adding Map Set Load/Save icons to the toolbar, purely because I was sick of using the menu. :)
Saturday, July 23, 2005
Saturday 23rd
Started implementing 'edit' checks in the code today; essentially, every time the user makes a change to a map, this action is flagged. Should they opt to load in a map or exit the program, the Editor can then check whether or not there are unsaved changes and prompt accordingly.
This sort of checking can be somewhat tiresome, as there are dozens of checks that need to be added, so I concentrated mainly on the basic logic, setting up the necessary flags, putting warnings on the program exit points, and clearing the edit check flags should the user save their map or project.
As an afterthought, the Editor also prints an asterisk next to any layers which have been edited but not saved (like FrontPage, for example), so it's much easier to see which files need to be saved.
Rounded off the night by plucking another task off my list, that of regenerating the Brush Thumbnail images should the user load a new tileset. This was fairly painless thanks mainly to the modular nature of the thumbnail routine. Further tweaks may be required in order to tell each stored Brush while tileset to get its image from. Maybe. :)
This sort of checking can be somewhat tiresome, as there are dozens of checks that need to be added, so I concentrated mainly on the basic logic, setting up the necessary flags, putting warnings on the program exit points, and clearing the edit check flags should the user save their map or project.
As an afterthought, the Editor also prints an asterisk next to any layers which have been edited but not saved (like FrontPage, for example), so it's much easier to see which files need to be saved.
Rounded off the night by plucking another task off my list, that of regenerating the Brush Thumbnail images should the user load a new tileset. This was fairly painless thanks mainly to the modular nature of the thumbnail routine. Further tweaks may be required in order to tell each stored Brush while tileset to get its image from. Maybe. :)
Thursday, July 21, 2005
Thursday 21st
A nice email arrived this morning, with another snippet of code from Muttley; I'd hit a snag with my Tile padding routine, so rather than waste precious time trying every possibility I asked Muttley to explore the problem. It all boiled down to the fact that I was using AnimImages, which produce quirky results when the image is written to.
After a few tweaks, the code was working correctly, albeit with a slight snag - the padding routine creates an Image, not an AnimImage, so none of my Editor code could display the tiles properly. I considered that if a tileset was too short, the user would probably want to save the corrected Tileset anyway, so I got around the problem by saving the corrected Tileset (for future use), then loading it back in as an AnimImage.
Hit upon the notion that Tilesets might also contain too many tiles; thankfully, the padding routine also automatically crops larger images, so the addition of a simple check at the start of the routine now means that over and undersized Tilesets are catered for! :)
Also took the opportunity of adding an Export Tileset function; currently, the Editor can handle either continuous strips of tiles, or images which hold a block of tiles - the Export function now allows tiles loaded as blocks to be saved out as strips.
After a few tweaks, the code was working correctly, albeit with a slight snag - the padding routine creates an Image, not an AnimImage, so none of my Editor code could display the tiles properly. I considered that if a tileset was too short, the user would probably want to save the corrected Tileset anyway, so I got around the problem by saving the corrected Tileset (for future use), then loading it back in as an AnimImage.
Hit upon the notion that Tilesets might also contain too many tiles; thankfully, the padding routine also automatically crops larger images, so the addition of a simple check at the start of the routine now means that over and undersized Tilesets are catered for! :)
Also took the opportunity of adding an Export Tileset function; currently, the Editor can handle either continuous strips of tiles, or images which hold a block of tiles - the Export function now allows tiles loaded as blocks to be saved out as strips.
Wednesday, July 20, 2005
Wednesday 20th
In a bid to stop my brain becoming fried by bugs and problems, my attention turned towards the Map I/O routine and, specifically, adding the map dimensions to the Map files. This was a fairly quick process, and after converting all of my test maps to this new system, I set about the error handling code.
Basically, if the user chooses to load in a Map that is different in size to the current project, they can either opt to resize the map, or to 'force load' the map into the current project (which may result in cropping if the map being loaded is bigger than the project).
After some tinkering, and a couple of tweaks to my Resize Map routine (which I added a few weeks ago), the system was up and running; all that remains is to write the force-load routine.
Basically, if the user chooses to load in a Map that is different in size to the current project, they can either opt to resize the map, or to 'force load' the map into the current project (which may result in cropping if the map being loaded is bigger than the project).
After some tinkering, and a couple of tweaks to my Resize Map routine (which I added a few weeks ago), the system was up and running; all that remains is to write the force-load routine.
Monday, July 18, 2005
Monday 18th
Started tackling the I/O error handling on the Tileset loading routine, thanks to some helpful hints and suggestions from Muttley, one of my test pilots who very kindly mocked up some source code for me to work from. Using this as a template, I popped in some code to calculate that the image dimensions corresponded to the current Tile size.
Next came the code which counts the number of tiles in the Tileset, based on the image dimensions. The next task, which will have to wait until later in the week, will involve 'padding out' the Tileset if there aren't sufficient tiles (the Editor uses 256 tiles, and I'm not changing this unless a) I receive a lot of requests, or b) receive a lot of money!).
Next came the code which counts the number of tiles in the Tileset, based on the image dimensions. The next task, which will have to wait until later in the week, will involve 'padding out' the Tileset if there aren't sufficient tiles (the Editor uses 256 tiles, and I'm not changing this unless a) I receive a lot of requests, or b) receive a lot of money!).
Sunday, July 17, 2005
Sunday 17th
Had a little bit of a tidy-up today, with the I/O routines getting a rigorous revamp (partly because many of my Save/Save As routines were separate, but could easily be combined into a single routine as the code for each was largely the same.
This led on to the addition of the Map Set loading and saving routines, allowing the user to save out all 8 maps as a single file (this is something I'd had on my 'Possibly To Do' list for a while, but a little gentle nudging from one of my Test Pilots convinced me it was a good idea!).
Finished up by fixing a small bug in the Tileset loading routine, which occasionally missed out a specific tile when the Tileset was loaded, but subsequently loaded the tile properly when the Tileset was refreshed. The code for each one was identical, save for one mistyped number, and after a deft slap to the forehead everything was working as intended.
This led on to the addition of the Map Set loading and saving routines, allowing the user to save out all 8 maps as a single file (this is something I'd had on my 'Possibly To Do' list for a while, but a little gentle nudging from one of my Test Pilots convinced me it was a good idea!).
Finished up by fixing a small bug in the Tileset loading routine, which occasionally missed out a specific tile when the Tileset was loaded, but subsequently loaded the tile properly when the Tileset was refreshed. The code for each one was identical, save for one mistyped number, and after a deft slap to the forehead everything was working as intended.
Wednesday, July 13, 2005
Wednesday 13th
Decided to take a delve back into the Undo/Redo code today, with little in the way of progress. I did manage to crack a small problem in the logic, however, which was preventing the Undo going right back to the start of the list; essentially, the Editor needs to call the Undo routine at the start of the program, or if a map is loaded into memory - this 'saves' the initial state of the map, allowing the user to Undo back to the beginning.
Tuesday, July 12, 2005
Tuesday 12th
Tonight's session saw me tackling a task which had never worked properly since it was added many moons ago. In theory, the system seemed fairly straightforward: when the user holds Shift, it constrains lines to 90 or 45 degrees, and constrains boxes to a perfect square.
After delving in with a brain full of caffeine, I managed to track down the problem which was causing unpredictable results - it stemmed from the fact that a line/box is not always drawn from top-left to bottom-right; sometimes, the box is drawn in reverse. Once my code understood this, the routine worked like a dream. Getting this functionality to work with Brush grabbing will be another matter!
After delving in with a brain full of caffeine, I managed to track down the problem which was causing unpredictable results - it stemmed from the fact that a line/box is not always drawn from top-left to bottom-right; sometimes, the box is drawn in reverse. Once my code understood this, the routine worked like a dream. Getting this functionality to work with Brush grabbing will be another matter!
Sunday, July 10, 2005
Sunday 10th
Avid followers of this Blog will recall the Bookmark code I added to the Editor a while ago (which basically allowed the user to store their current position and current map at the press of a button). The feature was coded, but left on the sidelines due to a keyboard conflict.
I'd always liked the system, so today I tied in the functionality to my recently-created Bookmark menu - a deft click of the mouse now allows the user to store and retrieve up to eight different editing positions.
I'd always liked the system, so today I tied in the functionality to my recently-created Bookmark menu - a deft click of the mouse now allows the user to store and retrieve up to eight different editing positions.
Saturday, July 9, 2005
Saturday 9th
After yesterday's bug chasing, I decided to continue with the tweaks and fixes. First of all, I finalised the scrolling system for the Tile window, so that it comfortably copes with tiles of any size. It's likely that the user will be restricted to tilesets of 256 tiles - files smaller than this will be 'padded out' when loaded into the editor.
Fixing the Tile window also forced me to tackle another bug: the inability to load a 128x128 tileset into the editor. After trying - and failing - to load the image back into PhotoShop, it occurred to me that there must be some physical restriction (possibly in MS Windows) that shies away from files over a certain width/height.
Sure enough, I managed to deduce that files over 16384 pixels in width/height will cause problems - luckily, the Editor can handle blocks of tiles as well as strips of tiles, so after a quick snip and paste, everything was peachy.
Rounded off by tweaking the Meta Panel, as the addition of 64x64 and 128x128 tiles means that I needed to drop the Copy/Paste buttons and shift down the Meta Flags display. The buttons were convenient, admittedly, so they now sit nicely in the Tile menu.
Fixing the Tile window also forced me to tackle another bug: the inability to load a 128x128 tileset into the editor. After trying - and failing - to load the image back into PhotoShop, it occurred to me that there must be some physical restriction (possibly in MS Windows) that shies away from files over a certain width/height.
Sure enough, I managed to deduce that files over 16384 pixels in width/height will cause problems - luckily, the Editor can handle blocks of tiles as well as strips of tiles, so after a quick snip and paste, everything was peachy.
Rounded off by tweaking the Meta Panel, as the addition of 64x64 and 128x128 tiles means that I needed to drop the Copy/Paste buttons and shift down the Meta Flags display. The buttons were convenient, admittedly, so they now sit nicely in the Tile menu.
Friday, July 8, 2005
Friday 8th
Started tinkering with ideas for a Zoom function; I've used an editor in the past which allows the user to zoom out to get a better picture of how the whole map looks. This would be ideal for the Editor, particularly as it's just a cosmetic function (no editing takes place when the user is zoomed in/out), and partly because I have much of the code written already.
Finished off the day searching for an elusive bug which causes a quirky problem when in 16x16 tile mode. Still can't work out why it's happening - perhaps I'll just remove the 16x16 option altogether ;)
Finished off the day searching for an elusive bug which causes a quirky problem when in 16x16 tile mode. Still can't work out why it's happening - perhaps I'll just remove the 16x16 option altogether ;)
Thursday, July 7, 2005
Thursday 7th
Not much progress today. Decided to delve into the Undo/Redo code again, as it's been sitting on my To Do list for far too long. Most of the logic was plotted out on paper, which is always helpful, but by the time I reached the keyboard my head was blank (typical!). Not one to waste valuable minutes, I set about creating a Key List, to help me keep track of the assigned keys.
Wednesday, July 6, 2005
Wednesday 6th
After a brief stint yesterday, trying to get my head around the Mini Map and Meta Data functionality, I decided to leave that task momentarily and tackle a few other pressing issues.
First on the agenda was the startup menu; currently, the Editor loads up all my test tilesets, and sets the map at a specific size. Now that the tile size changes have been implemented and - touch wood - should be working properly, it seems appropriate to implement the startup menu (this will allow the user to create a new project with the desired map dimensions and tilesize, or load an existing project).
It's always interesting when a new piece of code is integrated into an existing (and complex) framework - thankfully, the startup screen was a cinch to implement, and fires the Editor up properly every time. :)
Rounded off the evening by adding a few more options to the menus, to cope with the Layer flipping and Bookmark routines (which will hopefully be added this week).
First on the agenda was the startup menu; currently, the Editor loads up all my test tilesets, and sets the map at a specific size. Now that the tile size changes have been implemented and - touch wood - should be working properly, it seems appropriate to implement the startup menu (this will allow the user to create a new project with the desired map dimensions and tilesize, or load an existing project).
It's always interesting when a new piece of code is integrated into an existing (and complex) framework - thankfully, the startup screen was a cinch to implement, and fires the Editor up properly every time. :)
Rounded off the evening by adding a few more options to the menus, to cope with the Layer flipping and Bookmark routines (which will hopefully be added this week).
Monday, July 4, 2005
Monday 4th
Tonight's session saw the addition of some enhanced functionality for the Mini Map. Currently, the Mini Map works on a fixed tile range (all tiles within this range show up on the Mini Map panel). I wanted to extend this capability to make it more user-controllable, so the first task involved adding extra options to the relevant menu.
That done, I added the code to read the Mini Map from the current Tile Mask - although this only gives the user two choices (the tile is either displayed or not), it is quite a useful way to track tile usage.
Next, I wanted to implement a system that allowed the Mini Map to get its information from the Meta Data. I prototyped a pop-up window in PhotoShop, then used this template to code the necessary routines.
This is actually a pretty cool system, as I can read the co-ordinates in PhotoShop and transfer them directly to Blitz, thus saving plenty of painstaking tweaks. With the shell complete, I tied up the functionality ready to write the more serious code tomorrow.
That done, I added the code to read the Mini Map from the current Tile Mask - although this only gives the user two choices (the tile is either displayed or not), it is quite a useful way to track tile usage.
Next, I wanted to implement a system that allowed the Mini Map to get its information from the Meta Data. I prototyped a pop-up window in PhotoShop, then used this template to code the necessary routines.
This is actually a pretty cool system, as I can read the co-ordinates in PhotoShop and transfer them directly to Blitz, thus saving plenty of painstaking tweaks. With the shell complete, I tied up the functionality ready to write the more serious code tomorrow.
Sunday, July 3, 2005
Sunday 3rd
Managed to crack the Brush plotting changes today. Basically, the user can hold CTRL when plotting a Brush to mask out Tile 0 - this allows genuine Brush transparency. However, I hit upon the idea of making CTRL mask out the currently selected tile - that way, the user can specify exactly which tile in the Brush they don't wish to plot.
Confused? Ok, imagine the map is filled with Tile 4, and on top of this the user has drawn a shape with Tile 3. Imagine they wanted to plot this brush on to a background consisting of Tile 8 - plotting the brush as-is will cause the instances of Tile 4 to be plotted too.
Using my new system, once the Brush is grabbed the user simply selects Tile 4, then holds CTRL as they plot their Brush - only Tile 3 is plotted, any instances of Tile 4 in the Brush are ignored (it's much easier to understand when you see it working!).
After toiling away for an hour or so, I managed to override the conflicts associated with Masked Tiles, and the whole system was working perfectly. I'm extremely pleased with the Editor's Brush functions, and it's getting to the point where I'm itching to stop coding and start messing around with maps :)
Confused? Ok, imagine the map is filled with Tile 4, and on top of this the user has drawn a shape with Tile 3. Imagine they wanted to plot this brush on to a background consisting of Tile 8 - plotting the brush as-is will cause the instances of Tile 4 to be plotted too.
Using my new system, once the Brush is grabbed the user simply selects Tile 4, then holds CTRL as they plot their Brush - only Tile 3 is plotted, any instances of Tile 4 in the Brush are ignored (it's much easier to understand when you see it working!).
After toiling away for an hour or so, I managed to override the conflicts associated with Masked Tiles, and the whole system was working perfectly. I'm extremely pleased with the Editor's Brush functions, and it's getting to the point where I'm itching to stop coding and start messing around with maps :)
Saturday, July 2, 2005
Saturday 2nd
Today saw the implementation of a colour cycling routine to pulse my new vector cursors; this took a little longer than expected due to the quirky way in which Blitz handles Data statements. Ok, it's actually perfectly fine, but it's a little different to Commodore BASIC so I'm sticking with my quirky statement :)
The cursors looked so good, I actually tweaked my Brush Grab cursors and converted them to vectors, which now means that they too can have pulsing colour (and makes a big difference to the Editor's look and feel).
Next, I plucked a task from my To Do list which had been negelected for far too long, that of allowing the user to change both the X and Y dimensions of the Grid (previously, X and Y were locked). This entailed creating a custom pop-up window, but the added flexibility is well worth the effort.
The final task involved an amendment to the Brush plotting routine, but with the time approaching midnight, I thought better of delving into one of the Editor's more complex routines and reserved it a spot on tomorrow's schedule. ;)
The cursors looked so good, I actually tweaked my Brush Grab cursors and converted them to vectors, which now means that they too can have pulsing colour (and makes a big difference to the Editor's look and feel).
Next, I plucked a task from my To Do list which had been negelected for far too long, that of allowing the user to change both the X and Y dimensions of the Grid (previously, X and Y were locked). This entailed creating a custom pop-up window, but the added flexibility is well worth the effort.
The final task involved an amendment to the Brush plotting routine, but with the time approaching midnight, I thought better of delving into one of the Editor's more complex routines and reserved it a spot on tomorrow's schedule. ;)
Friday, July 1, 2005
Friday 1st
Work continued on the tile size tweaks today, kicking off with a few changes to the various mouse pointers and cursors (naturally, these were constructed for 32x32 tiles but now need to accommodate all tile sizes).
The main task involved converting my map and tile cursors from bitmap images into actual rectangles drawn by Blitz. This was a simple task, and allowed me to trim out all of the cursor animations (which makes their colours "pulse") from my cursor bitmap image. I finished off by creating cursor bitmap images to suit all tile sizes.
The main task involved converting my map and tile cursors from bitmap images into actual rectangles drawn by Blitz. This was a simple task, and allowed me to trim out all of the cursor animations (which makes their colours "pulse") from my cursor bitmap image. I finished off by creating cursor bitmap images to suit all tile sizes.
Thursday, June 30, 2005
Thursday 30th
The main task on today's agenda was to start preparing the Editor for the implementation of multiple tile sizes (currently I hope to implement 16x16 tiles, 32x32 tiles, 64x64 tiles, and 128x128 tiles).
The first task was to change the display cursors and tile selection cursors from bitmap images into Blitz-drawn rectangles and lines (which should also allow for customisable colour schemes).
That done, I started wading through the routines one by one, tweaking those that didn't utilise my handy "tilesize" variable, and making sure those that did no longer assumed the tiles were 32x32.
The first task was to change the display cursors and tile selection cursors from bitmap images into Blitz-drawn rectangles and lines (which should also allow for customisable colour schemes).
That done, I started wading through the routines one by one, tweaking those that didn't utilise my handy "tilesize" variable, and making sure those that did no longer assumed the tiles were 32x32.
Wednesday, June 29, 2005
Wednesday 29th
Wasn't in the mood for a heavy coding session today, so I decided to tackle a few of the smaller tasks from my To Do list. Currently I have three different lists: the first covers all the features and so forth that need to be added; the second covers possible features and ideas I may want to explore; the third covers any bugs, as well as features that may need attention as the Editor is expanded.
Having these lists means that I always have something to do; if I don't fancy a big tasks, I can tackle a smaller one. It's a simple way of keeping things moving in the right direction, and also keeps the creative juices flowing.
My first task was to resize the Tile window; I want to implement different tile sizes, and thus, the Tile window needs to be able to cope with this. Thankfully, it was a relatively simple task, and also freed up a little bit of space to add some buttons for tile and tileset selection. While making these tweaks I hit upon the idea of adding a grid to the Tile window, to make the tile divisions a little clearer.
The next task was a simple tweak to allow the user to confine the current Brush to the screen boundary (currently, the Brushes can be moved off the sides of the display).
Next, I tweaked the routine which inverts the current tileset mask (if you recall, I changed the mask system from a single array to 8 different databanks - the invert mask routine therefore needed changing accordingly).
The final task of the day was a batch of menu changes I'd been meaning to implement for a few days. I also took the liberty of adding options to save and load a Map Set, a feature which will be coded in the upcoming days.
Having these lists means that I always have something to do; if I don't fancy a big tasks, I can tackle a smaller one. It's a simple way of keeping things moving in the right direction, and also keeps the creative juices flowing.
My first task was to resize the Tile window; I want to implement different tile sizes, and thus, the Tile window needs to be able to cope with this. Thankfully, it was a relatively simple task, and also freed up a little bit of space to add some buttons for tile and tileset selection. While making these tweaks I hit upon the idea of adding a grid to the Tile window, to make the tile divisions a little clearer.
The next task was a simple tweak to allow the user to confine the current Brush to the screen boundary (currently, the Brushes can be moved off the sides of the display).
Next, I tweaked the routine which inverts the current tileset mask (if you recall, I changed the mask system from a single array to 8 different databanks - the invert mask routine therefore needed changing accordingly).
The final task of the day was a batch of menu changes I'd been meaning to implement for a few days. I also took the liberty of adding options to save and load a Map Set, a feature which will be coded in the upcoming days.
Friday, June 24, 2005
Friday 24th
Finally managed to crack an I/O problem that had plagued me for the last two days; essentially, I needed to tweak the Brush Set loading and saving routines, so that a) any brushes not defined are ignored during the save, and b) brushes being loaded into the Editor will generate their own thumbnails.
The I/O routines for Brush Sets had been temperamental to say the least, and with only tiny chunks of time here and there to actually work on the problem, it took a lot of headscratching to work out why I was getting inundated with errors. Ultimately it boiled down to a simple slip of logic - I was trying to access a Data Bank at the wrong point.
With that out of the way, I tied in the I/O routine to the thumbnail routine so that when a set of Brushes is loaded, their thumbnails are automatically generated (previously, thumbnails were generated only when the user chose to manually "store" the current brush in a buffer).
The routine required only a couple of tweaks to make it work in both instances, and now the entire system is complete and working like a dream.
I finished off the day by adding an "Anim" panel to the group of tile panels, and began adding the various display information (such as source tile, animation sequence, etc.), as well as the buttons to make everything work. I've still no idea how to actually put the system together, but there's plenty of groundwork to do in the meantime. :)
The I/O routines for Brush Sets had been temperamental to say the least, and with only tiny chunks of time here and there to actually work on the problem, it took a lot of headscratching to work out why I was getting inundated with errors. Ultimately it boiled down to a simple slip of logic - I was trying to access a Data Bank at the wrong point.
With that out of the way, I tied in the I/O routine to the thumbnail routine so that when a set of Brushes is loaded, their thumbnails are automatically generated (previously, thumbnails were generated only when the user chose to manually "store" the current brush in a buffer).
The routine required only a couple of tweaks to make it work in both instances, and now the entire system is complete and working like a dream.
I finished off the day by adding an "Anim" panel to the group of tile panels, and began adding the various display information (such as source tile, animation sequence, etc.), as well as the buttons to make everything work. I've still no idea how to actually put the system together, but there's plenty of groundwork to do in the meantime. :)
Tuesday, June 21, 2005
Tuesday 21st
Got cracking on the Meta routines today, and specifically, setting up the Data Banks and coaxing the checkboxes to set the relevant flags - this took a little longer than expected thanks to a stray variable which was pointing my values at the wrong place in the Data Bank.
Next I added the functionality to the three new buttons on the Meta panel, which allow the user to Copy the Meta data for the current tile, Paste the Meta data in the buffer to the current tile, or Paste All (which applies the Meta data in the buffer to all tiles).
The final task for the Meta panel was to add the file I/O routines, so that Meta data can be saved for later use. As with Maps, the user will be able to save and load Meta files individually, for maximum flexibility.
As an afterthought, I also added a toggle on the Meta checkboxes; currently, the tiny display area gets a little cluttered - the toggle removes the checkbox numbers, which will hopefully make things clearer for experienced users.
Work continued tonight with the Brushes panel next on the agenda. Back in the day, I wanted to include a small thumbnail view for the current brush; the Tab was added, but as things progressed and the Brush functionality expanded, I honestly expected this to fall by the wayside.
However, after a conversation with Muttley (again!), I discovered the ResizeImage command which should help me to accomplish my goal, so tonight I set about putting the framework together. I started off by adding the tabber functionality, new canvas, and gadget panel.
Next I set about taking a stored brush, converting the brush to a single image, then scaling the image down to fit in the Brush window. After typing frantically for 15 minutes, I fired up the code... and it worked first time!
The next task was to ensure the scaling remained proportional no matter what the brush dimensions; basically, the image is resized to be exactly 256 pixels wide - but I also needed the program to proportionally scale the image height, based on the scale ratio used for the image width.
After a bit of headscratching, I came up with a formula, but the results were somewhat limited so I decided to post on the Llamasoft forum for advice. No sooner did I click the POST button, the solution to the problem popped into my head. Duh! A couple of tweaks later, the scaling was working perfectly.
With time ticking away, I decided to leave the remaining fiddly code until tomorrow (I need to tie in the thumbnail functions with the I/O functions, for example), and instead added a trio of buttons to allow the user to select and choose a brush from the library.
Next I added the functionality to the three new buttons on the Meta panel, which allow the user to Copy the Meta data for the current tile, Paste the Meta data in the buffer to the current tile, or Paste All (which applies the Meta data in the buffer to all tiles).
The final task for the Meta panel was to add the file I/O routines, so that Meta data can be saved for later use. As with Maps, the user will be able to save and load Meta files individually, for maximum flexibility.
As an afterthought, I also added a toggle on the Meta checkboxes; currently, the tiny display area gets a little cluttered - the toggle removes the checkbox numbers, which will hopefully make things clearer for experienced users.
* * *
Work continued tonight with the Brushes panel next on the agenda. Back in the day, I wanted to include a small thumbnail view for the current brush; the Tab was added, but as things progressed and the Brush functionality expanded, I honestly expected this to fall by the wayside.
However, after a conversation with Muttley (again!), I discovered the ResizeImage command which should help me to accomplish my goal, so tonight I set about putting the framework together. I started off by adding the tabber functionality, new canvas, and gadget panel.
Next I set about taking a stored brush, converting the brush to a single image, then scaling the image down to fit in the Brush window. After typing frantically for 15 minutes, I fired up the code... and it worked first time!
The next task was to ensure the scaling remained proportional no matter what the brush dimensions; basically, the image is resized to be exactly 256 pixels wide - but I also needed the program to proportionally scale the image height, based on the scale ratio used for the image width.
After a bit of headscratching, I came up with a formula, but the results were somewhat limited so I decided to post on the Llamasoft forum for advice. No sooner did I click the POST button, the solution to the problem popped into my head. Duh! A couple of tweaks later, the scaling was working perfectly.
With time ticking away, I decided to leave the remaining fiddly code until tomorrow (I need to tie in the thumbnail functions with the I/O functions, for example), and instead added a trio of buttons to allow the user to select and choose a brush from the library.
Monday, June 20, 2005
Monday 20th
The main task on today's agenda was the Meta Data panel, which I've been meaning to implement for some time. After careful thought (and a little discussion with my test pilots), it seemed logical to implement a flag-based system; each tile will have 16 flags associated with it, and the user can turn any of these flags on or off as required.
Obviously, it's possible that the average user might prefer more flags, but coupled with the ability to create additional collision layers and so forth, the Editor currently offers enough flexibility to cover all eventualities (in my opinion, of course!).
With precious little space left on the screen for extra buttons and suchlike, the only option was to overlay the Meta Data information over the bottom of the Tile panel. After knocking up a rough design in PhotoShop, I began the arduous task of creating panels and gadgets, and adding the various buttons and checkboxes.
Once in place, I tackled the control logistics to ensure that the Tile, Meta, and Mask panels could share the same code, but didn't conflict with one another. Then came the task of allowing the tiles to scroll slightly further on the Meta panel, as there's less on-screen space. After a couple of hours, the whole system - or at least, the framework - was in place, ready for the final code additions tomorrow.
Obviously, it's possible that the average user might prefer more flags, but coupled with the ability to create additional collision layers and so forth, the Editor currently offers enough flexibility to cover all eventualities (in my opinion, of course!).
With precious little space left on the screen for extra buttons and suchlike, the only option was to overlay the Meta Data information over the bottom of the Tile panel. After knocking up a rough design in PhotoShop, I began the arduous task of creating panels and gadgets, and adding the various buttons and checkboxes.
Once in place, I tackled the control logistics to ensure that the Tile, Meta, and Mask panels could share the same code, but didn't conflict with one another. Then came the task of allowing the tiles to scroll slightly further on the Meta panel, as there's less on-screen space. After a couple of hours, the whole system - or at least, the framework - was in place, ready for the final code additions tomorrow.
Friday, June 17, 2005
Friday 17th
Bit of a slow start today, thanks to an eyeful of soap (which seemed like God's way of saying, "don't code today"). Not that I believe in God, or indeed, believe that God, if he existed, would have time to send messages about my code. But I digress.
The first task on today's list was to tweak the resize function; one of my test pilots pointed out that if a map is smaller than the screen, it's hard to tell where the edges of the map are because it's surrounded by blank tiles. I therefore popped in a small piece of code that resizes the canvas should the map drop below a certain size, and certainly makes editing smaller maps a little more intuitive.
Next up came a tweak to the Mask system; currently the user can activate a simple on/off mask, which allows tiles to be masked (in the same way that DPaint stencils worked) to prevent them from being drawn over. Masks will also be used to quickly generate collision maps and so forth. In response to feedback, however, it became apparent that one Mask per tileset would be preferable to just a single Mask.
This was no simple task, as I not only had to tweak the Mask display routine, I also needed to convert the array-based system to a more flexible bank-based one, and then convert all the drawing functions accordingly. Surprisingly, the additions and tweaks took about 25 minutes, and left me time to add Mask functionality to Fill Mode (something I'd previously neglected to do).
While I was tinkering with Masks, I hit upon the idea of displaying the masked tiles on the map (as opposed to just on the tile panel), which makes it easier to see which tiles are masked and which aren't. After a few tiny adjustments (mainly to ensure that only masked tiles from the current layer are displayed, and in the correct order), the system was in and working beautifully.
The first task on today's list was to tweak the resize function; one of my test pilots pointed out that if a map is smaller than the screen, it's hard to tell where the edges of the map are because it's surrounded by blank tiles. I therefore popped in a small piece of code that resizes the canvas should the map drop below a certain size, and certainly makes editing smaller maps a little more intuitive.
Next up came a tweak to the Mask system; currently the user can activate a simple on/off mask, which allows tiles to be masked (in the same way that DPaint stencils worked) to prevent them from being drawn over. Masks will also be used to quickly generate collision maps and so forth. In response to feedback, however, it became apparent that one Mask per tileset would be preferable to just a single Mask.
This was no simple task, as I not only had to tweak the Mask display routine, I also needed to convert the array-based system to a more flexible bank-based one, and then convert all the drawing functions accordingly. Surprisingly, the additions and tweaks took about 25 minutes, and left me time to add Mask functionality to Fill Mode (something I'd previously neglected to do).
While I was tinkering with Masks, I hit upon the idea of displaying the masked tiles on the map (as opposed to just on the tile panel), which makes it easier to see which tiles are masked and which aren't. After a few tiny adjustments (mainly to ensure that only masked tiles from the current layer are displayed, and in the correct order), the system was in and working beautifully.
Thursday, June 16, 2005
Thursday 16th
Spent the better part of the day finalising the resize routine; the map can now be resized in both the X and Y axes, enlarged, reduced, and cropped properly using the anchor facility.
The rest of the day was spent tinkering with the Mini Map code; this has never really worked precisely as I would have liked, and now that the map sizes can be changed the Mini Map also needs to be able to cope with this.
Part of the problem with going back to old routines is that of familiarity; you can spend far too much time simply working out how a routine works, and getting back into the mindset you were in when you wrote the code originally. Luckily, I want to completely revamp the Mini Map system, so most of the time was spent stripping down the routine to its basic elements ready for some serious tinkering.
The rest of the day was spent tinkering with the Mini Map code; this has never really worked precisely as I would have liked, and now that the map sizes can be changed the Mini Map also needs to be able to cope with this.
Part of the problem with going back to old routines is that of familiarity; you can spend far too much time simply working out how a routine works, and getting back into the mindset you were in when you wrote the code originally. Luckily, I want to completely revamp the Mini Map system, so most of the time was spent stripping down the routine to its basic elements ready for some serious tinkering.
Tuesday, June 14, 2005
Tuesday 14th
I wonder if anyone will notice the 3-month gap between diary entries? After an extremely busy few months getting my life packed into boxes ready for the move to Canada, I'm finally finding time to sit down with Blitz again and finish off the Editor (otherwise known as FishEd, for those who weren't paying attention).
I'm particularly keen to get the Editor finished not only so I can crack on with Citadel, but also because a couple of colleagues wish to use FishEd to put together the maps for their Blitz project. I've already received glowing praise for the Alpha version - now the inconsiderable task of finishing the project is staring me in the face.
Today's task was a bug in the Resize Map routine, which had seen me tearing my hair out for the best part of three days; after discussion with Muttley from the YakYak forums, and after pasting in some of his code to try and trace the problem, it finally dawned on me: in my haste, I'd cut 'n' pasted a PEEK statement and changed it into a POKE statement, but neglected to leave out a set of brackets. Yep, all that fuss that could have been avoided with two deft jabs of the DEL key.
After slapping my head for what seemed like an eternity, I tidied up the code and now the map resizing works like a dream. I still need to properly implement all resizing combinations in all dimensions, and adjust the code so that the maps get cropped properly.
With this in mind, I knocked up a small grid of radio buttons to emulate the "anchor" system (if you've ever resized your canvas in PhotoShop, you'll be familiar with this - it basically allows you to specify where the original portion of the image will wind up once the canvas has been resized).
Getting the radio buttons in and working took mere minutes (such is the beauty of Blitz's GUI functionality), but I'll tackle the code tomorrow when my head is a little clearer.
I'm particularly keen to get the Editor finished not only so I can crack on with Citadel, but also because a couple of colleagues wish to use FishEd to put together the maps for their Blitz project. I've already received glowing praise for the Alpha version - now the inconsiderable task of finishing the project is staring me in the face.
Today's task was a bug in the Resize Map routine, which had seen me tearing my hair out for the best part of three days; after discussion with Muttley from the YakYak forums, and after pasting in some of his code to try and trace the problem, it finally dawned on me: in my haste, I'd cut 'n' pasted a PEEK statement and changed it into a POKE statement, but neglected to leave out a set of brackets. Yep, all that fuss that could have been avoided with two deft jabs of the DEL key.
After slapping my head for what seemed like an eternity, I tidied up the code and now the map resizing works like a dream. I still need to properly implement all resizing combinations in all dimensions, and adjust the code so that the maps get cropped properly.
With this in mind, I knocked up a small grid of radio buttons to emulate the "anchor" system (if you've ever resized your canvas in PhotoShop, you'll be familiar with this - it basically allows you to specify where the original portion of the image will wind up once the canvas has been resized).
Getting the radio buttons in and working took mere minutes (such is the beauty of Blitz's GUI functionality), but I'll tackle the code tomorrow when my head is a little clearer.
Saturday, February 26, 2005
Saturday 26th
Only managed a brief coding session today, and started off by tweaking the menus (yet again) to cope with the impending arrival of the Map Properties routine, which will allow the maps sizes to be changed dynamically at any point (as opposed to being fixed at runtime, as they currently are).
As I've now decided to handle the Map Properties system a little differently than I'd initially planned, the Tileset loading/refresh routines needed a new home, as did options to save/load Meta data and Mask data, so creating a Tile menu seemed to be the obvious choice.
I also took a little time out to have a look-see at the toolbar, just to see if there was space to add any more functions to it. I have space for about 14 more icons, which seems a lot until you consider that I have about 30 options I want to include! After careful examination, I concluded that the toolbar should house only important functions (loading, saving, and drawing tools), with secondary functions confined to the Menus.
While I was tinkering with the Toolbar, I came upon an idea to add bookmarks - essentially, you can hit a key to save your current position on the map; hitting the recall key returns you to the correct position, and even remembers which map you were editing at the time.
Although this took mere minutes to add, a keyboard conflict arose: I was using Alt+F9-F12 to store a bookmark, and F9-F12 to recall. However, F10 is a special key, and returns a different code to those of the other F-keys. Unable to find a decent solution to this, the bookmark code remains unused for the moment. On the plus side, I did work out how to manually "select" a tabber from within the program, so now my map select keys (F1 to F8, for those with a key fetish) now finally work as I originally intended. :)
The final task for the night was a brief tinker with the Map Properties code; currently this triggers a small window, into which you type the new dimensions for the map, but there were a few minor bugs which needed to be rectified first (this merely involved freeing up gadgets when the window was closed and returning the correct values). With the window now working properly, this will hopefully allow me to crack on with the more important code tomorrow.
As I've now decided to handle the Map Properties system a little differently than I'd initially planned, the Tileset loading/refresh routines needed a new home, as did options to save/load Meta data and Mask data, so creating a Tile menu seemed to be the obvious choice.
I also took a little time out to have a look-see at the toolbar, just to see if there was space to add any more functions to it. I have space for about 14 more icons, which seems a lot until you consider that I have about 30 options I want to include! After careful examination, I concluded that the toolbar should house only important functions (loading, saving, and drawing tools), with secondary functions confined to the Menus.
While I was tinkering with the Toolbar, I came upon an idea to add bookmarks - essentially, you can hit a key to save your current position on the map; hitting the recall key returns you to the correct position, and even remembers which map you were editing at the time.
Although this took mere minutes to add, a keyboard conflict arose: I was using Alt+F9-F12 to store a bookmark, and F9-F12 to recall. However, F10 is a special key, and returns a different code to those of the other F-keys. Unable to find a decent solution to this, the bookmark code remains unused for the moment. On the plus side, I did work out how to manually "select" a tabber from within the program, so now my map select keys (F1 to F8, for those with a key fetish) now finally work as I originally intended. :)
The final task for the night was a brief tinker with the Map Properties code; currently this triggers a small window, into which you type the new dimensions for the map, but there were a few minor bugs which needed to be rectified first (this merely involved freeing up gadgets when the window was closed and returning the correct values). With the window now working properly, this will hopefully allow me to crack on with the more important code tomorrow.
Friday, February 25, 2005
Friday 25th
After yesterday's successes, I decided to continue plucking tasks from my To-Do list. First on the agenda was a keypress to prevent tile zero being plotted when the user draws with a brush. Essentially, tile zero is transparent in every tileset, and usually shows up as black (because the background is black).
Whenever a Brush is drawn, if there are any instances of tile zero, these get plotted too, overwriting anything that might be underneath. However, there may be instances where you need to draw a non-rectangular shape onto an existing map without plotting tile 0 - and thanks to a tiny bit of fiddling, the user can now hold Control when plotting a Brush to do just that (essentially this gives you a genuine transparency on tile 0).
This idea may be expanded to apply the current mask to the plotting procedure (currently the mask prevents certain tiles being drawn over - this could be tweaked to prevent masked tiles actually being plotted), but this will be logged on the Wish-List for now.
The next task of the day saw me implementing the Merge Visible routine, which takes all of the currently visible layers and merges them to the layer currently being edited (tile zero is not plotted, allowing the maps at the back to show through the gaps in the maps at the front). This routine took a while due to an interesting problem with Bank sizes (i.e. I was using the actual Bank size in bytes as opposed to the relative Bank size in doublewords).
That done, I finished up by adding a Swap Visible routine, which will - surprisingly - swap the two layers which are currently visible. This again took a little bit of thought, as I needed to add error handling should the user have too few/too many layers selected.
Whenever a Brush is drawn, if there are any instances of tile zero, these get plotted too, overwriting anything that might be underneath. However, there may be instances where you need to draw a non-rectangular shape onto an existing map without plotting tile 0 - and thanks to a tiny bit of fiddling, the user can now hold Control when plotting a Brush to do just that (essentially this gives you a genuine transparency on tile 0).
This idea may be expanded to apply the current mask to the plotting procedure (currently the mask prevents certain tiles being drawn over - this could be tweaked to prevent masked tiles actually being plotted), but this will be logged on the Wish-List for now.
The next task of the day saw me implementing the Merge Visible routine, which takes all of the currently visible layers and merges them to the layer currently being edited (tile zero is not plotted, allowing the maps at the back to show through the gaps in the maps at the front). This routine took a while due to an interesting problem with Bank sizes (i.e. I was using the actual Bank size in bytes as opposed to the relative Bank size in doublewords).
That done, I finished up by adding a Swap Visible routine, which will - surprisingly - swap the two layers which are currently visible. This again took a little bit of thought, as I needed to add error handling should the user have too few/too many layers selected.
Thursday, February 24, 2005
Thursday 24th
Tackled the remainder of the Brush I/O code today, which involves saving the entire collection of brush buffers (as well as the Brush currently being used, the user can store up to 8 Brushes in temporary buffers and thus have a 'library' of commonly-used Brushes).
As has been the case all week, however, I struggled with this code making tweak after tweak; the problem with I/O is knowing what's going wrong - if you save a file and it won't load back in, has the save routine messed up or the load routine? The only way to work through the issues is edit the routines side by side to ensure that everything is read/written in the correct order.
With progress slow, I decided to turn my attention to my To-Do list, rather than waste valuable time pouring over what could turn out to be a very simple problem (I'm hoping a fresh look at the code tomorrow will yield some results).
The biggest remaining task on my list - something I'd been dreading for some time - was the Tileset integration. Currently, the code already contains commands that load in a default set of tiles when the program is run. While this is obviously fine for me - I merely tweak a line of code to use an alternative Tileset - it limits the Editor's functionality for anyone else wishing to create maps.
After careful tinkering, the user can now load in a Tileset to any one of the eight "slots" designated for Tilesets. As an added bonus, the program even handles Tilesets that aren't in the correct format; although the results are clearly bad, the program doesn't crash, which means that I don't have to write a lengthy routine to validate each file. As a final tweak, I added a refresh facility so that the tiles can be tweaked simultaneously in another package and 're-loaded' with a single click.
The next task was an idea that only occurred to me yesterday: the user can currently dump the screen or the entire Map to a BMP file - so why not the current Brush? A quick amendment to the Brush routine, and this was in and working beautifully. Far too many Editors overlook the facility to save graphics out from the editor, but in my experience this has been invaluable for the artist creating the tiles - it's easier to track down mistakes, and they can even tweak the tiles on the screen dump then slice this up into tiles again and re-import them.
Still in Brush territory, I expanded the Exchange Tile code to encompass Brushes as well (if you recall, the user can highlight a Tile with the Left button, then the replacement Tile with the Right button, then press a key to exchange all instances of the Left tile with the Right). It seemed a natural evolution to apply this to Brushes, since it now allows you to perform 'localised' tile exchanges.
Flushed with my progress, I also tackled another pretty big routine that displays a Static backdrop behind the map window. Though this probably isn't something I'll be using for Citadel, it will come in handy for other projects, especially those that utilise a static or parallax backdrop. The basic routine was up and running fairly quickly, but may need further refinement as things progress.
The final job for the night came as a result of adding the Static backdrop code: originally, when the Editor was first put into its GUI, one of the Layers had been reserved specifically for the Static backdrop. As this has now changed slightly (and given that I want to avoid restricting what sort of data a Layer can hold), I made the Static backdrop independent of the actual Layers, and expanded the number of Layers from six to eight.
As has been the case all week, however, I struggled with this code making tweak after tweak; the problem with I/O is knowing what's going wrong - if you save a file and it won't load back in, has the save routine messed up or the load routine? The only way to work through the issues is edit the routines side by side to ensure that everything is read/written in the correct order.
With progress slow, I decided to turn my attention to my To-Do list, rather than waste valuable time pouring over what could turn out to be a very simple problem (I'm hoping a fresh look at the code tomorrow will yield some results).
* * *
The biggest remaining task on my list - something I'd been dreading for some time - was the Tileset integration. Currently, the code already contains commands that load in a default set of tiles when the program is run. While this is obviously fine for me - I merely tweak a line of code to use an alternative Tileset - it limits the Editor's functionality for anyone else wishing to create maps.
After careful tinkering, the user can now load in a Tileset to any one of the eight "slots" designated for Tilesets. As an added bonus, the program even handles Tilesets that aren't in the correct format; although the results are clearly bad, the program doesn't crash, which means that I don't have to write a lengthy routine to validate each file. As a final tweak, I added a refresh facility so that the tiles can be tweaked simultaneously in another package and 're-loaded' with a single click.
The next task was an idea that only occurred to me yesterday: the user can currently dump the screen or the entire Map to a BMP file - so why not the current Brush? A quick amendment to the Brush routine, and this was in and working beautifully. Far too many Editors overlook the facility to save graphics out from the editor, but in my experience this has been invaluable for the artist creating the tiles - it's easier to track down mistakes, and they can even tweak the tiles on the screen dump then slice this up into tiles again and re-import them.
Still in Brush territory, I expanded the Exchange Tile code to encompass Brushes as well (if you recall, the user can highlight a Tile with the Left button, then the replacement Tile with the Right button, then press a key to exchange all instances of the Left tile with the Right). It seemed a natural evolution to apply this to Brushes, since it now allows you to perform 'localised' tile exchanges.
Flushed with my progress, I also tackled another pretty big routine that displays a Static backdrop behind the map window. Though this probably isn't something I'll be using for Citadel, it will come in handy for other projects, especially those that utilise a static or parallax backdrop. The basic routine was up and running fairly quickly, but may need further refinement as things progress.
The final job for the night came as a result of adding the Static backdrop code: originally, when the Editor was first put into its GUI, one of the Layers had been reserved specifically for the Static backdrop. As this has now changed slightly (and given that I want to avoid restricting what sort of data a Layer can hold), I made the Static backdrop independent of the actual Layers, and expanded the number of Layers from six to eight.
Wednesday, February 23, 2005
Wednesday 23rd
After a couple of day's break from coding, I returned to the Editor to tackle an extremely quirky problem that had plagued Monday night's coding session; I'd put in the code required to Load and Save the current Brush, but for some reason the Load code wasn't functioning correctly.
I examined my code, made a few more tweaks, but the problem still persisted: if I grabbed a Brush then saved it, I couldn't load the Brush back in during that session - I physically had to quit the editor then restart it, at which point the Brush would load in. This pointed to a problem with the save routine, so I included a CloseFile command - but to no avail.
Tonight, as is typical with stubborn bugs, I solved the problem in about 30 seconds - the CloseFile command has to be applied to the variable used to read/write the data, and not by using the filename (as I had been doing). This tweaked, everything was working beautifully, and you can now quick-save a Brush and load it back in with ease.
The final task of the night was to fix a small bug in the Mini-Map routine I worked on in January; this was never completely finished, due to the fact that I wanted to tweak a couple of things after I implement the facility to change the map size. The bug was a quick fix, however, and merely needed to check and adjust a couple of display variables if the map was below a certain size.
I examined my code, made a few more tweaks, but the problem still persisted: if I grabbed a Brush then saved it, I couldn't load the Brush back in during that session - I physically had to quit the editor then restart it, at which point the Brush would load in. This pointed to a problem with the save routine, so I included a CloseFile command - but to no avail.
Tonight, as is typical with stubborn bugs, I solved the problem in about 30 seconds - the CloseFile command has to be applied to the variable used to read/write the data, and not by using the filename (as I had been doing). This tweaked, everything was working beautifully, and you can now quick-save a Brush and load it back in with ease.
The final task of the night was to fix a small bug in the Mini-Map routine I worked on in January; this was never completely finished, due to the fact that I wanted to tweak a couple of things after I implement the facility to change the map size. The bug was a quick fix, however, and merely needed to check and adjust a couple of display variables if the map was below a certain size.
Sunday, February 20, 2005
Sunday 20th
Another annoyingly slow start to the day saw me tinkering with drawing "constraints". It's almost standard these days for art packages to include a constraint option - often associated with the Shift key - which restricts the current drawing tool. For instance, in PhotoShop, holding Shift will ensure that the lasso tool draws perfect squares instead of rectangles, or that the line tool will draw perfectly horizontal, vertical, or diagonal lines.
I'd tinkered with this briefly a couple of months ago, but it was pushed to the bottom of my To Do list in favour of more important tasks. It is something I think is important to the toolset, however, and can envisage a number of scenarios for Citadel where it'll be, like, essential.
With things progressing slowly, I shifted my attention momentarily to another idea I'd had: displaying the dimensions of the shape currently being drawn (which struck me as an obvious omission as soon as I'd thought of it). This wasn't too painful to implement, partly because the variables exited anyway, and partly because my drawing routines all use a similar structure, but nevertheless will be worth its weight in gold.
I'd tinkered with this briefly a couple of months ago, but it was pushed to the bottom of my To Do list in favour of more important tasks. It is something I think is important to the toolset, however, and can envisage a number of scenarios for Citadel where it'll be, like, essential.
With things progressing slowly, I shifted my attention momentarily to another idea I'd had: displaying the dimensions of the shape currently being drawn (which struck me as an obvious omission as soon as I'd thought of it). This wasn't too painful to implement, partly because the variables exited anyway, and partly because my drawing routines all use a similar structure, but nevertheless will be worth its weight in gold.
Subscribe to:
Posts (Atom)
