Пример #1
0
/*
==================
Mod_LoadModel

Loads a model into the cache
==================
*/
static model_t *Mod_LoadModel (model_t *mod, qboolean crash)
{
	unsigned int	*buf;

	if (mod->needload == NL_PRESENT)
		return mod;

//
// load the file
//
	buf = (unsigned int *)FS_LoadTempFile (mod->name);
	if (!buf)
	{
		if (crash)
			SV_Error ("%s: %s not found", __thisfunc__, mod->name);
		return NULL;
	}

//
// allocate a new model
//
	COM_FileBase (mod->name, loadname, sizeof(loadname));

	loadmodel = mod;

//
// fill it in
//

// call the apropriate loader
	mod->needload = NL_PRESENT;

	Mod_LoadBrushModel (mod, buf);

	return mod;
}
Пример #2
0
qbool VM_LoadBytecode( vm_t * vm, sys_callex_t syscall1 )
{
	char name[MAX_OSPATH];
	byte *buff;
	vmHeader_t *header;
	qvm_t *qvm;
	char num[32];
	int filesize;

	snprintf( name, sizeof( name ), "%s.qvm", vm->name );

	Con_DPrintf( "VM_LoadBytecode: load %s\n", name );
	buff = FS_LoadTempFile( name , &filesize );

	if ( !buff )
		return false;

	// add qvm crc to the serverinfo
	snprintf( num, sizeof(num), "%i", CRC_Block( ( byte * ) buff, filesize ) );
	Info_SetValueForStarKey( svs.info, "*progs", num, MAX_SERVERINFO_STRING );

	header = ( vmHeader_t * ) buff;

	header->vmMagic = LittleLong( header->vmMagic );
	header->instructionCount = LittleLong( header->instructionCount );
	header->codeOffset = LittleLong( header->codeOffset );
	header->codeLength = LittleLong( header->codeLength );
	header->dataOffset = LittleLong( header->dataOffset );
	header->dataLength = LittleLong( header->dataLength );
	header->litLength = LittleLong( header->litLength );
	header->bssLength = LittleLong( header->bssLength );

	// check file
	if ( header->vmMagic != VM_MAGIC || header->instructionCount <= 0 || header->codeLength <= 0 )
	{
		return false;
	}
	// create vitrual machine
	if(vm->hInst)
		qvm = (qvm_t *)vm->hInst;
	else
		qvm = (qvm_t *) Q_malloc (sizeof (qvm_t));

	qvm->len_cs = header->instructionCount + 1;	//bad opcode padding.
	qvm->len_ds = header->dataOffset + header->litLength + header->bssLength;
	//align ds
	qvm->ds_mask = 1;
	while( qvm->ds_mask < qvm->len_ds) qvm->ds_mask<<=1;
	qvm->len_ds = qvm->ds_mask;
	qvm->ds_mask--;

	qvm->len_ss = 0x10000;	// default by q3asm
	if ( qvm->len_ds < qvm->len_ss )
		Sys_Error( "VM_LoadBytecode: stacksize greater than data segment" );

	qvm->cs = ( qvm_instruction_t * ) Hunk_AllocName( qvm->len_cs * sizeof( qvm_instruction_t ), "qvmcode" );
	qvm->ds = (byte *) Hunk_AllocName( qvm->len_ds, "qvmdata" );
	qvm->ss = qvm->ds + qvm->len_ds - qvm->len_ss;

	// setup registers
	qvm->PC = 0;
	qvm->SP = 0;
	qvm->LP = qvm->len_ds - sizeof(int);
	qvm->cycles = 0;
	qvm->reenter = 0;
	qvm->syscall = syscall1;


	// load instructions
	{
		byte   *src = buff + header->codeOffset;
		qvm_instruction_t *dst = qvm->cs;
		opcode_t op;
		int     i;

		for ( i = 0; i < header->instructionCount; i++, dst++ )
		{
			op = (opcode_t) *src++;
			dst->opcode = op;
			switch ( op )
			{
			case OP_ARG:
				dst->parm._int = ( int ) *src++;
				break;

			case OP_ENTER:
			case OP_LEAVE:
			case OP_CONST:
			case OP_LOCAL:
			case OP_EQ:
			case OP_NE:
			case OP_LTI:
			case OP_LEI:
			case OP_GTI:
			case OP_GEI:
			case OP_LTU:
			case OP_LEU:
			case OP_GTU:
			case OP_GEU:
			case OP_EQF:
			case OP_NEF:
			case OP_LTF:
			case OP_LEF:
			case OP_GTF:
			case OP_GEF:
			case OP_BLOCK_COPY:

				dst->parm._int = LittleLong( *( int * ) src );
				src += 4;
				break;

			default:
				dst->parm._int = 0;
				break;
			}
		}
		dst->opcode = OP_BREAK;
		dst->parm._int = 0;
	}
	// load data segment
	{
		int   *src = ( int * ) ( buff + header->dataOffset );
		int   *dst = ( int * ) qvm->ds;
		int     i;

		for ( i = 0; i < header->dataLength / 4; i++ )
			*dst++ = LittleLong( *src++ );

		memcpy( dst, src, header->litLength );
	}

	LoadMapFile( qvm, vm->name );
	vm->type = VM_BYTECODE;
	vm->hInst = qvm;
	return true;
}
Пример #3
0
void LoadMapFile( qvm_t*qvm, char* fname )
{
	char    name[MAX_OSPATH];
	char	lineBuffer[MAX_LINE_LENGTH];
	char	symname[MAX_LINE_LENGTH];
	int	i,off,seg,len,num_symbols = 0;
	symbols_t *sym = NULL;

	byte   *buff;
	byte   *p;

	Con_DPrintf("Loading symbol information\n");
	snprintf( name, sizeof( name ), "%s.map", fname );
	buff = FS_LoadTempFile( name , NULL );
	qvm->sym_info = NULL;
	if ( !buff )
		return;
	p=buff;
	while(*p)
	{
		for( i = 0; i < MAX_LINE_LENGTH; i++)
		{
			if( p[i] == 0 || p[i] == '\n')
				break;
		}
		if ( i == MAX_LINE_LENGTH )
		{
			return;
		}

		memcpy( lineBuffer, p, i );
		lineBuffer[i] = 0;
		p += i;
		if( *p == '\n') p++;
		if( 3 != sscanf( lineBuffer,"%d %8x %s",&seg,&off,symname) )
			return;
		len = strlen(symname);
		if(!len)continue;
		if( off < 0 )
			continue;

		if( seg == 0 && off >= qvm->len_cs)
		{
			Con_DPrintf("bad cs off in map file %s.map\n",fname);
			qvm->sym_info = NULL;
			return;
		}
		if( seg >= 1 && off >= qvm->len_ds )
		{
			Con_DPrintf("bad ds off in map file %s.map\n",fname);
			continue;
		}

		if( !qvm->sym_info )
		{
			qvm->sym_info = (symbols_t *) Hunk_Alloc( sizeof(symbols_t) + len + 1);
			sym = qvm->sym_info;
		}
		else
		{
			sym->next = (symbols_t *) Hunk_Alloc( sizeof(symbols_t) + len + 1);
			sym = sym->next;
		}
		sym->seg = seg;
		sym->off = off;
		sym->next= NULL;
		num_symbols++;
		strlcpy(sym->name, symname, len + 1);
	}
	Con_DPrintf("%i symbols loaded from %s\n",num_symbols,name);
}
Пример #4
0
/*
=============
LoadTGA
=============
*/
void LoadTGA (char *filename, byte **out, int *width, int *height)
{
	int		columns, rows, numPixels;
	byte	*pixbuf, *tgabuf;
	int		row, column;
	TargaHeader targa_header;

	*out = NULL;
	tgabuf = FS_LoadTempFile (filename);
	if (!tgabuf)
	{
		Com_DPrintf ("LoadTGA: Could not open %s\n", filename);
		return;
	}

	targa_header.id_length = *(byte *)tgabuf++;
	targa_header.colormap_type = *(byte *)tgabuf++;
	targa_header.image_type = *(byte *)tgabuf++;
	
	targa_header.colormap_index = LittleShort (*(short *)tgabuf); tgabuf += 2;
	targa_header.colormap_length = LittleShort (*(short *)tgabuf); tgabuf += 2;
	targa_header.colormap_size = *(byte *)tgabuf++;
	targa_header.x_origin = LittleShort (*(short *)tgabuf); tgabuf += 2;
	targa_header.y_origin = LittleShort (*(short *)tgabuf); tgabuf += 2;
	targa_header.width = LittleShort (*(short *)tgabuf); tgabuf += 2;
	targa_header.height = LittleShort (*(short *)tgabuf); tgabuf += 2;
	targa_header.pixel_size = *(byte *)tgabuf++;
	targa_header.attributes = *(byte *)tgabuf++;

	if (targa_header.image_type != 2 && targa_header.image_type != 10)
	{
		Com_DPrintf ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
		return;
	}

	if (targa_header.colormap_type != 0 || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24))
	{
		Com_DPrintf ("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
		return;
	}

	columns = targa_header.width;
	rows = targa_header.height;
	numPixels = columns * rows;

	if (width)
		*width = columns;
	if (height)
		*height = rows;

	*out = Q_malloc (numPixels*4 + 128000 /* !!!!TESTING */);

	if (targa_header.id_length != 0)
		tgabuf += targa_header.id_length;
	
	if (targa_header.image_type==2) {  // Uncompressed, RGB images
		for (row = rows - 1; row >= 0; row--) {
			pixbuf = *out + ((targa_header.attributes & 0x20) ? rows-1-row : row) * columns * 4;
			for(column=0; column<columns; column++) {
				unsigned char red,green,blue,alphabyte;
				switch (targa_header.pixel_size) {
					case 24:
							
							blue = *(byte *)tgabuf++;
							green = *(byte *)tgabuf++;
							red = *(byte *)tgabuf++;
							*pixbuf++ = red;
							*pixbuf++ = green;
							*pixbuf++ = blue;
							*pixbuf++ = 255;
							break;
					case 32:
							blue = *(byte *)tgabuf++;
							green = *(byte *)tgabuf++;
							red = *(byte *)tgabuf++;
							alphabyte = *(byte *)tgabuf++;
							*pixbuf++ = red;
							*pixbuf++ = green;
							*pixbuf++ = blue;
							*pixbuf++ = alphabyte;
							break;
				}
			}
		}
	}
	else if (targa_header.image_type==10) {   // Runlength encoded RGB images
		unsigned char red = 0,green = 0,blue = 0,alphabyte = 0,packetHeader = 0,packetSize = 0,j = 0;
		for (row = rows - 1; row >= 0; row--) {
			pixbuf = *out + ((targa_header.attributes & 0x20) ? rows-1-row : row) * columns * 4;
			for(column=0; column<columns; ) {
				packetHeader = *(byte *)tgabuf++;
				packetSize = 1 + (packetHeader & 0x7f);
				if (packetHeader & 0x80) {        // run-length packet
					switch (targa_header.pixel_size) {
						case 24:
								blue = *(byte *)tgabuf++;
								green = *(byte *)tgabuf++;
								red = *(byte *)tgabuf++;
								alphabyte = 255;
								break;
						case 32:
								blue = *(byte *)tgabuf++;
								green = *(byte *)tgabuf++;
								red = *(byte *)tgabuf++;
								alphabyte = *(byte *)tgabuf++;
								break;
					}
	
					for(j=0;j<packetSize;j++) {
						*pixbuf++=red;
						*pixbuf++=green;
						*pixbuf++=blue;
						*pixbuf++=alphabyte;
						column++;
						if (column==columns) { // run spans across rows
							column=0;
							if (row>0)
								row--;
							else
								goto breakOut;
							pixbuf = *out + row*columns*4;
						}
					}
				}
				else {                            // non run-length packet
					for(j=0;j<packetSize;j++) {
						switch (targa_header.pixel_size) {
							case 24:
									blue = *(byte *)tgabuf++;
									green = *(byte *)tgabuf++;
									red = *(byte *)tgabuf++;
									*pixbuf++ = red;
									*pixbuf++ = green;
									*pixbuf++ = blue;
									*pixbuf++ = 255;
									break;
							case 32:
									blue = *(byte *)tgabuf++;
									green = *(byte *)tgabuf++;
									red = *(byte *)tgabuf++;
									alphabyte = *(byte *)tgabuf++;
									*pixbuf++ = red;
									*pixbuf++ = green;
									*pixbuf++ = blue;
									*pixbuf++ = alphabyte;
									break;
						}
						column++;
						if (column==columns) { // pixel packet run spans across rows
							column=0;
							if (row>0)
								row--;
							else
								goto breakOut;
							pixbuf = *out + row*columns*4;
						}
					}
				}
			}
			breakOut:;
		}
	}
}
Пример #5
0
/*
============
LoadPCX
============
*/
void LoadPCX (char *filename, byte **pic, int *width, int *height)
{
	pcx_t	*pcx;
	byte	*pcxbuf, *out, *pix;
	int		x, y;
	int		dataByte, runLength;

	*pic = NULL;
	pcxbuf = FS_LoadTempFile (filename);
	if (!pcxbuf)
	{
		Com_DPrintf ("LoadPCX: Could not open %s\n", filename);
		return;
	}

//
// parse the PCX file
//
	pcx = (pcx_t *)pcxbuf;
	pcx->xmax = LittleShort (pcx->xmax);
	pcx->xmin = LittleShort (pcx->xmin);
	pcx->ymax = LittleShort (pcx->ymax);
	pcx->ymin = LittleShort (pcx->ymin);
	pcx->hres = LittleShort (pcx->hres);
	pcx->vres = LittleShort (pcx->vres);
	pcx->bytes_per_line = LittleShort (pcx->bytes_per_line);
	pcx->palette_type = LittleShort (pcx->palette_type);

	pix = &pcx->data;

	if (pcx->manufacturer != 0x0a
		|| pcx->version != 5
		|| pcx->encoding != 1
		|| pcx->bits_per_pixel != 8
		|| pcx->xmax >= 640
		|| pcx->ymax >= 480)
	{
		Com_DPrintf ("LoadPCX: Bad pcx file %s\n", filename);
		return;
	}

	if (width)
		*width = pcx->xmax+1;
	if (height)
		*height = pcx->ymax+1;

	*pic = out = Q_malloc ((pcx->xmax+1) * (pcx->ymax+1));

	for (y=0 ; y<=pcx->ymax ; y++, out += pcx->xmax+1)
	{
		for (x=0 ; x<=pcx->xmax ; )
		{
			if (pix - (byte *)pcx > fs_filesize) 
			{
				Q_free (*pic);
				*pic = NULL;
				Com_DPrintf ("LoadPCX: %s is malformed\n", filename);
				return;
			}

			dataByte = *pix++;

			if((dataByte & 0xC0) == 0xC0)
			{
				runLength = dataByte & 0x3F;
				if (pix - (byte *)pcx > fs_filesize) 
				{
					Q_free (*pic);
					*pic = NULL;
					Com_DPrintf ("LoadPCX: %s is malformed\n", filename);
					return;
				}
				dataByte = *pix++;
			}
			else
				runLength = 1;

			// sanity check
			if (runLength + x > pcx->xmax + 2)
			{
				Q_free (*pic);
				*pic = NULL;
				Com_DPrintf ("LoadPCX: %s is malformed\n", filename);
				return;
			}

			while (runLength-- > 0)
				out[x++] = dataByte;
		}
	}

	if (pix - (byte *)pcx > fs_filesize)
	{
		Q_free (*pic);
		*pic = NULL;
		Com_DPrintf ("LoadPCX: %s is malformed\n", filename);
	}
}
Пример #6
0
/*
==========
Skin_Cache

Returns a pointer to the skin bitmap, or NULL to use the default
==========
*/
byte	*Skin_Cache (skin_t *skin)
{
	char	name[1024];
	byte	*raw;
	byte	*out, *pix;
	pcx_t	*pcx;
	int		x, y;
	int		dataByte;
	int		runLength;

	if (cls.downloadtype == dl_skin)
		return NULL;		// use base until downloaded

	if (noskins.integer == 1)	// JACK: So NOSKINS > 1 will show skins, but
		return NULL;		//	 not download new ones.

	if (skin->failedload)
		return NULL;

	out = (byte *) Cache_Check (&skin->cache);
	if (out)
		return out;

//
// load the pic from disk
//
	q_snprintf (name, sizeof(name), "skins/%s.pcx", skin->name);
	raw = FS_LoadTempFile (name, NULL);
	if (!raw)
	{
		Con_Printf ("Couldn't load skin %s\n", name);
		q_snprintf (name, sizeof(name), "skins/%s.pcx", baseskin.string);
		raw = FS_LoadTempFile (name, NULL);
		if (!raw)
		{
			skin->failedload = true;
			return NULL;
		}
	}

//
// parse the PCX file
//
	pcx = (pcx_t *)raw;
	raw = &pcx->data;

	if (pcx->manufacturer != 0x0a
		|| pcx->version != 5
		|| pcx->encoding != 1
		|| pcx->bits_per_pixel != 8
		|| pcx->xmax >= 320
		|| pcx->ymax >= 200)
	{
		skin->failedload = true;
		Con_Printf ("Bad skin %s\n", name);
		return NULL;
	}

	out = (byte *) Cache_Alloc (&skin->cache, 320*200, skin->name);
	if (!out)
		Sys_Error ("%s: couldn't allocate", __thisfunc__);

	pix = out;
	memset (out, 0, 320*200);

	for (y = 0; y < pcx->ymax; y++, pix += 320)
	{
		for (x = 0; x <= pcx->xmax ; )
		{
			if ((size_t)(raw - (byte*)pcx) > fs_filesize)
			{
				Cache_Free (&skin->cache);
				skin->failedload = true;
				Con_Printf ("Skin %s was malformed.  You should delete it.\n", name);
				return NULL;
			}
			dataByte = *raw++;

			if ((dataByte & 0xC0) == 0xC0)
			{
				runLength = dataByte & 0x3F;
				if ((size_t)(raw - (byte*)pcx) > fs_filesize)
				{
					Cache_Free (&skin->cache);
					skin->failedload = true;
					Con_Printf ("Skin %s was malformed.  You should delete it.\n", name);
					return NULL;
				}
				dataByte = *raw++;
			}
			else
				runLength = 1;

			// skin sanity check
			if (runLength + x > pcx->xmax + 2)
			{
				Cache_Free (&skin->cache);
				skin->failedload = true;
				Con_Printf ("Skin %s was malformed.  You should delete it.\n", name);
				return NULL;
			}
			while (runLength-- > 0)
				pix[x++] = dataByte;
		}
	}

	if ((size_t)(raw - (byte *)pcx) > fs_filesize)
	{
		Cache_Free (&skin->cache);
		skin->failedload = true;
		Con_Printf ("Skin %s was malformed.  You should delete it.\n", name);
		return NULL;
	}

	skin->failedload = false;

	return out;
}