lignite 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.rubocop.yml +12 -0
- data/NEWS.md +5 -1
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/ev3tool +111 -104
- data/examples/bobbee.rb +7 -7
- data/examples/hello.rb +2 -0
- data/examples/hello.yml +4 -0
- data/examples/light-sensor.rb +2 -0
- data/examples/light-sensor.yml +3 -0
- data/examples/lights.rb +7 -7
- data/examples/lights.yml +4 -0
- data/examples/sys_list_files.rb +4 -2
- data/examples/sys_list_files.yml +9 -0
- data/lib/lignite.rb +5 -1
- data/lib/lignite/assembler.rb +6 -6
- data/lib/lignite/body_compiler.rb +4 -0
- data/lib/lignite/connection.rb +59 -1
- data/lib/lignite/connection/bluetooth.rb +7 -1
- data/lib/lignite/connection/replay.rb +57 -0
- data/lib/lignite/connection/tap.rb +45 -0
- data/lib/lignite/connection/usb.rb +10 -7
- data/lib/lignite/direct_commands.rb +56 -5
- data/lib/lignite/message.rb +8 -5
- data/lib/lignite/motors.rb +5 -5
- data/lib/lignite/op_compiler.rb +19 -18
- data/lib/lignite/rbf_object.rb +1 -1
- data/lib/lignite/system_commands.rb +30 -2
- data/lib/lignite/variables.rb +2 -2
- data/lignite.gemspec +14 -4
- data/rubocop-suse.yml +74 -0
- data/spec/connection_usb_spec.rb +42 -0
- data/spec/data/ColorReadout.rb +11 -12
- data/spec/data/HelloWorld-subop.rb +1 -1
- data/spec/data/HelloWorld.rb +1 -1
- data/spec/data/NoDebug.rb +1 -1
- data/spec/data/VernierReadout.rb +4 -4
- data/spec/direct_commands_spec.rb +25 -0
- data/spec/system_commands_spec.rb +22 -0
- metadata +28 -3
- data/lib/lignite/message_sender.rb +0 -94
data/lib/lignite/motors.rb
CHANGED
@@ -6,10 +6,10 @@ module Lignite
|
|
6
6
|
# do the DCs spawn independent threads??
|
7
7
|
# must run ready in the same block?
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
attr_reader :layer
|
10
|
+
attr_reader :nos
|
11
11
|
# @return [Lignite::DirectCommands]
|
12
|
-
|
12
|
+
attr_reader :dc
|
13
13
|
|
14
14
|
# 0x02 | 0x04 | 0x08 -> [1, 2, 3]
|
15
15
|
def nos_as_indices
|
@@ -24,7 +24,7 @@ module Lignite
|
|
24
24
|
@dc = dc
|
25
25
|
end
|
26
26
|
|
27
|
-
# TODO filter out support: official: no
|
27
|
+
# TODO: filter out support: official: no
|
28
28
|
|
29
29
|
# the type is an OUT param so the VM SETs and we GET to learn the type?
|
30
30
|
def set_type
|
@@ -62,7 +62,7 @@ module Lignite
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def start
|
65
|
-
dc.output_start(layer, nos)
|
65
|
+
dc.output_start(layer, nos) # apparently not
|
66
66
|
end
|
67
67
|
|
68
68
|
# ATTR ~polarity
|
data/lib/lignite/op_compiler.rb
CHANGED
@@ -119,7 +119,7 @@ module Lignite
|
|
119
119
|
end
|
120
120
|
|
121
121
|
enums = yml["enums"]
|
122
|
-
enums.
|
122
|
+
enums.each_value do |edata|
|
123
123
|
edata["members"].each do |mname, mdata|
|
124
124
|
load_const(mname, mdata["value"])
|
125
125
|
end
|
@@ -177,29 +177,30 @@ module Lignite
|
|
177
177
|
end
|
178
178
|
|
179
179
|
def make_lc(n, bytes = nil)
|
180
|
-
bytes ||= if (-31
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
180
|
+
bytes ||= if (-31..31).cover? n
|
181
|
+
0
|
182
|
+
elsif (-127..127).cover? n
|
183
|
+
1
|
184
|
+
elsif (-32767..32767).cover? n
|
185
|
+
2
|
186
|
+
else
|
187
|
+
4
|
188
|
+
end
|
189
189
|
make_lcn(n, bytes)
|
190
190
|
end
|
191
191
|
|
192
192
|
def make_v(n, local_or_global)
|
193
193
|
vartag = PRIMPAR_VARIABEL | local_or_global
|
194
|
-
if (0
|
195
|
-
|
196
|
-
elsif (0
|
197
|
-
|
198
|
-
elsif (0
|
199
|
-
|
194
|
+
if (0..31).cover? n
|
195
|
+
[vartag | (n & PRIMPAR_VALUE)]
|
196
|
+
elsif (0..255).cover? n
|
197
|
+
[vartag | PRIMPAR_LONG | PRIMPAR_1_BYTE, n & 0xff]
|
198
|
+
elsif (0..65535).cover? n
|
199
|
+
[vartag | PRIMPAR_LONG | PRIMPAR_2_BYTES, n & 0xff, (n >> 8) & 0xff]
|
200
|
+
else
|
201
|
+
[vartag | PRIMPAR_LONG | PRIMPAR_4_BYTES,
|
202
|
+
n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]
|
200
203
|
end
|
201
|
-
[vartag | PRIMPAR_LONG | PRIMPAR_4_BYTES,
|
202
|
-
n & 0xff, (n >> 8) & 0xff, (n >> 16) & 0xff, (n >> 24) & 0xff]
|
203
204
|
end
|
204
205
|
|
205
206
|
# Reference a variable.
|
data/lib/lignite/rbf_object.rb
CHANGED
@@ -4,12 +4,24 @@ module Lignite
|
|
4
4
|
include Logger
|
5
5
|
extend Logger
|
6
6
|
|
7
|
+
def self.run(conn = Connection.create, &block)
|
8
|
+
sc = new(conn)
|
9
|
+
sc.instance_exec(&block)
|
10
|
+
sc.close
|
11
|
+
end
|
12
|
+
|
7
13
|
# @param conn [Connection]
|
8
14
|
def initialize(conn = Connection.create)
|
9
|
-
@
|
15
|
+
@conn = conn
|
10
16
|
load_yml
|
11
17
|
end
|
12
18
|
|
19
|
+
def close
|
20
|
+
@conn.close
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
13
25
|
def load_yml
|
14
26
|
fname = File.expand_path("../../../data/sysops.yml", __FILE__)
|
15
27
|
op_hash = YAML.load_file(fname)["sysops"]
|
@@ -38,7 +50,7 @@ module Lignite
|
|
38
50
|
end.join("")
|
39
51
|
logger.debug "sysop to execute: #{bytes.inspect}"
|
40
52
|
|
41
|
-
reply =
|
53
|
+
reply = system_command_with_reply(bytes)
|
42
54
|
|
43
55
|
# TODO: parse it with return_handlers
|
44
56
|
replies = return_handlers.map do |h|
|
@@ -99,5 +111,21 @@ module Lignite
|
|
99
111
|
end
|
100
112
|
end
|
101
113
|
|
114
|
+
def system_command_with_reply(instr_bytes)
|
115
|
+
cmd = Message.system_command_with_reply(instr_bytes)
|
116
|
+
@conn.send(cmd.bytes)
|
117
|
+
|
118
|
+
reply = Message.reply_from_bytes(@conn.receive)
|
119
|
+
assert_match(reply.msgid, cmd.msgid, "Reply id")
|
120
|
+
assert_match(reply.command, unpack_u8(instr_bytes[0]), "Command num")
|
121
|
+
raise VMError, format("Error: %u", reply.status) if reply.error?
|
122
|
+
|
123
|
+
reply.data
|
124
|
+
end
|
125
|
+
|
126
|
+
def assert_match(actual, expected, description)
|
127
|
+
return if actual == expected
|
128
|
+
raise "#{description} does not match, expected #{expected}, actual #{actual}"
|
129
|
+
end
|
102
130
|
end
|
103
131
|
end
|
data/lib/lignite/variables.rb
CHANGED
@@ -14,7 +14,7 @@ module Lignite
|
|
14
14
|
# declare
|
15
15
|
def add(id, size, unpacker)
|
16
16
|
raise "Duplicate variable #{id}" if @vars.key?(id)
|
17
|
-
@vars[id] = {offset: @offset, size: size}
|
17
|
+
@vars[id] = { offset: @offset, size: size }
|
18
18
|
@offset += size
|
19
19
|
@unpacker += unpacker
|
20
20
|
end
|
@@ -41,7 +41,7 @@ module Lignite
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
#
|
44
|
+
# `variables` are {Variables}
|
45
45
|
module VariableDeclarer
|
46
46
|
def data8(id)
|
47
47
|
variables.add(id, 1, "C")
|
data/lignite.gemspec
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
1
|
require File.expand_path(File.dirname(__FILE__) + "/lib/lignite/version")
|
4
2
|
|
5
3
|
Gem::Specification.new do |s|
|
@@ -20,6 +18,8 @@ TXT
|
|
20
18
|
s.files = [
|
21
19
|
".coveralls.yml",
|
22
20
|
".gitignore",
|
21
|
+
".rspec",
|
22
|
+
".rubocop.yml",
|
23
23
|
".travis.yml",
|
24
24
|
".yardopts",
|
25
25
|
"COPYING",
|
@@ -34,22 +34,27 @@ TXT
|
|
34
34
|
"data/sysops.yml",
|
35
35
|
"examples/bobbee.rb",
|
36
36
|
"examples/hello.rb",
|
37
|
+
"examples/hello.yml",
|
37
38
|
"examples/light-sensor.rb",
|
39
|
+
"examples/light-sensor.yml",
|
38
40
|
"examples/lights.rb",
|
41
|
+
"examples/lights.yml",
|
39
42
|
"examples/motors.rb",
|
40
43
|
"examples/sound.rb",
|
41
44
|
"examples/sys_list_files.rb",
|
45
|
+
"examples/sys_list_files.yml",
|
42
46
|
"lib/lignite.rb",
|
43
47
|
"lib/lignite/assembler.rb",
|
44
48
|
"lib/lignite/body_compiler.rb",
|
45
49
|
"lib/lignite/bytes.rb",
|
46
50
|
"lib/lignite/connection.rb",
|
47
51
|
"lib/lignite/connection/bluetooth.rb",
|
52
|
+
"lib/lignite/connection/replay.rb",
|
53
|
+
"lib/lignite/connection/tap.rb",
|
48
54
|
"lib/lignite/connection/usb.rb",
|
49
55
|
"lib/lignite/direct_commands.rb",
|
50
56
|
"lib/lignite/logger.rb",
|
51
57
|
"lib/lignite/message.rb",
|
52
|
-
"lib/lignite/message_sender.rb",
|
53
58
|
"lib/lignite/motors.rb",
|
54
59
|
"lib/lignite/op_compiler.rb",
|
55
60
|
"lib/lignite/rbf_object.rb",
|
@@ -57,7 +62,9 @@ TXT
|
|
57
62
|
"lib/lignite/variables.rb",
|
58
63
|
"lib/lignite/version.rb",
|
59
64
|
"lignite.gemspec",
|
65
|
+
"rubocop-suse.yml",
|
60
66
|
"spec/assembler_spec.rb",
|
67
|
+
"spec/connection_usb_spec.rb",
|
61
68
|
"spec/data/ColorReadout.lms",
|
62
69
|
"spec/data/ColorReadout.rb",
|
63
70
|
"spec/data/ColorReadout.rbf",
|
@@ -72,13 +79,16 @@ TXT
|
|
72
79
|
"spec/data/VernierReadout.lms",
|
73
80
|
"spec/data/VernierReadout.rb",
|
74
81
|
"spec/data/VernierReadout.rbf",
|
75
|
-
"spec/
|
82
|
+
"spec/direct_commands_spec.rb",
|
83
|
+
"spec/spec_helper.rb",
|
84
|
+
"spec/system_commands_spec.rb"
|
76
85
|
]
|
77
86
|
|
78
87
|
s.executables = s.files.grep(/^bin\//) { |f| File.basename(f) }
|
79
88
|
|
80
89
|
s.required_ruby_version = ">= 2.1" # mandatory keyword arguments
|
81
90
|
s.add_dependency "libusb", "~> 0.6"
|
91
|
+
s.add_dependency "thor", "~> 0.19"
|
82
92
|
|
83
93
|
s.add_development_dependency "coveralls", "~> 0"
|
84
94
|
s.add_development_dependency "simplecov", "~> 0"
|
data/rubocop-suse.yml
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# This is the shared Rubocop configuration for SUSE projects. It is maintained
|
2
|
+
# at https://github.com/SUSE/style-guides/blob/master/rubocop-suse.yml
|
3
|
+
#
|
4
|
+
# The configuration is tested and used with the Rubocop version used by Hound
|
5
|
+
# (https://houndci.com).
|
6
|
+
#
|
7
|
+
# We use the default Hound config as a baseline:
|
8
|
+
#
|
9
|
+
# https://raw.githubusercontent.com/thoughtbot/hound/master/config/style_guides/ruby.yml
|
10
|
+
#
|
11
|
+
# This file contains the rules with derive from this.
|
12
|
+
|
13
|
+
Lint/EndAlignment:
|
14
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#lintendalignment
|
15
|
+
EnforcedStyleAlignWith: variable
|
16
|
+
|
17
|
+
Metrics/AbcSize:
|
18
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#metricsabcsize
|
19
|
+
Max: 30
|
20
|
+
|
21
|
+
Metrics/LineLength:
|
22
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#metricslinelength
|
23
|
+
Max: 100
|
24
|
+
# To make it possible to copy or click on URIs in the code, we allow lines
|
25
|
+
# contaning a URI to be longer than Max.
|
26
|
+
AllowURI: true
|
27
|
+
URISchemes:
|
28
|
+
- http
|
29
|
+
- https
|
30
|
+
|
31
|
+
Style/AlignHash:
|
32
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylealignhash
|
33
|
+
EnforcedHashRocketStyle: table
|
34
|
+
EnforcedColonStyle: table
|
35
|
+
|
36
|
+
Style/AlignParameters:
|
37
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylealignparameters
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/CollectionMethods:
|
41
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylecollectionmethods
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
Style/EmptyLinesAroundBlockBody:
|
45
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#styleemptylinesaroundblockbody
|
46
|
+
Enabled: false
|
47
|
+
|
48
|
+
Style/MultilineOperationIndentation:
|
49
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylemultilineoperationindentation
|
50
|
+
EnforcedStyle: indented
|
51
|
+
|
52
|
+
Style/StringLiterals:
|
53
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylestringliterals
|
54
|
+
EnforcedStyle: double_quotes
|
55
|
+
|
56
|
+
Style/StringLiteralsInInterpolation:
|
57
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylestringliteralsininterpolation
|
58
|
+
EnforcedStyle: double_quotes
|
59
|
+
|
60
|
+
Style/WordArray:
|
61
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#deviations-from-the-upstream-style-guide
|
62
|
+
Enabled: false
|
63
|
+
|
64
|
+
Style/RegexpLiteral:
|
65
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#deviations-from-the-upstream-style-guide
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
Style/SignalException:
|
69
|
+
StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
|
70
|
+
EnforcedStyle: only_raise
|
71
|
+
|
72
|
+
Style/NumericLiterals:
|
73
|
+
StyleGuide: https://github.com/SUSE/style-guides/blob/master/Ruby.md#stylenumericliterals
|
74
|
+
Enabled: false
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative "spec_helper"
|
2
|
+
require "lignite"
|
3
|
+
|
4
|
+
describe Lignite::Connection::Usb do
|
5
|
+
let(:device) do
|
6
|
+
instance_double("FakeDevice", interfaces: [interface])
|
7
|
+
end
|
8
|
+
let(:interface) { double("FakeInterface", endpoints: [in_ep, out_ep]) }
|
9
|
+
let(:in_ep) { double("InEndpoint", direction: :in) }
|
10
|
+
let(:out_ep) { double("OutEndpoint", direction: :out) }
|
11
|
+
let(:dev_handle) { double("FakeDevHandle") }
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
usb = instance_double("FakeContext", devices: [device])
|
15
|
+
allow(LIBUSB::Context).to receive(:new).and_return(usb)
|
16
|
+
allow(dev_handle).to receive(:"auto_detach_kernel_driver=")
|
17
|
+
allow(dev_handle).to receive(:claim_interface).and_yield
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#write" do
|
21
|
+
it "does not crash" do
|
22
|
+
data = "hello"
|
23
|
+
allow(device).to receive(:open).and_yield(dev_handle)
|
24
|
+
allow(dev_handle).to receive(:interrupt_transfer).and_return(data.bytesize)
|
25
|
+
expect { subject.write(data) }.to_not raise_error
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#read" do
|
30
|
+
it "does not crash" do
|
31
|
+
allow(device).to receive(:open).and_yield(dev_handle)
|
32
|
+
allow(dev_handle).to receive(:interrupt_transfer).and_return("hello")
|
33
|
+
expect(subject.read(1000)).to eq("hello")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#write" do
|
38
|
+
it "does not crash" do
|
39
|
+
expect { subject.close }.to_not raise_error
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/spec/data/ColorReadout.rb
CHANGED
@@ -15,38 +15,37 @@ vmthread :MAIN do
|
|
15
15
|
data8 :Mode
|
16
16
|
data8 :State
|
17
17
|
|
18
|
-
|
19
18
|
move8_8(3, :Mode)
|
20
19
|
|
21
|
-
|
20
|
+
loop do
|
22
21
|
ui_draw(FILLWINDOW, 0x00, 0, 0)
|
23
22
|
ui_draw(SELECT_FONT, SMALL_FONT)
|
24
|
-
ui_draw(TEXT, FG_COLOR, 0, 10,
|
25
|
-
ui_draw(TEXT, FG_COLOR, 0, 30,
|
23
|
+
ui_draw(TEXT, FG_COLOR, 0, 10, " Color Readout V0.00 ")
|
24
|
+
ui_draw(TEXT, FG_COLOR, 0, 30, "Mode ")
|
26
25
|
|
27
|
-
ui_draw(TEXT, FG_COLOR, 0, 50,
|
28
|
-
ui_draw(TEXT, FG_COLOR, 0, 65,
|
29
|
-
ui_draw(TEXT, FG_COLOR, 0, 80,
|
30
|
-
ui_draw(TEXT, FG_COLOR, 0, 118,
|
26
|
+
ui_draw(TEXT, FG_COLOR, 0, 50, "Raw 1")
|
27
|
+
ui_draw(TEXT, FG_COLOR, 0, 65, "Raw 2")
|
28
|
+
ui_draw(TEXT, FG_COLOR, 0, 80, "Raw 3")
|
29
|
+
ui_draw(TEXT, FG_COLOR, 0, 118, "Left = 3 Right = 4")
|
31
30
|
ui_draw(SELECT_FONT, NORMAL_FONT)
|
32
31
|
|
33
32
|
move8_32(:Mode, :Data1)
|
34
33
|
and32(:Data1, 0xFF, :Data1)
|
35
|
-
strings(NUMBER_FORMATTED, :Data1,
|
34
|
+
strings(NUMBER_FORMATTED, :Data1, "%1d", 8, :String)
|
36
35
|
ui_draw(TEXT, FG_COLOR, 64, 30, :String)
|
37
36
|
|
38
37
|
input_device(READY_RAW, 0, PORT, 0, :Mode, 3, :Data1, :Data2, :Data3)
|
39
38
|
|
40
39
|
and32(:Data1, 0xFFFF, :Data1)
|
41
|
-
strings(NUMBER_FORMATTED, :Data1,
|
40
|
+
strings(NUMBER_FORMATTED, :Data1, "%-5d", 8, :String)
|
42
41
|
ui_draw(TEXT, FG_COLOR, 64, 50, :String)
|
43
42
|
|
44
43
|
and32(:Data2, 0xFFFF, :Data2)
|
45
|
-
strings(NUMBER_FORMATTED, :Data2,
|
44
|
+
strings(NUMBER_FORMATTED, :Data2, "%-5d", 8, :String)
|
46
45
|
ui_draw(TEXT, FG_COLOR, 64, 65, :String)
|
47
46
|
|
48
47
|
and32(:Data3, 0xFFFF, :Data3)
|
49
|
-
strings(NUMBER_FORMATTED, :Data3,
|
48
|
+
strings(NUMBER_FORMATTED, :Data3, "%-5d", 8, :String)
|
50
49
|
ui_draw(TEXT, FG_COLOR, 64, 80, :String)
|
51
50
|
|
52
51
|
ui_draw(UPDATE)
|
data/spec/data/HelloWorld.rb
CHANGED
data/spec/data/NoDebug.rb
CHANGED
data/spec/data/VernierReadout.rb
CHANGED
@@ -5,18 +5,18 @@ vmthread :MAIN do
|
|
5
5
|
data32 :Data1
|
6
6
|
datas :String, 8
|
7
7
|
|
8
|
-
|
8
|
+
loop do
|
9
9
|
ui_draw(FILLWINDOW, 0x00, 0, 0)
|
10
10
|
ui_draw(SELECT_FONT, SMALL_FONT)
|
11
|
-
ui_draw(TEXT, FG_COLOR, 0, 10,
|
11
|
+
ui_draw(TEXT, FG_COLOR, 0, 10, "Vernier Readout V0.00")
|
12
12
|
|
13
|
-
ui_draw(TEXT, FG_COLOR, 0, 50,
|
13
|
+
ui_draw(TEXT, FG_COLOR, 0, 50, "Raw 1")
|
14
14
|
ui_draw(SELECT_FONT, NORMAL_FONT)
|
15
15
|
|
16
16
|
input_device(READY_RAW, 0, PORT, 1, 0, 1, :Data1)
|
17
17
|
|
18
18
|
and32(:Data1, 0xFFFF, :Data1)
|
19
|
-
strings(NUMBER_FORMATTED, :Data1,
|
19
|
+
strings(NUMBER_FORMATTED, :Data1, "%-5d", 8, :String)
|
20
20
|
ui_draw(TEXT, FG_COLOR, 64, 50, :String)
|
21
21
|
|
22
22
|
ui_draw(UPDATE)
|