api with struct definitions in header file
[henge/webcc.git] / src / apc / ir.h
1 /*!@file
2 \brief Intermediate Representation (IR) between Directory Structure and Engine Grammar
3 \details The IR serves as a storage structure that is populated during the
4 parsing of the input directory structure. After parsing is complete,
5 the IR will be condensed (removed of excess allocated space) and then
6 output as the Engine Grammar. In this file we describe the semantic actions
7 that are called at each step, and the memory buffers that they populate.
8 See parser.y for the description on how the input grammar is constructed,
9 and where/when semantic actions are called.
10 TODO: or just write it here.
11 \author Jordan Lavatai
12 \date Aug 2016
13 ----------------------------------------------------------------------------*/
14
15
16 #include <stdint.h>
17
18 #define BUF_SIZE 256
19 #define MAX_SETS 256
20 #define MAX_ELES 256
21 #define MAX_QUADS 256
22 #define MAX_MODELS 256
23 #define MAX_POSTS 256
24 #define MAX_CLASS_DEPTH 256
25 #define MAX_CLASSES 256
26 #define MAX_FRAMES 256
27 #define PTRS_IN_PAGE 1024
28
29 /* General: All information from the directory structure is stored in */
30 /* five buffers that comprise the IR: cdat_buf, odat_buf, vdat_buf, ref_buf */
31 /* and link_buf. Each buf corresponds to the data structure that it stores. */
32 /* The storage techique for all bufs (except cdat) is the same. Each bufs member first */
33 /* populates its struct and then allocates the space for the next member */
34 /* and increments the buf index. This means that we have to allocate the */
35 /* very first member of each buf at ir_init(), so that we don't segfault */
36 /* as the first member attempts to access memory that its previous member */
37 /* didn't allocate (because it doesnt exist). We access the buf members */
38 /* through standard array indexing but conceal the tediousness of array */
39 /* indexing with macros. E.g. without macros, acessing an elements name */
40 /* member would look like (split up to not go over line char limit): */
41 /* (*cdat_stackp)->set_list[(*cdat_stackp)->num_sets] */
42 /* .ele_list[(*cdat_stackp)->set_list[(*cdat_stackp->num_sets)].num_ele].name */
43
44 /* For cdats in cdat_buf, we allocate the memory for a cdat once a cdat
45 is recognized in the grammar. Cdat_buf is different from the other bufs
46 because cdats have a root cdat that all cdats are a subclass of. This root
47 cdat can have a set_list like other cdats. */
48
49 /* Elements: Ele stands for element and has two representations in the IR. */
50 /* In the cdat_buf eles store their name, cdat_idx (their classes index in */
51 /* the cdat_buf) and the ref_id (refer to ref ). In the odat_buf, eles store */
52 /* their object data (odat). At output time, the ref_id is dereferenced to */
53 /* determine the elements odat which is the data that the engine expects */
54 extern struct cdat** cdat_stackp;
55 /* from an element. */
56
57
58 /* All bufs are of pointers to their respective structs. When a buf is full */
59 /* (number of data structs pointers >= max number of data struct pointers), */
60 /* we need to allocate a more pointers for that buf. Allocate these */
61 /* pointers a page at a time (1024 = Page bytes (4096)/bytes per pointer(4)) */
62
63 struct ele {
64 char name[32];
65 uint64_t ref_id;
66 int cdat_idx;
67 };
68
69 /* Sets: The set is similar to the ele, but it contains a list of its */
70 /* elements. The set is populated at parse time AFTER the elements are */
71 /* populated, due to the nature of bottom up parsing. */
72
73 struct set {
74 char name[32];
75 uint64_t ref_id;
76 int cdat_idx;
77 int num_ele;
78 struct ele ele_list[MAX_ELES];
79 };
80
81 /* Cdats: A cdat is a class data structure. Cdats serve as the central */
82 /* data types of the IR. At output, the cdat_buf is iterated through and */
83 /* each is written to the output file. For each cdat, sets and element */
84 /* ref_ids must be dereferenced to determine the odat information. Cdats */
85 /* contain pointers to their subclasses so that the relationship between */
86 /* classes can be determined, but the subclasses are not represented inside */
87 /* of the cdat itself but rather in the subsequent cdats in cdat_buf. We */
88 /* can determine the number of subclasses (the last index into cdat_buf */
89 /* that represents a subclass of some arbitrary cdat) each cdat has by */
90 /* incrementing num_classes during parse time. */
91 /* TODO: Should classes point to their parent class? */
92
93 struct cdat {
94 char name[32];
95 int idx;
96 int num_classes;
97 int num_sets;
98 struct cdat* class_list[MAX_CLASSES];
99 struct set set_list[MAX_SETS];
100 };
101
102 /* There are an unknown amount of cdats at compile time, so we maintain */
103 /* a cdat_buf of cdat pointers that can be expanded as needed. */
104
105 /* The cdat_stack is a stack pointers to cdat pointers, the top of which is
106 the cdat that is currently being parsed. Whenever a new cdat is recognized
107 by the grammar (CLOPEN), a cdat is pushed onto the cdat_stack, and we refer
108 to this cdat through the macro CURR_CDAT. By keeping a cdat_stack, we have
109 access to the current cdat so that the elements and sets can populate themselves
110 in the cdat accordingly. */
111
112
113 /* Refs: Each set/ele has a reference to its object data (odat) through a ref_id.
114 Ref_ids are unsigned 64 byte integers that map to the hex values RGBA. During
115 the construction of the directory structure, users can choose a RGBA value for
116 each object that any other object can refer to via links (see link). If a user
117 does not choose an RGBA value, then the object is given one from the system space.
118 We maintain a doubly linked list of refs in the ref_buf at parse time so that
119 links can be resolved after the parsing of the directory structure is complete.
120 For every 16th ref, we create a post so that we can reduce on the search time for
121 a random access. */
122
123 struct ref {
124 int type;
125 struct ref* nextref;
126 struct ref* lastref;
127 struct odat* odatp;
128 uint64_t ref_id; //0xFFFFFF->digit
129 };
130
131
132 /* Like the cdat_buf, ref_buf stores pointers to refs and can
133 increase in size */
134
135 /* posts for ref_buf */
136
137 /* Links: At parse time, a set/ele can include a link in their
138 grammar representation instead of the actual data and this signifies
139 to the APC that that set/ele wishes to use the data of another
140 set/ele, either its video data (vdat) or object data (odat). The link
141 itself contains the type of link it is, the ref_id OR name, and
142 which set/ele created the link. During parse time, links can be made
143 to o/vdats that have yet to be parsed. In order to accomodate for this,
144 we resolve all links AFTER parse time by iterating through the link_buf,
145 finding the ref_id that was stored for some object (if the ref_id exists),
146 and creating a relative pointer from the original object to the data that
147 was linked */
148
149 /* Svlinks stand for short vlink, which is a link to a vdat
150 TODO: diff btwn vlink*/
151
152 struct svlink {
153 uint64_t ref_id;
154 };
155
156 /* A vlink is what it sounds like, a link to a vdat
157 TODO: model link? */
158 struct vlink {
159 uint64_t ref_id;
160 char anim_name[32];
161 };
162
163 /* Olinks are links to odats */
164 struct olink {
165 uint64_t ref_id;
166 };
167
168 union link_t {
169 struct olink olink;
170 struct vlink vlink;
171 struct svlink svlink;
172 };
173
174 struct link {
175 int type; //1 = olink, 2 = vlink, 3 = svlink
176 union link_t link_t;
177 int cdat_idx;
178 int set_idx;
179 int ele_idx;
180 };
181
182 /* link_buf contains all the links that
183 we encountered during parse time that need
184 to be resolved to an offset at output time.
185 This does not include quad refs, because
186 those are already known to need to be resolved */
187
188
189 /* Odats: Odats consist of the object data necessary for
190 each object. Odats are sometimes referred to as archetypes
191 at compile-time, in order to distinguish the difference from
192 a runtime object and a compile-time object.
193 TODO: Need more info about objects at runtime, to described
194 the reasoning behind odat structure at compile-time*/
195
196 /* Each set has a quad_list or a list of quads. The quad_list
197 is the ? */
198 struct quad {
199 int x, y, z;
200 uint64_t ref_id; //rgba
201 };
202
203 struct root {
204 int x, y, z;
205 };
206
207 struct odat {
208 char name[32];
209 int vdat_id;
210 int cdat_idx;
211 int hitbox;
212 struct root root;
213 struct ref* refp; /* pointer to it's ref on ref_list */
214 int num_quads;
215 struct quad quad_list[MAX_QUADS];
216 };
217
218 struct odat* curr_set_odatp; //when a set has elements, insert_set() can no longer
219 //refer to its odat via curr_odat, so save the set odat.
220
221 /* A framesheet is a grouping of animation frames in
222 a single direction (N,W,S,E) */
223 struct framesheet {
224 int width;
225 int height;
226 int num_frames;
227 void* frames[MAX_FRAMES];
228 };
229
230 /* A model is a collection of framesheets for every
231 direction (N,W,S,E,NW,NE,SW,SE)*/
232 /* NAMED spritesheet */
233 struct model {
234 char name[32];
235 struct framesheet spritesheet[8]; //one for each
236 };
237
238 /* Vdat: Vdats are the video data of each object. They can not be
239 created as a stand alone object (because they consist solely
240 of animation information and not the skeleton on which the
241 animation manipulates). Vdats have a list of models for every
242 animation that the vdats odat can do for that vdat*/
243 struct vdat {
244 struct odat* creator; //pointer to odat that made this vdat
245 int num_models;
246 struct model model_list[MAX_MODELS];
247 };
248
249 /* Called after the cdat open operator has been recognized in grammar. Allocates
250 the space for a cdat on the cdat_buf, pushes that pointer onto
251 the cdat_stack */
252 void
253 push_cdat(char*);
254
255 /* Called after a cdat end operator has been recognized in grammar. Sets
256 top stack cdat ** to null and decrements stack pointer */
257 void
258 pop_cdat(void);
259
260 /* Called after an odat has been populated. Allocates memory for
261 the next odat. */
262
263 void
264 insert_set_label(char*, uint64_t);
265
266 /* Populate the sets representation in CURR_CDAT with a ref_id and insert a link
267 into the link_buf that will resolve the ref_id to an actual odat after parse time. */
268 void
269 insert_set_olink(uint64_t);
270
271 /* Put the vlink in the link_buf to be processed after parsetime */
272 void
273 insert_set_vlink(uint64_t, char*);
274
275 /* Put svlink in the link_buf to be processed after parsetime */
276 void
277 insert_set_svlink(uint64_t);
278
279 /* Called for every set reduction except for sets with olinks. Populates the
280 set data structures in the CDAT and in the ODAT. Uses the name and ref_id
281 from insert_set_label. Also inserts a ref into the ref_buf with the CURR_ODAT
282 pointer so that we can also resolve the odat from its ref_id. */
283 void
284 insert_set(void);
285
286 /* Insertion of eles is practically equivalent to how sets are inserted because both
287 share the same data type (ODAT). Like sets, eles have links, labels
288 and odats. Eles have the added notion of a parent set, and so must be inserted
289 into said parent set, but this is the only place they truly differ from sets. */
290
291 void
292 insert_set_vdatid(void);
293
294 void
295 insert_ele_label(char*, uint64_t);
296
297 /* Insert an ele olink into the CURR_ODAT */
298 void
299 insert_ele_olink(uint64_t);
300
301 /* Insert a ele vlink into CURR_ODAT*/
302 void
303 insert_ele_vlink(uint64_t, char*);
304
305 /* Inserts an ele short vlink into CURR_ODAT*/
306 void
307 insert_ele_svlink(uint64_t);
308
309 /* inserts ele into CURR_CLASS and CURR_ODAT */
310 void
311 insert_ele(void);
312
313 void
314 insert_ele_vdatid(void);
315
316 /* Inserts the hitbox into the CURR_ODAT */
317 void
318 insert_hitbox(int);
319
320 /* Inserts the root into the CURR_ODAT */
321 void
322 insert_root(int, int, int);
323
324 /* Inserts a quad into the CURR_ODAT */
325 void
326 insert_quad(int, int, int, uint64_t);
327
328 void
329 insert_model(void);
330
331 void
332 insert_framesheet(char, char*, uint64_t, int, int, int);
333
334 void
335 insert_frame_pointer(char, void*);
336
337 void
338 alloc_vdat(void);