· 10 years ago · Apr 16, 2016, 07:21 AM
1local user=""
2local locked=false
3-- functions for making read only values
4
5function version()
6 return "1.21"
7end
8
9function sprint(text)
10 textutils.slowPrint(text)
11end
12
13function waitForKey()
14 while true do
15 event, param = os.pullEvent()
16 if event == "key" then
17 break
18 end
19 end
20 return param
21end
22
23function setUser(sUser)
24 if not locked then user=sUser end
25 locked=true
26end
27
28function getUser()
29 return user
30end
31
32function reading()
33 sleep(0.5)
34 write "."
35end
36
37function showLogo()
38 term.clear()
39 term.setCursorPos(1,1)
40 print(" " .. os.version() .. " with Redworks "..redworks.version().." Terminal ID# " .. os.getComputerID())
41 print(" _ \\ | | ")
42 print(" / -_) _' | \\ \\ \\ / _ \\ _| | / (_-< ")
43 print(" _|_\\ \\___| \\__,_| \\_/\\_/ \\___/ _| _\\_\\ ___/ ")
44 print(" Development Team at http://redworksos.com")
45end
46
47function showLogo2()
48 term.clear()
49 print"@@@@@@@ @@@@@@@@ @@@@@@@"
50 print"@@! @@@ @@! @@! @@@"
51 print"@!@!!@! @!!!:! @!@ !@!"
52 print"!!: :!! !!: !!: !!!"
53 print":: : : : :: :: :: :::"
54 print"@@@ @@@ @@@ @@@@@@ @@@@@@@ @@@ @@@ @@@@@@"
55 print"@@! @@! @@! @@! @@@ @@! @@@ @@! !@@ !@@"
56 print"@!! !!@ @!@ @!@ !@! @!@!!@! @!@@!@! !@@!!"
57 print" !: !!: !! !!: !!! !!: :!! !!: :!! !:!"
58 print" ::.: ::: : :. : : : : : ::: ::.: : "
59end
60
61function doLogin() --returns true if login succeeds, false if it fails
62 local sPasswdPath = "ACCOUNTS.F"
63 --check we have a login path, if not, what we enter will create the account instead of log in
64 if fs.exists( sPasswdPath ) then--Password exists so this is not the first run
65 local loginCount=0
66 while loginCount < 3 do
67 local tPasswd={}
68 local file = fs.open(sPasswdPath,"r")
69 local sLine = file:readLine()
70 while sLine do
71 for k, v in string.gmatch(sLine, "(%w+)%s(%w+)") do
72 tPasswd[k]=v
73 end
74 sLine = file:readLine()
75 end
76 file:close()
77 numItems = 0
78 for k,v in pairs(tPasswd) do
79 numItems = numItems + 1
80 end
81
82 if (numItems==0) then
83 --no passwords, not first run, so exit with out login.
84 print(" ")
85 print("To secure this terminal use:\n\nadduser username password")
86 sleep(3)
87 return "",true
88 end
89 local ux,uy,px,py=8,8,8,10
90 local size,len = 2,10
91 rawWriteLoc(ux,uy,"Username:")
92 rawWriteLoc(px,py,"Password:")
93 textBox(ux+10,uy-1,len,size,false,false,"",true)
94 textBox(px+10,py-1,len,size,false,true,"",true)
95 local enterPressed = false
96 local username,password="",""
97 while not enterPressed do
98 username, enterPressed=textBox(ux+10,uy-1,len,size,true,false,username,true)
99 password, enterPressed=textBox(px+10,py-1,len,size,true,true,"",true)
100 end
101 if (tPasswd[username]==password) then --Login ok
102 return username,true
103 else --invalid login
104 loginCount=loginCount+1
105 rawWriteLoc(ux+10,7,"Invalid login")
106 end
107 end
108 return "",false
109 else--This is the first run, ask if they want to secure this box.
110 local iSelected, sText = selectWindow(nil,nil,"Lock Terminal",{"Yes","No"})
111 clearArea(16,6,17,7)
112 local userFocus=true
113 if (sText=="Yes") then
114 local passwordMatch=false
115 local username,password,password2="",""
116 while not passwordMatch do
117 local ux,uy=12,8
118 local px,py=ux,10
119 local size,len = 2,10
120 rawWriteLoc(ux,uy,"Username:")
121 rawWriteLoc(px,py,"Password:")
122 rawWriteLoc(px,py+2,"Re-enter:")
123 textBox(ux+10,uy-1,len,size,false,false,"xlilcasper",true)
124 textBox(px+10,py-1,len,size,false,true,"",true)
125 textBox(px+10,py+1,len,size,false,true,"",true)
126 local enterPressed = false
127
128 while not enterPressed do
129 username, enterPressed=textBox(ux+10,uy-1,len,size,userFocus,false,username,true)
130 password, enterPressed=textBox(px+10,py-1,len,size,true,true,"",true)
131 password2, enterPressed=textBox(px+10,py+1,len,size,true,true,"",true)
132 end
133 if (password == password2) then
134 passwordMatch = true
135 else
136 userFocus=false
137 rawWriteLoc(ux+1,7,"Passwords do not match")
138 end
139 end
140 --Our passwords match, store them for later.
141 tPasswd={}
142 tPasswd[username]=password
143
144 local file = io.open(sPasswdPath,"w")
145 for user,pass in pairs(tPasswd) do
146 file:write(user .. " " .. pass .."\n")
147 end
148 file:close()
149 return username,true
150 else --Do not secure
151 local file = io.open(sPasswdPath,"w")
152 file:close()
153 return "",true
154 end
155 end
156end
157
158--Helper functions
159
160--XLC (XLilCaspers) Windows libary included with permissions. Access with redworks.showWindow, redworks.textBox, redworks.selectWindow...
161function rawWriteLoc(x,y,sText)
162 term.setCursorPos(x,y)
163 term.write(sText)
164end
165
166function textBox(x,y,len,size,focus,hideChar,default,disableTerm)
167 local h=2
168 local w=len+3
169 local char=""
170 local line=""
171 if size==1 then
172 y=y
173 w=len
174 for tx=0,w do
175 rawWriteLoc(x+tx,y,"_")
176 end
177 elseif size==2 then
178 for tx=0,w do
179 rawWriteLoc(x+tx,y+2,"-")
180 end
181 else
182 for ty=0,h do
183 for tx=0,w do
184 char=" "
185 if (ty==0) or (ty==h) then --horizonal line
186 if (tx==0 or tx==w) then
187 char="+"
188 else
189 char="-"
190 end
191 elseif (ty==1) then
192 if (tx==0 or tx==w) then
193 char="|"
194 end
195 else--normal line
196 if (tx==0 or tx==w) then
197 char="|"
198 end
199 end
200 line=line..char
201 end
202 rawWriteLoc(x,y+ty,line)
203 line=""
204 end
205 end
206
207 if (focus) then
208 if size==2 then
209 y=y+1
210 len=len+3
211 elseif size==3 then
212 x=x+2
213 y=y+1
214 end
215 term.setCursorPos(x,y)
216 term.setCursorBlink(true)
217 sText=default or ""
218 rawWriteLoc(x,y,sText)
219 bExit = false
220 local dispText=""
221 local clearChar=" "
222 if size==1 then clearChar="_" end
223 local falt, sEvent, param = nil,nil,nil
224 while not bExit do
225 if disableTerm then
226 falt, sEvent, param = pcall(os.pullEvent)
227 else
228 sEvent, param = os.pullEvent()
229 falt=false
230 end
231
232 if sEvent == "key" then
233 if param == 28 then
234 return sText,true
235 elseif param==15 then
236 return sText,false
237 elseif param == 14 then
238 sText = string.sub(sText,1,string.len(sText)-1)
239 end
240 end
241
242 if sEvent == "char" then
243 sText = sText .. param
244 end
245
246 local dispChars=string.len(sText)
247 if dispChars > len then dispChars=len end
248 if not hideChar then
249 dispText = string.sub(sText,-len)
250 else
251 dispText=""
252 for n=1,dispChars do
253 dispText=dispText.."*"
254 end
255 dispText = string.sub(dispText,-len)
256 end
257 dispChars=string.len(dispText)
258 for n=dispChars,len do
259 dispText=dispText..clearChar
260 end
261 rawWriteLoc(x,y,dispText)
262 term.setCursorPos(x+dispChars,y)
263 end
264 else
265 return sText,true
266 end
267end
268
269function tCopy (tOrig, tTwin)
270if not tTwin then tTwin = { } end
271local tStack = {{tOrig, tTwin}}
272local function copy (tTable, tTarget)
273if not getmetatable(tTarget) then setmetatable(tTarget, getmetatable(tTable)) end
274for k, v in pairs(tTable) do
275if type(v)~='table' then
276tTarget[k] = v
277else
278tTarget[k] = { }
279table.insert(tStack, {tTable[k], tTarget[k]})
280end
281end
282end
283while #tStack>0 do
284copy(tStack[1][1], tStack[1][2])
285table.remove(tStack, 1)
286end
287return tTwin
288end
289
290function showWindow(x,y,w,h,title,text)
291 local sTitle = title or ""
292 local sText = text or ""
293 width, height = term.getSize()
294 sTitle = string.sub(sTitle,1,w-2)
295 iTitleStart = ((w/2)-1)-((#sTitle-1)/2)
296 if (not x) then
297 x=(width-w)/2
298 end
299 if (not y) then
300 y=(height-h)/2
301 end
302 if (w > width) then w = width end
303 if (h > height) then h = height end
304 local line=""
305 local char=""
306 local curChar=1
307 local waitForLine=1
308 if (sTitle ~= "") then waitForLine = 2 end
309 for ty=0,h do
310 for tx=0,w do
311 char=" "
312 if (ty==0) or ((ty==2) and (sTitle ~= "")) or (ty==h) then --horizonal line
313 if (tx==0 or tx==w) then
314 char="+"
315 else
316 char="-"
317 end
318 elseif (ty==1) then
319 if (tx==0 or tx==w) then
320 char="|"
321 else
322 --if (tx-iTitleStart < #sTitle+1) and (tx > iTitleStart) then
323 -- char = string.sub(sTitle,tx-iTitleStart,tx-iTitleStart)
324 --end
325 end
326 else--normal line
327 if (tx==0 or tx==w) then
328 char="|"
329 end
330 end
331 line=line..char
332 end
333 rawWriteLoc(x,y+ty,line)
334 line=""
335 end
336 if (sTitle ~= "") then
337 rawWriteLoc(x+iTitleStart+1,y+1,sTitle)
338 end
339 if (sText ~= "") then
340 term.setCursorPos(x+1,y+3)
341 local wrapedText = getWrapedText(x+1,y+2,x+w-2,y+h-1,sText)
342 local offset = 0
343 if (sTitle ~= "") then offset=2 end
344 for ty=1,#wrapedText do
345 rawWriteLoc(x+1,ty+y+offset,wrapedText[ty])
346 if (ty>h-offset-2) then break end
347 end
348 end
349end
350
351function getWrapedText(sx,sy,w,h, sText )
352 local x,y = sx,sy
353 local line = ""
354 local wraped = { }
355 local function newLine()
356 table.insert(wraped,line)
357 line=""
358 x=sx
359 end
360
361 local function storeText(text)
362 line=line..text
363 return #text
364 end
365
366 -- Print the line with proper word wrapping
367 while string.len(sText) > 0 do
368 local whitespace = string.match( sText, "^[ \t]+" )
369 if whitespace then
370 -- Print whitespace
371 x = x + storeText(whitespace)
372 sText = string.sub( sText, string.len(whitespace) + 1 )
373 end
374
375 local newline = string.match( sText, "^\n" )
376 if newline then
377 -- Print newlines
378 newLine()
379 sText = string.sub( sText, 2 )
380 end
381
382 local text = string.match( sText, "^[^ \t\n]+" )
383 if text then
384 sText = string.sub( sText, string.len(text) + 1 )
385 if string.len(text) > w then
386 -- Print a multiline word
387 while string.len( text ) > 0 do
388 if x > w then
389 newLine()
390 end
391 x = x + storeText( text )
392 text = string.sub( text, (w-x) + 2 )
393 end
394 else
395 -- Print a word normally
396 if x + string.len(text) > w then
397 newLine()
398 end
399 x = x + storeText( text )
400 end
401 end
402 end
403 newLine()
404 return wraped
405end
406
407function selectWindow(x,y,title,tOptions,iSelected)
408 local w=#title
409 local h=1
410 local selected=iSelected or 1
411 local tOptionsOrg=tCopy(tOptions)
412 local width, height = term.getSize()
413 for n=1,#tOptions do
414 tOptions[n]=" "..tOptionsOrg[n].." "
415 if (string.len(tOptions[n])>w) then w=string.len(tOptions[n]) end
416 end
417 w=w+2
418 local sTitle = title or ""
419 if (sTitle ~= "") then h = h + 2 end
420 h = h + #tOptions
421 tOptions[selected]="*"..tOptionsOrg[selected].."*"
422 if (not x) then
423 x=(width-w)/2
424 end
425 if (not y) then
426 y=(height-h)/2
427 end
428 showWindow(x,y,w,h,sTitle,table.concat(tOptions,"\n"))
429
430 --loop and capture arrow keys for selecting output.
431 bExit = false
432 while not bExit do
433 event, param = os.pullEvent()
434 if event == "key" then
435 if param == 197 then --Exit on pause/break
436 bExit = true
437 elseif param == 208 then
438 tOptions[selected]=" "..tOptionsOrg[selected].." " --Clear selection
439 selected=selected+1
440 if (selected>#tOptions) then selected=1 end
441 tOptions[selected]="*"..tOptionsOrg[selected].."*"
442 showWindow(x,y,w,h,sTitle,table.concat(tOptions,"\n"))
443 elseif param == 200 then
444 tOptions[selected]=" "..tOptionsOrg[selected].." " --Clear selection
445 selected=selected-1
446 if (selected<1) then selected=#tOptions end
447 tOptions[selected]="*"..tOptionsOrg[selected].."*"
448 showWindow(x,y,w,h,sTitle,table.concat(tOptions,"\n"))
449 elseif param == 28 then
450 return selected,tOptionsOrg[selected]
451 end
452 end
453
454 end
455end
456
457function clearArea(x,y,w,h,char)
458 local sChar = char or " "
459 for yy=0,h do
460 for xx=0,w do
461 rawWriteLoc(x+xx,y+yy,sChar)
462 end
463 end
464end
465
466--End of windows libary
467
468function class(base, init)
469 local c = {} -- a new class instance
470 if not init and type(base) == 'function' then
471 init = base
472 base = nil
473 elseif type(base) == 'table' then
474 -- our new class is a shallow copy of the base class!
475 for i,v in pairs(base) do
476 c[i] = v
477 end
478 c._base = base
479 end
480 -- the class will be the metatable for all its objects,
481 -- and they will look up their methods in it.
482 c.__index = c
483
484 -- expose a constructor which can be called by <classname>(<args>)
485 local mt = {}
486 mt.__call = function(class_tbl, ...)
487 local obj = {}
488 setmetatable(obj,c)
489 if init then
490 init(obj,...)
491 else
492 -- make sure that any stuff from the base class is initialized!
493 if base and base.init then
494 base.init(obj, ...)
495 end
496 end
497 return obj
498 end
499 c.init = init
500 c.is_a = function(self, klass)
501 local m = getmetatable(self)
502 while m do
503 if m == klass then return true end
504 m = m._base
505 end
506 return false
507 end
508 setmetatable(c, mt)
509 return c
510end
511-----------EXTRA----------
512
513--[[ (( Rin API ))
514
515Usage: Just use the following information to utilize the available commands
516
517:::Functions:::
518
519 ENTITY
520
521[entity.new( Name, X, Y, Text, Visibility, Physical )] returns Integer ID
522Creates a new entity
523Name;String -- Entity Name -- Currently only usable via entity.getvar() and entity.setvar()
524X;Integer -- Entity X Position
525Y;Integer -- Entity Y Position
526Text;String -- The text on-screen that represents the entity
527Visibility;Bool -- Whether or not the entity is drawn
528Physical;Bool -- Whether or not the entity is a physical entity -- Currently only changeable via entity.getvar() and entity.setvar()
529Note: Physical entities are unable to move to the position of other physical entities, but can be created at the same position, watch out.
530
531[entity.setpos(ID, x, y, r)] -- ID is the returned value of entity.new()
532Sets the position of entity ID to position x, y
533Or, if r is set to true, sets position relative to current position
534entity.setpos(ID, 3, 0, r) would add 3 to ID's x position, and 0 to ID's y position
535
536[entity.setchar(ID, Text)]
537Changes the character, or group of characters, that represent the entity on-screen
538
539[entity.setvis(ID, Bool)]
540Sets whether the entity is visible on-screen
541
542[entity.setabs(ID, Bool)]
543Sets whether the entity's position is absolute( x:1 y:1 remains the same regardless of screen position. Useful for GUI )
544
545[entity.addvar(ID, Var, Value)]
546Creates a new variable named Var of value Value to the entity ID
547Var:String -- Variable Name
548Value:Any -- Variable Value
549
550[entity.setvar(ID, Var, Value)]
551Sets the value of the variable Var to the value Value on the entity ID
552
553[entity.getvar(ID, Var)]
554Returns the value of the variable Var on the entity ID
555
556[entity.getposx(ID)]
557Returns the X position of the entity ID
558
559[entity.getposy(ID)]
560returns the Y position of the entity ID
561
562[entity.remvar(ID, Var)]
563Removes the variable Var from the entity ID
564
565 GET
566
567[get.locphys(x, y)]
568Checks if there is a physical entity at position x,y
569returns physical entity's ID, otherwise returns false
570
571 EXECUTABLE
572
573[exec.quit()]
574Ends the current execution
575
576[exec.draw()]
577Draws the screen -- Runs automatically if a custom exec.update isn't set
578
579[exec.update()]
580User defined;
581Runs every step, exec.update() overrides exec.defupdate(), which is the default update function
582If you update yourself, you need to run exec.draw() or create your own drawing procedure
583
584[exec.start()]
585Starts the execution, nothing will be executed beyond this point until exec.stop() is called!
586
587[exec.beginstep()] [exec.step()] [exec.endstep()]
588User defined;
589These are run every step, and in the order seen above.
590This is a good place to put any sort of logic or conditional checks.
591
592[exec.key(k)]
593User defined;
594This is run when a key is pressed, and the argument k contains the code for the key.
595Find the Key Codes here; http://www.minecraftwiki.net/wiki/Key_Codes
596
597[exec.quit]
598Ends the execution, returning to the command line.
599
600:::Variables:::
601
602window.w -- Window Width
603window.h -- Window Height
604window.midw -- Center of the Window Width
605window.midh -- Center of the Window Height
606
607screen.x -- Screen x offset
608screen.y -- Screen y offset
609
610:::Entity Variables:::
611These are the default Entity variables, found with entity.getvar()
612'Name' -- String -- Entity's name, which you set when making a new entity
613'X Position' -- Integer -- Entity's X Position
614'Y Position' -- Integer -- Entity's Y Position
615'Character' -- String -- The string that represents the entity on-screen
616'Visibility' -- Bool -- Defines whether an entity is drawn on-screen
617'Physical' -- Bool -- Defines whether an entity is physical or not
618'Absolute' -- Bool -- Defines whether an entity's location is absolute;
619Position (1,1) is the top left corner of the screen at all times if this is true for the object
620'Variable Count' -- Integer -- Defines how many variables the entity has :::DO NOT CHANGE:::
621
622]]--
623
624window = {}
625window.w,window.h = term.getSize()
626window.midw = window.w/2
627window.midh = window.h/2
628
629screen = {}
630
631screen.x = 0
632screen.y = 0
633
634--[[ ENTITY VARIABLES AND FUNCTIONS ]]--
635entity = {}
636entitynum = 1
637
638function entity.new(a, x, y, t, c, d) -- Adds a new Entity to the execution
639 id = entitynum
640 entity[id] = {}
641
642 entity[id][1] = {}
643 entity[id][1][1] = 'Name'
644 entity[id][1][2] = a
645
646 entity[id][2] = {}
647 entity[id][2][1] = 'X Position'
648 entity[id][2][2] = x -- XPos
649
650 entity[id][3] = {}
651 entity[id][3][1] = 'Y Position'
652 entity[id][3][2] = y -- YPos
653
654 entity[id][4] = {}
655 entity[id][4][1] = 'Character'
656 entity[id][4][2] = t -- Text Representing the Entity
657
658 entity[id][5] = {}
659 entity[id][5][1] = 'Visibility'
660 entity[id][5][2] = c -- Depicts whether the object is visible or not
661
662 entity[id][6] = {}
663 entity[id][6][1] = 'Physical'
664 entity[id][6][2] = d -- If an object is Physical, it cannot move onto the same spot as a physical object
665 -- WARNING: Objects can still be set to physical using entity.setvar(), or by creating an object at the same spot as another object!
666
667 entity[id][7] = {}
668 entity[id][7][1] = 'Absolute'
669 entity[id][7][2] = false -- Sets whether an object has an absolute position(1 = 1 on screen regardless of screen offset) or not
670
671 entity[id][8] = {}
672 entity[id][8][1] = 'Variable Count'
673 entity[id][8][2] = 7 -- Counts how many variables there are
674
675 entitynum = entitynum+1
676 return id
677end
678
679function entity.setchar(a, b)
680 entity[a][4][2] = b
681end
682
683function entity.setphys(a, b)
684 entity[a][5][2] = b
685end
686
687function entity.setabs(a, b)
688 entity[a][7][2] = b
689end
690
691function entity.addvar(a, b, c) -- Adds a new variable to an Entity
692 varcount = entity[a][8][2] + 1
693 entity[a][varcount] = {}
694 entity[a][varcount][1] = b
695 entity[a][varcount][2] = c
696 entity[a][8][2] = varcount
697end
698
699function entity.remvar(a, b)
700 for i in ipairs(entity[a]) do
701 if entity[a][i][1] == b then
702 table.remove(entity[a], i)
703 entity[a][8][2] = entity[a][8][2] - 1
704 break
705 end
706 end
707end
708
709function entity.setvar(a, b, c)
710 for i in ipairs(entity[a]) do
711 if entity[a][i][1] == b then
712 entity[a][i][2] = c
713 break
714 end
715 end
716end
717
718function entity.getvar(a, b)
719 answer = 0
720 for i in ipairs(entity[a]) do
721 if entity[a][i][1] == b then
722 answer = entity[a][i][2]
723 break
724 end
725 end
726 return answer
727end
728
729
730function entity.rem(a) -- Removes Entity from the execution
731 --Don't know if this is possible or not. Might just zero out the entity. Reason? table.remove() would shift all the higher index entities down, changing their ID's
732end
733
734function entity.getposx(a) return entity[a][2][2] end
735function entity.getposy(a) return entity[a][3][2] end
736
737function entity.setpos(a, x, y, r) -- Sets the Entity's Position
738 if r ~= nil then
739 local resx = entity[a][2][2] + x
740 local resy = entity[a][3][2] + y
741 if get.locphys(resx,resy) == false then
742 entity[a][2][2] = resx
743 entity[a][3][2] = resy
744 end
745 else
746 if get.locphys(x,y) == false then
747 entity[a][2][2] = x
748 entity[a][3][2] = y
749 end
750 end
751end
752
753--[[ GET FUNCTIONS ]]--
754get = {}
755
756function get.locphys(x, y)
757 answer = false
758 for i,v in ipairs(entity) do
759 if entity[i][6][2] then
760 if entity[i][2][2] == x then
761 if entity[i][3][2] == y then
762 answer = i
763 break
764 end
765 end
766 end
767 end
768 return answer
769end
770
771--[[ SCREEN FUNCTIONS ]]--
772function printCenter( y, s ) -- Prints centered text on the screen
773 local x = math.floor((w - string.len(s)) / 2)
774 term.setCursorPos(x, y)
775 term.clearLine()
776 term.write( s )
777end
778
779--[[ RUNTIME ]]--
780--Variables
781exec = {}
782exec.active = false
783--Functions
784function exec.quit() -- Ends the current execution
785 term.clear()
786 exec.active = false
787 term.setCursorPos(window.midw-7,window.h)
788 term.write('Thanks for using the RinAPI')
789 sleep(2)
790 term.clear()
791 term.setCursorPos(1,1)
792end
793
794function exec.draw() -- Draws the screen
795 term.clear()
796 for i,v in ipairs(entity) do
797 if entity[i][5][2] == true and entity[i][7][2] == false then
798 local x = entity[i][2][2]
799 local y = entity[i][3][2]
800 term.setCursorPos(x - screen.x, y - screen.y)
801 term.write(entity[i][4][2])
802 end
803 end
804 for i,v in ipairs(entity) do
805 if entity[i][5][2] == true and entity[i][7][2] == true then
806 local x = entity[i][2][2]
807 local y = entity[i][3][2]
808 term.setCursorPos(x, y)
809 term.write(entity[i][4][2])
810 end
811 end
812end
813
814function exec.defupdate() -- Default Update, can be overridden for custom draw handling
815 term.clear()
816 exec.draw()
817end
818
819function exec.start() -- Starts the current execution
820 exec.active = true
821 os.startTimer(1/30)
822 while exec.active do
823 local t,k = os.pullEvent()
824 if t == 'timer' then
825 if exec.beginstep ~= nil then exec.beginstep() end
826 if exec.step ~= nil then exec.step() end
827 if exec.endstep ~= nil then exec.endstep() end
828 if exec.update ~= nil then exec.update()
829 else exec.defupdate() end
830 os.startTimer(1/30)
831 elseif t == 'key' then
832 if k == 14 then
833 exec.quit()
834 else
835 if exec.key ~= nil then exec.key(k) end
836 end
837 end
838 end
839end