Example #1
0
model3DS::model3DS(const char* filename, float scale) : m_filename(filename), m_scale(scale){
    
    std::ifstream *modelFile = new std::ifstream(filename,std::ios::in | std::ios::binary | std::ios::ate);
	
    if(!modelFile->is_open()){
        std::cout<<"[3DS] ERROR: Could not open '"<<filename<<"'"<<std::endl;
        return;
    }
    if(int(modelFile->tellg()) == 0){
        std::cout<<"[3DS] ERROR: Model '"<<filename<<"' is empty"<<std::endl;
        modelFile->close();
        return;
    }

	// Extract path from filename
	int lastSlashPosition=-1, lastForwardSlash=-1, lastBackslash=-1;
	lastForwardSlash = (int)m_filename.find_last_of('/');
	lastBackslash = (int)m_filename.find_last_of('\\');
	if(lastForwardSlash > lastSlashPosition) lastSlashPosition = lastForwardSlash;
	if(lastBackslash > lastSlashPosition) lastSlashPosition = lastBackslash;
	m_filepath = m_filename.substr(0,lastSlashPosition+1);
	m_filename = m_filename.substr(lastSlashPosition+1);
	
	// Check to make sure file is valid 3DS format (begins with 0x4D4D)
    ushort chunkHeader;
	unsigned int chunkLength;
    
    modelFile->seekg(0, std::ios::beg);
	modelFile->read((char*)&chunkHeader,2);
	modelFile->read((char*)&chunkLength,4);
	
	if(chunkHeader != CHUNK_MAIN){
		std::cout<<"[3DS] ERROR: Model '"<<filename<<"' is not a valid 3DS file"<<std::endl;
        modelFile->close();
        return;
	}
	
	// Detect VBO support
	std::stringstream extStream((const char*)glGetString(GL_EXTENSIONS));
	std::string nextToken;
	bool isVBOSupported=false;	
	while(!extStream.eof()){
		extStream >> nextToken;
		if(nextToken == "GL_ARB_vertex_buffer_object"){
			isVBOSupported=true;
			break;
		}
	}
	m_drawMode = DRAW_VERTEX_ARRAY;

	// Initialise bounding box to min & max 4-byte float values
	m_boundingBox.minX = m_boundingBox.minY = m_boundingBox.minZ = 3.4e+38f;
	m_boundingBox.maxX = m_boundingBox.maxY = m_boundingBox.maxZ = 3.4e-38f;

	// Read all 3DS chunks recursively
	bool finished = false;
	while(!finished){
		finished = readChunk(modelFile, modelFile->tellg(), chunkLength);
	}

	m_centerX = (m_boundingBox.minX + m_boundingBox.maxX) / 2.f;
	m_centerY = (m_boundingBox.minY + m_boundingBox.maxY) / 2.f; 
	m_centerZ = (m_boundingBox.minZ + m_boundingBox.maxZ) / 2.f;

	// Model loaded, clean up    
	modelFile->close();
	delete modelFile;
    std::cout<<"[3DS] Model '"<<filename<<"' loaded"<<std::endl;

}
Example #2
0
    bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm)
    {
        if (!iIsTiled)
        {
            // currently, core creates grids for all maps, whether it has terrain tiles or not
            // so we need "fake" tile loads to know when we can unload map geometry
            iLoadedTiles[packTileID(tileX, tileY)] = false;
            return true;
        }
        if (!iTreeValues)
        {
            VMAP_ERROR_LOG("misc", "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY);
            return false;
        }
        bool result = true;

        std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
        FILE* tf = fopen(tilefile.c_str(), "rb");
        if (tf)
        {
            char chunk[8];

            if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
                result = false;
            uint32 numSpawns = 0;
            if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
                result = false;
            for (uint32 i=0; i<numSpawns && result; ++i)
            {
                // read model spawns
                ModelSpawn spawn;
                result = ModelSpawn::readFromFile(tf, spawn);
                if (result)
                {
                    // acquire model instance
                    WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name);
                    if (!model)
                        VMAP_ERROR_LOG("misc", "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY);

                    // update tree
                    uint32 referencedVal;

                    if (fread(&referencedVal, sizeof(uint32), 1, tf) == 1)
                    {
                        if (!iLoadedSpawns.count(referencedVal))
                        {
                            if (referencedVal > iNTreeValues)
                            {
                                VMAP_ERROR_LOG("maps", "StaticMapTree::LoadMapTile() : invalid tree element (%u/%u) referenced in tile %s", referencedVal, iNTreeValues, tilefile.c_str());
                                continue;
                            }

                            iTreeValues[referencedVal] = ModelInstance(spawn, model);
                            iLoadedSpawns[referencedVal] = 1;
                        }
                        else
                        {
                            ++iLoadedSpawns[referencedVal];
#ifdef VMAP_DEBUG
                            if (iTreeValues[referencedVal].ID != spawn.ID)
                                TC_LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : trying to load wrong spawn in node");
                            else if (iTreeValues[referencedVal].name != spawn.name)
                                TC_LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : name collision on GUID=%u", spawn.ID);
#endif
                        }
                    }
                    else
                        result = false;
                }
            }
            iLoadedTiles[packTileID(tileX, tileY)] = true;
            fclose(tf);
        }
        else
            iLoadedTiles[packTileID(tileX, tileY)] = false;
        TC_METRIC_EVENT("map_events", "LoadMapTile",
            "Map: " + std::to_string(iMapID) + " TileX: " + std::to_string(tileX) + " TileY: " + std::to_string(tileY));
        return result;
    }
Example #3
0
bool model3DS::readChunk(std::ifstream *modelFile, const int objectStart, const int objectLength){
	//std::cout<<std::hex<<"readChunk("<<objectStart<<"-"<<(objectStart+objectLength)<<")"<<std::dec<<std::endl;
	
	ushort chunkHeader = 0;
	unsigned int chunkLength = 0;
    
	unsigned long offset = 0;
    ushort numVertices = 0;
	ushort usTemp = 0;
	unsigned int uiTemp = 0;
	float vertexX = 0,vertexY = 0,vertexZ = 0;
    int v = 0;
	std::string name = "";
	char currentLetter = 0;
	unsigned char rgbByte = 0;
	
    while((modelFile->tellg() < (objectStart + objectLength)) && !modelFile->eof()){
		
        offset = modelFile->tellg();
		if(offset == objectLength)
		{
			return true;
		}

		modelFile->read((char*)&chunkHeader, 2);
		modelFile->read((char*)&chunkLength, 4);

        if(DEBUG_OUTPUT) std::cout<<std::hex<<"["<<offset<<"] chunk: 0x"<<chunkHeader<<" ("<<offset<<"-"<<(offset+chunkLength)<<")"<<std::dec<<std::endl;
		switch(chunkHeader){

			  //////////////////
			 // Main chunks
			/////////////////

			case CHUNK_MAIN: continue;

			case CHUNK_3D_EDITOR: continue;

			case CHUNK_OBJECT_BLOCK:
                if(DEBUG_OUTPUT) std::cout<<std::endl<<"[Object block]"<<std::endl;

				m_currentMesh = new mesh3DS(this);
				m_currentMesh->setDrawMode(m_drawMode);

				// Read object name
				do{
					modelFile->read(&currentLetter,1);
					name += currentLetter;
				}while(currentLetter!='\0' && name.length()<20);
				m_currentMesh->setName(name);
				if(DEBUG_OUTPUT) std::cout<<"  Object: "<<name<<std::endl;
				name.erase();

				// Read object sub-chunks
				readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));

				if(m_currentMesh->getNumFaces() != 0){
					m_currentMesh->buildMesh();
					m_meshes.push_back(*m_currentMesh);
				}
				delete m_currentMesh;
				break;

			  /////////////////////
			 // Geometry chunks
			////////////////////

			case CHUNK_MESH:continue; 

            case CHUNK_VERTICES: 
                modelFile->read((char*)&numVertices,2);
                for(v=0; v < numVertices*3; v+=3){
                    modelFile->read((char*)&vertexX,4);
					modelFile->read((char*)&vertexY,4);
					modelFile->read((char*)&vertexZ,4);
					// 3DS Max has different axes to OpenGL
					vertexX *= m_scale;
					vertexY *= m_scale;
					vertexZ *= m_scale;
                    m_currentMesh->addVertex(vertexX);// x
                    m_currentMesh->addVertex(vertexZ);// y
                    m_currentMesh->addVertex(-vertexY);// z
					// Update bounding box
					if(vertexX < m_boundingBox.minX)m_boundingBox.minX = vertexX;
					if(vertexZ < m_boundingBox.minY)m_boundingBox.minY = vertexZ;
					if(-vertexY < m_boundingBox.minZ)m_boundingBox.minZ = -vertexY;
					if(vertexX > m_boundingBox.maxX)m_boundingBox.maxX = vertexX;
					if(vertexZ > m_boundingBox.maxY)m_boundingBox.maxY = vertexZ;
					if(-vertexY > m_boundingBox.maxZ)m_boundingBox.maxZ = -vertexY;
                }
                break;

            case CHUNK_TEXCOORDS: // texcoords list
                modelFile->read((char*)&numVertices,2);
                for(v=0; v < numVertices*2; v+=2){
                    modelFile->read((char*)&vertexX,4);
                    modelFile->read((char*)&vertexY,4);
                    m_currentMesh->addTexcoord(vertexX);
					m_currentMesh->addTexcoord(vertexY);
                }
                break;

			case CHUNK_FACES: 
                modelFile->read((char*)&m_tempUshort,2);
				
                for(v=0; v < m_tempUshort*3; v+=3){
                    modelFile->read((char*)&usTemp,2);m_currentMesh->addFaceIndex(usTemp);
					modelFile->read((char*)&usTemp,2);m_currentMesh->addFaceIndex(usTemp);
					modelFile->read((char*)&usTemp,2);m_currentMesh->addFaceIndex(usTemp);
					modelFile->read((char*)&usTemp,2); //face flags
                }

				// Read face sub-chunks
				readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));
                break;

			case CHUNK_SMOOTHING_GROUP:
				for(v=0; v < m_tempUshort; v++){
					modelFile->read((char*)&uiTemp,4);
					m_currentMesh->addFaceSmoothing(uiTemp);
					//if(DEBUG_OUTPUT) std::cout<<"Smoothing: "<<uiTemp<<std::endl;
				}
				break;

			  /////////////////////
			 // Material chunks
			////////////////////

            case CHUNK_FACE_MATERIAL:
				// Read material name
				do{
					modelFile->read(&currentLetter,1);
					name += currentLetter;
				}while(currentLetter!='\0' && name.length()<20);
				
				modelFile->read((char*)&m_tempUshort,2);
				
				for(v=0; v < m_tempUshort; v++){
					modelFile->read((char*)&usTemp,2);
					m_currentMesh->addMaterialFace(name, usTemp);
				}
				
				name.erase();

				break;

			case CHUNK_MATERIAL_BLOCK:
				if(DEBUG_OUTPUT) std::cout<<std::endl<<"[Material block]"<<std::endl;

				m_currentMaterial = new material3DS();

				// Read material sub-chunks
                readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));
				
				m_materials[m_currentMaterial->getName()] = *m_currentMaterial;
				delete m_currentMaterial;
                break;

			case CHUNK_MATERIAL_NAME:
				// Read material name and add to current material
				do{
					modelFile->read(&currentLetter,1);
					name += currentLetter;
				}while(currentLetter!='\0' && name.length()<20);
				m_currentMaterial->setName(name);
				if(DEBUG_OUTPUT) std::cout<<"  Material: "<<m_currentMaterial->getName()<<"("<<m_currentMaterial->getName().size()<<")"<<std::endl;
				name.erase();
				break;

			case CHUNK_TEXTURE_MAP:
			case CHUNK_BUMP_MAP:
				//Read texture name and add to current material
				readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));
				m_currentMaterial->loadTexture(m_filepath + m_tempString, chunkHeader);

				break;

			case CHUNK_MAP_FILENAME:
				// Read texture map filename
				m_tempString.erase();
				do{
					modelFile->read(&currentLetter,1);
					m_tempString += currentLetter;
				}while(currentLetter!='\0' && m_tempString.length()<20);
				break;

			case CHUNK_MATERIAL_TWO_SIDED:
				m_currentMaterial->setTwoSided(true);
				break;

			case CHUNK_DIFFUSE_COLOR:
				// Read color sub-chunks
                readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));
				m_currentMaterial->setDiffuseColor(m_currentColor);

				break;

			case CHUNK_AMBIENT_COLOR:
				// Read color sub-chunks
                readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));
				m_currentMaterial->setAmbientColor(m_currentColor);
				
				break;

			case CHUNK_SPECULAR_COLOR:
				// Read color sub-chunks
                readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));
				m_currentMaterial->setSpecularColor(m_currentColor);

				break;
			
			case CHUNK_SPECULAR_EXPONENT:
				// Read percent sub-chunk
				readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));
                m_currentMaterial->setSpecularExponent(m_tempFloat);
				break;

			case CHUNK_SHININESS:
				// Read percent sub-chunk
				readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));
                m_currentMaterial->setShininess(m_tempFloat);
				break;

			case CHUNK_TRANSPARENCY:
				// Read percent sub-chunk
				readChunk(modelFile, modelFile->tellg(), chunkLength - (long(modelFile->tellg()) - offset));
                m_currentMaterial->setOpacity(1.0f - m_tempFloat);
				break;

			  /////////////////////
			 // Global chunks
			////////////////////

			case CHUNK_RGB_FLOAT:
			case CHUNK_RGB_FLOAT_GAMMA:
				modelFile->read((char*)&m_currentColor[0],4);
				modelFile->read((char*)&m_currentColor[1],4);
				modelFile->read((char*)&m_currentColor[2],4);				
				break;

			case CHUNK_RGB_BYTE:
			case CHUNK_RGB_BYTE_GAMMA:
				modelFile->read((char*)&rgbByte,1); m_currentColor[0]=float(rgbByte)/255.f;
				modelFile->read((char*)&rgbByte,1); m_currentColor[1]=float(rgbByte)/255.f;
				modelFile->read((char*)&rgbByte,1); m_currentColor[2]=float(rgbByte)/255.f;
				break;

			case CHUNK_PERCENT_INT:
				modelFile->read((char*)&usTemp,2);
				m_tempFloat = usTemp / 100.f;
				break;

			case CHUNK_PERCENT_FLOAT:
				modelFile->read((char*)&m_tempFloat,4);
				m_tempFloat /= 100.f;
				break;

			default:break; // any other chunk
				
		}	 //switch case

		// Go to the next chunk's header (if any left in object)
		modelFile->seekg(offset + chunkLength, std::ios::beg);
	
	} //end of while loop
	return false;
}
std::string HttpConnection::readChunk(int chunkSize)
{
    return readChunk(chunkSize, sock);
}
void QGitHubReleaseAPIPrivate::updateReply(QNetworkReply *r) {

	QObject::disconnect(m_readReply, SIGNAL(readyRead()), this, SLOT(readChunk()));
	QObject::connect(r, SIGNAL(readyRead()), this, SLOT(readChunk()));
	m_readReply = r;
}
Example #6
0
    bool StaticMapTree::InitMap(const std::string& fname, VMapManager2* vm)
    {
        DEBUG_FILTER_LOG(LOG_FILTER_MAP_LOADING, "Initializing StaticMapTree '%s'", fname.c_str());
        bool success = true;
        std::string fullname = iBasePath + fname;
        FILE* rf = fopen(fullname.c_str(), "rb");
        if (!rf)
            return false;
        else
        {
            char chunk[8];
            // general info
            if (!readChunk(rf, chunk, VMAP_MAGIC, 8))
                success = false;

            char tiled = 0;
            if (success && fread(&tiled, sizeof(char), 1, rf) != 1)
                success = false;

            iIsTiled = bool(tiled);

            // Nodes
            if (success && !readChunk(rf, chunk, "NODE", 4))
                success = false;

            if (success)
                success = iTree.readFromFile(rf);

            if (success)
            {
                iNTreeValues = iTree.primCount();
                iTreeValues = new ModelInstance[iNTreeValues];
            }

            if (success && !readChunk(rf, chunk, "GOBJ", 4))
                success = false;

            // global model spawns
            // only non-tiled maps have them, and if so exactly one (so far at least...)
            ModelSpawn spawn;
#ifdef VMAP_DEBUG
            DEBUG_LOG("Map isTiled: %u", static_cast<uint32>(iIsTiled));
#endif
            if (success && !iIsTiled && ModelSpawn::readFromFile(rf, spawn))
            {
                WorldModelPtr model = vm->acquireModelInstance(iBasePath, spawn.name);
                DEBUG_FILTER_LOG(LOG_FILTER_MAP_LOADING, "StaticMapTree::InitMap(): loading %s", spawn.name.c_str());
                if (model)
                {
                    // assume that global model always is the first and only tree value (could be improved...)
                    iTreeValues[0] = ModelInstance(spawn, model);
                    iLoadedSpawns[0] = 1;
                }
                else
                {
                    delete[] iTreeValues;
                    iTreeValues = NULL;

                    success = false;
                    ERROR_LOG("StaticMapTree::InitMap() could not acquire WorldModel pointer for '%s'!", spawn.name.c_str());
                }
            }

            fclose(rf);
        }
        return success;
    }
Example #7
0
    bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm)
    {
        if (!iIsTiled)
        {
            // currently, core creates grids for all maps, whether it has terrain tiles or not
            // so we need "fake" tile loads to know when we can unload map geometry
            iLoadedTiles[packTileID(tileX, tileY)] = false;
            return true;
        }
        if (!iTreeValues)
        {
            ERROR_LOG("StaticMapTree::LoadMapTile(): Tree has not been initialized! [%u,%u]", tileX, tileY);
            return false;
        }
        bool result = true;

        std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY);
        FILE* tf = fopen(tilefile.c_str(), "rb");
        if (tf)
        {
            char chunk[8];
            if (!readChunk(tf, chunk, VMAP_MAGIC, 8))
                result = false;
            uint32 numSpawns = 0;
            if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1)
                result = false;
            for (uint32 i = 0; i < numSpawns && result; ++i)
            {
                // read model spawns
                ModelSpawn spawn;
                result = ModelSpawn::readFromFile(tf, spawn);
                if (result)
                {
                    // acquire model instance
                    WorldModelPtr model = vm->acquireModelInstance(iBasePath, spawn.name);
                    if (!model)
                        ERROR_LOG("StaticMapTree::LoadMapTile() could not acquire WorldModel pointer for '%s'!", spawn.name.c_str());

                    // update tree
                    uint32 referencedVal;

                    fread(&referencedVal, sizeof(uint32), 1, tf);
                    if (!iLoadedSpawns.count(referencedVal))
                    {
#ifdef VMAP_DEBUG
                        if (referencedVal > iNTreeValues)
                        {
                            DEBUG_LOG("invalid tree element! (%u/%u)", referencedVal, iNTreeValues);
                            continue;
                        }
#endif
                        iTreeValues[referencedVal] = ModelInstance(spawn, model);
                        iLoadedSpawns[referencedVal] = 1;
                    }
                    else
                    {
                        ++iLoadedSpawns[referencedVal];
#ifdef VMAP_DEBUG
                        if (iTreeValues[referencedVal].ID != spawn.ID)
                            DEBUG_LOG("Error: trying to load wrong spawn in node!");
                        else if (iTreeValues[referencedVal].name != spawn.name)
                            DEBUG_LOG("Error: name mismatch on GUID=%u", spawn.ID);
#endif
                    }
                }
            }
            iLoadedTiles[packTileID(tileX, tileY)] = true;
            fclose(tf);
        }
        else
            iLoadedTiles[packTileID(tileX, tileY)] = false;
        return result;
    }
Example #8
0
bool PmvPlayer::play(const char *filename) {

	_aborted = false;
	_surface = NULL;

	_fd = new Common::File();
	if (!_fd->open(filename)) {
		delete _fd;
		return false;
	}

	uint32 chunkType, chunkSize, prevChunkSize = 0;

	readChunk(chunkType, chunkSize);	// "MOVE"
	if (chunkType != MKTAG('M','O','V','E')) {
		warning("Unexpected PMV video header, expected 'MOVE'");
		delete _fd;
		return false;
	}

	readChunk(chunkType, chunkSize);	// "MHED"
	if (chunkType != MKTAG('M','H','E','D')) {
		warning("Unexpected PMV video header, expected 'MHED'");
		delete _fd;
		return false;
	}

	uint frameDelay = _fd->readUint16LE();
	_fd->skip(4);	// always 0?
	uint frameCount = _fd->readUint16LE();
	_fd->skip(4);	// always 0?

	uint soundFreq = _fd->readUint16LE();
	// Note: There seem to be weird sound frequencies in PMV videos.
	// Not sure why, but leaving those original frequencies intact
	// results to sound being choppy. Therefore, we set them to more
	// "common" values here (11025 instead of 11127 and 22050 instead
	// of 22254)
	if (soundFreq == 11127) soundFreq = 11025;
	if (soundFreq == 22254) soundFreq = 22050;

	for (int i = 0; i < 22; i++) {
		int unk = _fd->readUint16LE();
		debug(2, "%i ", unk);
	}

	_mixer->stopAll();

	// Read palette
	_fd->read(_paletteRGB, 768);
	_vm->_screen->setRGBPalette(_paletteRGB);

	uint32 frameNumber = 0;
	uint16 chunkCount = 0;
	uint32 soundSize = 0;
	uint32 soundChunkOfs = 0, palChunkOfs = 0;
	uint32 palSize = 0;
	byte *frameData = 0, *audioData, *soundData, *palData, *imageData;
	bool firstTime = true;

	uint32 soundStartTime = 0, skipFrames = 0;

	uint32 bytesRead;
	uint16 width, height, cmdOffs, pixelOffs, maskOffs, lineSize;

	// TODO: Sound can still be a little choppy. A bug in the decoder or -
	// perhaps more likely - do we have to implement double buffering to
	// get it to work well?
	_audioStream = Audio::makeQueuingAudioStream(soundFreq, false);

	while (!_vm->shouldQuit() && !_aborted && !_fd->eos() && frameNumber < frameCount) {

		int32 frameTime = _vm->_system->getMillis();

		readChunk(chunkType, chunkSize);
		if (chunkType != MKTAG('M','F','R','M')) {
			warning("Unknown chunk type");
		}

		// Only reallocate the frame data buffer if its size has changed
		if (prevChunkSize != chunkSize || !frameData) {
			delete[] frameData;
			frameData = new byte[chunkSize];
		}

		prevChunkSize = chunkSize;

		bytesRead = _fd->read(frameData, chunkSize);

		if (bytesRead < chunkSize || _fd->eos())
			break;

		soundChunkOfs = READ_LE_UINT32(frameData + 8);
		palChunkOfs = READ_LE_UINT32(frameData + 16);

		// Handle audio
		if (soundChunkOfs) {
			audioData = frameData + soundChunkOfs - 8;
			chunkSize = READ_LE_UINT16(audioData + 4);
			chunkCount = READ_LE_UINT16(audioData + 6);

			debug(1, "chunkCount = %d; chunkSize = %d; total = %d\n", chunkCount, chunkSize, chunkCount * chunkSize);

			soundSize = chunkCount * chunkSize;
			soundData = (byte *)malloc(soundSize);
			decompressSound(audioData + 8, soundData, chunkSize, chunkCount);
			_audioStream->queueBuffer(soundData, soundSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED);
		}

		// Handle palette
		if (palChunkOfs) {
			palData = frameData + palChunkOfs - 8;
			palSize = READ_LE_UINT32(palData + 4);
			decompressPalette(palData + 8, _paletteRGB, palSize);
			_vm->_screen->setRGBPalette(_paletteRGB);
		}

		// Handle video
		imageData = frameData + READ_LE_UINT32(frameData + 12) - 8;

		// frameNum @0
		width = READ_LE_UINT16(imageData + 8);
		height = READ_LE_UINT16(imageData + 10);
		cmdOffs = READ_LE_UINT16(imageData + 12);
		pixelOffs = READ_LE_UINT16(imageData + 16);
		maskOffs = READ_LE_UINT16(imageData + 20);
		lineSize = READ_LE_UINT16(imageData + 24);

		debug(2, "width = %d; height = %d; cmdOffs = %04X; pixelOffs = %04X; maskOffs = %04X; lineSize = %d\n",
			width, height, cmdOffs, pixelOffs, maskOffs, lineSize);

		if (!_surface) {
			_surface = new Graphics::Surface();
			_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
		}

		decompressMovieImage(imageData, *_surface, cmdOffs, pixelOffs, maskOffs, lineSize);

		if (firstTime) {
			_mixer->playStream(Audio::Mixer::kPlainSoundType, &_audioStreamHandle, _audioStream);
			soundStartTime = g_system->getMillis();
			skipFrames = 0;
			firstTime = false;
		}

		handleEvents();
		updateScreen();

		if (skipFrames == 0) {
			int32 waitTime = (frameNumber * frameDelay) -
				(g_system->getMillis() - soundStartTime) - (_vm->_system->getMillis() - frameTime);

			if (waitTime < 0) {
				skipFrames = -waitTime / frameDelay;
				warning("Video A/V sync broken, skipping %d frame(s)", skipFrames + 1);
			} else if (waitTime > 0)
				g_system->delayMillis(waitTime);

		} else
			skipFrames--;

		frameNumber++;

	}

	delete[] frameData;

	_audioStream->finish();
	_mixer->stopHandle(_audioStreamHandle);

	//delete _audioStream;
	delete _fd;
	_surface->free();
	delete _surface;

	return !_aborted;

}
Example #9
0
TResult CKKMApi::loadKKMData(QByteArray& baOutData)
{
	LOG_DBG("loadKKMData ==>");
	TResult nRet = kResult_Success;
	
	do
	{
		QByteArray readData;
		QByteArray baPacket;

		if ((nRet = readChunk(readData, defs::nReadDataTimeout)) != kResult_Success)
			break;
		
		char cPrevByte = 0x0;
		char cByte     = 0x0;

		bool bSTX            = false;
		bool bPacketComplete = false;
		for (int i = 0; i < readData.size(); ++i)
		{
			cByte = readData.at(i);
			if (cByte == defs::cSTX)
				bSTX = true;

			if (bSTX)
			{
				baPacket.append(cByte);
				if ((cPrevByte != defs::cDLE)&&(cByte == defs::cETX))
				{
					bPacketComplete = true;
					break;	
				}
				cPrevByte = cByte;
			}
		}

		if(!bSTX)
		{
			LOG_DBG("CKKMApi::loadKKMData, can`t find STX byte.");
			nRet = kResult_ReadError;
			break;
		}

		if(!bPacketComplete)
		{
			do
			{
				QByteArray readDataEx;
				if ((nRet = readChunk(readDataEx, defs::nReadByteTimeout)) != kResult_Success)
					break;

				cPrevByte = 0x0;
				cByte     = 0x0;
				for (int i = 0; i < readDataEx.size(); ++i)
				{
					cByte = readDataEx.at(i);
					baPacket.append(cByte);
					if ((cPrevByte != defs::cDLE)&&(cByte == defs::cETX))
					{
						bPacketComplete = true;
						break;	
					}
					cPrevByte = cByte;
				}
			}
			while(!bPacketComplete);
			if(nRet != kResult_Success)
				break;
		}

		baOutData = demaskCommand(baPacket);
		LOG_DBG("CKKMApi::loadKKMData, data  : "<<ba2hex(baOutData));
	}
	while(false);
	LOG_DBG("loadKKMData <==");
	return nRet;
}
Example #10
0
    bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm)
    {
        if (!iTreeValues)
        {
            TC_LOG_ERROR("misc", "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY);
            return false;
        }
        bool result = true;

        TileFileOpenResult fileResult = OpenMapTileFile(iBasePath, iMapID, tileX, tileY, vm);
        if (fileResult.File)
        {
            char chunk[8];

            if (!readChunk(fileResult.File, chunk, VMAP_MAGIC, 8))
                result = false;
            uint32 numSpawns = 0;
            if (result && fread(&numSpawns, sizeof(uint32), 1, fileResult.File) != 1)
                result = false;
            for (uint32 i=0; i<numSpawns && result; ++i)
            {
                // read model spawns
                ModelSpawn spawn;
                result = ModelSpawn::readFromFile(fileResult.File, spawn);
                if (result)
                {
                    // acquire model instance
                    WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name, spawn.flags);
                    if (!model)
                        TC_LOG_ERROR("misc", "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY);

                    // update tree
                    auto spawnIndex = iSpawnIndices.find(spawn.ID);
                    if (spawnIndex != iSpawnIndices.end())
                    {
                        uint32 referencedVal = spawnIndex->second;
                        if (!iLoadedSpawns.count(referencedVal))
                        {
                            if (referencedVal >= iNTreeValues)
                            {
                                TC_LOG_ERROR("maps", "StaticMapTree::LoadMapTile() : invalid tree element (%u/%u) referenced in tile %s", referencedVal, iNTreeValues, fileResult.Name.c_str());
                                continue;
                            }

                            iTreeValues[referencedVal] = ModelInstance(spawn, model);
                            iLoadedSpawns[referencedVal] = 1;
                        }
                        else
                        {
                            ++iLoadedSpawns[referencedVal];
#ifdef VMAP_DEBUG
                            if (iTreeValues[referencedVal].ID != spawn.ID)
                                TC_LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : trying to load wrong spawn in node");
                            else if (iTreeValues[referencedVal].name != spawn.name)
                                TC_LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : name collision on GUID=%u", spawn.ID);
#endif
                        }
                    }
                    else
                        result = false;
                }
            }
            iLoadedTiles[packTileID(tileX, tileY)] = true;
            fclose(fileResult.File);
        }
        else
            iLoadedTiles[packTileID(tileX, tileY)] = false;
        TC_METRIC_EVENT("map_events", "LoadMapTile",
            "Map: " + std::to_string(iMapID) + " TileX: " + std::to_string(tileX) + " TileY: " + std::to_string(tileY));
        return result;
    }
    bool readValue(VLXValue& val)
    {
      unsigned char chunk = 0;

      if (!readChunk(chunk))
        return false;

      std::string str;

      switch(chunk)
      {

      case VLB_ChunkStructure:
        val.setStructure( new VLXStructure );
        return parseStructure( val.getStructure() );
      
      case VLB_ChunkList:
        val.setList( new VLXList );
        return parseList( val.getList() );

      case VLB_ChunkArrayInteger:
        {
          // tag
          if (!readString(str))
            return false;
          else
            val.setArrayInteger( new VLXArrayInteger( str.c_str() ) );

          // count
          long long count = 0;
          if (!readInteger(count))
            return false;

          // values
          VLXArrayInteger& arr = *val.getArrayInteger();
          if (count)
          {
            long long encode_count = 0;
            if (!readInteger(encode_count))
              return false;
            VL_CHECK(encode_count >= 0)
            if (encode_count)
            {
              std::vector<unsigned char> encoded;
              encoded.resize((size_t)encode_count);
              inputFile()->readUInt8(&encoded[0], encode_count);
              decodeIntegers(encoded, arr.value());
            }
          }
          VL_CHECK((size_t)count == arr.value().size())
          return (size_t)count == arr.value().size();
        }

      case VLB_ChunkArrayRealDouble:
        {
          // tag
          if (!readString(str))
            return false;
          else
            val.setArrayReal( new VLXArrayReal( str.c_str() ) );
          // count
          long long count = 0;
          if (!readInteger(count))
            return false;
          // values
          VLXArrayReal& arr = *val.getArrayReal();
          arr.value().resize( (size_t)count );
          if (count)
          {
#if 1
            long long c = inputFile()->readDouble( &arr.value()[0], count );
            VL_CHECK(c == count * (int)sizeof(double))
            return c == count * (int)sizeof(double);
#elif 0
            long long zsize = 0;
            readInteger(zsize);
            std::vector<unsigned char> zipped;
            zipped.resize((size_t)zsize);
            inputFile()->read(&zipped[0], zipped.size());
            bool ok = decompress(&zipped[0], (size_t)zsize, &arr.value()[0]);
            VL_CHECK(ok);
            return ok;
#endif
          }
          else
            return true;
        }

      case VLB_ChunkArrayRealFloat:
        {
          // tag
          if (!readString(str))
            return false;
          else
            val.setArrayReal( new VLXArrayReal( str.c_str() ) );
          // count
          long long count = 0;
          if (!readInteger(count))
            return false;
          // values
          VLXArrayReal& arr = *val.getArrayReal();
          arr.value().resize( (size_t)count );
          if (count)
          {
#if 1
            std::vector<float> floats;
            floats.resize( (size_t)count );
            long long c = inputFile()->readFloat( &floats[0], count );
            // copy over floats to doubles
            for(size_t i=0; i<floats.size(); ++i)
              arr.value()[i] = floats[i];
            VL_CHECK(c == count * (int)sizeof(float))
            return c == count * (int)sizeof(float);
#elif 0
            long long zsize = 0;
            readInteger(zsize);
            std::vector<unsigned char> zipped;
            zipped.resize((size_t)zsize);
            inputFile()->read(&zipped[0], zipped.size());
            bool ok = decompress(&zipped[0], (size_t)zsize, &arr.value()[0]);
            VL_CHECK(ok);
            return ok;
#endif
          }
          else
            return true;
        }
    bool parse()
    {
      class CloseFileClass
      {
      public:
        CloseFileClass(VirtualFile* f): mFile(f) {}
        ~CloseFileClass()
        {
          if (mFile)
            mFile->close();
        }
      private:
        ref<VirtualFile> mFile;
      } CloseFile(inputFile());

      inputFile()->close();
      inputFile()->open(OM_ReadOnly);

      // clear metadata
      mMetadata.clear();

      // read version and encoding
      mVersion = 0;
      mEncoding.clear();

      if (!parseHeader())
      {
        Log::error("VLXParserVLB : error parsing VLB header.\n");
        return false;
      }

      if (mVersion != 100)
      {
        Log::error("VLX version not supported.\n");
        return false;
      }

      if (mEncoding != "ascii")
      {
        Log::error("Encoding not supported.\n");
        return false;
      }

      unsigned char chunk;
      std::string str;

      while(readChunk(chunk))
      {
        if(chunk == VLB_ChunkStructure)
        {
          ref<VLXStructure> st = new VLXStructure;

          if (!parseStructure(st.get()))
          {
            Log::error( Say("Error parsing binary file at offset %n.\n") << inputFile()->position() );
            return false;
          }

          mStructures.push_back(st);
        }
        else
        {
          Log::error( Say("Error parsing binary file at offset %n. Expected chunk structure.\n") << inputFile()->position() );
          return false;
        }
      }

      parseMetadata();

      return true;
    }