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