Codetapper's Amiga Site

R-Type 2

R-Type 2 uses the Amiga sprites to create a 64 pixel wide repeating pattern for the backgrounds on most levels. If sprites are disabled, the game looks almost identical to the Atari ST version. First up, here is midway through level 1 with sprites enabled on the left, and disabled on the right:

Level 1 with sprites enabled

Level 1 with sprites disabled

When sprites are disabled, you just see black pixels in the Bydo base.

Interestingly, at the start of the level sprites are not enabled at all, but when you approach the Bydo base, the sprite playfield will suddenly appear, covering the entire screen:

Start of level 1 with bitplane DMA disabled

Midway level 1 with bitplane DMA disabled

Curiously enough, the sprite layer scrolls onto the screen at the same speed as the background until the sprite layer completely covers the screen, then moves at half the speed to give a parallax effect. Have a look at approximately 1 minute 18 seconds in the following longplay to see the effect:

[フレーム]

By examining memory, we can extract the sprites used for the pattern:

[画像:R-Type 2 16 pixel wide sprites]

Those with a keen eye might be able to see that the pattern repeats every 64 pixels. Displaying them in blocks of 64 pixels shows each combination:

[画像:R-Type 2 64 pixel wide strips]

Only a selection is shown here, the full image is actually 1024 pixels across x 192 pixels high, which uses up 50kb of chip memory. Because there are 16 different indent levels to give pixel accurate scrolling, 64 pixels wide x 16 increments = 1024 pixels width required.

Amiga sprites are 16 pixels wide so 4 of them are required to draw a vertical strip of the background. Because each pair of sprites have their own colour palette, the game duplicates the sprite colours for all 4 sprite pairs:

[画像:R-Type 2 palette]

Because the background pattern is 64 pixels wide, the game could multiplex the 4 sprites completely across the screen and only require 4 sprites. That would free up the remaining sprites for something else. For whatever reason, programmer Tim Round decided to multiplex all 8 across.

The Copperlist

The copperlist begins by setting up all 8 sprite pointers. Note that sprite 4 is set to the same address as sprite 0, ditto with 5 and 1, 6 and 2, and 7 and 3:

Chip Addr: Copper instructions ; Comments
--------------------------------------------------
00010378ドル: 0096 87E0 ; DMACON = 0x87E0
0001037ドルC: 0120 0006 0122 3610 ; SPR0PT = 0x00063610
00010384ドル: 0124 0006 0126 3918 ; SPR1PT = 0x00063918
0001038ドルC: 0128 0006 012A 3000 ; SPR2PT = 0x00063000
00010394ドル: 012C 0006 012E 3308 ; SPR3PT = 0x00063308
0001039ドルC: 0130 0006 0132 3610 ; SPR4PT = 0x00063610
000103ドルA4: 0134 0006 0136 3918 ; SPR5PT = 0x00063918
000103ドルAC: 0138 0006 013A 3000 ; SPR6PT = 0x00063000
000103ドルB4: 013C 0006 013E 3308 ; SPR7PT = 0x00063308

Now the game sets up the display properties, the bitplane pointers and the entire colour palette:

000103ドルBC: 0092 0038 ; DDFSTRT = 0x0038
000103ドルC0: 0094 00C8 ; DDFSTOP = 0x00C8
000103ドルC4: 008E 3F91 ; DIWSTRT = 0x3F91
000103ドルC8: 0090 0FB1 ; DIWSTOP = 0x0FB1
000103ドルCC: 3D09 FFFE ; Wait for vpos >= 0x3D and hpos >= 0x08
000103ドルD0: 0100 4200 ; BPLCON0 = 0x4200
000103ドルD4: 0102 00FF ; BPLCON1 = 0x00FF
000103ドルD8: 0104 0000 ; BPLCON2 = 0x0000
000103ドルDC: 0108 007A ; BPL1MOD = 0x007A
000103ドルE0: 010A 007A ; BPL2MOD = 0x007A
000103ドルE4: 00E0 0007 00E2 7400 ; BPL1PT = 0x00077400
000103ドルEC: 00E4 0007 00E6 7428 ; BPL2PT = 0x00077428
000103ドルF4: 00E8 0007 00EA 7450 ; BPL3PT = 0x00077450
000103ドルFC: 00EC 0007 00EE 7478 ; BPL4PT = 0x00077478
00010404ドル: 0180 0000 ; COLOR00 = 0x0000 - Transparent colour
00010408ドル: 0182 0A74 ; COLOR01 = 0x0A74
0001040ドルC: 0184 0CA7 ; COLOR02 = 0x0CA7
00010410ドル: 0186 0CB9 ; COLOR03 = 0x0CB9
00010414ドル: 0188 0EDB ; COLOR04 = 0x0EDB
00010418ドル: 018A 0666 ; COLOR05 = 0x0666
0001041ドルC: 018C 0AAA ; COLOR06 = 0x0AAA
00010420ドル: 018E 0DDD ; COLOR07 = 0x0DDD
00010424ドル: 0190 0000 ; COLOR08 = 0x0000
00010428ドル: 0192 00DF ; COLOR09 = 0x00DF
0001042ドルC: 0194 005F ; COLOR10 = 0x005F
00010430ドル: 0196 0C00 ; COLOR11 = 0x0C00
00010434ドル: 0198 0FB0 ; COLOR12 = 0x0FB0
00010438ドル: 019A 0080 ; COLOR13 = 0x0080
0001043ドルC: 019C 0D06 ; COLOR14 = 0x0D06
00010440ドル: 019E 0FFF ; COLOR15 = 0x0FFF
00010444ドル: 01A0 0000 ; COLOR16 = 0x0000 - Sprite 0 and 1 colours
00010448ドル: 01A2 0653 ; COLOR17 = 0x0653
0001044ドルC: 01A4 0774 ; COLOR18 = 0x0774
00010450ドル: 01A6 0996 ; COLOR19 = 0x0996
00010454ドル: 01A8 0000 ; COLOR20 = 0x0000 - Sprite 2 and 3 colours
00010458ドル: 01AA 0653 ; COLOR21 = 0x0653
0001045ドルC: 01AC 0774 ; COLOR22 = 0x0774
00010460ドル: 01AE 0996 ; COLOR23 = 0x0996
00010464ドル: 01B0 0000 ; COLOR24 = 0x0000 - Sprite 4 and 5 colours
00010468ドル: 01B2 0653 ; COLOR25 = 0x0653
0001046ドルC: 01B4 0774 ; COLOR26 = 0x0774
00010470ドル: 01B6 0996 ; COLOR27 = 0x0996
00010474ドル: 01B8 0000 ; COLOR28 = 0x0000 - Sprite 6 and 7 colours
00010478ドル: 01BA 0653 ; COLOR29 = 0x0653
0001047ドルC: 01BC 0774 ; COLOR30 = 0x0774
00010480ドル: 01BE 0996 ; COLOR31 = 0x0996

Now for a small trick which explains how the sprites are turned off at the start of the level but instantly appear! At the start of the level, the 1st copper pointer is set to address 146ドルd4, which happens to skip the entire sprite display section! The copperlist becomes active by strobing the jump address:

00010484ドル: 0080 0001 0082 46D4 ; COP1LC = 0x000146D4
0001048ドルC: 0084 00FF ; COPJMP1 = 0x00FF - Copper jumps to 146ドルd4

When the sprite layer is required, the game alters the word at 1048ドルc, inserting a no-operation instruction instead:

00010484ドル: 0080 0001 0082 46D4 ; COP1LC = 0x000146D4
0001048ドルC: 01FE 00FF ; NO-OP = 0x00FF - Copper continues to next instruction

Now the horizontal sprite multiplexing trick is setup on every line of the display. All 8 sprites are positioned 16 pixels from each other, giving an initial width of 128 pixels.

00010490ドル: 0140 3F48 ; SPR0POS = 0x3F48
00010494ドル: 0148 3F50 ; SPR1POS = 0x3F50
00010498ドル: 0150 3F58 ; SPR2POS = 0x3F58
0001049ドルC: 0158 3F60 ; SPR3POS = 0x3F60
000104ドルA0: 0160 3F68 ; SPR4POS = 0x3F68
000104ドルA4: 0168 3F70 ; SPR5POS = 0x3F70
000104ドルA8: 0170 3F78 ; SPR6POS = 0x3F78
000104ドルAC: 0178 3F80 ; SPR7POS = 0x3F80

The copper then waits for the beam to catch up to horizontal position 80,ドル then quickly shifts all the sprites across to their new locations (128 pixels from where they started):

000104ドルB0: 3F81 FFFE ; Wait for vpos >= 0x3F and hpos >= 0x80
000104ドルB4: 0140 3F88 ; SPR0POS = 0x3F88
000104ドルB8: 0148 3F90 ; SPR1POS = 0x3F90
000104ドルBC: 0150 3F98 ; SPR2POS = 0x3F98
000104ドルC0: 0158 3FA0 ; SPR3POS = 0x3FA0
000104ドルC4: 0160 3FA8 ; SPR4POS = 0x3FA8
000104ドルC8: 0168 3FB0 ; SPR5POS = 0x3FB0
000104ドルCC: 0170 3FB8 ; SPR6POS = 0x3FB8
000104ドルD0: 0178 3FC0 ; SPR7POS = 0x3FC0

The game has now displayed 256 pixels worth of sprites, but the display is 288 pixels wide, so two more sprites are required on each line. The game waits for the beam to reach position $c0 and repositions the final 2 sprites:

000104ドルD4: 3FB1 FFFE ; Wait for vpos >= 0x3F and hpos >= 0xB0
000104ドルD8: 3FC1 FFFE ; Wait for vpos >= 0x3F and hpos >= 0xC0
000104ドルDC: 01FE 0000 ; NO-OP = 0x0000
000104ドルE0: 0140 3FC8 ; SPR0POS = 0x3FC8
000104ドルE4: 0148 3FD0 ; SPR1POS = 0x3FD0

In actual fact, the wait at this location is completely unnecessary because by the time the 8 sprites above are repositioned, the beam will have already displayed the first 2 sprites, so they could be moved directly after the first 8!

As you can see, the next line is identical except for a different vertical location so I will not bother pasting the other 190 lines of the display:

000104ドルE8: 0140 4048 ; SPR0POS = 0x4048
000104ドルEC: 0148 4050 ; SPR1POS = 0x4050
000104ドルF0: 0150 4058 ; SPR2POS = 0x4058
000104ドルF4: 0158 4060 ; SPR3POS = 0x4060
000104ドルF8: 0160 4068 ; SPR4POS = 0x4068
000104ドルFC: 0168 4070 ; SPR5POS = 0x4070
00010500ドル: 0170 4078 ; SPR6POS = 0x4078
00010504ドル: 0178 4080 ; SPR7POS = 0x4080
00010508ドル: 4081 FFFE ; Wait for vpos >= 0x40 and hpos >= 0x80
0001050ドルC: 0140 4088 ; SPR0POS = 0x4088
00010510ドル: 0148 4090 ; SPR1POS = 0x4090
00010514ドル: 0150 4098 ; SPR2POS = 0x4098
00010518ドル: 0158 40A0 ; SPR3POS = 0x40A0
0001051ドルC: 0160 40A8 ; SPR4POS = 0x40A8
00010520ドル: 0168 40B0 ; SPR5POS = 0x40B0
00010524ドル: 0170 40B8 ; SPR6POS = 0x40B8
00010528ドル: 0178 40C0 ; SPR7POS = 0x40C0
0001052ドルC: 40B1 FFFE ; Wait for vpos >= 0x40 and hpos >= 0xB0
00010530ドル: 40C1 FFFE ; Wait for vpos >= 0x40 and hpos >= 0xC0
00010534ドル: 01FE 0000 ; NO-OP = 0x0000
00010538ドル: 0140 40C8 ; SPR0POS = 0x40C8
0001053ドルC: 0148 40D0 ; SPR1POS = 0x40D0

The final part of the copperlist sets up the score panel at the bottom of the screen by switching to different bitplane pointers, a new palette and then preparing for the next frame:

00014690ドル: FF09 FFFE ; Wait for vpos >= 0xFF and hpos >= 0x08
00014694ドル: 0102 0000 ; BPLCON1 = 0x0000
00014698ドル: 00E0 0007 00E2 F600 ; BPL1PT = 0x0007F600
000146ドルA0: 00E4 0007 00E6 F628 ; BPL2PT = 0x0007F628
000146ドルA8: 00E8 0007 00EA F650 ; BPL3PT = 0x0007F650
000146ドルB0: 00EC 0007 00EE F678 ; BPL4PT = 0x0007F678
000146ドルB8: 0709 FFFE ; Wait for vpos >= 0x07 and hpos >= 0x08
000146ドルBC: 0190 0FFF ; COLOR08 = 0x0FFF
000146ドルC0: 0182 0CFF ; COLOR01 = 0x0CFF
000146ドルC4: 0184 0CFF ; COLOR02 = 0x0CFF
000146ドルC8: 0080 0001 0082 0378 ; COP1LC = 0x00010378
000146ドルD0: FFFF FFFE ; Wait for vpos >= 0xFF and hpos >= 0xFE
 ; End of copperlist

At the start of the level when the sprites are disabled, the copper is pointed to 146ドルd4, which sets up a different display, again with a jump instruction swapping between a no-op to skip part of the code:

000146ドルd4: 0080 0001 0082 46f0 ; COP1LC := 0x000146f0 
000146ドルdc: 01fe 00ff ; NO-OP(NULL) := 0x00ff - Jump to 146ドルf0
000146ドルe0: 0096 0020 ; DMACON := 0x0020
000146ドルe4: 0080 0001 0082 4690 ; COP1LC := 0x00014690
000146ドルec: 0088 00ff ; COPJMP1 := 0x00ff - Jump to 14690ドル
000146ドルf0: 0096 0020 ; DMACON := 0x0020
000146ドルf4: ff09 fffe ; Wait for vpos >= 0xff and hpos >= 0x08
000146ドルf8: 0102 0000 ; BPLCON1 := 0x0000
000146ドルfc: 00e0 0007 ; BPL1PTH := 0x0007
00014700ドル: 00e2 f600 ; BPL1PTL := 0xf600
00014704ドル: 00e4 0007 ; BPL2PTH := 0x0007
00014708ドル: 00e6 f628 ; BPL2PTL := 0xf628
0001470ドルc: 00e8 0007 ; BPL3PTH := 0x0007
00014710ドル: 00ea f650 ; BPL3PTL := 0xf650
00014714ドル: 00ec 0007 ; BPL4PTH := 0x0007
00014718ドル: 00ee f678 ; BPL4PTL := 0xf678
0001471ドルc: 0182 0000 ; COLOR01 := 0x0000
00014720ドル: 0184 0000 ; COLOR02 := 0x0000
00014724ドル: 0186 0000 ; COLOR03 := 0x0000
00014728ドル: 0188 0000 ; COLOR04 := 0x0000
0001472ドルc: 018a 0000 ; COLOR05 := 0x0000
00014730ドル: 018c 0000 ; COLOR06 := 0x0000
00014734ドル: 018e 0000 ; COLOR07 := 0x0000
00014738ドル: 0190 0000 ; COLOR08 := 0x0000
0001473ドルc: 0192 0000 ; COLOR09 := 0x0000
00014740ドル: 0194 0000 ; COLOR10 := 0x0000
00014744ドル: 0196 0000 ; COLOR11 := 0x0000
00014748ドル: 0198 0000 ; COLOR12 := 0x0000
0001474ドルc: 019a 0000 ; COLOR13 := 0x0000
00014750ドル: 019c 0000 ; COLOR14 := 0x0000
00014754ドル: 019e 0000 ; COLOR15 := 0x0000
00014758ドル: 0080 0001 ; COP1LCH := 0x0001
0001475ドルc: 0082 0378 ; COP1LCL := 0x0378
00014760ドル: ffff fffe ; Wait for vpos >= 0xff and hpos >= 0xfe
 ; End of Copperlist

Popular Sprite Tricks

R-Type 2

Jim Power

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.

R-Type 2

Risky Woods

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.

R-Type 2

Shadow of the Beast

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.

R-Type 2

Stardust

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.

© 2016-2024 Codetapper! Hosting provided by Mythic-Beasts. See the Hosting Information page for more details.

AltStyle によって変換されたページ (->オリジナル) /