Compare commits
66 Commits
add-code-o
...
master
Author | SHA1 | Date |
---|---|---|
TheMrIron2 | 73aa45db2a | |
TheMrIron2 | 1840d91908 | |
TheMrIron2 | f2f2ade263 | |
TheMrIron2 | 350cbdf50d | |
TheMrIron2 | 39a286a303 | |
TheMrIron2 | b86ff1a6eb | |
TheMrIron2 | 94dc7f1f28 | |
TheMrIron2 | 392938c001 | |
TheMrIron2 | c7f77a8638 | |
TheMrIron2 | 340df7fa77 | |
TheMrIron2 | 53772635fe | |
TheMrIron2 | 2d870f3720 | |
TheMrIron2 | 31f7164172 | |
TheMrIron2 | 7618dbc499 | |
TheMrIron2 | d4bc0f1f2b | |
TheMrIron2 | 4620d602d9 | |
TheMrIron2 | 07fb7dfb0f | |
TheMrIron2 | 21292f781c | |
TheMrIron2 | d3dfb3eea3 | |
TheMrIron2 | d8d7216d0f | |
TheMrIron2 | 436f833172 | |
TheMrIron2 | 4f0fe98e5c | |
TheMrIron2 | 922cf0ffaf | |
TheMrIron2 | c82c11e803 | |
TheMrIron2 | f59a7d7c7e | |
Funey | d746640ebc | |
TheMrIron2 | 48ca1e3896 | |
byte-chan™ | 89a21efdea | |
byte-chan™ | 7e1a505dce | |
Funey | 4dbafc8e73 | |
Funey | c100d176f2 | |
Funey | f90ef059af | |
Funey | ad32374df6 | |
TheMrIron2 | 327a64a099 | |
TheMrIron2 | 304d8bde5b | |
TheMrIron2 | 03e5e5b948 | |
TheMrIron2 | d31f131c63 | |
TheMrIron2 | 773d35eaf9 | |
TheMrIron2 | 67a4f4d52c | |
TheMrIron2 | 64fb5bd16e | |
TheMrIron2 | cb1c1b4b57 | |
byte-chan™ | 20de8834e6 | |
TheMrIron2 | 4066cbdb1b | |
TheMrIron2 | 8cafaedbad | |
TheMrIron2 | 1db7679e5c | |
TheMrIron2 | bc9563ab65 | |
TheMrIron2 | adf36fa5f9 | |
TheMrIron2 | 9c5281f887 | |
TheMrIron2 | 16d67ddd5a | |
TheMrIron2 | 416bc4754b | |
TheMrIron2 | 514485b6c1 | |
TheMrIron2 | cfbb838ce5 | |
byte-chan™ | 4c674261dc | |
TheMrIron2 | 032bdb5505 | |
TheMrIron2 | ece46823b4 | |
byte-chan™ | f17b4b555e | |
byte-chan™ | ddffbc658f | |
TheMrIron2 | dec4b62c09 | |
TheMrIron2 | 1a934b9720 | |
TheMrIron2 | d27b302d88 | |
TheMrIron2 | c8b10714f6 | |
TheMrIron2 | b2dfb7525d | |
TheMrIron2 | ed57b5de54 | |
TheMrIron2 | 0c080cf538 | |
TheMrIron2 | 738ba2c372 | |
TheMrIron2 | 68046a654c |
|
@ -0,0 +1,24 @@
|
||||||
|
-- Simple test for QLink status
|
||||||
|
|
||||||
|
local modem = peripheral.find("modem")
|
||||||
|
modem.open(6464)
|
||||||
|
modem.transmit(6464,6464,{sType = "requestStatus"})
|
||||||
|
local t = os.startTimer(2)
|
||||||
|
while true do
|
||||||
|
local e = {os.pullEvent()}
|
||||||
|
if e[1] == "modem_message" then
|
||||||
|
if e[3] == 6464 then
|
||||||
|
if type(e[5]) == "table" then
|
||||||
|
if e[5].sType then
|
||||||
|
if e[5].sType == "status" then
|
||||||
|
print("C64 Status: "..e[5].sContents)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif e[1] == "timer" then
|
||||||
|
print("C64 Status:")
|
||||||
|
print("Error: Could not connect to server")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
23
README.md
23
README.md
|
@ -1,17 +1,24 @@
|
||||||
# Commander 64
|
# Commander 64
|
||||||
|
|
||||||
The workstation computer.
|
Commander 64 is the first workstation computer for ComputerCraft. Featuring unrivalled efficiency with specialised APIs, minimal design to ensure that your C64 has as much overhead as possible and monochrome design allowing it to run on any computer, Commander 64 is the computer for all of your workstation needs.
|
||||||
|
|
||||||
## Featuring:
|
## Features:
|
||||||
|
|
||||||
### - Q-Link Online Service - connect your C64 to the internet!
|
The Q-Link online service allows your Commander 64 to communicate wirelessly over the internet. Q-Link is an intuitive system where programs connect to the Q-Link server before proceeding online to ensure that you are a legitimate user. This keeps everything unified by ensuring your system is correctly functional and works well online and by authentication it makes sure nobody unwanted ruins the experience.
|
||||||
|
|
||||||
### - Creativity machine - play your music on as many iron note blocks as you want and use tools like NBS Studio.
|
Commander 64 is a machine built for those who want to do *more*. With NBS and other tools, you can unleash your best music on as many iron note blocks as you could want. Commander 64 also makes development interesting - with flexible CPU, GPU and IOP APIs designed to replicate their counterparts with concise but clear code, along with minimalistic design to make it just you and the machine, ComputerCraft programming just got more interesting. C64 can also be a gaming machine - the C64 is capable of delivering improved gaming experiences using its special APIs, so you can take a break from your work.
|
||||||
|
|
||||||
### - Pure productivity - just the necessities. Less time wasted = more productivity.
|
## Installation
|
||||||
|
|
||||||
### - Development made interesting - with flexible CPU, GPU and IOP APIs designed to replicate their counterparts with concise but clear code, ComputerCraft programming just got more interesting.
|
Get the C64 files here:
|
||||||
|
|
||||||
### - A gaming machine; play a selection of games for a well earned break
|
- pastebin get PPsK13XD /startup
|
||||||
|
- pastebin get zABhn8nQ /apis/cpu.lua
|
||||||
|
- pastebin get vmGUPHtP /apis/gpu.lua
|
||||||
|
- pastebin get RuXLZSKf /apis/iop.lua
|
||||||
|
|
||||||
Coming Soon.
|
### Server installation
|
||||||
|
- Server startup file: pastebin get 5qqg2rWu startup
|
||||||
|
|
||||||
|
|
||||||
|
[Proper installer coming soon.]
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
-- OFFICIAL GAME FUSION 2017 COMMANDER 64 DEVELOPMENT KIT
|
||||||
|
-- Licensed for use for the general public
|
||||||
|
|
||||||
|
os.loadAPI("/apis/gpu")
|
||||||
|
|
||||||
|
local function draw()
|
||||||
|
gpu.setText("black")
|
||||||
|
gpu.setBg("white")
|
||||||
|
gpu.center(3," Official C64 SDK ")
|
||||||
|
gpu.center(6," 1. Lua IDE ")
|
||||||
|
gpu.center(8," 2. Game Dev. Setup ")
|
||||||
|
gpu.center(10," 3. Shut down ")
|
||||||
|
gpu.cursPos(1,18)
|
||||||
|
print("BETA")
|
||||||
|
gpu.setBg("black")
|
||||||
|
gpu.setText("white")
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do draw()
|
||||||
|
local event,key = os.pullEvent("key")
|
||||||
|
if key == keys.one then
|
||||||
|
shell.run("/.dev/ide")
|
||||||
|
elseif key == keys.two then
|
||||||
|
shell.run("/.dev/sdk")
|
||||||
|
elseif key == keys.three then
|
||||||
|
os.shutdown()
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
theme: jekyll-theme-slate
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
||||||
|
-- OFFICIAL GAME FUSION 2017 COMMANDER 64 DEVELOPMENT KIT
|
||||||
|
-- Licensed for use for the general public
|
||||||
|
|
||||||
|
os.loadAPI("/apis/gpu")
|
||||||
|
|
||||||
|
local function draw()
|
||||||
|
gpu.setText("black")
|
||||||
|
gpu.setBg("white")
|
||||||
|
gpu.center(3," Official C64 SDK ")
|
||||||
|
gpu.center(6," 1. Lua IDE ")
|
||||||
|
gpu.center(8," 2. Game Dev. Setup ")
|
||||||
|
gpu.center(10," 3. Shut down ")
|
||||||
|
gpu.cursPos(1,18)
|
||||||
|
print("BETA")
|
||||||
|
gpu.setBg("black")
|
||||||
|
gpu.setText("white")
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do draw()
|
||||||
|
local event,key = os.pullEvent("key")
|
||||||
|
if key == keys.one then
|
||||||
|
shell.run("/.dev/ide")
|
||||||
|
elseif key == keys.two then
|
||||||
|
-- shell.run("/.dev/sdk")
|
||||||
|
gpu.center(7, "Option not available!")
|
||||||
|
gpu.center(9, "To make your programs run on disk,")
|
||||||
|
gpu.center(10, "simply place it at /disk/run.c64.")
|
||||||
|
elseif key == keys.three then
|
||||||
|
os.shutdown()
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,98 +1,92 @@
|
||||||
-- API for managing processor tasks
|
-- API for managing processor tasks
|
||||||
-- Including but not limited to calculations and process management
|
-- Including but not limited to calculations and process management
|
||||||
|
-- By Mr_Iron2 and MultMine
|
||||||
|
|
||||||
|
local version = 1.1
|
||||||
|
|
||||||
|
-- Basic math functionality
|
||||||
|
|
||||||
|
randomInt = math.random -- Random integer between X and Y, ie. cpu.randomInt(1, 100)
|
||||||
|
|
||||||
|
sqrt = math.sqrt -- Square root of a number
|
||||||
|
|
||||||
-- Bit API for bitwise binary manipulation
|
-- Bit API for bitwise binary manipulation
|
||||||
-- Bit already had simple syntax so it's largely the same
|
|
||||||
|
|
||||||
function blshift(n, bit) -- Shifts a number left by a specified number of bits
|
blshift = bit.blshift -- Shifts a number left by a specified number of bits
|
||||||
bit.blshift(n, bit)
|
|
||||||
end
|
|
||||||
|
|
||||||
function brshift(n, bit) -- Shifts a number right arithmetically by a specified number of bits
|
brshift = bit.brshift -- Shifts a number right arithmetically by a specified number of bits
|
||||||
bit.brshift(n, bit)
|
|
||||||
end
|
|
||||||
|
|
||||||
function blogic_rshift(n, bit) -- Shifts a number right logically by a specified number of bits
|
blogic_rshift = bit.blogic_rshift -- Shifts a number right logically by a specified number of bits
|
||||||
bit.blogic_rshift(n, bit)
|
|
||||||
end
|
|
||||||
|
|
||||||
function bxor(m, n) -- Computes the bitwise exclusive OR of two numbers
|
bxor = bit.bxor -- Computes the bitwise exclusive OR of two numbers
|
||||||
bit.bxor(m, n)
|
|
||||||
end
|
|
||||||
|
|
||||||
function bor(m, n) -- Computes the bitwise inclusive OR of two numbers
|
bor = bit.bor -- Computes the bitwise inclusive OR of two numbers
|
||||||
bit.bor(m, n)
|
|
||||||
end
|
|
||||||
|
|
||||||
function band(m, n) -- Computes the bitwise AND of two numbers
|
band = bit.band -- Computes the bitwise AND of two numbers
|
||||||
bit.band(m, n)
|
|
||||||
end
|
|
||||||
|
|
||||||
function bnot(n) -- Computes the bitwise NOT of a number
|
bnot = bit.bnot -- Computes the bitwise NOT of a number
|
||||||
bit.bnot(n)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Parallel functions
|
-- Parallel functions
|
||||||
-- Syntax intact for convenience
|
-- Syntax intact for convenience
|
||||||
|
|
||||||
function waitForAny(1, 2) -- Only 2 for now - will eventually get infinite threads
|
waitForAny = parallel.waitForAny -- infinite threads
|
||||||
parallel.waitForAny(1, 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
function waitForAll(1, 2)
|
waitForAll = parallel.waitForAll -- wait for all processes before proceeding
|
||||||
parallel.waitForAll(1, 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Multishell support for future multithreading/multishell(?)
|
-- Multishell support for future multithreading/multishell(?)
|
||||||
-- Multishell commands begin with t to indicate threading/multishell + to avoid conflicts
|
-- Multishell commands begin with t to indicate threading/multishell + to avoid conflicts
|
||||||
|
|
||||||
function tGetTitle(tab)
|
if multishell then
|
||||||
multishell.getTitle(tab)
|
tGetTitle = multishell.getTitle
|
||||||
|
tGetCount = multishell.getCount
|
||||||
|
tLaunch = multishell.launch
|
||||||
|
tSetFocus = multishell.setFocus
|
||||||
|
tSetTitle = multishell.setTitle
|
||||||
|
tGetFocus = multishell.getFocus
|
||||||
|
|
||||||
|
else
|
||||||
|
tGetTitle = function()
|
||||||
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
function tGetCount()
|
tGetCount = function()
|
||||||
multishell.getCount()
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function tLaunch(env, path)
|
tLaunch = function()
|
||||||
multishell.launch(env, path)
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function tSetFocus(tab)
|
tSetFocus = function()
|
||||||
multishell.setFocus(tab)
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function tSetTitle(tab, title)
|
tSetTItle = function()
|
||||||
multishell.setTitle(tab, title)
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function tGetTitle(tab)
|
tGetFocus = function()
|
||||||
multishell.getTitle(tab)
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
function tGetFocus(tab)
|
|
||||||
multishell.getFocus(tab)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Other processes
|
-- Other processes
|
||||||
-- eg. GPS, encoding and serialization
|
-- eg. GPS, encoding and serialization
|
||||||
|
|
||||||
function serialize(data)
|
startTimer = os.startTimer
|
||||||
textutils.serialize(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
function unserialize(data)
|
clock = os.clock
|
||||||
textutils.unserialize(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
function serializeJSON(data)
|
cancelTimer = os.cancelTimer
|
||||||
textutils.serializeJSON(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
function urlEncode(url)
|
sleep = os.sleep
|
||||||
textutils.urlEncode(url)
|
|
||||||
end
|
|
||||||
|
|
||||||
function locate(timeout)
|
serialize = textutils.serialize
|
||||||
gps.locate(timeout)
|
|
||||||
end
|
unserialize = textutils.unserialize
|
||||||
|
|
||||||
|
serializeJSON = textutils.serializeJSON
|
||||||
|
|
||||||
|
urlEncode = textutils.urlEncode
|
||||||
|
|
||||||
|
locate = gps.locate
|
||||||
|
|
|
@ -1,48 +1,51 @@
|
||||||
-- Minimalist graphics API by Mr_Iron2 for Commander 64
|
-- Advanced graphics API by Mr_Iron2 for Commander 64
|
||||||
-- Essentials from term, window, paintutils and textutils
|
-- Essentials from term, window, paintutils and textutils
|
||||||
|
-- Cleaned up and fixed by MultMine and Funey
|
||||||
|
|
||||||
-- Basic clear and colour functions
|
local version = 1.1
|
||||||
|
|
||||||
function blit(text, textcol, backcol)
|
-- Term clear and colour functions
|
||||||
term.blit(text, textcol, backcol)
|
|
||||||
end
|
|
||||||
|
|
||||||
function clr()
|
blit = term.blit
|
||||||
term.clear()
|
|
||||||
end
|
|
||||||
|
|
||||||
function center(y, string)
|
clr = term.clear
|
||||||
|
|
||||||
|
function center(y, str)
|
||||||
local w,h = term.getSize()
|
local w,h = term.getSize()
|
||||||
local x = (w/2)-(#string/2)
|
local x = (w/2)-(#str/2)
|
||||||
term.setCursorPos(x,y)
|
term.setCursorPos(x,y)
|
||||||
print(string)
|
print(str)
|
||||||
end
|
end
|
||||||
|
|
||||||
function cursPos(x,y)
|
cursPos = term.setCursorPos
|
||||||
term.setCursorPos(x,y)
|
|
||||||
end
|
|
||||||
|
|
||||||
function cursBlink(bool)
|
cursBlink = term.setCursorBlink
|
||||||
term.setCursorBlink(bool)
|
|
||||||
end
|
|
||||||
|
|
||||||
function centerSlow(y, string)
|
function centerSlow(y, str)
|
||||||
local w,h = term.getSize()
|
local w,h = term.getSize()
|
||||||
local x = (w/2)-(#string/2)
|
local x = (w/2)-(#str/2)
|
||||||
term.setCursorPos(x,y)
|
term.setCursorPos(x,y)
|
||||||
textutils.slowPrint(string)
|
textutils.slowPrint(str)
|
||||||
end
|
end
|
||||||
|
|
||||||
function setBg(col)
|
bg = term.setBackgroundColour
|
||||||
term.setBackgroundColour(colours.col)
|
|
||||||
|
write = term.write
|
||||||
|
|
||||||
|
function setBg(col) -- thanks to MultMine for fix
|
||||||
|
term.setBackgroundColour(colours[col])
|
||||||
end
|
end
|
||||||
|
|
||||||
function setTxt(col)
|
function setTxt(col)
|
||||||
term.setTextColour(colours.col)
|
term.setTextColour(colours[col])
|
||||||
|
end
|
||||||
|
|
||||||
|
function setText(col)
|
||||||
|
term.setTextColour(colours[col])
|
||||||
end
|
end
|
||||||
|
|
||||||
function clrBg(back)
|
function clrBg(back)
|
||||||
term.setBackgroundColour(colours.back)
|
term.setBackgroundColour(colours[back])
|
||||||
term.clear()
|
term.clear()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -53,66 +56,61 @@ end
|
||||||
|
|
||||||
-- Window/display commands
|
-- Window/display commands
|
||||||
|
|
||||||
function winSize()
|
winSize = term.getSize
|
||||||
term.getSize()
|
|
||||||
end
|
|
||||||
|
|
||||||
function newWindow(parent, x, y, w, h)
|
getSize = term.getSize
|
||||||
window.create(parent, x, y, w, h)
|
|
||||||
end
|
|
||||||
|
|
||||||
function current()
|
newWindow = window.create
|
||||||
term.current()
|
|
||||||
end
|
|
||||||
|
|
||||||
function redirect(target)
|
current = term.current
|
||||||
term.redirect(target)
|
|
||||||
end
|
|
||||||
|
|
||||||
function setVis(bool)
|
redirect = term.redirect
|
||||||
window.setVisible(bool)
|
|
||||||
|
function setVis(bool) -- both term.current and term.setVisible
|
||||||
|
local func = term.current().setVisible
|
||||||
|
if func then
|
||||||
|
func(bool)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function redraw()
|
function redraw()
|
||||||
window.redraw()
|
local func = term.current().redraw
|
||||||
|
if func then
|
||||||
|
func()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function monTxtScale(size)
|
function monTxtScale(size)
|
||||||
monitor.setTextScale(size)
|
local func = term.current().setTextScale
|
||||||
|
if func then
|
||||||
|
func(size)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Paintutils derived commands
|
-- Paintutils derived commands
|
||||||
|
|
||||||
function loadImg(src)
|
loadImg = paintutils.loadImage
|
||||||
paintutils.loadImage(src)
|
|
||||||
end
|
|
||||||
|
|
||||||
function drawImg(img, x, y)
|
drawImg = paintutils.drawImage
|
||||||
paintutils.drawImage(img, x, y)
|
|
||||||
end
|
|
||||||
|
|
||||||
function drawPixel(x, y)
|
function drawPixel(x, y, col)
|
||||||
paintutils.drawPixel(x, y)
|
paintutils.drawPixel(x, y, colours[col])
|
||||||
end
|
end
|
||||||
|
|
||||||
function drawLine(x1, y1, x2, y2, col)
|
function drawLine(x1, y1, x2, y2, col)
|
||||||
paintutils.drawLine(x1, y1, x2, y2, colours.col)
|
paintutils.drawLine(x1, y1, x2, y2, colours[col])
|
||||||
end
|
end
|
||||||
|
|
||||||
function drawBox(x1, y1, x2, y2, col)
|
function drawBox(x1, y1, x2, y2, col)
|
||||||
paintutils.drawBox(x1, y1, x2, y2, colours.col)
|
paintutils.drawBox(x1, y1, x2, y2, colours[col])
|
||||||
end
|
end
|
||||||
|
|
||||||
function drawFilledBox(x1, y1, x2, y2, col)
|
function drawFilledBox(x1, y1, x2, y2, col)
|
||||||
paintutils.drawFilledBox(x1, y1, x2, y2, colours.col)
|
paintutils.drawFilledBox(x1, y1, x2, y2, colours[col])
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Textutils commands
|
-- Textutils commands
|
||||||
|
|
||||||
function slowWrite(text, spd)
|
slowWrite = textutils.slowWrite
|
||||||
textutils.slowWrite(text, spd)
|
|
||||||
end
|
|
||||||
|
|
||||||
function slowPrint(text, spd)
|
slowPrint = textutils.slowPrint
|
||||||
textutils.slowPrint(text, spd)
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,190 +1,108 @@
|
||||||
-- API made to replicate an input/output processor (IOP)'s functionality
|
-- API made to replicate an input/output processor (IOP)'s functionality
|
||||||
|
-- By Mr_Iron2 and MultMine
|
||||||
|
|
||||||
-- OS functionality
|
-- OS
|
||||||
function run(string)
|
|
||||||
shell.run(string)
|
|
||||||
end
|
|
||||||
|
|
||||||
function loadAPI(api)
|
--run = shell.run
|
||||||
os.loadAPI(api)
|
|
||||||
end
|
|
||||||
|
|
||||||
function unloadAPI(api)
|
loadAPI = os.loadAPI
|
||||||
os.unloadAPI(api)
|
|
||||||
end
|
|
||||||
|
|
||||||
function pullEvt(string)
|
unloadAPI = os.unloadAPI
|
||||||
os.pullEvent(string)
|
|
||||||
end
|
|
||||||
|
|
||||||
--pullEvt == pullEvent need to experiment before implementing
|
qEvt = os.queueEvent
|
||||||
|
|
||||||
function pullEvtRaw(string)
|
queueEvent = os.queueEvent
|
||||||
os.pullEventRaw(string)
|
|
||||||
end
|
|
||||||
|
|
||||||
--pullEvtRaw == pullEventRaw
|
pullEvt = os.pullEvent
|
||||||
|
|
||||||
|
pullEvent = os.pullEvent
|
||||||
|
|
||||||
|
pullEventRaw = os.pullEventRaw
|
||||||
|
|
||||||
|
pullEvtRaw = os.pullEventRaw
|
||||||
|
|
||||||
-- FS management
|
-- FS management
|
||||||
|
|
||||||
function list(string)
|
list = fs.list
|
||||||
fs.list(string)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getName(path)
|
getName = fs.getName
|
||||||
fs.getName(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getDrive(path)
|
getDrive = fs.getDrive
|
||||||
fs.getDrive(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getSize(path)
|
getSize = fs.getSize
|
||||||
fs.getSize(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
function freeSpace(path)
|
freeSpace = fs.getFreeSpace
|
||||||
fs.getFreeSpace(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
--freeSpace == getFreeSpace
|
mkDir = fs.makeDir
|
||||||
|
|
||||||
function mkDir(path)
|
move = fs.move
|
||||||
fs.makeDir(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
function move(from, to)
|
copy = fs.copy
|
||||||
fs.move(from, to)
|
|
||||||
end
|
|
||||||
|
|
||||||
function copy(from, to)
|
delete = fs.delete
|
||||||
fs.copy(from, to)
|
|
||||||
end
|
|
||||||
|
|
||||||
function delete(path)
|
combine = fs.combine
|
||||||
fs.delete(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
function combine(base, local)
|
open = fs.open -- REMEMBER TO CLOSE AFTER OPENING, h.close
|
||||||
fs.combine(base, local)
|
|
||||||
end
|
|
||||||
|
|
||||||
function open(path, rw)
|
getDir = fs.getDir
|
||||||
fs.open(path, rw)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getDir(path)
|
|
||||||
fs.getDir(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Disk
|
-- Disk
|
||||||
|
|
||||||
function diskPresent(side)
|
diskPresent = disk.isPresent
|
||||||
disk.isPresent(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function diskHasData(side)
|
diskHasData = disk.hasData
|
||||||
disk.hasData(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function diskMountPath(side)
|
diskMountPath = disk.getMountPath
|
||||||
disk.getMountPath(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function setDiskLabel(side)
|
setDiskLabel = disk.setLabel
|
||||||
disk.setLabel(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getDiskLabel(side)
|
getDiskLabel = disk.getLabel
|
||||||
disk.getLabel(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getDiskID(side)
|
getDiskID = disk.getID
|
||||||
disk.getID(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function eject(side)
|
eject = disk.eject
|
||||||
disk.eject(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Peripherals
|
-- Peripherals
|
||||||
|
|
||||||
function pIsPresent(side)
|
pIsPresent = peripheral.isPresent
|
||||||
peripheral.isPresent(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function pGetType(side)
|
pGetType = peripheral.getType
|
||||||
peripheral.getType(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function pGetMethods(side)
|
pGetMethods = peripheral.getMethods
|
||||||
peripheral.getMethods(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function pCall(side, cmd)
|
pCall = peripheral.call
|
||||||
peripheral.call(side, cmd)
|
|
||||||
end
|
|
||||||
|
|
||||||
function pWrap(side)
|
pWrap = peripheral.wrap
|
||||||
peripheral.wrap(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function pFind(type)
|
pFind = peripheral.find
|
||||||
peripheral.find(type)
|
|
||||||
end
|
|
||||||
|
|
||||||
function pGetNames()
|
pGetNames = peripheral.getNames
|
||||||
peripheral.getNames()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Redstone
|
-- Redstone
|
||||||
|
|
||||||
function rGetSides()
|
rGetSides = rs.getSides
|
||||||
redstone.getSides()
|
|
||||||
end
|
|
||||||
|
|
||||||
function rGetInput(side)
|
rGetInput = rs.getInput
|
||||||
redstone.getInput(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function rSetOutput(side, bool)
|
rSetOutput = rs.setOutput
|
||||||
redstone.setOutput(side, bool)
|
|
||||||
end
|
|
||||||
|
|
||||||
function rGetOutput(side)
|
rGetOutput = rs.getOutput
|
||||||
redstone.getOutput(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function rGetAnalogInput(side)
|
rGetAnalogInput = rs.getAnalogInput
|
||||||
redstone.getAnalogInput(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function rSetAnalogOutput(side, strength)
|
rSetAnalogOutput = rs.setAnalogOutput
|
||||||
redstone.setAnalogOutput(side, strength)
|
|
||||||
end
|
|
||||||
|
|
||||||
function rGetAnalogOutput(side)
|
rGetAnalogOutput = rs.getAnalogOutput
|
||||||
redstone.getAnalogOutput(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function rGetBundledInput(side)
|
rGetBundledInput = rs.getBundledInput
|
||||||
redstone.getBundledInput(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function rGetBundledOutput
|
rGetBundledOutput = rs.getBundledOutput
|
||||||
redstone.getBundledOutput(side)
|
|
||||||
end
|
|
||||||
|
|
||||||
function rSetBundledOutput(side, col)
|
rSetBundledOutput = rs.setBundledOutput
|
||||||
redstone.setBundledOutput(side, colours.col)
|
|
||||||
end
|
|
||||||
|
|
||||||
function rTestBundledInput(side, col)
|
rTestBundledInput = rs.testBundledInput
|
||||||
redstone.testBundledInput(side, colours.col)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Misc
|
-- Misc
|
||||||
|
|
||||||
function getKeyName(code)
|
getKeyName = keys.getName
|
||||||
keys.getName(code)
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
os.loadAPI("/apis/gpu")
|
local version = 1.2
|
||||||
|
|
||||||
|
os.loadAPI("/apis/iop.lua")
|
||||||
|
os.loadAPI("/apis/gpu.lua")
|
||||||
|
os.loadAPI("/apis/cpu.lua")
|
||||||
|
|
||||||
|
local w,h = gpu.winSize()
|
||||||
|
|
||||||
local w,h = gpu.getSize()
|
|
||||||
local function start()
|
local function start()
|
||||||
gpu.setTxt(white)
|
gpu.setTxt("white")
|
||||||
gpu.clrBg(black)
|
gpu.clrBg("black")
|
||||||
gpu.center(9,"Welcome to Commander 64.")
|
gpu.center(9,"Welcome to Commander 64.")
|
||||||
sleep(1.25)
|
cpu.sleep(1.25)
|
||||||
gpu.clr()
|
gpu.clr()
|
||||||
end
|
end
|
||||||
start()
|
|
||||||
|
|
||||||
local function draw()
|
local function draw()
|
||||||
gpu.setBg(colours.white)
|
gpu.setBg("white")
|
||||||
gpu.drawBox(1,1,w,h)
|
gpu.drawBox(1,1,w,h)
|
||||||
gpu.setTxt(colours.white)
|
gpu.setTxt("white")
|
||||||
gpu.setBg(black)
|
gpu.setBg("black")
|
||||||
gpu.drawFilledBox(2,2,w-1,h-1)
|
gpu.drawFilledBox(2,2,w-1,h-1)
|
||||||
gpu.center(3,"*** COMMANDER 64 V1 ***")
|
gpu.center(3,"*** COMMANDER 64 V1 ***")
|
||||||
gpu.cursPos(2,5)
|
gpu.cursPos(2,5)
|
||||||
|
@ -23,20 +27,31 @@ gpu.cursPos(2,6)
|
||||||
gpu.cursBlink(true)
|
gpu.cursBlink(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
start()
|
||||||
|
|
||||||
while true do draw()
|
while true do draw()
|
||||||
if fs.exists("/disk/run.c64") then print("COMMANDER 64 DISK INSERTED")
|
-- local event,key = os.pullEvent("key")
|
||||||
sleep(0.5)
|
-- if key == keys.zero then shell.run("/.dev/devkit") -- make this disk-based now as of v1.2
|
||||||
print("LOADING")
|
|
||||||
sleep(0.5)
|
if fs.exists("/disk/run.c64") then
|
||||||
|
gpu.cursBlink(false)
|
||||||
|
gpu.slowPrint("COMMANDER 64 DISK INSERTED.")
|
||||||
|
cpu.sleep(0.5)
|
||||||
|
gpu.cursPos(2,7)
|
||||||
|
gpu.slowPrint("LOADING...")
|
||||||
|
cpu.sleep(0.5)
|
||||||
shell.run("/disk/run.c64")
|
shell.run("/disk/run.c64")
|
||||||
elseif fs.exists("/disk/update.c64") then print("UPDATE AVAILABLE!")
|
|
||||||
sleep(0.75)
|
elseif fs.exists("/disk/update.c64") then
|
||||||
print("To cancel this update, please shut down")
|
print("UPDATE AVAILABLE!")
|
||||||
print("(Hold CTRL + S to shut down)")
|
cpu.sleep(0.75)
|
||||||
sleep(0.75)
|
print("To cancel this update, please shut down (CTRL + S)")
|
||||||
|
cpu.sleep(0.75)
|
||||||
print("Update beginning in 10 seconds...")
|
print("Update beginning in 10 seconds...")
|
||||||
sleep(10)
|
cpu.sleep(10)
|
||||||
shell.run("/disk/update.c64")
|
shell.run("/disk/update.c64")
|
||||||
else sleep() --prevent "too long without yielding"
|
|
||||||
|
else cpu.sleep() --prevent "too long without yielding"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,69 @@
|
||||||
|
-- Commodore Cloud
|
||||||
|
-- Based upon Revolution's GRID/Cloud
|
||||||
|
-- Powered by Q-Link
|
||||||
|
|
||||||
|
local function gridTitle()
|
||||||
|
gpu.setTxt("white")
|
||||||
|
gpu.clrBg("black")
|
||||||
|
gpu.center(1,"Commodore Cloud")
|
||||||
|
gpu.setBg("white")
|
||||||
|
gpu.cursPos(1,2)
|
||||||
|
gpu.clrLine()
|
||||||
|
gpu.setBg("black")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function terminated()
|
||||||
|
gridTitle()
|
||||||
|
gpu.center(4,"Sorry!")
|
||||||
|
gpu.center(6,"Q-Link has been terminated.")
|
||||||
|
gpu.center(7,"The Commodore Cloud service is unavailable.")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- will check for QLink later, need to test
|
||||||
|
|
||||||
|
gridTitle()
|
||||||
|
gpu.center(4,"Welcome to Commodore Cloud!")
|
||||||
|
gpu.center(5,"This is the Commodore game streaming")
|
||||||
|
gpu.center(6,"service. You can stream great games straight")
|
||||||
|
gpu.center(7,"to your Commodore!")
|
||||||
|
sleep(2)
|
||||||
|
|
||||||
|
local function render()
|
||||||
|
gridTitle()
|
||||||
|
gpu.setTxt("white")
|
||||||
|
gpu.center(5,"Select a Game:")
|
||||||
|
gpu.center(7,"1. Cookie Clicker")
|
||||||
|
gpu.center(9,"2. BATTLE")
|
||||||
|
gpu.center(11,"3. Solitaire")
|
||||||
|
gpu.center(13,"4. TRON")
|
||||||
|
gpu.center(15,"5. Skyfall")
|
||||||
|
gpu.center(17,"Press Space to exit")
|
||||||
|
end
|
||||||
|
render()
|
||||||
|
|
||||||
|
while true do local evt, button, x, y = os.pullEvent("keys")
|
||||||
|
if key == keys.one then
|
||||||
|
gpu.clrBg("black")
|
||||||
|
shell.run("pastebin run JknhWZ2a")
|
||||||
|
render()
|
||||||
|
elseif key == keys.two then
|
||||||
|
gpu.clrBg("black")
|
||||||
|
shell.run("pastebin run MbvMiiCU")
|
||||||
|
render()
|
||||||
|
elseif key == keys.three then
|
||||||
|
gpu.clrBg("black")
|
||||||
|
shell.run("pastebin run wg6xLisV")
|
||||||
|
render()
|
||||||
|
elseif key == keys.four then
|
||||||
|
gpu.clrBg("black")
|
||||||
|
shell.run("pastebin run fuL9BpjX")
|
||||||
|
render()
|
||||||
|
elseif key == keys.five then
|
||||||
|
gpu.clrBg("black")
|
||||||
|
shell.run("pastebin run mjyCbPks")
|
||||||
|
render()
|
||||||
|
elseif key == keys.six then
|
||||||
|
shell.run("/startup")
|
||||||
|
render()
|
||||||
|
else end
|
||||||
|
end
|
|
@ -0,0 +1,347 @@
|
||||||
|
-- LaserBlast by NitrogenFingers
|
||||||
|
-- Port and optimisation by Mr_Iron2
|
||||||
|
-- Note: Requires latest APIs
|
||||||
|
|
||||||
|
os.loadAPI("/apis/gpu.lua")
|
||||||
|
os.loadAPI("/apis/cpu.lua")
|
||||||
|
os.loadAPI("/apis/iop.lua")
|
||||||
|
|
||||||
|
local w,h = gpu.winSize()
|
||||||
|
local plpos = math.floor(w/2)
|
||||||
|
|
||||||
|
--music stuff
|
||||||
|
local minterval = 1
|
||||||
|
local mtimer = 1
|
||||||
|
local left = false
|
||||||
|
|
||||||
|
local level = 1
|
||||||
|
local score = 0
|
||||||
|
local gameover = false
|
||||||
|
local killc = 0
|
||||||
|
|
||||||
|
--x,y,dir
|
||||||
|
local projlist = {}
|
||||||
|
--x,y,intvspeed,dtimer
|
||||||
|
local baddylist = {}
|
||||||
|
local btimer = 0
|
||||||
|
local bintv = 1
|
||||||
|
local utime = 0.05
|
||||||
|
local bsmp = 6
|
||||||
|
local powerup = 0
|
||||||
|
|
||||||
|
--Landscape and stars
|
||||||
|
local stars = {}
|
||||||
|
for i=1,math.random()*10+10 do
|
||||||
|
stars[i] = { x = math.ceil(math.random()*w),
|
||||||
|
y = math.ceil(math.random() * h-8) }
|
||||||
|
end
|
||||||
|
local landscape = {
|
||||||
|
[6]=" ___________________ ";
|
||||||
|
[5]=" _______/ \\_____ ";
|
||||||
|
[4]=" ____// \\________ \\_________";
|
||||||
|
[3]=" / / \\ ";
|
||||||
|
[2]=" / / \\_________ ";
|
||||||
|
[1]="_/____/ \\______________";
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawHeader()
|
||||||
|
if term.isColour() then gpu.setTxt("white") end
|
||||||
|
gpu.cursPos(5, 1)
|
||||||
|
gpu.write("Score: "..score)
|
||||||
|
if score~=0 then gpu.write("00") end
|
||||||
|
local lstr = "Level: "..level
|
||||||
|
gpu.cursPos(w-#lstr-5,1)
|
||||||
|
gpu.write(lstr)
|
||||||
|
|
||||||
|
if powerup > 0 then
|
||||||
|
local pstr = "POWERUP"
|
||||||
|
gpu.cursPos(w/2 - #pstr/2,1)
|
||||||
|
if term.isColour() then gpu.setTxt("cyan") end
|
||||||
|
gpu.write(pstr)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawPlayer()
|
||||||
|
if term.isColour() then gpu.setTxt("white") end
|
||||||
|
gpu.cursPos(plpos-1, h-1)
|
||||||
|
gpu.write("@@@")
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawProjectile(proj)
|
||||||
|
if term.isColour() then gpu.setTxt("red") end
|
||||||
|
gpu.cursPos(proj.x, proj.y)
|
||||||
|
gpu.write("|")
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawVacance(x,y)
|
||||||
|
gpu.cursPos(x, y)
|
||||||
|
for _,baddy in pairs(baddylist) do
|
||||||
|
if baddy.x == x and baddy.y == y and baddy.dtimer > 0 then
|
||||||
|
drawBaddie(baddy)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if y >= h-8 and y <= h-3 then
|
||||||
|
if term.isColour() then gpu.setTxt("lime") end
|
||||||
|
gpu.write(string.sub(landscape[h - y - 2], x, x))
|
||||||
|
elseif y < h-8 then
|
||||||
|
for i=1,#stars do
|
||||||
|
if x == stars[i].x and y == stars[i].y then
|
||||||
|
if term.isColour() then gpu.setTxt("yellow") end
|
||||||
|
gpu.write(".")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
gpu.write(" ")
|
||||||
|
else
|
||||||
|
gpu.write(" ")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawBaddie(baddy)
|
||||||
|
gpu.cursPos(baddy.x, baddy.y)
|
||||||
|
if baddy.dtimer==0 then
|
||||||
|
if baddy.pup then
|
||||||
|
if term.isColour() then gpu.setTxt("blue") end
|
||||||
|
gpu.write("P")
|
||||||
|
elseif baddy.frag then
|
||||||
|
if term.isColour() then gpu.setTxt("brown") end
|
||||||
|
gpu.write("*")
|
||||||
|
else
|
||||||
|
if term.isColour() then gpu.setTxt("brown") end
|
||||||
|
gpu.write("O")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if term.isColour() then gpu.setTxt("orange") end
|
||||||
|
gpu.write("#")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawWorld()
|
||||||
|
drawLandscape()
|
||||||
|
drawPlayer()
|
||||||
|
drawHeader()
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawLandscape()
|
||||||
|
if term.isColour() then
|
||||||
|
gpu.setTxt("yellow")
|
||||||
|
end
|
||||||
|
for i=1,#stars do
|
||||||
|
gpu.cursPos(stars[i].x, stars[i].y)
|
||||||
|
gpu.write(".")
|
||||||
|
end
|
||||||
|
|
||||||
|
gpu.cursPos(1,h)
|
||||||
|
local land = string.rep("-", w)
|
||||||
|
if term.isColour() then
|
||||||
|
gpu.setTxt("green")
|
||||||
|
end
|
||||||
|
gpu.write(land)
|
||||||
|
if term.isColour() then
|
||||||
|
gpu.setTxt("lime")
|
||||||
|
end
|
||||||
|
|
||||||
|
for y,line in ipairs(landscape) do
|
||||||
|
gpu.cursPos(1,h-y-2)
|
||||||
|
gpu.write(line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function updateWorld()
|
||||||
|
--Music
|
||||||
|
iop.rSetOutput("back", false)
|
||||||
|
mtimer=mtimer-utime
|
||||||
|
if mtimer<=0 then
|
||||||
|
mtimer = minterval
|
||||||
|
if left then
|
||||||
|
iop.rSetOutput("left", true)
|
||||||
|
iop.rSetOutput("right", false)
|
||||||
|
else
|
||||||
|
iop.rSetOutput("left", false)
|
||||||
|
iop.rSetOutput("right", true)
|
||||||
|
end
|
||||||
|
left = not left
|
||||||
|
end
|
||||||
|
|
||||||
|
local i=1
|
||||||
|
while i<=#projlist do
|
||||||
|
drawVacance(projlist[i].x, projlist[i].y)
|
||||||
|
projlist[i].y = projlist[i].y+projlist[i].dir
|
||||||
|
if projlist[i].y <= 1 or projlist[i].y > h-1 then
|
||||||
|
table.remove(projlist,i)
|
||||||
|
i=i-1
|
||||||
|
else drawProjectile(projlist[i]) end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
i=1
|
||||||
|
while i<=#baddylist do
|
||||||
|
local baddy = baddylist[i]
|
||||||
|
baddy.timer=baddy.timer+utime
|
||||||
|
|
||||||
|
if baddy.y==h-1 and math.abs(baddy.x-plpos)<2 then
|
||||||
|
if baddy.pup then
|
||||||
|
powerup = 10
|
||||||
|
drawPlayer()
|
||||||
|
else
|
||||||
|
gameover = true
|
||||||
|
iop.rSetOutput("back", true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
j=1
|
||||||
|
while j<=#projlist do
|
||||||
|
local proj = projlist[j]
|
||||||
|
if baddy.x==proj.x and math.abs(baddy.y-proj.y)<2
|
||||||
|
and baddy.dtimer==0 then
|
||||||
|
baddy.dtimer = 0.5
|
||||||
|
drawBaddie(baddy)
|
||||||
|
drawVacance(projlist[j].x, projlist[j].y)
|
||||||
|
table.remove(projlist,j)
|
||||||
|
j=j-1
|
||||||
|
score=score+5
|
||||||
|
iop.rSetOutput("back", true)
|
||||||
|
killc=killc+1
|
||||||
|
if killc>5+(level*5) and level<10 then levelUp() end
|
||||||
|
drawHeader()
|
||||||
|
|
||||||
|
--Adds fragments
|
||||||
|
if math.random(1, 5) == 2 and not baddy.frag then
|
||||||
|
table.insert(baddylist, {
|
||||||
|
x = baddy.x-1,
|
||||||
|
y = baddy.y,
|
||||||
|
pup = false,
|
||||||
|
frag = true,
|
||||||
|
timer = 0,
|
||||||
|
dtimer = 0,
|
||||||
|
speed = baddy.speed/2
|
||||||
|
})
|
||||||
|
drawBaddie(baddylist[#baddylist])
|
||||||
|
table.insert(baddylist, {
|
||||||
|
x = baddy.x+1,
|
||||||
|
y = baddy.y,
|
||||||
|
pup = false,
|
||||||
|
frag = true,
|
||||||
|
timer = 0,
|
||||||
|
dtimer = 0,
|
||||||
|
speed = baddy.speed/2
|
||||||
|
})
|
||||||
|
drawBaddie(baddylist[#baddylist])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
j=j+1
|
||||||
|
end
|
||||||
|
|
||||||
|
if baddy.timer>baddy.speed and baddy.dtimer==0 then
|
||||||
|
drawVacance(baddy.x, baddy.y)
|
||||||
|
baddy.y=baddy.y+1
|
||||||
|
if baddy.y==h then
|
||||||
|
table.remove(baddylist,i)
|
||||||
|
i=i-1
|
||||||
|
score=score-1
|
||||||
|
drawHeader()
|
||||||
|
else
|
||||||
|
drawBaddie(baddy)
|
||||||
|
baddy.timer = 0
|
||||||
|
end
|
||||||
|
elseif baddy.dtimer>0 then
|
||||||
|
baddy.dtimer=baddy.dtimer-utime
|
||||||
|
if baddy.dtimer<=0 then
|
||||||
|
drawVacance(baddy.x, baddy.y)
|
||||||
|
table.remove(baddylist,i)
|
||||||
|
i=i-1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
btimer=btimer+utime
|
||||||
|
if btimer > bintv then
|
||||||
|
table.insert(baddylist, {
|
||||||
|
x = math.random(w/4, 3*(w/4)),
|
||||||
|
y = 2,
|
||||||
|
speed = utime*bsmp,
|
||||||
|
timer = 0,
|
||||||
|
dtimer = 0,
|
||||||
|
pup = math.random(1,20)==5,
|
||||||
|
frag = false
|
||||||
|
})
|
||||||
|
drawBaddie(baddylist[#baddylist])
|
||||||
|
btimer=0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function levelUp()
|
||||||
|
level=level+1
|
||||||
|
bintv=bintv-0.10
|
||||||
|
bsmp=bsmp-0.5
|
||||||
|
killc=0
|
||||||
|
minterval=minterval-0.10
|
||||||
|
end
|
||||||
|
|
||||||
|
function updatePlayer(key)
|
||||||
|
if powerup>0 then
|
||||||
|
powerup = powerup-utime
|
||||||
|
end
|
||||||
|
|
||||||
|
if key==203 and plpos>1 then
|
||||||
|
gpu.cursPos(plpos+1,h-1)
|
||||||
|
gpu.write(" ")
|
||||||
|
plpos=plpos-1
|
||||||
|
drawPlayer()
|
||||||
|
elseif key==205 and plpos<w then
|
||||||
|
gpu.cursPos(plpos-1,h-1)
|
||||||
|
gpu.write(" ")
|
||||||
|
plpos=plpos+1
|
||||||
|
drawPlayer()
|
||||||
|
elseif key==57 then
|
||||||
|
if powerup>0 then
|
||||||
|
table.insert(projlist, {
|
||||||
|
dir = -1,
|
||||||
|
x = plpos+1,
|
||||||
|
y = h-2
|
||||||
|
})
|
||||||
|
drawProjectile(projlist[#projlist])
|
||||||
|
table.insert(projlist, {
|
||||||
|
dir = -1,
|
||||||
|
x = plpos-1,
|
||||||
|
y = h-2
|
||||||
|
})
|
||||||
|
drawProjectile(projlist[#projlist])
|
||||||
|
else
|
||||||
|
table.insert(projlist, {
|
||||||
|
dir = -1,
|
||||||
|
x = plpos,
|
||||||
|
y = h-2
|
||||||
|
})
|
||||||
|
drawProjectile(projlist[#projlist])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
gpu.clrBg("black")
|
||||||
|
drawWorld()
|
||||||
|
local wtimer cpu.startTimer(utime)
|
||||||
|
while not gameover do
|
||||||
|
local e, v = iop.pullEvt()
|
||||||
|
|
||||||
|
if e=="timer" then
|
||||||
|
updateWorld()
|
||||||
|
wtimer = cpu.startTimer(utime)
|
||||||
|
elseif e=="key" then
|
||||||
|
if v==28 then break end
|
||||||
|
updatePlayer(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
gpu.cursPos(plpos-1, h-1)
|
||||||
|
if term.isColour() then gpu.setTxt("red") end
|
||||||
|
gpu.write("###")
|
||||||
|
local go = "Game Over!"
|
||||||
|
gpu.cursPos(w/2 - #go/2, 10)
|
||||||
|
if term.isColour() then gpu.setTxt("white") end
|
||||||
|
gpu.write(go)
|
||||||
|
gpu.cursPos(1,h)
|
||||||
|
cpu.sleep(5)
|
||||||
|
iop.rSetOutput("back", false)
|
||||||
|
gpu.clrBg("black")
|
|
@ -0,0 +1,279 @@
|
||||||
|
--[[ Skyfall
|
||||||
|
By Nitrogenfingers
|
||||||
|
]]--
|
||||||
|
|
||||||
|
-- An optimised port of Skyfall by NitrogenFingers to C64
|
||||||
|
-- Ported by Mr_Iron2
|
||||||
|
|
||||||
|
os.loadAPI("/apis/gpu")
|
||||||
|
|
||||||
|
-- Gonow32's Colour to Monochrome wrapper
|
||||||
|
|
||||||
|
local current = term.current()
|
||||||
|
term.redirect(window.create(current,1,1,current.getSize()))
|
||||||
|
|
||||||
|
if not term.isColour() then
|
||||||
|
local oldback = gpu.setBg
|
||||||
|
function gpu.setBg("colour")
|
||||||
|
if colour == 1 then
|
||||||
|
oldback(colour)
|
||||||
|
else
|
||||||
|
oldback(colours.black)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local oldtext = gpu.setTxt
|
||||||
|
function gpu.setTxt(colour)
|
||||||
|
if colour == 32768 then
|
||||||
|
oldtext(colour)
|
||||||
|
else
|
||||||
|
oldtext(colours.white)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local version = 1.1
|
||||||
|
local reponame = "Skyfall"
|
||||||
|
local platform = C64
|
||||||
|
|
||||||
|
local function displayNitrosoftTitle()
|
||||||
|
gpu.clr()
|
||||||
|
local _w,_h = gpu.winSize()
|
||||||
|
local _t1,_t2 = "nitrosoft", "games"
|
||||||
|
gpu.cursPos(math.floor(_w/2-#_t1), math.floor(_h/2))
|
||||||
|
if term.isColour() then gpu.setTxt("blue") end
|
||||||
|
term.write(_t1)
|
||||||
|
gpu.cursPos(math.floor(_w/2-#_t2/2),math.floor(_h/2)+1)
|
||||||
|
gpu.setTxt("white")
|
||||||
|
term.write(_t2)
|
||||||
|
if term.isColour() then gpu.setTxt("red") end
|
||||||
|
gpu.cursPos(math.floor(_w/2-#_t1), math.floor(_h/2)+2)
|
||||||
|
term.write(string.rep("-",#_t1*2))
|
||||||
|
gpu.setBg("green")
|
||||||
|
gpu.cursPos(_w/2+#_t1-4, math.floor(_h/2)-2)
|
||||||
|
term.write(" ")
|
||||||
|
gpu.cursPos(_w/2+#_t1-4, math.floor(_h/2)-1)
|
||||||
|
term.write(" ")
|
||||||
|
gpu.setBg("lime|)
|
||||||
|
gpu.cursPos(_w/2+#_t1-3, math.floor(_h/2)-1)
|
||||||
|
term.write(" ")
|
||||||
|
gpu.cursPos(_w/2+#_t1-3, math.floor(_h/2))
|
||||||
|
term.write(" ")
|
||||||
|
gpu.setBg("black")
|
||||||
|
gpu.setTxt("white")
|
||||||
|
gpu.cursPos(1,_h)
|
||||||
|
term.write("v"..version)
|
||||||
|
os.pullEvent("key")
|
||||||
|
end
|
||||||
|
displayNitrosoftTitle()
|
||||||
|
|
||||||
|
local w,h = gpu.winSize()
|
||||||
|
|
||||||
|
local levelbg = {colours.lightBlue, colours.blue, colours.black}
|
||||||
|
local level = {}
|
||||||
|
local title = {
|
||||||
|
"##### ## # ## ## ##### ### ## ## ";
|
||||||
|
"## ## ## ## ## ## ##### ## ## ";
|
||||||
|
"##### #### ##### ### ## ## ## ## ";
|
||||||
|
" ## ## ## ### ## ##### ### ###";
|
||||||
|
"##### ## # ### ## ## ## ### ###";
|
||||||
|
}
|
||||||
|
|
||||||
|
local bgcol = colours.lightBlue
|
||||||
|
local pcol = colours.red
|
||||||
|
local flakes = {}
|
||||||
|
local px, py = math.floor(w/2), h
|
||||||
|
local pjump = 0
|
||||||
|
local jtimer, jinterval = nil,0.06
|
||||||
|
local gameOver = false
|
||||||
|
local levelnum = 1
|
||||||
|
|
||||||
|
local gintdef = 0.3
|
||||||
|
local gtimer, ginterval = nil,gintdef
|
||||||
|
|
||||||
|
local function makeLevel()
|
||||||
|
for y = 1, h+1 do
|
||||||
|
level[y] = {}
|
||||||
|
end
|
||||||
|
for x = 1, w do
|
||||||
|
level[h+1][x] = "#"
|
||||||
|
end
|
||||||
|
flakes = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updateTile(x,y)
|
||||||
|
gpu.cursPos(x, y)
|
||||||
|
if level[y][x] == nil then gpu.setBg(bgcol)
|
||||||
|
else gpu.setBg("white") end
|
||||||
|
term.write(" ")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function drawPlayer()
|
||||||
|
if py <= 0 then return end
|
||||||
|
if level[py][px] == nil then
|
||||||
|
gpu.cursPos(px, py)
|
||||||
|
gpu.setTxt(pcol)
|
||||||
|
gpu.setBg(bgcol)
|
||||||
|
term.write("&")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local draw = function(self)
|
||||||
|
gpu.cursPos(self.x,self.y)
|
||||||
|
gpu.setBg("white")
|
||||||
|
term.write(" ")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function drawLevel()
|
||||||
|
for y = 1, h do
|
||||||
|
for x = 1, w do
|
||||||
|
updateTile(x,y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
drawPlayer()
|
||||||
|
for i=1,#flakes do
|
||||||
|
gpu.cursPos(flakes[i].x, flakes[i].y)
|
||||||
|
gpu.setBg(colours.white)
|
||||||
|
tern.write(" ")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function addFlake()
|
||||||
|
local x,y = math.random(1,w),1
|
||||||
|
level[y][x] = "#"
|
||||||
|
updateTile(x,y)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updateBG()
|
||||||
|
gpu.setBg(bgcol)
|
||||||
|
gpu.setTxt(colours.white)
|
||||||
|
for i=1,#flakes do
|
||||||
|
updateTile(flakes[i].x, flakes[i].y)
|
||||||
|
flakes[i].y = flakes[i].y + 1
|
||||||
|
if level[flakes[i].y][flakes[i].x] == nil then
|
||||||
|
gpu.cursPos(flakes[i].x, flakes[i].y)
|
||||||
|
gpu.setBg(bgcol)
|
||||||
|
term.write(".")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for i=1,2 do
|
||||||
|
table.insert(flakes, {x = math.random(1,w), y = 1})
|
||||||
|
end
|
||||||
|
for i = #flakes,1,-1 do
|
||||||
|
if flakes[i].y >= h + 1 then
|
||||||
|
table.remove(flakes, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
drawPlayer()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function updateSnow()
|
||||||
|
for y = h-1,1,-1 do
|
||||||
|
for x = 1,w do
|
||||||
|
if level[y][x] ~= nil and level[y+1][x] == nil then
|
||||||
|
level[y][x] = nil
|
||||||
|
updateTile(x,y)
|
||||||
|
level[y+1][x] = "#"
|
||||||
|
updateTile(x,y+1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if level[py][px] ~= nil then
|
||||||
|
if level[py+1][px] == nil then
|
||||||
|
py = py + 1
|
||||||
|
pjump = -1
|
||||||
|
else
|
||||||
|
gameOver = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function transitionLevel()
|
||||||
|
levelnum = levelnum + 1
|
||||||
|
bgcol = levelbg[math.min(levelnum, #levelbg)]
|
||||||
|
gpu.setBg(bgcol)
|
||||||
|
local ttimer = os.startTimer(0.1)
|
||||||
|
local inc = 0
|
||||||
|
while inc < h do
|
||||||
|
local id,p1 = os.pullEvent("timer")
|
||||||
|
if p1 == ttimer then
|
||||||
|
term.scroll(-1)
|
||||||
|
inc = inc + 1
|
||||||
|
ttimer = os.startTimer(0.1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
makeLevel()
|
||||||
|
ginterval = math.max(ginterval - 0.1, 0.1)
|
||||||
|
py = h
|
||||||
|
gtimer = os.startTimer(ginterval)
|
||||||
|
jtimer = os.startTimer(jinterval)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function update()
|
||||||
|
local bgcount = 0
|
||||||
|
gtimer = os.startTimer(ginterval)
|
||||||
|
jtimer = os.startTimer(jinterval)
|
||||||
|
drawLevel()
|
||||||
|
while not gameOver do
|
||||||
|
local _id, _p1 = os.pullEvent()
|
||||||
|
|
||||||
|
if _id == "timer" then
|
||||||
|
if _p1 == gtimer then
|
||||||
|
updateSnow()
|
||||||
|
for i=0, math.random(0,levelnum) do
|
||||||
|
addFlake()
|
||||||
|
end
|
||||||
|
gtimer = os.startTimer(ginterval)
|
||||||
|
elseif _p1 == jtimer then
|
||||||
|
if pjump > 0 then
|
||||||
|
updateTile(px,py)
|
||||||
|
py = py -1
|
||||||
|
pjump = pjump - 1
|
||||||
|
if py <= 1 then
|
||||||
|
transitionLevel()
|
||||||
|
pjump = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif level[py+1][px] == nil then
|
||||||
|
updateTile(px,py)
|
||||||
|
py = py + 1
|
||||||
|
else
|
||||||
|
pjump = 0
|
||||||
|
end
|
||||||
|
drawPlayer()
|
||||||
|
jtimer = os.startTimer(jinterval)
|
||||||
|
end
|
||||||
|
bgcount = bgcount + 1
|
||||||
|
if bgcount % 8 == 0 then updateBG() end
|
||||||
|
elseif _id == "key" then
|
||||||
|
if _p1 == keys.left and px > 1 then
|
||||||
|
updateTile(px,py)
|
||||||
|
if level[py][px-1] == nil then
|
||||||
|
px = px - 1
|
||||||
|
elseif level[py-1][px] == nil and level[py-1][px-1] == nil then
|
||||||
|
px = px - 1
|
||||||
|
py = py - 1
|
||||||
|
end
|
||||||
|
drawPlayer()
|
||||||
|
elseif _p1 == keys.right and px < w then
|
||||||
|
updateTile(px,py)
|
||||||
|
if level[py][px+1] == nil then
|
||||||
|
px = px + 1
|
||||||
|
elseif level[py-1][px] == nil and level[py-1][px+1] == nil then
|
||||||
|
px = px + 1
|
||||||
|
py = py - 1
|
||||||
|
end
|
||||||
|
drawPlayer()
|
||||||
|
elseif _p1 == keys.space and level[py+1][px] ~= nil then
|
||||||
|
pjump = 2
|
||||||
|
elseif _p1 == keys.enter then
|
||||||
|
gameOver = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
makeLevel()
|
||||||
|
update()
|
||||||
|
gpu.clrBg("black")
|
|
@ -0,0 +1 @@
|
||||||
|
This is a compilation of source code for all commercially available Commander 64 programs.
|
|
@ -0,0 +1,523 @@
|
||||||
|
-- Basic custom shell for C64
|
||||||
|
local multishell = multishell
|
||||||
|
local parentShell = shell
|
||||||
|
local parentTerm = term.current()
|
||||||
|
|
||||||
|
if multishell then
|
||||||
|
multishell.setTitle( multishell.getCurrent(), "shell" )
|
||||||
|
end
|
||||||
|
|
||||||
|
local bExit = false
|
||||||
|
local sDir = (parentShell and parentShell.dir()) or ""
|
||||||
|
local sPath = (parentShell and parentShell.path()) or ".:/rom/programs"
|
||||||
|
local tAliases = (parentShell and parentShell.aliases()) or {}
|
||||||
|
local tCompletionInfo = (parentShell and parentShell.getCompletionInfo()) or {}
|
||||||
|
local tProgramStack = {}
|
||||||
|
|
||||||
|
local shell = {}
|
||||||
|
local function createShellEnv( sDir )
|
||||||
|
local tEnv = {}
|
||||||
|
tEnv[ "shell" ] = shell
|
||||||
|
tEnv[ "multishell" ] = multishell
|
||||||
|
|
||||||
|
local package = {}
|
||||||
|
package.loaded = {
|
||||||
|
_G = _G,
|
||||||
|
bit32 = bit32,
|
||||||
|
coroutine = coroutine,
|
||||||
|
math = math,
|
||||||
|
package = package,
|
||||||
|
string = string,
|
||||||
|
table = table,
|
||||||
|
}
|
||||||
|
package.path = "?;?.lua;?/init.lua;/rom/modules/main/?;/rom/modules/main/?.lua;/rom/modules/main/?/init.lua"
|
||||||
|
if turtle then
|
||||||
|
package.path = package.path..";/rom/modules/turtle/?;/rom/modules/turtle/?.lua;/rom/modules/turtle/?/init.lua"
|
||||||
|
elseif command then
|
||||||
|
package.path = package.path..";/rom/modules/command/?;/rom/modules/command/?.lua;/rom/modules/command/?/init.lua"
|
||||||
|
end
|
||||||
|
package.config = "/\n;\n?\n!\n-"
|
||||||
|
package.preload = {}
|
||||||
|
package.loaders = {
|
||||||
|
function( name )
|
||||||
|
if package.preload[name] then
|
||||||
|
return package.preload[name]
|
||||||
|
else
|
||||||
|
return nil, "no field package.preload['" .. name .. "']"
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
function( name )
|
||||||
|
local fname = string.gsub(name, "%.", "/")
|
||||||
|
local sError = ""
|
||||||
|
for pattern in string.gmatch(package.path, "[^;]+") do
|
||||||
|
local sPath = string.gsub(pattern, "%?", fname)
|
||||||
|
if sPath:sub(1,1) ~= "/" then
|
||||||
|
sPath = fs.combine(sDir, sPath)
|
||||||
|
end
|
||||||
|
if fs.exists(sPath) and not fs.isDir(sPath) then
|
||||||
|
local fnFile, sError = loadfile( sPath, tEnv )
|
||||||
|
if fnFile then
|
||||||
|
return fnFile, sPath
|
||||||
|
else
|
||||||
|
return nil, sError
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if #sError > 0 then
|
||||||
|
sError = sError .. "\n"
|
||||||
|
end
|
||||||
|
sError = sError .. "no file '" .. sPath .. "'"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil, sError
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
local sentinel = {}
|
||||||
|
local function require( name )
|
||||||
|
if type( name ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( name ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
if package.loaded[name] == sentinel then
|
||||||
|
error("Loop detected requiring '" .. name .. "'", 0)
|
||||||
|
end
|
||||||
|
if package.loaded[name] then
|
||||||
|
return package.loaded[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
local sError = "Error loading module '" .. name .. "':"
|
||||||
|
for n,searcher in ipairs(package.loaders) do
|
||||||
|
local loader, err = searcher(name)
|
||||||
|
if loader then
|
||||||
|
package.loaded[name] = sentinel
|
||||||
|
local result = loader( err )
|
||||||
|
if result ~= nil then
|
||||||
|
package.loaded[name] = result
|
||||||
|
return result
|
||||||
|
else
|
||||||
|
package.loaded[name] = true
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
else
|
||||||
|
sError = sError .. "\n" .. err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
error(sError, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
tEnv["package"] = package
|
||||||
|
tEnv["require"] = require
|
||||||
|
|
||||||
|
return tEnv
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Colours
|
||||||
|
local promptColour, textColour, bgColour
|
||||||
|
if term.isColour() then
|
||||||
|
promptColour = colours.white
|
||||||
|
textColour = colours.white
|
||||||
|
bgColour = colours.blue
|
||||||
|
else
|
||||||
|
promptColour = colours.white
|
||||||
|
textColour = colours.white
|
||||||
|
bgColour = colours.black
|
||||||
|
end
|
||||||
|
|
||||||
|
local function run( _sCommand, ... )
|
||||||
|
local sPath = shell.resolveProgram( _sCommand )
|
||||||
|
if sPath ~= nil then
|
||||||
|
tProgramStack[#tProgramStack + 1] = sPath
|
||||||
|
if multishell then
|
||||||
|
local sTitle = fs.getName( sPath )
|
||||||
|
if sTitle:sub(-4) == ".lua" then
|
||||||
|
sTitle = sTitle:sub(1,-5)
|
||||||
|
end
|
||||||
|
multishell.setTitle( multishell.getCurrent(), sTitle )
|
||||||
|
end
|
||||||
|
local sDir = fs.getDir( sPath )
|
||||||
|
local result = os.run( createShellEnv( sDir ), sPath, ... )
|
||||||
|
tProgramStack[#tProgramStack] = nil
|
||||||
|
if multishell then
|
||||||
|
if #tProgramStack > 0 then
|
||||||
|
local sTitle = fs.getName( tProgramStack[#tProgramStack] )
|
||||||
|
if sTitle:sub(-4) == ".lua" then
|
||||||
|
sTitle = sTitle:sub(1,-5)
|
||||||
|
end
|
||||||
|
multishell.setTitle( multishell.getCurrent(), sTitle )
|
||||||
|
else
|
||||||
|
multishell.setTitle( multishell.getCurrent(), "shell" )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
else
|
||||||
|
printError( "No such program" )
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tokenise( ... )
|
||||||
|
local sLine = table.concat( { ... }, " " )
|
||||||
|
local tWords = {}
|
||||||
|
local bQuoted = false
|
||||||
|
for match in string.gmatch( sLine .. "\"", "(.-)\"" ) do
|
||||||
|
if bQuoted then
|
||||||
|
table.insert( tWords, match )
|
||||||
|
else
|
||||||
|
for m in string.gmatch( match, "[^ \t]+" ) do
|
||||||
|
table.insert( tWords, m )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
bQuoted = not bQuoted
|
||||||
|
end
|
||||||
|
return tWords
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Install shell API
|
||||||
|
function shell.run( ... )
|
||||||
|
local tWords = tokenise( ... )
|
||||||
|
local sCommand = tWords[1]
|
||||||
|
if sCommand then
|
||||||
|
return run( sCommand, table.unpack( tWords, 2 ) )
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.exit()
|
||||||
|
bExit = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.dir()
|
||||||
|
return sDir
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.setDir( _sDir )
|
||||||
|
if type( _sDir ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( _sDir ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
if not fs.isDir( _sDir ) then
|
||||||
|
error( "Not a directory", 2 )
|
||||||
|
end
|
||||||
|
sDir = _sDir
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.path()
|
||||||
|
return sPath
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.setPath( _sPath )
|
||||||
|
if type( _sPath ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( _sPath ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
sPath = _sPath
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.resolve( _sPath )
|
||||||
|
if type( _sPath ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( _sPath ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
local sStartChar = string.sub( _sPath, 1, 1 )
|
||||||
|
if sStartChar == "/" or sStartChar == "\\" then
|
||||||
|
return fs.combine( "", _sPath )
|
||||||
|
else
|
||||||
|
return fs.combine( sDir, _sPath )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pathWithExtension( _sPath, _sExt )
|
||||||
|
local nLen = #sPath
|
||||||
|
local sEndChar = string.sub( _sPath, nLen, nLen )
|
||||||
|
-- Remove any trailing slashes so we can add an extension to the path safely
|
||||||
|
if sEndChar == "/" or sEndChar == "\\" then
|
||||||
|
_sPath = string.sub( _sPath, 1, nLen - 1 )
|
||||||
|
end
|
||||||
|
return _sPath .. "." .. _sExt
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.resolveProgram( _sCommand )
|
||||||
|
if type( _sCommand ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( _sCommand ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
-- Substitute aliases firsts
|
||||||
|
if tAliases[ _sCommand ] ~= nil then
|
||||||
|
_sCommand = tAliases[ _sCommand ]
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If the path is a global path, use it directly
|
||||||
|
if _sCommand:find("/") or _sCommand:find("\\") then
|
||||||
|
local sPath = shell.resolve( _sCommand )
|
||||||
|
if fs.exists( sPath ) and not fs.isDir( sPath ) then
|
||||||
|
return sPath
|
||||||
|
else
|
||||||
|
local sPathLua = pathWithExtension( sPath, "lua" )
|
||||||
|
if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then
|
||||||
|
return sPathLua
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Otherwise, look on the path variable
|
||||||
|
for sPath in string.gmatch(sPath, "[^:]+") do
|
||||||
|
sPath = fs.combine( shell.resolve( sPath ), _sCommand )
|
||||||
|
if fs.exists( sPath ) and not fs.isDir( sPath ) then
|
||||||
|
return sPath
|
||||||
|
else
|
||||||
|
local sPathLua = pathWithExtension( sPath, "lua" )
|
||||||
|
if fs.exists( sPathLua ) and not fs.isDir( sPathLua ) then
|
||||||
|
return sPathLua
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Not found
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.programs( _bIncludeHidden )
|
||||||
|
local tItems = {}
|
||||||
|
|
||||||
|
-- Add programs from the path
|
||||||
|
for sPath in string.gmatch(sPath, "[^:]+") do
|
||||||
|
sPath = shell.resolve( sPath )
|
||||||
|
if fs.isDir( sPath ) then
|
||||||
|
local tList = fs.list( sPath )
|
||||||
|
for n=1,#tList do
|
||||||
|
local sFile = tList[n]
|
||||||
|
if not fs.isDir( fs.combine( sPath, sFile ) ) and
|
||||||
|
(_bIncludeHidden or string.sub( sFile, 1, 1 ) ~= ".") then
|
||||||
|
if #sFile > 4 and sFile:sub(-4) == ".lua" then
|
||||||
|
sFile = sFile:sub(1,-5)
|
||||||
|
end
|
||||||
|
tItems[ sFile ] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sort and return
|
||||||
|
local tItemList = {}
|
||||||
|
for sItem, b in pairs( tItems ) do
|
||||||
|
table.insert( tItemList, sItem )
|
||||||
|
end
|
||||||
|
table.sort( tItemList )
|
||||||
|
return tItemList
|
||||||
|
end
|
||||||
|
|
||||||
|
local function completeProgram( sLine )
|
||||||
|
if #sLine > 0 and (sLine:find("/") or sLine:find("\\")) then
|
||||||
|
-- Add programs from the root
|
||||||
|
return fs.complete( sLine, sDir, true, false )
|
||||||
|
|
||||||
|
else
|
||||||
|
local tResults = {}
|
||||||
|
local tSeen = {}
|
||||||
|
|
||||||
|
-- Add aliases
|
||||||
|
for sAlias, sCommand in pairs( tAliases ) do
|
||||||
|
if #sAlias > #sLine and string.sub( sAlias, 1, #sLine ) == sLine then
|
||||||
|
local sResult = string.sub( sAlias, #sLine + 1 )
|
||||||
|
if not tSeen[ sResult ] then
|
||||||
|
table.insert( tResults, sResult )
|
||||||
|
tSeen[ sResult ] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add all subdirectories. We don't include files as they will be added in the block below
|
||||||
|
local tDirs = fs.complete( sLine, sDir, false, false )
|
||||||
|
for i = 1, #tDirs do
|
||||||
|
local sResult = tDirs[i]
|
||||||
|
if not tSeen[ sResult ] then
|
||||||
|
table.insert ( tResults, sResult )
|
||||||
|
tSeen [ sResult ] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add programs from the path
|
||||||
|
local tPrograms = shell.programs()
|
||||||
|
for n=1,#tPrograms do
|
||||||
|
local sProgram = tPrograms[n]
|
||||||
|
if #sProgram > #sLine and string.sub( sProgram, 1, #sLine ) == sLine then
|
||||||
|
local sResult = string.sub( sProgram, #sLine + 1 )
|
||||||
|
if not tSeen[ sResult ] then
|
||||||
|
table.insert( tResults, sResult )
|
||||||
|
tSeen[ sResult ] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sort and return
|
||||||
|
table.sort( tResults )
|
||||||
|
return tResults
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function completeProgramArgument( sProgram, nArgument, sPart, tPreviousParts )
|
||||||
|
local tInfo = tCompletionInfo[ sProgram ]
|
||||||
|
if tInfo then
|
||||||
|
return tInfo.fnComplete( shell, nArgument, sPart, tPreviousParts )
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.complete( sLine )
|
||||||
|
if type( sLine ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( sLine ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
if #sLine > 0 then
|
||||||
|
local tWords = tokenise( sLine )
|
||||||
|
local nIndex = #tWords
|
||||||
|
if string.sub( sLine, #sLine, #sLine ) == " " then
|
||||||
|
nIndex = nIndex + 1
|
||||||
|
end
|
||||||
|
if nIndex == 1 then
|
||||||
|
local sBit = tWords[1] or ""
|
||||||
|
local sPath = shell.resolveProgram( sBit )
|
||||||
|
if tCompletionInfo[ sPath ] then
|
||||||
|
return { " " }
|
||||||
|
else
|
||||||
|
local tResults = completeProgram( sBit )
|
||||||
|
for n=1,#tResults do
|
||||||
|
local sResult = tResults[n]
|
||||||
|
local sPath = shell.resolveProgram( sBit .. sResult )
|
||||||
|
if tCompletionInfo[ sPath ] then
|
||||||
|
tResults[n] = sResult .. " "
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return tResults
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif nIndex > 1 then
|
||||||
|
local sPath = shell.resolveProgram( tWords[1] )
|
||||||
|
local sPart = tWords[nIndex] or ""
|
||||||
|
local tPreviousParts = tWords
|
||||||
|
tPreviousParts[nIndex] = nil
|
||||||
|
return completeProgramArgument( sPath , nIndex - 1, sPart, tPreviousParts )
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.completeProgram( sProgram )
|
||||||
|
if type( sProgram ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( sProgram ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
return completeProgram( sProgram )
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.setCompletionFunction( sProgram, fnComplete )
|
||||||
|
if type( sProgram ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( sProgram ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
if type( fnComplete ) ~= "function" then
|
||||||
|
error( "bad argument #2 (expected function, got " .. type( fnComplete ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
tCompletionInfo[ sProgram ] = {
|
||||||
|
fnComplete = fnComplete
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.getCompletionInfo()
|
||||||
|
return tCompletionInfo
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.getRunningProgram()
|
||||||
|
if #tProgramStack > 0 then
|
||||||
|
return tProgramStack[#tProgramStack]
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.setAlias( _sCommand, _sProgram )
|
||||||
|
if type( _sCommand ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( _sCommand ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
if type( _sProgram ) ~= "string" then
|
||||||
|
error( "bad argument #2 (expected string, got " .. type( _sProgram ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
tAliases[ _sCommand ] = _sProgram
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.clearAlias( _sCommand )
|
||||||
|
if type( _sCommand ) ~= "string" then
|
||||||
|
error( "bad argument #1 (expected string, got " .. type( _sCommand ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
tAliases[ _sCommand ] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.aliases()
|
||||||
|
-- Copy aliases
|
||||||
|
local tCopy = {}
|
||||||
|
for sAlias, sCommand in pairs( tAliases ) do
|
||||||
|
tCopy[sAlias] = sCommand
|
||||||
|
end
|
||||||
|
return tCopy
|
||||||
|
end
|
||||||
|
|
||||||
|
if multishell then
|
||||||
|
function shell.openTab( ... )
|
||||||
|
local tWords = tokenise( ... )
|
||||||
|
local sCommand = tWords[1]
|
||||||
|
if sCommand then
|
||||||
|
local sPath = shell.resolveProgram( sCommand )
|
||||||
|
if sPath == "rom/programs/shell.lua" then
|
||||||
|
return multishell.launch( createShellEnv( "rom/programs" ), sPath, table.unpack( tWords, 2 ) )
|
||||||
|
elseif sPath ~= nil then
|
||||||
|
return multishell.launch( createShellEnv( "rom/programs" ), "rom/programs/shell.lua", sCommand, table.unpack( tWords, 2 ) )
|
||||||
|
else
|
||||||
|
printError( "No such program" )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function shell.switchTab( nID )
|
||||||
|
if type( nID ) ~= "number" then
|
||||||
|
error( "bad argument #1 (expected number, got " .. type( nID ) .. ")", 2 )
|
||||||
|
end
|
||||||
|
multishell.setFocus( nID )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local tArgs = { ... }
|
||||||
|
if #tArgs > 0 then
|
||||||
|
-- "shell x y z"
|
||||||
|
-- Run the program specified on the commandline
|
||||||
|
shell.run( ... )
|
||||||
|
|
||||||
|
else
|
||||||
|
-- "shell"
|
||||||
|
-- Print the header
|
||||||
|
term.setBackgroundColor( bgColour )
|
||||||
|
term.clear()
|
||||||
|
term.setTextColour( promptColour )
|
||||||
|
term.setCursorPos(1,1)
|
||||||
|
print( "C64 Shell v1.0" )
|
||||||
|
term.setTextColour( textColour )
|
||||||
|
|
||||||
|
-- Run the startup program
|
||||||
|
if parentShell == nil then
|
||||||
|
shell.run( "/rom/startup.lua" )
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Read commands and execute them
|
||||||
|
local tCommandHistory = {}
|
||||||
|
while not bExit do
|
||||||
|
term.redirect( parentTerm )
|
||||||
|
term.setBackgroundColor( bgColour )
|
||||||
|
term.setTextColour( promptColour )
|
||||||
|
write( shell.dir() .. "> " )
|
||||||
|
term.setTextColour( textColour )
|
||||||
|
|
||||||
|
|
||||||
|
local sLine
|
||||||
|
if settings.get( "shell.autocomplete" ) then
|
||||||
|
sLine = read( nil, tCommandHistory, shell.complete )
|
||||||
|
else
|
||||||
|
sLine = read( nil, tCommandHistory )
|
||||||
|
end
|
||||||
|
if sLine:match("%S") and tCommandHistory[#tCommandHistory] ~= sLine then
|
||||||
|
table.insert( tCommandHistory, sLine )
|
||||||
|
end
|
||||||
|
shell.run( sLine )
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue