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

  1. ; Cases                                                    8x8x4 sample
  2. ; Worst Case = 394 + (499 * YLength) cycles        :         4'386 cycles
  3. ; Best  Case = 394 + (331 * YLength) cycles        :        3'042 cycles
  4. ; Real  Case = 394 + ((331 + 12 * BitDisp) * YLength)
  5. ;
  6. ; Notice the worst case is faster then the best case of the routines I've seen.
  7. ; The worst case is a completelly non-alligned sprite ex : (15, Y).
  8. ; The best case is an alligned sprite ex : (16, Y).
  9. ;
  10. ; Note also that the clipping routines takes less cycles then shown up here.  They take
  11. ; more cycles to start up, but once the patches are applied, they run much faster since they
  12. ; have less pixels to write.
  13. ;
  14. ; It's also possible to calculate the Mask table on the fly supposing you assume that
  15. ; color "00b" mean it's transparent.  My game "Lemmingz" does this and it uses 8 cycles
  16. ; less for both cases.  Although for this, I'll let you do the modifications :)
  17. ; For this, it's very simple, instead of using the mask table, the value found at that table
  18. ; is actually = (Color1 or Color2).
  19. ;
  20. ; If you read my document "Z80Optimization" you should be able to understand all the code I 
  21. ; wrote in here.  It uses *a lot* of code patching.  Without it, the routine would've 
  22. ; surelly boosted of 13 * BitDisp * YLen.  That's a heck of a lot of cycles.
  23. ;
  24. ; Note : Your Destination address must be a multiple of 400h for optimization
  25. ;        reasons.  Although most addresses already used by the grayscla
  26. ;        already have that.  FC00h & 4000h it shouldn't prove a big problem.
  27. ;        Also, your sprite should be arranged so that you have the 2 grey
  28. ;        layers followed by the OR mask.  So basically if you have a 8xY sprite,
  29. ;        you should basically take 3 * 8 * Y bytes.  Since there's 3 layers.
  30. ;
  31. ; Anyone could optimize this more, I'm sure there's still a few places to optimize :)
  32.  
  33. ; There values only serve as example, you may change them as you see fit!
  34. ; Here I'm using the typical pages which are used by games for grayscale
  35. Dest    equ 0FC00h                                    ; First gray destination
  36. Delta    equ (0CA00h - 0FC00h) / 100h                ; Diffrence between the 2 gray pages / 100h
  37.  
  38. ; Procedure to draw a 8xYx4 Sprite created by Christopher Tremblay             <ti_chris@yahoo.com>
  39. ; The fastest routine I know for now!
  40. ; [In] : hl = Source, b = X, c = Y, a = YLength (< 128)
  41. ; [Out] : b = 0, a = 15
  42. ; [Uses] : af, bc, de, hl, ix
  43. ;<[]>---<[]>---<[]>---<[]>---<[]>---<[]>---<[]>---<[]>---<[]>---<[]>---<[]>---<[]>---<[]>---<[]>
  44. DrawSprite:
  45.     ld   (SpriteLen), a
  46.     ld   (GrayDelta), a
  47.     add  a, a
  48.     ld   (Addr1), a                                        ; Patch the length(s)
  49.     rra
  50.     ld   e, a
  51.     add  a, c
  52.     dec  a
  53.     ret  m
  54.     jr   nc, IsLow
  55.  
  56.     inc  a
  57.     ld   d, 0
  58.     ld   (SpriteLen), a
  59.     sub  e
  60.     neg
  61.     ld   e, a
  62.     add  hl, de
  63.     ld   c, d                                            ; It's being clipped from the top!
  64.  
  65. IsLow:
  66.     push hl
  67.     pop  ix                                                ; Load ix with hl
  68.     ld   a, c
  69.     add  a, a
  70.     add  a, a
  71.  
  72. DrawPage:
  73.     ld   h, Dest / 400h                                    ; (*1)
  74.     ld   l, a
  75.  
  76.     ld   a, b
  77.  
  78.     cp   0
  79.     jp   p, NotFixup                                    ; Should we clip left?
  80.  
  81.     xor  a
  82.  
  83. NotFixup:
  84.     rra
  85.     add  hl, hl
  86.     rra
  87.     add  hl, hl
  88.     rra                                                    ; a = X / 8
  89.  
  90.     cp   15
  91.     jr   nz, NoClipRight
  92.  
  93.     add  a, l
  94.     ld   l, a                                            ; Get rid of a
  95.     ld   a, SecondPixel - FirstPixel - 2
  96.     ld   (FirstPixel), a
  97.     ld   a, 16
  98.     ld   (SecondPixel), a
  99.     xor  a
  100.     ld   (SecondPixel + 1), a
  101.     jr   AdjustH
  102.  
  103. NoClipRight:
  104.     add  a, l
  105.     ld   l, a
  106.  
  107. AdjustH:
  108.     ld   a, b
  109.     cp   0
  110.     jp   p, NotClipLeft                                    ; Should we clip left?
  111.     cp   -7
  112.     jp   m, Return                                        ; Nothing to draw we're overflowing!
  113.  
  114.     ld   a, FirstPixel - DoFirstPixel
  115.     ld   (DoFirstPixel), a
  116.     ld   a, b
  117.     dec  hl
  118.  
  119. NotClipLeft:
  120.     and  %00000111
  121.     ld   b, a
  122.     add  a, a
  123.     add  a, b                                            ; a = X * 3
  124.  
  125.     sub  3 * 7                                            ; Skip the Left portion of it
  126.     neg
  127. SpriteLen    equ $ + 1
  128.     ld   b, 8                                            ; e = Length loop
  129.     ld   (MDrawY1), a
  130.     ld   (MDrawY2), a
  131.     xor  a                                                ; Clear the carry flag
  132.     ld   e, a
  133.  
  134. StartMDrawLoop:                                            ; Here b will always be 0 :)
  135.     ld   e, 0
  136.     ld   d, e                                            ; hl = Source
  137. GrayDelta equ $ + 2
  138.     ld   a, (ix + 8)                                    ; cd = 2st Gray Layer
  139.  
  140. MDrawY1     equ $ + 1                                        ; Heavy code patching occrurs here! :o)
  141.     jr   $ + 2
  142.  
  143.     rra
  144.     rr   d
  145.     rra
  146.     rr   d
  147.     rra
  148.     rr   d
  149.     rra
  150.     rr   d
  151.     rra
  152.     rr   d
  153.     rra
  154.     rr   d
  155.     rra
  156.     rr   d                                                ; Shift a & d accordingly
  157.     ld   (OldA), a
  158.     ld   a, (ix)                                        ; ab = 1st Gray Layer
  159.  
  160. MDrawY2     equ $ + 1                                        ; Heavy code patching occrurs here! :o)
  161.     jr   $ + 2
  162.  
  163.     rra
  164.     rr   e
  165.     rra
  166.     rr   e
  167.     rra
  168.     rr   e
  169.     rra
  170.     rr   e
  171.     rra
  172.     rr   e
  173.     rra
  174.     rr   e
  175.     rra
  176.     rr   e                                                ; Shift a & e accordingly
  177.  
  178. DoFirstPixel equ $ + 1
  179.     jr   $ + 2
  180.  
  181.     ld   (NewA), a
  182.  
  183. Addr1     equ $ + 2
  184.     ld   a, (ix + 16)
  185.     ld   c, a
  186.     and  (hl)
  187. NewA     equ $ + 1
  188.     or   0                                                ; Preserve the "a" value
  189.     ld   (hl), a                                        ; Write the first pixel
  190.  
  191.     ld   a, h
  192.     add  a, Delta
  193.     ld   h, a
  194.  
  195.     ld   a, c
  196.     and  (hl)
  197. OldA     equ $ + 1
  198.     or   0
  199.     ld   (hl), a                                        ; Write the second layers' last pix
  200.  
  201.     ld   a, h
  202.     sub  Delta
  203.     ld   h, a
  204.  
  205. FirstPixel equ $ + 1
  206.     jr   $ + 2
  207.  
  208.     inc  hl
  209.     ld   a, c
  210.     and  (hl)
  211.     or   e
  212.     ld   (hl), a                                        ; Write the next pixel
  213.  
  214.     ld   a, h
  215.     add  a, Delta
  216.     ld   h, a
  217.  
  218.     ld   a, c                                            ; Restore the mask
  219.     and  (hl)
  220.     or   d
  221.     ld   (hl), a                                        ; Write the second layers' first pix
  222.  
  223. SecondPixel     equ $ + 1
  224.     ld   de, 10010h - (Delta * 100h) - 1
  225.     add  hl, de
  226.     inc  ix
  227.  
  228.     djnz StartMDrawLoop
  229.  
  230. Return:
  231.     xor  a
  232.     ld   (FirstPixel), a
  233.     ld   (DoFirstPixel), a
  234.     ld   a, 15
  235.     ld   (SecondPixel), a
  236.     ld   hl, 10010h - (Delta * 100h) - 1
  237.     ld   (SecondPixel), hl
  238.  
  239.     ret
  240.