Shift
The Shift value will perform a right bit-shift for the number of places specified. For example, to shift the value 4 places to the right (dividing by 16), you would enter 4. If you need to bit-shift to the left (highly unusual), specify a negative value.
Why on earth would you want to do this? The most logical way to store maps in games is to create an array of the tile numbers. For example, a small 5 by 4 map might look like this:
$11, $12, $13, $14, $15
$21, $22, $23, $24, $25
$31, $32, $33, $34, $35
$41, $42, $43, $44, $45
Each entry in the array refers to a single tile, so the top row of the map contains tile number $11, then $12, $13, $14 and $15. When the game has to draw the screen, it will look up the tile, and then have to locate the tile graphics in memory.
If each tile is 16x16 pixels in size and stored as 4 bitplanes (16 colours), then each tile would occupy 2 bytes x 16 pixels high x 4 planes = 128 bytes. The game knows where the tile graphics are located, so it has to take each tile number and multiply it by 128 to find the correct graphics for that tile:
_GetTileGfx lea _MapData(pc),a0 ;a0 = Map lea _TileGfx(pc),a1 ;a1 = Tile graphics move.w (a0)+,d0 ;Read tile index into d0 mulu #128,d0 ;Multiply by 128 to get offset
Multiplication is very slow on the 68000 chip. This can be sped up by using bit-shifting if the number is a power of 2. In this case, a shift of 7 to the left will give the same number, but is much faster:
_FasterTileGfx lea _MapData(pc),a0 ;a0 = Map lea _TileGfx(pc),a1 ;a1 = Tile graphics move.w (a0)+,d0 ;Read tile index into d0 lsl.w #7,d0 ;Faster multiply by 128 to get offset
But even bit-shifting is slow on the 68000, and it takes longer for every bit shift. Thus a bit-shift of 5 will be slower than a bit-shift of 4. The best solution is to store the map indexes pre-multiplied by 128, or if you don't have spare bits for that, at least bit-shift as many places as possible. The optimal routine would be removing the shift altogether:
_FastestTileGfx lea _MapData(pc),a0 ;a0 = Map lea _TileGfx(pc),a1 ;a1 = Tile graphics move.w (a0)+,d0 ;Read tile graphics offset into d0
If you are having to plot hundreds of tiles every frame, this optimisation can make the difference between a fast or slow frame rate.
This does pose a problem for map ripping however! If you are expecting to find the values $11, $12, $13, $14 and $15 in memory, you might find they are actually stored as $880, $900, $980, $a00 and $a80!
The program comes with a sophisticated map search function that will attempt to calculate the correct Mask and Shift values automatically.
When it comes time to display the map, you need to reverse the bit-shifting that has already taken place, otherwise the wrong tiles will be drawn. This is where the Shift value is useful. In this example, if we specify 7 as the Shift value, each tile index will be shifted right 7 times (dividing by 128) and giving the correct tile index. The first tile would be read from memory ($880), shifted right 7 times to give $11, which is the actual tile number.
You may enjoy these articles...
If you look inside many Amiga games, secret messages have been hidden by the programmers. Richard Aplin was the king of hiding messages in the startup-sequence file, and his Line of Fire and Final Fight startup-sequences have become legendary! The Sensible Software team were also prolific at hiding messages in their games.
A collection of technical interviews with Amiga programmers that worked on commercial software in the glory days of the Amiga (late 1980s to early 1990s!)
The Ultimate Amiga Graphics, Level and Map Ripper!
A random assortment of rants relating to the Amiga!
An explanation of how many famous Amiga games utilised sprites in weird and interesting ways
Post your comment
Comments
No one has commented on this page yet.
RSS feed for comments on this page | RSS feed for all comments