Ticket #147: Fix `viewport.shake()`

- Now works with any size map.
- Will no longer actually "scroll" the map position.
- Always resets to original position when shaking completes.
- Simplified code.
- Now accepts `duration` argument in *milliseconds* instead of frame count.