View difference between Paste ID: JK334Xmq and nh9XfpLX
SHOW: | | - or go back to the newest paste.
1
if warpdriveCommons then os.unloadAPI("warpdriveCommons") end
2
if not os.loadAPI("warpdrive/warpdriveCommons") then error("missing warpdriveCommons") end
3
local w = warpdriveCommons.w
4
5
local data
6
7
----------- Force field support
8
9
local ffield_projectorAddresses = {}
10
local ffield_projectors = {}
11
local ffield_projector_indexSelected = 1
12
local ffield_projector_indexFirstLine = 1
13
local ffield_projector_lines = 10
14
15
local ffield_relayAddresses = {}
16
local ffield_relays = {}
17
local ffield_relay_indexSelected = 1
18
local ffield_relay_indexFirstLine = 1
19
local ffield_relay_lines = 10
20
21
function ffield_boot(isDetailed)
22
  if #ffield_projectorAddresses == 0 and #ffield_relayAddresses == 0 then
23
    return
24
  end
25
  
26
  if isDetailed == nil then
27
    isDetailed = true
28
  end
29
  
30
  if isDetailed then
31
    w.write("Booting Force field projectors and relays")
32
    
33
    w.writeLn("...")
34
    w.sleep(0.1)
35
  end
36
  
37
  -- getting projectors parameters
38
  ffield_projectors = {}
39
  for key, address in pairs(ffield_projectorAddresses) do
40
    local device = w.device_get(address)
41
    local x, y, z = device.getLocalPosition()
42
    local name = device.name()
43
    if name == "" then name = "-not defined-" end
44
    local beamFrequency = device.beamFrequency()
45
    -- local isEnabled = device.enable()
46
    local status, isEnabled, isConnected, isPowered, shape, energy = device.state()
47
    -- @TODO add tier reporting
48
    local projector = {
49
      address = address,
50
      device = device,
51
      position = { x = x, y = y, z = z },
52
      name = name,
53
      beamFrequency = beamFrequency,
54
      shape = shape,
55
      isEnabled = isEnabled }
56
    if isDetailed then
57
      w.writeLn(ffield_projector_getDescription(projector))
58
    end
59
    table.insert(ffield_projectors, projector)
60
  end
61
  
62
  -- getting relays parameters
63
  ffield_relays = {}
64
  for key, address in pairs(ffield_relayAddresses) do
65
    local device = w.device_get(address)
66
    local x, y, z = device.getLocalPosition()
67
    local name = device.name()
68
    if name == "" then name = "-not defined-" end
69
    local beamFrequency = device.beamFrequency()
70
    local isEnabled = device.enable()
71
    local relay = {
72
      address = address,
73
      device = device,
74
      position = { x = x, y = y, z = z },
75
      name = name,
76
      beamFrequency = beamFrequency,
77
      isEnabled = isEnabled }
78
    if isDetailed then
79
      w.writeLn(ffield_relay_getDescription(relay))
80
    end
81
    table.insert(ffield_relays, relay)
82
  end
83
end
84
85
function ffield_save()
86
  -- nothing
87
end
88
89
function ffield_read(parData)
90
  data = parData
91
end
92
93
function ffield_projector_getDescription(projector)
94
  if projector == nil or projector.device == nil then
95
    return "~invalid~"
96
  end
97
  local description = "#" .. w.format_integer(projector.beamFrequency, 5)
98
          .. " @ (" .. w.format_integer(projector.position.x, 7) .. " " .. w.format_integer(projector.position.y, 3) .. " " .. w.format_integer(projector.position.z, 7) .. ") "
99
          .. w.format_string(projector.shape, 10)
100
          .. " "
101
  if projector.isEnabled then
102
    description = description .. "Enabled"
103
  else
104
    description = description .. "Disabled"
105
  end
106
  return description
107
end
108
109
function ffield_projector_getIndexes()
110
  if ffield_projectors ~= nil then
111
    if ffield_projector_indexSelected > #ffield_projectors then
112
      ffield_projector_indexSelected = 1
113
    elseif ffield_projector_indexSelected < 1 then
114
      ffield_projector_indexSelected = #ffield_projectors
115
    end
116
    if ffield_projector_indexFirstLine > ffield_projector_indexSelected then
117
      ffield_projector_indexFirstLine = ffield_projector_indexSelected
118
    elseif ffield_projector_indexFirstLine + ffield_projector_lines < ffield_projector_indexSelected then
119
      ffield_projector_indexFirstLine = ffield_projector_indexSelected - ffield_projector_lines
120
    end
121
    return ffield_projector_indexFirstLine, ffield_projector_indexSelected
122
  else
123
    return 1, 1
124
  end
125
end
126
127
function ffield_projector_get(index)
128
  local indexToUse = index
129
  local projector
130
  
131
  if ffield_projectors ~= nil then
132
    if indexToUse > #ffield_projectors then
133
      indexToUse = 1
134
    elseif indexToUse < 1 then
135
      indexToUse = #ffield_projectors
136
    end
137
    projector = ffield_projectors[indexToUse]
138
  end
139
  
140
  if projector == nil then
141
    ffield_boot(false)
142
    w.status_showWarning("Invalid projector index " .. index)
143
    projector = {
144
      address = "-",
145
      device = nil,
146
      position = { x = 0, y = 0, z = 0 },
147
      name = "-",
148
      beamFrequency = -1,
149
      shape = "NONE",
150
      isEnabled = false }
151
  end
152
  
153
  return projector
154
end
155
156
function ffield_projector_getSelected()
157
  return ffield_projector_get(ffield_projector_indexSelected)
158
end
159
160
function ffield_enable(projectorOrRelay, enable)
161
  if projectorOrRelay == nil or projectorOrRelay.device == nil then
162
    return
163
  end
164
  local enableToApply = enable
165
  if enableToApply == nil then
166
    enableToApply = not projectorOrRelay.device.enable()
167
  end
168
  projectorOrRelay.isEnabled = projectorOrRelay.device.enable(enableToApply)
169
  return projectorOrRelay.isEnabled
170
end
171
172
function ffield_projector_key(character, keycode)
173
  if character == 's' or character == 'S' then
174
    for key, projector in pairs(ffield_projectors) do
175
      ffield_enable(projector, true)
176
    end
177
    return true
178
  elseif character == 'p' or character == 'P' then
179
    for key, projector in pairs(ffield_projectors) do
180
      ffield_enable(projector, false)
181
    end
182
    return true
183
  elseif character == 'e' or character == 'E' then
184
    local projector = ffield_projector_getSelected()
185
    if projector ~= nil and projector.device ~= nil then
186
      ffield_enable(projector)
187
    end
188
    return true
189
  elseif character == 'c' or character == 'C' then -- C or keycode == 46
190
    ffield_projector_config()
191
    w.data_save()
192
    return true
193
  elseif keycode == 200 or keycode == 203 or character == '-' then -- Up or Left or -
194
    ffield_projector_indexSelected = ffield_projector_indexSelected - 1
195
    return true
196
  elseif keycode == 208 or keycode == 205 or character == '+' then -- Down or Right or +
197
    ffield_projector_indexSelected = ffield_projector_indexSelected + 1
198
    return true
199
  end
200
  return false
201
end
202
203
function ffield_projector_page()
204
  w.page_begin(w.data_getName() .. " - Force field projectors")
205
  
206
  -- w.setCursorPos(1, 2)
207
  if #ffield_projectors == 0 then
208
    w.setColorDisabled()
209
    w.writeCentered(2, "No force field projector defined, connect one and reboot!")
210
  else
211
    w.setColorNormal()
212
    local indexFirstLine, indexSelected = ffield_projector_getIndexes()
213
    w.writeCentered(2, "Force field projector " .. indexSelected .. " of " .. #ffield_projectors .. " is selected")
214
    local indexLastLine = math.min(indexFirstLine + ffield_projector_lines, #ffield_projectors)
215
    for indexCurrent = indexFirstLine, indexLastLine do
216
      if indexCurrent == indexSelected then
217
        w.setColorSelected()
218
        w.clearLine()
219
        w.write(">")
220
      else
221
        w.setColorNormal()
222
        w.write(" ")
223
      end
224
      local projector = ffield_projector_get(indexCurrent)
225
      local description = ffield_projector_getDescription(projector)
226
      w.write(description)
227
      w.writeLn("")
228
    end
229
  end
230
  
231
  w.setCursorPos(1, 14)
232
  w.setColorNormal()
233
  w.write("  -----------------------------------------------")
234
  
235
  w.setCursorPos(1, 15)
236
  w.setColorControl()
237
  w.writeFullLine(" Start/stoP all force field projectors (S/P)")
238
  w.writeFullLine(" Configure (C) or togglE (E) selected projector")
239
  w.writeFullLine(" select force field projector (Up, Down)")
240
end
241
242
function ffield_projector_config()
243
  local projector = ffield_projector_getSelected()
244
  if projector == nil then
245
    return
246
  end
247
  w.page_begin(w.data_getName() .. " - Projector configuration")
248
  
249
  w.setCursorPos(1, 2)
250
  w.setColorNormal()
251
  projector.position.x, projector.position.y, projector.position.z = projector.device.getLocalPosition()
252
  w.write("Projector @ " .. w.format_integer(projector.position.x, 7) .. " " .. w.format_integer(projector.position.y, 3) .. " " .. w.format_integer(projector.position.z, 7))
253
  
254
  -- name
255
  w.setCursorPos(1, 16)
256
  w.setColorHelp()
257
  w.writeFullLine(" Press enter to validate.")
258
  w.setCursorPos(1, 3)
259
  w.setColorNormal()
260
  w.writeLn("Name (" .. projector.name .. "):")
261
  local nameOriginal = projector.name
262
  projector.name = w.input_readText(projector.name)
263
  w.setCursorPos(1, 3)
264
  w.setColorNormal()
265
  w.clearLine()
266
  if nameOriginal ~= projector.name then
267
    w.setColorSuccess()
268
  else
269
    w.setColorNormal()
270
  end
271
  projector.name = projector.device.name(projector.name)
272
  w.writeLn("Name set to " .. projector.name)
273
  w.setColorNormal()
274
  w.clearLine()
275
  
276
  -- beam frequency
277
  projector.beamFrequency = projector.device.beamFrequency()
278
  w.setCursorPos(1, 16)
279
  w.setColorHelp()
280
  w.writeFullLine(" Enter a number between 0 and 65000.")
281
  local frequency
282
  repeat
283
    w.setCursorPos(1, 5)
284
    w.setColorNormal()
285
    w.clearLine()
286
    w.write("Beam frequency (" .. w.format_integer(projector.beamFrequency, 5) .. "): ")
287
    frequency = w.input_readInteger(projector.beamFrequency)
288
    if frequency ~= 0 and (frequency < 0 or frequency > 65000) then
289
      w.status_showWarning("This is not a valid beam frequency. Try again.")
290
    end
291
  until frequency > 0 and frequency <= 65000
292
  w.setCursorPos(1, 4)
293
  w.clearLine()
294
  if frequency ~= projector.beamFrequency then
295
    w.setColorSuccess()
296
  else
297
    w.setColorNormal()
298
  end
299
  projector.beamFrequency = projector.device.beamFrequency(frequency)
300
  w.write("Beam frequency set to " .. projector.beamFrequency)
301
  w.setColorNormal()
302
  w.setCursorPos(1, 5)
303
  w.clearLine()
304
  w.setCursorPos(1, 16)
305
  w.clearLine()
306
  
307
  -- translation
308
  ffield_config_xyz(5, "Translation", "%", "translation where 0 is centered", projector.device.translation, 100)
309
  
310
  -- rotation
311
  ffield_config_xyz(6, "Rotation", "", "rotation in deg where 0 is centered", projector.device.rotation, 1)
312
  
313
  -- scale
314
  ffield_config_xyz(7, "Min scale", "%", "min scale where -100 is full scale", projector.device.min, 100)
315
  ffield_config_xyz(8, "Max scale", "%", "max scale where 100 is full scale", projector.device.max, 100)
316
  
317
  w.sleep(0.5)
318
end
319
320
function ffield_config_xyz(yCursor, title, unit, help, method, factor)
321
  local xOriginal, yOriginal, zOriginal = method()
322
  local x = factor * xOriginal
323
  local y = factor * yOriginal
324
  local z = factor * zOriginal
325
  w.setCursorPos(1, yCursor + 1)
326
  w.setColorNormal()
327
  w.write(title .. " is currently set to " .. w.format_integer(x, 4) .. " "  .. unit .. " " .. w.format_integer(y, 4) .. " "  .. unit .. " " .. w.format_integer(z, 4) .. " "  .. unit)
328
  
329
  w.setCursorPos(1, 16)
330
  w.setColorHelp()
331
  w.writeFullLine(" Enter X " .. help)
332
  
333
  w.setCursorPos(1, yCursor + 3)
334
  w.setColorNormal()
335
  w.write(title .. " along X axis (" .. w.format_integer(x, 4) .. "): ")
336
  x = w.input_readInteger(x)
337
  
338
  w.setCursorPos(1, 16)
339
  w.setColorHelp()
340
  w.writeFullLine(" Enter Y " .. help)
341
  
342
  w.setCursorPos(1, yCursor + 4)
343
  w.setColorNormal()
344
  w.write(title .. " along Y axis (" .. w.format_integer(y, 4) .. "): ")
345
  y = w.input_readInteger(y)
346
  
347
  w.setCursorPos(1, 16)
348
  w.setColorHelp()
349
  w.writeFullLine(" Enter Z " .. help)
350
  
351
  w.setCursorPos(1, yCursor + 5)
352
  w.setColorNormal()
353
  w.write(title .. " along Z axis (" .. w.format_integer(z, 4) .. "): ")
354
  z = w.input_readInteger(z)
355
  
356
  w.setCursorPos(1, 16)
357
  w.clearLine()
358
  
359
  local xSet = x / factor
360
  local ySet = y / factor
361
  local zSet = z / factor
362
  local message
363
  x, y, z, message = method(xSet, ySet, zSet)
364
  x = factor * x
365
  y = factor * y
366
  z = factor * z
367
  w.setCursorPos(1, yCursor)
368
  if message ~= nil then
369
    w.setColorWarning()
370
    w.write(title .. " error: " .. message)
371
    w.status_showWarning(message)
372
  else
373
    if xOriginal ~= xSet or yOriginal ~= ySet or zOriginal ~= zSet then
374
      w.setColorSuccess()
375
    else
376
      w.setColorNormal()
377
    end
378
    w.write(title .. " set to " .. w.format_integer(x, 4) .. " "  .. unit .. " " .. w.format_integer(y, 4) .. " "  .. unit .. " " .. w.format_integer(z, 4) .. " "  .. unit)
379
  end
380
  w.setColorNormal()
381
  w.setCursorPos(1, yCursor + 1)
382
  w.clearLine()
383
  w.setCursorPos(1, yCursor + 3)
384
  w.clearLine()
385
  w.setCursorPos(1, yCursor + 4)
386
  w.clearLine()
387
  w.setCursorPos(1, yCursor + 5)
388
  w.clearLine()
389
end
390
391
function ffield_relay_getDescription(relay)
392
  if relay == nil or relay.device == nil then
393
    return "~invalid~"
394
  end
395
  local description = "#" .. w.format_integer(relay.beamFrequency, 5)
396
          .. " @ (" .. w.format_integer(relay.position.x, 7) .. " " .. w.format_integer(relay.position.y, 3) .. " " .. w.format_integer(relay.position.z, 7) .. ") "
397
  if relay.isEnabled then
398
    description = description .. "Enabled"
399
  else
400
    description = description .. "Disabled"
401
  end
402
  return description
403
end
404
405
function ffield_relay_getIndexes()
406
  if ffield_relays ~= nil then
407
    if ffield_relay_indexSelected > #ffield_relays then
408
      ffield_relay_indexSelected = 1
409
    elseif ffield_relay_indexSelected < 1 then
410
      ffield_relay_indexSelected = #ffield_relays
411
    end
412
    if ffield_relay_indexFirstLine > ffield_relay_indexSelected then
413
      ffield_relay_indexFirstLine = ffield_relay_indexSelected
414
    elseif ffield_relay_indexFirstLine + ffield_relay_lines < ffield_relay_indexSelected then
415
      ffield_relay_indexFirstLine = ffield_relay_indexSelected - ffield_relay_lines
416
    end
417
    return ffield_relay_indexFirstLine, ffield_relay_indexSelected
418
  else
419
    return 1, 1
420
  end
421
end
422
423
function ffield_relay_get(index)
424
  local indexToUse = index
425
  local relay
426
  
427
  if ffield_relays ~= nil then
428
    if indexToUse > #ffield_relays then
429
      indexToUse = 1
430
    elseif indexToUse < 1 then
431
      indexToUse = #ffield_relays
432
    end
433
    relay = ffield_relays[indexToUse]
434
  end
435
  
436
  if relay == nil then
437
    ffield_boot(false)
438
    w.status_showWarning("Invalid relay index " .. index)
439
    relay = {
440
      address = "-",
441
      device = nil,
442
      position = { x = 0, y = 0, z = 0 },
443
      name = "-",
444
      beamFrequency = -1,
445
      isEnabled = false }
446
  end
447
  
448
  return relay
449
end
450
451
function ffield_relay_getSelected()
452
  return ffield_relay_get(ffield_relay_indexSelected)
453
end
454
455
function ffield_relay_key(character, keycode)
456
  if character == 's' or character == 'S' then
457
    for key, relay in pairs(ffield_relays) do
458
      ffield_enable(relay, true)
459
    end
460
    return true
461
  elseif character == 'p' or character == 'P' then
462
    for key, relay in pairs(ffield_relays) do
463
      ffield_enable(relay, false)
464
    end
465
    return true
466
  elseif character == 'e' or character == 'E' then
467
    local relay = ffield_relay_getSelected()
468
    ffield_enable(relay)
469
    return true
470
  elseif character == 'c' or character == 'C' then -- C or keycode == 46
471
    ffield_relay_config()
472
    w.data_save()
473
    return true
474
  elseif keycode == 200 or keycode == 203 or character == '-' then -- Up or Left or -
475
    ffield_relay_indexSelected = ffield_relay_indexSelected - 1
476
    return true
477
  elseif keycode == 208 or keycode == 205 or character == '+' then -- Down or Right or +
478
    ffield_relay_indexSelected = ffield_relay_indexSelected + 1
479
    return true
480
  end
481
  return false
482
end
483
484
function ffield_relay_page()
485
  w.page_begin(w.data_getName() .. " - Force field relays")
486
  
487
  -- w.setCursorPos(1, 2)
488
  if #ffield_relays == 0 then
489
    w.setColorDisabled()
490
    w.writeCentered(2, "No force field relay defined, connect one and reboot!")
491
  else
492
    w.setColorNormal()
493
    local indexFirstLine, indexSelected = ffield_relay_getIndexes()
494
    w.writeCentered(2, "Force field relay " .. indexSelected .. " of " .. #ffield_relays .. " is selected")
495
    local indexLastLine = math.min(indexFirstLine + ffield_relay_lines, #ffield_relays)
496
    for indexCurrent = indexFirstLine, indexLastLine do
497
      if indexCurrent == indexSelected then
498
        w.setColorSelected()
499
        w.clearLine()
500
        w.write(">")
501
      else
502
        w.setColorNormal()
503
        w.write(" ")
504
      end
505
      local relay = ffield_relay_get(indexCurrent)
506
      local description = ffield_relay_getDescription(relay)
507
      w.write(description)
508
      w.writeLn("")
509
    end
510
  end
511
  
512
  w.setCursorPos(1, 14)
513
  w.setColorNormal()
514
  w.write("  -----------------------------------------------")
515
  
516
  w.setCursorPos(1, 15)
517
  w.setColorControl()
518
  w.writeFullLine(" Start/stoP all force field relays (S/P)")
519
  w.writeFullLine(" Configure (C) or togglE (E) selected relay")
520
  w.writeFullLine(" select force field relay (Up, Down)")
521
end
522
523
function ffield_relay_config()
524
  local relay = ffield_relay_getSelected()
525
  if relay == nil then
526
    return
527
  end
528
  w.page_begin(w.data_getName() .. " - Relay configuration")
529
  
530
  w.setCursorPos(1, 2)
531
  w.setColorNormal()
532
  relay.position.x, relay.position.y, relay.position.z = relay.device.getLocalPosition()
533
  w.write("Relay @ " .. w.format_integer(relay.position.x, 7) .. " " .. w.format_integer(relay.position.y, 3) .. " " .. w.format_integer(relay.position.z, 7))
534
  
535
  -- name
536
  w.setCursorPos(1, 16)
537
  w.setColorHelp()
538
  w.writeFullLine(" Press enter to validate.")
539
  w.setCursorPos(1, 3)
540
  w.setColorNormal()
541
  w.writeLn("Name (" .. relay.name .. "):")
542
  local nameOriginal = relay.name
543
  relay.name = w.input_readText(relay.name)
544
  w.setCursorPos(1, 3)
545
  w.setColorNormal()
546
  w.clearLine()
547
  if nameOriginal ~= relay.name then
548
    w.setColorSuccess()
549
  else
550
    w.setColorNormal()
551
  end
552
  relay.name = relay.device.name(relay.name)
553
  w.writeLn("Name set to " .. relay.name)
554
  w.setColorNormal()
555
  w.clearLine()
556
  
557
  -- beam frequency
558
  relay.beamFrequency = relay.device.beamFrequency()
559
  w.setCursorPos(1, 16)
560
  w.setColorHelp()
561
  w.writeFullLine(" Enter a number between 0 and 65000.")
562
  local frequency
563
  repeat
564
    w.setCursorPos(1, 5)
565
    w.setColorNormal()
566
    w.clearLine()
567
    w.write("Beam frequency (" .. w.format_integer(relay.beamFrequency, 5) .. "): ")
568
    frequency = w.input_readInteger(relay.beamFrequency)
569
    if frequency ~= 0 and (frequency < 0 or frequency > 65000) then
570
      w.status_showWarning("This is not a valid beam frequency. Try again.")
571
    end
572
  until frequency > 0 and frequency <= 65000
573
  w.setCursorPos(1, 4)
574
  w.clearLine()
575
  if frequency ~= relay.beamFrequency then
576
    w.setColorSuccess()
577
  else
578
    w.setColorNormal()
579
  end
580
  relay.beamFrequency = relay.device.beamFrequency(frequency)
581
  w.write("Beam frequency set to " .. relay.beamFrequency)
582
  w.setColorNormal()
583
  w.setCursorPos(1, 5)
584
  w.clearLine()
585
  w.setCursorPos(1, 6)
586
  w.clearLine()
587
end
588
589
function ffield_register()
590
  w.device_register("warpdriveForceFieldProjector",
591
      function(deviceType, address, wrap) table.insert(ffield_projectorAddresses, address) end,
592
      function() end)
593
  w.device_register("warpdriveForceFieldRelay",
594
      function(deviceType, address, wrap) table.insert(ffield_relayAddresses, address) end,
595
      function() end)
596
  w.data_register("ffield", ffield_read, ffield_save, nil)
597
end
598
599
----------- connections status
600
601
function connections_page(isBooting)
602
  w.page_begin(w.data_getName() .. " - Connections")
603
  
604
  w.writeLn("")
605
  
606
  local monitors = w.device_getMonitors()
607
  if #monitors == 0 then
608
    w.setColorDisabled()
609
    w.writeLn("No Monitor detected")
610
  elseif #monitors == 1 then
611
    w.setColorSuccess()
612
    w.writeLn("1 monitor detected")
613
  else
614
    w.setColorSuccess()
615
    w.writeLn(#monitors .. " Monitors detected")
616
  end
617
  
618
  if #ffield_projectorAddresses == 0 then
619
    w.setColorDisabled()
620
    w.writeLn("No force field projector detected")
621
  elseif #ffield_projectorAddresses == 1 then
622
    w.setColorSuccess()
623
    w.writeLn("1 force field projector detected")
624
  else
625
    w.setColorSuccess()
626
    w.writeLn(#ffield_projectorAddresses .. " force field projectors detected")
627
  end
628
  
629
  if #ffield_relayAddresses == 0 then
630
    w.setColorDisabled()
631
    w.writeLn("No force field relay detected")
632
  elseif #ffield_relayAddresses == 1 then
633
    w.setColorSuccess()
634
    w.writeLn("1 force field relay detected")
635
  else
636
    w.setColorSuccess()
637
    w.writeLn(#ffield_relayAddresses .. " force field relays detected")
638
  end
639
  
640
  if isBooting then
641
    ffield_boot()
642
  end
643
  
644
  w.writeLn("")
645
  w.setColorNormal()
646
  w.writeLn("This is a keyboard controlled user interface.")
647
  w.write("Key controls are written like so: ")
648
  w.setColorControl()
649
  w.write("Action (key)")
650
  w.setColorNormal()
651
  w.writeLn(".")
652
  w.write("For example, typing ")
653
  w.setColorControl()
654
  w.write(" 1 ")
655
  w.setColorNormal()
656
  w.writeLn(" will open Force field projectors.")
657
end
658
659
----------- Boot sequence
660
661
w.page_setEndText(" Home (0), Projectors (1), Relays (2)")
662
w.page_register('0', connections_page, nil)
663
w.page_register('1', ffield_projector_page, ffield_projector_key)
664
w.page_register('2', ffield_relay_page, ffield_relay_key)
665
ffield_register()
666
667
w.boot()
668
w.run()
669
w.close()