23 #include "colors.h" |
23 #include "colors.h" |
24 |
24 |
25 // ============================================================================= |
25 // ============================================================================= |
26 // Helper function for parseLDConfig |
26 // Helper function for parseLDConfig |
27 // ----------------------------------------------------------------------------- |
27 // ----------------------------------------------------------------------------- |
28 static bool parseLDConfigTag (LDConfigParser& pars, char const* tag, str& val) { |
28 static bool parseLDConfigTag (LDConfigParser& pars, char const* tag, str& val) |
29 short pos; |
29 { short pos; |
30 |
30 |
31 // Try find the token and get its position |
31 // Try find the token and get its position |
32 if (!pars.findToken (pos, tag, 1)) |
32 if (!pars.findToken (pos, tag, 1)) |
33 return false; |
33 return false; |
34 |
34 |
35 // Get the token after it and store it into val |
35 // Get the token after it and store it into val |
36 return pars.getToken (val, pos + 1); |
36 return pars.getToken (val, pos + 1); |
37 } |
37 } |
38 |
38 |
39 // ============================================================================= |
39 // ============================================================================= |
40 // ----------------------------------------------------------------------------- |
40 // ----------------------------------------------------------------------------- |
41 void parseLDConfig() { |
41 void parseLDConfig() |
42 File* f = openLDrawFile ("LDConfig.ldr", false); |
42 { File* f = openLDrawFile ("LDConfig.ldr", false); |
43 |
43 |
44 if (!f) { |
44 if (!f) |
45 critical (fmt (QObject::tr ("Unable to open LDConfig.ldr for parsing! (%1)"), |
45 { critical (fmt (QObject::tr ("Unable to open LDConfig.ldr for parsing! (%1)"), |
46 strerror (errno))); |
46 strerror (errno))); |
47 return; |
47 return; |
48 } |
48 } |
49 |
49 |
50 // Read in the lines |
50 // Read in the lines |
51 for (str line : *f) { |
51 for (str line : *f) |
52 if (line.length() == 0 || line[0] != '0') |
52 { if (line.length() == 0 || line[0] != '0') |
53 continue; // empty or illogical |
53 continue; // empty or illogical |
54 |
54 |
55 line.remove ('\r'); |
55 line.remove ('\r'); |
56 line.remove ('\n'); |
56 line.remove ('\n'); |
57 |
57 |
58 // Parse the line |
58 // Parse the line |
59 LDConfigParser pars (line, ' '); |
59 LDConfigParser pars (line, ' '); |
60 |
60 |
61 short code = 0, alpha = 255; |
61 short code = 0, alpha = 255; |
62 str name, facename, edgename, valuestr; |
62 str name, facename, edgename, valuestr; |
63 |
63 |
64 // Check 0 !COLOUR, parse the name |
64 // Check 0 !COLOUR, parse the name |
65 if (!pars.tokenCompare (0, "0") || !pars.tokenCompare (1, "!COLOUR") || !pars.getToken (name, 2)) |
65 if (!pars.tokenCompare (0, "0") || !pars.tokenCompare (1, "!COLOUR") || !pars.getToken (name, 2)) |
66 continue; |
66 continue; |
67 |
67 |
68 // Replace underscores in the name with spaces for readability |
68 // Replace underscores in the name with spaces for readability |
69 name.replace ("_", " "); |
69 name.replace ("_", " "); |
70 |
70 |
71 // Get the CODE tag |
71 // Get the CODE tag |
72 if (!parseLDConfigTag (pars, "CODE", valuestr)) |
72 if (!parseLDConfigTag (pars, "CODE", valuestr)) |
73 continue; |
73 continue; |
74 |
74 |
75 if (!isNumber (valuestr)) |
75 if (!isNumber (valuestr)) |
76 continue; // not a number |
76 continue; // not a number |
77 |
77 |
78 // Ensure that the code is within [0 - 511] |
78 // Ensure that the code is within [0 - 511] |
79 bool ok; |
79 bool ok; |
80 code = valuestr.toShort (&ok); |
80 code = valuestr.toShort (&ok); |
81 |
81 |
82 if (!ok || code < 0 || code >= 512) |
82 if (!ok || code < 0 || code >= 512) |
83 continue; |
83 continue; |
84 |
84 |
85 // VALUE and EDGE tags |
85 // VALUE and EDGE tags |
86 if (!parseLDConfigTag (pars, "VALUE", facename) || !parseLDConfigTag (pars, "EDGE", edgename)) |
86 if (!parseLDConfigTag (pars, "VALUE", facename) || !parseLDConfigTag (pars, "EDGE", edgename)) |
87 continue; |
87 continue; |
88 |
88 |
89 // Ensure that our colors are correct |
89 // Ensure that our colors are correct |
90 QColor faceColor (facename), |
90 QColor faceColor (facename), |
91 edgeColor (edgename); |
91 edgeColor (edgename); |
92 |
92 |
93 if (!faceColor.isValid() || !edgeColor.isValid()) |
93 if (!faceColor.isValid() || !edgeColor.isValid()) |
94 continue; |
94 continue; |
95 |
95 |
96 // Parse alpha if given. |
96 // Parse alpha if given. |
97 if (parseLDConfigTag (pars, "ALPHA", valuestr)) |
97 if (parseLDConfigTag (pars, "ALPHA", valuestr)) |
98 alpha = clamp<short> (valuestr.toShort(), 0, 255); |
98 alpha = clamp<short> (valuestr.toShort(), 0, 255); |
99 |
99 |
100 LDColor* col = new LDColor; |
100 LDColor* col = new LDColor; |
101 col->name = name; |
101 col->name = name; |
102 col->faceColor = faceColor; |
102 col->faceColor = faceColor; |
103 col->edgeColor = edgeColor; |
103 col->edgeColor = edgeColor; |
104 col->hexcode = facename; |
104 col->hexcode = facename; |
105 col->faceColor.setAlpha (alpha); |
105 col->faceColor.setAlpha (alpha); |
106 col->index = code; |
106 col->index = code; |
107 setColor (code, col); |
107 setColor (code, col); |
108 } |
108 } |
109 |
109 |
110 delete f; |
110 delete f; |
111 } |
111 } |
112 |
112 |
113 // ============================================================================= |
113 // ============================================================================= |
114 // ----------------------------------------------------------------------------- |
114 // ----------------------------------------------------------------------------- |
115 LDConfigParser::LDConfigParser (str inText, char sep) { |
115 LDConfigParser::LDConfigParser (str inText, char sep) |
116 m_tokens = container_cast<QStringList, List<str>> (inText.split (sep, QString::SkipEmptyParts)); |
116 { m_tokens = container_cast<QStringList, List<str>> (inText.split (sep, QString::SkipEmptyParts)); |
117 m_pos = -1; |
117 m_pos = -1; |
118 } |
118 } |
119 |
119 |
120 // ============================================================================= |
120 // ============================================================================= |
121 // ----------------------------------------------------------------------------- |
121 // ----------------------------------------------------------------------------- |
122 bool LDConfigParser::atBeginning() { |
122 bool LDConfigParser::atBeginning() |
123 return (m_pos == -1); |
123 { return (m_pos == -1); |
124 } |
124 } |
125 |
125 |
126 // ============================================================================= |
126 // ============================================================================= |
127 // ----------------------------------------------------------------------------- |
127 // ----------------------------------------------------------------------------- |
128 bool LDConfigParser::atEnd() { |
128 bool LDConfigParser::atEnd() |
129 return (m_pos == (signed) m_tokens.size() - 1); |
129 { return (m_pos == (signed) m_tokens.size() - 1); |
130 } |
130 } |
131 |
131 |
132 // ============================================================================= |
132 // ============================================================================= |
133 // ----------------------------------------------------------------------------- |
133 // ----------------------------------------------------------------------------- |
134 bool LDConfigParser::getToken (str& val, const ushort pos) { |
134 bool LDConfigParser::getToken (str& val, const ushort pos) |
135 if (pos >= m_tokens.size()) |
135 { if (pos >= m_tokens.size()) |
136 return false; |
136 return false; |
137 |
137 |
138 val = m_tokens[pos]; |
138 val = m_tokens[pos]; |
139 return true; |
139 return true; |
140 } |
140 } |
141 |
141 |
142 // ============================================================================= |
142 // ============================================================================= |
143 // ----------------------------------------------------------------------------- |
143 // ----------------------------------------------------------------------------- |
144 bool LDConfigParser::next (str& val) { |
144 bool LDConfigParser::next (str& val) |
145 return getToken (val, ++m_pos); |
145 { return getToken (val, ++m_pos); |
146 } |
146 } |
147 |
147 |
148 // ============================================================================= |
148 // ============================================================================= |
149 // ----------------------------------------------------------------------------- |
149 // ----------------------------------------------------------------------------- |
150 bool LDConfigParser::peekNext (str& val) { |
150 bool LDConfigParser::peekNext (str& val) |
151 return getToken (val, m_pos + 1); |
151 { return getToken (val, m_pos + 1); |
152 } |
152 } |
153 |
153 |
154 // ============================================================================= |
154 // ============================================================================= |
155 // ----------------------------------------------------------------------------- |
155 // ----------------------------------------------------------------------------- |
156 bool LDConfigParser::findToken (short& result, char const* needle, short args) { |
156 bool LDConfigParser::findToken (short& result, char const* needle, short args) |
157 for (ushort i = 0; i < (m_tokens.size() - args); ++i) { |
157 { for (ushort i = 0; i < (m_tokens.size() - args); ++i) |
158 if (m_tokens[i] == needle) { |
158 { if (m_tokens[i] == needle) |
159 result = i; |
159 { result = i; |
160 return true; |
160 return true; |
161 } |
161 } |
162 } |
162 } |
163 |
163 |
164 return false; |
164 return false; |
165 } |
165 } |
166 |
166 |
167 // ============================================================================= |
167 // ============================================================================= |
168 // ----------------------------------------------------------------------------- |
168 // ----------------------------------------------------------------------------- |
169 void LDConfigParser::rewind() { |
169 void LDConfigParser::rewind() |
170 m_pos = -1; |
170 { m_pos = -1; |
171 } |
171 } |
172 |
172 |
173 // ============================================================================= |
173 // ============================================================================= |
174 // ----------------------------------------------------------------------------- |
174 // ----------------------------------------------------------------------------- |
175 void LDConfigParser::seek (short amount, bool rel) { |
175 void LDConfigParser::seek (short amount, bool rel) |
176 m_pos = (rel ? m_pos : 0) + amount; |
176 { m_pos = (rel ? m_pos : 0) + amount; |
177 } |
177 } |
178 |
178 |
179 // ============================================================================= |
179 // ============================================================================= |
180 // ----------------------------------------------------------------------------- |
180 // ----------------------------------------------------------------------------- |
181 size_t LDConfigParser::size() { |
181 size_t LDConfigParser::size() |
182 return m_tokens.size(); |
182 { return m_tokens.size(); |
183 } |
183 } |
184 |
184 |
185 // ============================================================================= |
185 // ============================================================================= |
186 // ----------------------------------------------------------------------------- |
186 // ----------------------------------------------------------------------------- |
187 bool LDConfigParser::tokenCompare (short inPos, const char* sOther) { |
187 bool LDConfigParser::tokenCompare (short inPos, const char* sOther) |
188 str tok; |
188 { str tok; |
|
189 |
189 if (!getToken (tok, inPos)) |
190 if (!getToken (tok, inPos)) |
190 return false; |
191 return false; |
191 |
192 |
192 return (tok == sOther); |
193 return (tok == sOther); |
193 } |
194 } |