Fri, 15 Mar 2013 20:39:29 +0200
don't crash if g_CurrentFile is null
0 | 1 | #include <vector> |
2 | ||
3 | #include "common.h" | |
4 | #include "io.h" | |
5 | #include "ldtypes.h" | |
6 | #include "misc.h" | |
7 | ||
8 | // ============================================================================= | |
9 | // IO_FindLoadedFile (str) | |
10 | // | |
11 | // Returns a pointer to the first found open file with the given name. | |
12 | // ============================================================================= | |
13 | OpenFile* IO_FindLoadedFile (str name) { | |
14 | OpenFile* file; | |
15 | ||
16 | for (uint i = 0; i < g_LoadedFiles.size(); i++) { | |
17 | file = g_LoadedFiles[i]; | |
18 | if (!file->filename.icompare (name)) | |
19 | return file; | |
20 | } | |
21 | ||
22 | return NULL; | |
23 | } | |
24 | ||
25 | // ============================================================================= | |
26 | // IO_ParseLDFile (str) | |
27 | // | |
28 | // Opens the given file and parses the LDraw code within. | |
29 | // ============================================================================= | |
30 | OpenFile* IO_ParseLDFile (str path) { | |
31 | FILE* fp = fopen (path.chars (), "r"); | |
32 | ||
33 | if (!fp) { | |
34 | printf ("Couldn't open %s!\n", path.chars ()); | |
35 | return NULL; | |
36 | } | |
37 | ||
38 | OpenFile* load = new OpenFile; | |
39 | load->filename = path; | |
40 | ||
41 | vector<str> lines; | |
42 | ||
43 | { | |
44 | char line[1024]; | |
45 | while (fgets (line, sizeof line, fp)) { | |
46 | // Trim the trailing newline | |
47 | str zLine = line; | |
48 | while (zLine[~zLine - 1] == '\n' || zLine[~zLine - 1] == '\r') | |
49 | zLine -= 1; | |
50 | ||
51 | lines.push_back (zLine); | |
52 | } | |
53 | } | |
54 | ||
55 | fclose (fp); | |
56 | ||
57 | for (ulong i = 0; i < lines.size(); ++i) | |
58 | load->objects.push_back (ParseLine (lines[i])); | |
59 | ||
60 | g_LoadedFiles.push_back (load); | |
61 | return g_LoadedFiles[g_LoadedFiles.size() - 1]; | |
62 | } | |
63 | ||
64 | // ============================================================================= | |
65 | // ParseLine (str) | |
66 | // | |
67 | // Parses a string line containing an LDraw object and returns the object parsed. | |
68 | // ============================================================================= | |
69 | LDObject* ParseLine (str zLine) { | |
70 | str zNoWhitespace = zLine; | |
71 | StripWhitespace (zNoWhitespace); | |
72 | if (!~zNoWhitespace) { | |
73 | // Line was empty, or only consisted of whitespace | |
74 | return new LDEmpty; | |
75 | } | |
76 | ||
77 | char c = zLine[0]; | |
78 | vector<str> tokens = zLine / " "; | |
79 | printf ("line: %s\n", zLine.chars()); | |
80 | ||
81 | switch (c - '0') { | |
82 | case 0: | |
83 | { | |
84 | // Comment | |
85 | LDComment* obj = new LDComment; | |
86 | obj->zText = zLine.substr (1, -1); | |
87 | printf ("\t-> comment (%s)\n", obj->zText.chars()); | |
88 | return obj; | |
89 | } | |
90 | ||
91 | case 1: | |
92 | { | |
93 | // Subfile | |
94 | LDSubfile* obj = new LDSubfile; | |
95 | obj->dColor = atoi (tokens[1]); | |
96 | obj->vPosition = ParseVertex (zLine, 2); // 2 - 4 | |
97 | ||
98 | for (short i = 0; i < 9; ++i) | |
99 | obj->faMatrix[i] = atof (tokens[i + 5]); // 5 - 13 | |
100 | ||
101 | obj->zFileName = tokens[14]; | |
102 | return obj; | |
103 | } | |
104 | ||
105 | case 2: | |
106 | { | |
107 | // Line | |
108 | LDLine* obj = new LDLine; | |
109 | obj->dColor = GetWordInt (zLine, 1); | |
110 | for (short i = 0; i < 2; ++i) | |
111 | obj->vaCoords[i] = ParseVertex (zLine, 2 + (i * 3)); // 2 - 7 | |
112 | return obj; | |
113 | } | |
114 | ||
115 | case 3: | |
116 | { | |
117 | // Triangle | |
118 | LDTriangle* obj = new LDTriangle; | |
119 | obj->dColor = GetWordInt (zLine, 1); | |
120 | ||
121 | for (short i = 0; i < 3; ++i) | |
122 | obj->vaCoords[i] = ParseVertex (zLine, 2 + (i * 3)); // 2 - 10 | |
123 | ||
124 | return obj; | |
125 | } | |
126 | ||
127 | case 4: | |
128 | { | |
129 | // Quadrilateral | |
130 | LDQuad* obj = new LDQuad; | |
131 | obj->dColor = GetWordInt (zLine, 1); | |
132 | ||
133 | for (short i = 0; i < 4; ++i) | |
134 | obj->vaCoords[i] = ParseVertex (zLine, 2 + (i * 3)); // 2 - 13 | |
135 | ||
136 | return obj; | |
137 | } | |
138 | ||
139 | case 5: | |
140 | { | |
141 | // Conditional line | |
142 | LDCondLine* obj = new LDCondLine; | |
143 | obj->dColor = GetWordInt (zLine, 1); | |
144 | ||
145 | for (short i = 0; i < 2; ++i) | |
146 | obj->vaCoords[i] = ParseVertex (zLine, 2 + (i * 3)); // 2 - 7 | |
147 | ||
148 | for (short i = 0; i < 2; ++i) | |
149 | obj->vaControl[i] = ParseVertex (zLine, 8 + (i * 3)); // 8 - 13 | |
150 | return obj; | |
151 | } | |
152 | ||
153 | default: | |
154 | { | |
155 | // Strange line we couldn't parse | |
156 | LDGibberish* obj = new LDGibberish; | |
157 | obj->zContent = zLine; | |
158 | return obj; | |
159 | } | |
160 | } | |
161 | } |