sync on sync rate 0 color backdrop 0 `Enabled use of constant for keys keyConstants() Dim LastKeyState(255) as boolean #constant IMG_SIZE 256 make memblock 1, 12 + (IMG_SIZE * IMG_SIZE * 4) write memblock dword 1, 0, IMG_SIZE write memblock dword 1, 4, IMG_SIZE write memblock dword 1, 8, 32 for i = 12 to get memblock size(1)-1 step 4 write memblock dword 1, i, 0xFFFFFFFF next i make image from memblock 999, 1 delete memblock 1 position camera 0, 0, 3 point camera 0, 0, 0 Type Coord x as float y as float EndType Type WindowData Direction as integer Scale as float pos as Coord id as float lastDrawnCoord as Coord EndType Dim Windows() as WindowData newWindow() currentWindow = 0 Tool = 1 global W as WindowData startTime = timer() frameTime# = 1.0 repeat frameTime# = (0.5 * frameTime#) + (0.5 * (timer() - startTime)) startTime = timer() W = Windows(currentWindow) text 0, 0, "FPS: " + str$(screen fps()) text 0, 10, "SK: " + str$(sk) + ", Direction: " + str$(W.Direction) + ", Scale: " + str$(W.Scale) if KeyOnce(DIK_T) inc Tool if Tool > 3 then Tool = 1 endif testForFunction(Tool) if KeyOnce(DIK_DELETE) make memblock from image 2, 999 make image from memblock Windows(currentWindow).id, 2 delete memblock 2 endif `Sync changes to temp window "W" back into the typed array Windows(currentWindow) = W `Sync the window sync until keystate(DIK_ESCAPE) end function KeyOnce(K as DWORD) r = 0 if LastKeyState(K) if keystate(K) = 0 then LastKeyState(K) = 0 else if keystate(K) LastKeyState(K) = 1 r = 1 endif endif endfunction r remstart function minimiseWindow() if spacekey() if sk = 0 AND W.Direction = 0 sk = 1 if W.Scale = 100 W.Direction = -1 else W.Direction = 1 endif endif else if sk = 1 then sk = 0 endif if W.Direction = -1 W.Scale = curvevalue(10.0, W.Scale, 500.0 / frameTime#) W.pos.x = curvevalue(1.5, W.pos.x, 500.0 / frameTime#) W.pos.y = curvevalue(-1.25, W.pos.y, 500.0 / frameTime#) if W.Scale <= 10.2 W.Direction = 0 W.Scale = 10.0 endif scale object 1, W.SCale, W.Scale, 100 position object 1, W.x, W.y, 0.0 else if W.Direction = 1 W.Scale = curvevalue(100.0, W.Scale, 500.0 / frameTime#) W.x = curvevalue(0.0, W.x, 500.0 / frameTime#) W.y = curvevalue(0.0, W.y, 500.0 / frameTime#) if W.Scale >= 99.8 W.Direction = 0 W.Scale = 100.0 endif scale object 1, W.SCale, W.Scale, 100 position object 1, W.x, W.y, 0.0 endif endif endfunction remend function testForFunction(f) clicked as boolean : clicked = 0 onCanvas as boolean : onCanvas = 0 x as integer : x = -1 y as integer : y = -1 if W.Direction = 0 if W.Scale = 100 if pick object(mousex(), mousey(), W.id, W.id) = W.id onCanvas = 1 if mouseclick() = 1 x as double float y as double float x = int((0.5 - ((get pick vector x() - camera position x() - object position x(W.id)) / object size x(W.id))) * IMG_SIZE) y = int((0.0 - ((get pick vector y() - camera position y() - object position y(W.id)) / object size y(W.id))) * IMG_SIZE) clicked = 1 endif endif endif endif select f case 1 : drawLineInWindow(x, y, clicked, onCanvas) : endcase case 2 : drawFreehandInWindow(x, y, clicked, onCanvas) : endcase case 3 : fillAtCoord(x, y, clicked, onCanvas) : endcase endselect endfunction function fillAtCoord(x as word, y as word, clicked as boolean, onCanvas as boolean) PrintToolName("Fill In") if onCanvas if clicked `Used as a stack global ptr as DWORD : ptr = make memory(IMG_SIZE * IMG_SIZE * 4) `Create a memblock image make memblock from image 1, W.id `Get the match colour matchColor as dword : matchColor = memblock dword(1, getMemblockImagePos(x, y, IMG_SIZE)) `Add to the queue... `writeMemory(ptr, getMemblockImagePos(x, y, IMG_SIZE)) writeMemory(ptr, x) writeMemory(ptr+2, y) `Next point to write to i = 4 repeat `"pop" the stack offset dec i, 4 `If its not negative, grab it if i > -1 `get the x and y coors from the memory section, +0 = 0, +2 = y. x = getMemory(ptr + i) y = getMemory(ptr + i + 2) `Clear the old bit fill memory ptr, i, 4 `check left, up, right and down. If its within canvas boundaries - go into the fill test function below if x > 0 then i = FillTest(x-1, y, matchColor, i) if y > 0 then i = FillTest(x, y-1, matchColor, i) if x < IMG_SIZE - 1 then i = FillTest(x+1, y, matchColor, i) if y < IMG_SIZE - 1 then i = FillTest(x, y+1, matchColor, i) `Finally, fill this pixel black (after validation) pos = getMemblockImagePos(x, y, IMG_SIZE) if pos >= 12 AND pos <= get memblock size(1) -4 then write memblock dword 1, pos, 0xFF000000 `Debug... make image from memblock W.id, 1 sync endif `Keep going to till we exhaust the stack until i <= 0 `turn it into an image and clean up. make image from memblock W.id, 1 delete memblock 1 delete memory ptr endif endif endfunction function FillTest(x as word, y as word, matchColor as dword, i as DWORD) pos = getMemblockImagePos(x, y, IMG_SIZE) if pos <= get memblock size(1)-4 if memblock dword(1, pos) = matchColor `Check its not already in the stack j = 0 repeat if getMemory(ptr + j) = x then if getMemory(ptr + j + 2) = y then exitfunction inc j, 4 until getMemory(ptr + j) = 0 `Write the next coord to look at into the memory queue writeMemory(ptr + i, x) writeMemory(ptr + i + 2, y) `Forward the memory pointer on by 1 inc i, 4 endif endif endfunction i `Simple "get" function. returns value at pointer position function getMemory(ptr as DWORD) r = *ptr endfunction r `Simple write function - sets a value at the pointer position function writeMemory(ptr as DWORD, value as DWORD) *ptr = value endfunction function drawFreehandInWindow(x as integer, y as integer, clicked as boolean, onCanvas as boolean) PrintToolName("Freehand") if onCanvas if clicked = 1 make memblock from image 1, W.id if W.lastDrawnCoord.x = -1 MemblockLine(1, x, y, x, y) else MemblockLine(1, W.lastDrawnCoord.x, W.lastDrawnCoord.y, x, y) endif W.lastDrawnCoord.x = x W.lastDrawnCoord.y = y make image from memblock W.id, 1 delete memblock 1 else W.lastDrawnCoord.x = -1 W.lastDrawnCoord.y = -1 if memblock exist(1) then delete memblock 1 endif else W.lastDrawnCoord.x = -1 W.lastDrawnCoord.y = -1 if memblock exist(1) then delete memblock 1 endif endfunction function drawLineInWindow(x as integer, y as integer, clicked as boolean, onCanvas as boolean) PrintToolName("Line Tool") if onCanvas if clicked if W.lastDrawnCoord.x = -1 W.lastDrawnCoord.x = x W.lastDrawnCoord.y = y make memblock from image 2, W.id make memblock from image 1, W.id endif copy memblock 2, 1, 0, 0, get memblock size(2) if W.lastDrawnCoord.x = -1 MemblockLine(1, x, y, x, y) else MemblockLine(1, W.lastDrawnCoord.x, W.lastDrawnCoord.y, x, y) endif make image from memblock W.id, 1 else W.lastDrawnCoord.x = -1 W.lastDrawnCoord.y = -1 if memblock exist(1) then delete memblock 1 if memblock exist(2) then delete memblock 2 endif endif endfunction function PrintToolName(tool as string) text screen width() - text width(tool), 0, tool endfunction function newWindow() array insert at bottom Windows() Windows().Direction = 0 Windows().Scale = 100 Windows().pos.x = 0 Windows().pos.y = 0 Windows().lastDrawnCoord.x = -1 Windows().lastDrawnCoord.y = -1 Windows().id = nextFreeObj() make memblock from image 2, 999 make image from memblock Windows().id, 2 delete memblock 2 make object plain Windows().id, 3, 3 texture object Windows().id, Windows().id set object transparency Windows().id, 3 set object light Windows().id, 0 position object Windows().id, 0.0, 0.0, 0 point object Windows().id, 0.0, 0.0, 1 endfunction function nextFreeObj() i = 1 while object exist(i) : inc i : endwhile endfunction i function getMemblockImagePos(x, y, width) p = 12 + (x + (y * width)) * 4 endfunction p function MemblockLine(mb, x1, y1, x2, y2) `Flip the image if going "up" if y2 < y1 tx = x1 ty = y1 x1 = x2 y1 = y2 x2 = tx y2 = ty endif dx = abs(x1-x2) dy = abs(y1-y2) if dy > dx `More than 45 degrees, so flip the x and y angles but make a note for later checking. t = dx dx = dy dy = t t = 1 else t = 0 endif `dStart value d = (2 * dy) - dx `Check the x values to see if we draw from left to right if x1 > x2 incX = -1 else incX = 1 endif x = x1 `No need to check the y as we have flipped it earlier if we needed to y = y1 incY = 1 `Start the Loop do `Are we at the end yet? If so then exit if incx > 0 if x >= x2 if incy > 0 if y >= y2 then exit else if y <= y2 then exit endif endif else if x <= x2 if incy > 0 if y >= y2 then exit else if y <= y2 then exit endif endif endif if d < 0 `OPTION a d = d + (2 * dy) if t = 0 inc x, incX else inc y, incY endif else `OPTION b d = d + (2 * dy) - (2 * dx) inc x, incX inc y, incY endif `Draw a dot (but check within memblock range first... pos = getMemblockImagePos(x, y, IMG_SIZE) if pos < get memblock size(mb)-5 AND pos > 0 write memblock dword mb, pos, 0xFF000000 endif loop endfunction function keyConstants() #constant DIK_0 11 #constant DIK_1 2 #constant DIK_2 3 #constant DIK_3 4 #constant DIK_4 5 #constant DIK_5 6 #constant DIK_6 7 #constant DIK_7 8 #constant DIK_8 9 #constant DIK_9 10 #constant DIK_A 30 #constant DIK_ABNT_C1 115 #constant DIK_ABNT_C2 126 #constant DIK_ADD 78 #constant DIK_APOSTROPHE 40 #constant DIK_APPS 221 #constant DIK_AT 145 #constant DIK_AX 150 #constant DIK_B 48 #constant DIK_BACK 14 #constant DIK_BACKSLASH 43 #constant DIK_BACKSPACE 14 #constant DIK_C 46 #constant DIK_CALCULATOR 161 #constant DIK_CAPITAL 58 #constant DIK_CAPSLOCK 58 #constant DIK_CIRCUMFLEX 144 #constant DIK_COLON 146 #constant DIK_COMMA 51 #constant DIK_CONVERT 121 #constant DIK_D 32 #constant DIK_DECIMAL 83 #constant DIK_DELETE 211 #constant DIK_DIVIDE 181 #constant DIK_DOWN 208 #constant DIK_DOWNARROW 208 #constant DIK_E 18 #constant DIK_END 207 #constant DIK_EQUALS 13 #constant DIK_ESCAPE 1 #constant DIK_F 33 #constant DIK_F1 59 #constant DIK_F2 60 #constant DIK_F3 61 #constant DIK_F4 62 #constant DIK_F5 63 #constant DIK_F6 64 #constant DIK_F7 65 #constant DIK_F8 66 #constant DIK_F9 67 #constant DIK_F10 68 #constant DIK_F11 87 #constant DIK_F12 88 #constant DIK_F13 100 #constant DIK_F14 101 #constant DIK_F15 102 #constant DIK_G 34 #constant DIK_GRAVE 41 #constant DIK_H 35 #constant DIK_HOME 199 #constant DIK_I 23 #constant DIK_INSERT 210 #constant DIK_J 36 #constant DIK_K 37 #constant DIK_KANA 112 #constant DIK_KANJI 148 #constant DIK_L 38 #constant DIK_LALT 56 #constant DIK_LBRACKET 26 #constant DIK_LCONTROL 29 #constant DIK_LEFT 203 #constant DIK_LEFTARROW 203 #constant DIK_LMENU 56 #constant DIK_LSHIFT 42 #constant DIK_LWIN 219 #constant DIK_M 50 #constant DIK_MAIL 236 #constant DIK_MEDIASELECT 237 #constant DIK_MEDIASTOP 164 #constant DIK_MINUS 12 #constant DIK_MULTIPLY 55 #constant DIK_MUTE 160 #constant DIK_MYCOMPUTER 235 #constant DIK_N 49 #constant DIK_NEXT 209 #constant DIK_NEXTTRACK 153 #constant DIK_NOCONVERT 123 #constant DIK_NUMLOCK 69 #constant DIK_NUMPAD0 82 #constant DIK_NUMPAD1 79 #constant DIK_NUMPAD2 80 #constant DIK_NUMPAD3 81 #constant DIK_NUMPAD4 75 #constant DIK_NUMPAD5 76 #constant DIK_NUMPAD6 77 #constant DIK_NUMPAD7 71 #constant DIK_NUMPAD8 72 #constant DIK_NUMPAD9 73 #constant DIK_NUMPADCOMMA 179 #constant DIK_NUMPADENTER 156 #constant DIK_NUMPADEQUALS 141 #constant DIK_NUMPADMINUS 74 #constant DIK_NUMPADPERIOD 83 #constant DIK_NUMPADPLUS 78 #constant DIK_NUMPADSLASH 181 #constant DIK_NUMPADSTAR 55 #constant DIK_O 24 #constant DIK_OEM_102 86 #constant DIK_P 25 #constant DIK_PAUSE 197 #constant DIK_PERIOD 52 #constant DIK_PGDN 209 #constant DIK_PGUP 201 #constant DIK_PLAYPAUSE 162 #constant DIK_POWER 222 #constant DIK_PREVTRACK 144 #constant DIK_PRIOR 201 #constant DIK_Q 16 #constant DIK_R 19 #constant DIK_RALT 184 #constant DIK_RBRACKET 27 #constant DIK_RCONTROL 157 #constant DIK_RETURN 28 #constant DIK_RIGHT 205 #constant DIK_RIGHTARROW 205 #constant DIK_RMENU 184 #constant DIK_RSHIFT 54 #constant DIK_RWIN 220 #constant DIK_S 31 #constant DIK_SCROLL 70 #constant DIK_SEMICOLON 39 #constant DIK_SLASH 53 #constant DIK_SLEEP 223 #constant DIK_SPACE 57 #constant DIK_STOP 149 #constant DIK_SUBTRACT 74 #constant DIK_SYSRQ 183 #constant DIK_T 20 #constant DIK_TAB 15 #constant DIK_U 22 #constant DIK_UNDERLINE 147 #constant DIK_UNLABELED 151 #constant DIK_UP 200 #constant DIK_UPARROW 200 #constant DIK_V 47 #constant DIK_VOLUMEDOWN 174 #constant DIK_VOLUMEUP 176 #constant DIK_W 17 #constant DIK_WAKE 227 #constant DIK_WEBBACK 234 #constant DIK_WEBFAVORITES 230 #constant DIK_WEBFORWARD 233 #constant DIK_WEBHOME 178 #constant DIK_WEBREFRESH 231 #constant DIK_WEBSEARCH 229 #constant DIK_WEBSTOP 232 #constant DIK_X 45 #constant DIK_Y 21 #constant DIK_YEN 125 #constant DIK_Z 44 endfunction