Avoid symlink attacks in tetris

It's better to use fstat() on an open()'d fd instead of stat() and open()
one after another on a path.
Optimise maps and animations

Since animations are a critical part of optimisation, we must properly
incorporate them with the map optimisation.

The map optimisation uses a private X/Y-based dirty marker translation into
the linear 'items' vector. It would only pollute the interface with unneeded
code so it is kept just inline.

We assume that a 'dirty' entry means that the corresponding tile must again
be put onto screen but the non-dirty ones do not (unless the drawn
map_region changes). This is as far as optimisation could go AFAICS - and
it's a lot for normal use!

By the way, improve error handling in the map loading function. I this
course I added a more descriptiv "out of range" error variant to distinguish
this error for coordinates and with tilesets. This is only a problem when
drawing maps. You can have "out of range" with, e.g. palettes, too, but it
is unambiguous there but not here.

Note that the laytest example does not work currently. The error must be
fixed in the layer subsystem.