421f6e5d4f8f0ef0ec0b7fc2e86006b6ffcbbb59
[henge/webcc.git] / src / apc / ir.c
1 /*!@file
2 \brief IR Memory Implementation
3 \details Intermediary memory management
4 \author Jordan Lavatai
5 \date Aug 2016
6 ----------------------------------------------------------------------------*/
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdint.h> //uint64_t
10 #include <string.h> //memmove
11 #include <stdlib.h> //malloc
12 #include <apc/ir.h>
13
14
15
16 /* functions needed from irmem.c */
17 extern
18 void
19 ir_init(void);
20
21 extern
22 struct cdat*
23 alloc_cdat(void);
24
25 extern
26 struct odat*
27 alloc_odat(void);
28
29 extern
30 void
31 alloc_vdat(void);
32
33 extern
34 struct link*
35 alloc_link(void);
36
37 extern
38 struct ref*
39 alloc_ref(void);
40
41 extern
42 struct cdat*
43 curr_cdat(void);
44
45 extern
46 struct odat*
47 curr_odat(void);
48
49 extern
50 struct vdat*
51 curr_vdat(void);
52
53 extern
54 struct set*
55 curr_set(void);
56
57 extern
58 struct ref*
59 curr_ref(void);
60
61 extern
62 struct quad*
63 curr_quad(void);
64
65 extern
66 struct model*
67 curr_model(void);
68
69 /* struct definitions needed from irmem.c */
70 extern int num_cdats;
71 extern struct cdat** cdat_stackp;
72 extern struct odat* curr_set_odatp;
73 extern uint64_t ss_ref_id;
74
75 extern int num_vdats;
76 /* Dynamically allocate memory for a class data structure,
77 or cdat, after a class has been identified in a grammar.
78 We also create a stack of class pointers so that
79 we can access the cdat during processing of that
80 cdats sets and elements, a requirement because the
81 nature of recursive classes prevents us from accessing
82 the cdat based on the previous index into cdat_buf,
83 which is a list of all allocated cdats*/
84 void
85 push_cdat
86 ( char* name
87 )
88 {
89 struct cdat* curr_cdatp;
90
91 curr_cdatp = alloc_cdat();
92
93 memmove(curr_cdatp->name, name, 32);
94 curr_cdatp->idx = num_cdats;
95
96 /* Set the cdat as a subclass of the previous cdat */
97 (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes] = curr_cdatp;
98 /* Push the cdat onto the cdat_stack */
99 *++cdat_stackp = curr_cdatp;
100
101 }
102
103 void
104 pop_cdat
105 ()
106 {
107 cdat_stackp--;
108 }
109
110 /* Called in the reduction of a set. While both odats (eles and sets)
111 have identical label terminals, we are unable to give a single grammatical rule
112 for both due to how we allocate odats in the odat buf. Due to the
113 nature of bottom up parsing, the set label is recognized first, and then the
114 sets elements are recognized. This means that after we have processed the sets elemenets,
115 the curr_odat is going to be the last element and NOT the set that was first allocated.
116 To get around this, we create a global variable set_odatp that will store the pointer
117 to the odat when it is first allocated (in insert_set_label()) so that insert_set() can
118 have access to it. Curr set points the sets representation in the cdat, curr_set_odatp
119 points to the sets representation as an odat*/
120
121 void
122 insert_set_label
123 ( char* name,
124 uint64_t ref_id
125 )
126 {
127
128 struct set* curr_setp;
129
130 curr_setp = curr_set();
131 curr_set_odatp = alloc_odat();
132
133 memmove(curr_set_odatp->name, name, 32);
134 memmove(curr_setp->name, name, 32);
135
136 if(ref_id != -1)
137 { curr_set_odatp->ref_id = ref_id;
138 curr_setp->ref_id = ref_id;
139 }
140 else
141 { curr_setp->ref_id = ss_ref_id;
142 curr_set_odatp->ref_id = ss_ref_id++;
143 }
144
145 }
146
147 /* Inserting a olink instead of a set. Set is really just a placeholder
148 for another set. Allocate the memory for the set so taht it can be populated*/
149 void
150 insert_set_olink
151 ( uint64_t ref_id
152 )
153 {
154 struct set* curr_setp;
155
156 curr_setp = curr_set();
157
158 curr_setp->ref_id = ref_id;
159
160 }
161
162 void
163 insert_set_vlink
164 ( uint64_t ref_id,
165 char* anim_name
166 )
167 {
168 struct cdat* curr_cdatp;
169 struct odat* curr_odatp;
170 struct link* curr_linkp;
171
172
173 curr_cdatp = curr_cdat();
174 curr_odatp = curr_odat();
175 curr_linkp = alloc_link();
176
177 /* Insert vlink into link_stack so that it gets processed at
178 output time */
179 curr_linkp->type = 2;
180 /* Store the target odat information*/
181 curr_linkp->link_t.vlink.ref_id = ref_id;
182 memmove(curr_linkp->link_t.vlink.anim_name, anim_name, 32);
183 /* Store the linking odat/cdat information */
184 curr_linkp->classp = curr_cdatp;
185 curr_linkp->odatp = curr_odatp;
186 curr_linkp->set_idx = curr_cdatp->num_sets;
187 curr_linkp->ele_idx = -1;
188
189 }
190
191 /* Svlinks dont have animation names */
192 void
193 insert_set_svlink
194 ( uint64_t ref_id
195 )
196 {
197 struct cdat* curr_cdatp;
198 struct link* curr_linkp;
199
200 curr_cdatp = curr_cdat();
201 curr_linkp = alloc_link();
202
203 /* Insert svlink into link_stack so that it gets processed at
204 output time */
205 curr_linkp->type = 3;
206 curr_linkp->classp = curr_cdatp;
207 curr_linkp->set_idx = curr_cdatp->num_sets;
208 curr_linkp->ele_idx = -1;
209 curr_linkp->link_t.svlink.ref_id = ref_id;
210
211 }
212
213 /* At the point of reducing to a set, most of the
214 sets odat information has already been populated
215 during the reduction of its right hand side
216 non terminals (hitbox, root, quad_list). */
217 void
218 insert_set
219 ()
220 { uint64_t ref_id;
221 struct odat* curr_odatp;
222 struct cdat* curr_cdatp;
223 struct set* curr_setp;
224 struct ref* prev_refp;
225 struct ref* curr_refp;
226 struct vdat* curr_vdatp;
227
228 curr_odatp = curr_set_odatp; //allocated at insert_set_label, preserved in global space
229 curr_cdatp = curr_cdat();
230 curr_setp = curr_set();
231 prev_refp = curr_ref();
232 curr_refp = alloc_ref();
233 curr_vdatp = curr_vdat();
234
235 curr_vdatp->creator = curr_set_odatp;
236
237 curr_setp->cdat_idx = curr_cdatp->idx; //does a set need its class idx?
238 memmove(curr_setp->name, curr_odatp->name, 32);
239 curr_cdatp->num_sets++;
240
241 curr_odatp->cdat_idx = curr_cdatp->idx;
242 curr_odatp->refp = curr_refp;
243
244 ref_id = curr_setp->ref_id; // ref_id set by insert_set_label(name, ref_id)
245
246 curr_refp->ref_id = ref_id;
247 curr_refp->lastref = prev_refp;
248 curr_refp->odatp = curr_odatp;
249 prev_refp->nextref = curr_refp;
250
251
252
253 }
254 /* Created as a seperate function, instead of setting the ODATS vdat_id and
255 calling inc_vdat() inside of insert_set(), to account for the set reduction
256 where a vdat is not created (o/v/svlinks). */
257 void
258 insert_set_vdatid
259 ()
260 {
261 struct vdat* curr_vdatp;
262
263 curr_vdatp = curr_vdat();
264
265 curr_set_odatp->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks
266 curr_set_odatp->vdatp = curr_vdatp;
267 curr_set_odatp = NULL; //This sets odat shouldnt be modified after populating odats vdat info
268 }
269
270 /* Populates the odat name and ref_id for odat, allocate the odat here for the rest of
271 the functions to use via curr_odat(). */
272 void
273 insert_ele_label
274 ( char* name,
275 uint64_t ref_id
276 )
277 {
278 struct odat* curr_odatp;
279
280 curr_odatp = alloc_odat();
281
282 memmove(curr_odatp->name, name, 32);
283
284 if(ref_id != -1)
285 curr_odatp->ref_id = ref_id;
286 else
287 curr_odatp->ref_id = ss_ref_id++;
288
289 }
290
291 /* We don't make an odat here, at output time we will resolve
292 the ref_id to the corresponding odat. */
293 void
294 insert_ele_olink
295 ( uint64_t ref_id
296 )
297 {
298 /* Do nothing because we already know the ref_id that
299 the odat needs for this element (in the quad_file) */
300 }
301
302 void
303 insert_ele_vlink
304 ( uint64_t ref_id,
305 char* anim_name
306 )
307 {
308 struct cdat* curr_cdatp;
309 struct set* curr_setp;
310 struct link* curr_linkp;
311
312 curr_cdatp = curr_cdat();
313 curr_setp = curr_set();
314 curr_linkp = alloc_link();
315
316 /* Insert vlink into link_stack so that it gets processed at
317 output time */
318 curr_linkp->classp = curr_cdatp;
319 curr_linkp->type = 2;
320 curr_linkp->set_idx = curr_cdatp->num_sets;
321 //curr_linkp->ele_idx = curr_setp->num_ele;
322 curr_linkp->link_t.vlink.ref_id = ref_id;
323 memmove(curr_linkp->link_t.vlink.anim_name, anim_name, 32);
324
325 }
326
327 void
328 insert_ele_svlink
329 ( uint64_t ref_id
330 )
331 {
332 struct cdat* curr_cdatp;
333 struct set* curr_setp;
334 struct link* curr_linkp;
335
336 curr_cdatp = curr_cdat();
337 curr_setp = curr_set();
338 curr_linkp = alloc_link();
339
340 curr_linkp->classp = curr_cdatp;
341 curr_linkp->type = 3;
342
343 //curr_linkp->ele_idx = curr_setp->num_ele;
344 curr_linkp->link_t.svlink.ref_id = ref_id;
345
346
347 }
348
349 //Insert element into odat_buf and cdatpages
350 void
351 insert_ele()
352 {
353 uint64_t ref_id;
354 struct cdat* curr_cdatp;
355 struct odat* curr_odatp;
356 struct vdat* curr_vdatp;
357 struct set* curr_setp;
358 struct ele* curr_elep;
359 struct ref* curr_refp;
360 struct ref* prev_refp;
361
362
363 curr_odatp = curr_odat(); //malloced @ insert_ele_label
364 curr_vdatp = curr_vdat();
365 curr_setp = curr_set();
366 prev_refp = curr_ref();
367 curr_refp = alloc_ref();
368
369 curr_vdatp->creator = curr_odatp;
370
371 /* Populate odat for ele */
372 curr_odatp->cdat_idx = curr_cdatp->idx;
373 curr_odatp->refp = curr_refp;
374
375 ref_id = curr_odatp->ref_id;
376
377 curr_refp->ref_id = ref_id;
378 curr_refp->lastref = prev_refp;
379 curr_refp->odatp = curr_odatp;
380 prev_refp->nextref = curr_refp;
381
382 }
383
384 void
385 insert_ele_vdatid
386 ()
387 { struct odat* curr_odatp;
388 curr_odatp = curr_odat();
389 curr_odatp->vdat_id = num_vdats;
390 }
391
392 void
393 insert_quad
394 ( void* quad_filep
395 )
396 {
397 struct odat* curr_odatp;
398
399 curr_odatp->quad_filep = quad_filep;
400 }
401
402 /* Inserting the hitbox into the set
403 odat. Elements that don't have
404 a hitbox will use the sets root. */
405 void
406 insert_hitbox
407 ( int hitbox
408 )
409 { struct odat* curr_odatp;
410
411 curr_odatp = curr_odat();
412 curr_odatp->hitbox = hitbox;
413 }
414
415 /* Inserting the root into the set
416 odat. Elements that don't have
417 a root will use the sets root. */
418 void
419 insert_root
420 ( int x,
421 int y,
422 int z
423 )
424 { struct odat* curr_odatp;
425
426 curr_odatp = curr_odat();
427 curr_odatp->root.x = x;
428 curr_odatp->root.y = y;
429 curr_odatp->root.z = z;
430 }
431
432
433 void
434 insert_framesheet
435 ( char direction,
436 char* name,
437 uint64_t ref_id,
438 int height ,
439 int width,
440 int num_frames
441 )
442 { struct vdat* curr_vdatp;
443 struct model* curr_modelp;
444
445 curr_vdatp = curr_vdat();
446 curr_modelp = curr_model();
447
448 curr_modelp->spritesheet[(int)direction].height = height;
449 curr_modelp->spritesheet[(int)direction].width = width;
450 curr_modelp->spritesheet[(int)direction].num_frames = num_frames;
451 curr_vdatp->num_models++;
452 }
453
454 void
455 insert_frame_pointer
456 ( char direction,
457 void* frame
458 )
459 { struct model* curr_modelp;
460
461 curr_modelp = curr_model();
462
463 curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame;
464 }
465