In case I don't get around to actually finishing this before tonight, here's what I have so far. It's not complete as I can't actually select a file, but you can folder browser somewhat.
// Project: file selector
// Created: 2017-02-14
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "file selector" )
SetWindowSize( 1024, 768, 0 )
// set display properties
SetVirtualResolution( 1024, 768 )
SetOrientationAllowed( 1, 1, 1, 1 )
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
UseNewDefaultFonts( 1 ) // since version 2.0.20 we can use nicer default fonts
if getFileExists("wallpaper.jpg") = 1
createSprite(loadImage("wallpaper.jpg"))
else
http = createHTTPConnection()
ret = setHTTPHost(http, "powellong.com", 0)
getHTTPFile(http, "data/wallpapers/12/WDF_606421.jpg", "wallpaper.jpg", "")
while getHTTPFileComplete(http) = 0
endwhile
if getHTTPResponseReady(http) = 1 then createSprite(loadImage("wallpaper.jpg"))
CloseHTTPConnection(http)
DeleteHTTPConnection(http)
endif
global shadow
mem = makeMemblockImage(600, 400, E2DC_ARGB(128,0,0,0))
mem2 = makeMemblockImage(600, 400, 0)
mem_rounded_box(mem2, 10, 10, 590, 390, 0, E2DC_ARGB(128,0,0,0), 1, 0)
img2 = createImageFromMemblock(mem2)
shadow = createSprite(img2)
// Shader code from CJB
if getFileExists("blur.ps") = 0
f = openToWrite("blur.ps")
writeLine(f, "uniform sampler2D texture0;varying vec2 posVarying;varying vec2 uvVarying;uniform vec2 agk_resolution;uniform float BlurSize;")
writeLine(f,"float blurSizeH = BlurSize / agk_resolution.x;float blurSizeV = BlurSize / agk_resolution.y;")
writeLine(f,"void main(){")
writeLine(f,"vec4 sum = vec4(0.0);for (float x = -4.0; x <= 4.0; x++)for (float y = -4.0; y <= 4.0; y++)")
writeLine(f,"sum += texture2D(texture0,vec2(uvVarying.x + x * blurSizeH, uvVarying.y + y * blurSizeV))/ 81.0;gl_FragColor = sum;}")
closeFile(f)
endif
BlurShaderID=LoadSpriteShader("blur.ps")
SetSpriteShader(shadow, BlurShaderID)
setShaderConstantByName(BlurShaderID, "BlurSize",4,0,0,0)
color = makeColor(212,212,212)
Type ThumbObject
spr as integer
height as integer
percent as float
maxScroll as integer
yPos as float
EndType
Type WindowObject
spr as integer[4]
guides as integer[6]
x as integer
y as integer
width as integer
height as integer
borderThickness as integer
pad as integer
folders as string[]
files as integer[]
text as integer[]
viewOffset as float
maxScroll as integer
textSize as integer
thumb as ThumbObject
folderViewHeight as integer
folderViewportHeight as integer
curPath as string
selectedFolderId as integer
maxFileWidth as integer
EndType
w as WindowObject
w.borderThickness = 1
w.width = 600
w.height = 400
w.pad = 4
w.textSize = 16
w.thumb.spr = createSprite(0)
setSpriteSize(w.thumb.spr, 5, 100)
// main body
w.spr[1] = createSprite(0)
setSpriteColor(w.spr[1], 25,50,83,228)
setSpriteSize(w.spr[1], 600,400)
// title bar
m = makeMemblockImage(224, 32, 0)
for i = 1 to 31
mem_line(m, 1+(31-i), i, 224-(31-i), i, makeColor(25,50,83), 0)
next i
mem_line(m, 1, 31, 31, 1, makeColor(44,92,154), 1)
mem_line(m, 224, 31, 194, 1, makeColor(44,92,154), 1)
mem_line(m, 31, 1, 194, 1, makeColor(44,92,154), 1)
w.spr[4] = createSprite(createImageFromMemblock(m)) : deleteMemblock(m)
setSpriteColorAlpha(w.spr[4], 228)
// resize icon
m = makeMemblockImage(32, 32, 0)
mem_line(m, 1,31,31,1,makeColor(255,255,255), 0)
mem_line(m, 10,31,31,10,makeColor(255,255,255), 0)
mem_line(m, 20,31,31,20,makeColor(255,255,255), 0)
w.spr[2] = createSprite(createImageFromMemblock(m)) : deleteMemblock(m)
setSpritePosition(w.spr[2], 100,100)
setSpriteColor(w.spr[2],44,92,154,228)
// folder selection highlight
w.spr[3] = createSprite(0)
setSpriteSize(w.spr[3], 150, w.textSize)
setSpriteColor(w.spr[3], 39,122,229,128)
w.guides[1] = createSprite(0) : setSpriteColor(w.guides[1], 44,92,154,228) : setSpriteSize(w.guides[1], w.width+w.borderThickness*2, w.borderThickness)
w.guides[2] = cloneSprite(w.guides[1])
w.guides[3] = cloneSprite(w.guides[1]) : setSpriteSize(w.guides[3], w.borderThickness, w.height)
w.guides[4] = cloneSprite(w.guides[3])
w.guides[5] = cloneSprite(w.guides[3])
w.guides[6] = cloneSprite(w.guides[3])
positionWindow(w, 50, 75)
resizeWindow(w, 600, 400)
drives as string[]
getDrives(drives)
setFolderView(w, "c:\")
do
if getRawMouseLeftPressed() = 1
x = getRawMouseX()
y = getRawMouseY()
x1 = w.x+w.width
y1 = w.y+w.height
// resize
if x > x1-30 and x < x1 and y > y1-30 and y < y1 and resizeFlag = 0
ox = x1 - x
oy = y1 - y
resizeFlag = 1
endif
// folder selection
if x > w.x and x < w.x+150 and y > w.y+w.pad and y < w.y+w.height-w.pad
w.selectedFolderId = ((y+w.viewOffset) - w.y) / w.textSize - 1
sy = w.selectedFolderId*w.textSize + w.y + w.pad - w.viewOffset
setSpritePosition(w.spr[3], w.x, sy)
p$ = w.curPath + w.folders[w.selectedFolderId+1]
`SetFolder("")
SetRawWritePath(p$)
getFileObjects(w.files, w)
/*
w.files.length = 0
w.files.length = getFileCount()
`w.files[1] = getFirstFile()
w.files[1] = createText(getFirstFile())
setTextSize(w.files[1], w.textSize)
for i = 2 to w.files.length
w.files[i] = createText(getNextFile())
setTextSize(w.files[i], w.textSize)
next i
w.files.sort()
*/
endif
// grab title bar
if x > w.x+50 and x < w.x+274 and y < w.y and y > w.y-32
ox = w.x - x
oy = w.y - y
moveFlag = 1
endif
endif
`print(p$)
if GetRawMouseLeftState() = 1
x = getRawMouseX()
y = getRawMouseY()
if resizeFlag = 1
resizeWindow(w, x-w.x+ox, y-w.y+oy)
endif
if moveFlag = 1
positionWindow(w, x+ox, y+oy)
endif
else
resizeFlag = 0
moveFlag = 0
endif
// mouse wheel scrolling
scroll = GetRawMouseWheelDelta()
if scroll <> 0 then amount# = amount# + 5
if amount# > 18 then amount# = 18
if scroll > 0
d = -1
elseif scroll < 0
d = 1
endif
if amount# > 0
w.thumb.yPos = w.thumb.yPos + amount#*d
if w.thumb.yPos < 0 then w.thumb.yPos = 0
if w.thumb.yPos > w.thumb.maxScroll then w.thumb.yPos = w.thumb.maxScroll
// avoid division by zero
if w.thumb.maxScroll > 0
w.thumb.percent = (w.thumb.yPos / w.thumb.maxScroll)
else
w.thumb.percent = 0
endif
w.viewOffset = (w.folderViewHeight - w.folderViewportHeight) * w.thumb.percent
dec amount#, 1
positionWindow(w, w.x, w.y)
endif
print(w.maxFileWidth)
Sync()
loop
function getFileObjects(files ref as integer[], w ref as WindowObject)
local temp as string[]
temp.length = getFileCount()
temp[0] = getFirstFile()
for i = 1 to temp.length
temp[i] = getNextFile()
next i
temp.sort()
w.maxFileWidth = 0
for i = 0 to temp.length-1
if i <= files.length
setTextString(files[i], temp[i])
else
files.insert(createText(temp[i]))
setTextSize(files[i], w.textSize)
endif
width = getTextTotalWidth(files[i])
if width > w.maxFileWidth then w.maxFileWidth = width
next i
if temp.length <> files.length
for i = temp.length to files.length
next i
endif
temp.length = -1
endfunction
function getDrives(drives ref as string[])
local _ghostFiles as string[]
// Get ghost files (files that appear everywhere, even non-existent drives)
SetFolder("")
SetRawWritePath("(0)(0)")
getCurrentFileArray(_ghostFiles)
_ghostFiles.sort()
// Drive letters A through Z
for i = 0 to 25
d$ = chr(i+65)+":\"
SetFolder("")
SetRawWritePath(d$)
count = getFileCount()
// If file count of this drive is same as the fake drive, compare (sorted) files
if count = _ghostFiles.length
temp as string[]
getCurrentFileArray(temp)
// If file arrays don't match, then this drive contains other legit files. It is valid
if matchStringArray(_ghostFiles, temp) = 0
drives.insert(d$)
else
if getFolderCount() > 0 and getFirstFolder() <> "media" then drives.insert(d$)
endif
// File count differs from fake drive, assume valid
elseif count > 0
drives.insert(d$)
endif
next i
endfunction
function matchStringArray(a as string[], b as string[])
if a.length <> b.length then exitfunction 0
for i = 1 to a.length
if a[i] <> b[i] then exitfunction 0
next i
endfunction 1
function getCurrentFileArray(f ref as string[])
f.length = -1
f.length = getFileCount()
f[1] = getFirstFile()
for i = 2 to f.length
f[i] = getNextFile()
next i
f.sort()
endfunction
function setFolderView(w ref as WindowObject, path as string)
w.curPath = path
SetFolder("")
SetRawWritePath(path)
w.folders.length = getFolderCount()
w.text.length = w.folders.length
w.folders[1] = getFirstFolder()
for i = 2 to w.folders.length
w.folders[i] = getNextFolder()
next i
w.folders.sort()
for i = 1 to w.folders.length
w.text[i] = createText(w.folders[i])
setTextSize(w.text[i], w.textSize)
setTextColor(w.text[i],235,248,251,255)
next i
// to refactor the scroll bar size
resizeWindow(w, w.width, w.height)
endfunction
function resizeWindow(w ref as WindowObject, width as integer, height as integer)
w.width = width
w.height = height
setSpriteSize(w.spr[1], w.width, w.height)
setSpriteSize(shadow, w.width+24, w.height+24)
// window borders
setSpriteSize(w.guides[1], w.width+w.borderThickness*2, w.borderThickness)
setSpriteSize(w.guides[2], w.width+w.borderThickness*2, w.borderThickness)
setSpriteSize(w.guides[3], w.borderThickness, w.height)
setSpriteSize(w.guides[4], w.borderThickness, w.height)
// scroll tracks
setSpriteSize(w.guides[5], w.borderThickness, w.height)
setSpriteSize(w.guides[6], w.borderThickness, w.height)
// max scroll amount for left-side folder list
w.folderViewHeight = w.text.length*w.textSize
w.folderViewportHeight = w.height - w.pad*2
// calc thumb size
v# = w.folders.length*w.textSize
f# = w.height / v#
if f# > 1 then f# = 1
w.thumb.height = w.height*f#
w.thumb.maxScroll = w.height - w.thumb.height
if w.thumb.maxScroll < 0 then w.thumb.maxScroll = 0
setSpriteSize(w.thumb.spr, 5, w.thumb.height)
// avoid division by zero
if w.thumb.maxScroll > 0
w.thumb.percent = (w.thumb.yPos / w.thumb.maxScroll)
else
w.thumb.percent = 0
endif
// keep thumb size updated while resizing window
if w.thumb.yPos < 0 then w.thumb.yPos = 0
if w.thumb.yPos > w.thumb.maxScroll then w.thumb.yPos = w.thumb.maxScroll
w.viewOffset = (w.folderViewHeight - w.folderViewportHeight) * w.thumb.percent
// positioning window also refactors certain elements
positionWindow(w, w.x, w.y)
endfunction
function positionWindow(w ref as WindowObject, x as integer, y as integer)
w.x = x
w.y = y
setSpritePosition(shadow, x-12, y-12)
// main window
setSpritePosition(w.spr[1], x, y)
// resize icon
setSpritePosition(w.spr[2], x+w.width-31, y+w.height-31)
// title bar
setSpritePosition(w.spr[4], w.x+50, w.y-32)
// window borders
setSpritePosition(w.guides[1], w.x-w.borderThickness, w.y-w.borderThickness)
setSpritePosition(w.guides[2], w.x-w.borderThickness, w.y+w.height)
setSpritePosition(w.guides[3], w.x-w.borderThickness, w.y)
setSpritePosition(w.guides[4], w.x+w.width, w.y)
// tracks
setSpritePosition(w.guides[5], w.x+150, w.y)
setSpritePosition(w.guides[6], w.x+156, w.y)
// folder list
for i = 1 to w.text.length
y = (w.y+w.pad+(i-1)*w.textSize) - w.viewOffset
setTextPosition(w.text[i], w.x+w.pad, y)
setTextScissor(w.text[i], w.x, w.y+w.pad, w.x+150-w.pad, w.y+w.height-w.pad)
next i
// scroll thumb
setSpritePosition(w.thumb.spr, w.x+151, w.y+w.thumb.yPos)
// folder highlight
sy = w.selectedFolderId*w.textSize + w.y + w.pad - w.viewOffset
setSpritePosition(w.spr[3], w.x, sy)
setSpriteScissor(w.spr[3], w.x, w.y+w.pad, w.x+150, w.y+w.height-w.pad)
tw# = w.height-w.pad-32
maxRows = tw# / w.textSize - 2
c = 0
r = 0
// file list
for i = 1 to w.files.length
setTextPosition(w.files[i], w.x+155+w.pad+c*(w.maxFileWidth+w.pad), w.y+w.pad+r*w.textSize)
setTextScissor(w.files[i], w.x+155+w.pad, w.y+w.pad, w.x+w.width-w.pad, w.y+w.height-32)
inc r, 1
if r > maxRows
r = 0
inc c
endif
next i
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(width, height, color)
size = width*height*4+12
mem = createMemblock(size)
setMemblockInt(mem, 0, width)
setMemblockInt(mem, 4, height)
setMemblockInt(mem, 8, 32)
if color <> 0
for y = 0 to height-1
for x = 0 to width-1
pos = (y*width + x)*4 + 12
setMemblockInt(mem, pos, color)
next x
next y
endif
endfunction mem
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, preserveBackground)
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 = getMemblockInt(mem, 0)
height = getMemblockInt(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 = trunc(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 = trunc(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 = trunc(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 = trunc(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 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, solid, preserveBackground)
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
local alpha2
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, solid, preserveBackground)
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 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, preserveBackground)
pos = ((y-1)*getMemblockInt(mem, 0) + (x-1))*4 + 12
if preserveBackground
c = getMemblockInt(mem, pos)
if c >> 24 > 0 then color = getAlphaComposite(c, color)
endif
setMemblockInt(mem, pos, color)
endfunction
REM **************************************************
REM Truncates the integer part of a float and returns
REM just the decimal value
REM **************************************************
function fract#(x as float)
a# = x - trunc(x)
endfunction a#
REM **************************************************
REM Returns a color with an alpha value
REM **************************************************
function E2DC_ARGB(a,r,g,b)
c = (a*16777216)+(b*65536)+(g*256)+r
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
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, above)
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
function rgbr(c)
c = c && 255
endfunction c
function rgbg(c)
c = (c >> 8) && 255
endfunction c
function rgbb(c)
c = (c >> 16) && 255
endfunction c
"I like offending people, because I think people who get offended should be offended." - Linus Torvalds