void templateAppInit(int width, int height)
{
    GFX_start();
    glViewport(0.0f, 0.0f, width, height);
    GFX_set_matrix_mode(PROJECTION_MATRIX);
    GFX_load_identity();
    GFX_set_perspective(45.0f, (float)width / (float)height, 0.1f, 100.0f, -90.0f);
    obj = OBJ_load(OBJ_FILE, 1);
    unsigned int i = 0;
    while (i != obj->n_objmesh) {
	OBJ_build_mesh(obj, i);
	OBJ_free_mesh_vertex_data(obj, i);
	++i;
    }
    i = 0;
    while (i != obj->n_texture) {
	OBJ_build_texture(obj, i, obj->texture_path, TEXTURE_MIPMAP, TEXTURE_FILTER_2X, 0.0f);
	++i;
    }
    i = 0;
    while (i != obj->n_objmaterial) {
	MEMORY *fragment_shader = mopen((char *)"fragment.glsl", 1);
	MEMORY *vertex_shader = mopen((char *)"vertex.glsl", 1);
	OBJMATERIAL *objmaterial = &obj->objmaterial[i];
	OBJ_build_material(obj, i, NULL);
	if (objmaterial->dissolve == 1.0f)
	    minsert(fragment_shader, (char *)"#define SOLID_OBJECT\n", 0);
	else if (!objmaterial->dissolve)
	    minsert(fragment_shader, (char *)"#define ALPHA_TESTED_OBJECT\n", 0);
	else
	    minsert(fragment_shader, (char *)"#define TRANSPARENT_OBJECT\n", 0);
	if (objmaterial->illumination_model) {
	    minsert(vertex_shader, (char *)"#define LIGHTING_SHADER\n", 0);
	    minsert(fragment_shader, (char *)"#define LIGHTING_SHADER\n", 0);
	}
	objmaterial->program = PROGRAM_init(objmaterial->name);
	objmaterial->program->vertex_shader = SHADER_init((char *)"vertex", GL_VERTEX_SHADER);
	objmaterial->program->fragment_shader = SHADER_init((char *)"fragment", GL_FRAGMENT_SHADER);
	SHADER_compile(objmaterial->program->vertex_shader, (char *)vertex_shader->buffer, 1);
	SHADER_compile(objmaterial->program->fragment_shader, (char *)fragment_shader->buffer, 1);
	PROGRAM_set_bind_attrib_location_callback(objmaterial->program, program_bind_attrib_location);
	PROGRAM_link(objmaterial->program, 1);
	OBJ_set_draw_callback_material(obj, i, material_draw_callback);
	mclose(fragment_shader);
	mclose(vertex_shader);
	++i;
    }
}
Esempio n. 2
0
void *malloc(size_t size)
{
    register PACKET *current;
    register size_t  newsize;
    register size_t  oldsize;

    if (size <= 0) return NULL;

    if (check_alloc_size(size) == 0) return 0;

    if (need_mem_init)  minit();

    _lock();

    /*-----------------------------------------------------------------------*/
    /* SIZE IS CALCULATED BY FIRST ALIGNING (SIZE + BLOCK OVERHEAD) TO THE   */
    /* REQUIRED MINIMUM ALIGNMENT AND THEN SUBTRACTING THE BLOCK OVERHEAD.   */
    /*-----------------------------------------------------------------------*/
    newsize = _M_RNDUP((size + _M_BLOCK_OVERHEAD), _M_MIN_ALN) - 
	                                                    _M_BLOCK_OVERHEAD;

    current = sys_free;

    /*-----------------------------------------------------------------------*/
    /* SCAN THROUGH FREE LIST FOR PACKET LARGE ENOUGH TO CONTAIN PACKET      */
    /*-----------------------------------------------------------------------*/
    while (current && current->packet_size < newsize)
       current = current->size_ptr;

    if (!current)
    {
	_unlock();
	return NULL;
    }
    
    oldsize = current->packet_size;	    /* REMEMBER OLD SIZE	     */
    mremove(current);		            /* REMOVE PACKET FROM FREE LIST  */

    /*-----------------------------------------------------------------------*/
    /* IF PACKET IS LARGER THAN NEEDED, FREE EXTRA SPACE AT END	             */
    /* BY INSERTING REMAINING SPACE INTO FREE LIST.			     */
    /*-----------------------------------------------------------------------*/
    if (oldsize - newsize >= (_M_MIN_BLOCK + _M_BLOCK_OVERHEAD))
    {
       register PACKET *next = 
	       (PACKET *) ((char *) current + _M_BLOCK_OVERHEAD + newsize);
 
       next->packet_size    = oldsize - newsize - _M_BLOCK_OVERHEAD;
       minsert(next);
       current->packet_size = newsize;
    }

   current->packet_size |= _M_BLOCK_USED;
   _unlock();
   return (char *)current + _M_BLOCK_OVERHEAD;
}
Esempio n. 3
0
/*
 * Takes the value "val" and inserts it into the tree.
 * Grows at the root if necessary.
 */
void insert(float val, tree * root) {
   node * n = root->root;
   if (n->left || n->right) { //If I am a 2 or 3 node w/ children.
      if (val < n->ldata) {
         minsert(val, n->left, left);
      }
      else if (n->middle != NULL && val < n->rdata) {
         minsert(val, n->middle, middle);
      }
      else {
         minsert(val, n->right, right);
      }
   }
   //The root is a temp-4 node w/children, grow a new root and right node.
   if (n->is4node && n->mid_right) {
      //Create new root, have old root's parent ptr point to it.
      //Make sure to clear out the middle data as well.
      node * new_root = modmem(GET, NULL);
      n->parent = new_root;
      new_root->ldata = n->mdata;
      new_root->is2node = true;
      n->mdata = 0;
      //Have the new root point to the old one.
      new_root->left = n;
      //Create the new right branch of the tree as well. Migrate 
      //the proper pointers over (including the parent pointers!)
      node * new_right = modmem(GET, NULL);
      new_root->right = new_right;
      new_right->parent = new_root;
      new_right->ldata = n->rdata;
      new_right->is2node = true;
      n->rdata = 0;
      n->is4node = false;
      n->is3node = false;
      n->is2node = true;
      new_right->left = n->mid_right;
      new_right->right = n->right;
      n->right = n->middle;
      n->middle = NULL;
      n->mid_right = NULL;
      //Have grandchild parent pointers point to new right node.
      new_right->left->parent = new_right;
      new_right->right->parent = new_right;
      root->root = new_root;
   }
   //Initial case of inserting data: a full root node with no children.
   else if (n->is3node && n->left == NULL) {
      node * new_root = modmem(GET, NULL);
      new_root->left = n;
      swapsort(val, n);
      node * new_right = modmem(GET, NULL);
      n->parent = new_root;
      new_right->parent = new_root;
      new_root->ldata = n->mdata;
      new_root->is2node = true;
      n->mdata = 0;
      new_root->right = new_right;
      new_right->ldata = n->rdata;
      new_right->is2node = true;
      n->rdata = 0;
      n->is3node = false;
      n->is2node = true;
      root->root = new_root;
   }
   else if (n->is2node != true && n->left == NULL) {
      n->ldata = val;
      n->is2node = true;
   }
   else if (n->is2node && n->left == NULL) {
      simpleswap(val, n);
   }

}
Esempio n. 4
0
//Helper function for insert. Does all the heavy lifting save for growth
//at the root node, which is reserved for insert itself.
static void minsert(float val, node * n, direction dir) {
   //Shameless copy from insert. The logic is identical...
   if (n->left || n->right) { //If I am a 2 or 3 node w/ children.
      if (val < n->ldata) {
         minsert(val, n->left, left);
      }
      else if (n->middle != NULL && val < n->rdata) {
         minsert(val, n->middle, middle);
      }
      else {
         minsert(val, n->right, right);
      }
   }
   else if (n->is2node && n->left == NULL) { //I am a leaf 2-node
      simpleswap(val, n);
   }
   else { //I am a leaf 3-node and I'm ready to overflow!
      swapsort(val, n);
      n->is4node = true;
   }
   //The node has overflowed! Split accordingly.
   if (n->is4node) {
      node * parent = n->parent;
      float promoted_val = n->mdata;
      if (parent->is2node) { //Parent is a 2-node
         simpleswap(promoted_val, parent);
         node * new_node = modmem(GET, NULL);
         new_node->parent = parent;
         parent->middle = new_node;
         switch(dir) {
            case left:
               new_node->ldata = n->rdata;
               //Transfer pointers unconditionally, since it wouldn't hurt
               //either way
               new_node->left = n->mid_right;
               new_node->right = n->right;
               if (new_node->left != NULL) {
                  new_node->left->parent = new_node;
                  new_node->right->parent = new_node;
               }
               n->right = n->middle;
               break;
            case right:
               new_node->ldata = n->ldata;
               n->ldata = n->rdata;
               //As above, unconditional pointer xfer.
               new_node->left = n->left;
               new_node->right = n->middle;
               if (new_node->left != NULL) {
                  new_node->left->parent = new_node;
                  new_node->right->parent = new_node;
               }
               n->left = n->mid_right;
               break;
         }
         n->mid_right = NULL;
         n->middle = NULL;
         n->rdata = 0;
         new_node->is2node = true;
      }
      else { //Parent is a 3-node.
         swapsort(promoted_val, parent);
         parent->is4node = true;
         node * new_node = modmem(GET, NULL);
         new_node->parent = parent;
         switch(dir) {
            case left: //Rearrange for left

               parent->mid_right = parent->middle;
               parent->middle = new_node;
               new_node->ldata = n->rdata;
               new_node->left = n->mid_right;
               new_node->right = n->right;
               if (new_node->left != NULL) {
                  new_node->left->parent = new_node;
                  new_node->right->parent = new_node;
               }
               n->right = n->middle;
               break;
            case middle: //Rearrange for middle
               parent->mid_right = new_node;
               new_node->ldata = n->rdata;
               new_node->left = n->mid_right;
               new_node->right = n->right;
               if (new_node->left != NULL) {
                  new_node->left->parent = new_node;
                  new_node->right->parent = new_node;
               }
               n->right = n->middle;
               break;
            case right: //Rearrange for right
               parent->mid_right = new_node;
               new_node->ldata = n->ldata;
               n->ldata = n->rdata;
               new_node->left = n->left;
               new_node->right = n->middle;
               if (new_node->left != NULL) {
                  new_node->left->parent = new_node;
                  new_node->right->parent = new_node;
               }
               n->left = n->mid_right;
               break;
         }
         n->rdata = 0;
         n->middle = NULL;
         n->mid_right = NULL;
         new_node->is2node = true;
      }
      n->mdata = 0; //Clean up temp value storage.
      n->is2node = true;
      n->is3node = false;
      n->is4node = false;
   }
}
Esempio n. 5
0
void *memalign(size_t alignment, size_t size)
{
    PACKET *aln_packet;
    PACKET *current;
    size_t  newsize;
    size_t  aln_mask = alignment - 1;
    int     leftover = -1;
    char   *aln_start;
    char   *un_aln_start;
 
    if (size <= 0) return NULL;

    if (check_alloc_size(size) == 0) return NULL;
      
    /*--------------------------------------------------------------------*/
    /* IF ALIGNMENT IS NOT A POWER OF TWO OR IS LESS THAN THE DEFAULT     */
    /* ALIGNMENT OF MALLOC, THEN SIMPLY RETURN WHAT MALLOC RETURNS.       */
    /*--------------------------------------------------------------------*/
    if (alignment <= _M_MIN_ALN || (alignment & (alignment-1)))
	  return malloc(size);

    if (need_mem_init)  minit();

    _lock();

    newsize = _M_RNDUP((size + _M_BLOCK_OVERHEAD), _M_MIN_ALN) - 
	                                                    _M_BLOCK_OVERHEAD;

    current = sys_free;

    /*-----------------------------------------------------------------------*/
    /* SCAN THROUGH FREE LIST FOR PACKET LARGE ENOUGH TO CONTAIN ALIGNED     */
    /* PACKET                                                                */
    /*-----------------------------------------------------------------------*/
    for ( ; current ; current = current->size_ptr)
    {
       un_aln_start = (char *) current + _M_BLOCK_OVERHEAD;
       /*--------------------------------------------------------------------*/
       /* IT IS POSSIBLE THAT WE COULD OVERFLOW THE size_t TYPE BELOW, BUT   */
       /* ADDING A CHECK HERE WOULD LIKELY BE A SIGNIFICANT PERFORMANCE HIT. */
       /*--------------------------------------------------------------------*/
       aln_start    = (char *)(((size_t) un_aln_start + aln_mask) & ~aln_mask);
       leftover     = un_aln_start + current->packet_size - aln_start -newsize;

       /*--------------------------------------------------------------------*/
       /* MAKE SURE THAT THE PRE BLOCK SPACE IS LARGE ENOUGH TO BE A BLOCK   */
       /* OF ITS OWN.                                                        */
       /*--------------------------------------------------------------------*/
       for ( ; (char *)current+sizeof(PACKET) > aln_start-_M_BLOCK_OVERHEAD ;
	       aln_start += alignment, leftover -= alignment);

       if (leftover >= 0) break;
    }

    if (!current) { _unlock(); return NULL; }

    /*-----------------------------------------------------------------------*/
    /* SETUP NEW PACKET FOR ALIGNED MEMORY.                                  */
    /*-----------------------------------------------------------------------*/
    mremove(current);
    aln_packet              = (PACKET *) (aln_start - _M_BLOCK_OVERHEAD);
    aln_packet->packet_size = newsize | _M_BLOCK_USED;

    /*-----------------------------------------------------------------------*/
    /* HANDLE THE FREE SPACE BEFORE THE ALIGNED BLOCK.  IF THE ORIGINAL      */
    /* BLOCK WAS ALIGNED, THERE WON'T BE FREE SPACE BEFORE THE ALIGNED BLOCK.*/
    /*-----------------------------------------------------------------------*/
    if (aln_start != un_aln_start) 
    {
	current->packet_size = (char *)aln_packet - un_aln_start;
	minsert(current);
    }

    /*-----------------------------------------------------------------------*/
    /* HANDLE THE FREE SPACE AFTER THE ALIGNED BLOCK. IF IT IS LARGE ENOUGH  */
    /* TO BE A BLOCK OF ITS OWN, THEN MAKE IT ONE, OTHERWISE ADD THE         */
    /* LEFTOVER SIZE TO THE ALIGNED BLOCK.                                   */ 
    /*-----------------------------------------------------------------------*/ 
    if (leftover >= _M_BLOCK_OVERHEAD + _M_MIN_BLOCK)
    {
       register PACKET *next = (PACKET *) (aln_start + newsize);
       next->packet_size     = leftover - _M_BLOCK_OVERHEAD;
       minsert(next);
    }
    else aln_packet->packet_size += leftover;

    _unlock();
    return aln_start;
}
Esempio n. 6
0
void free(void *packet)
{
    register char   *ptr = (char *)packet;
    register PACKET *last;	      /* POINT TO PREVIOUS PACKET            */
    register PACKET *current;	      /* POINTER TO THIS PACKET              */
    register PACKET *next;	      /* POINTER TO NEXT PACKET              */

    if (ptr == NULL) return;

    last = next = NULL;		      /* INITIALIZE POINTERS                 */
    ptr -= _M_BLOCK_OVERHEAD;	      /* ADJUST POINT TO BEGINNING OF PACKET */

    if (need_mem_init)  minit();

    _lock();

    current = _M_SYS_FIRST;

    /*-----------------------------------------------------------------------*/
    /* SEARCH FOR THE POINTER IN THE PACKET POINTED TO			     */
    /*-----------------------------------------------------------------------*/
    while (current < (PACKET *) ptr)
    {
        last    = current;
        current = (PACKET *)((char *)current + 
		  (current->packet_size & ~_M_BLOCK_USED) + _M_BLOCK_OVERHEAD);
    }

    /*-----------------------------------------------------------------------*/
    /* CHECK FOR POINTER OR PACKET ERRORS.				     */
    /*-----------------------------------------------------------------------*/
    if ((current != (PACKET *)ptr) || (!(current->packet_size & _M_BLOCK_USED)))
    {
	 _unlock();
         return;
    }

    current->packet_size &= ~_M_BLOCK_USED;   /* MARK PACKET AS FREE */

    /*-----------------------------------------------------------------------*/
    /* GET POINTER TO NEXT PACKET IN MEMORY, IF ANY.			     */
    /*-----------------------------------------------------------------------*/
    next = (PACKET *)((char *)current + _M_BLOCK_OVERHEAD + 
	                                             current->packet_size);
    if (next > (PACKET *) &heap_mem[_memory_size - _M_BLOCK_OVERHEAD]) 
	next = NULL;

    if (last && last->packet_size & _M_BLOCK_USED) last = NULL;
    if (next && next->packet_size & _M_BLOCK_USED) next = NULL;

    /*-----------------------------------------------------------------------*/
    /* ATTEMPT TO COLLESCE THE THREE PACKETS (PREVIOUS, CURRENT, NEXT)	     */
    /*-----------------------------------------------------------------------*/
    if (last && next)
    {
	mremove(last);
	mremove(next);
	last->packet_size += current->packet_size + next->packet_size + 
			     _M_BLOCK_OVERHEAD + _M_BLOCK_OVERHEAD;
	minsert(last);
	_unlock();
	return;
    }

    /*-----------------------------------------------------------------------*/
    /* ATTEMPT TO COLLESCE THE CURRENT WITH LAST PACKET. (LAST, CURRENT)     */
    /*-----------------------------------------------------------------------*/
    if (last)
    {
	mremove(last);
	last->packet_size += current->packet_size + _M_BLOCK_OVERHEAD;
	minsert(last);
	_unlock();
	return;
    }

    /*-----------------------------------------------------------------------*/
    /* ATTEMPT TO COLLESCE THE CURRENT WITH NEXT PACKET. (CURRENT, NEXT)     */
    /*-----------------------------------------------------------------------*/
    if (next)
    {
       mremove(next);
       current->packet_size += next->packet_size + _M_BLOCK_OVERHEAD;
       minsert(current);
	_unlock();
       return;
    }

    /*-----------------------------------------------------------------------*/
    /* NO COLLESCENCE POSSIBLE, JUST INSERT THIS PACKET INTO LIST	     */
    /*-----------------------------------------------------------------------*/
    minsert(current);
    _unlock();
}
Esempio n. 7
0
void *realloc(void *packet, size_t size)
{
    register char    *pptr    = (char *) packet - _M_BLOCK_OVERHEAD;
    register size_t   newsize;
    register size_t   oldsize;

    if (packet == 0)  return malloc(size);
    if (size   == 0)  { free(packet); return NULL; }

    if (check_alloc_size(size) == 0) return 0;

    if (need_mem_init)  minit();

    _lock();

    /*-----------------------------------------------------------------------*/
    /* NEW SIZE IS CALCULATED BY FIRST ALIGNING (SIZE+BLOCK OVERHEAD) TO THE */
    /* REQUIRED MINIMUM ALIGNMENT AND THEN SUBTRACTING THE BLOCK OVERHEAD.   */
    /*-----------------------------------------------------------------------*/
    newsize = _M_RNDUP((size + _M_BLOCK_OVERHEAD), _M_MIN_ALN) - 
	                                                    _M_BLOCK_OVERHEAD;

    oldsize = ((PACKET *)pptr)->packet_size;

    if (!(oldsize & _M_BLOCK_USED)) { _unlock(); return NULL; }
    if (newsize == --oldsize)       { _unlock(); return packet; }

    /*-----------------------------------------------------------------------*/
    /* IF NEW SIZE IS LESS THAN CURRENT SIZE, TRUNCATE PACKET AND RETURN END */
    /* TO FREE LIST		                                             */
    /*-----------------------------------------------------------------------*/
    if (newsize < oldsize)
    {
       if (oldsize - newsize < (_M_MIN_BLOCK + _M_BLOCK_OVERHEAD))
       {
	  _unlock();
	  return packet;
       }
       ((PACKET *)pptr)->packet_size = newsize | _M_BLOCK_USED;

       oldsize -= newsize + _M_BLOCK_OVERHEAD;
       pptr    += newsize + _M_BLOCK_OVERHEAD;
       ((PACKET *)pptr)->packet_size = oldsize | _M_BLOCK_USED;
       free(pptr + _M_BLOCK_OVERHEAD);
       _unlock();
       return packet;
    }

    /*-----------------------------------------------------------------------*/
    /* IF NEW SIZE IS BIGGER THAN CURRENT PACKET,		             */
    /*	1) CHECK NEXT PACKET IN LIST, SEE IF PACKET CAN BE EXPANDED          */
    /*	2) IF NOT, MOVE PACKET TO NEW LOCATION. 		             */
    /*-----------------------------------------------------------------------*/
    else
    {
	PACKET *next = (PACKET *)(pptr + oldsize + _M_BLOCK_OVERHEAD);
	int     temp;

	if (((char *)next < &heap_mem[_memory_size - _M_BLOCK_OVERHEAD]) &&
           (!(next->packet_size & _M_BLOCK_USED))                        &&
           ((temp = oldsize + next->packet_size +_M_BLOCK_OVERHEAD - newsize) 
	                                                      >= 0))
	{
	    mremove(next);
	    if (temp < _M_MIN_BLOCK + _M_BLOCK_OVERHEAD)
	    {
	       ((PACKET *)pptr)->packet_size = newsize + temp | _M_BLOCK_USED;
	       _unlock();
	       return packet;
	    }

	    ((PACKET *)pptr)->packet_size = newsize | _M_BLOCK_USED;
	    pptr += newsize + _M_BLOCK_OVERHEAD;
	    ((PACKET *)pptr)->packet_size = temp - _M_BLOCK_OVERHEAD;
	    minsert((PACKET *)pptr);
	    _unlock();
	    return packet;
	}
	else
	{
            /*---------------------------------------------------------------*/
	    /* ALLOCATE NEW PACKET AND MOVE DATA INTO IT. 	             */
            /*---------------------------------------------------------------*/
	    register char *new_packet = (char *)malloc(size);
	    if (new_packet == 0) { _unlock(); return NULL; }
	    memcpy(new_packet, packet, oldsize);
	    free(packet);
	    _unlock();
	    return new_packet;
	}
    }
}