4 #include "io.h" |
4 #include "io.h" |
5 #include "misc.h" |
5 #include "misc.h" |
6 #include "gui.h" |
6 #include "gui.h" |
7 #include "bbox.h" |
7 #include "bbox.h" |
8 |
8 |
|
9 vector<str> g_zaFileLoadPaths; |
|
10 |
9 // ============================================================================= |
11 // ============================================================================= |
10 // IO_FindLoadedFile (str) |
12 // IO_FindLoadedFile (str) |
11 // |
13 // |
12 // Returns a pointer to the first found open file with the given name. |
14 // Returns a pointer to the first found open file with the given name. |
13 // ============================================================================= |
15 // ============================================================================= |
14 OpenFile* IO_FindLoadedFile (str name) { |
16 OpenFile* IO_FindLoadedFile (str name) { |
15 OpenFile* file; |
17 for (ulong i = 0; i < g_LoadedFiles.size(); i++) { |
16 |
18 OpenFile* const file = g_LoadedFiles[i]; |
17 for (uint i = 0; i < g_LoadedFiles.size(); i++) { |
19 if (file->zFileName == name) |
18 file = g_LoadedFiles[i]; |
|
19 if (!file->zFileName.icompare (name)) |
|
20 return file; |
20 return file; |
21 } |
21 } |
22 |
22 |
23 return NULL; |
23 return nullptr; |
24 } |
24 } |
25 |
25 |
26 // ============================================================================= |
26 // ============================================================================= |
27 // IO_OpenLDrawFile (str) |
27 // IO_OpenLDrawFile (str) |
28 // |
28 // |
32 logf ("Opening %s...\n", path.chars()); |
32 logf ("Opening %s...\n", path.chars()); |
33 |
33 |
34 FILE* fp = fopen (path.chars (), "r"); |
34 FILE* fp = fopen (path.chars (), "r"); |
35 |
35 |
36 if (!fp) { |
36 if (!fp) { |
|
37 for (ushort i = 0; i < g_zaFileLoadPaths.size(); ++i) { |
|
38 str zFilePath = str::mkfmt ("%s/%s", g_zaFileLoadPaths[i].chars(), path.chars()); |
|
39 printf ("try open %s\n", zFilePath.chars ()); |
|
40 fp = fopen (zFilePath.chars (), "r"); |
|
41 |
|
42 if (fp) |
|
43 break; |
|
44 } |
|
45 } |
|
46 |
|
47 if (!fp) { |
37 logf (LOG_Error, "Couldn't open %s: %s\n", path.chars (), strerror (errno)); |
48 logf (LOG_Error, "Couldn't open %s: %s\n", path.chars (), strerror (errno)); |
38 return NULL; |
49 return nullptr; |
39 } |
50 } |
40 |
51 |
41 OpenFile* load = new OpenFile; |
52 OpenFile* load = new OpenFile; |
42 ulong numWarnings = 0; |
53 ulong numWarnings = 0; |
43 |
54 |
71 numWarnings++; |
82 numWarnings++; |
72 } |
83 } |
73 } |
84 } |
74 |
85 |
75 g_LoadedFiles.push_back (load); |
86 g_LoadedFiles.push_back (load); |
76 g_CurrentFile = g_LoadedFiles[g_LoadedFiles.size() - 1]; |
|
77 |
|
78 // Recalculate the bounding box |
|
79 g_BBox.calculate(); |
|
80 |
|
81 // Rebuild the object tree view now. |
|
82 g_qWindow->buildObjList (); |
|
83 g_qWindow->setTitle (); |
|
84 |
87 |
85 logf (LOG_Success, "File %s parsed successfully (%lu warning%s).\n", |
88 logf (LOG_Success, "File %s parsed successfully (%lu warning%s).\n", |
86 path.chars(), numWarnings, PLURAL (numWarnings)); |
89 path.chars(), numWarnings, PLURAL (numWarnings)); |
87 |
90 |
88 return g_CurrentFile; |
91 return load; |
89 } |
92 } |
90 |
93 |
91 // ============================================================================= |
94 // ============================================================================= |
92 // isNumber (char*) |
95 // isNumber (char*) [static] |
93 // |
96 // |
94 // Returns whether a given string represents a floating point number |
97 // Returns whether a given string represents a floating point number |
95 // TODO: Does LDraw support scientific notation? |
98 // TODO: Does LDraw support scientific notation? |
96 // ============================================================================= |
99 // ============================================================================= |
97 static bool isNumber (char* sToken) { |
100 static bool isNumber (char* sToken) { |
144 if (!~zNoWhitespace) { |
147 if (!~zNoWhitespace) { |
145 // Line was empty, or only consisted of whitespace |
148 // Line was empty, or only consisted of whitespace |
146 return new LDEmpty; |
149 return new LDEmpty; |
147 } |
150 } |
148 |
151 |
149 char c = zLine[0]; |
|
150 vector<str> tokens = zLine / " "; |
152 vector<str> tokens = zLine / " "; |
|
153 |
|
154 // Rid leading all-whitespace tokens |
|
155 while (tokens.size() && !(~tokens[0])) |
|
156 tokens.erase (tokens.begin()); |
151 |
157 |
152 if (~tokens[0] != 1) |
158 if (~tokens[0] != 1) |
153 return new LDGibberish (zLine, "Illogical line code"); |
159 return new LDGibberish (zLine, "Illogical line code"); |
154 |
160 |
|
161 char const c = tokens[0][0]; |
155 switch (c - '0') { |
162 switch (c - '0') { |
156 case 0: |
163 case 0: |
157 { |
164 { |
158 // Comment |
165 // Comment |
159 LDComment* obj = new LDComment; |
166 LDComment* obj = new LDComment; |
161 return obj; |
168 return obj; |
162 } |
169 } |
163 |
170 |
164 case 1: |
171 case 1: |
165 { |
172 { |
|
173 // Subfile |
166 CHECK_TOKEN_COUNT (15) |
174 CHECK_TOKEN_COUNT (15) |
167 CHECK_TOKEN_NUMBERS (1, 13) |
175 CHECK_TOKEN_NUMBERS (1, 13) |
168 |
176 |
169 // Subfile |
177 #ifndef WIN32 |
|
178 tokens[14].replace ("\\", "/"); |
|
179 #endif // WIN32 |
|
180 |
|
181 // Try open the file |
|
182 OpenFile* pFile = IO_FindLoadedFile (tokens[14]); |
|
183 if (!pFile) |
|
184 pFile = IO_OpenLDrawFile (tokens[14]); |
|
185 |
|
186 // If we cannot open the file, mark it an error |
|
187 if (!pFile) |
|
188 return new LDGibberish (zLine, "Could not open referred file"); |
|
189 |
170 LDSubfile* obj = new LDSubfile; |
190 LDSubfile* obj = new LDSubfile; |
171 obj->dColor = atoi (tokens[1]); |
191 obj->dColor = atoi (tokens[1]); |
172 obj->vPosition = ParseVertex (zLine, 2); // 2 - 4 |
192 obj->vPosition = ParseVertex (zLine, 2); // 2 - 4 |
173 |
193 |
174 for (short i = 0; i < 9; ++i) |
194 for (short i = 0; i < 9; ++i) |
175 obj->faMatrix[i] = atof (tokens[i + 5]); // 5 - 13 |
195 obj->faMatrix[i] = atof (tokens[i + 5]); // 5 - 13 |
176 |
196 |
177 obj->zFileName = tokens[14]; |
197 obj->zFileName = tokens[14]; |
|
198 obj->pFile = pFile; |
178 return obj; |
199 return obj; |
179 } |
200 } |
180 |
201 |
181 case 2: |
202 case 2: |
182 { |
203 { |