Compare commits
54 Commits
Author | SHA1 | Date |
---|---|---|
TheMrIron2 | d15ea7c611 | |
TheMrIron2 | 963f649ead | |
TheMrIron2 | f708817cb0 | |
TheMrIron2 | dfd3d03b25 | |
TheMrIron2 | 7f7bdae469 | |
TheMrIron2 | a1a7422c25 | |
TheMrIron2 | 5f55be92d7 | |
TheMrIron2 | 746bfe3f09 | |
TheMrIron2 | 4a7d22b9c9 | |
TheMrIron2 | db8ec4f643 | |
TheMrIron2 | dc336061fe | |
TheMrIron2 | 553d30f1a1 | |
TheMrIron2 | f82cdfc7b5 | |
TheMrIron2 | 46cf861694 | |
TheMrIron2 | 30a9017405 | |
TheMrIron2 | a947b41901 | |
TheMrIron2 | 55e5ba7c0d | |
TheMrIron2 | 897967c192 | |
TheMrIron2 | ea2d1fdd86 | |
TheMrIron2 | 6a123b3140 | |
TheMrIron2 | 28ac3d9333 | |
TheMrIron2 | 8a3b7b931b | |
TheMrIron2 | 79d50d7a33 | |
TheMrIron2 | 6aa091d447 | |
TheMrIron2 | 5875e00c3b | |
TheMrIron2 | ffc6c60920 | |
TheMrIron2 | 2d9d828d09 | |
TheMrIron2 | 745c812ede | |
TheMrIron2 | 0117e01827 | |
TheMrIron2 | a6be32275b | |
Ale32bit | 63e1ec40b6 | |
Ale32bit | 72e5cc2360 | |
Ale32bit | 3c9129b50d | |
Ale32bit | 094fd0b656 | |
Ale32bit | 94eb25d370 | |
Ale32bit | cf3e934708 | |
TheMrIron2 | 3c8689c3e3 | |
TheMrIron2 | ac9326ea8b | |
TheMrIron2 | c9bf6726a8 | |
TheMrIron2 | 62590d4212 | |
TheMrIron2 | d47f9fdc64 | |
TheMrIron2 | 69b6e03ea9 | |
TheMrIron2 | 8ecebb0f3c | |
TheMrIron2 | 0f4084b257 | |
TheMrIron2 | 066e0b4d17 | |
TheMrIron2 | 91f9fa2320 | |
TheMrIron2 | 66260f9bba | |
TheMrIron2 | 05472c8b0e | |
TheMrIron2 | 92928fbc95 | |
TheMrIron2 | 93dfb68e02 | |
TheMrIron2 | aa4636b52a | |
TheMrIron2 | cecc7def22 | |
TheMrIron2 | 107c89ef96 | |
TheMrIron2 | a8ff38f9f9 |
|
@ -0,0 +1,49 @@
|
||||||
|
-- Add center in case there's no existing center function
|
||||||
|
|
||||||
|
local function center(y,str)
|
||||||
|
local w,h = term.getSize()
|
||||||
|
local x = (w/2)-(#str/2)
|
||||||
|
term.setCursorPos(x,y)
|
||||||
|
print(str)
|
||||||
|
end
|
||||||
|
|
||||||
|
local modem = peripheral.find("modem")
|
||||||
|
local openModem = false
|
||||||
|
|
||||||
|
for k,v in pairs({"right", "left", "top", "bottom", "front", "back"}) do
|
||||||
|
if peripheral.getType(v) == "modem" then
|
||||||
|
rednet.open(v)
|
||||||
|
local openModem = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function renderNetCentre()
|
||||||
|
term.setBackgroundColour(colours.green)
|
||||||
|
term.setTextColour(colours.white)
|
||||||
|
center(8, " Network Centre ")
|
||||||
|
term.setBackgroundColour(colours.white)
|
||||||
|
term.setTextColour(colours.green)
|
||||||
|
center(9, " Profile ")
|
||||||
|
center(10, " Power Off ")
|
||||||
|
center(11, " Disconnect ")
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do
|
||||||
|
renderNetCentre()
|
||||||
|
local evt, button, x, y = os.pullEvent("mouse_click")
|
||||||
|
if y == 9 then
|
||||||
|
shell.run("/dnas/profile")
|
||||||
|
|
||||||
|
elseif y == 10 then
|
||||||
|
term.clear()
|
||||||
|
center(8,"Shutting Down...")
|
||||||
|
sleep(1)
|
||||||
|
os.shutdown()
|
||||||
|
|
||||||
|
elseif y == 11 then
|
||||||
|
modem.open(30000)
|
||||||
|
modem.transmit(30000, 30000, {sType = "disconnect"})
|
||||||
|
error("Disconnected")
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,108 @@
|
||||||
|
os.loadAPI("/GS2/APIs/gs")
|
||||||
|
-- It is assumed this is running on a GS2 or GS2 devkit
|
||||||
|
|
||||||
|
local function topmenu()
|
||||||
|
gs.clrBg("blue")
|
||||||
|
gs.setBg("white")
|
||||||
|
gs.setTxt("blue")
|
||||||
|
gs.clrLine(2)
|
||||||
|
gs.clrLine(3)
|
||||||
|
gs.clrLine(4)
|
||||||
|
gs.center(3,"DNAS Utility")
|
||||||
|
end
|
||||||
|
|
||||||
|
topmenu()
|
||||||
|
|
||||||
|
-- Welcome section
|
||||||
|
gs.clrLine(7)
|
||||||
|
gs.clrLine(8)
|
||||||
|
gs.clrLine(9)
|
||||||
|
gs.clrLine(10)
|
||||||
|
gs.clrLine(11)
|
||||||
|
gs.center(8,"Welcome to the DNAS Utility!")
|
||||||
|
gs.center(9,"Here, we will test your connection and attempt")
|
||||||
|
gs.center(10,"to connect to the DNAS servers.")
|
||||||
|
ee.sleep(1.75)
|
||||||
|
|
||||||
|
-- Modem check
|
||||||
|
if not peripheral.find("modem") then
|
||||||
|
topmenu()
|
||||||
|
gs.clrLine(7)
|
||||||
|
gs.clrLine(8)
|
||||||
|
gs.clrLine(9)
|
||||||
|
gs.center(8,"There is no modem attached!")
|
||||||
|
gs.center(9,"Please attach a modem, then retry.")
|
||||||
|
ee.sleep(2)
|
||||||
|
error("No modem attached")
|
||||||
|
|
||||||
|
elseif peripheral.find("modem") then
|
||||||
|
-- work as normal
|
||||||
|
topmenu()
|
||||||
|
gs.line(7)
|
||||||
|
gs.line(8)
|
||||||
|
gs.line(9)
|
||||||
|
gs.line(10)
|
||||||
|
gs.center(8,"Attempting Connection...")
|
||||||
|
ee.sleep(1)
|
||||||
|
local modem = peripheral.find("modem")
|
||||||
|
modem.open(661)
|
||||||
|
modem.transmit(661, 661, {sType = "status"})
|
||||||
|
local t = ee.startTimer(3)
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local e = {os.pullEvent()}
|
||||||
|
if e[1] == "modem_message" then
|
||||||
|
if e[3] == 661 then
|
||||||
|
if type(e[5]) == "table" then
|
||||||
|
if e[5].sType then
|
||||||
|
if e[5].sType == "status" then
|
||||||
|
if e[5].sContents == "Offline" then
|
||||||
|
topmenu()
|
||||||
|
gs.clrLine(7)
|
||||||
|
gs.clrLine(8)
|
||||||
|
gs.clrLine(9)
|
||||||
|
gs.clrLine(10)
|
||||||
|
gs.center(8,"Connection Failed:")
|
||||||
|
gs.center(9,"The DNAS servers are currently offline.")
|
||||||
|
ee.sleep(3)
|
||||||
|
--ee.shRun("/GS2/Browser")
|
||||||
|
|
||||||
|
elseif e[5].sContents == "Shutdown" then
|
||||||
|
topmenu()
|
||||||
|
gs.clrLine(7)
|
||||||
|
gs.clrLine(8)
|
||||||
|
gs.clrLine(9)
|
||||||
|
gs.clrLine(10)
|
||||||
|
gs.center(8,"Connection Failed:")
|
||||||
|
gs.center(9,"DNAS has been terminated.")
|
||||||
|
ee.sleep(3)
|
||||||
|
--ee.shRun("/GS2/Browser")
|
||||||
|
|
||||||
|
elseif e[5].sContents == "Online" then
|
||||||
|
topmenu()
|
||||||
|
gs.clrLine(7)
|
||||||
|
gs.clrLine(8)
|
||||||
|
gs.clrLine(9)
|
||||||
|
gs.clrLine(10)
|
||||||
|
gs.center(8,"Connection Successful!")
|
||||||
|
gs.center(9,"DNAS systems online.")
|
||||||
|
ee.sleep(3)
|
||||||
|
--ee.shRun("/GS2/Browser")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif e[1] == "timer" then topmenu()
|
||||||
|
gs.clrLine(7)
|
||||||
|
gs.clrLine(8)
|
||||||
|
gs.clrLine(9)
|
||||||
|
gs.clrLine(10)
|
||||||
|
gs.center(8,"Connection Failed:")
|
||||||
|
gs.center(9,"The DNAS servers did not respond.")
|
||||||
|
ee.sleep(2)
|
||||||
|
--ee.shRun("/GS2/Browser")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
# DNAS Servers
|
||||||
|
|
||||||
|
DNAS (Dynamic Network Access System) is the networking service used by the GameStation 2. If the developer so wishes, they can use these servers for many uses, including:
|
||||||
|
|
||||||
|
- Authenticating valid or pirated copies of a game.
|
||||||
|
|
||||||
|
- Connectivity between different games (eg. linking two games together with one DNAS server so statistics or usernames can be shared).
|
||||||
|
|
||||||
|
- Easy control of the current status of their games - universal online, offline and shutdown messages that work across any games using DNAS.
|
||||||
|
|
||||||
|
The client code can be run on a real GS2 to connect to a computer with the sample server code running. Developers are encouraged to expand upon this code and make their own custom DNAS servers for their games.
|
|
@ -0,0 +1,48 @@
|
||||||
|
--[[
|
||||||
|
DNAS master server
|
||||||
|
|
||||||
|
Credits:
|
||||||
|
Mr_Iron2: Concept, client utility
|
||||||
|
Gonow32: Modem code
|
||||||
|
|
||||||
|
Note: since this is a server program, it is NOT
|
||||||
|
reliant on the GS2 APIs and is NOT designed to be
|
||||||
|
run on a real GS2. It will work on any computer.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
term.clear()
|
||||||
|
term.setCursorPos(1,1)
|
||||||
|
print("DNAS Server")
|
||||||
|
|
||||||
|
local online = true
|
||||||
|
|
||||||
|
if online == true then
|
||||||
|
print("Current Status: Online")
|
||||||
|
elseif online == false then
|
||||||
|
print("Current Status: Unavailable")
|
||||||
|
else
|
||||||
|
print("Current Status: Shut Down")
|
||||||
|
end
|
||||||
|
|
||||||
|
local modem = peripheral.find("modem")
|
||||||
|
modem.open(6)
|
||||||
|
|
||||||
|
while true do
|
||||||
|
local e = {os.pullEvent()}
|
||||||
|
if e[1] == "modem_message" then
|
||||||
|
if e[3] == 661 then
|
||||||
|
if type(e[5]) == "table" then
|
||||||
|
if e[5].sType then
|
||||||
|
if e[5].sType == "status" then
|
||||||
|
if online == true then
|
||||||
|
modem.transmit(661, 661, {sType = "status", sContents = "Online"})
|
||||||
|
elseif online == false then
|
||||||
|
modem.transmit(661, 661, {sType = "status", sContents = "Shutdown"})
|
||||||
|
else
|
||||||
|
modem.transmit(661, 661, {sType = "status", sContents = "Offline"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,9 +1,6 @@
|
||||||
#GameStation 2
|
# Licensed Games
|
||||||
#Officially Licensed Games
|
|
||||||
|
|
||||||
These are all officially licensed/approved games currently available on the GameStation 2.
|
These are all officially licensed and approved games currently available on the GameStation 2.
|
||||||
#Note:
|
|
||||||
This does NOT include the big library of games available on Strafe, just commercially available [on physical media] games.
|
|
||||||
|
|
||||||
Games:
|
Games:
|
||||||
|
|
||||||
|
@ -17,4 +14,7 @@ Games:
|
||||||
|
|
||||||
- CCSand
|
- CCSand
|
||||||
|
|
||||||
^Supports NetPlay
|
^ Multiplayer-ready with DNAS
|
||||||
|
|
||||||
|
### Note:
|
||||||
|
This does NOT include the big library of games available on Strafe, just commercially available [on physical media] games.
|
||||||
|
|
18
README.md
18
README.md
|
@ -1,17 +1,21 @@
|
||||||
# GameStation 2
|
# GameStation 2
|
||||||
# Real power for real players
|
## Real power for real players
|
||||||
|
|
||||||
Features of GS2:
|
Features of GS2:
|
||||||
|
|
||||||
• Play online through the DNAS network!
|
• Play online through the DNAS network!
|
||||||
|
|
||||||
• Download an abundance of games via the Strafe store
|
• Download an abundance of games via the Strafe store!
|
||||||
|
|
||||||
• Dig into the classic GS2 releases library^ - enjoy timeless classics that paved the way forward for the industry, such as TRON and Skyfall - and they were played first on GameStation 2!
|
• Dig into the classic GS2 releases library - enjoy timeless classics that paved the way forward for the industry, such as TRON and Skyfall - and they were played first on GameStation 2!
|
||||||
|
|
||||||
• Native monitor support! Enjoy beautiful high resolution on the GameStation 2 flawlessly^^
|
• Native monitor support! Enjoy pristine higher resolution graphics on the GameStation 2!
|
||||||
|
|
||||||
• Enjoy the GS2's rich support from Game Fusion
|
• Enjoy the GS2's rich and longstanding support from Game Fusion
|
||||||
|
|
||||||
|
• Support for monochrome computers has arrived at last! Enjoy GS2 games on non-advanced PCs thanks to Gonow32's colour to monochrome graphics wrapper!
|
||||||
|
|
||||||
|
• A developer's dream; custom APIs for graphics and other tasks along with documentation and servers hosted by GF!
|
||||||
|
|
||||||
And more!
|
And more!
|
||||||
|
|
||||||
|
@ -20,6 +24,6 @@ GameStation 2 - The ultimate CC console.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
^ This is not including Strafe and is referring to GameStation 2 licensed releases
|
"Classic GS2 releases" is not including Strafe and is referring to GameStation 2 licensed releases only
|
||||||
|
|
||||||
^^ Not all games support custom resolution or "hi res" - however the system menus are guaranteed to support this
|
Not all games support custom resolution or "hi-res" mode - however the system menus are dynamically coded to support this
|
||||||
|
|
|
@ -4,41 +4,26 @@ local gravity = {}
|
||||||
|
|
||||||
--CREDIT TO marumaru
|
--CREDIT TO marumaru
|
||||||
function getColor ( mctag )
|
function getColor ( mctag )
|
||||||
if mctag == "&0" then
|
local tags = {
|
||||||
return 32768
|
["0"] = colors.black,
|
||||||
elseif mctag == "&f" then
|
["1"] = colors.blue,
|
||||||
return 1
|
["2"] = colors.green,
|
||||||
elseif mctag == "&e" then
|
["3"] = colors.cyan,
|
||||||
return 16
|
["4"] = colors.red,
|
||||||
elseif mctag == "&a" then
|
["5"] = colors.purple,
|
||||||
return colors.lime
|
["6"] = colors.orange,
|
||||||
elseif mctag == "&b" then
|
["7"] = colors.lightGray,
|
||||||
return colors.lightBlue
|
["8"] = colors.gray,
|
||||||
elseif mctag == "&c" then
|
["9"] = colors.cyan,
|
||||||
return colors.red
|
a = colors.lime,
|
||||||
elseif mctag == "&d" then
|
b = colors.lightBlue,
|
||||||
return colors.pink
|
c = colors.red,
|
||||||
elseif mctag == "&1" then
|
d = colors.pink,
|
||||||
return colors.blue
|
e = colors.yellow,
|
||||||
elseif mctag == "&2" then
|
f = colors.white
|
||||||
return colors.green
|
}
|
||||||
elseif mctag == "&3" then
|
mgtag = mgtag:gsub("&","")
|
||||||
return colors.cyan
|
return tags[mgtag] or colors.white
|
||||||
elseif mctag == "&4" then
|
|
||||||
return colors.red
|
|
||||||
elseif mctag == "&5" then
|
|
||||||
return colors.purple
|
|
||||||
elseif mctag == "&6" then
|
|
||||||
return colors.orange
|
|
||||||
elseif mctag == "&7" then
|
|
||||||
return colors.lightGray
|
|
||||||
elseif mctag == "&8" then
|
|
||||||
return colors.gray
|
|
||||||
elseif mctag == "&9" then
|
|
||||||
return colors.cyan
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- CREIDT TO marumaru
|
-- CREIDT TO marumaru
|
||||||
|
@ -57,44 +42,33 @@ function getLines(dir)
|
||||||
local cur = 1
|
local cur = 1
|
||||||
local file = fs.open(dir, "r")
|
local file = fs.open(dir, "r")
|
||||||
local line = file.readLine()
|
local line = file.readLine()
|
||||||
while line ~= nil do
|
repeat
|
||||||
lines[cur] = line
|
lines[cur] = line
|
||||||
line = file.readLine()
|
line = file.readLine()
|
||||||
end
|
until not line
|
||||||
file.close()
|
file.close()
|
||||||
return lines
|
return lines
|
||||||
else
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
function split(str, pat)
|
function split(str, sep)
|
||||||
local t = {} -- NOTE: use {n = 0} in Lua-5.0
|
local out = {}
|
||||||
if str ~= nil then
|
if sep == nil then
|
||||||
local fpat = "(.-)" .. pat
|
sep = "%s"
|
||||||
local last_end = 1
|
|
||||||
local s, e, cap = str:find(fpat, 1)
|
|
||||||
while s do
|
|
||||||
if s ~= 1 or cap ~= "" then
|
|
||||||
table.insert(t,cap)
|
|
||||||
end
|
end
|
||||||
last_end = e+1
|
i=1
|
||||||
s, e, cap = str:find(fpat, last_end)
|
for st in string.gmatch(str, "([^"..sep.."]+)") do
|
||||||
|
out[i] = st
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
if last_end <= #str then
|
return out
|
||||||
cap = str:sub(last_end)
|
|
||||||
table.insert(t, cap)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
print("##CGE ERROR failed to split ["..str.."] by:"..pat)
|
|
||||||
end
|
|
||||||
return t
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function getTableSize(table)
|
function getTableSize(table)
|
||||||
local cur = 0
|
local cur = 0
|
||||||
for i,v in ipairs(table) do
|
for _ in pairs(table) do
|
||||||
cur = i
|
cur = cur+1
|
||||||
end
|
end
|
||||||
return cur
|
return cur
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
-- "Emotion Engine" API
|
||||||
|
-- Powerful CPU API for GS2
|
||||||
|
-- Based on C64 CPU v1.1
|
||||||
|
|
||||||
|
local version = 1.1
|
||||||
|
local debug = false -- Enable debug for extra info eg. telling you when EE reloads
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
|
||||||
|
blshift = bit.blshift -- Shifts a number left by a specified number of bits
|
||||||
|
|
||||||
|
brshift = bit.brshift -- Shifts a number right arithmetically by a specified number of bits
|
||||||
|
|
||||||
|
blogic_rshift = bit.blogic_rshift -- Shifts a number right logically by a specified number of bits
|
||||||
|
|
||||||
|
bxor = bit.bxor -- Computes the bitwise exclusive OR of two numbers
|
||||||
|
|
||||||
|
bor = bit.bor -- Computes the bitwise inclusive OR of two numbers
|
||||||
|
|
||||||
|
band = bit.band -- Computes the bitwise AND of two numbers
|
||||||
|
|
||||||
|
bnot = bit.bnot -- Computes the bitwise NOT of a number
|
||||||
|
|
||||||
|
-- Parallel functions
|
||||||
|
-- Syntax intact for convenience
|
||||||
|
|
||||||
|
waitForAny = parallel.waitForAny -- infinite threads
|
||||||
|
|
||||||
|
waitForAll = parallel.waitForAll -- wait for all processes before proceeding
|
||||||
|
|
||||||
|
-- Multishell support for future multithreading/multishell(?)
|
||||||
|
-- Multishell commands begin with t to indicate threading/multishell + to avoid conflicts
|
||||||
|
|
||||||
|
if multishell then
|
||||||
|
tGetTitle = multishell.getTitle
|
||||||
|
tGetCount = multishell.getCount
|
||||||
|
tLaunch = multishell.launch
|
||||||
|
tSetFocus = multishell.setFocus
|
||||||
|
tSetTitle = multishell.setTitle
|
||||||
|
tGetFocus = multishell.getFocus
|
||||||
|
|
||||||
|
else
|
||||||
|
tGetTitle = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
tGetCount = function()
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
tLaunch = function()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
tSetFocus = function()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
tSetTItle = function()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
tGetFocus = function()
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Other processes
|
||||||
|
-- eg. GPS, encoding and serialization
|
||||||
|
|
||||||
|
run = os.run
|
||||||
|
|
||||||
|
shRun = shell.run
|
||||||
|
--Careful not to confuse these two
|
||||||
|
--Use shRun unless you want a special environment
|
||||||
|
|
||||||
|
pullEvt = os.pullEvent
|
||||||
|
|
||||||
|
pullEvtRaw = os.pullEventRaw
|
||||||
|
|
||||||
|
queueEvt = os.queueEvent
|
||||||
|
|
||||||
|
function reload()
|
||||||
|
os.loadAPI("/GS2/APIs/ee")
|
||||||
|
if debug then
|
||||||
|
print("EE reloaded!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function info()
|
||||||
|
print("Emotion Engine CPU API")
|
||||||
|
print("API version: v"...version..." ")
|
||||||
|
if debug then
|
||||||
|
print("Debug mode: Enabled")
|
||||||
|
else
|
||||||
|
print("Debug mode: Disabled")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
startTimer = os.startTimer
|
||||||
|
|
||||||
|
clock = os.clock
|
||||||
|
|
||||||
|
cancelTimer = os.cancelTimer
|
||||||
|
|
||||||
|
sleep = os.sleep
|
||||||
|
|
||||||
|
serialize = textutils.serialize
|
||||||
|
|
||||||
|
unserialize = textutils.unserialize
|
||||||
|
|
||||||
|
serializeJSON = textutils.serializeJSON
|
||||||
|
|
||||||
|
urlEncode = textutils.urlEncode
|
||||||
|
|
||||||
|
locate = gps.locate
|
|
@ -0,0 +1,154 @@
|
||||||
|
--[[
|
||||||
|
Graphics Synthesizer API
|
||||||
|
|
||||||
|
Based on Commander 64 GPU API
|
||||||
|
with some additions and changes.
|
||||||
|
|
||||||
|
By TheMrIron2 (Mr_Iron2)
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local version = 1.2
|
||||||
|
|
||||||
|
local debug = false
|
||||||
|
-- disabled by default
|
||||||
|
|
||||||
|
local function reload()
|
||||||
|
os.loadAPI("/GS2/APIs/gs")
|
||||||
|
if debug then
|
||||||
|
print("GS reloaded!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Term functions
|
||||||
|
|
||||||
|
blit = term.blit
|
||||||
|
|
||||||
|
clr = term.clear
|
||||||
|
|
||||||
|
function center(y, str)
|
||||||
|
local w,h = term.getSize()
|
||||||
|
local x = (w/2)-(#str/2)
|
||||||
|
term.setCursorPos(x,y)
|
||||||
|
print(str)
|
||||||
|
end
|
||||||
|
|
||||||
|
cursPos = term.setCursorPos
|
||||||
|
|
||||||
|
cursBlink = term.setCursorBlink
|
||||||
|
|
||||||
|
function centerSlow(y, str)
|
||||||
|
local w,h = term.getSize()
|
||||||
|
local x = (w/2)-(#str/2)
|
||||||
|
term.setCursorPos(x,y)
|
||||||
|
textutils.slowPrint(str)
|
||||||
|
end
|
||||||
|
|
||||||
|
write = term.write
|
||||||
|
|
||||||
|
-- Colour related term functions
|
||||||
|
|
||||||
|
bg = term.setBackgroundColour
|
||||||
|
|
||||||
|
function setBg(col) -- thanks to MultMine for fix
|
||||||
|
term.setBackgroundColour(colours[col])
|
||||||
|
end
|
||||||
|
|
||||||
|
function setTxt(col)
|
||||||
|
term.setTextColour(colours[col])
|
||||||
|
end
|
||||||
|
|
||||||
|
function setText(col)
|
||||||
|
term.setTextColour(colours[col])
|
||||||
|
end
|
||||||
|
|
||||||
|
function clrBg(back)
|
||||||
|
term.setBackgroundColour(colours[back])
|
||||||
|
term.clear()
|
||||||
|
end
|
||||||
|
|
||||||
|
function clrLine(y)
|
||||||
|
term.setCursorPos(1,y)
|
||||||
|
term.clearLine()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Colour functions
|
||||||
|
|
||||||
|
combineColour = colours.combine
|
||||||
|
|
||||||
|
combineColor = colors.combine
|
||||||
|
-- combining outputs the bitwise result
|
||||||
|
|
||||||
|
subtractCol = colours.subtract
|
||||||
|
|
||||||
|
-- Window/display commands
|
||||||
|
|
||||||
|
winSize = term.getSize
|
||||||
|
|
||||||
|
getSize = term.getSize
|
||||||
|
|
||||||
|
newWindow = window.create
|
||||||
|
|
||||||
|
current = term.current
|
||||||
|
|
||||||
|
redirect = term.redirect
|
||||||
|
|
||||||
|
function setVis(bool) -- both term.current and term.setVisible
|
||||||
|
local func = term.current().setVisible
|
||||||
|
if func then
|
||||||
|
func(bool)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function redraw()
|
||||||
|
local func = term.current().redraw
|
||||||
|
if func then
|
||||||
|
func()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function monTxtScale(size)
|
||||||
|
local func = term.current().setTextScale
|
||||||
|
if func then
|
||||||
|
func(size)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function wrap(side)
|
||||||
|
local mon = peripheral.wrap(side)
|
||||||
|
-- use command like mon.write("hi")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Paintutils derived commands
|
||||||
|
|
||||||
|
loadImg = paintutils.loadImage
|
||||||
|
|
||||||
|
drawImg = paintutils.drawImage
|
||||||
|
|
||||||
|
function drawPixel(x, y, col)
|
||||||
|
paintutils.drawPixel(x, y, colours[col])
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawLine(x1, y1, x2, y2, col)
|
||||||
|
paintutils.drawLine(x1, y1, x2, y2, colours[col])
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawBox(x1, y1, x2, y2, col)
|
||||||
|
paintutils.drawBox(x1, y1, x2, y2, colours[col])
|
||||||
|
end
|
||||||
|
|
||||||
|
function drawFilledBox(x1, y1, x2, y2, col)
|
||||||
|
paintutils.drawFilledBox(x1, y1, x2, y2, colours[col])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Textutils commands
|
||||||
|
|
||||||
|
slowWrite = textutils.slowWrite
|
||||||
|
|
||||||
|
slowPrint = textutils.slowPrint
|
||||||
|
|
||||||
|
-- Parallel functions
|
||||||
|
|
||||||
|
waitForAny = parallel.waitForAny
|
||||||
|
|
||||||
|
waitForAll = parallel.waitForAll
|
|
@ -1,24 +1,14 @@
|
||||||
function split(str, pat)
|
function split(str, sep)
|
||||||
local t = {} -- NOTE: use {n = 0} in Lua-5.0
|
local out = {}
|
||||||
if str ~= nil then
|
if sep == nil then
|
||||||
local fpat = "(.-)" .. pat
|
sep = "%s"
|
||||||
local last_end = 1
|
|
||||||
local s, e, cap = str:find(fpat, 1)
|
|
||||||
while s do
|
|
||||||
if s ~= 1 or cap ~= "" then
|
|
||||||
table.insert(t,cap)
|
|
||||||
end
|
end
|
||||||
last_end = e+1
|
i=1
|
||||||
s, e, cap = str:find(fpat, last_end)
|
for st in string.gmatch(str, "([^"..sep.."]+)") do
|
||||||
|
out[i] = st
|
||||||
|
i = i + 1
|
||||||
end
|
end
|
||||||
if last_end <= #str then
|
return out
|
||||||
cap = str:sub(last_end)
|
|
||||||
table.insert(t, cap)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
print("##ERROR failed to split ["..str.."] by:"..pat)
|
|
||||||
end
|
|
||||||
return t
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function getTableSize(table)
|
local function getTableSize(table)
|
||||||
|
@ -34,7 +24,7 @@ function unformatTable(string, join)
|
||||||
end
|
end
|
||||||
|
|
||||||
function formatTable(table, join, start)
|
function formatTable(table, join, start)
|
||||||
if start == nil then start = 1 end
|
if type(start) == "nil" then start = 1 end
|
||||||
local str = ""
|
local str = ""
|
||||||
for i=start,#table do
|
for i=start,#table do
|
||||||
if i == start then str = table[i] else str = str..join..table[i] end
|
if i == start then str = table[i] else str = str..join..table[i] end
|
|
@ -0,0 +1,493 @@
|
||||||
|
-- Vector Unit (VU) API for GS2
|
||||||
|
-- Designed for fast, optimised vector processing
|
||||||
|
-- Also does some CPU tasks
|
||||||
|
-- This means some commands will overlap
|
||||||
|
-- Special thanks to Advanced Vector API for most of this vector code
|
||||||
|
-- http://www.computercraft.info/forums2/index.php?/topic/3752-advanced-vector-api-v11/
|
||||||
|
|
||||||
|
local version = 1.0
|
||||||
|
|
||||||
|
-- debug currently does nothing useful: devs could use it though
|
||||||
|
local debug = false
|
||||||
|
|
||||||
|
local function reload()
|
||||||
|
os.loadAPI("/GS2/APIs/vu")
|
||||||
|
if debug then
|
||||||
|
print("VUs reloaded!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function info()
|
||||||
|
print("Vector Unit coprocessor API")
|
||||||
|
print("API version: v"...version..." ")
|
||||||
|
if debug then
|
||||||
|
print("Debug mode: Enabled")
|
||||||
|
else
|
||||||
|
print("Debug mode: Disabled")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Multishell support for multithreading/multishell
|
||||||
|
-- Multishell commands begin with t to indicate threading/multishell + to avoid conflicts
|
||||||
|
|
||||||
|
if multishell then
|
||||||
|
tGetTitle = multishell.getTitle
|
||||||
|
tGetCount = multishell.getCount
|
||||||
|
tLaunch = multishell.launch
|
||||||
|
tSetFocus = multishell.setFocus
|
||||||
|
tSetTitle = multishell.setTitle
|
||||||
|
tGetFocus = multishell.getFocus
|
||||||
|
|
||||||
|
else
|
||||||
|
tGetTitle = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
|
tGetCount = function()
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
tLaunch = function()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
tSetFocus = function()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
tSetTItle = function()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
tGetFocus = function()
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Vector functions
|
||||||
|
|
||||||
|
new = vector.new
|
||||||
|
|
||||||
|
local vector = {
|
||||||
|
add = function(self, v)
|
||||||
|
return new(
|
||||||
|
self.x + v.x,
|
||||||
|
self.y + v.y,
|
||||||
|
self.z + v.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
scalarAdd = function(self, n)
|
||||||
|
return new(
|
||||||
|
self.x + n,
|
||||||
|
self.y + n,
|
||||||
|
self.z + n
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
subtract = function(self, v)
|
||||||
|
return new(
|
||||||
|
self.x - v.x,
|
||||||
|
self.y - v.y,
|
||||||
|
self.z - v.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
scalarSubtract = function(self, n)
|
||||||
|
return new(
|
||||||
|
self.x - n,
|
||||||
|
self.y - n,
|
||||||
|
self.z - n
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
multiply = function(self, v)
|
||||||
|
return new(
|
||||||
|
self.x * v.x,
|
||||||
|
self.y * v.y,
|
||||||
|
self.z * v.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
scalarMultiply = function(self, n)
|
||||||
|
return new(
|
||||||
|
self.x * n,
|
||||||
|
self.y * n,
|
||||||
|
self.z * n
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
divide = function(self, o)
|
||||||
|
return new(
|
||||||
|
self.x / o.x,
|
||||||
|
self.y / o.y,
|
||||||
|
self.z / o.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
scalarDivide = function(self, n)
|
||||||
|
return new(
|
||||||
|
self.x / n,
|
||||||
|
self.y / n,
|
||||||
|
self.z / n
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
length = function(self)
|
||||||
|
return math.sqrt(
|
||||||
|
self.x * self.x
|
||||||
|
+ self.y * self.y
|
||||||
|
+ self.z * self.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
lengthSq = function(self)
|
||||||
|
return (
|
||||||
|
self.x * self.x
|
||||||
|
+ self.y * self.y
|
||||||
|
+ self.z * self.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
distance = function(self, o)
|
||||||
|
return math.sqrt(
|
||||||
|
math.pow(o.x - self.x, 2)
|
||||||
|
+ math.pow(o.y - self.y, 2)
|
||||||
|
+ math.pow(o.z - self.z, 2)
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
distanceSq = function(self, o)
|
||||||
|
return (
|
||||||
|
math.pow(o.x - self.x, 2)
|
||||||
|
+ math.pow(o.y - self.y, 2)
|
||||||
|
+ math.pow(o.z - self.z, 2)
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
normalize = function(self)
|
||||||
|
return self:scalarDivide(self:length())
|
||||||
|
end,
|
||||||
|
|
||||||
|
dot = function(self, o)
|
||||||
|
return (
|
||||||
|
self.x * o.x
|
||||||
|
+ self.y * o.y
|
||||||
|
+ self.z * o.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
cross = function(self, o)
|
||||||
|
return new(
|
||||||
|
self.y * o.z - self.z * o.y,
|
||||||
|
self.z * o.x - self.x * o.z,
|
||||||
|
self.x * o.y - self.y * o.x
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
containedWithin = function(self, min, max)
|
||||||
|
return (
|
||||||
|
self.x >= min.x and self.x <= max.x
|
||||||
|
and self.y >= min.y and self.y <= max.y
|
||||||
|
and self.z >= min.z and self.z <= max.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
clampX = function(self, min, max)
|
||||||
|
return new(
|
||||||
|
math.max(min, math.min(max, self.x)),
|
||||||
|
self.y,
|
||||||
|
self.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
clampY = function(self, min, max)
|
||||||
|
return new(
|
||||||
|
self.x,
|
||||||
|
math.max(min, math.min(max, self.y)),
|
||||||
|
self.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
clampZ = function(self, min, max)
|
||||||
|
return new(
|
||||||
|
self.x,
|
||||||
|
self.y,
|
||||||
|
math.max(min, math.min(max, self.z))
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
floor = function(self)
|
||||||
|
return new(
|
||||||
|
math.floor(self.x),
|
||||||
|
math.floor(self.y),
|
||||||
|
math.floor(self.z)
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
ceil = function(self)
|
||||||
|
return new(
|
||||||
|
math.ceil(self.x),
|
||||||
|
math.ceil(self.y),
|
||||||
|
math.ceil(self.z)
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
round = function(self)
|
||||||
|
return new(
|
||||||
|
math.floor(self.x + 0.5),
|
||||||
|
math.floor(self.y + 0.5),
|
||||||
|
math.floor(self.z + 0.5)
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
absolute = function(self)
|
||||||
|
return new(
|
||||||
|
math.abs(self.x),
|
||||||
|
math.abs(self.y),
|
||||||
|
math.abs(self.z)
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
isCollinearWith = function(self, o)
|
||||||
|
if self.x == 0 and self.y == 0 and self.z == 0 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
local otherX, otherY, otherZ = o.x, o.y, o.z
|
||||||
|
if otherX == 0 and otherY == 0 and otherZ == 0 then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
if (self.x == 0) ~= (otherX == 0) then return false end
|
||||||
|
if (self.y == 0) ~= (otherY == 0) then return false end
|
||||||
|
if (self.z == 0) ~= (otherZ == 0) then return false end
|
||||||
|
local quotientX = otherX / self.x
|
||||||
|
if quotientX == quotientX then
|
||||||
|
return o:equals(self:scalarMultiply(quotientX))
|
||||||
|
end
|
||||||
|
local quotientY = otherY / self.y
|
||||||
|
if quotientY == quotientY then
|
||||||
|
return o:equals(self:scalarMultiply(quotientY))
|
||||||
|
end
|
||||||
|
local quotientZ = otherZ / self.z
|
||||||
|
if quotientZ == quotientZ then
|
||||||
|
return o:equals(self:scalarMultiply(quotientZ))
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
getIntermediateWithX = function(self, o, v)
|
||||||
|
local vX = o.x - self.x
|
||||||
|
local vY = o.y - self.y
|
||||||
|
local vZ = o.z - self.z
|
||||||
|
if vX * vX < 1.0000000116860974e-7 then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
local nMul = (v - self.x) / vX
|
||||||
|
return (
|
||||||
|
(nMul >= 0 and nMul <= 1)
|
||||||
|
and new(
|
||||||
|
self.x + vX * nMul,
|
||||||
|
self.y + vY * nMul,
|
||||||
|
self.z + vZ * nMul
|
||||||
|
)
|
||||||
|
or nil
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
getIntermediateWithY = function(self, o, v)
|
||||||
|
local vX = o.x - self.x
|
||||||
|
local vY = o.y - self.y
|
||||||
|
local vZ = o.z - self.z
|
||||||
|
if vY * vY < 1.0000000116860974e-7 then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
local nMul = (v - self.y) / vY
|
||||||
|
return (
|
||||||
|
(nMul >= 0 and nMul <= 1)
|
||||||
|
and new(
|
||||||
|
self.x + vX * nMul,
|
||||||
|
self.y + vY * nMul,
|
||||||
|
self.z + vZ * nMul
|
||||||
|
)
|
||||||
|
or nil
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
getIntermediateWithZ = function(self, o, v)
|
||||||
|
local vX = o.x - self.x
|
||||||
|
local vY = o.y - self.y
|
||||||
|
local vZ = o.z - self.z
|
||||||
|
if vZ * vZ < 1.0000000116860974e-7 then
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
local nMul = (v - self.z) / vZ
|
||||||
|
return (
|
||||||
|
(nMul >= 0 and nMul <= 1)
|
||||||
|
and new(
|
||||||
|
self.x + vX * nMul,
|
||||||
|
self.y + vY * nMul,
|
||||||
|
self.z + vZ * nMul
|
||||||
|
)
|
||||||
|
or nil
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
rotateAroundX = function(self, n)
|
||||||
|
local c, s = math.cos(n), math.sin(n)
|
||||||
|
return new(
|
||||||
|
self.x,
|
||||||
|
self.y * c + self.z * s,
|
||||||
|
self.z * c - self.y * s
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
rotateAroundY = function(self, n)
|
||||||
|
local c, s = math.cos(n), math.sin(n)
|
||||||
|
return new(
|
||||||
|
self.x * c + self.z * s,
|
||||||
|
self.y,
|
||||||
|
self.z * c - self.x * s
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
rotateAroundZ = function(self, n)
|
||||||
|
local c, s = math.cos(n), math.sin(n)
|
||||||
|
return new(
|
||||||
|
self.x * c + self.y * s,
|
||||||
|
self.y * c - self.x * s,
|
||||||
|
self.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
clone = function(self)
|
||||||
|
return new(
|
||||||
|
self.x,
|
||||||
|
self.y,
|
||||||
|
self.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
equals = function(self, o)
|
||||||
|
if not isVector(self) or not isVector(o) then return false end
|
||||||
|
return (
|
||||||
|
o.x == self.x
|
||||||
|
and o.y == self.y
|
||||||
|
and o.z == self.z
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
tostring = function(self)
|
||||||
|
return "("..self.x..", "..self.y..", "..self.z..")"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
local vmetatable = {
|
||||||
|
__index = vector,
|
||||||
|
__tostring = vector.tostring,
|
||||||
|
__unm = function(v) return v:scalarMultiply(-1) end,
|
||||||
|
__add = function(a, b)
|
||||||
|
if type(b) == "number" and isVector(a) then
|
||||||
|
return a:scalarAdd(b)
|
||||||
|
elseif type(a) == "number" and isVector(b) then
|
||||||
|
return b:scalarAdd(a)
|
||||||
|
elseif isVector(a) and isVector(b) then
|
||||||
|
return a:add(b)
|
||||||
|
else
|
||||||
|
error("Attempt to perform vector addition on <"..getType(a).."> and <"..getType(b)..">")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
__sub = function(a, b)
|
||||||
|
if type(b) == "number" and isVector(a) then
|
||||||
|
return a:scalarSubtract(b)
|
||||||
|
elseif type(a) == "number" and isVector(b) then
|
||||||
|
return b:scalarSubtract(a)
|
||||||
|
elseif isVector(a) and isVector(b) then
|
||||||
|
return a:subtract(b)
|
||||||
|
else
|
||||||
|
error("Attempt to perform vector subtraction on <"..getType(a).."> and <"..getType(b)..">")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
__mul = function(a, b)
|
||||||
|
if type(b) == "number" and isVector(a) then
|
||||||
|
return a:scalarMultiply(b)
|
||||||
|
elseif type(a) == "number" and isVector(b) then
|
||||||
|
return b:scalarMultiply(a)
|
||||||
|
elseif isVector(a) and isVector(b) then
|
||||||
|
return a:multiply(b)
|
||||||
|
else
|
||||||
|
error("Attempt to perform vector multiplication on <"..getType(a).."> and <"..getType(b)..">")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
__div = function(a, b)
|
||||||
|
if type(b) == "number" and isVector(a) then
|
||||||
|
return a:scalarDivide(b)
|
||||||
|
elseif type(a) == "number" and isVector(b) then
|
||||||
|
return b:scalarDivide(a)
|
||||||
|
elseif isVector(a) and isVector(b) then
|
||||||
|
return a:divide(b)
|
||||||
|
else
|
||||||
|
error("Attempt to perform vector division on <"..getType(a).."> and <"..getType(b)..">")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
__eq = vector.equals
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMinimum(v1, v2)
|
||||||
|
return new(
|
||||||
|
math.min(v1.x, v2.x),
|
||||||
|
math.min(v1.y, v2.y),
|
||||||
|
math.min(v1.z, v2.z)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function getMaximum(v1, v2)
|
||||||
|
return new(
|
||||||
|
math.max(v1.x, v2.x),
|
||||||
|
math.max(v1.y, v2.y),
|
||||||
|
math.max(v1.z, v2.z)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function getMidpoint(v1, v2)
|
||||||
|
return new(
|
||||||
|
(v1.x + v2.x) / 2,
|
||||||
|
(v1.y + v2.y) / 2,
|
||||||
|
(v1.z + v2.z) / 2
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
getType = function(v)
|
||||||
|
if isVector(v) then
|
||||||
|
return "vector"
|
||||||
|
else
|
||||||
|
return type(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
isVector = function(v)
|
||||||
|
return getmetatable(v) == vmetatable
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Parallel functions
|
||||||
|
|
||||||
|
waitForAny = parallel.waitForAny
|
||||||
|
|
||||||
|
waitForAll = parallel.waitForAll
|
||||||
|
|
||||||
|
-- Other functions
|
||||||
|
|
||||||
|
run = shell.run -- No os.run equivalent to avoid confusion, as shell.run is sufficient most of the time and EE has os.run
|
||||||
|
|
||||||
|
sleep = os.sleep
|
||||||
|
|
||||||
|
serialize = textutils.serialize
|
||||||
|
|
||||||
|
unserialize = textutils.unserialize
|
||||||
|
|
||||||
|
serializeJSON = textutils.serializeJSON
|
||||||
|
|
||||||
|
urlEncode = textutils.urlEncode
|
|
@ -1,429 +1,169 @@
|
||||||
---------------------------------------------------
|
--[[
|
||||||
-- GameStation 2 Browser - Credits:
|
|
||||||
-- Strafe: CrazedProgrammer
|
|
||||||
-- Everything Else: Mr_Iron2
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
function strafe()
|
GameStation 2 Browser
|
||||||
function split(pString, pPattern)
|
|
||||||
local Table = {} -- NOTE: use {n = 0} in Lua-5.0
|
|
||||||
local fpat = "(.-)" .. pPattern
|
|
||||||
local last_end = 1
|
|
||||||
local s, e, cap = pString:find(fpat, 1)
|
|
||||||
while s do
|
|
||||||
if s ~= 1 or cap ~= "" then
|
|
||||||
table.insert(Table,cap)
|
|
||||||
end
|
|
||||||
last_end = e+1
|
|
||||||
s, e, cap = pString:find(fpat, last_end)
|
|
||||||
end
|
|
||||||
if last_end <= #pString then
|
|
||||||
cap = pString:sub(last_end)
|
|
||||||
table.insert(Table, cap)
|
|
||||||
end
|
|
||||||
return Table
|
|
||||||
end
|
|
||||||
|
|
||||||
function install(game)
|
Credits:
|
||||||
if not fs.isDir(dir.."strafedata/"..game) then
|
|
||||||
fs.delete(dir.."strafedata/"..game)
|
|
||||||
fs.makeDir(dir.."strafedata/"..game)
|
|
||||||
end
|
|
||||||
local _d = shell.dir()
|
|
||||||
local i = split(online[game].install, "|")
|
|
||||||
term.setTextColor(colors.white)
|
|
||||||
term.setBackgroundColor(colors.black)
|
|
||||||
term.setCursorPos(1, 1)
|
|
||||||
term.clear()
|
|
||||||
shell.run("cd /"..dir.."strafedata/"..game)
|
|
||||||
for k,v in pairs(i) do
|
|
||||||
shell.run(({v:gsub("?", dir.."strafedata/"..game)})[1])
|
|
||||||
end
|
|
||||||
shell.run("cd /".._d)
|
|
||||||
online[game].banner = online[game].banner:saveString()
|
|
||||||
local f = fs.open(dir.."strafedata/"..game..".tab", "w")
|
|
||||||
f.write(textutils.serialize(online[game]))
|
|
||||||
f.close()
|
|
||||||
online[game].banner = surface.loadString(online[game].banner)
|
|
||||||
timer = os.startTimer(0)
|
|
||||||
updateGames()
|
|
||||||
updateOnline()
|
|
||||||
end
|
|
||||||
|
|
||||||
function updateGames()
|
Strafe: CrazedProgrammer
|
||||||
games = { }
|
Browser and Apps: Mr_Iron2
|
||||||
for k,v in pairs(fs.list(dir.."strafedata")) do
|
Code cleanup + fixes: Ale32bit
|
||||||
if v:sub(#v - 3, #v) == ".tab" then
|
|
||||||
local name = v:sub(1, #v - 4)
|
|
||||||
local f = fs.open(dir.."strafedata/"..v, "r")
|
|
||||||
games[name] = textutils.unserialize(f.readAll())
|
|
||||||
games[name]["banner"] = surface.loadString(games[name]["banner"])
|
|
||||||
f.close()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function updateOnline()
|
--]]
|
||||||
http.request("http://pastebin.com/raw.php?i=m9YK1tke")
|
|
||||||
end
|
|
||||||
|
|
||||||
function updateSize()
|
local version = 2.0
|
||||||
width, height = term.getSize()
|
|
||||||
rows = math.floor((width - 1) / 25)
|
|
||||||
offset = math.floor((width - rows * 25 + 1) / 2)
|
|
||||||
surf = surface.create(width, height)
|
|
||||||
end
|
|
||||||
|
|
||||||
function update()
|
os.loadAPI("/GS2/APIs/gs")
|
||||||
draw()
|
|
||||||
end
|
|
||||||
|
|
||||||
function draw()
|
local function powerOff()
|
||||||
surf:clear(nil, colors.white, colors.black)
|
gs.setTxt("white")
|
||||||
if state == 1 then
|
gs.clrBg("grey")
|
||||||
drawGames()
|
gs.cursPos(1,8)
|
||||||
elseif state == 2 then
|
gs.center(8,"Shutting Down...")
|
||||||
drawOnline()
|
|
||||||
end
|
|
||||||
surf:drawLine(1, 1, width, 1, " ", colors.lightGray, colors.black)
|
|
||||||
if width >= 43 then
|
|
||||||
surf:drawText(1, 1, "Strafe")
|
|
||||||
surf:drawText(9, 1, "Installed Games Download Games", nil, colors.blue)
|
|
||||||
else
|
|
||||||
surf:drawText(1, 1, "Installed Download", nil, colors.blue)
|
|
||||||
end
|
|
||||||
surf:drawPixel(width, 1, "X", colors.red, colors.white)
|
|
||||||
surf:drawPixel(width, 2, "^")
|
|
||||||
surf:drawPixel(width, height, "v")
|
|
||||||
surf:render()
|
|
||||||
end
|
|
||||||
|
|
||||||
function drawGames()
|
|
||||||
local i = 0
|
|
||||||
for k,v in pairs(games) do
|
|
||||||
surf:drawSurface((i % rows) * 25 + 1 + offset, math.floor(i / rows) * 6 + 3 - gamesOffset, v.banner)
|
|
||||||
surf:drawText((i % rows) * 25 + 1 + offset, math.floor(i / rows) * 6 + 7 - gamesOffset, "Play Delete", colors.black, colors.white)
|
|
||||||
i = i + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function drawOnline()
|
|
||||||
local i = 0
|
|
||||||
for k,v in pairs(online) do
|
|
||||||
surf:drawSurface((i % rows) * 25 + 1 + offset, math.floor(i / rows) * 6 + 3 - onlineOffset, v.banner)
|
|
||||||
local str = "Download"
|
|
||||||
if games[k] then
|
|
||||||
if games[k].version == v.version then
|
|
||||||
str = "Installed"
|
|
||||||
else
|
|
||||||
str = "Update"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
surf:drawText((i % rows) * 25 + 1 + offset, math.floor(i / rows) * 6 + 7 - onlineOffset, str, colors.black, colors.white)
|
|
||||||
i = i + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function onClick(x, y)
|
|
||||||
if y == 1 then
|
|
||||||
if x == width then
|
|
||||||
term.setTextColor(colors.white)
|
|
||||||
term.setBackgroundColor(colors.black)
|
|
||||||
term.setCursorPos(1, 1)
|
|
||||||
term.clear()
|
|
||||||
running = false
|
|
||||||
elseif width >= 43 then
|
|
||||||
if x >= 9 and x <= 23 then
|
|
||||||
updateGames()
|
|
||||||
state = 1
|
|
||||||
elseif x >= 26 and x <= 39 then
|
|
||||||
updateOnline()
|
|
||||||
state = 2
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if x >= 1 and x <= 9 then
|
|
||||||
updateGames()
|
|
||||||
state = 1
|
|
||||||
elseif x >= 12 and x <= 19 then
|
|
||||||
updateOnline()
|
|
||||||
state = 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif x == width and y == 2 then
|
|
||||||
if state == 1 and gamesOffset > 0 then
|
|
||||||
gamesOffset = gamesOffset - 6
|
|
||||||
elseif onlineOffset > 0 then
|
|
||||||
onlineOffset = onlineOffset - 6
|
|
||||||
end
|
|
||||||
elseif x == width and y == height then
|
|
||||||
if state == 1 then
|
|
||||||
gamesOffset = gamesOffset + 6
|
|
||||||
else
|
|
||||||
onlineOffset = onlineOffset + 6
|
|
||||||
end
|
|
||||||
elseif y > 1 and state == 1 then
|
|
||||||
local id = math.floor((y + gamesOffset - 2) / 6) * rows
|
|
||||||
if x - offset + 1 <= rows * 25 then
|
|
||||||
id = id + math.floor((x - offset) / 25)
|
|
||||||
end
|
|
||||||
local xx = (x - offset) % 25
|
|
||||||
local yy = (y - 2) % 6
|
|
||||||
local i = 0
|
|
||||||
for k,v in pairs(games) do
|
|
||||||
if id == i then
|
|
||||||
if xx >= 1 and xx <= 4 and yy == 5 then
|
|
||||||
local d = shell.dir()
|
|
||||||
shell.run("cd /"..dir.."strafedata/"..k.."/"..v.launchdir)
|
|
||||||
term.setTextColor(colors.white)
|
|
||||||
term.setBackgroundColor(colors.black)
|
|
||||||
term.setCursorPos(1, 1)
|
|
||||||
term.clear()
|
|
||||||
shell.run(v.launch)
|
|
||||||
shell.run("cd /"..d)
|
|
||||||
timer = os.startTimer(0)
|
|
||||||
updateSize()
|
|
||||||
elseif xx >= 6 and xx <= 11 and yy == 5 then
|
|
||||||
fs.delete(dir.."strafedata/"..k)
|
|
||||||
fs.delete(dir.."strafedata/"..k..".tab")
|
|
||||||
updateGames()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
i = i + 1
|
|
||||||
end
|
|
||||||
elseif y > 1 and state == 2 then
|
|
||||||
local id = math.floor((y + onlineOffset - 2) / 6) * rows
|
|
||||||
if x - offset + 1 <= rows * 25 then
|
|
||||||
id = id + math.floor((x - offset) / 25)
|
|
||||||
end
|
|
||||||
local xx = (x - offset) % 25
|
|
||||||
local yy = (y - 2) % 6
|
|
||||||
local i = 0
|
|
||||||
for k,v in pairs(online) do
|
|
||||||
if id == i then
|
|
||||||
if xx >= 1 and xx <= 8 and yy == 5 and not games[k] then
|
|
||||||
install(k)
|
|
||||||
elseif xx >= 1 and xx <= 6 and yy == 5 and games[k] then
|
|
||||||
if games[k].version ~= v.version then
|
|
||||||
fs.delete(dir.."strafedata/"..k)
|
|
||||||
fs.delete(dir.."strafedata/"..k..".tab")
|
|
||||||
install(k)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
i = i + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
dir = fs.getDir(shell.getRunningProgram()).."/"
|
|
||||||
if not fs.isDir(dir.."strafedata") then
|
|
||||||
fs.delete(dir.."strafedata")
|
|
||||||
fs.makeDir(dir.."strafedata")
|
|
||||||
end
|
|
||||||
if not fs.exists("/GS2/APIs/surface") or fs.isDir(dir.."strafedata/surface") then
|
|
||||||
fs.delete(dir.."strafedata/surface")
|
|
||||||
local d = shell.dir()
|
|
||||||
shell.run("cd /GS2/APIs/")
|
|
||||||
shell.run("pastebin get J2Y288mW surface")
|
|
||||||
shell.run("cd /")
|
|
||||||
end
|
|
||||||
os.loadAPI("GS2/APIs/surface")
|
|
||||||
updateSize()
|
|
||||||
local _off = math.floor(width / 2) surf:drawText(1, 1, "Made by CrazedProgrammer") local cp = surface.loadString("_00100010208f208f208f208f208f208f208f208f208f208f208f208f208f208f208f208f208f20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff207f208f20ff20ff200f200f20ff200f200f20ff20ff20ff20ff20ff20ff20ff207f208f20ff200f20ff20ff20ff200f20ff200f20ff20ff20ff20ff20ff20ff207f208f20ff200f20ff20ff20ff200f200f20ff20ff20ff20ff20ff20ff20ff207f208f20ff200f20ff20ff20ff200f20ff20ff20ff20ff20ff20ff20ff20ff207f208f20ff20ff200f200f20ff200f20ff20ff20ff200f200f200f20ff20ff207f208f20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff20ff207f208f207f207f207f207f207f207f207f207f207f207f207f207f207f207f207f20_720_720_720_720_720_720_72077207720_720_720_720_720_720_720_720_720_720_720_720_720_7207720772077207720_720_720_720_720_720_720872087208720872087208720872087208720872087208720872087208720872087208720872087208720872087208720872087208720872087208720872077208720772077207720772077208720772077208720772077208720b72087207720872087208720872087208720872087208720872087208720872087208720772077207720772077207720772077207720772077207720772077207720772077") for i=1,16,1 do local surf2 = surface.create(i, i) surf2:drawSurfaceScaled(1, 1, i, i, cp) surf:fillRect(1, 2, width, height, nil, colors.black) surf:drawSurfaceRotated(_off, 10, i / 2, i / 2, 4 - i / 4, surf2) surf:render() os.sleep(0) end for i=1,4,1 do surf:fillRect(1, 2, width, height, nil, colors.black) surf:drawSurface(_off - 7, 3, cp) surf:drawLine(_off - 7, i * 4, _off + i * 4 - 11, 3, nil, colors.white) surf:drawLine(_off - 7, 1 + i * 4, _off + i * 4 - 10, 3, nil, colors.white) surf:drawLine(_off - 7, 2 + i * 4, _off + i * 4 - 9, 3, nil, colors.white) surf:render() os.sleep(0) end for i=1,4,1 do surf:fillRect(1, 2, width, height, nil, colors.black) surf:drawSurface(_off - 7, 3, cp) surf:drawLine(_off + i * 4 - 11, 18, _off + 8, i * 4, nil, colors.white) surf:drawLine(_off + i * 4 - 10, 18, _off + 8, 1 + i * 4, nil, colors.white) surf:drawLine(_off + i * 4 - 9, 18, _off + 8, 2 + i * 4, nil, colors.white) surf:render() os.sleep(0) end
|
|
||||||
games = { }
|
|
||||||
online = { }
|
|
||||||
updateGames()
|
|
||||||
state = 1
|
|
||||||
gamesOffset = 0
|
|
||||||
onlineOffset = 0
|
|
||||||
running = true
|
|
||||||
timer = os.startTimer(0)
|
|
||||||
while running do
|
|
||||||
local e = {os.pullEvent()}
|
|
||||||
if e[1] == "timer" and e[2] == timer then
|
|
||||||
timer = os.startTimer(0)
|
|
||||||
update()
|
|
||||||
elseif e[1] == "mouse_click" then
|
|
||||||
onClick(e[3], e[4])
|
|
||||||
elseif e[1] == "mouse_scroll"then
|
|
||||||
if e[2] == -1 then
|
|
||||||
if state == 1 and gamesOffset + e[2] * 6 >= 0 then
|
|
||||||
gamesOffset = gamesOffset + e[2] * 6
|
|
||||||
elseif state == 2 and onlineOffset > 0 then
|
|
||||||
onlineOffset = onlineOffset + e[2] * 6
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if state == 1 then
|
|
||||||
gamesOffset = gamesOffset + e[2] * 6
|
|
||||||
else
|
|
||||||
onlineOffset = onlineOffset + e[2] * 6
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif e[1] == "term_resize" then
|
|
||||||
updateSize()
|
|
||||||
elseif e[1] == "http_success" and e[2] == "http://pastebin.com/raw.php?i=m9YK1tke" then
|
|
||||||
online = textutils.unserialize(e[3].readAll())
|
|
||||||
e[3].close()
|
|
||||||
for k,v in pairs(online) do
|
|
||||||
v.banner = surface.loadString(v.banner)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function powerOff()
|
|
||||||
term.setBackgroundColour(colours.grey)
|
|
||||||
term.setTextColour(colours.white)
|
|
||||||
term.clear()
|
|
||||||
term.setCursorPos(1,8)
|
|
||||||
center(8,"Shutting Down...")
|
|
||||||
sleep(1)
|
sleep(1)
|
||||||
term.setBackgroundColour(colours.lightGrey)
|
gs.clrBg("lightGrey")
|
||||||
term.clear()
|
|
||||||
sleep(0.2)
|
sleep(0.2)
|
||||||
term.setBackgroundColour(colours.white)
|
gs.clrBg("white")
|
||||||
term.clear()
|
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
os.shutdown()
|
os.shutdown()
|
||||||
end
|
end
|
||||||
|
|
||||||
function gamesApps()
|
local function gamesApps()
|
||||||
term.setBackgroundColour(colours.blue)
|
gs.clrBg("blue")
|
||||||
term.clear()
|
gs.cursPos(1,1)
|
||||||
term.setCursorPos(1,1)
|
gs.setTxt("white")
|
||||||
term.setTextColor(colors.white)
|
|
||||||
while true do
|
while true do
|
||||||
programs = fs.list("/GS2/GamesApps")
|
programs = fs.list("/GS2/GamesApps")
|
||||||
term.setCursorPos(1,1)
|
gs.cursPos(1,1)
|
||||||
term.clear()
|
gs.clr()
|
||||||
for i=1,#programs do
|
for i=1,#programs do
|
||||||
term.setTextColor(colors.white)
|
gs.setTxt("white")
|
||||||
term.setCursorPos(1,i-scroll)
|
gs.cursPos(1,i-scroll)
|
||||||
print(programs[i])
|
print(programs[i])
|
||||||
end
|
end
|
||||||
|
|
||||||
if #programs == 0 then
|
if #programs == 0 then
|
||||||
term.setTextColor(colors.white)
|
gs.setTxt("white")
|
||||||
term.setCursorPos(1,1)
|
gs.cursPos(1,1)
|
||||||
print("You have no games.")
|
print("You have no games.")
|
||||||
end
|
end
|
||||||
term.setCursorPos(1,19)
|
|
||||||
term.setTextColor(colors.white)
|
gs.cursPos(1,19)
|
||||||
|
gs.setTxt("white")
|
||||||
write("Click a program to run it. Space to exit.")
|
write("Click a program to run it. Space to exit.")
|
||||||
|
|
||||||
os.startTimer(0.3)
|
os.startTimer(0.3)
|
||||||
event,a,b,c,d = os.pullEvent()
|
event,a,b,c,d = os.pullEvent()
|
||||||
if (event == "key" and a == 57) then
|
if (event == "key" and a == 57) then
|
||||||
menu()
|
menu()
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
if event == "mouse_scroll" then
|
if event == "mouse_scroll" then
|
||||||
scroll = scroll + a
|
scroll = scroll + a
|
||||||
if scroll > 0 then
|
if scroll > 0 then
|
||||||
scroll = 0
|
scroll = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if event == "mouse_click" then
|
if event == "mouse_click" then
|
||||||
if c <= #programs then
|
if c <= #programs then
|
||||||
c = c - scroll
|
c = c - scroll
|
||||||
print(programs[c])
|
print(programs[c])
|
||||||
term.setTextColor(colors.white)
|
gs.setTxt("white")
|
||||||
term.clear()
|
gs.clr()
|
||||||
term.setCursorPos(1,1)
|
gs.cursPos(1,1)
|
||||||
shell.run("/GS2/GamesApps/"..programs[c])
|
shell.run("/GS2/GamesApps/"..programs[c])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function systemInfo()
|
local function systemInfo()
|
||||||
term.setBackgroundColour(colours.red)
|
gs.clrBg("grey")
|
||||||
term.setTextColour(colours.white)
|
gs.setTxt("white")
|
||||||
term.clear()
|
gs.center(2,"Information")
|
||||||
center(2,"Information")
|
gs.center(4,"GS2 Model: GS2 SCPH-50000")
|
||||||
center(4,"GS2 Model: GS2 SCPH-25000")
|
gs.center(5,"Software version: v2.0")
|
||||||
center(5,"Software version: BETA")
|
gs.center(7,"Credits:")
|
||||||
center(7,"Credits:")
|
gs.center(9,"Programming: TheMrIron2")
|
||||||
center(9,"Rest of Coding - datcoder1208")
|
gs.center(10,"Programming: Funey")
|
||||||
center(10,"Majority of Coding - Mr_Iron2")
|
gs.center(11,"Strafe: CrazedProgrammer")
|
||||||
center(11,"Strafe: CrazedProgrammer")
|
gs.center(14,"Thank you for using your GS2!")
|
||||||
center(14,"Thank you for using your GS2!")
|
gs.center(16,"Press space to go back")
|
||||||
center(16,"Click here to go back")
|
|
||||||
while true do local evt, button, x, y = os.pullEvent("mouse_click")
|
while true do
|
||||||
if y == 16 then menu()
|
local evt, button, key = os.pullEventRaw()
|
||||||
else end
|
if key == keys.space then
|
||||||
|
menu()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function installDisk()
|
local function installDisk()
|
||||||
term.setBackgroundColour(colours.red)
|
gs.clrBg("white")
|
||||||
term.setTextColour(colours.white)
|
gs.setTxt("black")
|
||||||
term.clear()
|
|
||||||
while true do if fs.exists("/disk/") then center(8,"Installing...")
|
while true do
|
||||||
|
if fs.exists("/disk/") then
|
||||||
|
gs.center(8,"Installing...")
|
||||||
shell.run("cp disk/* GS2/GamesApps/")
|
shell.run("cp disk/* GS2/GamesApps/")
|
||||||
center(10,"Installed!")
|
gs.center(10,"Installed!")
|
||||||
else center(8,"No disk found!")
|
else
|
||||||
|
gs.center(8,"No disk found!")
|
||||||
sleep(3)
|
sleep(3)
|
||||||
menu()
|
menu()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function settings()
|
local function settings()
|
||||||
term.setBackgroundColour(colours.green)
|
gs.setTxt("white")
|
||||||
term.setTextColour(colours.white)
|
gs.clrBg("grey")
|
||||||
term.clear()
|
gs.center(2,"System Settings")
|
||||||
center(2,"System Settings")
|
gs.setBg("lightGrey")
|
||||||
term.setBackgroundColour(colours.red)
|
gs.center(4,"1. Modify Files ")
|
||||||
center(4," Modify Files ")
|
gs.center(14,"Press space to Quit")
|
||||||
term.setBackgroundColour(colours.green)
|
|
||||||
center(14,"Click here to Quit")
|
|
||||||
|
|
||||||
while true do local evt, button, x, y = os.pullEvent()
|
while true do
|
||||||
if evt == "mouse_click" then
|
local evt, button, key = os.pullEventRaw()
|
||||||
if y == 4 then term.clear()
|
if key == keys.one then
|
||||||
term.setCursorPos(1,1)
|
gs.clr()
|
||||||
|
gs.cursPos(1,1)
|
||||||
shell.run("/rom/programs/shell")
|
shell.run("/rom/programs/shell")
|
||||||
elseif y == 14 then menu()
|
elseif key == keys.space then
|
||||||
else end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function updater()
|
|
||||||
local w,h = term.getSize()
|
|
||||||
term.setBackgroundColour(colours.red)
|
|
||||||
term.clear()
|
|
||||||
term.setBackgroundColour(colours.white)
|
|
||||||
term.setCursorPos(1,1)
|
|
||||||
term.clearLine()
|
|
||||||
term.setTextColour(colours.blue)
|
|
||||||
center(1,"GameStation 2 Updater v1")
|
|
||||||
term.setBackgroundColour(colours.red)
|
|
||||||
term.setTextColour(colours.white)
|
|
||||||
term.setCursorPos(1,3)
|
|
||||||
print(" Install")
|
|
||||||
print(" Exit")
|
|
||||||
center(7,"To update, get an official GS2 update disk.")
|
|
||||||
center(8,"disk and press 'Install'.")
|
|
||||||
|
|
||||||
while true do local evt, button, x, y = os.pullEvent("mouse_click")
|
|
||||||
if y == 3 then
|
|
||||||
if not fs.exists("/disk/.flashUpdate/") then
|
|
||||||
center(8,"Invalid Disk!")
|
|
||||||
menu()
|
menu()
|
||||||
elseif fs.exists("disk/boot.elf") then shell.run("disk/boot.elf")
|
|
||||||
elseif fs.exists("/disk/.flashUpdate/") and fs.isDir("/disk/.flashUpdate") then
|
|
||||||
for i,v in pairs(fs.list("/")) do
|
|
||||||
if v == "rom" then
|
|
||||||
elseif v == "disk" then
|
|
||||||
elseif v == "moarp" then
|
|
||||||
else
|
|
||||||
fs.delete("/"..v)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
shell.run("cp /disk/.flashUpdate/* /")
|
|
||||||
end
|
end
|
||||||
term.clear()
|
|
||||||
centerSlow(8,"Installed!")
|
local function updater()
|
||||||
sleep(0.9)
|
local w,h = gs.getSize()
|
||||||
|
gs.clrBg("grey")
|
||||||
|
gs.setBg("white")
|
||||||
|
gs.cursPos(1,1)
|
||||||
|
gs.clrLine()
|
||||||
|
gs.setTxt("grey")
|
||||||
|
gs.center(1,"GameStation 2 Updater v1")
|
||||||
|
gs.setBg("grey")
|
||||||
|
gs.setTxt("white")
|
||||||
|
gs.cursPos(1,3)
|
||||||
|
print(" 1. Install")
|
||||||
|
print(" 2. Exit")
|
||||||
|
gs.center(7,"To update, get an official GS2 update")
|
||||||
|
gs.center(8,"disk and press 1.")
|
||||||
|
|
||||||
|
while true do local evt, button, y = os.pullEvent("mouse_click")
|
||||||
|
if y == 3 then
|
||||||
|
if not fs.exists("/disk/.flashUpdate/") then -- Used for disk updates or other purposes to install code
|
||||||
|
gs.center(8,"Invalid Disk!")
|
||||||
|
menu()
|
||||||
|
elseif fs.exists("disk/boot.elf") then
|
||||||
|
shell.run("disk/boot.elf")
|
||||||
|
|
||||||
|
elseif fs.exists("/disk/.flashUpdate/") then
|
||||||
|
shell.run("/disk/.flashUpdate/boot.elf")
|
||||||
|
gs.clr()
|
||||||
|
gs.centerSlow(8,"Installed!")
|
||||||
|
sleep(1)
|
||||||
menu()
|
menu()
|
||||||
elseif y == 4 then menu()
|
elseif y == 4 then menu()
|
||||||
else end
|
else end
|
||||||
|
@ -432,33 +172,61 @@ while true do local evt, button, x, y = os.pullEvent("mouse_click")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function menu()
|
local function menu()
|
||||||
term.setBackgroundColour(colours.red)
|
gs.clrBg("red")
|
||||||
term.clear()
|
gs.setCursorPos(1,1)
|
||||||
term.setCursorPos(1,1)
|
gs.setBg("white")
|
||||||
term.setBackgroundColour(colours.white)
|
gs.clrLine()
|
||||||
term.clearLine()
|
gs.setTxt("red")
|
||||||
term.setTextColour(colours.red)
|
gs.center(1,"GameStation 2 Browser")
|
||||||
center(1,"GameStation 2 Browser")
|
gs.setBg("red")
|
||||||
term.setBackgroundColour(colours.red)
|
gs.cursPos(1,3)
|
||||||
term.setCursorPos(1,3)
|
gs.setTxt("blue")
|
||||||
term.setTextColour(colours.blue)
|
gs.setBg("white")
|
||||||
term.setBackgroundColour(colours.white)
|
gs.center(3,"1. Games and Apps ")
|
||||||
center(3," Games and Apps ")
|
gs.center(5,"2. Install ")
|
||||||
center(5," Install ")
|
gs.center(7,"3. Strafe ")
|
||||||
center(7," Strafe ")
|
gs.center(9,"4. Shutdown ")
|
||||||
center(9," Shutdown ")
|
gs.center(11,"5. Information ")
|
||||||
center(11," Information ")
|
gs.center(13,"6. Settings ")
|
||||||
center(13," Settings ")
|
gs.center(15,"7. Software Update ")
|
||||||
center(15," Software Update ")
|
|
||||||
|
|
||||||
while true do local evt, button, x, y = os.pullEvent("mouse_click")
|
while true do
|
||||||
if y == 3 then gamesApps()
|
local evt, key, y = os.pullEventRaw()
|
||||||
elseif y == 5 then installDisk()
|
if evt == "mouse_click" then
|
||||||
elseif y == 7 then strafe()
|
if y == 3 then
|
||||||
elseif y == 9 then powerOff()
|
gamesApps()
|
||||||
elseif y == 11 then systemInfo()
|
elseif y == 5 then
|
||||||
elseif y == 13 then settings()
|
installDisk()
|
||||||
elseif y == 15 then updater()
|
elseif y == 7 then
|
||||||
|
shell.run("pastebin run bj3qj1Pj")
|
||||||
|
elseif y == 9 then
|
||||||
|
powerOff()
|
||||||
|
elseif y == 11 then
|
||||||
|
systemInfo()
|
||||||
|
elseif y == 13 then
|
||||||
|
settings()
|
||||||
|
elseif y == 15 then
|
||||||
|
updater()
|
||||||
end
|
end
|
||||||
end menu()
|
|
||||||
|
elseif evt == "key" then
|
||||||
|
if key == keys.one then
|
||||||
|
gamesApps()
|
||||||
|
elseif key == keys.two then
|
||||||
|
installDisk()
|
||||||
|
elseif key == keys.three then
|
||||||
|
shell.run("pastebin run bj3qj1Pj")
|
||||||
|
elseif key == keys.four then
|
||||||
|
powerOff()
|
||||||
|
elseif key == keys.five then
|
||||||
|
systemInfo()
|
||||||
|
elseif key == keys.six then
|
||||||
|
settings()
|
||||||
|
elseif key == keys.seven then
|
||||||
|
updater()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
menu()
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
--[[
|
||||||
|
|
||||||
|
This is documentation for the Emotion Engine API.
|
||||||
|
|
||||||
|
The Emotion Engine API is powerful and flexible.
|
||||||
|
Based on Commander 64's CPU API, the EE is the
|
||||||
|
heart of the GS2 in an ideal world. It is
|
||||||
|
capable of complete bitwise manipulation
|
||||||
|
(replacing the Bit API) and parallel threading
|
||||||
|
(replacing the Parallel API), which also
|
||||||
|
does most of what Coroutines is used for -
|
||||||
|
one exception being multishell.
|
||||||
|
|
||||||
|
Speaking of multishell, the full Multishell API
|
||||||
|
is also implemented in EE for multitasking and
|
||||||
|
multithreading, almost eliminating the need
|
||||||
|
for Coroutines. Other miscellaneous functions
|
||||||
|
include serialization and timers.
|
||||||
|
|
||||||
|
Full command documentation follows.
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
ee.randomInt(numberStart, numberEnd)
|
||||||
|
Random integer between X and Y
|
||||||
|
|
||||||
|
ee.sqrt(number)
|
||||||
|
Square root of a number
|
||||||
|
|
||||||
|
ee.blshift(number, bits)
|
||||||
|
Shifts a number left by a specified number of bits
|
||||||
|
|
||||||
|
ee.brshift(number, bits)
|
||||||
|
Shifts a number right arithmetically by a specified number of bits
|
||||||
|
|
||||||
|
ee.blogic_rshift(number, bits)
|
||||||
|
Shifts a number right logically by a specified number of bits
|
||||||
|
|
||||||
|
ee.bxor(number1, number2)
|
||||||
|
Computes the bitwise exclusive OR of two numbers
|
||||||
|
|
||||||
|
ee.bor(number1, number2)
|
||||||
|
Computes the bitwise inclusive OR of two numbers
|
||||||
|
|
||||||
|
ee.band(number1, number2)
|
||||||
|
Computes the bitwise AND of two numbers
|
||||||
|
|
||||||
|
ee.bnot(number1, number2)
|
||||||
|
Computes the bitwise NOT of a number.
|
||||||
|
|
||||||
|
ee.waitForAny(function1, function2...)
|
||||||
|
Runs all the functions at the same time, and stops when any of them returns.
|
||||||
|
|
||||||
|
ee.waitForAll(function1, function2...)
|
||||||
|
Runs all the functions at the same time, and stops when all of them have returned.
|
||||||
|
|
||||||
|
ee.tGetTitle = multishell.getTitle(numberTagID, title)
|
||||||
|
Relabels the specified tab to use the specified title
|
||||||
|
|
||||||
|
ee.tGetCount = multishell.getCount()
|
||||||
|
Returns the number of tabs currently being handled by the multishell system.
|
||||||
|
|
||||||
|
ee.tLaunch()
|
||||||
|
Launches a multishell.
|
||||||
|
|
||||||
|
ee.tSetFocus(tabID)
|
||||||
|
Launches the specified script in a new tab.
|
||||||
|
|
||||||
|
ee.tSetTitle(numberTabID, title)
|
||||||
|
Relabels the specified tab to use the specified title.
|
||||||
|
|
||||||
|
ee.tGetFocus()
|
||||||
|
Returns the ID of the currently focused tab.
|
||||||
|
|
||||||
|
ee.run(environment, program)
|
||||||
|
An advanced way of starting programs.
|
||||||
|
A started program will have a given environment table which determines what functions it has available, as well as any variables it will be able to access by default.
|
||||||
|
You may prefer to use shell.run unless you need to do something special.
|
||||||
|
Usage: ee.run({}, "rom/programs/shell")
|
||||||
|
|
||||||
|
ee.shRun(program)
|
||||||
|
A simpler shell run execution of a program.
|
||||||
|
Usage: ee.shRun("startup")
|
||||||
|
|
||||||
|
ee.pullEvt(targetEvent, parameter1, parameter2, ...)
|
||||||
|
Blocks until the computer receives an event, or if targetEvent is specified, will block until an instance of target-event occurs.
|
||||||
|
ee.pullEvt(targetEvent) returns the event and any parameters the event may have.
|
||||||
|
If a targetEvent is specified, the computer will not break for any other events (except termination).
|
||||||
|
|
||||||
|
ee.pullEvtRaw(targetEvent, parameter1, parameter2, ...)
|
||||||
|
Advanced version of pullEvent().
|
||||||
|
Blocks until the computer receives an event, or if targetEvent is specified, will block until an instance of targetEvent occurs.
|
||||||
|
ee.pullEvtRaw(targetEvent) returns the event and any parameters the event may have.
|
||||||
|
Unlike ee.pullEvt(targetEvent), this function will not raise an error if a 'terminate' event is received.
|
||||||
|
|
||||||
|
ee.queueEvt(targetEvent, parameter1, parameter2, ...)
|
||||||
|
Adds an event to the event queue with the name event and the given parameters.
|
||||||
|
|
||||||
|
ee.reload()
|
||||||
|
Reloads the EE. Useful for restarting the API for various reasons.
|
||||||
|
|
||||||
|
ee.info()
|
||||||
|
Displays API info, ie. version number and whether debug is true or false.
|
||||||
|
ee.startTimer(timeout)
|
||||||
|
Queues an event to be triggered after a number of seconds (timeout).
|
||||||
|
The ID of the timer is returned from this function to differentiate multiple timers.
|
||||||
|
Timers are one-shot; once they have fired an event you will need to start another one if you need a recurring timer.
|
||||||
|
|
||||||
|
ee.clock()
|
||||||
|
Returns the amount of time since the in-game computer was started.
|
||||||
|
|
||||||
|
ee.cancelTimer()
|
||||||
|
Cancels a running timer, to prevent it throwing an event.
|
||||||
|
|
||||||
|
ee.sleep(time)
|
||||||
|
Waits for the specified amount of seconds.
|
||||||
|
Minimum = 0.05s.
|
||||||
|
If unspecified, sleep for 0.05 seconds.
|
||||||
|
|
||||||
|
ee.serialize(table/string/int/boolean/nil serial)
|
||||||
|
Returns a string representation of the data (serial) for storage or transmission.
|
||||||
|
|
||||||
|
ee.unserialize(serializedData)
|
||||||
|
Returns the data reassembled from string serializedData.
|
||||||
|
Used mainly together with ee.serialize().
|
||||||
|
|
||||||
|
ee.serializeJSON(table/string/number/boolean data [, boolean unquote keys])
|
||||||
|
Returns a JSON representation of the data data in a form of a string.
|
||||||
|
Mainly for command usage.
|
||||||
|
|
||||||
|
ee.urlEncode
|
||||||
|
Makes a string safe to encode into a url.
|
||||||
|
Spaces are replaced with +s.
|
||||||
|
Unsafe characters such as '\', '£' and '}' are translated into ASCII code and preceded with a % for transmission.
|
||||||
|
|
||||||
|
ee.locate(timeout [boolean debug])
|
||||||
|
Tries to retrieve the location.
|
||||||
|
On success, returns the location of the modem.
|
||||||
|
On failure (if no responses are received after timeout, by default 2), returns nil.
|
||||||
|
If debug is true, debug messages are printed.
|
||||||
|
--]]
|
|
@ -0,0 +1,136 @@
|
||||||
|
--[[
|
||||||
|
|
||||||
|
This is documentation for the Vector Unit API.
|
||||||
|
|
||||||
|
The VU is a powerful API designed to make
|
||||||
|
calculations (including but not limited to
|
||||||
|
vectors) more efficient while allowing
|
||||||
|
for complex maths.
|
||||||
|
|
||||||
|
Example of how vectors can be used to improve
|
||||||
|
other code:
|
||||||
|
------------------------------------------------------------
|
||||||
|
local home = vu.new(45, 85, 20)
|
||||||
|
local position = vu.new(ee.locate(5))
|
||||||
|
local displacement = position - home
|
||||||
|
|
||||||
|
print("I am ", tostring(displacement), " away from home!!!")
|
||||||
|
------------------------------------------------------------
|
||||||
|
|
||||||
|
In the above example, X/Y/Z vectors are used
|
||||||
|
to set the home coordinates. This is used
|
||||||
|
to accompany GPS location approximation on
|
||||||
|
the EE so that both VU/EE can work together
|
||||||
|
to produce a result.
|
||||||
|
|
||||||
|
Vectors are commonly used with GPS algorithms
|
||||||
|
because a new vector uses X, Y and Z
|
||||||
|
variables. However, this is far from their
|
||||||
|
only use. Vectors can also be used as more
|
||||||
|
effective tables for numbers, for example.
|
||||||
|
|
||||||
|
----------------------------
|
||||||
|
table.foreach(Vector,print)
|
||||||
|
copy function: 0x80692c0
|
||||||
|
dot function: 0x8069300
|
||||||
|
mag function: 0x80692e0
|
||||||
|
new function: 0x8069398
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Smart utilisation of vectors on the VU leads
|
||||||
|
to more efficient, clean, fast and advanced
|
||||||
|
code.
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------
|
||||||
|
Description of vectors
|
||||||
|
From ComputerCraft Wiki:
|
||||||
|
Vectors act much like tables, storing the coordinate data with labels "x", "y" and "z". However, it can be worthwhile to use vectors instead of tables in certain situations.
|
||||||
|
|
||||||
|
|
||||||
|
Among other things, vectors can be useful to aid in creating navigation algorithms using GPS coordinates.
|
||||||
|
|
||||||
|
To transform GPS quickly into vector format, simply use:
|
||||||
|
|
||||||
|
local a = vu.new(gps.locate())
|
||||||
|
Then, getting the displacements between a turtle position and a desired location becomes:
|
||||||
|
|
||||||
|
local b = vu.new(20, 85, 40)
|
||||||
|
local c = a - b
|
||||||
|
--displacement in the x direction: c.x
|
||||||
|
--displacement in the y direction: c.y
|
||||||
|
--displacement in the z direction: c.z
|
||||||
|
By making use of vectors, code can be cleaner and easier to follow.
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
From Advanced Vectors, code modified for VU:
|
||||||
|
|
||||||
|
Advanced Vector API by Tomass1996
|
||||||
|
|
||||||
|
Vector 'Object' Functions And Fields:
|
||||||
|
vu.x -- Vectors X component
|
||||||
|
vu.y -- Vectors Y component
|
||||||
|
vu.z -- Vectors Z component
|
||||||
|
vu:add(otherVector) -- Component-wise addition
|
||||||
|
vu:scalarAdd(n) -- Scalar addition
|
||||||
|
vu:subtract(otherVector) -- Component-wise subtraction
|
||||||
|
vu:scalarSubtract(n) -- Scalar subtraction
|
||||||
|
vu:multiply(otherVector) -- Component-wise multiplication
|
||||||
|
vu:scalarMultiply(n) -- Scalar multiplication
|
||||||
|
vu:divide(otherVector) -- Component-wise division
|
||||||
|
vu:scalarDivide(n) -- Scalar division
|
||||||
|
vu:length() -- Get the length of the vector
|
||||||
|
vu:lengthSq() -- Get the length ^ 2 of the vector
|
||||||
|
vu:distance(otherVector) -- Get the distance away from a vector
|
||||||
|
vu:distanceSq(otherVector) -- Get the distance away from a vector, squared
|
||||||
|
vu:normalize() -- Get the normalized vector
|
||||||
|
vu:dot(otherVector) -- Get the dot product of vector and otherVector
|
||||||
|
vu:cross(otherVector) -- Get the cross product of vector and otherVector
|
||||||
|
vu:containedWithin(minVec, maxVec) -- Check to see if vector is contained within minVec and maxVec
|
||||||
|
vu:clampX(min, max) -- Clamp the X component
|
||||||
|
vu:clampY(min, max) -- Clamp the Y component
|
||||||
|
vu:clampZ(min, max) -- Clamp the Z component
|
||||||
|
vu:floor() -- Rounds all components down
|
||||||
|
vu:ceil() -- Rounds all components up
|
||||||
|
vu:round() -- Rounds all components to the closest integer
|
||||||
|
vu:absolute() -- Vector with absolute values of components
|
||||||
|
vu:isCollinearWith(otherVector) -- Checks to see if vector is collinear with otherVector
|
||||||
|
vu:getIntermediateWithX(other, x) -- New vector with given x value along the line between vector and other, or nil if not possible
|
||||||
|
vu:getIntermediateWithY(other, y) -- New vector with given y value along the line between vector and other, or nil if not possible
|
||||||
|
vu:getIntermediateWithZ(other, z) -- New vector with given z value along the line between vector and other, or nil if not possible
|
||||||
|
vu:rotateAroundX(angle) -- Rotates vector around the x axis by the specified angle(radians)
|
||||||
|
vu:rotateAroundY(angle) -- Rotates vector around the y axis by the specified angle(radians)
|
||||||
|
vu:rotateAroundZ(angle) -- Rotates vector around the z axis by the specified angle(radians)
|
||||||
|
vu:clone() -- Returns a new vector with same component values as vector
|
||||||
|
vu:equals(otherVector) -- Checks to see if vector and otherVector are equal
|
||||||
|
vu:tostring() -- Returns the string representation of vector "(x, y, z)"
|
||||||
|
|
||||||
|
Vector 'Object' Metatable Overrides: -- [x, y, z] represents a vector object in these examples, not irl
|
||||||
|
To String -- tostring will get the string representation
|
||||||
|
ie. tostring([1, 2, 3]) --> "(1, 2, 3)"
|
||||||
|
Unary Minus -- Using unary minus on a vector will result in the negative of vector
|
||||||
|
ie. -[1, -2, 3] --> [-1, 2, -3]
|
||||||
|
Addition -- Can add two vectors or vector and number with +
|
||||||
|
ie. [1, 2, 3] + [4, 5, 6] --> [5, 7, 9]
|
||||||
|
[1, 2, 3] + 3 --> [4, 5, 6]
|
||||||
|
Subtraction -- Can subtract two vectors or vector and number with -
|
||||||
|
ie. [4, 5, 6] - [1, 2, 3] --> [3, 3, 3]
|
||||||
|
[4, 5, 6] - 3 --> [1, 2, 3]
|
||||||
|
Multiplication -- Can multiply two vectors or vector and number with *
|
||||||
|
ie. [1, 2, 3] * [4, 5, 6] --> [4, 10, 18]
|
||||||
|
[1, 2, 3] * 3 --> [3, 6, 9]
|
||||||
|
Division -- Can divide two vectors or vector and number with /
|
||||||
|
ie. [4, 10, 18] / [1, 2, 3] --> [4, 5, 6]
|
||||||
|
[3, 6, 9] / 3 --> [1, 2, 3]
|
||||||
|
Equality -- Can check if two vectors are the same with ==
|
||||||
|
ie. [4, 5, 6] == [4, 5, 6] --> true
|
||||||
|
[4, 5, 6] == [4, 99, 6] --> false
|
||||||
|
|
||||||
|
Vector API functions (Can be used in VU by replacing "Vector" with "VU":
|
||||||
|
Vector.getMinimum(v1, v2) -- Gets the minimum components of two vectors
|
||||||
|
Vector.getMaximum(v1, v2) -- Gets the maximum components of two vectors
|
||||||
|
Vector.getMidpoint(v1, v2) -- Gets the midpoint of two vectors
|
||||||
|
Vector.isVector(v) -- Checks whether v is a vector created by this api
|
||||||
|
Vector.new(x, y, z) -- Creates a new vector object with the component values
|
||||||
|
--]]
|
|
@ -1,48 +0,0 @@
|
||||||
local function render()
|
|
||||||
term.setBackgroundColour(colours.white)
|
|
||||||
term.clear()
|
|
||||||
term.setBackgroundColour(colours.grey)
|
|
||||||
term.setCursorPos(1,1)
|
|
||||||
term.clearLine()
|
|
||||||
center(1,"GameStation 2")
|
|
||||||
term.setCursorPos(1,2)
|
|
||||||
print(" ")
|
|
||||||
print(" Disk ")
|
|
||||||
print(" Info ")
|
|
||||||
print(" Strafe ")
|
|
||||||
print(" Vinyl ")
|
|
||||||
print(" Shutdown ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
print(" ")
|
|
||||||
end
|
|
||||||
|
|
||||||
while true do render()
|
|
||||||
local evt, button, x, y = os.pullEvent("mouse_click")
|
|
||||||
if y == 3 then shell.run("/GS2/Disk")
|
|
||||||
elseif y == 4 then shell.run("/GS2/Info")
|
|
||||||
elseif y == 5 then shell.run("/GS2/Strafe")
|
|
||||||
elseif y == 6 then shell.run("/GS2/Vinyl")
|
|
||||||
elseif y == 7 then term.setBackgroundColour(colours.white)
|
|
||||||
term.clear()
|
|
||||||
center(8,"Shutting Down...")
|
|
||||||
sleep(0.7)
|
|
||||||
term.setBackgroundColour(colours.lightGrey)
|
|
||||||
term.clear()
|
|
||||||
sleep(0.25)
|
|
||||||
term.setBackgroundColour(colours.grey)
|
|
||||||
term.clear()
|
|
||||||
sleep(0.2)
|
|
||||||
os.shutdown()
|
|
||||||
else
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,45 +1,63 @@
|
||||||
function center(y,string)
|
os.loadAPI("/GS2/APIs/gs")
|
||||||
local w,h = term.getSize()
|
os.loadAPI("/GS2/APIs/ee")
|
||||||
local x = (w/2)-(#string/2)
|
|
||||||
term.setCursorPos(x,y)
|
|
||||||
print(string)
|
|
||||||
end
|
|
||||||
|
|
||||||
function centerSlow(y,string)
|
if peripheral.find("monitor") then
|
||||||
local w,h = term.getSize()
|
shell.run("monitor right startup")
|
||||||
local x = (w/2)-(#string/2)
|
|
||||||
term.setCursorPos(x,y)
|
|
||||||
textutils.slowPrint(string)
|
|
||||||
end
|
|
||||||
|
|
||||||
if peripheral.find("monitor") then shell.run("monitor right startup")
|
|
||||||
shell.run("monitor left startup")
|
shell.run("monitor left startup")
|
||||||
shell.run("monitor top startup")
|
shell.run("monitor top startup")
|
||||||
shell.run("monitor bottom startup")
|
shell.run("monitor bottom startup")
|
||||||
shell.run("monitor front startup")
|
shell.run("monitor front startup")
|
||||||
shell.run("monitor back startup")
|
shell.run("monitor back startup")
|
||||||
|
|
||||||
elseif not term.isColour then
|
elseif not term.isColour then
|
||||||
term.setBackgroundColour(colours.white)
|
|
||||||
term.setTextColour(colours.black)
|
-- Colour-monochrome wrapper by Gonow32
|
||||||
term.clear()
|
|
||||||
centerSlow(8,"Whoops!")
|
local current = term.current()
|
||||||
centerSlow(10,"Please use GameStation 2 on an advanced computer!")
|
term.redirect(window.create(current,1,1,current.getSize()))
|
||||||
sleep(3)
|
|
||||||
term.setBackgroundColour(colours.black)
|
if not term.isColour() then
|
||||||
term.clear()
|
local oldback = term.setBackgroundColour
|
||||||
term.setCursorPos(1,1)
|
function term.setBackgroundColor(colour)
|
||||||
error("Monochrome not supported (yet)")
|
if colour == 1 then
|
||||||
|
oldback(colour)
|
||||||
|
else
|
||||||
|
oldback(colours.black)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
term.setBackgroundColour = term.setBackgroundColor
|
||||||
|
|
||||||
|
local oldtext = term.setTextColour
|
||||||
|
function term.setTextColor(colour)
|
||||||
|
if colour == 32768 then
|
||||||
|
oldtext(colour)
|
||||||
|
else
|
||||||
|
oldtext(colours.white)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
gs.setTxt("white")
|
||||||
|
gs.clrBg("red")
|
||||||
|
gs.centerSlow(6,"Game Fusion Presents...")
|
||||||
|
sleep(1.5)
|
||||||
|
gs.clr()
|
||||||
|
gs.centerSlow(6,"GameStation 2.")
|
||||||
|
sleep(1)
|
||||||
|
gs.center(7,"The ultimate CC console.")
|
||||||
|
sleep(2)
|
||||||
|
shell.run("/GS2/Browser")
|
||||||
|
|
||||||
else
|
else
|
||||||
term.setTextColour(colours.white)
|
gs.setTxt("white")
|
||||||
term.setBackgroundColour(colours.red)
|
gs.clrBg("red")
|
||||||
term.clear()
|
gs.centerSlow(6,"Game Fusion Presents...")
|
||||||
centerSlow(6,"Game Fusion Presents...")
|
|
||||||
sleep(1.5)
|
sleep(1.5)
|
||||||
term.clear()
|
gs.clr()
|
||||||
centerSlow(6,"GameStation 2.")
|
gs.centerSlow(6,"GameStation 2.")
|
||||||
sleep(1)
|
sleep(1)
|
||||||
center(7,"The Ultimate CC Console.")
|
gs.center(7,"The ultimate CC console.")
|
||||||
sleep(2.25)
|
sleep(2)
|
||||||
shell.run("/GS2/Browser")
|
shell.run("/GS2/Browser")
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Basic documentation for high resolution
|
||||||
|
graphics on GS2, utilising the GS
|
||||||
|
API functions at developers'
|
||||||
|
disposal to not only make life easier,
|
||||||
|
but to demonstrate practical use cases
|
||||||
|
of the GS and to give developers an
|
||||||
|
idea of how to set up their programs
|
||||||
|
to be as graphically flexible as
|
||||||
|
possible.
|
||||||
|
|
||||||
|
Written by Mr_Iron2, (C) 2018
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
The key to the best possible graphical
|
||||||
|
experience is to make things dynamic
|
||||||
|
wherever possible. To start, instead of
|
||||||
|
setting predefined resolution variables
|
||||||
|
(designed around a typical 51x19 CC
|
||||||
|
computer screen) we should instead get
|
||||||
|
the size of the current window.
|
||||||
|
|
||||||
|
To do this with GS, simply call:
|
||||||
|
local w,h = gs.winSize()
|
||||||
|
|
||||||
|
This command gets the size of the current
|
||||||
|
window, and assigns the resolutions to the
|
||||||
|
"w" and "h" variables. For example, on a
|
||||||
|
51x19 display, this would mean w = 51 and
|
||||||
|
h = 19. This is far more efficient than
|
||||||
|
hard-coding resolution values.
|
||||||
|
|
||||||
|
Now you can design your program around
|
||||||
|
these variables. For example, the GS
|
||||||
|
"center" code averages the center point
|
||||||
|
of the screen based on the length of the
|
||||||
|
text and the width of the screen. Here's
|
||||||
|
the source code:
|
||||||
|
|
||||||
|
function center(y, string)
|
||||||
|
local x = (w/2)-(#string/2)
|
||||||
|
term.setCursorPos(x,y)
|
||||||
|
print(string)
|
||||||
|
end
|
||||||
|
|
||||||
|
What this function is doing is taking the
|
||||||
|
"W" and "H" parameters we got earlier from
|
||||||
|
gs.winSize() and using them in a practical
|
||||||
|
situation. To get X, the horizontal point
|
||||||
|
the cursor is set to, it divides the horizontal
|
||||||
|
resolution (W ie. width) by two, and subtracts
|
||||||
|
the length of the text. It then takes a value
|
||||||
|
for Y from the user, as you can see below,
|
||||||
|
and sets the cursor accordingly to print the
|
||||||
|
text.
|
||||||
|
|
||||||
|
gs.center(8, "Hello world!")
|
||||||
|
|
||||||
|
That's not so difficult, is it? This center
|
||||||
|
code is a great example of how the program
|
||||||
|
can be adapted to adjust itself dynamically
|
||||||
|
based on the window/screen resolution. It
|
||||||
|
will always find the horizontal center because
|
||||||
|
it uses a dynamic width value given to us by
|
||||||
|
gs.winSize(), so this allows us to use this code
|
||||||
|
at any resolution we like!
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
Adjusting resolution for monitors
|
||||||
|
|
||||||
|
By default, monitors have a text scale of 1.
|
||||||
|
Using the default text scale, a single monitor
|
||||||
|
has a resolution of 7 pixels horizontally by 5
|
||||||
|
pixels vertically (7x5). With the default text
|
||||||
|
scale, monitor borders take up two pixels on the
|
||||||
|
left and right sides, and one pixel on the top
|
||||||
|
and bottom sides. Using the default text
|
||||||
|
scale, the largest possible monitor cluster - 8
|
||||||
|
blocks wide and 6 blocks tall - has a resolution
|
||||||
|
of 70x40. However, this isn't the highest we can go.
|
||||||
|
The text scale of monitor.setTextScale can be increased
|
||||||
|
or decreased in increments of 0.5, and the highest
|
||||||
|
resolution setting is achieved when the text scale is set
|
||||||
|
to 0.5. Under this setting, a single monitor has a
|
||||||
|
resolution of 15x10. At this scale, monitor borders take
|
||||||
|
up three pixels on the left and right sides, and two
|
||||||
|
pixels on the top and bottom sides.
|
||||||
|
|
||||||
|
Using the 0.5 text scale for maximum resolution, the
|
||||||
|
largest possible monitor cluster has a total resolution
|
||||||
|
of 162 pixels horizontally by 80 pixels vertically.
|
||||||
|
That's a lot of hi-res potential! So using the
|
||||||
|
techniques mentioned before, we can do a lot of cool
|
||||||
|
stuff. To set the scale of the text on a monitor, use
|
||||||
|
the following GS command:
|
||||||
|
|
||||||
|
gs.monTxtScale(size)
|
||||||
|
|
||||||
|
Simple enough, right? This encapsulates a few lines of
|
||||||
|
code and handles what the current display is before calling
|
||||||
|
the generic setTextScale command. So by setting this to 0.5
|
||||||
|
we can get the highest possible resolution out of our
|
||||||
|
GS2. By using this with our above command, we can get the best
|
||||||
|
experience with a dynamic way of handling the resolution and
|
||||||
|
getting the most pixels out of a ComputerCraft monitor.
|
||||||
|
What's important to note is that this command doesn't simply
|
||||||
|
change the size of text; it also changes the size of pixels
|
||||||
|
drawn by paintutils, so this is a really powerful command and
|
||||||
|
it's strongly recommended when using a monitor! To wrap the
|
||||||
|
GS2 to a monitor, use the following code:
|
||||||
|
|
||||||
|
local monitor = peripheral.wrap( "top" )
|
||||||
|
|
||||||
|
(NOTE: As of v1.2, GS has the "gs.wrap(side)" command as well.
|
||||||
|
However, this is a new version of GS, and as such it is advised
|
||||||
|
that if you use this command instead, you should ensure the GS2's
|
||||||
|
GS API is v1.2 or later; local version should return the version.)
|
||||||
|
|
||||||
|
This wraps any code with "monitor" before it to the wrapped display.
|
||||||
|
For example, monitor.write("Hello!")
|
||||||
|
(NOTE: for gs.wrap(), the syntax is mon.write() instead)
|
||||||
|
So by combining these functions, you can get a great high res
|
||||||
|
experience from ComputerCraft! The rest is up to you; the above
|
||||||
|
will give you a framework to build some high-res code around.
|
||||||
|
Happy programming!
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
print("Edit me instead to read!")
|
|
@ -0,0 +1,40 @@
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Guide to networking on the GS2
|
||||||
|
written by Mr_Iron2.
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
The GS2 is known for, among other things,
|
||||||
|
its ambitious forays into servers and
|
||||||
|
networking at launch. It tried everything
|
||||||
|
from a game distribution platform to a game
|
||||||
|
streaming service (which is now used in
|
||||||
|
Revolution's Shield device) and even the
|
||||||
|
famous DNAS system, an optional authentication
|
||||||
|
server which games can pass through.
|
||||||
|
|
||||||
|
---
|
||||||
|
DNAS
|
||||||
|
|
||||||
|
DNAS (Dynamic Network Authentication Service)
|
||||||
|
is a GS2 service which games can pass through
|
||||||
|
to get information about the GS2 and/or to
|
||||||
|
authenticate games connecting to servers or P2P.
|
||||||
|
To send a request to the DNAS servers, simply
|
||||||
|
do the following:
|
||||||
|
|
||||||
|
local modem = peripheral.find("modem")
|
||||||
|
modem.open(661)
|
||||||
|
modem.transmit(661, 661, {sType = "status"})
|
||||||
|
|
||||||
|
This sends a status request to the DNAS servers
|
||||||
|
to check whether DNAS is still online, temporarily
|
||||||
|
down or permanently terminated. Simple, right?
|
||||||
|
|
||||||
|
DNAS also has a utility, which can be found on
|
||||||
|
the GS2 GitHub page, as well as a Network Center
|
||||||
|
program so you can configure and test your
|
||||||
|
connection to DNAS. Handy!
|
||||||
|
|
||||||
|
--]]
|
|
@ -0,0 +1,87 @@
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Guide to GS2SDK written by Mr_Iron2.
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
Welcome to the GameStation 2 Software
|
||||||
|
Development Kit (GS2SDK)! This guide will
|
||||||
|
help you get to grips with what is possible
|
||||||
|
and will hopefully give you some ideas.
|
||||||
|
|
||||||
|
-----
|
||||||
|
APIs:
|
||||||
|
The GS2 has many flexible and powerful APIs
|
||||||
|
to ensure you can write concise code which is
|
||||||
|
readable, easy and efficient. These include a few
|
||||||
|
standard, third party APIs - which you can read into
|
||||||
|
by yourself from their official documentation - but
|
||||||
|
this also includes a selection of tailored APIs
|
||||||
|
exclusively for GS2!
|
||||||
|
|
||||||
|
EE: The GS2's "Emotion Engine" API allows you to
|
||||||
|
perform CPU functions in a concise form. The EE has
|
||||||
|
functionality for maths, bit-shifting, parallelisation,
|
||||||
|
timers and much more! It's a very robust API for general
|
||||||
|
processing. Things that can be done with it include
|
||||||
|
making a calculator, a GPS program, a URLencoder, a JSON
|
||||||
|
serializer, a clock and much more! You can read into it
|
||||||
|
yourself by editing /GS2/APIs/ee and seeing all the functions
|
||||||
|
for yourself; they are very straightforward and easy to
|
||||||
|
understand, like GS.
|
||||||
|
|
||||||
|
GS: The GS2's "Graphics Synthesizer" API is an API
|
||||||
|
designed for processing graphics and rendering tasks.
|
||||||
|
These range from simple nice-to-haves such as one-line
|
||||||
|
functions for clearing the screen to a given background,
|
||||||
|
to more complex functions like wrapping to a monitor, a ton
|
||||||
|
of paintutils commands that can be called on-the-fly and
|
||||||
|
setting up windows/displays! Some things you could make
|
||||||
|
with GS include a paint program, a psuedo-3D game, a
|
||||||
|
platformer, a high-resolution rendering demo and lots of other
|
||||||
|
things! It is a full replacement for term and paintutils while
|
||||||
|
including commands of its own and other miscellaneous
|
||||||
|
functions.
|
||||||
|
|
||||||
|
VU: The most complex API of them all, the "Vector Unit" API
|
||||||
|
is for only the most advanced CC programs. The VU allows for
|
||||||
|
parallelising programs and an array of vector-based processes.
|
||||||
|
Vectors act a lot like tables, storing coordinate data with
|
||||||
|
labels "x", "y" and "z". However, it can be worthwhile to use
|
||||||
|
vectors instead of tables in certain situations. Among other
|
||||||
|
things, vectors can be useful to aid in creating navigation
|
||||||
|
programs using GPS coordinates. By making good use of vectors,
|
||||||
|
code can be cleaner and easier to follow.
|
||||||
|
|
||||||
|
---
|
||||||
|
Networking:
|
||||||
|
|
||||||
|
The GS2 has a special DNAS service designed to allow
|
||||||
|
developers to authenticate or otherwise pass through an
|
||||||
|
official server. This gives a layer of security and assurance
|
||||||
|
but is also completely optional. Read the sdk documentation's
|
||||||
|
piece on networking and you can see how easy it is to
|
||||||
|
send some requests to DNAS, and it also has utility programs
|
||||||
|
available on the GitHub!
|
||||||
|
|
||||||
|
---
|
||||||
|
Footnote
|
||||||
|
|
||||||
|
The GS2 is a flexible machine with APIs and services that will
|
||||||
|
allow you to do anything you can imagine doing in CC with ease.
|
||||||
|
Its APIs allow for concise code and anyone can have immediate
|
||||||
|
access to the GS2 SDK, and not only that - anyone has permission
|
||||||
|
to modify it and redistribute a "homebrew" version of the GS2SDK
|
||||||
|
as well as publishing their own homebrew games, with official
|
||||||
|
licensing available upon request! The only difference is that
|
||||||
|
your game will be added to the list of licensed GS2 games.
|
||||||
|
|
||||||
|
The GS2 is a console that allows you to make anything, so with
|
||||||
|
that in mind, we've done our best to help you with your
|
||||||
|
programming work with our documentation; we hope you enjoy
|
||||||
|
working with the GS2!
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
|
||||||
|
print("Edit me to read!")
|
|
@ -0,0 +1,3 @@
|
||||||
|
-- Set dev path
|
||||||
|
|
||||||
|
shell.setPath(shell.path()..":/.gs2/sdk/bin")
|
|
@ -0,0 +1,75 @@
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Official GameStation 2 (GS2) software development
|
||||||
|
kit (SDK) installer
|
||||||
|
|
||||||
|
By Mr_Iron2/TheMrIron2
|
||||||
|
(C) 2018 Game Fusion
|
||||||
|
GameStation 2 is (C) 2015-2018 Game Fusion.
|
||||||
|
|
||||||
|
NOTE: The GS2 SDK does NOT include the GS2 operating system.
|
||||||
|
It is recommended that the SDK is installed on top of an existing GS2,
|
||||||
|
however this is not required. The SDK can also function as an
|
||||||
|
independent development environment, with no GS2 files necessary.
|
||||||
|
|
||||||
|
This SDK is free to be used by anyone.
|
||||||
|
It is open source and is permissive of modification.
|
||||||
|
You may modify this as you wish and/or redistribute your modified GS2SDK,
|
||||||
|
as long as credit is provided.
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local function center(y, string)
|
||||||
|
local w, h = term.getSize()
|
||||||
|
local x = (w / 2)-(#string / 2)
|
||||||
|
term.setCursorPos(x, y)
|
||||||
|
print(string)
|
||||||
|
end
|
||||||
|
|
||||||
|
term.setBackgroundColour(colours.blue)
|
||||||
|
term.setTextColour(colours.white)
|
||||||
|
term.clear()
|
||||||
|
|
||||||
|
center(3, "Welcome to the GameStation 2 (GS2)")
|
||||||
|
center(4, "Software Development Kit (SDK) installer.")
|
||||||
|
sleep(2)
|
||||||
|
center(6, "This will now install the GS2 SDK.")
|
||||||
|
center(7, "If you do not want the program to continue,")
|
||||||
|
center(8, "please terminate now (CTRL + T). Otherwise, wait 10 seconds.")
|
||||||
|
sleep(10)
|
||||||
|
term.clear()
|
||||||
|
|
||||||
|
-- Removing GS2 components to download new ones
|
||||||
|
if fs.exists("/GS2/APIs/") then
|
||||||
|
fs.delete("/GS2/APIs")
|
||||||
|
else
|
||||||
|
center(1, "GS2 SDK")
|
||||||
|
term.setCursorPos(1,2)
|
||||||
|
term.setBackgroundColour(colours.white)
|
||||||
|
term.clearLine()
|
||||||
|
term.setBackgroundColour(colours.blue)
|
||||||
|
|
||||||
|
-- Downloading everything
|
||||||
|
center(4, "Installing necessary APIs... ")
|
||||||
|
shell.run("pastebin get p7p3R4ze /GS2/APIs/ee")
|
||||||
|
shell.run("pastebin get WXCnYffd /GS2/APIs/gs")
|
||||||
|
shell.run("pastebin get gCkEYHDh /GS2/APIs/vu")
|
||||||
|
write("done!")
|
||||||
|
sleep()
|
||||||
|
center(5, "Installing GS2SDK commandline... ")
|
||||||
|
shell.run("pastebin get yA9ez1Z8")
|
||||||
|
write("done!")
|
||||||
|
sleep()
|
||||||
|
center(6, "Installing Lua pre-processor... ")
|
||||||
|
shell.run("pastebin get V9x3Sctv /.gs2/sdk/bin/lua-preproc")
|
||||||
|
write("done!")
|
||||||
|
sleep(1) -- ensure user sees everything has been completed
|
||||||
|
|
||||||
|
-- Finalising
|
||||||
|
term.clear()
|
||||||
|
center(7, "GS2SDK installed!")
|
||||||
|
center(8, "Run "/.gs2/sdk/dev" to enter the GS2SDK commandline.")
|
||||||
|
sleep(5)
|
||||||
|
|
||||||
|
term.setBackgroundColour(colours.black)
|
||||||
|
term.clear()
|
||||||
|
term.setCursorPos(1, 1)
|
Loading…
Reference in New Issue