I fixed that in the NeWS and X11 versions of SimCity, but probably that code didn't get ported to the JavaScript version, since it was in the user interface layer, which works a bit differently in MicropolisJS (and on every platform) of course.

The MicropolisEngine::toolDrag method does what you want, I think: it drags a tool from one tile to another, drawing all the tiles in-between without gaps.

It would be wonderful if somebody would port the "toolDrag" code to the JavaScript version. It's pretty brute force but straightforward. The mouse tracking code that calls it needs to pass in the previous mouse coordinates (in tile coordinates, independent of scrolling), of course.

(I'm sorry, but I haven't had time to work on Micropolis in a long time, but I'm delighted for other people to work on it and I love Graham's excellent work, and I'm happy to answer any questions.)

https://github.com/SimHacker/micropolis/blob/master/Micropol...

/**
* Drag a tool from (\a fromX, \a fromY) to (\a toX, \a toY).
* @param tool Tool being dragged.
* @param fromX Horizontal coordinate of the starting position.
* @param fromY Vertical coordinate of the starting position.
* @param toX Horizontal coordinate of the ending position.
* @param toY Vertical coordinate of the ending position.
*/
void Micropolis::toolDrag(EditingTool tool,
short fromX, short fromY, short toX, short toY)
...
// Do not drag big tools.
...
doTool(tool, fromX, fromY); // Ensure the start position is done.
...
// Vertical line up or down
...
// Horizontal line left/right
...
// General case: both X and Y change.
...

Here's the Python code for the MicropolisTool class that calls it (via SWIG), in the PyGTK user interface:

https://github.com/SimHacker/micropolis/blob/master/Micropol...

And here's the client/server version (OpenLaszlo/Flash client, Python/TurboGears server):

Laszlo appview.drawToolStart/Move/Start:

https://github.com/SimHacker/micropolis/blob/master/laszlo/m...

Python Micropolis Session handleMessage_drawToolStart/Move/Stop:

https://github.com/SimHacker/micropolis/blob/master/Micropol...

Looks like the old TCL/Tk/X11 version even let you hold down the control key to constrain the road/rail to vertical or horizontal lines -- that's a nice feature I totally forgot about:

https://github.com/SimHacker/micropolis/blob/master/micropol...

https://github.com/SimHacker/micropolis/blob/master/micropol...

Make sure you call toolDrag on the initial and final mouse coordinate on mouse down and up, don't just call toolDrag on mouse move events (or animation ticks), or you might miss the initial source or final destination when the user draws quickly!

For extra credit, make sure the drawing tools work smoothly and reliably with auto-scroll! That makes drawing long roads and railroads easy. ;)

Some of the above user interface code is tricky because it supports multiple views, and each view must maintain its own independent track state. (TCL/Tk/X11 SimCity supported not only multiple views, but also multi-player mode with one X11 client connected to several X11 servers at once (which is rightfully considered a terribly unsafe practice these days), so several people could actually be drawing at once, and you don't want to get their tracking state mixed up! The Python/Flash networked version supported multiple views and users via multiple independent "Sessions" attached to the same simulator, and all the tracking state (like the last tile position to draw from) stayed on the client side.)

Nowadays it's second nature for user interface views to encapsulate all of the mouse tracking state, but the original SimCity code (and the original TCL/Tk UI tracking code) just had lots and lots of global variables! So all the mouse tracking and tool drawing stuff needed to be abstracted and implemented in a higher level platform specific layer, instead of inside MicropolisCore.