Duplicate a hardware sprite

Do you live and breathe hexadecimal? Do you like speaking to hardware directly?

Moderator: Programming Moderators

Post Reply
namco
Posts: 6
Joined: Sun Aug 13, 2017 7:58 pm

Duplicate a hardware sprite

Post by namco » Tue Apr 03, 2018 12:46 pm

I'm wondering if it possible to duplicate a hardware sprite but to use the same sprite slot.

For example:
Sprite slot 0
x = 37
y = 37

Sprite slot 0 (copy on screen)
x = 37
y = 57

If I try the above all I get is the same sprite but moved to 37x57 rather than 2 sprites of the same sprite slot in 2 different locations.

If it isn't possible should I just copy the graphic for the sprite in slot 0 to another spare sprite slot?

User avatar
SevenFFF
Posts: 211
Joined: Mon Jun 05, 2017 5:30 pm
Location: USA

Re: Duplicate a hardware sprite

Post by SevenFFF » Tue Apr 03, 2018 12:55 pm

There are 64 patterns and 64 slots. You can reuse the same pattern number for two different slots to get what you want.

If you define the same slot with two different patterns or coordinates then you’ll just get the second one. The only way you could make this work is to use the raster interrupt to redefine the same slot back and forth between two different patterns and/or coordinates.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel Spectron 2084blog

namco
Posts: 6
Joined: Sun Aug 13, 2017 7:58 pm

Re: Duplicate a hardware sprite

Post by namco » Tue Apr 24, 2018 1:10 pm

Sorry for the late reply but I think I got it (your suggestion of 1 pattern, n slots).

Thanks.

User avatar
SevenFFF
Posts: 211
Joined: Mon Jun 05, 2017 5:30 pm
Location: USA

Re: Duplicate a hardware sprite

Post by SevenFFF » Tue Apr 24, 2018 3:23 pm

No problem.

This is an example from my code. The macro is in Zeus format, so you might have to tweak it, but you can see how the calculations are made. As you can see, the slot goes in the first byte written to port $57, and the pattern goes in the fourth byte written.

In this example, the sprite for digits "00" (pattern 16) gets written to two slots - slot 0 at coordinates (66, -18) for Player 1 score, and slot 1 at coordinates (168, -18) for Player 2 score.

For convenience, I have my macro set up so sprite coordinate (0, 0) is the same as ULA pixel (0, 0), meaning negative numbers are in the left/top borders. In reality, the coordinates start at the top left of the borders, so my macro adds 32 to each coordinate to get them in the right form.

Code: Select all

                        NextSprite(0,   66,    -18, 0,false, false, false, true, 16) ; Score Left
                        NextSprite(1,  168,    -18, 0,false, false, false, true, 16) ; Score Right
                        NextSprite(2,  111,    193, 0,false, false, false, true, 17) ; Credits A
                        NextSprite(3,  111+16, 193, 0,false, false, false, true, 18) ; Credits B
                        NextSprite(4,  111+32, 193, 0,false, false, false, true, 19) ; Credits C

NextSprite              macro(ID, u16X, u8Y, PaletteOffset, bMirrorX, bMirrorY, bRotate, bVisible, Pattern)
                        ; Port $303B, if written, defines the sprite slot to be configured by ports $57 and $5B,
                        ; and also initializes the address of the palette.
                        ; Port $57 is write-only and is used to send the attributes of the selected sprite slot,
                        ; being the address is auto-incremented each writing and after sending the 4 bytes of
                        ; attributes the address points to the next sprite. The description of each byte follows below:
                        ;   1st: X position (bits 7-0).
                        ;   2nd: Y position (0-255).
                        ;   3rd: bits 7-4 is palette offset, bit 3 is X mirror, bit 2 is Y mirror,
                        ;        bit 1 is rotate flag and bit 0 is X MSB.
                        ;   4th: bit 7 is visible flag, bit 6 is reserved, bits 5-0 is Name (pattern index, 0-63).
                        B1 = low(u16X+32);
                        B2 = (u8Y+32) and %11111111
                        B3a = (PaletteOffset and %1111) shl 4           ; OOOOxxxx
                        B3b = (bMirrorX and %1) shl 3                   ; xxxxXxxx
                        B3c = (bMirrorY and %1) shl 2                   ; xxxxxYxx
                        B3d = (bRotate  and %1) shl 1                   ; xxxxxxRx
                        B3e = (((u16X+32) and %1 00000000) shr 8) and %1; xxxxxxxM
                        B3 = B3a+B3b+B3c+B3d+B3e                        ; OOOOXYRM
                        B4a = (bVisible and %1) shl 7                   ; Vxxxxxxx
                        B4b = Pattern and %111111                       ; xxPPPPPP
                        B4 = B4a+B4b                                    ; VxPPPPPP
                        ld a, ID and %111111
                        ld hl, B1+(B2*256)
                        ld de, B3+(B4*256)
                        call NextSpriteProc
mend

NextSpriteProc          proc
                        ld bc, Sprite_Index_Port        ; Set the sprite index (port $303B)
                        out (c), a                      ; (0 to 63)
                        ld bc, Sprite_Sprite_Port       ; Send the sprite slot attributes (port $57)
                        out (c), l
                        out (c), h
                        out (c), e
                        out (c), d
                        ret
End equ $-1
pend
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel Spectron 2084blog

Post Reply