REM ***********************************************
REM Title: Memblock drawing functions
REM Author: Phaelax
REM Downloaded from: http://dbcc.zimnox.com/
REM ***********************************************
 
makeMemblockImage(1, 300, 300, E2DC_ARGB(0,0,0,0))
 
 
mem_circle(1, 180, 100, 50, E2DC_ARGB(255, 0,255,0), 0, 1)
mem_circle_gradient_radial(1, 100, 150, 50, E2DC_ARGB(255, 0,255,0), E2DC_ARGB(255, 255,255,0), 100,110,50, 1)
mem_rounded_box(1, 2,2,100,125,16, 0xFFBBBBBB, 1, 1)
mem_line(1, 5, 15, 230, 140, E2DC_ARGB(255,255,0,0), 1)
mem_box(1, 20, 1, 120, 300, E2DC_ARGB(92,0,0,255),1,1)
 
make image from memblock 1, 1
delete memblock 1
 
 
sync on
DO
 
      box 0,0,640,480,rgb(0,255,255), rgb(255,0,0),rgb(0,0,255),rgb(0,255,0)
 
 
      paste image 1, mousex(), mousey(), 1
 
 
      sync
LOOP
 
 
 
 
 
 
REM *****************************************************************
REM COMMANDS:
REM 
REM   makeMemblockImage(memblock_num, width, height, fill_color)
REM   mem_circle(memblock_num, centerX, centerY, radius, color, fill, preseveBackground)
REM   mem_circle_gradient_radial(memblock_num, centerX, centerY, radius, innerColor, outerColor, gradient_centerX, gradient_centerY, gradient_radius, preseveBackground)
REM   mem_rounded_box(memblock_num, x1, y1, x2, y2, radius, color, fill, preseveBackground)
REM   mem_line(memblock_num, x1, y1, x2, y2, color, preseveBackground)
REM   mem_box(memblock_num, x1, y1, x2, y2, color, fill, preseveBackground)
REM 
REM *****************************************************************
 
 
 
REM *****************************************************************
REM
REM Draws a filled in circle with AA edges and a radial gradient
REM 
REM 
REM        -= Parameters =-
REM  mem                - memblock number to draw to
REM  [cx,cy]            - circle's center coordinates
REM  r                  - circle radius
REM  color1             - Inner color for gradient
REM  color2             - Outer color for gradient 
REM  [sx,sy]            - Center coordinates for gradient fill
REM  r2#                - Radius of radial gradient
REM  preserveBackground - TRUE keeps current memblock pixels, 
REM                           using alpha-compositing to draw on top of them
REM                     - FALSE replaces current memblock pixels.
REM *****************************************************************
function mem_circle_gradient_radial(mem, cx as integer, cy as integer, r as integer, color1 as dword, color2 as dword, sx, sy, r2#, preserveBackground as boolean )
      local alpha1 as dword
      local alpha2 as dword
 
      red1   = rgbr(color1)
      green1 = rgbg(color1)
      blue1  = rgbb(color1)
      red2   = rgbr(color2)
      green2 = rgbg(color2)
      blue2  = rgbb(color2)
      a1# = (color1 >> 24) / 255.0
      a2# = (color2 >> 24) / 255.0
 
      x = r
      y = -1
      t# = 0
      gr# = r2#*r2#
 
      while x > y
            inc y
            cur_dist# = E2DC_Distance#(r, y)
            if cur_dist# < t# then dec x
 
 
            if x <> y
                  rem anit-aliased pixels outside the circle
                  c = 127 - (127*cur_dist#)
                  alpha1 = E2DC_ARGB(c*a1#, red1, green1, blue1)
                  alpha2 = E2DC_ARGB(c*a2#, red2, green2, blue2)
 
                  rem Fill the circle with the gradient
                  for gx = cx-x to cx+x
                        gy = cy-y
                        gy2 = cy+y
                        t1# = (gr#-((gx - sx)^2 + (gy - sy)^2)) / gr#
                        t2# = (gr#-((gx - sx)^2 + (gy2 - sy)^2)) / gr#
                        rem octant 2,7
                        mem_dot(mem, gx, gy, E2DC_Get_LO_Color(color2, color1, t1#), preserveBackground)
                        rem octant 3,6
                        mem_dot(mem, gx, gy2, E2DC_Get_LO_Color(color2, color1, t2#), preserveBackground)
                  next gx
                  for gx = cx-y to cx+y
                        gy = cy-x
                        gy2 = cy+x
                        t1# = (gr#-((gx - sx)^2 + (gy - sy)^2)) / gr#
                        t2# = (gr#-((gx - sx)^2 + (gy2 - sy)^2)) / gr#
                        rem octant 1,8
                        mem_dot(mem, gx, gy, E2DC_Get_LO_Color(color2, color1, t1#), preserveBackground)
                        rem octant 4,5
                        mem_dot(mem, gx, gy2, E2DC_Get_LO_Color(color2, color1, t2#), preserveBackground)
                  next gx
 
 
                  rem octant 1
                  t1# = (gr#-(((cx-y) - sx)^2 + ((cy-x-1) - sy)^2)) / gr#
                  mem_dot(mem, cx-y,   cy-x-1, E2DC_Get_LO_Color(alpha2, alpha1, t1#), preserveBackground)
                  rem octant 2
                  t1# = (gr#-(((cx-x-1) - sx)^2 + ((cy-y) - sy)^2)) / gr#
                  mem_dot(mem, cx-x-1, cy-y, E2DC_Get_LO_Color(alpha2, alpha1, t1#), preserveBackground)
                  rem octant 3
                  t1# = (gr#-(((cx-x-1) - sx)^2 + ((cy+y) - sy)^2)) / gr#
                  mem_dot(mem, cx-x-1, cy+y, E2DC_Get_LO_Color(alpha2, alpha1, t1#), preserveBackground)
                  rem octant 4
                  t1# = (gr#-(((cx-y) - sx)^2 + ((cy+x+1) - sy)^2)) / gr#
                  mem_dot(mem, cx-y,   cy+x+1, E2DC_Get_LO_Color(alpha2, alpha1, t1#), preserveBackground)
                  rem octant 5
                  t1# = (gr#-(((cx+y) - sx)^2 + ((cy+x+1) - sy)^2)) / gr#
                  mem_dot(mem, cx+y,   cy+x+1, E2DC_Get_LO_Color(alpha2, alpha1, t1#), preserveBackground)
                  rem octant 6
                  t1# = (gr#-(((cx+x+1) - sx)^2 + ((cy+y) - sy)^2)) / gr#
                  mem_dot(mem, cx+x+1, cy+y, E2DC_Get_LO_Color(alpha2, alpha1, t1#), preserveBackground)
                  rem octant 7
                  t1# = (gr#-(((cx+x+1) - sx)^2 + ((cy-y) - sy)^2)) / gr#
                  mem_dot(mem, cx+x+1, cy-y, E2DC_Get_LO_Color(alpha2, alpha1, t1#), preserveBackground)
                  rem octant 8
                  t1# = (gr#-(((cx+y) - sx)^2 + ((cy-x-1) - sy)^2)) / gr#
                  mem_dot(mem, cx+y,   cy-x-1, E2DC_Get_LO_Color(alpha2, alpha1, t1#), preserveBackground)
            endif     
            t# = cur_dist#
      endwhile
endfunction
 
 
 
 
 
 
 
 
REM *****************************************************************
REM
REM Draws a box with rounded corners
REM 
REM 
REM        -= Parameters =-
REM  mem                - memblock number to draw to
REM  [x1,y1]            - upper-left coordinates of box
REM  [x2,y2]            - lower-right coordinates of box
REM  radius             - radius of corners
REM  color              - Box color
REM  solid              - TRUE filled-in box, FALSE outline
REM  preserveBackground - TRUE keeps current memblock pixels, 
REM                           using alpha-compositing to draw on top of them
REM                     - FALSE replaces current memblock pixels.
REM *****************************************************************
function mem_rounded_box(mem, x1, y1, x2, y2, radius, color as dword, solid as boolean, preserveBackground as boolean)
      mem_line(mem, x1+radius+2, y1, x2-radius-2, y1, color, preserveBackground)
      if solid = 0
            mem_line(mem, x1+radius+2, y2, x2-radius-2, y2, color, preserveBackground)
            mem_line(mem, x1, y1+radius+2, x1, y2-radius-2, color, preserveBackground)
            mem_line(mem, x2, y1+radius+2, x2, y2-radius-2, color, preserveBackground)
      else
            mem_box(mem, x1, y1+radius, x2, y2-radius, color, 1, preserveBackground)
            `mem_line(mem, x1+radius, y1, x2-radius, y1, color, preserveBackground)
            mem_line(mem, x1+radius, y2, x2-radius, y2, color, preserveBackground)
      endif
 
 
      local alpha1 as dword
      local alpha2 as dword
 
      red = rgbr(color)
      green = rgbg(color)
      blue = rgbb(color)
 
      h = y2 - y1
      w = x2 - x1
      cx = x1
      cy = y1
 
      x = radius
      y = -1
      t# = 0
      r = radius
 
      while x > y
            inc y
            cur_dist# = E2DC_Distance#(r, y)
            if cur_dist# < t# then dec x
 
 
            if x <> y
                  rem anti-aliased pixels inside the circle
                  c = 127*cur_dist#       : alpha1 = E2DC_ARGB(c, red, green, blue)
                  rem anit-aliased pixels outside the circle
                  c = 127 - c             : alpha2 = E2DC_ARGB(c, red, green, blue)      
 
                  rem Either fill in the middle or draw inside AA pixels
                  if solid = 1
                        mem_box(mem, cx-y+r,   cy-x+1+r, cx+y+w-r,   cy-x+1+r, color, 1, preserveBackground)
                        mem_box(mem, cx-x+1+r, cy-y+r,   cx+x-1+w-r, cy-y+r,   color, 1, preserveBackground)
                        mem_box(mem, cx-x+1+r+1, cy+y+h-r-1, cx+x-1+w-r-1, cy+y+h-r-1, color, 1, preserveBackground)
                        mem_box(mem, cx-y+r+1,   cy+x+h-r-1, cx+y+w-r-1,   cy+x+h-r-1, color, 1, preserveBackground)
                  else
                        mem_dot(mem, cx-y+r,   cy-x+1+r,   alpha1, preserveBackground)
                        mem_dot(mem, cx-x+1+r, cy-y+r,     alpha1, preserveBackground)
                        mem_dot(mem, cx-x+1+r, cy+y+h-r,   alpha1, preserveBackground)
                        mem_dot(mem, cx-y+r,   cy+x-1+h-r, alpha1, preserveBackground)
 
                        mem_dot(mem, cx+y+w-r,   cy+x-1+h-r, alpha1, preserveBackground)
                        mem_dot(mem, cx+x-1+w-r, cy+y+h-r,   alpha1, preserveBackground)
                        mem_dot(mem, cx+x-1+w-r, cy-y+r,     alpha1, preserveBackground)
                        mem_dot(mem, cx+y+w-r,   cy-x+1+r,   alpha1, preserveBackground)
 
                  endif
 
                  rem octant 1
                  mem_dot(mem, cx-y+r+1,   cy-x+r+1,   color,  preserveBackground)
                  mem_dot(mem, cx-y+r+1,   cy-x-1+r+1, alpha2, preserveBackground)
                  rem octant 2
                  mem_dot(mem, cx-x+r+1,   cy-y+r+1, color,  preserveBackground)
                  mem_dot(mem, cx-x-1+r+1, cy-y+r+1, alpha2, preserveBackground)
 
                  rem octant 3
                  mem_dot(mem, cx-x+r+1,   (cy+y+h-r)-1, color,  preserveBackground)
                  mem_dot(mem, cx-x-1+r+1, (cy+y+h-r)-1, alpha2, preserveBackground)
                  rem octant 4
                  mem_dot(mem, cx-y+r+1,   (cy+x+h-r)-1,   color,  preserveBackground)
                  mem_dot(mem, cx-y+r+1,   (cy+x+1+h-r)-1, alpha2, preserveBackground)
                  rem octant 5
                  mem_dot(mem, cx+y+w-r-1,   cy+x+h-r-1,   color,  preserveBackground)
                  mem_dot(mem, cx+y+w-r-1,   cy+x+1+h-r-1, alpha2, preserveBackground)
                  rem octant 6
                  mem_dot(mem, cx+x+w-r-1,   cy+y+h-r-1, color,  preserveBackground)
                  mem_dot(mem, cx+x+1+w-r-1, cy+y+h-r-1, alpha2, preserveBackground)
                  rem octant 7
                  mem_dot(mem, cx+x+w-r-1,   cy-y+r+1, color,  preserveBackground)
                  mem_dot(mem, cx+x+1+w-r-1, cy-y+r+1, alpha2, preserveBackground)
                  rem octant 8
                  mem_dot(mem, cx+y+w-r-1,   cy-x+r+1,   color,  preserveBackground)
                  mem_dot(mem, cx+y+w-r-1,   cy-x-1+r+1, alpha2, preserveBackground)
 
            endif     
            t# = cur_dist#
      endwhile
endfunction
 
 
 
 
 
 
 
REM *****************************************************************
REM
REM Draws a box
REM 
REM 
REM        -= Parameters =-
REM  mem                - memblock number to draw to
REM  [x1,y1]            - upper-left coordinates of box
REM  [x2,y2]            - lower-right coordinates of box
REM  color              - Box color
REM  solid              - TRUE filled-in box, FALSE outline
REM  preserveBackground - TRUE keeps current memblock pixels, 
REM                           using alpha-compositing to draw on top of them
REM                     - FALSE replaces current memblock pixels.
REM *****************************************************************
function mem_box(mem, x1, y1, x2, y2, color as dword, solid as boolean, preserveBackground as boolean)
      if solid = 0
            for x = x1 to x2
                  mem_dot(mem, x, y1, color, preserveBackground)
                  mem_dot(mem, x, y2, color, preserveBackground)
            next x
            for y = y1 to y2
                  mem_dot(mem, x1, y, color, preserveBackground)
                  mem_dot(mem, x2, y, color, preserveBackground)
            next y
      else
            for y = y1 to y2
                  for x = x1 to x2
                        mem_dot(mem, x, y, color, preserveBackground)
                  next x
            next y
      endif
endfunction
 
 
 
 
 
REM *****************************************************************
REM
REM Draws a circle with AA edges
REM 
REM 
REM        -= Parameters =-
REM  mem                - memblock number to draw to
REM  [cx,cy]            - circle's center coordinates
REM  r                  - circle radius
REM  color              - Color of circle
REM  solid              - TRUE filled-in box, FALSE outline
REM  preserveBackground - TRUE keeps current memblock pixels, 
REM                           using alpha-compositing to draw on top of them
REM                     - FALSE replaces current memblock pixels.
REM *****************************************************************
function mem_circle(mem, cx as integer, cy as integer, r as integer, color as dword, solid as boolean, preserveBackground as boolean )
      local alpha1 as dword
      local alpha2 as dword
 
      red = rgbr(color)
      green = rgbg(color)
      blue = rgbb(color)
      a# = (color >> 24) / 255.0
      `a# = 1
      x = r
      y = -1
      t# = 0
 
      while x > y
            inc y
            cur_dist# = E2DC_Distance#(r, y)
            if cur_dist# < t# then dec x
 
 
            if x <> y
                  rem anti-aliased pixels inside the circle
                  c = 127*cur_dist#       : alpha1 = E2DC_ARGB(c*a#, red, green, blue)
                  rem anit-aliased pixels outside the circle
                  c = 127 - c             : alpha2 = E2DC_ARGB(c*a#, red, green, blue)      
 
                  rem Either fill in the middle or draw inside AA pixels
                  if solid = 1
                        mem_box(mem, cx-y,   cy-x+1, cx+y,   cy-x+1, color, 1, preserveBackground)
                        mem_box(mem, cx-x+1, cy-y,   cx+x-1, cy-y,   color, 1, preserveBackground)
                        mem_box(mem, cx-x+1, cy+y,   cx+x-1, cy+y,   color, 1, preserveBackground)
                        mem_box(mem, cx-y,   cy+x,   cx+y,   cy+x,   color, 1, preserveBackground)
                  else
                        mem_dot(mem, cx-y,   cy-x+1, alpha1, preserveBackground)
                        mem_dot(mem, cx-x+1, cy-y,   alpha1, preserveBackground)
                        mem_dot(mem, cx-x+1, cy+y,   alpha1, preserveBackground)
                        mem_dot(mem, cx-y,   cy+x-1, alpha1, preserveBackground)
                        mem_dot(mem, cx+y,   cy+x-1, alpha1, preserveBackground)
                        mem_dot(mem, cx+x-1, cy+y,   alpha1, preserveBackground)
                        mem_dot(mem, cx+x-1, cy-y,   alpha1, preserveBackground)
                        mem_dot(mem, cx+y,   cy-x+1, alpha1, preserveBackground)
                  endif
 
                  rem octant 1
                  mem_dot(mem, cx-y,   cy-x,   color,  preserveBackground)
                  mem_dot(mem, cx-y,   cy-x-1, alpha2, preserveBackground)
                  rem octant 2
                  mem_dot(mem, cx-x,   cy-y, color,  preserveBackground)
                  mem_dot(mem, cx-x-1, cy-y, alpha2, preserveBackground)
                  rem octant 3
                  mem_dot(mem, cx-x,   cy+y, color,  preserveBackground)
                  mem_dot(mem, cx-x-1, cy+y, alpha2, preserveBackground)
                  rem octant 4
                  mem_dot(mem, cx-y,   cy+x,   color,  preserveBackground)
                  mem_dot(mem, cx-y,   cy+x+1, alpha2, preserveBackground)
                  rem octant 5
                  mem_dot(mem, cx+y,   cy+x,   color,  preserveBackground)
                  mem_dot(mem, cx+y,   cy+x+1, alpha2, preserveBackground)
                  rem octant 6
                  mem_dot(mem, cx+x,   cy+y, color,  preserveBackground)
                  mem_dot(mem, cx+x+1, cy+y, alpha2, preserveBackground)
                  rem octant 7
                  mem_dot(mem, cx+x,   cy-y, color,  preserveBackground)
                  mem_dot(mem, cx+x+1, cy-y, alpha2, preserveBackground)
                  rem octant 8
                  mem_dot(mem, cx+y,   cy-x,   color,  preserveBackground)
                  mem_dot(mem, cx+y,   cy-x-1, alpha2, preserveBackground)
            endif     
            t# = cur_dist#
      endwhile
endfunction
 
 
 
 
 
 
REM *****************************************************************
REM
REM Draws an AA line using Xialon Wu's algorithm
REM 
REM 
REM        -= Parameters =-
REM  mem                - memblock number to draw to
REM  [x1,y1]            - Starting coordinate of line
REM  [x2,y2]            - Ending coordinate of line
REM  color              - Color of circle
REM  preserveBackground - TRUE keeps current memblock pixels, 
REM                           using alpha-compositing to draw on top of them
REM                     - FALSE replaces current memblock pixels.
REM *****************************************************************
function mem_line(mem, x1, y1, x2, y2, color as dword, preserveBackground as boolean )
    local dx as float
    local dy as float
    local xend as float
    local yend as float
    local xgap as float
    local ygap as float
    local xpxl1 as float
    local ypxl1 as float
    local xpxl2 as float
    local ypxl2 as float
    local intery as float
    local interx as float
 
    width  = memblock dword(mem, 0)
    height = memblock dword(mem, 4)
 
    red   = rgbr(color)
    green = rgbg(color)
    blue  = rgbb(color)
 
    dx = x2-x1
    dy = y2-y1
 
    if abs(dx) > abs(dy)
        rem handle horizontal lines
        if x2 < x1
            ax = x1                 
            x1 = x2
            x2 = ax
            ay = y1
            y1 = y2
            y2 = ay
        endif
        gradient# = dy / dx
 
        rem handle first endpoint
        xend = ceil(x1)
        yend = y1 + gradient# * (xend-x1)
        xgap = 1.0 - fract#(x1 + 0.5)
        xpxl1 = xend : `used in main loop
        ypxl1 = int(yend)
        f# = 1-fract#(yend)*xgap : `brightness
        alpha = 255*f#
        c = E2DC_ARGB(alpha, red, green, blue)
        mem_dot(mem, xpxl1, ypxl1, c, preserveBackground)
        rem brightness: fract#(yend)*xgap
        f# = fract#(yend)*xgap : `brightness
        alpha = 255*f#
        c = E2DC_ARGB(alpha, red, green, blue)
        mem_dot(mem, xpxl1, ypxl1+1, c, preserveBackground)
        intery = yend + gradient# : `first y-intersection for main loop
 
        rem handle second endpoint
        xend = ceil(x2)
        yend = y2 + gradient# * (xend-x2)
        xgap = 1.0 - fract#(x2 + 0.5)
        xpxl2 = xend : `used in main loop
        ypxl2 = int(yend)
        f# = 1-fract#(yend)*xgap : `brightness
        alpha = 255*f#
        c = E2DC_ARGB(alpha, red, green, blue)
        mem_dot(mem, xpxl2, ypxl2, c, preserveBackground)
        f# = fract#(yend)*xgap : `brightness
        alpha = 255*f#
        c = E2DC_ARGB(alpha, red, green, blue)
        mem_dot(mem, xpxl2, ypxl2+1, c, preserveBackground)
 
        rem main loop
        a = xpxl1+1
        b = xpxl2-1
        for x = a to b
            f# = 1-fract#(intery) : `brightness
            alpha = 255*f#
            c = E2DC_ARGB(alpha, red, green, blue)
            mem_dot(mem, x, intery, c, preserveBackground)
            f# = fract#(intery) : `brightness
            alpha = 255*f#
            c = E2DC_ARGB(alpha, red, green, blue)
            mem_dot(mem, x, intery+1, c, preserveBackground)
            intery = intery + gradient#
        next x
 
    else
        rem handle vertical lines
        if y2 < y1
            ax = x1
            x1 = x2
            x2 = ax
            ay = y1
            y1 = y2
            y2 = ay
        endif
 
        gradient# = dx / dy
 
        rem handle first endpoint
        yend = ceil(y1)
        xend = x1 + gradient# * (yend-y1)
        ygap = 1.0 - fract#(y1 + 0.5)
        xpxl1 = int(xend)
        ypxl1 = yend            
        f# = 1-fract#(xend)*ygap : `brightness
        alpha = 255*f#
        c = E2DC_ARGB(alpha, red, green, blue)
        mem_dot(mem, xpxl1, ypxl1, c, preserveBackground)
        intery = intery + gradient#
        f# = fract#(xend)*ygap : `brightness
        alpha = 255*f#
        c = E2DC_ARGB(alpha, red, green, blue)
        mem_dot(mem, xpxl1, ypxl1+1, c, preserveBackground)
        interx = xend + gradient# : `first y-intersection for main loop
 
        rem handle second endpoint
        yend = ceil(y2)
        xend = x2 + gradient# * (yend-y2)
        ygap = fract#(y2 + 0.5)
        xpxl2 = int(xend)
        ypxl2 = yend
        f# = 1-fract#(xend)*ygap : `brightness
        alpha = 255*f#
        c = E2DC_ARGB(alpha, red, green, blue)
        mem_dot(mem, xpxl2, ypxl2, c, preserveBackground)
        f# = fract#(xend)*ygap : `brightness
        alpha = 255*f#
        c = E2DC_ARGB(alpha, red, green, blue)
        mem_dot(mem, xpxl2, ypxl2+1, c, preserveBackground)
 
        rem main loop
        a = ypxl1+1
        b = ypxl2-1
        for y = a to b                  
            f# = 1-fract#(interx) : `brightness
            alpha = 255*f#
            c = E2DC_ARGB(alpha, red, green, blue)
            mem_dot(mem, interx, y, c, preserveBackground)
            f# = fract#(interx) : `brightness
            alpha = 255*f#
            c = E2DC_ARGB(alpha, red, green, blue)
            mem_dot(mem, interx+1, y, c, preserveBackground)
            interx = interx + gradient#
        next y
    endif
endfunction
 
 
 
 
 
 
REM *****************************************************************
REM
REM Creates a memblock with a 32-bit image structure.
REM 
REM 
REM        -= Parameters =-
REM  mem                - memblock number to create
REM  width              - Width of image
REM  height             - height of image
REM  color              - Fill color (0 to leave blank/transparent)
REM *****************************************************************
function makeMemblockImage(mem, width, height, color as dword)
      make memblock mem, width*height*4+12
      write memblock dword mem, 0, width
      write memblock dword mem, 4, height
      write memblock dword mem, 8, 32
 
      if color <> 0
            for y = 0 to height-1
                  for x = 0 to width-1
                        pos = (y*width + x)*4 + 12
                        write memblock dword mem, pos, color
                  next x
            next y
      endif
endfunction
 
 
 
 
 
 
 
 
REM *****************************************************************
REM
REM Returns new color using alpha compositing
REM 
REM 
REM    -= Parameters =-
REM  base   - Color of base layer
REM  above  - Color above base layer 
REM           (what you're trying to merge on top of the base)
REM *****************************************************************
function getAlphaComposite(base as dword, above as dword)
      c as dword
      ab = base >> 24
      rb = rgbr(base)
      gb = rgbg(base)
      bb = rgbb(base)
      ab# = ab / 255.0
 
      aa = above >> 24
      ra = rgbr(above)
      ga = rgbg(above)
      ba = rgbb(above)
      aa# = aa / 255.0
 
      red   = ra*aa# + rb*ab#*(1-aa#)
      green = ga*aa# + gb*ab#*(1-aa#)
      blue  = ba*aa# + bb*ab#*(1-aa#)
      alpha = (aa# + ab#*(1-aa#)) * 255
 
      c = E2DC_ARGB(alpha, red, green, blue)
 
endfunction c
 
 
 
 
 
REM *****************************************************************
REM
REM Draws a dot to the memblock image
REM 
REM 
REM        -= Parameters =-
REM  mem                - memblock number to draw to
REM  [x,y]              - Coordinates of dot
REM  color              - Color of dot
REM  preserveBackground - TRUE keeps current memblock pixels, 
REM                           using alpha-compositing to draw on top of them
REM                     - FALSE replaces current memblock pixels.
REM *****************************************************************
function mem_dot(mem, x, y, color as dword, preserveBackground as boolean)
      pos = ((y-1)*memblock dword(mem, 0) + (x-1))*4 + 12
      if preserveBackground
            c as dword
            c = memblock dword(mem, pos)
            if c >> 24 > 0 then color = getAlphaComposite(c, color)
      endif
      write memblock dword mem, pos, color
endfunction
 
 
 
 
REM *****************************************************************
REM
REM Returns a color from the memblock image
REM 
REM 
REM   -= Parameters =-
REM  mem    - memblock number to retrieve color from
REM  [x,y]  - Point in image to retrieve
REM *****************************************************************
function mem_pick(mem, x, y) as dword
      c as dword
      pos = ((y-1)*memblock dword(mem, 0) + (x-1))*4 + 12
      c = memblock dword(mem, pos)
endfunction c
 
 
 
 
REM **************************************************
REM Truncates the integer part of a float and returns
REM just the decimal value
REM **************************************************
function fract#(x as float)
    a# = x - int(x)
endfunction a#
 
 
REM **************************************************
REM Returns a color with an alpha value
REM **************************************************
function E2DC_ARGB(a,r,g,b)
    local c as dword
    c = (a*16777216)+(r*65536)+(g*256)+b
endfunction c
 
 
 
 
REM **************************************************
REM Returns fractional part of distance
REM   * Needed for Xiaolin Wu functions
REM **************************************************
function E2DC_Distance#(a, b)
    real# = sqrt(a^2 - b^2)
    d# = ceil(real#) - real#
endfunction d#
 
 
 
 
REM **************************************************
REM Returns a linear interpolated color between base
REM color and target color. Percent ranges from 0 to 1
REM **************************************************
function E2DC_Get_LO_Color(base as dword, target as dword, percent# as float)
      if percent# > 1 then percent# = 1
      if percent# < 0 then percent# = 0
 
      color as dword
 
      br = rgbr(base)
      bg = rgbg(base)
      bb = rgbb(base)
      ba = base >> 24
 
      tr = rgbr(target)
      tg = rgbg(target)
      tb = rgbb(target)
      ta = target >> 24
 
      tr = br + (tr-br)*percent#
      tg = bg + (tg-bg)*percent#
      tb = bb + (tb-bb)*percent#
      ta = ba + (ta-ba)*percent#
 
      color = E2DC_ARGB(ta,tr,tg,tb)
endfunction color