Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ; $$$$$$$$$$$$$$$$$$$ ABAKIS $$$$$$$$$$$$$$$$$$$$$
  2. ; *************** STAR^2 SOFTWARE ****************
  3. ; ?????????????????? DRAW.INC ????????????????????
  4.  
  5. ; fast portable graphics
  6.  
  7. include 'color.inc'
  8. include 'box.inc'
  9.  
  10. ;;;;;;;;;;;;;;;;;;;;; SCREEN ;;;;;;;;;;;;;;;;;;;;;
  11.  
  12. align
  13.  
  14. void vga.p
  15.  
  16. integer screen.x, screen.y,\
  17.  screen.w, screen.h, screen.n,\
  18.  screen.bpp, screen.size,\
  19.  screen.pw, screen.pitch
  20. void palette.p
  21. BOX g.box
  22.  
  23. function set.screen, w, h, bpp
  24.   alias n=r0, pw=r1
  25.   . screen.w=w, screen.h=h  ; size
  26.   . n=w, n*h, screen.n=n    ; # pixels
  27.   . pw=bpp, pw/8            ; pixel width
  28.   . screen.pw=pw, n*pw      ; screen size
  29.   . screen.size=n           ; in bytes
  30.   . n=w, n*pw               ; screen pitch
  31.   . screen.pitch=n          ; w in bytes
  32.   . screen.bpp=bpp          ; bits per pixel
  33. endf
  34.  
  35. ;;;;;;;;;;;;;;;;;;;; DRAWING ;;;;;;;;;;;;;;;;;;;;;
  36.  
  37. ; erase screen with color
  38.  
  39. function clear.screen, c
  40.   alias p=r0, n=r1, z=r2
  41.   . p=vga.p, n=screen.n, z=c
  42.   loop n, (u32) *p++=z, endl
  43. endf
  44.  
  45. ; calculate x/y offset: (y*screen.w+x)*4
  46.  
  47. macro get.xy x, y
  48.   { . r0=y, r0*screen.w, r0+x, r0*4 }
  49.  
  50. ; address &vga[(y*screen.w+x)*4]
  51.  
  52. function vga.xy, x, y
  53.   get.xy x, y
  54.   . r0+vga.p
  55. endf
  56.  
  57. ; draw pixel
  58.  
  59. function draw.pixel, x, y, c
  60.   alias p=r0, z=r1
  61.   try clip.pixel x, y
  62.   vga.xy x, y
  63.   . z=c, (u32) *p=z
  64. endf 1
  65.  
  66. ; draw horizontal line
  67.  
  68. function draw.line.h, x, y, n, c
  69.   alias p=r0, z=r1, w=r2
  70.   . p=&x, z=&y, w=&n
  71.   try clip.line 0, p, z, w
  72.   vga.xy x, y
  73.   . z=c
  74.   loop n, (u32) *p++=z, endl
  75. endf 1
  76.  
  77. ; draw vertical line
  78.  
  79. function draw.line.v, x, y, n, c
  80.   locals swb
  81.   alias p=r0, z=r1, h=r2
  82.   . p=&x, z=&y, h=&n
  83.   try clip.line 1, p, z, h
  84.   vga.xy x, y
  85.   . z=c, swb=screen.pitch
  86.   loop n, (u32) *p=z, p+swb, endl
  87. endf 1
  88.  
  89. ; draw solid rectangle
  90.  
  91. function draw.box, x, y, w, h, c
  92.   locals i
  93.   try visible x, y, w, h
  94.   . i=y, i--
  95.   loop h, i++
  96.     draw.line.h x, i, w, c
  97.   endl
  98. endf 1
  99.  
  100. ; draw rectangle outline
  101.  
  102. function draw.outline, x, y, w, h, c
  103.   try visible x, y, w, h
  104.   draw.line.h x, y, w, c    ; top
  105.   . r0=y, r0+h, r0--        ; bottom
  106.   draw.line.h x, r0, w, c
  107.   . r0=y, r0++, r1=h, r1-2  ; left
  108.   draw.line.v x, r0, r1, c
  109.   . r0=x, r0+w, r0--
  110.   . r2=y, r2++, r1=h, r1-2  ; right
  111.   draw.line.v r0, r2, r1, c
  112. endf 1
  113.  
  114. macro draw.box.s b, c
  115.  { draw.box b#.x, b#.y, b#.w, b#.h, c }
  116. macro draw.box.o b, c
  117.  { draw.outline b#.x, b#.y, b#.w, b#.h, c }
  118.  
  119. macro draw.box a, b, c, d, e {
  120.   IF ~e eq
  121.     draw.box a, b, c, d, e
  122.   ELSE IF ~d eq
  123.     'Unsupported'
  124.   ELSE IF ~c eq
  125.     draw.box.s a, b
  126.     draw.box.o a, c
  127.   ELSE IF ~b eq
  128.     draw.box.s a, b
  129.   END IF
  130. }
  131.  
  132. ; draw scanline
  133.  
  134. function draw.scanline, pixels, x, y, w
  135.   locals i
  136.   alias p=r0, s=r1
  137.   . r0=&i, r1=&x, r2=&y, r3=&w
  138.   try clip.scanline r0, r1, r2, r3
  139.   vga.xy x, y
  140.   . s=pixels, s+i
  141.   loop w, (u32) *p++=*s++, endl
  142. endf 1
  143.  
  144. ; draw scanline with transparent key
  145.  
  146. function draw.scanline.t, pixels, x, y, w, key
  147.   locals i
  148.   alias p=r0, s=r1, c=r2
  149.   . r0=&i, r1=&x, r2=&y, r3=&w
  150.   try clip.scanline r0, r1, r2, r3
  151.   vga.xy x, y
  152.   . s=pixels, s+i
  153.   loop w, (u32) c=*s++
  154.     if c<>key, (u32) *p=c, end, p+4
  155.   endl
  156. endf 1
  157.  
  158. ; draw scanline with inverted x
  159.  
  160. function draw.scanline.ix, pixels, x, y, w
  161.   locals i
  162.   alias p=r0, s=r1
  163.   . r0=x, r0+w
  164.   vga.xy r0, y
  165.   . p-4, s=pixels
  166.   loop w, (u32) *p--=*s++, endl
  167. endf 1
  168.  
  169. ; draw variant scanline. pixels are
  170. ; grayscale, alpha intensity of co=color.
  171. ; for brushes and special effects
  172.  
  173. function draw.scanline.v, pixels, x, y, w, co
  174.   locals a, i
  175.   alias p=r0, s=r1, c=r2, c2=r3
  176.   . r0=&i, r1=&x, r2=&y, r3=&w
  177.   try clip.scanline r0, r1, r2, r3
  178.   vga.xy x, y
  179.   . s=pixels, s+i
  180.   loop w, (u32) c=*s++
  181.     . a=c, a&0FFh
  182.     if a=0, go .next, end
  183.     if a=0FFh, c=co, go .draw, end
  184.     . (u32) c2=*p
  185.     push p s
  186.     get c=mix co, c2, a
  187.     pop s p
  188.     .draw: . (u32) *p=c
  189.     .next: . p+4
  190.   endl
  191. endf 1
  192.  
  193. ; draw bitmap
  194.  
  195. function draw.bitmap, pixels, x, y, w, h
  196.   locals i, p
  197.   try visible x, y, w, h
  198.   . i=y, p=pixels
  199.   loop h
  200.     draw.scanline p, x, i, w
  201.     . r0=w, r0*4, p+r0, i++
  202.   endl
  203. endf 1
  204.  
  205. ; draw bitmap with transparency by
  206. ; upper left pixel color (X=0, Y=0)
  207.  
  208. function draw.bitmap.t, pixels, x, y, w, h
  209.   locals i, p, key
  210.   try visible x, y, w, h
  211.   . i=y, r0=pixels, p=r0
  212.   . (u32) r0=*r0, key=r0
  213.   loop h
  214.     draw.scanline.t p, x, i, w, key
  215.     . r0=w, r0*4, p+r0, i++
  216.   endl
  217. endf 1
  218.  
  219. ; draw bitmap with inverted x
  220.  
  221. function draw.bitmap.ix, pixels, x, y, w, h
  222.   locals i, p
  223.   try visible x, y, w, h
  224.   . p=pixels
  225.   loop h
  226.     draw.scanline.ix p, x, y, w
  227.     . r0=w, r0*4, p+r0, y++
  228.   endl
  229. endf 1
  230.  
  231. ; draw bitmap with inverted y
  232.  
  233. function draw.bitmap.iy, pixels, x, y, w, h
  234.   locals i, p
  235.   try visible x, y, w, h
  236.   . r0=h, r0--, y+r0, p=pixels
  237.   loop h
  238.     draw.scanline p, x, y, w
  239.     . r0=w, r0*4, p+r0, y--
  240.   endl
  241. endf 1
  242.  
  243. ; draw bitmap with both inverted
  244.  
  245. function draw.bitmap.ixy, pixels, x, y, w, h
  246.   locals i, p, n
  247.   try visible x, y, w, h
  248.   . p=pixels
  249.   loop h
  250.     draw.scanline.ix p, x, y, w
  251.     . r0=w, r0*4, p+r0, y--
  252.   endl
  253. endf 1
  254.  
  255. ; draw variant bitmap
  256.  
  257. function draw.bitmap.v, pixels, x, y, w, h, c
  258.   locals i, p
  259.   try visible x, y, w, h
  260.   . i=y, r0=pixels, p=r0
  261.   loop h
  262.     draw.scanline.v p, x, i, w, c
  263.     . r0=w, r0*4, p+r0, i++
  264.   endl
  265. endf 1
  266.  
  267. ; draw gradual vertical fade from
  268. ; color a to b. o/rient:
  269. ; 'h'=horizontal, 'v'=vertical
  270.  
  271. function draw.fade, bo, c1, c2
  272.   locals x, y, w, h, i, n, c,\
  273.    r, g, b, red, green, blue,\
  274.    nr, ng, nb, first, last
  275.   . r0=bo,\
  276.    x=[?box.x+r0], y=[?box.y+r0],\
  277.    w=[?box.w+r0], h=[?box.h+r0]
  278.  
  279.   . r0=y, first=r0, r1=h
  280.   . n=r1, r0+r1, last=r0
  281.  
  282.   . r0=&r, r1=&g, r2=&b
  283.   get.rgb c1, r0, r1, r2
  284.   . r0=&red, r1=&green, r2=&blue
  285.   get.rgb c2, r0, r1, r2
  286.  
  287.   . r<<8, g<<8, b<<8, r1=n
  288.   if r1=0, r1++, end
  289.   . r0=red, r0<<8, r0-r, r0/r1, nr=r0
  290.   . r0=green, r0<<8, r0-g, r0/r1, ng=r0
  291.   . r0=blue, r0<<8, r0-b, r0/r1, nb=r0
  292.  
  293.   . i=first
  294.   forever
  295.     . r0=r, r0>>8, r1=g, r1>>8, r2=b, r2>>8
  296.     get c=rgb r0, r1, r2
  297.     draw.line.h x, i, w, c
  298.     . r0=nr, r+r0, r1=ng, g+r1, r2=nb, b+r2
  299.     . i++, r0=last
  300.     if i>r0, go .out, end
  301.   endfv
  302.   .out:
  303. endf
  304.  
  305. ; draw with vertical center fade:
  306. ; a to b then b to a
  307.  
  308. function draw.shade, bo, a, b
  309.   memory.copy g.box, bo, 16
  310.   . g.box.h>>>1
  311.   draw.fade g.box, a, b
  312.   . r0=g.box.h, g.box.y+r0
  313.   draw.fade g.box, b, a
  314. endf
  315.  
  316. ;;;;;;;;;;;;;;;;; PALETTE PIXELS ;;;;;;;;;;;;;;;;;
  317.  
  318. ; 8BPP versions with pa/lette. no clipping
  319.  
  320. function draw.scanline.8, pixels, x, y, w
  321.   alias p=r0, s=r1, c=r2, q=r3
  322.   vga.xy x, y
  323.   . s=pixels
  324.   loop w, q=*s++, q*4, q+palette.p
  325.     . (u32) c=*q, (u32) *p++=c
  326.   endl
  327. endf 1
  328.  
  329. function draw.bitmap.8, pixels, x, y, w, h
  330.   locals i, p
  331.   try visible x, y, w, h
  332.   . i=y, i--, p=pixels
  333.   loop h, i++
  334.     draw.scanline.8 p, x, i, w
  335.     . r0=w, p+r0
  336.   endl
  337. endf 1
  338.  
  339. ;;;;;;;;;;;;;;;;;;;;; SPECIAL ;;;;;;;;;;;;;;;;;;;;
  340.  
  341. ; special variant 8BPP with alpha bias for
  342. ; fonts and sketching effects (example:
  343. ; chalkboard)
  344.  
  345. A.LIGHTEST=128
  346. A.LIGHTER=96
  347. A.LIGHT=64
  348. A.DARK=-32
  349. A.DARKER=-64
  350. A.DARKEST=-96
  351.  
  352. align
  353. integer alpha.bias=0 ; A.DARKEST
  354.  
  355. function draw.scanline.v.8, pixels, x, y, w, co
  356.   locals a, i
  357.   alias p=r0, s=r1, c=r2, c2=r3, q=r3
  358.   vga.xy x, y
  359.   . s=pixels
  360.   loop w, q=*s++, q*4, q+palette.p
  361.     . (u32) c=*q, a=c, a&0FFh
  362.     if a=0, go .next, end
  363.     . (u32) c2=*p
  364.     push p s
  365.     . r0=a
  366.     if alpha.bias, r0+alpha.bias
  367.       if r0<0, r0=0
  368.       else.if r0>255, r0=255, end
  369.     end
  370.     get c=mix co, c2, r0
  371.     pop s p
  372.     .draw: . (u32) *p=c
  373.     .next: . p+4
  374.   endl
  375. endf 1
  376.  
  377. function draw.bitmap.v.8, pixels, x, y, w, h, c
  378.   locals i, p
  379.   try visible x, y, w, h
  380.   . i=y, i--, p=pixels
  381.   loop h, i++
  382.     draw.scanline.v.8 p, x, i, w, c
  383.     . r0=w, p+r0
  384.   endl
  385. endf 1