This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
nutcase84's profile picture

Redirect API?

Started by nutcase84, 06 February 2014 - 11:06 AM
nutcase84 #1
Posted 06 February 2014 - 12:06 PM
I want to redirect a program so I can put a menu at the top of the screen, but I don't know how to make a redirect api myself and can't figure out how to use other people's. Help! :)/>
Edited on 06 February 2014 - 05:07 PM
SkyRamon #2
Posted 06 February 2014 - 12:33 PM
you can search a menu like i did and put the code


local termWidth, termHeight = term.getSize()
local selectedItem = 1
local onMainMenu = true

function Choice1()
term.clear()
term.setCursorPos(1,1)
print("Changeme to program name1")
sleep(1)
shell.run("Changeme to program name1")
end
function Choice2()
term.clear()
term.setCursorPos(1,1)
print("Send Mail")
sleep(1)
shell.run("SendMail")
end
function Choice3()
term.clear()
term.setCursorPos(1,1)
print("Read Mail")
sleep(1)
shell.run("ReadMail")
end
function Exit()
onMainMenu = false
end
mainMenu = {
[1] = { text = "Changeme to program name", handler = Choice1 },
[2] = { text = "Send Mail", handler = Choice2 },
[3] = { text = "ReadMail", handler = Choice3 },
[4] = { text = "Exit", handler = Exit }
}
function printMenu( menu )
for i=1,#menu do
if i == selectedItem then
print(">> "..menu[i].text)
else
print(" "..menu[i].text)
end
end
end
function onKeyPressed( key, menu )
if key == keys.enter then
onItemSelected(menu)
elseif key == keys.up then
if selectedItem > 1 then
selectedItem = selectedItem - 1
end
elseif key == keys.down then
if selectedItem < #menu then
selectedItem = selectedItem + 1
end
end
end
function onItemSelected( menu )
menu[selectedItem].handler()
end
function main()
while onMainMenu do
term.clear()
term.setCursorPos(1,1)
printMenu(mainMenu)
event, key = os.pullEvent("key")
onKeyPressed(key,mainMenu)
end
end

just change the Changeme to program name to your program name… and you can select your program and it will run
Edited on 06 February 2014 - 11:34 AM
nutcase84 #3
Posted 06 February 2014 - 02:57 PM
-Snip

Uhh… you in the right section bro? It's called "Ask A Pro"… :D/>

I want the menu to be there always. Even when a program has been launched. It will look exactly like Flow OS's menu bar. Look at screenshots.
Edited on 06 February 2014 - 05:10 PM
SkyRamon #4
Posted 06 February 2014 - 05:50 PM
well after you lanched the program and its done you should get back to it automaticly.
otherwise write


parallel.WaitForAll(main)

at bottom of the main menu code
Edited on 06 February 2014 - 04:51 PM
nutcase84 #5
Posted 06 February 2014 - 06:05 PM
well after you lanched the program and its done you should get back to it automaticly.
otherwise write


parallel.WaitForAll(main)

at bottom of the main menu code

Whatever program has launched can draw over the menu using that method. I have tried overriding the term and paintutil functions, but I can't get it to work properly.
D3matt #6
Posted 06 February 2014 - 07:16 PM
You want to use the term AP to create a new term object that copies all of the term API functions except modified to create your menu bar at the top and write everything below it.
nutcase84 #7
Posted 06 February 2014 - 08:21 PM
You want to use the term AP to create a new term object that copies all of the term API functions except modified to create your menu bar at the top and write everything below it.

I demand a explanation! This sounds good! ;)/>
D3matt #8
Posted 06 February 2014 - 08:35 PM
You'll want to look in your ComputerCraft/lua/ROM folder at the term API and copy the functions you'll need to change into your OWN API. At runtime you'll want to create a table containing references to all those functions. The unchanged ones you can reference straight from the term API. Then you'll want to term.redirect to the new table.

A very basic mockup:


faketerm = {write = mytermAPI.write, clearLine = term.clearLine}
term.direct(faketerm)

If you have ever done OOP in lua, this should look fairly similar. What happens is that the faketerm table is treated as a peripheral with an API like monitors. Whenever you call a terminal function, instead of calling the monitor API, it calls the functions you defined in your table. All you need to do is change those functions to do what you want.

Keeping in mind I might be horribly wrong. I've never done anything with this before, but I'm familiar enough with the theory, and with OOP (Object Oriented Programming)
Edited on 06 February 2014 - 07:37 PM
Lyqyd #9
Posted 06 February 2014 - 10:11 PM
The term API in /rom/apis doesn't have anything interesting in it. You'll want to get the list of functions you need by either iterating term.native (1.58 and earlier) or iterating the table returned by term.native() (1.6beta and later).
D3matt #10
Posted 06 February 2014 - 10:54 PM
The term API in /rom/apis doesn't have anything interesting in it. You'll want to get the list of functions you need by either iterating term.native (1.58 and earlier) or iterating the table returned by term.native() (1.6beta and later).
So there's no quick and easy way to make a clone of the terminal, then.
nutcase84 #11
Posted 07 February 2014 - 06:51 AM
I thought there was a API that did all this for me…
theoriginalbit #12
Posted 07 February 2014 - 07:01 AM
well if you only want to overwrite specific functions you can use metatables


local termObj = {
  clear = function()
	term.native.clear()
	term.setCursorPos(1,1)
	print("Awesome sauce")
  end
}

setmetatable(termObj, {__index = term.native})

term.redirect(termObj)

--# code that uses new term

term.restore()
doing the above means you don't need to make an implementation of each function in your new redirect object…

it should be noted that in CC1.6beta you'd have to use
local termObj = {
  clear = function()
	term.native().clear()
	term.setCursorPos(1,1)
	print("Awesome sauce")
  end
}

setmetatable(termObj, {__index = term.native()})

local previousTerm = term.redirect(termObj)

--# code that uses new term

term.redirect(previousTerm)

EDIT: oops, bugfix in 1.6beta code.
Edited on 07 February 2014 - 06:10 AM
nutcase84 #13
Posted 07 February 2014 - 10:07 AM
If I run the menu and the program through the parallel API, and just redraw the menu every so often, will that work? I would still have to redo most of the functions, but what about when a program draws outside of the screen? (games)
D3matt #14
Posted 07 February 2014 - 08:48 PM
I think it would be more effective and almost as easy to just write up a term clone.

Are there any servers you play on? I'd like to get on and chat and try and code something like this.
nutcase84 #15
Posted 08 February 2014 - 11:33 AM
I think it would be more effective and almost as easy to just write up a term clone.

Are there any servers you play on? I'd like to get on and chat and try and code something like this.

I am admin on karelmikie3's server.
Symmetryc #16
Posted 10 February 2014 - 04:54 PM
I don't really understand what you're trying to accomplish. Are you trying to overlay a menu on top of a running program?
nutcase84 #17
Posted 10 February 2014 - 05:17 PM
I don't really understand what you're trying to accomplish. Are you trying to overlay a menu on top of a running program?

Yes!
Symmetryc #18
Posted 10 February 2014 - 06:48 PM
I don't really understand what you're trying to accomplish. Are you trying to overlay a menu on top of a running program?

Yes!
Are you sure you don't just want to adjust the size and position of the program so that it fits in the space below the menu, rather than sit on top of the program (obstructing part of it)?
Edited on 10 February 2014 - 05:52 PM
nutcase84 #19
Posted 10 February 2014 - 07:41 PM
I don't really understand what you're trying to accomplish. Are you trying to overlay a menu on top of a running program?

Yes!
Are you sure you don't just want to adjust the size and position of the program so that it fits in the space below the menu, rather than sit on top of the program (obstructing part of it)?

That's why I said I wanted a "redirect" API. Thanks for understanding! I am making another OS, (:D/>) and I want to make it have a menu always there.
Bomb Bloke #20
Posted 11 February 2014 - 08:12 PM
That doesn't really answer his question…

There are two ways to go about this. One is to have your API ignore any attempts by the running script to write stuff to the first line of the screen. This is fairly simple, but has a big downside in that you simply won't see the first line such scripts attempt to write - it'll be cropped out of view.

The other is to have your API capture ANY writes by the running script, and move them down one line. The upside is that the first line no longer gets cropped out of view - it's now just a line lower. The downside is that you've gotta rewrite most of the term API to pull it off. Optionally, you'd also report a smaller screen size to the scripts you run - this will allow those scripts which feel they "need" the whole display to throw up appropriate errors.

He's wondering which of these approaches you intend to take with your API.

Either way, you'll need to capture mouse input as well… The first method requires you to prevent the running script from "seeing" clicks in the top row. The second method requires you to report all clicks (except those to the top row) as being a line lower then they were actually located at. Either way you need to handle clicks to the menu bar itself.

While you could just rig co-routines to re-draw the menu bar whenever there's a chance, you never know how often you'll get those chances, let alone whether or not it needs to be redrawn. Expect a lot of flickering and an overall performance hit if you take that approach.
nutcase84 #21
Posted 12 February 2014 - 08:16 AM
That doesn't really answer his question…

There are two ways to go about this. One is to have your API ignore any attempts by the running script to write stuff to the first line of the screen. This is fairly simple, but has a big downside in that you simply won't see the first line such scripts attempt to write - it'll be cropped out of view.

The other is to have your API capture ANY writes by the running script, and move them down one line. The upside is that the first line no longer gets cropped out of view - it's now just a line lower. The downside is that you've gotta rewrite most of the term API to pull it off. Optionally, you'd also report a smaller screen size to the scripts you run - this will allow those scripts which feel they "need" the whole display to throw up appropriate errors.

He's wondering which of these approaches you intend to take with your API.

Either way, you'll need to capture mouse input as well… The first method requires you to prevent the running script from "seeing" clicks in the top row. The second method requires you to report all clicks (except those to the top row) as being a line lower then they were actually located at. Either way you need to handle clicks to the menu bar itself.

While you could just rig co-routines to re-draw the menu bar whenever there's a chance, you never know how often you'll get those chances, let alone whether or not it needs to be redrawn. Expect a lot of flickering and an overall performance hit if you take that approach.

Yes, I need to move them down one line, not crop them. I couldn't figure out how to do it. All the text and stuff was messed up… so I was wondering if someone already made a API for this.
Edited on 12 February 2014 - 07:19 AM
CometWolf #22
Posted 12 February 2014 - 10:51 AM
A really quick and easy way of doing this would be overwriting the setCursorPos, getSize and pullEvent functions. This does however mean that you'll have to use the backup methods.

_G.backup = {
  term = {
	setCursorPos = _G.term.setCursorPos,
	getSize = _G.term.getSize
  }
  os = {
	pullEventRaw = _G.os.pullEventRaw
  }
}
_G.term.setCursorPos = function(x,y)
  _G.backup.term.setCursorPos(x,math.max(2,y))
end
_G.term.getSize = function()
  local x,y = _G.term.getSize()
  return x,y-1
end
_G.os.pullEventRaw = function(filter)
	local tEvent = {_G.backup.os.pullEvent(filter)}
	if tEvent[1] == "mouse_click" then
	  tEvent[3] = tEvent[3]-1
	  --menu code here
	end
  return unpack(tEvent)
end

The API way of doing this would require a bit more work. So here's a quick attempt i just threw together.
http://pastebin.com/FH3eB0t8

os.loadAPI"redir"
--this is how to use it on a running program
redir.redirect(getfenv())
-- this is how to use it on a program you wish to run
local prog = loadfile"/progPath"
redir.redirect(prog)
prog()
Do note however that both of these approaches require you to program your menu into them, because of how pullEvent works.
Edited on 12 February 2014 - 09:53 AM
nutcase84 #23
Posted 12 February 2014 - 11:29 AM
A really quick and easy way of doing this would be overwriting the setCursorPos, getSize and pullEvent functions. This does however mean that you'll have to use the backup methods.

_G.backup = {
  term = {
	setCursorPos = _G.term.setCursorPos,
	getSize = _G.term.getSize
  }
  os = {
	pullEventRaw = _G.os.pullEventRaw
  }
}
_G.term.setCursorPos = function(x,y)
  _G.backup.term.setCursorPos(x,math.max(2,y))
end
_G.term.getSize = function()
  local x,y = _G.term.getSize()
  return x,y-1
end
_G.os.pullEventRaw = function(filter)
	local tEvent = {_G.backup.os.pullEvent(filter)}
	if tEvent[1] == "mouse_click" then
	  tEvent[3] = tEvent[3]-1
	  --menu code here
	end
  return unpack(tEvent)
end

The API way of doing this would require a bit more work. So here's a quick attempt i just threw together.
http://pastebin.com/FH3eB0t8

os.loadAPI"redir"
--this is how to use it on a running program
redir.redirect(getfenv())
-- this is how to use it on a program you wish to run
local prog = loadfile"/progPath"
redir.redirect(prog)
prog()
Do note however that both of these approaches require you to program your menu into them, because of how pullEvent works.

Can you launch a program from the menu code inside of the API?
CometWolf #24
Posted 12 February 2014 - 12:09 PM
Yeah i don't see why not. However, the original program wouldn't be closed and the menu would stop working, unless you use the API on the program that's loaded aswell. If you do that however, you'd end up with some slight recursion. I just realized there is a simple way to keep the menu code seperate from the API, using parallel.

os.loadAPI"redir"
local program = loadFile"/programPath"
redir.redirect(program)
parallel.waitForAny(program,
  function()
	--menu code here
  end
)
Edited on 12 February 2014 - 11:17 AM
nutcase84 #25
Posted 12 February 2014 - 01:46 PM
Yeah i don't see why not. However, the original program wouldn't be closed and the menu would stop working, unless you use the API on the program that's loaded aswell. If you do that however, you'd end up with some slight recursion. I just realized there is a simple way to keep the menu code seperate from the API, using parallel.

os.loadAPI"redir"
local program = loadFile"/programPath"
redir.redirect(program)
parallel.waitForAny(program,
  function()
	--menu code here
  end
)

Thanks, I'll try that, it looks much more simple and understandable. XD

EDIT: Would I have to program my menu with something like term.setCursorPos(0) so I can put it on the top of the screen? Or will it work without anything fancy like that?
Edited on 12 February 2014 - 12:47 PM
CometWolf #26
Posted 12 February 2014 - 02:07 PM
I haven't exactly tested this API extensivly, but you should be able to use any non-redirected program as normal.
nutcase84 #27
Posted 12 February 2014 - 04:48 PM
Spoiler

os.loadAPI"redir"
local program = loadfile("paint test")
redir.redirect(program)
parallel.waitForAny(program,
  function()
--NutOS 1.0.0 DEVELOPMENT VERSION
--Made by nutcase84
--Do not distribute modified code without permission.
--ToDo
--Finish Override
--Implement Programs
--Make Settings Thing
--Menu Over Programs
--API?
--Multitasking?
--Variables
menuColor = colors.blue
menuXLength = 10
--[[Overrides
oldGetCursorPos = term.getCursorPos
oldSetCursorPos = term.setCursorPos
oldGetSize = term.getSize
oldPaintLine = paintutils.drawLine
oldPaintPixel = paintutils.drawPixel
term.getCursorPos = function()
  local x, y = oldGetCursorPos()
  return x, y + 1
end
term.setCursorPos = function(x, y)
  oldSetCursorPos(x, y + 1)
end]]
while true do
  term.setBackgroundColor(colors.white)
  term.setTextColor(colors.white)
  term.clear()
  paintutils.drawLine(1, 1, term.getSize(), 1, menuColor)
  term.setCursorPos(1,1)
  print("[Menu]  [Programs]")
  local event, button, x, y = os.pullEvent("mouse_click")
  if x >= 1 and x <= 7 and y == 1 then
	term.setBackgroundColor(colors.gray)
	term.setCursorPos(1,1)
	print("[Menu]")
	term.setTextColor(colors.black)
	print(" About	")
	print(" Settings ")
	print(" Reboot   ")
	print(" Shutdown ")
	local event, button, x, y = os.pullEvent("mouse_click")
	if x >= 1 and x <= menuXLength then
	  if y == 2 then
		shell.run("hello")
	  elseif y == 4 then
		os.reboot()
	  elseif y == 5 then
		os.shutdown()
	  end
	end
  end
end
  end
)

redir:69: Unable to redirect to a nil
Edited on 12 February 2014 - 03:48 PM
CometWolf #28
Posted 12 February 2014 - 05:11 PM
i did a few changes to the redir api, so you can just pass it the program path directly now, however chances are you're getting the error because the file "paint test" dosen't exist". Keep in mind that this API requies absolute paths, and you can't pass an argument to the program either, as it does not use shell.run.
Edited on 12 February 2014 - 04:13 PM
theoriginalbit #29
Posted 12 February 2014 - 06:20 PM
A really quick and easy way of doing this would be overwriting the setCursorPos, getSize and pullEvent functions. This does however mean that you'll have to use the backup methods.
you don't have to… as I've said already, you can make a term object and just redirect to it, its what I do in CCTicTacToe to easier support normal and advanced computers.

and you can't pass an argument to the program either, as it does not use shell.run.
Well could can with one change, you realise that shell.run uses os.run, and os.run uses loadfile and then invokes the function… look at the code below to see how you can do it in yours

os.run

function os.run( _tEnv, _sPath, ... )
	local tArgs = { ... }
	local fnFile, err = loadfile( _sPath )
	if fnFile then
		local tEnv = _tEnv
		setmetatable( tEnv, { __index = _G } )
		setfenv( fnFile, tEnv )
		local ok, err = pcall( function()
		 fnFile( unpack( tArgs ) )
		end )
		if not ok then
		 if err and err ~= "" then
		printError( err )
			end
		 return false
		end
		return true
	end
	if err and err ~= "" then
		printError( err )
		printError( "bar" )
	end
	return false
end
Edited on 12 February 2014 - 05:20 PM
Symmetryc #30
Posted 12 February 2014 - 08:01 PM
Woops, didn't click the link above…
Spoiler
A really quick and easy way of doing this would be overwriting the setCursorPos, getSize and pullEvent functions. This does however mean that you'll have to use the backup methods.
you don't have to… as I've said already, you can make a term object and just redirect to it, its what I do in CCTicTacToe to easier support normal and advanced computers.
Imho, an even better way is just

setfenv(
  loadfile("path"),
  setmetatable(
	{
	  term = {
		--[[override stuffs]]--
	  }
	},
	{
	  __index = _G
	}
  )
)()
So that you don't have to mess around with restoring or possible screw ups or anything since it's all controlled.
Edited on 13 February 2014 - 04:57 AM
CometWolf #31
Posted 13 February 2014 - 12:14 AM
So that you don't have to mess around with restoring or possible screw ups or anything since it's all controlled.
This is exactly what the api i threw together does >.>
you don't have to… as I've said already, you can make a term object and just redirect to it, its what I do in CCTicTacToe to easier support normal and advanced computers.
You're missing the point, that was a suggestion for a quick and easy way to do it. Also as far as i know, that wouldn't allow us to change os.pullEvent.
Edited on 12 February 2014 - 11:15 PM
theoriginalbit #32
Posted 13 February 2014 - 12:32 AM
You're missing the point, that was a suggestion for a quick and easy way to do it. Also as far as i know, that wouldn't allow us to change os.pullEvent.
the better one to change isn't even os.pullEvent, you're better adding the override to coroutine.yield
CometWolf #33
Posted 13 February 2014 - 02:29 AM
Oh herp derp, it's an suggestion so he would understand a simple way of doing it. pullEvent made more sense, since basically no one use coroutine yield instead of pullEvent, or even know they are the same. And there's no way you could override yield with redirect…
Edited on 13 February 2014 - 01:42 AM
theoriginalbit #34
Posted 13 February 2014 - 03:20 AM
and what about the people that use os.pullEventRaw or coroutine.yield in their programs, you're better to override the top-level function that way it effects all the lower ones too!
CometWolf #35
Posted 13 February 2014 - 04:08 AM
I used raw in my example. Which should be plenty sufficent, because like i said, barely anyone use yield in favor of pullEvent.
Symmetryc #36
Posted 13 February 2014 - 05:56 AM
So that you don't have to mess around with restoring or possible screw ups or anything since it's all controlled.
This is exactly what the api i threw together does >.>
>.< Didn't see that sorry. Although you should really localize your variables.
CometWolf #37
Posted 13 February 2014 - 06:05 AM
It's just one variable, the redirect table. I wasn't sure if indexing to a local table from a program that dosen't have acess to it would work or not.
nutcase84 #38
Posted 13 February 2014 - 08:44 AM
Yay! It works! Kinda anyway!

Now I need to get to work making it work better! Thanks guys!

EDIT: I tried to run Firewolf, and this error message pops up.

:(/>
Edited on 13 February 2014 - 07:51 AM
CometWolf #39
Posted 13 February 2014 - 09:22 AM
Ah yes…

local firewolfLocation = "/" .. shell.getRunningProgram()
Any program loaded with dofile/loadfile won't have acess to the shell table, and thus not it's functions either. Lemme get right on that, since i've been meaning to implement the argument possibility bit suggested i'll just do them both. Wasn't planning on putting much work into this, but it seems it could come in handy, so i might aswell.
Edited on 13 February 2014 - 08:23 AM
nutcase84 #40
Posted 13 February 2014 - 10:47 AM
Ah yes…

local firewolfLocation = "/" .. shell.getRunningProgram()
Any program loaded with dofile/loadfile won't have acess to the shell table, and thus not it's functions either. Lemme get right on that, since i've been meaning to implement the argument possibility bit suggested i'll just do them both. Wasn't planning on putting much work into this, but it seems it could come in handy, so i might aswell.

Thanks! You are going into the credits of my OS my friend!

EDIT: 700th post? Yay!
Edited on 13 February 2014 - 10:12 AM
CometWolf #41
Posted 13 February 2014 - 02:51 PM
Aaaand done, for the most part
http://pastebin.com/FH3eB0t8

There's been a small change in how you set it up, to allow acess to shell functions, aswell as some new features, so now you have to do it like this

local redir = dofile"/redir" -- this will return the redirect function
redir(x1,y1,x2,y2,(filePath or function or table),arguments)
--x1 is where the left of the screen should be
--y1 is where the top of the screen should be
--x2 is where the right of the screen should be
--y2 is where the bottom of the screen should be
--filePath should be self-explainatory
--as should arguments

To set this up for your menu, we'd do the following

local redir = dofile"/redir"
parallel.waitForAny(
  function()
    redir(1,2,term.getSize(),filePath)
  end,
  function()
    --menu code here
  end
)

The error handling is quite derpy right now, but i'll have a look into it later. Most of the other stuff works like it should, gimme a heads up if you find any bugs.
Symmetryc #42
Posted 13 February 2014 - 03:25 PM
It's just one variable, the redirect table. I wasn't sure if indexing to a local table from a program that dosen't have acess to it would work or not.
Yes, it would still work. i.e.

-- File 1
local t = {"hi"}
return t
-- File 2
local file_1 = dofile("file_1")
print(file_1[1]) --> "hi"
CometWolf #43
Posted 13 February 2014 - 03:42 PM
I know using return works. When i say indexing i mean metatable __index.
Edited on 13 February 2014 - 02:43 PM
nutcase84 #44
Posted 13 February 2014 - 06:28 PM


Tried to run my menu and firewolf at the same time. :(/>

Spoiler

local redir = dofile"/redir" -- this will return the redirect function
termX, termY = term.getSize()
function program()
  redir(1, 2, termX, termY, "firewolf", "test")
end
function main()
--NutOS 1.0.0 DEVELOPMENT VERSION
--Made by nutcase84
--Do not distribute modified code without permission.
--ToDo
--Finish Override
--Implement Programs
--Make Settings Thing
--Menu Over Programs
--API?
--Multitasking?
--Variables
menuColor = colors.blue
menuXLength = 10
--[[Overrides
oldGetCursorPos = term.getCursorPos
oldSetCursorPos = term.setCursorPos
oldGetSize = term.getSize
oldPaintLine = paintutils.drawLine
oldPaintPixel = paintutils.drawPixel
term.getCursorPos = function()
  local x, y = oldGetCursorPos()
  return x, y + 1
end
term.setCursorPos = function(x, y)
  oldSetCursorPos(x, y + 1)
end]]
while true do
  term.setTextColor(colors.white)
  term.clear()
  paintutils.drawLine(1, 1, term.getSize(), 1, menuColor)
  term.setCursorPos(1,1)
  print("[Menu]  [Programs]")
  local event, button, x, y = os.pullEvent("mouse_click")
  if x >= 1 and x <= 7 and y == 1 then
    term.setBackgroundColor(colors.gray)
    term.setCursorPos(1,1)
    print("[Menu]")
    term.setTextColor(colors.black)
    print(" About    ")
    print(" Settings ")
    print(" Reboot   ")
    print(" Shutdown ")
    local event, button, x, y = os.pullEvent("mouse_click")
    if x >= 1 and x <= menuXLength then
	  if y == 2 then
	    shell.run("hello")
	  elseif y == 4 then
	    os.reboot()
	  elseif y == 5 then
	    os.shutdown()
	  end
    end
  end
end
end
parallel.waitForAny(program, main)
nutcase84 #45
Posted 15 February 2014 - 10:07 AM
Still can't get it working.
D3matt #46
Posted 15 February 2014 - 01:24 PM
Wow. This ended up being way more complicated and over my head than I thought.
CometWolf #47
Posted 15 February 2014 - 10:10 PM
What i've done is pretty much what you've suggested Matt :P/>

Anyways, after derping around with my own software for testing for about 5 hours, i realized that it has a custom built in paintutils. As for firewolf, idk, something about the way it overrides functions and it's anti-virus crap is throwing my api off. No idea how to deal with that at this point tbh.
nutcase84 #48
Posted 16 February 2014 - 02:32 PM
Awwww. :(/>/>

So I will have to make programs work for my OS? No craft OS support?
Lyqyd #49
Posted 18 February 2014 - 12:23 PM
Nobody is saying that. What you're trying to do is possible, just difficult. Remember, the amount of effort you put in usually sets the maximum effort that we are willing to expend. Drill down into the problematic interactions that are causing the issue and show us what you're doing to try to troubleshoot it yourself. It is much easier to help someone who is trying to work through the problem, and people are more willing to help when they only need to help, not do every step for you.
CometWolf #50
Posted 18 February 2014 - 01:34 PM
The api i made will work on most normal programs, just not FireWolf, or my own Turtle Architect ironically enough…
nutcase84 #51
Posted 18 February 2014 - 05:03 PM
I've found paint gives an error.
CometWolf #52
Posted 18 February 2014 - 05:10 PM
I suggest you read Lyqyd's response again, giving me the error would be helpful…