Amiga Game Databases
Music
- Exotica
- Stone Oakvalley's Authentic SID Collection (SOASC=)
- Stone Oakvalley's Amiga Music Collection (SOAMC=)
Miscellaneous
Turrican 2
Rainbow Arts programmer Thomas Engel converted the Amiga version of Turrican 2 to the Atari ST, and did an amazing job considering the lack of hardware scrolling on the ST. To achieve the smooth scrolling, a number of compromises were made to keep the game running at a fair clip. The most obvious changes:
- Game area reduced from 304x192 pixels on the Amiga down to 288x144 pixels for the ST.
- Frame rate halved from 50 frames per second on the Amiga to 25 on the ST.
- Score panel size increased on the ST to fill some of the blank space, and life counter and score overlays moved into it.
Level maps
On the Amiga, each tile in the map is 32x32 pixels, and is drawn in 16 colours. These 32x32 blocks are then combined in a large map that is a series of bytes stored in vertical strips that becomes the map. The first level for the game is 163 blocks wide x 51 blocks tall.
On the Atari ST, 2 maps are used. Each tile is now 16x16 pixels in size, and the tile graphics are only stored once in memory — there are no pre-shifted combinations to speed up the drawing process. World 1-1 contains 290 of these 16x16 tiles:
A second map is used to place the tiles in a 2x2 table to form tiles that are now 32x32 pixels in size, and there are 197 of these tiles on world 1-1 (which is the same as the Amiga):
The game uses the 163x51 map to lookup each tile in the relevant 2x2 block to work out which tile needs to be placed onto the map. This forms the complete level:
The tiles on the ST are similar to the Amiga versions, but not identical. This is because the Amiga artist had the freedom to draw anything in each tile, but the ST was limited to a certain number of 16x16 tiles. Therefore, many tiles were re-used to reduce the number of them. You can see the differences in this animation:
Graphics
Each of the animated graphics in the ST version are stored 4 times in memory, along with a 1 bitplane mask before each graphical object that indicates which pixels should overwrite the background. Each object moves sideways in increments of 4 pixels. Here is a small selection of the graphics from the ST version as they exist in memory:
Bosses
Turrican 2 is famous for its bosses that can appear at any point during a level. Because of all the graphical combinations in memory, there isn't space on a 512k ST to store all the bosses, so these are loaded from disk prior to appearing. The boss graphics overwrite some unnecessary graphics, such as the waterfall animations on world 1-1. Once the boss is defeated, the game re-loads the graphics that were previously overwritten.
Like the other objects, there are 4 combinations of each and they are broken down into smaller pieces to save memory:
Background buffers
The game stores 4 copies of the backgrounds in a similar way to how the Amiga handles an "infinite scroll" cylindrical wrap. Each buffer is the same size as the gameplay window (288 pixels wide by 144 pixels high), and contains a different 4-pixel indented version of the gameplay area.
The most important thing to note is that the top left corner of the buffers do not correspond with the top left corner of the visible screen. They simply contain all the graphical tiles for the screen, and a later routine copies the tiles into the correct order to build the display.
The scrolling routine is as follows:
- When the game scrolls the screen sideways (by 4 pixels), the relevant indented buffer is updated with a vertical column of 16x16 tiles copied into it.
- When the game scrolls the screen vertically (by 8 pixels), the game copies a complete horizontal strip (288x8) into all 4 buffers. This obviously takes a lot longer than the horizontal scrolling because it's having to move more data around.
The easiest way to see what's happening is to view an animated sequence showing the 4 buffers changing as the player moves around the map. In this sequence, the player jumps upwards and to the right before landing, then moving to the right.
Double-buffered display
The game also uses two screen buffers 320x180 in size, preparing the next frame while the previous is being displayed. The graphics are copied from one of the 4 indented buffers, then any animated objects (such as the player, enemies and bullets) are drawn over the top.
Tile merging routine
The main routine that fills the 4 buffers has to continually merge 2 tiles together, working on 8 pixel high blocks at a time. This is because the minimum the game scrolls vertically at a time is 8 pixels. The 4 combinations are:
- Copy the entire 8 pixels high from one tile.
- Copy 4 pixels from the first tile, and 12 pixels from the second.
- Copy 8 pixels from each tile.
- Copy 12 pixels from the first tile, and 4 pixels from the second.
One of the four display updates will be copying an entire tile, so a more efficient routine could have been used in that case. However, the same routine is used in all cases. When the routine is called, register d6 contains the number of pixels to indent the tile graphics, either 0, 4, 8 or 12. The same chunk of code is inlined 8 times, but it's pretty much identical so I've cut out 5 of the loops. The code looks like this:
_a854 movem.w (a1)+,d0-d3 ;Read right tile line 1 graphics into d0-d3 swap d0 ;Bitplane 1 into high word swap d1 ;Bitplane 2 into high word swap d2 ;Bitplane 3 into high word swap d3 ;Bitplane 4 into high word move.w (a0)+,d0 ;Read left tile bitplane 1 graphics to low word of d0 move.w (a0)+,d1 ;Read left tile bitplane 2 graphics to low word of d1 move.w (a0)+,d2 ;Read left tile bitplane 3 graphics to low word of d2 move.w (a0)+,d3 ;Read left tile bitplane 4 graphics to low word of d3 rol.l d6,d0 ;Rotate bitplane 1 data to merge the tiles rol.l d6,d1 ;Rotate bitplane 2 data to merge the tiles rol.l d6,d2 ;Rotate bitplane 3 data to merge the tiles rol.l d6,d3 ;Rotate bitplane 4 data to merge the tiles movem.w d0-d3,(a2) ;Write the merged line 1 graphics into buffer movem.w (a1)+,d0-d3 ;Read right tile line 2 graphics into d0-d3 swap d0 ;Bitplane 1 into high word swap d1 ;Bitplane 2 into high word swap d2 ;Bitplane 3 into high word swap d3 ;Bitplane 4 into high word move.w (a0)+,d0 ;Read left tile bitplane 1 graphics to low word of d0 move.w (a0)+,d1 ;Read left tile bitplane 2 graphics to low word of d1 move.w (a0)+,d2 ;Read left tile bitplane 3 graphics to low word of d2 move.w (a0)+,d3 ;Read left tile bitplane 4 graphics to low word of d3 rol.l d6,d0 ;Rotate bitplane 1 data to merge the tiles rol.l d6,d1 ;Rotate bitplane 2 data to merge the tiles rol.l d6,d2 ;Rotate bitplane 3 data to merge the tiles rol.l d6,d3 ;Rotate bitplane 4 data to merge the tiles movem.w d0-d3,$90(a2) ;Write the merged line 2 graphics into buffer ... repeat another 5 times ... movem.w (a1)+,d0-d3 ;Read right tile line 8 graphics into d0-d3 swap d0 ;Bitplane 1 into high word swap d1 ;Bitplane 2 into high word swap d2 ;Bitplane 3 into high word swap d3 ;Bitplane 4 into high word move.w (a0)+,d0 ;Read left tile bitplane 1 graphics to low word of d0 move.w (a0)+,d1 ;Read left tile bitplane 2 graphics to low word of d1 move.w (a0)+,d2 ;Read left tile bitplane 3 graphics to low word of d2 move.w (a0)+,d3 ;Read left tile bitplane 4 graphics to low word of d3 rol.l d6,d0 ;Rotate bitplane 1 data to merge the tiles rol.l d6,d1 ;Rotate bitplane 2 data to merge the tiles rol.l d6,d2 ;Rotate bitplane 3 data to merge the tiles rol.l d6,d3 ;Rotate bitplane 4 data to merge the tiles movem.w d0-d3,$3f0(a2) ;Write the merged line 8 graphics into buffer
At this point, the game does some magic and works out whether it can continue copying another 8 pixels high into the buffer, or has to switch to copying new tiles. And if the game scrolled vertically, it has to do extra work again. This extra code is beyond the scope of this analysis, but if you wish to disassemble the game yourself, have a look around $a854.
Now the buffer is complete, the final step is to copy the buffer as fast as possible into the screen display, which erases the previous frame and all objects on it. Then the game can plot animated tiles, the player, enemies and bullets. The routine is at $ba00.
Any suggestions?
If you have any idea what should go in this box, please let me know! :)
Post your comment
Comments
No one has commented on this page yet.
RSS feed for comments on this page | RSS feed for all comments