예제 #1
0
	void RoutingLumpLoader::loadRoutingLump (ArchiveFile& file)
	{
		/* load the file */
		InputStream &stream = file.getInputStream();
		const std::size_t size = file.size();
		byte *buf = (byte*) malloc(size + 1);
		dBspHeader_t *header = (dBspHeader_t *) buf;
		stream.read(buf, size);

		CMod_LoadRouting(_routingLump, file.getName(), &header->lumps[LUMP_ROUTING], (byte *) buf, 0, 0, 0);
		free(buf);
	}
예제 #2
0
ImagePtr LoadImageGDK(ArchiveFile& file) {
	
	// Allocate a new GdkPixBuf and create an alpha-channel with alpha=1.0
	GdkPixbuf* rawPixbuf = gdk_pixbuf_new_from_file(file.getName().c_str(), NULL);
	
	// Only create an alpha channel if the other rawPixbuf could be loaded
	GdkPixbuf* img = (rawPixbuf != NULL) ? gdk_pixbuf_add_alpha(rawPixbuf, TRUE, 255, 0, 255) : NULL;
	
	if (img != NULL) {
		// Allocate a new image
		RGBAImagePtr image (new RGBAImage(gdk_pixbuf_get_width(img), gdk_pixbuf_get_height(img)));
		
		// Initialise the source buffer pointers
		guchar* gdkStart = gdk_pixbuf_get_pixels(img);
		int rowstride = gdk_pixbuf_get_rowstride(img);
		int numChannels = gdk_pixbuf_get_n_channels(img);
		
		// Set the target buffer pointer to the first RGBAPixel
		RGBAPixel* targetPixel = image->pixels;
		
		// Now do an unelegant cycle over all the pixels and move them into the target
		for (unsigned int y = 0; y < image->height; y++) {
			for (unsigned int x = 0; x < image->width; x++) {
				guchar* gdkPixel = gdkStart + y*rowstride + x*numChannels;
				
				// Copy the values from the GdkPixel
				targetPixel->red = gdkPixel[0];
				targetPixel->green = gdkPixel[1];
				targetPixel->blue = gdkPixel[2];
				targetPixel->alpha = gdkPixel[3];
				
				// Increase the pointer
				targetPixel++;
			}
		}
		
		// Free the GdkPixbufs from the memory
		g_object_unref(G_OBJECT(img)); 
		g_object_unref(G_OBJECT(rawPixbuf));

		return image;
	}
	
	// No image could be loaded, return NULL	
	return ImagePtr();
}
예제 #3
0
파일: md2.cpp 프로젝트: xonotic/netradient
void MD2Surface_read( Model& model, const byte* buffer, ArchiveFile& file ){
	Surface& surface = model.newSurface();
	md2Header_t header;
	{
		PointerInputStream inputStream( buffer );
		istream_read_md2Header( inputStream, header );
	}

	{

		md2Frame_t frame;
		PointerInputStream frameStream( buffer + header.ofs_frames );
		istream_read_md2Frame( frameStream, frame );


		surface.indices().reserve( header.num_tris * 3 );

		Array<md2XyzNormal_t> md2Xyz( header.num_xyz );
		for ( Array<md2XyzNormal_t>::iterator i = md2Xyz.begin(); i != md2Xyz.end(); ++i )
		{
			istream_read_md2XyzNormal( frameStream, *i );
		}

		Array<md2St_t> md2St( header.num_st );
		PointerInputStream stStream( buffer + header.ofs_st );
		for ( Array<md2St_t>::iterator i = md2St.begin(); i != md2St.end(); ++i )
		{
			istream_read_md2St( stStream, *i );
		}

		UniqueVertexBuffer<ArbitraryMeshVertex> inserter( surface.vertices() );
		inserter.reserve( header.num_st );

		PointerInputStream triangleStream( buffer + header.ofs_tris );
		for ( int i = 0; i < header.num_tris; ++i )
		{
			md2Triangle_t triangle;
			istream_read_md2Triangle( triangleStream, triangle );
			surface.indices().insert( inserter.insert( MD2Vertex_construct( &header, &frame, &md2Xyz[triangle.index_xyz[0]], &md2St[triangle.index_st[0]] ) ) );
			surface.indices().insert( inserter.insert( MD2Vertex_construct( &header, &frame, &md2Xyz[triangle.index_xyz[1]], &md2St[triangle.index_st[1]] ) ) );
			surface.indices().insert( inserter.insert( MD2Vertex_construct( &header, &frame, &md2Xyz[triangle.index_xyz[2]], &md2St[triangle.index_st[2]] ) ) );
		}
	}

	char skinname[MD2_MAX_SKINNAME];
	char skinnameRelative[MD2_MAX_SKINNAME];
	char path[MD2_MAX_SKINNAME];
	int i = MD2_MAX_SKINNAME;
	PointerInputStream inputStream( buffer + header.ofs_skins );
	inputStream.read( reinterpret_cast<byte*>( skinnameRelative ), MD2_MAX_SKINNAME );
	// relative texture path - allows moving of models in game dir structure without changing the skinpath
	// e.g. used in ufo:ai
	if ( skinnameRelative[0] == '.' ) {
		strncpy( path, file.getName(), MD2_MAX_SKINNAME );
		for (; i--; )
		{
			// skip filename
			if ( path[i] == '/' || path[i] == '\\' ) {
				break;
			}
			path[i] = '\0';
		}
//	globalErrorStream() << "modified skinname: " << path << " (path) and " << skinnameRelative << " (texture)" << "\n";
		snprintf( skinname, MD2_MAX_SKINNAME, "%s%s", path, &skinnameRelative[1] );
//	globalErrorStream() << skinname << "\n";
	}
	else
	{
		strcpy( skinname, skinnameRelative );
	}
	surface.setShader( skinname );
	surface.updateAABB();
}
예제 #4
0
void SoundPlayer::play(ArchiveFile& file) {
	// If we're not initialised yet, do it now
	if (!_initialised) {
		initialise();
    }

	// Stop any previous playback operations, that might be still active
	clearBuffer();

	// Retrieve the extension
	std::string ext = os::getExtension(file.getName());

	if (boost::algorithm::to_lower_copy(ext) == "ogg") {
		// Convert the file into a buffer, self-destructs at end of scope
		ScopedArchiveBuffer buffer(file);

		// This is an OGG Vorbis file, decode it
		vorbis_info* vorbisInfo;
  		OggVorbis_File oggFile;

  		// Initialise the wrapper class
  		OggFileStream stream(buffer);

  		// Setup the callbacks and point them to the helper class
  		ov_callbacks callbacks;
  		callbacks.read_func = OggFileStream::oggReadFunc;
  		callbacks.seek_func = OggFileStream::oggSeekFunc;
  		callbacks.close_func = OggFileStream::oggCloseFunc;
  		callbacks.tell_func = OggFileStream::oggTellFunc;

  		// Open the OGG data stream using the custom callbacks
  		int res = ov_open_callbacks(static_cast<void*>(&stream), &oggFile,
									NULL, 0, callbacks);

  		if (res == 0) {
  			// Open successful

  			// Get some information about the OGG file
			vorbisInfo = ov_info(&oggFile, -1);

			// Check the number of channels
			ALenum format = (vorbisInfo->channels == 1) ? AL_FORMAT_MONO16
														: AL_FORMAT_STEREO16;

			// Get the sample Rate
			ALsizei freq = (vorbisInfo->rate);
			//std::cout << "Sample rate is " << freq << "\n";

			long bytes;
			char smallBuffer[4096];
			DecodeBufferPtr largeBuffer(new DecodeBuffer());
			do {
				int bitStream;
				// Read a chunk of decoded data from the vorbis file
				bytes = ov_read(&oggFile, smallBuffer, sizeof(smallBuffer),
								0, 2, 1, &bitStream);

				if (bytes == OV_HOLE) {
					rError() << "SoundPlayer: Error decoding OGG: OV_HOLE.\n";
				}
				else if (bytes == OV_EBADLINK) {
					rError() << "SoundPlayer: Error decoding OGG: OV_EBADLINK.\n";
				}
				else {
					// Stuff this into the variable-sized buffer
					largeBuffer->insert(largeBuffer->end(), smallBuffer, smallBuffer + bytes);
				}
			} while (bytes > 0);

			// Allocate a new buffer
			alGenBuffers(1, &_buffer);

			DecodeBuffer& bufferRef = *largeBuffer;

			// Upload sound data to buffer
			alBufferData(_buffer,
						 format,
						 &bufferRef[0],
						 static_cast<ALsizei>(bufferRef.size()),
						 freq);

			// Clean up the OGG routines
  			ov_clear(&oggFile);
  		}
  		else {
  			rError() << "SoundPlayer: Error opening OGG file.\n";
  		}
	}
	else {
		// Must be a wave file
		try {
			// Create an AL sound buffer directly from the buffer in memory
			_buffer = WavFileLoader::LoadFromStream(file.getInputStream());
		}
		catch (std::runtime_error& e) {
			rError() << "SoundPlayer: Error opening WAV file: " << e.what() << std::endl;
			_buffer = 0;
		}
	}

	if (_buffer != 0) {
		alGenSources(1, &_source);
		// Assign the buffer to the source and play it
		alSourcei(_source, AL_BUFFER, _buffer);

		// greebo: Wait 10 msec. to fix a problem with buffers not being played
		// maybe the AL needs time to push the data?
		usleep(10000);

		alSourcePlay(_source);

		// Enable the periodic buffer check, this destructs the buffer
		// as soon as the playback has finished
		_timer.enable();
	}
}