home *** CD-ROM | disk | FTP | other *** search
/ ticalc.org / ticalc_org_rev_b.iso / archives / 86 / asm / source / routines / sprite.asm < prev    next >
Encoding:
Assembly Source File  |  2001-07-01  |  7.7 KB  |  203 lines

  1. ;=========================================================================
  2. ; Sprite routines by David Phillips <david@acz.org>    http://www.acz.org/
  3. ;=========================================================================
  4. ; All sprites are 8x8 masked sprites
  5. ;
  6. ;     PutSprite      -- black/white                  (sprite, mask)
  7. ;     PutSpriteClip  -- black/white with clipping      (sprite, mask)
  8. ;     GraySprite     -- grayscale                      (dark, light, mask)
  9. ;     GraySpriteClip -- grayscale with clipping      (dark, light, mask)
  10. ;
  11. ; in:   hl = pointer to sprite, bc = x,y location
  12. ; out:  af, bc, de, hl, ix = trash
  13. ; size: 250 bytes
  14. ;=========================================================================
  15. VideoDraw = VirtScr                    ; [1024] virtual screen or video ram
  16. GrayDraw1 = GrayMem1                ; [1024] dark grayscale plane
  17. GrayDraw2 = GrayMem2                ; [1024] light grayscale plane
  18. ;=========================================================================
  19. ; in: hl = 8x8 masked sprite, bc = x,y location
  20. PutSpriteClip:
  21.  ex de,hl                            ; save pointer in de
  22.  ld hl,PutSpriteE                    ; need to call putsprite
  23.  ld (ClipSpriteE),hl                ; modify call address
  24.  jr ClipSprite                        ; jump to clipsprite
  25.  
  26. ; in: hl = 8x8 masked grayscale sprite, bc = x,y location
  27. GraySpriteClip:
  28.  ex de,hl                            ; save pointer in de
  29.  ld hl,GraySpriteE                    ; need to call graysprite
  30.  ld (ClipSpriteE),hl                ; modify call address
  31.  
  32. ; in: de = sprite pointer, bc = x,y location
  33. ClipSprite:
  34.  ld a,b                                ; get x coord
  35.  cp 249                                ; hanging off left edge?
  36.  jr nc,ClipSpriteL                    ; then clip left edge
  37.  cp 128                                ; completely off right edge?
  38.  ret nc                                ; then don't draw it
  39.  jr ClipSpriteR                        ; clip right edge
  40. ClipSpriteL:
  41.  res 7,b                            ; draw on right edge
  42.  dec c                                ; move up a row (left clipping)
  43.  bit 7,c                            ; are we on the top edge?
  44.  jr z,ClipSpriteA                    ; if not, skip top fix
  45.  ld hl,RenderSpriteCV                ; point to rows to draw
  46.  inc (hl)                            ; increase it (decreased later)
  47.  dec de                                ; decrease sprite pointer
  48.  ld hl,-16                            ; need to draw up a row
  49.  ld (ClipSpriteX),hl                ; modify top row fix value
  50. ClipSpriteA:
  51.  ld hl,$0218                        ; change instruction to <jr 2>
  52.  ld (RenderSpriteCL),hl                ; modify to skip drawing left byte
  53.  jr ClipSpriteH                        ; done clipping horizontal
  54. ClipSpriteR:
  55.  cp 120                                ; hanging off right edge?
  56.  jr c,ClipSpriteH                    ; if not, don't clip
  57.  ld hl,$0218                        ; change instruction to <jr 2>
  58.  ld (RenderSpriteCR),hl                ; modify to skip drawing right byte
  59. ClipSpriteH:
  60.  ld a,c                                ; get y coord
  61.  cp 249                                ; hanging off top?
  62.  jr nc,ClipSpriteT                    ; then clip the top
  63.  cp 63                                ; completely off the bottom?
  64.  jr nc,ClipSpriteF                    ; then don't draw, but fix everything
  65.  jr ClipSpriteB                        ; clip the bottom
  66. ClipSpriteT:
  67.  xor a                                ; clear for subtract
  68.  ld h,a                                ; clear high byte
  69.  sub c                                ; calc bytes above screen
  70.  ld c,h                                ; set y coord to 0
  71.  ld l,a                                ; set low byte to bytes above screen
  72.  add hl,de                            ; advance sprite pointer
  73.  ex de,hl                            ; swap back into de
  74.  jr ClipSpriteV                        ; finish vertical clipping
  75. ClipSpriteB:
  76.  sub 57                                ; calc bytes below screen
  77.  jr c,ClipSpriteD                    ; don't clip if not below screen
  78.  inc a                                ; increase bytes below screen
  79. ClipSpriteV:
  80.  neg                                ; negate so it can be subtracted
  81. ClipSpriteZ =$+1
  82.  ld hl,RenderSpriteCV                ; point to rows to draw
  83.  add a,(hl)                            ; add (subtract) from current value
  84.  ld (hl),a                            ; save new value
  85. ClipSpriteD:
  86.  push de                            ; push sprite pointer
  87.  pop ix                                ; pop sprite pointer in ix
  88.  call FindAddress                    ; calc address and offset of sprite
  89. ClipSpriteX =$+1
  90.  ld de,0                            ; load address fix for top row
  91.  add hl,de                            ; add the fix value
  92. ClipSpriteE =$+1
  93.  call $ffff                            ; call the correct sprite routine
  94. ClipSpriteF:
  95.  ld a,8                                ; normally 8 rows are drawn
  96.  ld (RenderSpriteCV),a                ; set rows to draw back
  97.  ld hl,$a678                        ; normal opcode is <ld a,b \ and (hl)>
  98.  ld (RenderSpriteCL),hl                ; set instructions back
  99.  inc l                                ; change <ld a,b> to <ld a,c>
  100.  ld (RenderSpriteCR),hl                ; set instructions back
  101.  ld hl,0                            ; normally top row fix is 0
  102.  ld (ClipSpriteX),hl                ; set rox fix back
  103.  ret                                ; return from clipping
  104.  
  105. ; in: hl = 8x8 masked sprite, bc = x,y location
  106. PutSprite:
  107.  push hl                            ; push sprite pointer
  108.  pop ix                                ; pop in ix
  109.  call FindAddress                    ; calc address and offset
  110. PutSpriteE:
  111.  ld de,VideoDraw                    ; draw sprite to video memory
  112.  add hl,de                            ; add offset to buffer start
  113.  jr RenderSprite                    ; actually draw the sprite
  114.  
  115. ; in: hl = 8x8 masked grayscale sprite, bc = x,y location
  116. GraySprite:
  117.  push hl                            ; push sprite pointer
  118.  pop ix                                ; pop in ix
  119.  call FindAddress                    ; calc address and offset
  120. GraySpriteE:
  121.  push hl                            ; save address offset
  122.  push ix                            ; save sprite pointer
  123.  ld de,GrayDraw1                    ; draw to first gray buffer
  124.  add hl,de                            ; add offset to buffer start
  125.  ld a,16                            ; grayscale sprites are 16 bytes
  126.  ld (RenderSpriteM),a                ; adjust sprite load instruction
  127.  call RenderSprite                    ; draw the sprite
  128.  ld a,8                                ; second sprite is 8 bytes from mask
  129.  ld (RenderSpriteM),a                ; adjust sprite load instruction back
  130.  pop ix                                ; restore sprite pointer
  131.  pop hl                                ; restore address offset
  132.  ld de,GrayDraw2                    ; now draw to second gray buffer
  133.  add hl,de                            ; add offset to second buffer start
  134.  ld de,$0008                        ; sprites are 8 bytes
  135.  add ix,de                            ; advance sprite pointer
  136.  
  137. ; in: hl = address in buffer, c = offset, ix = sprite
  138. RenderSprite:
  139. RenderSpriteCV =$+1
  140.  ld b,8                                ; set row counter to 8 bytes
  141. RenderSpriteL:
  142.  push bc                            ; save row counter and sprite offset
  143.  ld a,(ix+8)                        ; load mask for this row
  144. RenderSpriteM =$-1
  145.  cpl                                ; invert the mask
  146.  ld b,a                                ; save inverted mask
  147.  ld d,(ix)                            ; load sprite byte for this row
  148.  inc ix                                ; advance sprite pointer
  149.  ld a,c                                ; set shift counter to sprite offset
  150.  ld c,$ff                            ; set all bits of right mask byte
  151.  ld e,0                                ; clear right byte of sprite
  152.  or a                                ; is the sprite aligned?
  153.  jr z,RenderSpriteD                    ; then skip shifting it
  154. RenderSpriteS:
  155.  srl d                                ; shift left sprite byte
  156.  rr e                                ; into the right sprite byte
  157.  scf                                ; set carry
  158.  rr b                                 ; shift left mask byte
  159.  rr c                                ; into the right mask byte
  160.  dec a                                ; decrease shift counter
  161.  jr nz,RenderSpriteS                ; loop until counter is 0
  162. RenderSpriteD:
  163. RenderSpriteCL =$
  164.  ld a,b                                ; load the left sprite byte
  165.  and (hl)                            ; and it with the screen
  166.  or d                                ; or it with the mask
  167.  ld (hl),a                            ; set screen memory to left byte
  168.  inc hl                                ; increase screen pointer
  169. RenderSpriteCR =$
  170.  ld a,c                                ; load the right sprite byte
  171.  and (hl)                            ; and it with the screen
  172.  or e                                ; or it with the mask
  173.  ld (hl),a                            ; set screen memory to left byte
  174.  ld de,15                            ; next row is 15 bytes ahead
  175.  add hl,de                            ; move screen pointer to next row
  176.  pop bc                                ; restore loop counter and shift mask
  177.  djnz RenderSpriteL                    ; loop for all bytes in sprite
  178.  ret                                ; done drawing the sprite
  179.  
  180. ; in: bc = x,y location
  181. ; out: hl = offset of byte, c = offset in video byte
  182. FindAddress:
  183.  ld a,c                                ; get the y coord
  184.  add a,a                            ; multiply by 2
  185.  add a,a                            ; again by 4
  186.  ld l,a                                ; save as low byte
  187.  ld h,0                                ; clear high byte
  188.  add hl,hl                            ; multiply by 8
  189.  add hl,hl                            ; and again by 16
  190.  ld a,b                                ; now get the x coord
  191.  and %11111000                        ; clear lower 3 bits
  192.  rra                                ; divide by 2
  193.  rra                                ; this time by 4
  194.  rra                                ; and finally by 8
  195.  or l                                ; combine with low byte
  196.  ld l,a                                ; save it
  197.  ld a,b                                ; get x coord again
  198.  and %00000111                        ; clear all but last 3 bits
  199.  ld c,a                                ; save sprite offset in c
  200.  ret                                ; return to caller
  201.  
  202. .end
  203.