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