Exemple #1
0
// return is only good thru end of level.
// using fgetc() since it auto-converts CRLF pairs
char *ReadTextFile(char *filename) {

	FILE		*fp;
	char		*filestring = NULL;
	long int	i = 0;
	struct stat mstat;

	if (stat(filename, &mstat) != 0)
		return NULL;

	while (true) {
		fp = fopen(filename, "rb");
		if (!fp) break;

		i = ReadFromFile(fp, NULL);
		filestring = V_Malloc(i, TAG_LEVEL);
		if (!filestring)
			break;

		fseek(fp, 0, SEEK_SET);
		ReadFromFile(fp, filestring);

		break;
	}

	if (fp) fclose(fp);

	return(filestring);	// return new text
}
Exemple #2
0
//=========================================
// Push Node to front of the linked list
//=========================================
void Push(node_t *Node) {
stack_t *STK;

  STK=(stack_t *)V_Malloc(sizeof(stack_t), TAG_LEVEL);
  STK->StackPtr=Stack; // NULL at start
  STK->NodePtr=Node;   // Tie the Node
  Stack=STK;           // Set to start of Stack
}
Exemple #3
0
/*
==================== 
  IMG_compileGLImage()
==================== 
*/
int IMG_compileGLImage (image_t *img)
{
    int i, j, rgba_sz;

    byte *compiled;

	if ( img->bpp != 1 && img->bpp != 3 && img->bpp != 4 ) {
        //Com_Error ( ERR_FATAL, "only handling 24 or 32-bit right now");
        Com_Printf( "%s", "only handling 8, 24 or 32-bit right now" );
		return -1;
	}

	if ( img->bpp == 1 ) {
		rgba_sz = img->numbytes;
	} else if ( img->bpp == 3 ) {
	    rgba_sz = img->numbytes * 4;
	    rgba_sz /= 3;
    } else {
        rgba_sz = img->numbytes;
    }

    rgba_sz += 16; // pad

    compiled = (byte *) V_Malloc ( rgba_sz );
    memset (compiled, 0, rgba_sz);

    if ( img->bpp == 1 ) {
		for ( i = 0; i < (int)img->numbytes; i++ ) {
			compiled[ i ] = img->data[ i ];
		}
	} else if (img->bpp == 3) {
        for (i = 0, j = 0; i < (int)img->numbytes; i += img->bpp, j+=4)
        {
            if (img->data[i] || img->data[i+1] || img->data[i+2]) {
                compiled[j+2] = img->data[i+0];
                compiled[j+1] = img->data[i+1];
                compiled[j+0] = img->data[i+2];
                compiled[j+3] = 255;
            }
        }
    } else {
        for (i = 0, j = 0; i < (int)img->numbytes; i += img->bpp, j+=4)
        {
            compiled[j+2] = img->data[i+0];
            compiled[j+1] = img->data[i+1];
            compiled[j+0] = img->data[i+2];
            compiled[j+3] = img->data[i+3];
        }
    }
    img->compiled = compiled;

	return 0;
}
Exemple #4
0
image_t * IMG_readfileTGA (const char *fullpath, image_t *img)
{
    //FILE *fp;
    byte tga_header_buf[18];
    int sz;
 //   int i,j;
    filehandle_t fh;

    if ( ! FS_FOpenReadOnly( fullpath, &fh ) ) 
        Com_Error ( ERR_FATAL, "couldn't open file: %s\n", fullpath);

    if ( ! FS_Read( (void *)tga_header_buf, 18, fh ) )
        Com_Error ( ERR_FATAL, "couldn't read file: %s\n", fullpath);

    IMG_copyHeaderTGA (&img->header.tga, tga_header_buf);

	sz = FS_GetFileSize( fh );
	if ( sz < 0 )
		Com_Error( ERR_FATAL, "returned bad size, file not found?\n" );

	img->data = (byte *)V_Malloc( sz - 18 );

	img->numbytes = FS_ReadAll( img->data, fh );
    if ( !img->numbytes )
        Com_Error ( ERR_FATAL, "error reading rest of file: %s\n", fullpath);
	if ( img->numbytes != sz-18 )
		Com_Error ( ERR_WARNING, "sizes don't match %i %i\n", img->numbytes, sz );

    img->type = IMG_TGA;
    
    img->h = img->header.tga.height;
    img->w = img->header.tga.width;
    img->bpp = img->header.tga.pixel_size / 8;

	FS_FClose( fh );

	return img;
}
Exemple #5
0
//=========================================
int FindPath(vec3_t start, vec3_t destination) {
node_t *StartNode;
node_t *BestNode;
node_t *tNode;
int NodeNumD;
int NodeNumS;
int g,c,i;
float h;
vec3_t tstart,tdest;

  VectorCopy(start,tstart);
  VectorCopy(destination,tdest);

  // Get NodeNum of start vector
  NodeNumS=GetNodeNum(tstart);
  if (NodeNumS==-1) {
	  //gi.dprintf("bad nodenum at start\n");
  return 0; // ERROR
  }

  // Get NodeNum of destination vector
  NodeNumD=GetNodeNum(tdest);
  if (NodeNumD==-1) 
  {
	 // gi.dprintf("bad nondenum at end\n");
	  return 0; // ERROR
  }

  // Allocate OPEN/CLOSED list pointers..
  OPEN=(node_t *)V_Malloc(sizeof(node_t), TAG_LEVEL);
 // OPEN=(node_t *)malloc(sizeof(node_t));
  OPEN->NextNode=NULL;

  CLOSED=(node_t *)V_Malloc(sizeof(node_t), TAG_LEVEL);
  //CLOSED=(node_t *)malloc(sizeof(node_t));
  CLOSED->NextNode=NULL;

  //================================================
  // This is our very first NODE!  Our start vector
  //================================================
  StartNode=(node_t *)V_Malloc(sizeof(node_t), TAG_LEVEL);
  //StartNode=(node_t *)malloc(sizeof(node_t));
  StartNode->nodenum=NodeNumS; // starting position nodenum
  StartNode->g=g=0; // we haven't gone anywhere yet
  StartNode->h=h=distance(start, destination);//fabs(vDiff(start,destination)); // calculate remaining distance (heuristic estimate) GHz - changed to fabs()
  StartNode->f=g+h; // total cost from start to finish
  for (c=0;c < NUMCHILDS;c++)
    StartNode->Child[c]=NULL; // no children for search pattern yet
  StartNode->NextNode=NULL;
  StartNode->PrevNode=NULL;
  //================================================

  // next node in open list points to our starting node
  OPEN->NextNode=BestNode=StartNode; // First node on OPEN list..

  //GHz - need to free these nodes too!
  //NodeList[NodeCount++] = OPEN;
//  NodeList[NodeCount++] = CLOSED;
  NodeCount+=2;

  for (;;) {
    tNode=BestNode; // Save last valid node
    BestNode=(node_t *)NextBestNode(NodeNumS, NodeNumD); // Get next node from OPEN list
    if (!BestNode) {
		//gi.dprintf("ran out of nodes to search\n");
		return 0;//GHz
     // BestNode=tNode; // Last valid node..
     // break;
	}

    if (BestNode->nodenum==NodeNumD) break;// we there yet?
    ComputeSuccessors(BestNode,NodeNumD);} // Search from here..

  //================================================

     RemoveDuplicates(BestNode, CLOSED);//FIXME: move this up before the start==end crash check

 // gi.dprintf("%d: processed %d nodes\n", level.framenum,NodeCount);
  if (BestNode==StartNode) {  // Start==End??
    FreeStack(StartNode);//FIXME: may cause crash
	//gi.dprintf("start==end\n");
    return 0; }

    


  //gi.dprintf("Start = %d End = %d\n", NodeNumS, NodeNumD);
 // gi.dprintf("Printing tNode (in reverse):\n");
 // PrintNodes(BestNode, true);
 // gi.dprintf("Printing OPEN list:\n");
  //PrintNodes(OPEN, false);
  //gi.dprintf("Printing CLOSED list:\n");
 // PrintNodes(CLOSED, false);

BestNode->NextNode=NULL; // Must tie this off!


  // How many nodes we got?
   tNode=BestNode;
  i=0;
  while (tNode) {
    i++; // How many nodes?
    tNode=tNode->PrevNode; }

  if (i <= 2) { // Only nodes are Start and End??
    FreeStack(BestNode);//FIXME: may cause crash
	//gi.dprintf("only start and end nodes\n");
    return 0; }

  // Let's allocate our own stuff...

 
  //CLOSED->NextNode = NULL;//GHz - only needs to be null if we are using freestack()
  numpts=i;

  //GHz - free old memory
  //V_Free(Waypoint);

  Waypoint=(int *)V_Malloc(numpts*sizeof(int), TAG_LEVEL);
  //Waypoint=(int *)malloc(numpts*sizeof(int));

  // Now, we have to assign the nodenum's along
  // this path in reverse order because that is
  // the way the A* algorithm finishes its search.
  // The last best node it visited was the END!
  // So, we copy them over in reverse.. No biggy..

  tNode=BestNode;
  while (BestNode) {
    Waypoint[--i]=BestNode->nodenum;//GHz: how/when is this freed?
    BestNode=BestNode->PrevNode; }

// NOTE: At this point, if our numpts returned is not
// zero, then a path has been found!  To follow this
// path we simply follow node[Waypoint[i]].origin
// because Waypoint array is filled with indexes into
// our node[i] array of valid vectors in the map..
// We did it!!  Now free the stack and exit..

  //================================================

  //++++++++++ GHz NOTES +++++++++++++
  // FreeStack() is flawed because the lists have nodes that point to nodes on other lists
  // so if you free one list, then the next list will crash when it encounters a node with
  // an invalid pointer (node was freed in last list)
  //++++++++++++++++++++++++++++++++++

  FreeStack(tNode); // Release ALL resources!!

  //GHz: cleanup test/debugging
  //for (i=0;i<NodeCount;i++)
  //{
//	  V_Free(NodeList[i]);
 // }
 // OPEN = NULL;
  //CLOSED = NULL;
  NodeCount = 0;

  //TODO: performance... cpu usage is still very high
  //TODO: grid editor, save grid to disk
  //TODO: need some way of handling manually edited grid
  // because NextNode() only searches within a specific 32x32 pattern


 // gi.dprintf("%d: found %d\n",level.framenum,numpts);

  return (numpts);
}
Exemple #6
0
//===========================================
// Successor Nodes all pushed onto OPEN list
//===========================================
void GetSuccessorNodes(node_t *StartNode, int NodeNumS, int NodeNumD) {
node_t *Old,*Successor;
node_t *tNode1,*tNode2;
int g,c;
float h;

// NOTE: NodeNumS is the index of a node that was found by the node searching routine
  //================================
  // Has NodeNumS been Searched yet?
  //================================
	// see if this node is already on the OPEN list
	Old = CheckLIST(OPEN, NodeNumS);
	if (Old) 
	{ 
		// node was found on the OPEN list
		// this means the node was found before (as a child of another node)
		// but not yet searched (as a parent node)
		for (c = 0; c < NUMCHILDS; c++)
		{
			// break on the first available child slot of StartNode
			if (!StartNode->Child[c]) 
				break;
		}

		// if we found an empty child slot, use it, otherwise use the last one
		StartNode->Child[((c < NUMCHILDS)?c:(NUMCHILDS-1))] = Old;

		// have we gone farther with this node than StartNode?
		if (StartNode->g + 1 < Old->g) 
		{ 
			Old->g = g = StartNode->g + 1; // make node one step beyond StartNode	
			Old->f = g + Old->h; // update total cost
			Old->PrevNode = StartNode; // reverse link to StartNode
		}
		return; 
	}

  //==================================
  // Has NodeNumS been searched yet?
  //==================================
  Old=CheckLIST(CLOSED,NodeNumS);
  if (Old!=NULL) {
	  // node has been searched before
    for (c=0;c < NUMCHILDS;c++)
      if (StartNode->Child[c]==NULL) break;
    StartNode->Child[((c < NUMCHILDS)?c:(NUMCHILDS-1))]=Old;
    if (StartNode->g+1 < Old->g) {
      Old->g=g=StartNode->g+1;
      Old->f=g+Old->h;
      Old->PrevNode=StartNode;
      PropagateDown(Old); }
    return; }

  //=======================================
  // It is NOT on the OPEN or CLOSED List!!
  //=======================================
  // Make Successor a Child of StartNode
  //=======================================
  //Successor=(node_t *)malloc(sizeof(node_t));
  Successor=(node_t *)V_Malloc(sizeof(node_t), TAG_LEVEL);
  Successor->nodenum=NodeNumS;
  Successor->g=g=StartNode->g+1;

  //GHz - track node memory use so we can free this later
//	NodeList[NodeCount++] = Successor;
  NodeCount++;

// NOTE: the heuristic estimate of the remaining path from this node
// to the destination node is given by the difference between the 2
// vectors.  You can come up with your own estimate..

  Successor->h=h=distance(pathnode[NodeNumS], pathnode[NodeNumD]);//fabs(vDiff(node[NodeNumS].origin,node[NodeNumD].origin));//GHz - changed to fabs()
  Successor->f=g+h;
  Successor->PrevNode=StartNode; // reverse link to StartNode
  Successor->NextNode=NULL;
  // make all child links of new Successor node NULL
  for (c=0;c < NUMCHILDS;c++)
    Successor->Child[c]=NULL;

  for (c=0;c < NUMCHILDS;c++)
    if (StartNode->Child[c]==NULL) break; // Find first empty Child[] of StartNode
  StartNode->Child[((c < NUMCHILDS)?c:(NUMCHILDS-1))]=Successor; // make Successor a child of StartNode

  //=================================
  // Insert Successor into OPEN List
  //=================================
  tNode1=OPEN;
  tNode2=OPEN->NextNode;
  // find node in OPEN list with f-cost greater than Successor node
  while (tNode2 && (tNode2->f < Successor->f)) {
    tNode1=tNode2;
    tNode2=tNode2->NextNode; }
  Successor->NextNode=tNode2;
  tNode1->NextNode=Successor;
  //gi.dprintf("added node %d to the OPEN list\n", Successor->nodenum);
}
Exemple #7
0
image_t *IMG_readfileBMP ( const char *fullpath, image_t *img )
{
    FILE *fp;
    int i, bytesread;
    int datasize;
    int infosize;
    byte buf[128];
	bmp_header_t *h;
    bmp_info_t *info;
    register byte temp;

    // open
    if ((fp = fopen(fullpath, "rb")) == NULL) {
        Com_Printf("cant read %s \n", fullpath);
        return NULL;
    }

    // read header straight in
    if (fread(buf, 14, 1, fp) == NULL) {
        Com_Printf("error reading header\n");
        return NULL;
    }

	h = &img->header.bmp;
	h->magic = (unsigned short) *(unsigned short *)buf;
	h->totalBytes = (unsigned int) *(unsigned int *)&buf[2];
	h->reserved1 = h->reserved2 = 0;
	h->dataOffsetBytes = (unsigned int) *(unsigned int *)&buf[10];

    // check magic number
    if (img->header.bmp.magic != 19778) {
        Com_Printf("Not a Bitmap File\n");
        return NULL;
    }

    // read info portion of header
    memset( buf , 0, sizeof(buf) );
    //infosize = img->header.bmp.dataOffsetBytes - sizeof(bmp_header_t);
    infosize = img->header.bmp.dataOffsetBytes - 14;

    info = (bmp_info_t *) buf;

    if (fread(info, infosize, 1, fp) == NULL) {
        Com_Printf("error reading bitmap info from file\n");
        return NULL;
    } 

    // record info
    if (! IMG_getBmpInfo(img, info) ) {
        return NULL;
    }
    
    // malloc data portion
	
	//   2 bytes padding (0x00, 0x00) on the end of bmp
    datasize = img->header.bmp.totalBytes - img->header.bmp.dataOffsetBytes;
    img->data = (byte *) V_Malloc (datasize);
    memset (img->data, 0, datasize);
    img->numbytes = datasize;
	img->type = IMG_BMP;

    // get data
    fseek ( fp, img->header.bmp.dataOffsetBytes, SEEK_SET );

	/*
    do {
        i = fread(img->data, 1, 1024, fp);
        bytesread += i;
        if (i <= 0)
            break;
    } while(1);
	*/

	// read image data
    bytesread = 0;
	while ((i = fread(&img->data[bytesread], 1, 8192, fp)) > 0)
		bytesread += i;

    if ( bytesread != datasize ) {
        Com_Printf("bitmap: incorrect datasize: %d\n", bytesread);
        return NULL;
    }

    return img;
}
Exemple #8
0
// tex and mask should already be created.  we'll re-read in each of their
//  file's data, and then create another image and GL compile it, storing
//  all of the new info to ip.  Only supports textures that have an equal
//  width and height value, and that value must be a powerof 2.
int IMG_CombineTextureMaskPow2( image_t *tex, image_t *mask, image_t **ipp ) {
    int i;
	
	if ( !( tex && mask && ipp ) )
		return -1;
	if ( tex->h != tex->w || mask->h != mask->w )
		return -2;
	if ( !ISPOWEROF2( tex->h ) )
		return -3;

	// alloc the image
    image_t *ip = (image_t *) V_Malloc( sizeof(image_t) );
	image_t *m_ip = (image_t*) V_Malloc( sizeof(image_t) );
	memset( ip, 0, sizeof(image_t) );
	memset( m_ip, 0, sizeof(image_t) );

	char path[ 512 ];
	snprintf( path, 512, "%s\\%s", fs_gamepath->string(), tex->syspath );

    // read the TEX file 
    switch ( tex->type ) {
    case IMG_TGA:
        IMG_readfileTGA( path, ip ); 
        break;
    case IMG_BMP:
        IMG_readfileBMP( path, ip );
        break;
    case IMG_GIF:
    case IMG_JPG:
    case IMG_PCX:
    case IMG_PPM:
    case IMG_PNG:
    default:
        Com_Printf( "image type: %s not supported\n", IMG_Error(tex->type) );
        V_Free(ip);
        V_Free(m_ip);
        return -6;
    }

	// save path info of the texture image
	ip->name[0] = 0;
	ip->syspath[0] = 0;
	strcpy( ip->name, strip_path( &path[0] ) );
	strcpy( ip->syspath, strip_gamepath( &path[0] ) );

	// read in the MASK file
	snprintf( path, 512, "%s\\%s", fs_gamepath->string(), mask->syspath );
    switch ( mask->type ) {
    case IMG_TGA:
        IMG_readfileTGA( path, m_ip ); 
        break;
    case IMG_BMP:
        IMG_readfileBMP( path, m_ip );
        break;
    case IMG_GIF:
    case IMG_JPG:
    case IMG_PCX:
    case IMG_PPM:
    case IMG_PNG:
    default:
        Com_Printf( "image type: %s not supported\n", IMG_Error(mask->type) );
		if ( ip->data )
			V_Free( ip->data );
        V_Free(ip);
        V_Free(m_ip);
        return -7;
    }

	int err_cond = 0;

	// allocates compiled array & formats data into it
    if ( IMG_compileGLImage( ip ) )
		err_cond = 1;
    if ( IMG_compileGLImage( m_ip ) )
		err_cond = 1;

	byte *rsmp = NULL;

	if ( !err_cond ) {

		int scale = ip->w / m_ip->w;	// difference between scales

		// single channel greyscale mask
		int r_sz = ip->h * ip->w; // 1 byte for each pixel
		rsmp = (byte *) V_Malloc( ip->h * ip->w );
		memset( rsmp, 0, r_sz );

		// convert mask from it's resident format to be the same dimension
		//  as the texture image
		int h, i, j, k, rsmp_i, rsmp_j, pix;

		/// foreach Row in Mask

		// for each row in m_ip ==> j
		for ( j = 0; j < m_ip->h; j++ ) {

			/// foreach col in Mask

			// for each col in m_ip ==> i
			for ( i = 0; i < m_ip->w; i++ ) {

				/// extrapolate Mask Pixel to Cover all of it's corresponding pixels
				///  in the new re-sampled mask

				// ROWS: ( j * scale ) to ( j * scale + scale ) 
				for ( k = 0; k < scale; k++ ) {

					rsmp_j = j * scale + k;

					// COLS: set i to i + scale pixels to value of m_ip->compiled[ i ]
					for ( h = 0; h < scale; h++ ) {

						rsmp_i = i * scale + h;

						// index into new mask
						pix = rsmp_j * ip->w + rsmp_i;

						if ( pix < r_sz ) {
							rsmp[ pix ] = m_ip->compiled[ j * m_ip->w + i ];
						}
					}
				}
			}
		}

		if ( ip->bpp == 1 ) {
			for ( i = 0; i < (int)ip->numbytes; i += 1 ) {
				if ( rsmp[ i ] == 0 ) {
					ip->compiled[ i + 0 ] = 0;
				}
			}
		} else if ( 0 ) {
			// set to zero any texels that didn't pass
			for ( i = 0; i < (int)r_sz; i++ ) {
				if ( rsmp[ i ] == 0 ) {
					ip->compiled[ i * 4 + 0 ] = 0;
					ip->compiled[ i * 4 + 1 ] = 0;
					ip->compiled[ i * 4 + 2 ] = 0;
					ip->compiled[ i * 4 + 3 ] = 255;
				}
			}
		} // if bpp == 4
		
		IMG_MakeGLTexture( ip );
	}

	if ( ip->data ) {
    	V_Free( ip->data );
    	ip->data = NULL;
	}
	if ( ip->compiled ) {
		V_Free( ip->compiled );
		ip->compiled = NULL;
	}
	if ( m_ip->data ) {
    	V_Free( m_ip->data );
    	m_ip->data = NULL;
	}
	if ( m_ip->compiled ) {
		V_Free( m_ip->compiled );
		m_ip->compiled = NULL;
	}
	V_Free( m_ip );
	if ( rsmp )
		V_Free( rsmp );

	*ipp = NULL;
	if ( err_cond )
		return -4;

	*ipp = ip;
	return 0;
}
Exemple #9
0
void IMG_compileImageFile ( const char *path, image_t **ip )
{
    int type;
    int i;

    *ip = (image_t *) V_Malloc( sizeof(image_t) );

    // get type from filename extension
    for (i = 0; path[i] != '\0'; i++)
        ;

    do {
        --i;
    } while ( path[i] != '.' );
    ++i;


    type = IMG_NONE;
    if ( !C_strncasecmp( &path[i], "BMP", 3 ) )
        type = IMG_BMP;
    else if ( !C_strncasecmp( &path[i], "TGA", 3 ) )
        type = IMG_TGA;


    // 
    switch(type) {
    case IMG_TGA:
        IMG_readfileTGA( path, *ip ); 
        break;
    case IMG_BMP:
        IMG_readfileBMP( path, *ip );
        break;
    case IMG_GIF:
    case IMG_JPG:
    case IMG_PCX:
    case IMG_PPM:
    case IMG_PNG:
    default:
        Com_Printf( "image type: %s not supported\n", IMG_Error(type) );
        V_Free(*ip);
        (*ip)=NULL;
        return;
    }

	(*ip)->name[0] = 0;
	(*ip)->syspath[0] = 0;

	// get basename
	strcpy( (*ip)->name, strip_path( &path[0] ) );

	// get relative name
	strcpy( (*ip)->syspath, strip_gamepath( &path[0] ) );

	int err_cond = 0;
    if ( IMG_compileGLImage( *ip ) )
		err_cond = 1;

    V_Free( (*ip)->data );
    (*ip)->data = NULL;

	if ( !err_cond ) {
		IMG_MakeGLTexture( *ip );

		V_Free( (*ip)->compiled );
		(*ip)->compiled = NULL;
	}
}