| 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 } |