I wrote a set of anti-aliased drawing routines that write directly to an image memblock. This is useful for creating custom graphics while preserving background transparency.
The box and circle commands can draw either an outline or filled-in. I'm still in the process of adding other commands for gradient filles, but the circle has a radial gradient function.
makeMemblockImage(memblock_num, width, height, fill_color)
mem_circle(memblock_num, centerX, centerY, radius, color, fill, preseveBackground)
mem_circle_gradient_radial(memblock_num, centerX, centerY, radius, innerColor, outerColor, gradient_centerX, gradient_centerY, gradient_radius, preseveBackground)
mem_rounded_box(memblock_num, x1, y1, x2, y2, radius, color, fill, preseveBackground)
mem_line(memblock_num, x1, y1, x2, y2, color, preseveBackground)
mem_box(memblock_num, x1, y1, x2, y2, color, fill, preseveBackground)
The preserveBackground option does just what it says. If turned off, the drawing routine will overwrite any pixel data currently in its pixels' positions. If turned on, it will use a form of alpha compositing to blend the drawing operation on top of any current data. It has a few quirks here and there, but works well in most situations.
Demo
#include "memdraw.dba"
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
Library
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
The shapes in the screenshot were all drawn to a single image.