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; }
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; }
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(¤tLetter,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(¤tLetter,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(¤tLetter,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(¤tLetter,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; }
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; }
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; }
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; }
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; }
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; }