Videokid
If you were a developer in the early 1990s and forced to create a game for the Amiga and Atari ST, you had 3 main options:
- Hire a separate Amiga and Atari ST programmer so you could get the best out of each platform (the Special FX method)
- Develop 16 colour games, use the Atari ST code on the Amiga and only change the music (the Tiertex technique)
- Enhance the game a little on the Amiga by making some of the static screens 32 colours and a few sprite tricks.
Twilight opted for the 3rd option, and given the deadlines, they did a pretty good job. The title screen on the Amiga has been enhanced to show 32 colours, and has a much improved palette compared to the Atari ST version:
Programmer Stuart Cook decided to enhance the Amiga version with a full screen parallax layer using 6 multiplexed sprites. The remaining 2 sprites are used elsewhere by the game. All levels use this technique, and I have extracted the 6 background sprites from the second level of the game, the "Wild West" level.
The 6 sprites form a repeating background pattern of 96 pixels wide by 176 pixels tall. The sprites are mutiplexed 3 times across to give a sprite layer of 288 pixels wide by 176 pixels tall.
The game stores 8 copies of the background pattern in memory, using up 40k of chip memory. It uses the same trick as Risky Woods, adjusting the sprite control words of the 6 background sprites to shift them all by a single pixel. Because the display is smaller than the sprite pattern (286 pixels vs 288 for the sprites), this single pixel shift is never seen. When the sprite pattern needs to scroll by 2 pixels, the game switches to a different set of the sprites. Without this trick, 16 copies of the background would have been required, and wasting another 40k of memory..
The full set of sprites in memory looks like this:
All levels use this technique, and you can see the difference this simple trick makes to the game visuals. The Amiga version looks infinitely better than the Atari ST version, has a bigger play area, features a parallax layer, scrolls twice as smoothly and has more colours:
The first 2 sprites were not used at the exact spot in the game that I took the snapshot, hence why those are not shown on the screen, but the sprite assignments are as follows:
The game begins by setting up the copperlist to display a 4 bitplane screen, and setting the modulos:
Chip Addr: Copper instructions ; Comments -------------------------------------------------- $00017882: 00E0 0000 00E2 469C ; BPL1PT = 0x0000469C $0001788A: 00E4 0000 00E6 46CA ; BPL2PT = 0x000046CA $00017892: 00E8 0000 00EA 46F8 ; BPL3PT = 0x000046F8 $0001789A: 00EC 0000 00EE 4726 ; BPL4PT = 0x00004726 $000178A2: 0100 4200 ; BPLCON0 = 0x4200 $000178A6: 0108 0092 ; BPL1MOD = 0x0092 $000178AA: 010A 0092 ; BPL2MOD = 0x0092
All 8 sprites are then setup:
Chip Addr: Copper instructions ; Comments -------------------------------------------------- $000178AE: 0120 0005 0122 6E86 ; SPR0PT = 0x00056E86 $000178B6: 0124 0005 0126 6F2A ; SPR1PT = 0x00056F2A $000178BE: 0128 0005 012A 5B8E ; SPR2PT = 0x00055B8E $000178C6: 012C 0005 012E 5ED6 ; SPR3PT = 0x00055ED6 $000178CE: 0130 0005 0132 621E ; SPR4PT = 0x0005621E $000178D6: 0134 0005 0136 6566 ; SPR5PT = 0x00056566 $000178DE: 0138 0005 013A 68AE ; SPR6PT = 0x000568AE $000178E6: 013C 0005 013E 5846 ; SPR7PT = 0x00055846
Then the palette is setup. Note that the 4 sprite colours (black followed by the light purples) are repeated 3 times in the palette, so that final 12 colours use identical colours. This is because each sprite pair on the Amiga uses a different set of colours, so they have to be the same:
Chip Addr: Copper instructions ; Comments -------------------------------------------------- $000178EE: 0182 0404 ; COLOR01 = 0x0404 $000178F2: 0182 0028 ; COLOR01 = 0x0028 $000178F6: 0184 004C ; COLOR02 = 0x004C $000178FA: 0186 00AE ; COLOR03 = 0x00AE $000178FE: 0188 0040 ; COLOR04 = 0x0040 $00017902: 018A 0080 ; COLOR05 = 0x0080 $00017906: 018C 00E0 ; COLOR06 = 0x00E0 $0001790A: 018E 0420 ; COLOR07 = 0x0420 $0001790E: 0190 0840 ; COLOR08 = 0x0840 $00017912: 0192 0C60 ; COLOR09 = 0x0C60 $00017916: 0194 0224 ; COLOR10 = 0x0224 $0001791A: 0196 0EA0 ; COLOR11 = 0x0EA0 $0001791E: 0198 0446 ; COLOR12 = 0x0446 $00017922: 019A 088A ; COLOR13 = 0x088A $00017926: 019C 0000 ; COLOR14 = 0x0000 $0001792A: 019E 0EEE ; COLOR15 = 0x0EEE $0001792E: 01A0 0000 ; COLOR16 = 0x0000 $00017932: 01A2 0550 ; COLOR17 = 0x0550 $00017936: 01A4 0690 ; COLOR18 = 0x0690 $0001793A: 01A6 07D0 ; COLOR19 = 0x07D0 $0001793E: 01A8 0000 ; COLOR20 = 0x0000 $00017942: 01AA 0B7F ; COLOR21 = 0x0B7F $00017946: 01AC 0C8F ; COLOR22 = 0x0C8F $0001794A: 01AE 0D9F ; COLOR23 = 0x0D9F $0001794E: 01B0 0000 ; COLOR24 = 0x0000 $00017952: 01B2 0B7F ; COLOR25 = 0x0B7F $00017956: 01B4 0C8F ; COLOR26 = 0x0C8F $0001795A: 01B6 0D9F ; COLOR27 = 0x0D9F $0001795E: 01B8 0000 ; COLOR28 = 0x0000 $00017962: 01BA 0B7F ; COLOR29 = 0x0B7F $00017966: 01BC 0C8F ; COLOR30 = 0x0C8F $0001796A: 01BE 0D9F ; COLOR31 = 0x0D9F
The next part sets up the display settings and smooth scroll:
Chip Addr: Copper instructions ; Comments -------------------------------------------------- $0001796E: 0102 0077 ; BPLCON1 = 0x0077 $00017972: 0104 0008 ; BPLCON2 = 0x0008
The sprites are multiplexed across the screen on every line by displaying and repositioning each sprite 3 times per line, giving a 288 pixel wide background pattern:
Chip Addr: Copper instructions ; Comments -------------------------------------------------- $00017976: 3A41 FFFE ; Wait for vpos >= 0x3A and hpos >= 0x40 $0001797A: 0150 3648 ; SPR2POS = 0x3648 $0001797E: 0158 3650 ; SPR3POS = 0x3650 $00017982: 0160 3658 ; SPR4POS = 0x3658 $00017986: 0168 3660 ; SPR5POS = 0x3660 $0001798A: 0170 3668 ; SPR6POS = 0x3668 $0001798E: 0178 3670 ; SPR7POS = 0x3670 $00017992: 0150 3678 ; SPR2POS = 0x3678 $00017996: 0158 3680 ; SPR3POS = 0x3680 $0001799A: 0160 3688 ; SPR4POS = 0x3688 $0001799E: 3A89 FFFE ; Wait for vpos >= 0x3A and hpos >= 0x88 $000179A2: 0168 3690 ; SPR5POS = 0x3690 $000179A6: 0170 3698 ; SPR6POS = 0x3698 $000179AA: 0178 36A0 ; SPR7POS = 0x36A0 $000179AE: 0150 36A8 ; SPR2POS = 0x36A8 $000179B2: 0158 36B0 ; SPR3POS = 0x36B0 $000179B6: 0160 36B8 ; SPR4POS = 0x36B8 $000179BA: 0168 36C0 ; SPR5POS = 0x36C0 $000179BE: 0170 36C8 ; SPR6POS = 0x36C8 $000179C2: 0178 36D0 ; SPR7POS = 0x36D0
This same section is then repeated for each line of the display, altering the vertical wait position by 1 pixel each time.
Chip Addr: Copper instructions ; Comments -------------------------------------------------- $000179C6: 3B41 FFFE ; Wait for vpos >= 0x3B and hpos >= 0x40 $000179CA: 0150 3648 ; SPR2POS = 0x3648 $000179CE: 0158 3650 ; SPR3POS = 0x3650 $000179D2: 0160 3658 ; SPR4POS = 0x3658 $000179D6: 0168 3660 ; SPR5POS = 0x3660 $000179DA: 0170 3668 ; SPR6POS = 0x3668 $000179DE: 0178 3670 ; SPR7POS = 0x3670 $000179E2: 0150 3678 ; SPR2POS = 0x3678 $000179E6: 0158 3680 ; SPR3POS = 0x3680 $000179EA: 0160 3688 ; SPR4POS = 0x3688 $000179EE: 3B89 FFFE ; Wait for vpos >= 0x3B and hpos >= 0x88 $000179F2: 0168 3690 ; SPR5POS = 0x3690 $000179F6: 0170 3698 ; SPR6POS = 0x3698 $000179FA: 0178 36A0 ; SPR7POS = 0x36A0 $000179FE: 0150 36A8 ; SPR2POS = 0x36A8 $00017A02: 0158 36B0 ; SPR3POS = 0x36B0 $00017A06: 0160 36B8 ; SPR4POS = 0x36B8 $00017A0A: 0168 36C0 ; SPR5POS = 0x36C0 $00017A0E: 0170 36C8 ; SPR6POS = 0x36C8 $00017A12: 0178 36D0 ; SPR7POS = 0x36D0
The main game display is 176 pixels tall, so there are 176 sets of these copperlist moves. The final set (after waiting for vertical position $e9) immediately switches in different sprites for the status panel at the bottom of the screen and turns off the display:
Chip Addr: Copper instructions ; Comments -------------------------------------------------- $0001B026: E941 FFFE ; Wait for vpos >= 0xE9 and hpos >= 0x40 $0001B02A: 0150 3648 ; SPR2POS = 0x3648 $0001B02E: 0158 3650 ; SPR3POS = 0x3650 $0001B032: 0160 3658 ; SPR4POS = 0x3658 $0001B036: 0168 3660 ; SPR5POS = 0x3660 $0001B03A: 0170 3668 ; SPR6POS = 0x3668 $0001B03E: 0178 3670 ; SPR7POS = 0x3670 $0001B042: 0150 3678 ; SPR2POS = 0x3678 $0001B046: 0158 3680 ; SPR3POS = 0x3680 $0001B04A: 0160 3688 ; SPR4POS = 0x3688 $0001B04E: E989 FFFE ; Wait for vpos >= 0xE9 and hpos >= 0x88 $0001B052: 0168 3690 ; SPR5POS = 0x3690 $0001B056: 0170 3698 ; SPR6POS = 0x3698 $0001B05A: 0178 36A0 ; SPR7POS = 0x36A0 $0001B05E: 0150 36A8 ; SPR2POS = 0x36A8 $0001B062: 0158 36B0 ; SPR3POS = 0x36B0 $0001B066: 0160 36B8 ; SPR4POS = 0x36B8 $0001B06A: 0168 36C0 ; SPR5POS = 0x36C0 $0001B06E: 0170 36C8 ; SPR6POS = 0x36C8 $0001B072: 0178 36D0 ; SPR7POS = 0x36D0 $0001B076: E9BF FFFE ; Wait for vpos >= 0xE9 and hpos >= 0xBE $0001B07A: 0128 0001 012A C1D6 ; SPR2PT = 0x0001C1D6 $0001B082: 012C 0001 012E C1FE ; SPR3PT = 0x0001C1FE $0001B08A: 0130 0001 0132 C226 ; SPR4PT = 0x0001C226 $0001B092: 0134 0001 0136 C24E ; SPR5PT = 0x0001C24E $0001B09A: 0138 0001 013A C276 ; SPR6PT = 0x0001C276 $0001B0A2: 013C 0001 013E C29E ; SPR7PT = 0x0001C29E $0001B0AA: EA01 FFFE ; Wait for vpos >= 0xEA and hpos >= 0x00 $0001B0AE: 0100 0200 ; BPLCON0 = 0x0200
Now the game switches the display to a small 16 colour status panel with a different palette. Sprites are used for the digits of the score and are overlaid on the status panel.
Chip Addr: Copper instructions ; Comments -------------------------------------------------- $0001B0B2: EB01 FFFE ; Wait for vpos >= 0xEB and hpos >= 0x00 $0001B0B6: 00E0 0005 00E2 715E ; BPL1PT = 0x0005715E $0001B0BE: 00E4 0005 00E6 7184 ; BPL2PT = 0x00057184 $0001B0C6: 00E8 0005 00EA 71AA ; BPL3PT = 0x000571AA $0001B0CE: 00EC 0005 00EE 71D0 ; BPL4PT = 0x000571D0 $0001B0D6: 0100 4200 ; BPLCON0 = 0x4200 $0001B0DA: 0102 0000 ; BPLCON1 = 0x0000 $0001B0DE: 0108 0072 ; BPL1MOD = 0x0072 $0001B0E2: 010A 0072 ; BPL2MOD = 0x0072 $0001B0E6: 0104 0020 ; BPLCON2 = 0x0020 $0001B0EA: 0104 0000 ; BPLCON2 = 0x0000 $0001B0EE: 0182 0000 ; COLOR01 = 0x0000 $0001B0F2: 0182 0048 ; COLOR01 = 0x0048 $0001B0F6: 0184 006C ; COLOR02 = 0x006C $0001B0FA: 0186 008E ; COLOR03 = 0x008E $0001B0FE: 0188 0060 ; COLOR04 = 0x0060 $0001B102: 018A 00A0 ; COLOR05 = 0x00A0 $0001B106: 018C 00E0 ; COLOR06 = 0x00E0 $0001B10A: 018E 0620 ; COLOR07 = 0x0620 $0001B10E: 0190 00F0 ; COLOR08 = 0x00F0 $0001B112: 0192 0C80 ; COLOR09 = 0x0C80 $0001B116: 0194 00AE ; COLOR10 = 0x00AE $0001B11A: 0196 0EC0 ; COLOR11 = 0x0EC0 $0001B11E: 0198 00EE ; COLOR12 = 0x00EE $0001B122: 019A 00AA ; COLOR13 = 0x00AA $0001B126: 019C 0840 ; COLOR14 = 0x0840 $0001B12A: 019E 0EEE ; COLOR15 = 0x0EEE $0001B12E: 01A8 0000 ; COLOR20 = 0x0000 $0001B132: 01AA 0E00 ; COLOR21 = 0x0E00 $0001B136: 01AC 0600 ; COLOR22 = 0x0600 $0001B13A: 01AE 0A00 ; COLOR23 = 0x0A00 $0001B13E: 01B0 0000 ; COLOR24 = 0x0000 $0001B142: 01B2 0E00 ; COLOR25 = 0x0E00 $0001B146: 01B4 0600 ; COLOR26 = 0x0600 $0001B14A: 01B6 0A00 ; COLOR27 = 0x0A00 $0001B14E: 01B8 0000 ; COLOR28 = 0x0000 $0001B152: 01BA 0E0E ; COLOR29 = 0x0E0E $0001B156: 01BC 0606 ; COLOR30 = 0x0606 $0001B15A: 01BE 0A0A ; COLOR31 = 0x0A0A $0001B15E: F801 FFFE ; Wait for vpos >= 0xF8 and hpos >= 0x00 $0001B162: 009C 8010 ; INTREQ = 0x8010 $0001B166: ffff fffe ; End of copperlist $0001B166: FFFF FFFE ; Wait for vpos >= 0xFF and hpos >= 0xFE
Popular Sprite Tricks
2 sprites are displayed then repositioned horizontally right across the screen to create the colourful static background. The remaining sprites are used for the main character, the status bar and player bullets.
The 16-colour background layer was created by using all 8 hardware sprites and repositioning them across the screen. The same 64 pixel wide graphics are repeated across the entire play area.
One of the first jaw-droppingly beautiful Amiga games that still looks great today. Sprites were heavily re-used on the screen, along with priority changes to make them appear between the playfields.
The amazing tunnel sequence was created with a 6 frame animation sequence made with only 4 colours and mirrored vertically. The asteroid layer sits on top of this, with a status panel and player ship made of sprites sitting on top.
Post your comment
Comments
Good points here. More or less what we're doing for rygar!
Well put
sandro sabene 27/10/2016 7:15am (8 years ago)
No one has commented on this page yet.
RSS feed for comments on this page | RSS feed for all comments