| |
Wednesday 21st
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.
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).
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.
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!
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. :)
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.
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.
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. :)
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. :)
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. :)
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.
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).
|
|