Difference between revisions of "Z80 Routines:Graphic:put8x8sprite"
From WikiTI
m |
(added routines from asmin28days, I hope it does not have errors) |
||
| Line 1: | Line 1: | ||
| − | [[Category:Z80 Routines:Graphic| | + | [[Category:Z80 Routines:Graphic|Put8xBsprite]][[Category:Z80 Routines|Put8xBsprite]] |
| − | The ''' | + | |
| − | + | The '''put8xBsprite''' routine is used to plot a 8xB sized sprite. | |
== Code == | == Code == | ||
| − | === Version | + | === Basic Version === |
<nowiki> | <nowiki> | ||
| + | putSprite8xb: | ||
| + | ld h,$00 | ||
| + | ld d,h | ||
| + | #ifdef faster | ||
| + | sla e ;*2 | ||
| + | sla e ;*4 | ||
| + | #endif | ||
| + | ld l,e | ||
| + | add hl,de ;*2 faster:*8 | ||
| + | add hl,de ;*3 faster:*12 | ||
| + | #ifndef faster | ||
| + | add hl,hl ;*6 | ||
| + | add hl,hl ;*12 | ||
| + | #endif | ||
| + | ld e,a | ||
| + | srl e | ||
| + | srl e | ||
| + | srl e | ||
| + | add hl,de | ||
| + | ld de,gbuf | ||
| + | add hl,de | ||
| + | and 7 | ||
| + | ld c,a | ||
| + | putSpriteLoop1: | ||
| + | ld d,(ix) | ||
| + | ld e,$00 | ||
| + | ld a,c | ||
| + | or a | ||
| + | jr z,putSpriteSkip1 | ||
| + | putSpriteLoop2: | ||
| + | srl d | ||
| + | rr e | ||
| + | dec a | ||
| + | jr nz,putSpriteLoop2 | ||
| + | putSpriteSkip1: | ||
| + | ld a,(hl) | ||
| + | xor d | ||
| + | ld (hl),a | ||
| + | inc hl | ||
| + | ld a,(hl) | ||
| + | xor e | ||
| + | ld (hl),a | ||
| + | ld de,$0B | ||
| + | add hl,de | ||
| + | inc ix | ||
| + | djnz putSpriteLoop1 | ||
| + | ret | ||
| + | </nowiki> | ||
| + | |||
| + | === Masked Version === | ||
| + | <nowiki> | ||
| + | PutSpriteMask: | ||
| + | ; Displays an 8x8 masked sprite | ||
| + | ; A = x coordinate | ||
| + | ; E = y coordinate | ||
| + | ; IX = address of sprite | ||
| + | ; IX + 8 = address of mask | ||
| + | LD H, 0 | ||
| + | LD D, H | ||
| + | LD E, L | ||
| + | ADD HL, HL | ||
| + | ADD HL, DE | ||
| + | ADD HL, HL | ||
| + | ADD HL, HL | ||
| + | |||
| + | LD E, A | ||
| + | SRL E | ||
| + | SRL E | ||
| + | SRL E | ||
| + | ADD HL, DE | ||
| + | |||
| + | LD DE, PlotSScreen | ||
| + | ADD HL, DE | ||
| + | |||
| + | AND 7 | ||
| + | JR Z, _Aligned | ||
| + | LD C, A | ||
| + | LD B,8 | ||
| + | |||
| + | _RowLoop: | ||
| + | PUSH BC | ||
| + | LD B, C | ||
| + | LD D, (IX) | ||
| + | LD A, (IX + 8) | ||
| + | LD C, 0 | ||
| + | LD E, C | ||
| + | |||
| + | _ShiftLoop: | ||
| + | SRL A | ||
| + | RR C | ||
| + | SRL D | ||
| + | RR E | ||
| + | DJNZ _ShiftLoop | ||
| + | |||
| + | CPL | ||
| + | AND (HL) | ||
| + | XOR D | ||
| + | LD (HL), A | ||
| + | |||
| + | INC HL | ||
| + | LD A, C | ||
| + | |||
| + | CPL | ||
| + | AND (HL) | ||
| + | XOR E | ||
| + | LD (HL), A | ||
| + | |||
| + | LD DE, 12 | ||
| + | ADD HL, DE | ||
| + | INC IX | ||
| + | POP BC | ||
| + | DJNZ _RowLoop | ||
| + | RET | ||
| + | |||
| + | _Aligned: | ||
| + | LD DE, 12 | ||
| + | |||
| + | _PutLoop | ||
| + | LD A, (IX + 8) | ||
| + | AND (HL) | ||
| + | XOR (IX) | ||
| + | LD (HL), A | ||
| + | INC IX | ||
| + | ADD HL, DE | ||
| + | DJNZ _PutLoop | ||
| + | RET | ||
</nowiki> | </nowiki> | ||
| − | === | + | === Full Clipping (vertical and horizontal) Version === |
<nowiki> | <nowiki> | ||
| + | ClipSprXOR: | ||
| + | ; D = xpos | ||
| + | ; E = ypos | ||
| + | ; B = height | ||
| + | ; IX = image address | ||
| + | ; Start by doing vertical clipping | ||
| + | LD A, %11111111 ; Reset clipping mask | ||
| + | LD (clip_mask), A | ||
| + | LD A, E ; If ypos is negative | ||
| + | OR A ; try clipping the top | ||
| + | JP M, ClipTop ; | ||
| + | |||
| + | SUB 64 ; If ypos is >= 64 | ||
| + | RET NC ; sprite is off-screen | ||
| + | |||
| + | NEG ; If (64 - ypos) > height | ||
| + | CP B ; don't need to clip | ||
| + | JR NC, VertClipDone ; | ||
| + | |||
| + | LD B, A ; Do bottom clipping by | ||
| + | JR VertClipDone ; setting height to (64 - ypos) | ||
| + | |||
| + | ClipTop: | ||
| + | LD A, B ; If ypos <= -height | ||
| + | NEG ; sprite is off-screen | ||
| + | SUB E ; | ||
| + | RET NC ; | ||
| + | |||
| + | PUSH AF | ||
| + | ADD A, B ; Get the number of clipped rows | ||
| + | LD E, 0 ; Set ypos to 0 (top of screen) | ||
| + | LD B, E ; Advance image data pointer | ||
| + | LD C, A ; | ||
| + | ADD IX, BC ; | ||
| + | POP AF | ||
| + | NEG ; Get the number of visible rows | ||
| + | LD B, A ; and set as height | ||
| + | |||
| + | VertClipDone: | ||
| + | ; Now we're doing horizontal clipping | ||
| + | LD C, 0 ; Reset correction factor | ||
| + | LD A, D | ||
| + | |||
| + | CP -7 ; If 0 > xpos >= -7 | ||
| + | JR NC, ClipLeft ; clip the left side | ||
| + | |||
| + | CP 96 ; If xpos >= 96 | ||
| + | RET NC ; sprite is off-screen | ||
| + | |||
| + | CP 89 ; If 0 <= xpos < 89 | ||
| + | JR C, HorizClipDone ; don't need to clip | ||
| + | |||
| + | ClipRight: | ||
| + | AND 7 ; Determine the clipping mask | ||
| + | LD C, A | ||
| + | LD A, %11111111 | ||
| + | FindRightMask: | ||
| + | ADD A, A | ||
| + | DEC C | ||
| + | JR NZ, FindRightMask | ||
| + | LD (clip_mask), A | ||
| + | LD A, D | ||
| + | JR HorizClipDone | ||
| + | |||
| + | ClipLeft: | ||
| + | AND 7 ; Determine the clipping mask | ||
| + | LD C, A | ||
| + | LD A, %11111111 | ||
| + | FindLeftMask: | ||
| + | ADD A, A | ||
| + | DEC C | ||
| + | JR NZ, FindLeftMask | ||
| + | CPL | ||
| + | LD (clip_mask), A | ||
| + | LD A, D | ||
| + | ADD A, 96 ; Set xpos so sprite will "spill over" | ||
| + | LD C, 12 ; Set correction | ||
| + | |||
| + | HorizClipDone: | ||
| + | ; A = xpos | ||
| + | ; E = ypos | ||
| + | ; B = height | ||
| + | ; IX = image address | ||
| + | |||
| + | ; Now we can finally display the sprite. | ||
| + | LD H, 0 | ||
| + | LD D, H | ||
| + | LD L, E | ||
| + | ADD HL, HL | ||
| + | ADD HL, DE | ||
| + | ADD HL, HL | ||
| + | ADD HL, HL | ||
| + | |||
| + | LD E, A | ||
| + | SRL E | ||
| + | SRL E | ||
| + | SRL E | ||
| + | ADD HL, DE | ||
| + | |||
| + | LD DE, PlotSScreen | ||
| + | ADD HL, DE | ||
| + | |||
| + | LD D, 0 ; Correct graph buffer address | ||
| + | LD E, C ; if clipping the left side | ||
| + | SBC HL, DE ; | ||
| + | |||
| + | AND 7 | ||
| + | JR Z, _Aligned | ||
| + | |||
| + | LD C, A | ||
| + | LD DE, 11 | ||
| + | |||
| + | _RowLoop: | ||
| + | PUSH BC | ||
| + | LD B, C | ||
| + | LD A, (clip_mask) ; Mask out the part of the sprite | ||
| + | AND (IX) ; to be horizontally clipped | ||
| + | LD C, 0 | ||
| + | |||
| + | _ShiftLoop: | ||
| + | SRL A | ||
| + | RR C | ||
| + | DJNZ _ShiftLoop | ||
| + | |||
| + | XOR (HL) | ||
| + | LD (HL), A | ||
| + | |||
| + | INC HL | ||
| + | LD A, C | ||
| + | XOR (HL) | ||
| + | LD (HL), A | ||
| + | |||
| + | ADD HL, DE | ||
| + | INC IX | ||
| + | POP BC | ||
| + | DJNZ _RowLoop | ||
| + | RET | ||
| + | |||
| + | _Aligned: | ||
| + | LD DE, 12 | ||
| + | |||
| + | _PutLoop: | ||
| + | LD A, (IX) | ||
| + | XOR (HL) | ||
| + | LD (HL), A | ||
| + | INC IX | ||
| + | ADD HL, DE | ||
| + | DJNZ _PutLoop | ||
| + | RET | ||
| + | |||
| + | clip_mask: .DB 0 | ||
</nowiki> | </nowiki> | ||
== Example == | == Example == | ||
| + | |||
| + | A example using the basic version of PutSprite. | ||
<nowiki> | <nowiki> | ||
;... | ;... | ||
Revision as of 05:48, 16 May 2010
The put8xBsprite routine is used to plot a 8xB sized sprite.
Contents
Code
Basic Version
putSprite8xb: ld h,$00 ld d,h #ifdef faster sla e ;*2 sla e ;*4 #endif ld l,e add hl,de ;*2 faster:*8 add hl,de ;*3 faster:*12 #ifndef faster add hl,hl ;*6 add hl,hl ;*12 #endif ld e,a srl e srl e srl e add hl,de ld de,gbuf add hl,de and 7 ld c,a putSpriteLoop1: ld d,(ix) ld e,$00 ld a,c or a jr z,putSpriteSkip1 putSpriteLoop2: srl d rr e dec a jr nz,putSpriteLoop2 putSpriteSkip1: ld a,(hl) xor d ld (hl),a inc hl ld a,(hl) xor e ld (hl),a ld de,$0B add hl,de inc ix djnz putSpriteLoop1 ret
Masked Version
PutSpriteMask:
; Displays an 8x8 masked sprite
; A = x coordinate
; E = y coordinate
; IX = address of sprite
; IX + 8 = address of mask
LD H, 0
LD D, H
LD E, L
ADD HL, HL
ADD HL, DE
ADD HL, HL
ADD HL, HL
LD E, A
SRL E
SRL E
SRL E
ADD HL, DE
LD DE, PlotSScreen
ADD HL, DE
AND 7
JR Z, _Aligned
LD C, A
LD B,8
_RowLoop:
PUSH BC
LD B, C
LD D, (IX)
LD A, (IX + 8)
LD C, 0
LD E, C
_ShiftLoop:
SRL A
RR C
SRL D
RR E
DJNZ _ShiftLoop
CPL
AND (HL)
XOR D
LD (HL), A
INC HL
LD A, C
CPL
AND (HL)
XOR E
LD (HL), A
LD DE, 12
ADD HL, DE
INC IX
POP BC
DJNZ _RowLoop
RET
_Aligned:
LD DE, 12
_PutLoop
LD A, (IX + 8)
AND (HL)
XOR (IX)
LD (HL), A
INC IX
ADD HL, DE
DJNZ _PutLoop
RET
Full Clipping (vertical and horizontal) Version
ClipSprXOR:
; D = xpos
; E = ypos
; B = height
; IX = image address
; Start by doing vertical clipping
LD A, %11111111 ; Reset clipping mask
LD (clip_mask), A
LD A, E ; If ypos is negative
OR A ; try clipping the top
JP M, ClipTop ;
SUB 64 ; If ypos is >= 64
RET NC ; sprite is off-screen
NEG ; If (64 - ypos) > height
CP B ; don't need to clip
JR NC, VertClipDone ;
LD B, A ; Do bottom clipping by
JR VertClipDone ; setting height to (64 - ypos)
ClipTop:
LD A, B ; If ypos <= -height
NEG ; sprite is off-screen
SUB E ;
RET NC ;
PUSH AF
ADD A, B ; Get the number of clipped rows
LD E, 0 ; Set ypos to 0 (top of screen)
LD B, E ; Advance image data pointer
LD C, A ;
ADD IX, BC ;
POP AF
NEG ; Get the number of visible rows
LD B, A ; and set as height
VertClipDone:
; Now we're doing horizontal clipping
LD C, 0 ; Reset correction factor
LD A, D
CP -7 ; If 0 > xpos >= -7
JR NC, ClipLeft ; clip the left side
CP 96 ; If xpos >= 96
RET NC ; sprite is off-screen
CP 89 ; If 0 <= xpos < 89
JR C, HorizClipDone ; don't need to clip
ClipRight:
AND 7 ; Determine the clipping mask
LD C, A
LD A, %11111111
FindRightMask:
ADD A, A
DEC C
JR NZ, FindRightMask
LD (clip_mask), A
LD A, D
JR HorizClipDone
ClipLeft:
AND 7 ; Determine the clipping mask
LD C, A
LD A, %11111111
FindLeftMask:
ADD A, A
DEC C
JR NZ, FindLeftMask
CPL
LD (clip_mask), A
LD A, D
ADD A, 96 ; Set xpos so sprite will "spill over"
LD C, 12 ; Set correction
HorizClipDone:
; A = xpos
; E = ypos
; B = height
; IX = image address
; Now we can finally display the sprite.
LD H, 0
LD D, H
LD L, E
ADD HL, HL
ADD HL, DE
ADD HL, HL
ADD HL, HL
LD E, A
SRL E
SRL E
SRL E
ADD HL, DE
LD DE, PlotSScreen
ADD HL, DE
LD D, 0 ; Correct graph buffer address
LD E, C ; if clipping the left side
SBC HL, DE ;
AND 7
JR Z, _Aligned
LD C, A
LD DE, 11
_RowLoop:
PUSH BC
LD B, C
LD A, (clip_mask) ; Mask out the part of the sprite
AND (IX) ; to be horizontally clipped
LD C, 0
_ShiftLoop:
SRL A
RR C
DJNZ _ShiftLoop
XOR (HL)
LD (HL), A
INC HL
LD A, C
XOR (HL)
LD (HL), A
ADD HL, DE
INC IX
POP BC
DJNZ _RowLoop
RET
_Aligned:
LD DE, 12
_PutLoop:
LD A, (IX)
XOR (HL)
LD (HL), A
INC IX
ADD HL, DE
DJNZ _PutLoop
RET
clip_mask: .DB 0
Example
A example using the basic version of PutSprite.
;... ld e,8 ;y ld a,16 ;x ld b,8 ;height ld ix,sprite call putsprite call fastcopy ;... sprite: .db %11111111 .db %10000001 .db %10000001 .db %10000001 .db %10000001 .db %10000001 .db %10000001 .db %11111111