Lexer actually lexes filenames now, and odats are made out of mapvariants
[henge/webcc.git] / src / apc / ir.c
old mode 100644 (file)
new mode 100755 (executable)
index 10aede8..5673d0c
-#include <errno.h>
-#include <ir.h>
-
-#define CURR_OBI (OB[obi])
-#define CURR_VBI (VB[vbi])
-#define CURR_CBI (CB[cbi])
-#define IS_SUBCLASS() (CB[cbi].num_subclasses)
-
-//TODO: label and vdat_id
-void
-insert_set()
-{
-  if(IS_SUBCLASS()) //if set is set of subclass
-    OB[obi].class_id = CB[cbi].subclass_list[subclass_index].label; //TODO: specify subclass other than label?
-  else
-    OB[obi].class_id = CB[cbi].label;
-
-  CB[cbi].set_list[set_index].odat_id = obi;
-  CB[cbi].set_list[set_index].parent_id = OB[obi].class_id;
-  //TODO: add ele_stack is created in element_list
-  //TODO: add odat
-
-}
-
-#define CURR_QUAD (OB[obi].ref_list[ref_index])
-void
-insert_ref(int x, int y, int z, int ref)
-{
-  CURR_QUAD.x = x;
-  CURR_QUAD.y = y;
-  CURR_QUAD.z = z;
-  CURR_QUAD.ref = ref;
-}
-
-
-//Insert element into OB and CB
-void
-insert_ele(char* label, int vdat_id)
-{
-
-
-  OB[obi].label = label;
-  OB[obi].vdat_id = vdat_id;
-  //TODO: check set_obi to see if set_map_data exists
-  OB[obi].num_ref = OB[set_obi].num_ref;
-  OB[obi].ref_list = OB[set_obi].ref_list;
-  OB[obi].class_id = cbi;
-
-  if(IS_SUBCLASS())
-    {
-      CB[cbi].subclass_list[subclass_index].set_list[set_index].ele_list[ele_index].odat_id = obi;
-      CB[cbi].subclass_list[subclass_index].set_list[set_index].ele_list[ele_index].parent_id = CB[cbi].subclass_list[subclass_index].set_index;
-    }
-  else
-    {
-      CB[cbi].set_list[set_index].ele_list[ele_index].odat_id = obi;
-      CB[cbi].set_list[set_index].ele_list[ele_index].parent_id = CB[cbi].set_index;
-    }
-
-  obi++;
-}
-
-
-/* fd could be a directory entry */
-int
-insert_fdat(char* label, char direction, int fd)
-{
-  VB[vbi].model_list[VB[vbi].len].label = label;
-  VB[vbi].model_list[VB[vbi].len].fdat_id[(int)direction] = fd;
-}
-
-void
-condense()
-{
-  FILE* vp, op, cp;
-  int v, m;
-  int num_models;
-
-  vp = fopen("vdat_output", w+);
-  if(!vp)
-    perror("vdat_output failed to open\n");
-
-  op = fopen("odat_output", w+);
-  if(!op)
-    perror("odat_output failed to open\n");
-
-  cp = fopen("cdat_output", w+);
-  if(!cp)
-    perror("cdat_output failed to open\n");
-
-
-
-  /* fwrite vdat */
-  for(v = 0; v <= vbi; v++)
-    {
-      num_models = VB[v].num_models; //data duplication for caching
-      for(m = 0; m <= num_models; m++)
-        {
-            
-        }
-    }
-
-  /* fwrite odat */
-  /* Convert ref_list to actual offset */
-
-  /* fwrite cdat */
-
-
-}
-
+/*!@file\r
+  \brief   IR Memory Implementation\r
+  \details Intermediary memory management\r
+  \author  Jordan Lavatai\r
+  \date    Aug 2016\r
+  ----------------------------------------------------------------------------*/\r
+#include <errno.h>\r
+#include <stdio.h>\r
+#include <unitypes.h> //uint8_t as a char\r
+#include <unistr.h> //u32_cpy\r
+#include <stdint.h> //uint64_t\r
+#include <stdlib.h> //malloc\r
+#include <apc/ir.h>\r
+\r
+//extern\r
+//scanner_scanpixels(int*, int);\r
+\r
+/* functions needed from irmem.c */\r
+extern\r
+void\r
+ir_init(void);\r
+\r
+extern\r
+struct cdat*\r
+alloc_cdat(void);\r
+\r
+extern\r
+struct odat*\r
+alloc_odat(void);\r
+\r
+extern\r
+struct vdat*\r
+alloc_vdat(void);\r
+\r
+extern\r
+void\r
+alloc_mdat(void);\r
+\r
+extern\r
+struct link*\r
+alloc_link(void);\r
+\r
+extern\r
+struct ref*\r
+alloc_ref(void);\r
+\r
+extern\r
+struct cdat*\r
+curr_cdat(void);\r
+\r
+extern\r
+struct odat*\r
+curr_odat(void);\r
+\r
+extern\r
+struct map*\r
+curr_map(void);\r
+\r
+extern\r
+struct map*\r
+alloc_map(void);\r
+\r
+extern\r
+struct vdat*\r
+curr_vdat(void);\r
+\r
+extern\r
+struct set*\r
+curr_set(void);\r
+\r
+extern\r
+struct ref*\r
+curr_ref(void);\r
+\r
+extern\r
+struct quad*\r
+curr_quad(void);\r
+\r
+extern\r
+struct model*\r
+curr_model(void);\r
+\r
+extern\r
+struct quad*\r
+curr_quad(void);\r
+\r
+/* struct definitions needed from irmem.c */\r
+extern int num_cdats;\r
+extern struct cdat** cdat_stackp;\r
+extern struct odat* curr_set_odatp;\r
+extern int ss_ref_id;\r
+\r
+extern int num_vdats;\r
+/* Dynamically allocate memory for a class data structure,\r
+   or cdat, after a class has been identified in a grammar.\r
+   We also create a stack of class pointers so that\r
+   we can access the cdat during processing of that\r
+   cdats sets and elements, a requirement because the\r
+   nature of recursive classes prevents us from accessing\r
+   the cdat based on the previous index into cdat_buf,\r
+   which is a list of all allocated cdats*/\r
+void\r
+push_cdat\r
+( uint8_t* name\r
+)\r
+{\r
+  struct cdat* curr_cdatp;\r
+\r
+  curr_cdatp = alloc_cdat();\r
+\r
+  u8_cpy(curr_cdatp->name, name, 32);\r
+  curr_cdatp->idx = num_cdats;\r
+\r
+  /* Set the cdat as a subclass of the previous cdat */\r
+  (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes] = curr_cdatp;\r
+  /* Push the cdat onto the cdat_stack */\r
+  *++cdat_stackp = curr_cdatp;\r
+\r
+}\r
+\r
+void\r
+pop_cdat\r
+()\r
+{\r
+  cdat_stackp--;\r
+}\r
+\r
+\r
+/* Every odat has a single map variant. We track the odats that have related map variants\r
+   by adding the name of the map to the end of the odat name. E.g. for an odat with name\r
+   A and map variants a,b,c we get A_a, A_b, A_c. We create new odats for each map variant*/\r
+void\r
+insert_map\r
+( uint8_t* name,\r
+  int height,\r
+  int width,\r
+  uint8_t* filepath\r
+)\r
+{\r
+  struct odat* curr_odatp;\r
+  int curr_odat_vdatid;\r
+\r
+  curr_odatp = curr_odat();\r
+\r
+  curr_odat_vdatid = curr_odatp->vdat_id;\r
+  \r
+\r
+   \r
+  if(curr_odatp->map.name[0] != 0) //odat already has a map so make a new odat\r
+    { curr_odatp = alloc_odat();\r
+      curr_odatp->vdat_id = curr_odat_vdatid;\r
+    }\r
+  /* Add a delimiter '_' in between odat name and map variant name */\r
+  u8_strcat(curr_odatp->map.name, (uint8_t*) '_'); \r
+  u8_strcat(curr_odatp->map.name, name);\r
+  \r
+  u8_strcpy(curr_odatp->map.filepath, filepath);\r
+  curr_odatp->map.height = height;\r
+  curr_odatp->map.width = width;\r
+  \r
+}\r
+  \r
+\r
+\r
+\r
+\r
+/* Called in the reduction of a set. While both odats (eles and sets)\r
+   have identical label terminals, we are unable to give a single grammatical rule\r
+   for both due to how we allocate odats in the odat buf. Due to the\r
+   nature of bottom up parsing, the set label is recognized first, and then the\r
+   sets elements are recognized. This means that after we have processed the sets elemenets,\r
+   the curr_odat is going to be the last element and NOT the set that was first allocated.\r
+   To get around this, we create a global variable set_odatp that will store the pointer\r
+   to the odat when it is first allocated (in insert_set_label()) so that insert_set() can\r
+   have access to it. Curr set points the sets representation in the cdat, curr_set_odatp\r
+   points to the sets representation as an odat*/\r
+\r
+void\r
+insert_set_label\r
+( uint8_t* name,\r
+  int ref_id\r
+)\r
+{\r
+\r
+  struct set* curr_setp;\r
+\r
+  curr_setp = curr_set();\r
+  curr_set_odatp = alloc_odat();\r
+\r
+  u8_cpy(curr_set_odatp->name, name, 32);\r
+  u8_cpy(curr_setp->name, name, 32);\r
+  curr_set_odatp->parent_odatp = NULL;\r
+  curr_set_odatp->map.name[0] = 0;\r
+\r
+  if(ref_id != -1)\r
+    { curr_set_odatp->ref_id = ref_id;\r
+      curr_setp->ref_id = ref_id;\r
+    }\r
+  else\r
+    { curr_setp->ref_id = ss_ref_id;\r
+      curr_set_odatp->ref_id = ss_ref_id++;\r
+    }\r
+\r
+}\r
+\r
+/* Inserting a olink instead of a set. Set is really just a placeholder\r
+   for another set. Allocate the memory for the set so taht it can be populated*/\r
+void\r
+insert_set_olink\r
+( int ref_id\r
+)\r
+{\r
+  struct set* curr_setp;\r
+\r
+  curr_setp = curr_set();\r
+\r
+  curr_setp->ref_id = ref_id;\r
+\r
+}\r
+\r
+void\r
+insert_set_vlink\r
+( int ref_id,\r
+  uint8_t* anim_name\r
+)\r
+{\r
+  struct cdat* curr_cdatp;\r
+  struct odat* curr_odatp;\r
+  struct link* curr_linkp;\r
+\r
+\r
+  curr_cdatp = curr_cdat();\r
+  curr_odatp = curr_odat();\r
+  curr_linkp = alloc_link();\r
+\r
+  /* Insert vlink into link_stack so that it gets processed at\r
+     output time */\r
+  curr_linkp->type = 2;\r
+  /* Store the target odat information*/\r
+  curr_linkp->link_t.vlink.ref_id = ref_id;\r
+  u8_cpy(curr_linkp->link_t.vlink.anim_name, anim_name, 32);\r
+  /* Store the linking odat/cdat information */\r
+  curr_linkp->classp = curr_cdatp;\r
+  curr_linkp->odatp = curr_odatp;\r
+  curr_linkp->set_idx = curr_cdatp->num_sets;\r
+  curr_linkp->ele_idx = -1;\r
+\r
+}\r
+\r
+/* Svlinks dont have animation names */\r
+void\r
+insert_set_svlink\r
+( int ref_id \r
+)\r
+{\r
+  struct cdat* curr_cdatp;\r
+  struct link* curr_linkp;\r
+\r
+  curr_cdatp = curr_cdat();\r
+  curr_linkp = alloc_link();\r
+\r
+  /* Insert svlink into link_stack so that it gets processed at\r
+     output time */\r
+  curr_linkp->type = 3;\r
+  curr_linkp->classp = curr_cdatp;\r
+  curr_linkp->set_idx = curr_cdatp->num_sets;\r
+  curr_linkp->ele_idx = -1;\r
+  curr_linkp->link_t.svlink.ref_id = ref_id;\r
+\r
+}\r
+\r
+/* At the point of reducing to a set, most of the\r
+   sets odat information has already been populated\r
+   during the reduction of its right hand side\r
+   non terminals (hitbox, root, quad_list). */\r
+void\r
+insert_set\r
+()\r
+{ int ref_id;\r
+  struct odat* curr_odatp;\r
+  struct cdat* curr_cdatp;\r
+  struct set* curr_setp;\r
+  struct ref* prev_refp;\r
+  struct ref* curr_refp;\r
+  struct vdat* curr_vdatp;\r
+\r
+  curr_odatp = curr_set_odatp; //allocated at insert_set_label\r
+  curr_cdatp = curr_cdat();\r
+  curr_setp = curr_set();\r
+  prev_refp = curr_ref();\r
+  curr_refp = alloc_ref();\r
+  curr_vdatp = curr_vdat();\r
+\r
+  curr_vdatp->creator = curr_set_odatp;\r
+\r
+  curr_setp->cdat_idx = curr_cdatp->idx; //does a set need its class idx?\r
+  u8_cpy(curr_setp->name, curr_odatp->name, 32);\r
+  curr_cdatp->num_sets++;\r
+\r
+  curr_odatp->cdat_idx = curr_cdatp->idx;\r
+  curr_odatp->refp = curr_refp;\r
+\r
+  ref_id = curr_setp->ref_id; // ref_id set by insert_set_label(name, ref_id)\r
+\r
+  curr_refp->ref_id = ref_id;\r
+  curr_refp->lastref = prev_refp;\r
+  curr_refp->odatp = curr_odatp;\r
+  prev_refp->nextref = curr_refp;\r
+\r
+\r
+\r
+}\r
+/* Created as a seperate function, instead of setting the ODATS vdat_id and\r
+   calling inc_vdat() inside of insert_set(), to account for the set reduction\r
+   where a vdat is not created (o/v/svlinks). */\r
+void\r
+insert_set_vdatid\r
+()\r
+{\r
+  struct vdat* curr_vdatp;\r
+\r
+  curr_vdatp = curr_vdat();\r
+\r
+  curr_set_odatp->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks\r
+  curr_set_odatp->vdatp = curr_vdatp;\r
+  curr_set_odatp = NULL; //This sets odat shouldnt be modified after populating odats vdat info\r
+}\r
+\r
+/* Populates the odat name and ref_id for odat, allocate the odat here for the rest of\r
+ the functions to use via curr_odat(). */\r
+void\r
+insert_ele_label\r
+( uint8_t* name,\r
+  int ref_id\r
+)\r
+{\r
+  struct odat* curr_odatp;\r
+\r
+  curr_odatp = alloc_odat();\r
+\r
+  u8_cpy(curr_odatp->name, name, 32);\r
+  curr_odatp->map.name[0] = 0;\r
+\r
+  if(ref_id != -1)\r
+    curr_odatp->ref_id = ref_id;\r
+  else\r
+    curr_odatp->ref_id = ss_ref_id++;\r
+\r
+}\r
+\r
+/* We don't make an odat here, at output time we will resolve\r
+   the ref_id to the corresponding odat. */\r
+void\r
+insert_ele_olink\r
+( int ref_id\r
+)\r
+{\r
+  /* Do nothing because we already know the ref_id that\r
+     the odat needs for this element (in the quad_file) */\r
+}\r
+\r
+void\r
+insert_ele_vlink\r
+( int ref_id,\r
+  uint8_t* anim_name\r
+)\r
+{\r
+  struct cdat* curr_cdatp;\r
+  struct set* curr_setp;\r
+  struct link* curr_linkp;\r
+\r
+  curr_cdatp = curr_cdat();\r
+  curr_setp = curr_set();\r
+  curr_linkp = alloc_link();\r
+\r
+  /* Insert vlink into link_stack so that it gets processed at\r
+     output time */\r
+  curr_linkp->classp = curr_cdatp;\r
+  curr_linkp->type = 2;\r
+  curr_linkp->set_idx = curr_cdatp->num_sets;\r
+  //curr_linkp->ele_idx = curr_setp->num_ele;\r
+  curr_linkp->link_t.vlink.ref_id = ref_id;\r
+  u8_cpy(curr_linkp->link_t.vlink.anim_name, anim_name, 32);\r
+\r
+}\r
+\r
+void\r
+insert_ele_svlink\r
+( int ref_id\r
+)\r
+{\r
+  struct cdat* curr_cdatp;\r
+  struct set* curr_setp;\r
+  struct link* curr_linkp;\r
+\r
+  curr_cdatp = curr_cdat();\r
+  curr_setp = curr_set();\r
+  curr_linkp = alloc_link();\r
+\r
+  curr_linkp->classp = curr_cdatp;\r
+  curr_linkp->type = 3;\r
+\r
+  //curr_linkp->ele_idx = curr_setp->num_ele;\r
+  curr_linkp->link_t.svlink.ref_id = ref_id;\r
+\r
+\r
+}\r
+\r
+//Insert element into odat_buf and cdatpages\r
+void\r
+insert_ele()\r
+{\r
+  int ref_id;\r
+  struct cdat* curr_cdatp;\r
+  struct odat* curr_odatp;\r
+  struct vdat* curr_vdatp;\r
+  struct set* curr_setp;\r
+  struct ele* curr_elep;\r
+  struct ref* curr_refp;\r
+  struct ref* prev_refp;\r
+\r
+\r
+  curr_odatp = curr_odat(); //malloced @ insert_ele_label\r
+  curr_vdatp = curr_vdat();\r
+  curr_setp = curr_set();\r
+  prev_refp = curr_ref();\r
+  curr_refp = alloc_ref();\r
+\r
+  curr_vdatp->creator = curr_odatp;\r
+\r
+  /* Populate odat for ele */\r
+  curr_odatp->cdat_idx = curr_cdatp->idx;\r
+  curr_odatp->refp = curr_refp;\r
+  curr_odatp->parent_odatp = curr_set_odatp;\r
+\r
+  ref_id = curr_odatp->ref_id;\r
+\r
+  curr_refp->ref_id = ref_id;\r
+  curr_refp->lastref = prev_refp;\r
+  curr_refp->odatp = curr_odatp;\r
+  prev_refp->nextref = curr_refp;\r
+\r
+}\r
+\r
+void\r
+insert_ele_vdatid\r
+()\r
+{ struct odat* curr_odatp;\r
+  curr_odatp = curr_odat();\r
+  curr_odatp->vdat_id = num_vdats;\r
+}\r
+\r
+void\r
+insert_vdat\r
+(uint8_t* filename, int height, int width, uint8_t* filepath)\r
+{\r
+  struct vdat* curr_vdatp;\r
+  int filename_len, filepath_len;\r
+\r
+  curr_vdatp = alloc_vdat();\r
+\r
+  u8_strcpy(curr_vdatp->filename, filename);\r
+  u8_strcpy(curr_vdatp->filepath, filepath);\r
+  curr_vdatp->height = height;\r
+  curr_vdatp->width = width;\r
+  curr_vdatp->creator = curr_odat();\r
+  \r
+}\r
+\r
+\r
+  \r
+\r
+/* void */\r
+/* insert_quad */\r
+/* ( int x, int y, int z, int ref_id */\r
+/* ) */\r
+/* { */\r
+/*   struct quad* curr_quadp; */\r
+\r
+/*   curr_quadp = curr_quad(); */\r
+\r
+/*   curr_quadp->x = x; */\r
+/*   curr_quadp->y = y; */\r
+/*   curr_quadp->z = z; */\r
+/*   curr_quadp->ref_id = ref_id; */\r
+  \r
+\r
+\r
+/* } */\r
+\r
+/* /\* serting the hitbox into the set */\r
+/*    odat. Elements that don't have */\r
+/*    a hitbox will use the sets root. *\/ */\r
+/* void */\r
+/* insert_hitbox */\r
+/* ( int hitbox */\r
+/* ) */\r
+/* { struct odat* curr_odatp; */\r
+\r
+/*   curr_odatp = curr_odat(); */\r
+/*   curr_odatp->hitbox = hitbox; */\r
+/* } */\r
+\r
+/* /\* Inserting the root into the set */\r
+/*    odat. Elements that don't have */\r
+/*    a root will use the sets root. *\/ */\r
+/* void */\r
+/* insert_root */\r
+/* ( int x, */\r
+/*   int y, */\r
+/*   int z */\r
+/* ) */\r
+/* { struct odat* curr_odatp; */\r
+\r
+/*   curr_odatp = curr_odat(); */\r
+/*   curr_odatp->root.x = x; */\r
+/*   curr_odatp->root.y = y; */\r
+/*   curr_odatp->root.z = z; */\r
+/* } */\r
+\r
+\r
+\r
+/* void */\r
+/* insert_framesheet */\r
+/* ( uint8_t direction, */\r
+/*   uint8_t* name, */\r
+/*   int ref_id, */\r
+/*   int height , */\r
+/*   int width, */\r
+/*   int num_frames */\r
+/* ) */\r
+/* { struct vdat* curr_vdatp; */\r
+/*   struct model* curr_modelp; */\r
+\r
+/*   curr_vdatp = curr_vdat(); */\r
+/*   curr_modelp = curr_model(); */\r
+\r
+/*   curr_modelp->spritesheet[(int)direction].height = height; */\r
+/*   curr_modelp->spritesheet[(int)direction].width = width; */\r
+/*   curr_modelp->spritesheet[(int)direction].num_frames = num_frames; */\r
+/*   curr_vdatp->num_models++; */\r
+/* } */\r
+\r
+/* void */\r
+/* insert_frame_pointer */\r
+/* ( uint8_t direction, */\r
+/*   void* frame */\r
+/* ) */\r
+/* { struct model* curr_modelp; */\r
+\r
+/*   curr_modelp = curr_model(); */\r
+\r
+/*   curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; */\r
+/* } */\r
+\r