Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- +--------------------------------------------------------+
- -- | |
- -- | Slide |
- -- | |
- -- +--------------------------------------------------------+
- local version = "Version 1.0.0"
- -- By Jeffrey Alexander, aka Bomb Bloke.
- -- A slide puzzle for the RandomPeripheral's Hologram Projector.
- -- http://www.computercraft.info/forums2/index.php?/topic/24764-slide-puzzle-randomperipherals/
- -- http://www.computercraft.info/forums2/index.php?/topic/20785-mc-1710cc-174-randomperipherals-read-nbt-data-from-every-item-and-more/
- ---------------------------------------------
- ------------Variable Declarations------------
- ---------------------------------------------
- if not fs.exists(shell.resolve("holo.pal")) then shell.run("pastebin get zszAghrq holo.pal") end
- if not package then
- if not (fs.exists("package") or fs.exists(shell.resolve("package"))) then
- shell.run("pastebin get cUYTGbpb package")
- os.loadAPI(shell.resolve("package"))
- else os.loadAPI(fs.exists("package") and "package" or shell.resolve("package")) end
- end
- if not GIF then
- if not (fs.exists("GIF") or fs.exists(shell.resolve("GIF"))) then
- shell.run("pastebin get 5uk9uRjC GIF")
- os.loadAPI(shell.resolve("GIF"))
- else os.loadAPI(fs.exists("GIF") and "GIF" or shell.resolve("GIF")) end
- end
- local xSize, ySize, rotate, sideLengthX, sideLengthY, emptyTile, image, myEvent, tileWidth, tileHeight
- local tilesPerSide, tiles, pal, holo, grid, correct, redraw, blackText, scale, stretch, center = 4, 15, {}, {}, {}, 0, true, _CC_VERSION and colours.grey or colours.black, 0, 1, 2
- local cursor = {{">> "," <<"},{"> > "," < <"},{" >> "," << "},{"> > "," < <"}}
- local arrow = {{1,1,1,1,1,1,1,1},{1,2,2,3,2,2,2,1},{1,2,3,3,3,2,2,1},{1,3,2,3,2,3,2,1},{1,2,2,3,2,2,2,1},{1,2,2,3,2,2,2,1},{1,2,2,3,2,2,2,1},{1,1,1,1,1,1,1,1}}
- local alterOption = {function(x, y) return x, y - 1 end, function(x, y) return x, y + 1 end, function(x, y) return x - 1, y end, function(x, y) return x + 1, y end}
- local rotateOption = {function(x, y) return x, y end, function(x, y) return 7 - y, x end, function(x, y) return 7 - x, 7 - y end, function(x, y) return y, 7 - x end}
- ---------------------------------------------
- ------------ Misc Functions ------------
- ---------------------------------------------
- local function clear(textCol, backCol)
- if textCol then term.setTextColour(textCol) end
- if backCol then term.setBackgroundColour(backCol) end
- for i = 4, ySize - 3 do
- term.setCursorPos(1, i)
- term.clearLine()
- end
- end
- -- Returns whether a click was performed at a given location.
- -- If one parameter is passed, it checks to see if y is [1].
- -- If two parameters are passed, it checks to see if x is [1] and y is [2].
- -- If three parameters are passed, it checks to see if x is between [1]/[2] (non-inclusive) and y is [3].
- -- If four paramaters are passed, it checks to see if x is between [1]/[2] and y is between [3]/[4] (non-inclusive).
- local function clickedAt(...)
- if myEvent[1] ~= "mouse_click" then return false end
- if #arg == 1 then return (arg[1] == myEvent[4])
- elseif #arg == 2 then return (myEvent[3] == arg[1] and myEvent[4] == arg[2])
- elseif #arg == 3 then return (myEvent[3] > arg[1] and myEvent[3] < arg[2] and myEvent[4] == arg[3])
- else return (myEvent[3] > arg[1] and myEvent[3] < arg[2] and myEvent[4] > arg[3] and myEvent[4] < arg[4]) end
- end
- -- Returns whether one of a given set of keys was pressed.
- local function pressedKey(...)
- if myEvent[1] ~= "key" then return false end
- for i=1,#arg do if arg[i] == myEvent[2] then return true end end
- return false
- end
- local function writeAt(text, x, y, tCol, bCol)
- if not (x and y) then
- local curX, curY = term.getCursorPos()
- x, y = x or curX, y or curY
- end
- term.setCursorPos(x, y)
- if tCol then term.setTextColour(tCol) end
- if bCol then term.setBackgroundColour(bCol) end
- term.write(text)
- end
- local function loadImage(loadThis, resizeMode)
- local GIFImage = GIF.loadGIF(loadThis, shell.resolve("holo.pal"))
- if GIFImage.width ~= sideLengthX or GIFImage.height ~= sideLengthY then
- for i = 2, #GIFImage do GIFImage[i] = nil end
- if resizeMode == scale then
- if sideLengthX < math.floor(sideLengthY / GIFImage.height * GIFImage.width) then
- GIFImage = GIF.resizeGIF(GIFImage, sideLengthX)
- else
- GIFImage = GIF.resizeGIF(GIFImage, nil, sideLengthY)
- end
- elseif resizeMode == stretch then
- GIFImage = GIF.resizeGIF(GIFImage, sideLengthX, sideLengthY)
- end
- end
- image = {}
- for y = 1, GIFImage.height do
- image[y] = {}
- for x = 1, GIFImage.width do image[y][x] = 0 end
- end
- pal = {}
- for i = 1, #GIFImage.pal do pal[i] = {GIFImage.pal[i][4], GIFImage.pal[i][5] or 0} end
- GIFImage = GIFImage[1]
- for y = 1, GIFImage.yend do
- local x, GIFImageY, imageY = GIFImage.xstart + 1, GIFImage[y], image[y + GIFImage.ystart]
- for i = 1, #GIFImageY do
- local GIFImageYI = GIFImageY[i]
- if type(GIFImageYI) == "number" then
- x = x + GIFImageYI
- else
- for pixel = 1, #GIFImageYI do imageY[x + pixel - 1] = GIFImageYI[pixel] end
- x = x + #GIFImageYI
- end
- end
- end
- if resizeMode == center and (#image[1] > sideLengthX or #image > sideLengthY) then
- local xbump, ybump, newImage = math.max(math.floor((#image[1] - sideLengthX) / 2), 0), math.max(math.floor((#image - sideLengthY) / 2), 0), {}
- for y = 1, math.min(#image, sideLengthY) do
- local newRow, oldRow = {}, image[y + ybump]
- for x = 1, math.min(#image[1], sideLengthX) do newRow[x] = oldRow[x + xbump] end
- newImage[y] = newRow
- end
- image = newImage
- end
- end
- ---------------------------------------------
- ------------ GUI Functions ------------
- ---------------------------------------------
- local function fileBrowser()
- local bump = math.floor((xSize - 49) / 2) + 1
- while true do
- local displayList, lastPosition, animationTimer, curCount, gapTimer, lastProgress, position = {}, 0, os.startTimer(0), 1
- if #shell.resolve(".") > 0 then displayList[1] = ".." end
- do
- local fullList = fs.list(shell.resolve("."))
- table.sort(fullList, function (a, b) return string.lower(a) < string.lower(b) end)
- for i = 1, #fullList do if fs.isDir(shell.resolve(fullList[i])) then displayList[#displayList + 1] = fullList[i] end end
- position = #displayList + 1
- for i = 1, #fullList do if fullList[i]:sub(#fullList[i] - 3):lower() == ".gif" then displayList[#displayList + 1] = fs.getName(fullList[i]) end end
- if position > #displayList then position = 1 end
- end
- while true do
- myEvent = {os.pullEvent()}
- -- Track animations (bouncing cursor + scrolling marquee).
- if myEvent[1] == "timer" and myEvent[2] == animationTimer then
- curCount = curCount == 4 and 1 or (curCount + 1)
- animationTimer = os.startTimer(0.5)
- myEvent[1] = "cabbage"
- -- Bail.
- elseif pressedKey(keys.backspace, keys.q, keys.x) or (myEvent[1] == "mouse_click" and myEvent[2] == 2) then
- return nil
- -- Move down the list.
- elseif pressedKey(keys.down, keys.s) or (myEvent[1] == "mouse_scroll" and myEvent[2] == 1) then
- position = position == #displayList and 1 or (position + 1)
- -- Move up the list.
- elseif pressedKey(keys.up, keys.w) or (myEvent[1] == "mouse_scroll" and myEvent[2] == -1) then
- position = position == 1 and #displayList or (position - 1)
- -- Select something.
- elseif pressedKey(keys.enter, keys.space) or clickedAt(math.floor(ySize / 2) + 1) then
- if fs.isDir(shell.resolve(displayList[position])) then
- shell.setDir(shell.resolve(displayList[position]))
- break
- else return shell.resolve(displayList[position]) end
- -- User clicked somewhere on the file list; move that entry to the currently-selected position.
- elseif clickedAt(0, xSize + 1, 3, ySize - 2) then
- position = position + myEvent[4] - math.floor(ySize / 2) - 1
- position = position > #displayList and #displayList or position
- position = position < 1 and 1 or position
- end
- -- Update other screen stuff.
- if myEvent[1] ~= "timer" then
- -- File list.
- term.setBackgroundColour(colours.black)
- for y = position == lastPosition and (math.floor(ySize / 2) + 1) or 4, position == lastPosition and (math.floor(ySize / 2) + 1) or (ySize - 3) do
- local thisLine = y + position - math.floor(ySize / 2) - 1
- if displayList[thisLine] then
- local thisString = displayList[thisLine]
- thisString = fs.isDir(shell.resolve(thisString)) and "["..thisString.."]" or thisString:sub(1, #thisString-4)
- if thisLine == position then
- term.setCursorPos(math.floor((xSize - #thisString - 8) / 2) + 1, y)
- term.clearLine()
- term.setTextColour(colours.red)
- term.write(cursor[curCount][1])
- term.setTextColour(colours.orange)
- term.write(thisString)
- term.setTextColour(colours.red)
- term.write(cursor[curCount][2])
- else
- term.setCursorPos(math.floor((xSize - #thisString) / 2) + 1, y)
- term.clearLine()
- if y == 4 or y == ySize - 3 then term.setTextColour(blackText)
- elseif y == 5 or y == ySize - 4 then term.setTextColour(colours.grey)
- elseif y == 6 or y == ySize - 5 then term.setTextColour(colours.lightGrey)
- else term.setTextColour(colours.white) end
- term.write(thisString)
- end
- else
- term.setCursorPos(1, y)
- term.clearLine()
- end
- end
- lastPosition = position
- end
- end
- end
- end
- ---------------------------------------------
- ------------ Hologram Control ------------
- ---------------------------------------------
- local function clearHolo()
- for row = 1, #holo do for col = 1, #holo[row] do
- holo[row][col].setVelocity(0)
- holo[row][col].setRotation(0)
- holo[row][col].clear("minecraft:air", 0)
- end end
- end
- local function pset(x, y, col)
- x, y = x - 1, y - 1
- local subX, subY = rotate(bit.band(x, 7), bit.band(y, 7))
- if col == 0 then
- holo[bit.brshift(bit.band(y, 16777208), 3) + 1][bit.brshift(bit.band(x, 16777208), 3) + 1].setBlock(subX, 0, subY, "minecraft:air")
- else
- holo[bit.brshift(bit.band(y, 16777208), 3) + 1][bit.brshift(bit.band(x, 16777208), 3) + 1].setBlockMeta(subX, 0, subY, pal[col][1], pal[col][2])
- end
- end
- local function drawTile(x, y, bumpx, bumpy)
- local tile = grid[y][x]
- if not tile then return end
- xbump, ybump = (x - 1) * tileWidth, (y - 1) * tileHeight
- if bumpx and bumpy then
- if bumpx < 0 then for i = 1, tileHeight do pset(tileWidth + xbump + bumpx + 1, i + ybump + bumpy, 0) end
- elseif bumpx > 0 then for i = 1, tileHeight do pset(xbump + bumpx, i + ybump + bumpy, 0) end
- elseif bumpy < 0 then for i = 1, tileWidth do pset(i + xbump + bumpx, tileHeight + ybump + bumpy + 1, 0) end
- elseif bumpy > 0 then for i = 1, tileWidth do pset(i + xbump + bumpx, ybump + bumpy, 0) end end
- else bumpx, bumpy = 0, 0 end
- for y = 1, tileHeight do for x = 1, tileWidth do pset(x + xbump + bumpx, y + ybump + bumpy, tile[y][x]) end end
- end
- local function displayImage()
- local xbump, ybump = math.floor((sideLengthX - #image[1]) / 2), math.floor((sideLengthY - #image) / 2)
- for y = 1, #image do for x = 1, #image[1] do pset(x + xbump, y + ybump, image[y][x]) end end
- end
- ---------------------------------------------
- ------------ Game Funcs ------------
- ---------------------------------------------
- local function displayTimer()
- local h, m, s = 0, 0, 0
- while true do
- writeAt((h < 10 and "0" or "") .. tostring(h) .. ":" .. (m < 10 and "0" or "") .. tostring(m) .. ":" .. (s < 10 and "0" or "") .. tostring(s), 18, 9, colours.blue)
- s = s + 1
- if s > 59 then
- s = 0
- m = m + 1
- if m > 59 then
- m = 0
- h = h + 1
- end
- end
- sleep(1)
- end
- end
- local function doHint()
- writeAt("Displaying hint!", 6, 6, colours.black)
- displayImage()
- sleep(5)
- clearHolo()
- for y = 1, tilesPerSide do for x = 1, tilesPerSide do drawTile(x, y) end end
- writeAt("Game in progress", 6, 6, colours.black)
- end
- local function puzzleLoop()
- local hints, moves = 0, 0
- writeAt(tostring(hints), 18, 11, colours.blue)
- writeAt(tostring(moves), 18, 13)
- while correct ~= tiles do
- myEvent = {os.pullEvent()}
- if myEvent[1] == "hologramTouch" then
- myEvent[3], myEvent[5] = rotate(myEvent[3], myEvent[5])
- local touchx, touchy, alter = math.floor((myEvent[3] + holo[myEvent[7]][1] - 1) / tileWidth) + 1, math.floor((myEvent[5] + holo[myEvent[7]][2] - 1) / tileHeight) + 1
- if touchx == emptyTile.x and touchy == emptyTile.y + 1 then alter = alterOption[1]
- elseif touchx == emptyTile.x and touchy == emptyTile.y - 1 then alter = alterOption[2]
- elseif touchx == emptyTile.x + 1 and touchy == emptyTile.y then alter = alterOption[3]
- elseif touchx == emptyTile.x - 1 and touchy == emptyTile.y then alter = alterOption[4] end
- if alter then
- moves = moves + 1
- writeAt(tostring(moves), 18, 13, colours.blue)
- local tempx, tempy = 0, 0
- for i = 1, touchx == emptyTile.x and tileHeight or tileWidth do
- tempx, tempy = alter(tempx, tempy)
- drawTile(touchx, touchy, tempx, tempy)
- sleep(0.05)
- end
- tempx, tempy = touchx, touchy
- touchx, touchy = alter(touchx, touchy)
- grid[touchy][touchx] = grid[tempy][tempx]
- if grid[tempy][tempx].x == tempx and grid[tempy][tempx].y == tempy then correct = correct - 1 end
- if grid[touchy][touchx].x == touchx and grid[touchy][touchx].y == touchy then correct = correct + 1 end
- grid[tempy][tempx], emptyTile = nil, {["x"] = tempx, ["y"] = tempy}
- end
- elseif pressedKey(keys.h) or clickedAt(37, 48, 8) then
- hints = hints + 1
- writeAt(tostring(hints), 18, 11, colours.blue)
- doHint()
- elseif pressedKey(keys.x, keys.q) or clickedAt(39, 45, 13) then
- return
- end
- end
- end
- local function doPuzzle()
- local getImage = fileBrowser()
- if not getImage then return end
- clear(colours.black, colours.lightGrey)
- writeAt("Loading image...", 6, 6)
- loadImage(getImage, stretch)
- local line = {}
- for i = 1, tileWidth do line[i] = bit.band(i, 1) == 1 and 8 or 9 end
- for gridy = 1, tilesPerSide do
- local ybump = (gridy - 1) * tileHeight
- grid[gridy] = {}
- for gridx = 1, tilesPerSide do
- grid[gridy][gridx] = {["x"] = gridx, ["y"] = gridy}
- local xbump = (gridx - 1) * tileWidth
- for y = 1, tileHeight - 1 do
- grid[gridy][gridx][y] = {}
- for x = 1, tileWidth - 1 do grid[gridy][gridx][y][x] = image[ybump + y][xbump + x] end
- grid[gridy][gridx][y][tileWidth] = bit.band(y, 1) == 1 and 8 or 9
- end
- grid[gridy][gridx][tileHeight] = line
- end
- end
- local eX, eY = tilesPerSide, tilesPerSide
- grid[eX][eY] = nil
- for i = 1, 1000 do
- local cX, cY
- repeat cX, cY = alterOption[math.random(4)](eX, eY) until cX > 0 and cY > 0 and cX <= tilesPerSide and cY <= tilesPerSide
- grid[eY][eX] = grid[cY][cX]
- grid[cY][cX] = nil
- eX, eY = cX, cY
- end
- for y = 1, tilesPerSide do for x = 1, tilesPerSide do if x ~= eX and y ~= eY and grid[y][x].x == x and grid[y][x].y == y then correct = correct + 1 end end end
- emptyTile = {["x"] = eX, ["y"] = eY}
- doHint()
- writeAt("Time spent:", 6, 9, colours.grey)
- writeAt("Hints used:", 6, 11)
- writeAt("Moves used:", 6, 13)
- writeAt(" Use Hint ", 38, 8, colours.lightGrey, colours.grey)
- writeAt(" Exit ", 40, 13)
- term.setBackgroundColour(colours.lightGrey)
- parallel.waitForAny(displayTimer, puzzleLoop)
- if correct == tiles then
- writeAt("Puzzle complete!", 6, 6, colours.black)
- writeAt("Press any key to continue...", 6, 15)
- displayImage()
- repeat local myEvent = os.pullEvent() until myEvent == "key" or myEvent == "mouse_click"
- else clearHolo() end
- end
- ---------------------------------------------
- ------------ Viewer Funcs ------------
- ---------------------------------------------
- local function showImage()
- local myEvent, par1, par2, imgName
- while true do
- repeat myEvent, par1, par2 = os.pullEvent() until myEvent == "getImage" or myEvent == "showImage"
- if myEvent == "getImage" then
- imgName = fs.getName(par1)
- loadImage(par1, par2)
- os.queueEvent("loaded")
- else
- clearHolo()
- displayImage()
- image = nil
- term.setCursorPos(1, 7)
- term.setBackgroundColour(colours.lightGrey)
- term.clearLine()
- writeAt(imgName, math.floor((51 - #imgName) / 2) + 1, 7, colours.blue)
- end
- end
- end
- local function getIndex(thisVal, thisTable)
- for i = 1, #thisTable do if thisTable[i] == thisVal then return i end end
- end
- local function viewerLoop()
- local loaded, reveal, fileList, myTimer = false, true, {}
- local getImage, resizeMode, play, shuffle = fileBrowser(), scale, false, false
- if not getImage then return end
- do
- local fullList = fs.list(shell.resolve("."))
- for i = 1, #fullList do if fullList[i]:sub(#fullList[i] - 3):lower() == ".gif" then fileList[#fileList + 1] = shell.resolve(fullList[i]) end end
- table.sort(fileList, function (a, b) return string.lower(a) < string.lower(b) end)
- end
- clearHolo()
- clear(colours.black, colours.lightGrey)
- writeAt("Image Viewer", 20, 5)
- writeAt("Sizing:", 6, 9, colours.grey)
- writeAt("Slideshow:", 6, 11)
- writeAt("Ordering:", 6, 13)
- writeAt(" Scale ", 17, 9, colours.lightGrey, colours.blue)
- writeAt(" Pause ", 19, 11)
- writeAt(" Sequence ", 17, 13)
- writeAt(" Stretch ", 26, 9, colours.lightGrey, colours.grey)
- writeAt(" Center ", 37, 9)
- writeAt(" Play ", 34, 11)
- writeAt(" Random ", 33, 13)
- writeAt(" Exit ", 23, 15)
- os.queueEvent("getImage", getImage, resizeMode)
- local curIndex = getIndex(getImage, fileList)
- while true do
- myEvent = {os.pullEvent()}
- if myEvent[1] == "loaded" then
- loaded = true
- elseif myEvent[1] == "hologramTouch" or (myEvent[1] == "timer" and myEvent[2] == myTimer) then
- if play then reveal = true end
- elseif clickedAt(16, 24, 9) then
- writeAt(" Scale ", 17, 9, colours.lightGrey, colours.blue)
- writeAt(" Stretch ", 26, 9, colours.lightGrey, colours.grey)
- writeAt(" Center ", 37, 9)
- resizeMode = scale
- os.queueEvent("getImage", getImage, resizeMode)
- reveal = true
- elseif clickedAt(25, 35, 9) then
- writeAt(" Stretch ", 26, 9, colours.lightGrey, colours.blue)
- writeAt(" Scale ", 17, 9, colours.lightGrey, colours.grey)
- writeAt(" Center ", 37, 9)
- resizeMode = stretch
- os.queueEvent("getImage", getImage, resizeMode)
- reveal = true
- elseif clickedAt(36, 45, 9) then
- writeAt(" Center ", 37, 9, colours.lightGrey, colours.blue)
- writeAt(" Stretch ", 26, 9, colours.lightGrey, colours.grey)
- writeAt(" Scale ", 17, 9)
- resizeMode = center
- os.queueEvent("getImage", getImage, resizeMode)
- reveal = true
- elseif clickedAt(18, 26, 11) then
- writeAt(" Pause ", 19, 11, colours.lightGrey, colours.blue)
- writeAt(" Play ", 34, 11, colours.lightGrey, colours.grey)
- play = false
- elseif clickedAt(33, 40, 11) then
- writeAt(" Pause ", 19, 11, colours.lightGrey, colours.grey)
- writeAt(" Play ", 34, 11, colours.lightGrey, colours.blue)
- play = true
- curIndex = shuffle and math.random(#fileList) or (curIndex == #fileList and 1 or curIndex + 1)
- getImage = fileList[curIndex]
- os.queueEvent("getImage", getImage, resizeMode)
- myTimer = os.startTimer(10)
- elseif clickedAt(16, 27, 13) then
- writeAt(" Sequence ", 17, 13, colours.lightGrey, colours.blue)
- writeAt(" Random ", 33, 13, colours.lightGrey, colours.grey)
- shuffle = false
- elseif clickedAt(32, 41, 13) then
- writeAt(" Sequence ", 17, 13, colours.lightGrey, colours.grey)
- writeAt(" Random ", 33, 13, colours.lightGrey, colours.blue)
- shuffle = true
- elseif pressedKey(keys.x, keys.q) or clickedAt(22, 29, 15) then
- return
- end
- if loaded and reveal then
- loaded, reveal = false, false
- os.queueEvent("showImage")
- if play then
- curIndex = shuffle and math.random(#fileList) or (curIndex == #fileList and 1 or curIndex + 1)
- getImage = fileList[curIndex]
- os.queueEvent("getImage", getImage, resizeMode)
- myTimer = os.startTimer(10)
- end
- end
- end
- end
- ---------------------------------------------
- ------------ Config Funcs ------------
- ---------------------------------------------
- local function drawArrows()
- for i = 1, #holo[1] do for y = 1, 8 do for x = 1, 8 do pset(x + (i - 1) * 8, y, arrow[y][x]) end end end
- end
- local function doConfig()
- clear(colours.black, colours.lightGrey)
- writeAt("Calibration", 21, 6)
- local oldHolo = holo
- holo = {{peripheral.find("hologram_projector", function(name, object) object.side = name return true end)}}
- if #holo[1] == 0 then error("Slide requires access to hologram projectors, from RandomPeripherals.") end
- clearHolo()
- writeAt(" Rotate ", 19, 12, colours.lightGrey, colours.grey)
- writeAt(" Ok ", 29, 12)
- if fs.exists(shell.resolve("slide.cfg")) then writeAt(" Cancel ", 22, 15, colours.lightGrey, colours.grey) end
- writeAt("Align the arrows to point \"upwards\":", 8, 10, colours.grey, colours.lightGrey)
- local curRotate, oldRotate = 1, rotate
- rotate = rotateOption[curRotate]
- pal = {{"minecraft:stained_hardened_clay", 11}, {"minecraft:stained_hardened_clay", 3}, {"minecraft:stained_hardened_clay", 14}}
- drawArrows()
- repeat
- myEvent = {os.pullEvent("mouse_click")}
- if clickedAt(18, 27, 12) then
- curRotate = curRotate == 4 and 1 or (curRotate + 1)
- rotate = rotateOption[curRotate]
- drawArrows()
- rotate = oldRotate
- elseif clickedAt(21, 30, 15) and fs.exists(shell.resolve("slide.cfg")) then
- clearHolo()
- holo = oldHolo
- return
- end
- until clickedAt(28, 33, 12)
- term.setCursorPos(1, 10)
- term.clearLine()
- term.setCursorPos(1, 12)
- term.clearLine()
- local rowLength = math.ceil(math.sqrt(#holo[1]))
- writeAt(" < ", 18, 12, colours.lightGrey, colours.grey)
- writeAt(" > ", 26, 12)
- writeAt(" Ok ", 31, 12)
- writeAt("How many projectors per row?", 12, 10, colours.grey, colours.lightGrey)
- local thisString = tostring(rowLength)
- writeAt(thisString, 22 + math.floor((4 - #thisString) / 2), 12, colours.blue)
- repeat
- myEvent = {os.pullEvent("mouse_click")}
- if clickedAt(17, 21, 12) then
- rowLength = rowLength == 1 and #holo[1] or (rowLength - 1)
- elseif clickedAt(25, 29, 12) then
- rowLength = rowLength == #holo[1] and 1 or (rowLength + 1)
- elseif clickedAt(21, 30, 15) and fs.exists(shell.resolve("slide.cfg")) then
- clearHolo()
- holo = oldHolo
- return
- end
- writeAt(" ", 22, 12)
- thisString = tostring(rowLength)
- writeAt(thisString, 22 + math.floor((4 - #thisString) / 2), 12)
- until clickedAt(30, 35, 12) and #holo[1] % rowLength == 0
- local colLength = #holo[1] / rowLength
- term.setCursorPos(1, 10)
- term.clearLine()
- term.setCursorPos(1, 12)
- term.clearLine()
- writeAt("Click each tile above the projector", 9, 8, colours.grey)
- writeAt("in the snaking order shown below:", 10, 9)
- local map = {{0, 0}, {1, 0}, {2, 0}, {2, 1}, {1, 1}, {0, 1}, {0, 2}, {1, 2}, {2, 2}}
- local outList, x, y, counter, myTimer = {{}}, 1, 1, -1, os.startTimer(0)
- while true do
- myEvent = {os.pullEvent()}
- if myEvent[1] == "hologramTouch" then
- outList[y][x] = myEvent[7]
- peripheral.call(myEvent[7], "clear", "minecraft:air", 0)
- x = x + (bit.band(y, 1) == 1 and 1 or -1)
- if x > rowLength or x < 1 then
- y = y + 1
- x = (bit.band(y, 1) == 1 and 1 or rowLength)
- if y > colLength then break end
- outList[y] = {}
- end
- elseif myEvent[1] == "timer" and myEvent[2] == myTimer then
- counter = counter == 9 and 0 or (counter + 1)
- myTimer = os.startTimer(1)
- if counter == 0 then paintutils.drawFilledBox(25, 11, 27, 13, colours.grey) else writeAt(" ", 25 + map[counter][1], 11 + map[counter][2], nil, colours.lime) end
- elseif clickedAt(21, 30, 15) and fs.exists(shell.resolve("slide.cfg")) then
- clearHolo()
- holo = oldHolo
- return
- end
- end
- term.setCursorPos(1, 10)
- term.clearLine()
- term.setCursorPos(1, 11)
- term.clearLine()
- holo = {}
- for y = 1, colLength do
- holo[y] = {}
- for x = 1, rowLength do holo[y][x] = peripheral.wrap(outList[y][x]) end
- end
- sideLengthX, sideLengthY, tileWidth, tileHeight, rotate = rowLength * 8, colLength * 8, rowLength * 2, colLength * 2, rotateOption[curRotate]
- local file = fs.open(shell.resolve("slide.cfg"), "w")
- file.writeLine(textutils.serialise({outList, curRotate}))
- file.close()
- clear(colours.black, colours.lightGrey)
- writeAt("Calibration", 21, 6)
- writeAt("Settings saved.", 4, 10, colours.grey)
- writeAt("Press any key to continue...", 6, 15)
- repeat local myEvent = os.pullEvent() until myEvent == "key" or myEvent == "mouse_click"
- end
- ---------------------------------------------
- ------------ Init ------------
- ---------------------------------------------
- if term.current().setTextScale then
- local setTextScale = term.current().setTextScale
- setTextScale(0.5)
- local scale = 5
- repeat
- setTextScale(scale)
- scale = scale - 0.5
- local xSize, ySize = term.getSize()
- until (xSize >= 50 and ySize >= 19) or scale == 0
- end
- xSize, ySize = term.getSize()
- if xSize < 50 or ySize < 19 or not term.isColour() then error("Sorry, a 50x19 colour display is required at minimum.") end
- term.setTextColour(colours.black)
- term.setBackgroundColour(colours.orange)
- for j = 0, 1 do for i = 1, 3 do
- term.setCursorPos(1, i + (j * (ySize - 3)))
- term.clearLine()
- end end
- term.setCursorPos(5, 2)
- term.write("Slide", 5, 2)
- paintutils.drawPixel(1, 1, colours.blue)
- paintutils.drawPixel(2, 1, colours.green)
- paintutils.drawPixel(3, 1, colours.yellow)
- paintutils.drawPixel(1, 2, colours.grey)
- paintutils.drawPixel(2, 2, colours.white)
- paintutils.drawPixel(3, 2, colours.lightBlue)
- paintutils.drawPixel(1, 3, colours.orange)
- paintutils.drawPixel(3, 3, colours.red)
- paintutils.drawPixel(2, 3, colours.lime)
- if fs.exists(shell.resolve("slide.cfg")) then
- local file = fs.open(shell.resolve("slide.cfg"), "r")
- local input = textutils.unserialise(file.readAll())
- file.close()
- holo, rotate = input[1], rotateOption[input[2]]
- sideLengthX, sideLengthY = #holo[1], #holo
- for y = 1, sideLengthY do for x = 1, sideLengthX do
- local key = holo[y][x]
- holo[y][x] = peripheral.wrap(key)
- if not holo[y][x] then error("Config file refers to missing projector \""..key.."\" at position "..tostring(x).."x"..tostring(y)..". Either connect it, or delete the file to enable reconfiguration (using \"rm slide.cfg\").") end
- holo[key] = {(x - 1) * 8 + 1, (y - 1) * 8 + 1}
- end end
- sideLengthX, sideLengthY = sideLengthX * 8, sideLengthY * 8
- tileWidth, tileHeight = sideLengthX / 4, sideLengthY / 4
- else doConfig() end
- clearHolo()
- ---------------------------------------------
- ------------ Main Program Loop ------------
- ---------------------------------------------
- while true do
- if redraw then
- clear(colours.black, colours.lightGrey)
- writeAt("What Do?", 22, 6)
- writeAt(" Game ", 23, 8, colours.lightGrey, colours.grey)
- writeAt(" Viewer ", 22, 10)
- writeAt(" Calibrate ", 21, 12)
- writeAt(" Quit ", 23, 14)
- else redraw = true end
- repeat myEvent = {os.pullEvent()} until myEvent[1] == "key" or myEvent[1] == "mouse_click"
- if clickedAt(22, 29, 8) then
- doPuzzle()
- elseif clickedAt(21, 30, 10) then
- parallel.waitForAny(showImage, viewerLoop)
- elseif clickedAt(20, 32, 12) then
- doConfig()
- elseif pressedKey(keys.x, keys.q) or clickedAt(22, 29, 14) then
- if myEvent[1] == "key" then os.pullEvent("char") end
- break
- else redraw = false end
- end
- term.setTextColour(colours.white)
- term.setBackgroundColour(colours.black)
- term.clear()
- term.setCursorPos(1, 1)
- print("Thanks for playing!\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement