/** * Private method which is used to register new resource to manager container. It can be called from Lua script. * @param name is new resource name id. * @param path is new resource file layer path. * @param path2 is new resource file layer path. * @param path3 is new resource file layer path. * @param path4 is new resource file layer path. * @param path5 is new resource file layer path. * @param path6 is new resource file layer path. * @param type is new resource type. */ void TextureManager::registerResource(const string& name, const string& path, const string& path2, const string& path3,const string& path4, const string& path5, const string& path6, const string& type) { Texture* textureResource = nullptr; textureResource = textureFactory->createTextureResource(name,path,path2,path3,path4,path5,path6,type); addResource(name,TextureResource(textureResource)); }
TEST_F(ResourceManagerServiceTest, addResource) { addResource(); }
Quarry::Quarry(sf::Vector2i const& coords) : Resource(coords) { mType = Buildings::Quarry; addTile(coords,"building",sf::IntRect(1024,0,256,256)); addResource(Resources::Rock,1000); }
void testReclaimResourceSecure() { Vector<MediaResource> resources; resources.push_back(MediaResource(String8(kResourceSecureCodec), 1)); resources.push_back(MediaResource(String8(kResourceGraphicMemory), 150)); // ### secure codec can't coexist and secure codec can coexist with non-secure codec ### { addResource(); mService->mSupportsMultipleSecureCodecs = false; mService->mSupportsSecureWithNonSecureCodec = true; // priority too low EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources)); // reclaim all secure codecs EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(true /* c1 */, false /* c2 */, true /* c3 */); // call again should reclaim one largest graphic memory from lowest process EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // nothing left EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ### { addResource(); mService->mSupportsMultipleSecureCodecs = false; mService->mSupportsSecureWithNonSecureCodec = false; // priority too low EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources)); // reclaim all secure and non-secure codecs EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(true /* c1 */, true /* c2 */, true /* c3 */); // nothing left EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ### { addResource(); mService->mSupportsMultipleSecureCodecs = true; mService->mSupportsSecureWithNonSecureCodec = false; // priority too low EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources)); // reclaim all non-secure codecs EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // call again should reclaim one largest graphic memory from lowest process EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); // call again should reclaim another largest graphic memory from lowest process EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, false /* c2 */, true /* c3 */); // nothing left EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codecs can coexist and secure codec can coexist with non-secure codec ### { addResource(); mService->mSupportsMultipleSecureCodecs = true; mService->mSupportsSecureWithNonSecureCodec = true; // priority too low EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); // one largest graphic memory from lowest process got reclaimed verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); // call again should reclaim another graphic memory from lowest process EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // call again should reclaim another graphic memory from lowest process EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, false /* c2 */, true /* c3 */); // nothing left EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codecs can coexist and secure codec can coexist with non-secure codec ### { addResource(); mService->mSupportsMultipleSecureCodecs = true; mService->mSupportsSecureWithNonSecureCodec = true; Vector<MediaResource> resources; resources.push_back(MediaResource(String8(kResourceSecureCodec), 1)); EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); // secure codec from lowest process got reclaimed verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); // call again should reclaim another secure codec from lowest process EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, false /* c2 */, true /* c3 */); // no more secure codec, non-secure codec will be reclaimed. EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); } }
void testReclaimResourceNonSecure() { Vector<MediaResource> resources; resources.push_back(MediaResource(String8(kResourceNonSecureCodec), 1)); resources.push_back(MediaResource(String8(kResourceGraphicMemory), 150)); // ### secure codec can't coexist with non-secure codec ### { addResource(); mService->mSupportsSecureWithNonSecureCodec = false; // priority too low EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources)); // reclaim all secure codecs EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(true /* c1 */, false /* c2 */, true /* c3 */); // call again should reclaim one graphic memory from lowest process EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // nothing left EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codec can coexist with non-secure codec ### { addResource(); mService->mSupportsSecureWithNonSecureCodec = true; // priority too low EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources)); EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); // one largest graphic memory from lowest process got reclaimed verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); // call again should reclaim another graphic memory from lowest process EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // call again should reclaim another graphic memory from lowest process EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(false /* c1 */, false /* c2 */, true /* c3 */); // nothing left EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources)); } // ### secure codec can coexist with non-secure codec ### { addResource(); mService->mSupportsSecureWithNonSecureCodec = true; Vector<MediaResource> resources; resources.push_back(MediaResource(String8(kResourceNonSecureCodec), 1)); EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); // one non secure codec from lowest process got reclaimed verifyClients(false /* c1 */, true /* c2 */, false /* c3 */); // no more non-secure codec, secure codec from lowest priority process will be reclaimed EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources)); verifyClients(true /* c1 */, false /* c2 */, false /* c3 */); // clean up client 3 which still left mService->removeResource(kTestPid2, getId(mTestClient3)); } }
Model* ModelManager::loadMD2( const char* filename ){ // The md2 file format is specified as follows // ___________ // | HEAD | // -----|----- // _____|_____ // | DATA | // ----------- // // Head is of fixed size, and is defined in the ModelHeader struct // Data contains lists of texnames, texcoordinates, triangles, frames (vertices), // and GLCommands. // // We will first define pointers so that we can dynamically load in memory (because // of varying model-sizes), and after that we will: // 1) Check if the model is an md2 file // 2) Check if it's md2 version 8 (we will require this) // 3) Copy the header data into our classvariables // 4) Allocate the memory for our buffers and VBO // 5) Load in our buffers // 6) Create our VBO and elements object. // 7) Bind these buffers // 8) Clean up, release data //Define pointers and other variables ModelHeader* head; frame* framePtr; triangle* trianglePtr; texCoo* texCooPtr; //Open the file std::string location; location += "models/"; location += filename; location += ".md2"; const File* modelfile = Filesystem::getSingleton().getFile(location.c_str()); if(!modelfile){ Logger::getSingleton() << Logger::WARNING << "Could not load modelfile: " << filename << endLog; return NULL; } head = (ModelHeader*)modelfile->data; // 1) Check if the model is an md2 file // 2) Check if it's md2 version 8 (we will require this) if( modelfile->size < sizeof(ModelHeader) || (head->identity != MD2_IDENTITY) || (head->version != MD2_VERSION)) { Logger::getSingleton() << Logger::WARNING << "File is not a valid MD2 model file: " << filename << endLog; Filesystem::getSingleton().unloadFile(modelfile); return NULL; } MD2Model* model = new MD2Model; // 3) Copy the header data into our classvariables model->frameCount = head->nFrames; model->frameSize = head->frameSize; model->triangleCount = head->nTriangles; if(model->frameCount > 1){ model->animated = true; } model->triangleCount = head->nTriangles; Mesh* modelMesh = new Mesh; char* buffer = modelfile->data + head->oFrames; //size = frameSize * frameCount trianglePtr = (triangle*)(modelfile->data + head->oTriangles); //size = sizeof(triangle) * triangleCount * frameCount texCooPtr = (texCoo*)(modelfile->data + head->oTexCoo); //size = sizeof(texCoo) * head.nTexCoo; // 6) Create our VBO and elements object. GLfloat* vertices = new GLfloat[(model->triangleCount * 3) * 12 * model->frameCount]; for( int j = 0; j < model->frameCount; j++ ) { //we need to adjust our pointer every loop (frame) framePtr = (frame*)&buffer[j * model->frameSize]; int frameOffset = (j * (model->triangleCount * 3) * 12); for( int k = 0; k < model->triangleCount; k++ ) { for(int m = 0; m < 3; m++) { int index = trianglePtr[k].vert[m]; int texcooindex = trianglePtr[k].tex[m]; int triangleOffset = (12 * (3*k + m)); //vertices vertices[frameOffset + triangleOffset + 0] = (framePtr->verts[index].v[1] * framePtr->scale[1]) + framePtr->translate[1]; vertices[frameOffset + triangleOffset + 1] = (framePtr->verts[index].v[2] * framePtr->scale[2]) + framePtr->translate[2]; vertices[frameOffset + triangleOffset + 2] = -((framePtr->verts[index].v[0] * framePtr->scale[0]) + framePtr->translate[0]); //color vertices[frameOffset + triangleOffset + 3] = 1.0f; vertices[frameOffset + triangleOffset + 4] = 1.0f; vertices[frameOffset + triangleOffset + 5] = 1.0f; vertices[frameOffset + triangleOffset + 6] = 1.0f; //normals vertices[frameOffset + triangleOffset + 7] = model->anorms[framePtr->verts[index].lightnormalindex][1]; vertices[frameOffset + triangleOffset + 8] = model->anorms[framePtr->verts[index].lightnormalindex][2]; vertices[frameOffset + triangleOffset + 9] = -model->anorms[framePtr->verts[index].lightnormalindex][0]; //texcoo vertices[frameOffset + triangleOffset + 10] = (float)texCooPtr[texcooindex].s / head->textureWidth; vertices[frameOffset + triangleOffset + 11] = ((float)texCooPtr[texcooindex].t / head->textureHeight); } } } // 7) Bind these buffers glGenBuffers(1, &modelMesh->vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, modelMesh->vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * model->triangleCount * 3 * 12 * model->frameCount, vertices, GL_STATIC_DRAW); delete[] vertices; modelMesh->hasColor = true; modelMesh->hasNormal = true; modelMesh->hasIndexBuffer = false; modelMesh->vertexCount = model->triangleCount * 3; modelMesh->vertexBufferSize = sizeof(GLfloat) * model->triangleCount * 3 * 12; //modelMesh->vertexBufferDataType = GL_FLOAT; modelMesh->primitiveType = GL_TRIANGLES; modelMesh->dimension = 3; modelMesh->stride = 48; //modelMesh->vertexOffset = 0; model->setMesh(modelMesh); std::string location_texture; location_texture += "textures/"; location_texture += filename; location_texture += ".tga"; model->setMaterial( MaterialManager::getSingleton().getMaterial(location_texture.c_str()) ); // delete file Filesystem::getSingleton().unloadFile(modelfile); addResource(filename, model); return getResource(filename);; }
bool onut::PropertyManager::loadPropertiesFromJson(const Json::Value& json) { for (auto &member : json.getMemberNames()) { auto propertyIT = m_properties.find(member); if (propertyIT == m_properties.end()) continue; auto &propertyLink = propertyIT->second; auto &jsonElement = json[member]; switch (propertyLink.type) { case ePropertyType::P_BOOL: if (jsonElement.isBool()) { *(bool*)propertyLink.pProperty = jsonElement.asBool(); } break; case ePropertyType::P_INT: if (jsonElement.isInt()) { *(int*)propertyLink.pProperty = jsonElement.asInt(); } break; case ePropertyType::P_FLOAT: if (jsonElement.isDouble()) { *(float*)propertyLink.pProperty = static_cast<float>(jsonElement.asDouble()); } break; case ePropertyType::P_STRING: if (jsonElement.isString()) { *(std::string*)propertyLink.pProperty = jsonElement.asCString(); } break; case ePropertyType::P_POINT: if (jsonElement.isArray() && jsonElement.size() == 2) { auto &x = jsonElement[0]; auto &y = jsonElement[1]; if (x.isInt() && y.isInt()) { ((glm::tvec2<int>*)propertyLink.pProperty)->x = x.asInt(); ((glm::tvec2<int>*)propertyLink.pProperty)->y = y.asInt(); } } break; case ePropertyType::P_VEC2: if (jsonElement.isArray() && jsonElement.size() == 2) { auto &x = jsonElement[0]; auto &y = jsonElement[1]; if (x.isDouble() && y.isDouble()) { ((glm::vec2*)propertyLink.pProperty)->x = static_cast<float>(x.asDouble()); ((glm::vec2*)propertyLink.pProperty)->y = static_cast<float>(y.asDouble()); } } break; case ePropertyType::P_VEC3: if (jsonElement.isArray() && jsonElement.size() == 3) { auto &x = jsonElement[0]; auto &y = jsonElement[1]; auto &z = jsonElement[2]; if (x.isDouble() && y.isDouble() && z.isDouble()) { ((glm::vec3*)propertyLink.pProperty)->x = static_cast<float>(x.asDouble()); ((glm::vec3*)propertyLink.pProperty)->y = static_cast<float>(y.asDouble()); ((glm::vec3*)propertyLink.pProperty)->z = static_cast<float>(z.asDouble()); } } break; case ePropertyType::P_VEC4: if (jsonElement.isArray() && jsonElement.size() == 4) { auto &x = jsonElement[0]; auto &y = jsonElement[1]; auto &z = jsonElement[2]; auto &w = jsonElement[3]; if (x.isDouble() && y.isDouble() && z.isDouble() && w.isDouble()) { ((glm::vec4*)propertyLink.pProperty)->x = static_cast<float>(x.asDouble()); ((glm::vec4*)propertyLink.pProperty)->y = static_cast<float>(y.asDouble()); ((glm::vec4*)propertyLink.pProperty)->z = static_cast<float>(z.asDouble()); ((glm::vec4*)propertyLink.pProperty)->w = static_cast<float>(w.asDouble()); } } break; case ePropertyType::P_ENTITY_ARRAY: if (jsonElement.isArray()) { auto pMyEntity = dynamic_cast<Entity*>(this); auto pEntities = static_cast<ObjectVector<Entity>*>(propertyLink.pProperty); for (auto &jsonEntity : jsonElement) { if (jsonEntity.isObject()) { if (pMyEntity) { auto pEntity = new onut::Entity(); pEntity->retain(); pEntity->loadPropertiesFromJson(jsonEntity); if (pEntities == &pMyEntity->getChildren()) { pMyEntity->add(pEntity); } else { pEntities->push_back(pEntity); } pEntity->release(); } else { assert(false); // TODO } } } } break; case ePropertyType::P_COMPONENT_ARRAY: if (jsonElement.isArray()) { auto pComponentManager = dynamic_cast<ComponentManager*>(this); auto pComponents = static_cast<ObjectVector<Component>*>(propertyLink.pProperty); for (auto &jsonComponent : jsonElement) { if (jsonComponent.isArray() && jsonComponent.size() == 2 && jsonComponent[0].isString() && jsonComponent[1].isObject()) { auto szComponentClassName = jsonComponent[0].asCString(); auto pComponentObject = ObjectLibrary::createObject(szComponentClassName); if (!pComponentObject) continue; auto pComponent = dynamic_cast<onut::Component*>(pComponentObject); if (!pComponent) continue; pComponent->loadPropertiesFromJson(jsonComponent[1]); pComponent->retain(); if (pComponentManager && pComponents == &pComponentManager->getComponents()) { pComponentManager->addComponent(pComponent); pComponent->release(); } else { pComponents->push_back(pComponent); } } } } break; case ePropertyType::P_MATERIAL: if (jsonElement.isString()) { auto ppMaterial = static_cast<onut::Material**>(propertyLink.pProperty); auto pContentManager = Game::getGame()->getComponent<ContentManager>(); if (ppMaterial && pContentManager) { auto filename = "assets/" + jsonElement.asString(); auto pMaterial = pContentManager->getResource<onut::Material>(filename); if (!pMaterial) { pMaterial = new onut::Material(); if (!pMaterial->loadPropertiesFromFile(filename)) { pMaterial->release(); break; } pContentManager->addResource(filename, pMaterial); } pMaterial->retain(); *ppMaterial = pMaterial; } } break; case ePropertyType::P_MESH: if (jsonElement.isString()) { auto ppMesh = static_cast<onut::Mesh**>(propertyLink.pProperty); auto pContentManager = Game::getGame()->getComponent<ContentManager>(); if (ppMesh && pContentManager) { auto filename = "assets/" + jsonElement.asString(); auto pMesh = pContentManager->getResource<onut::Mesh>(filename); if (!pMesh) { pMesh = onut::Mesh::create(); if (!pMesh->load(filename)) { pMesh->release(); break; } pContentManager->addResource(filename, pMesh); } pMesh->retain(); *ppMesh = pMesh; } } break; case ePropertyType::P_TEXTURE: if (jsonElement.isString()) { auto ppTexture = static_cast<onut::Texture**>(propertyLink.pProperty); auto pContentManager = Game::getGame()->getComponent<ContentManager>(); if (ppTexture && pContentManager) { auto filename = "assets/" + jsonElement.asString(); auto pTexture = pContentManager->getResource<onut::Texture>(filename); if (!pTexture) { pTexture = onut::Texture::create(); if (!pTexture->load(filename)) { pTexture->release(); break; } pContentManager->addResource(filename, pTexture); } pTexture->retain(); *ppTexture = pTexture; } } break; default: assert(false); } } return true; }
void AssetBrowser::update() { PROFILE_FUNCTION(); auto* patch = m_editor.getEngine().getPatchFileDevice(); if ((patch && !Lumix::equalStrings(patch->getBasePath(), m_patch_base_path)) || (!patch && m_patch_base_path[0] != '\0')) { findResources(); } if (!m_is_update_enabled) return; bool is_empty; { Lumix::MT::SpinLock lock(m_changed_files_mutex); is_empty = m_changed_files.empty(); } while (!is_empty) { Lumix::Path path; { Lumix::MT::SpinLock lock(m_changed_files_mutex); path = m_changed_files.back(); m_changed_files.pop(); is_empty = m_changed_files.empty(); } char ext[10]; Lumix::PathUtils::getExtension(ext, Lumix::lengthOf(ext), path.c_str()); m_on_resource_changed.invoke(path, ext); Lumix::uint32 resource_type = getResourceType(path.c_str()); if (resource_type == 0) continue; if (m_autoreload_changed_resource) m_editor.getEngine().getResourceManager().reload(path); char tmp_path[Lumix::MAX_PATH_LENGTH]; if (m_editor.getEngine().getPatchFileDevice()) { Lumix::copyString(tmp_path, m_editor.getEngine().getPatchFileDevice()->getBasePath()); Lumix::catString(tmp_path, path.c_str()); } if (!m_editor.getEngine().getPatchFileDevice() || !PlatformInterface::fileExists(tmp_path)) { Lumix::copyString(tmp_path, m_editor.getEngine().getDiskFileDevice()->getBasePath()); Lumix::catString(tmp_path, path.c_str()); if (!PlatformInterface::fileExists(tmp_path)) { int index = getTypeIndexFromManagerType(resource_type); m_resources[index].eraseItemFast(path); continue; } } char dir[Lumix::MAX_PATH_LENGTH]; char filename[Lumix::MAX_PATH_LENGTH]; Lumix::PathUtils::getDir(dir, sizeof(dir), path.c_str()); Lumix::PathUtils::getFilename(filename, sizeof(filename), path.c_str()); addResource(dir, filename); } m_changed_files.clear(); }
void createTessellatedQuadBuffers(Buffer** ppVertexBuffer, Buffer** ppIndexBuffer, unsigned tessellationX, unsigned tessellationY) { ASSERT(tessellationX >= 1); ASSERT(tessellationY >= 1); // full screen quad coordinates [-1, -1] to [1, 1] -> width & height = 2 const float width = 2.0f; const float height = 2.0f; const float dx = width / tessellationX; const float dy = height / tessellationY; const int numQuads = tessellationX * tessellationY; const int numVertices = (tessellationX + 1) * (tessellationY + 1); tinystl::vector<vec4> vertices(numVertices); const unsigned m = tessellationX + 1; const unsigned n = tessellationY + 1; for (unsigned i = 0; i < n; ++i) { const float y = i * dy - 1.0f; // offset w/ -1.0f : [0,2]->[-1,1] for (unsigned j = 0; j < m; ++j) { const float x = j * dx - 1.0f; // offset w/ -1.0f : [0,2]->[-1,1] vertices[i*m + j] = vec4(x, y, 0, 1); } } BufferLoadDesc vbDesc = {}; vbDesc.mDesc.mUsage = BUFFER_USAGE_VERTEX; vbDesc.mDesc.mMemoryUsage = RESOURCE_MEMORY_USAGE_GPU_ONLY; vbDesc.mDesc.mSize = vertices.size() * sizeof(vec4); vbDesc.mDesc.mVertexStride = sizeof(vec4); vbDesc.pData = vertices.data(); vbDesc.ppBuffer = ppVertexBuffer; addResource(&vbDesc); // Tessellate the quad tinystl::vector<uint16_t> indices(numQuads * 6); // A +------+ B // | / | // | / | // | / | // | / | // |/ | // C +------+ D // // A : V(i , j ) // B : V(i , j+1) // C : V(i+1, j ) // D : V(i+1, j+1) // // ABC : (i*n +j , i*n + j+1, (i+1)*n + j ) // CBD : ((i+1)*n +j, i*n + j+1, (i+1)*n + j+1) unsigned quad = 0; for (unsigned i = 0; i < tessellationY; ++i) { for (unsigned j = 0; j < tessellationX; ++j) { indices[quad * 6 + 0] = (uint16_t)(i*m + j); indices[quad * 6 + 1] = (uint16_t)(i*m + j + 1); indices[quad * 6 + 2] = (uint16_t)((i + 1)*m + j); indices[quad * 6 + 3] = (uint16_t)((i + 1)*m + j); indices[quad * 6 + 4] = (uint16_t)(i*m + j + 1); indices[quad * 6 + 5] = (uint16_t)((i + 1)*m + j + 1); quad++; } } BufferLoadDesc ibDesc = {}; ibDesc.mDesc.mUsage = BUFFER_USAGE_INDEX; ibDesc.mDesc.mMemoryUsage = RESOURCE_MEMORY_USAGE_GPU_ONLY; ibDesc.mDesc.mSize = indices.size() * sizeof(uint16_t); ibDesc.mDesc.mIndexType = INDEX_TYPE_UINT16; ibDesc.pData = indices.data(); ibDesc.ppBuffer = ppIndexBuffer; addResource(&ibDesc); }
Forest::Forest(sf::Vector2i const& coords) : Resource(coords) { mType = Buildings::Forest; addTile(coords,"building",sf::IntRect(512,0,256,256)); addResource(Resources::Wood,1000); }
int main(int argc, char **argv) { const char *inputImage = NULL, *outputImage = NULL, *string = NULL, *file = NULL; unsigned long mode = 0, result = 0, id = 0; Elf32_ResType type = ELF_RES_TYPE_UNKNOWN; extern char *optarg; int c; while ((c = getopt(argc, argv, "lhupart:n:s:f:i:o:I:")) != EOF) { switch (c) { case 'h': fprintf(stderr, "Usage: elfres [-u/-p/-l/-a/-r] [-t type] [-s string] [-f file]\n" " [-I id] [-i input img] [-o output img]\n\n" " -p --> print a resource specified by an id.\n" " -u --> update a resource.\n" " -l --> list resources in the specified input file.\n" " -a --> add a resource to the specified input file\n" " and store it in the output file, if specified.\n" " -r --> remove a resource to the specified input file\n" " and store it in the output file, if specified.\n" " the resource is identified by an index (-n).\n"); return 0; case 'l': mode = OPERATION_LIST; break; case 'p': mode = OPERATION_PRINT; break; case 'a': mode = OPERATION_ADD; break; case 'r': mode = OPERATION_REM; break; case 'u': mode = OPERATION_UPDATE; break; case 't': if (!strcasecmp(optarg, "binary")) type = ELF_RES_TYPE_BINARY; else if (!strcasecmp(optarg, "string")) type = ELF_RES_TYPE_STRING; else type = ELF_RES_TYPE_UNKNOWN; break; case 's': string = optarg; break; case 'f': file = optarg; break; case 'I': id = strtoul(optarg, NULL, 10); break; case 'i': inputImage = optarg; break; case 'o': outputImage = optarg; break; default: break; } } if (!inputImage) { fprintf(stderr, "elfres: No input file was specified.\n"); return 0; } if (!outputImage) outputImage = inputImage; switch (mode) { case OPERATION_LIST: result = listResources(inputImage); break; case OPERATION_PRINT: if (!id) fprintf(stderr, "elfres: no identifier was specified (-I).\n"); else result = printResource(inputImage, id); break; case OPERATION_ADD: case OPERATION_UPDATE: if (!id) fprintf(stderr, "elfres: no identifier was specified (-I).\n"); else if (!string && !file) fprintf(stderr, "elfres: no data source was specified (-s/-f).\n"); else result = addResource(mode, inputImage, outputImage, type, id, string, file); break; case OPERATION_REM: if (!id) fprintf(stderr, "elfres: no identifier was specified (-I).\n"); else result = removeResource(inputImage, outputImage, id); break; default: fprintf(stderr, "elfres: unknown mode of operation.\n"); break; } if (!result) fprintf(stderr, "elfres: the operation did not complete successfully.\n"); return result; }
/** * Helper function to add resource to the menu. */ void ResourceMenu::addResource(const UserResource &r) { addResource(r.status().type(), r.name()); }
int MpTopologyGraph::addTopologyResources(MpResourceTopology& resourceTopology, MpResourceFactory& resourceFactory, UtlHashBag& newResources, UtlBoolean replaceNumInName, int resourceNum) { // Add the resources int resourceIndex = 0; MpResource* resourcePtr = NULL; MpResource* resourceArray[MAX_CONSTRUCTED_RESOURCES]; UtlString resourceType; UtlString resourceName; MpConnectionID resourceConnId; int resourceStreamId; OsStatus result; while(resourceTopology.getResource(resourceIndex, resourceType, resourceName, resourceConnId, resourceStreamId) == OS_SUCCESS) { if(replaceNumInName) { MpResourceTopology::replaceNumInName(resourceName, resourceNum); } int numConstructorResources; OsStatus status; status = resourceFactory.newResource(resourceType, resourceName, MAX_CONSTRUCTED_RESOURCES, numConstructorResources, resourceArray); if(status == OS_SUCCESS) { assert(numConstructorResources > 0); int arrayIndex; // We now can potentially get more than one resource back from the // constructor for(arrayIndex = 0; arrayIndex < numConstructorResources; arrayIndex++) { resourcePtr = resourceArray[arrayIndex]; assert(resourcePtr); if(resourcePtr) { #ifdef TEST_PRINT printf("constructed and adding resource name: %s type: %s\n", resourcePtr->getName().data(), resourceType.data()); #endif if(replaceNumInName && resourceConnId == MP_INVALID_CONNECTION_ID) { resourcePtr->setConnectionId(resourceNum); } else { resourcePtr->setConnectionId(resourceConnId); } resourcePtr->setStreamId(resourceStreamId); newResources.insert(resourcePtr); result = addResource(*resourcePtr, FALSE); assert(result == OS_SUCCESS); } } } else { OsSysLog::add(FAC_MP, PRI_ERR, "Failed to create resource type: %s name: %s status: %d", resourceType.data(), resourceName.data(), status); } resourceIndex++; } return(resourceIndex); }
SResourcePackage::SResourcePackage() : QDomDocument() { QDomElement root = createElement("Resources"); appendChild(root); // Leemos los datos desde un archivo de indices QFile rscIndex(HOME+"/data/index.rsc"); if( rscIndex.open( QIODevice::ReadOnly | QIODevice::Text)) { QDomDocument doc; if ( doc.setContent( &rscIndex ) ) { QDomElement docElem = doc.documentElement(); QDomNode n = docElem.firstChild(); QDomElement resource; while(!n.isNull()) { QDomElement e = n.toElement(); if(!e.isNull()) { dDebug() << e.tagName(); QString path = e.attribute("path"); QString name = e.attribute("name"); if( name.isEmpty() ) { QFileInfo finfo(path); name = finfo.fileName(); } if ( e.tagName() == "Image" ) { resource = createElement("Image"); resource.setAttribute("filename", name); addResource( resource, path ); documentElement().appendChild(resource); } else if ( e.tagName() == "Svg" ) { resource = createElement("Svg"); resource.setAttribute("filename", name); addResource( resource, path ); documentElement().appendChild(resource); } else if ( e.tagName() == "Sourd" ) { resource = createElement("Sourd"); resource.setAttribute("filename", name); addResource( resource, path ); documentElement().appendChild(resource); } } n = n.nextSibling(); } } else { dError() << "Invalid resource index file: " << rscIndex.fileName(); } rscIndex.close(); } }
int ResourceManager::readAudioMapSCI11(ResourceSource *map) { #ifndef ENABLE_SCI32 // SCI32 support is not built in. Check if this is a SCI32 game // and if it is abort here. if (_volVersion >= kResVersionSci2) return SCI_ERROR_RESMAP_NOT_FOUND; #endif uint32 offset = 0; Resource *mapRes = findResource(ResourceId(kResourceTypeMap, map->_volumeNumber), false); if (!mapRes) { warning("Failed to open %i.MAP", map->_volumeNumber); return SCI_ERROR_RESMAP_NOT_FOUND; } ResourceSource *src = findVolume(map, 0); if (!src) return SCI_ERROR_NO_RESOURCE_FILES_FOUND; byte *ptr = mapRes->data; // Heuristic to detect entry size uint32 entrySize = 0; for (int i = mapRes->size - 1; i >= 0; --i) { if (ptr[i] == 0xff) entrySize++; else break; } if (map->_volumeNumber == 65535) { while (ptr < mapRes->data + mapRes->size) { uint16 n = READ_LE_UINT16(ptr); ptr += 2; if (n == 0xffff) break; if (entrySize == 6) { offset = READ_LE_UINT32(ptr); ptr += 4; } else { offset += READ_LE_UINT24(ptr); ptr += 3; } addResource(ResourceId(kResourceTypeAudio, n), src, offset); } } else if (map->_volumeNumber == 0 && entrySize == 10 && ptr[3] == 0) { // QFG3 demo format // ptr[3] would be 'seq' in the normal format and cannot possibly be 0 while (ptr < mapRes->data + mapRes->size) { uint16 n = READ_BE_UINT16(ptr); ptr += 2; if (n == 0xffff) break; offset = READ_LE_UINT32(ptr); ptr += 4; uint32 size = READ_LE_UINT32(ptr); ptr += 4; addResource(ResourceId(kResourceTypeAudio, n), src, offset, size); } } else if (map->_volumeNumber == 0 && entrySize == 8 && READ_LE_UINT16(ptr + 2) == 0xffff) { // LB2 Floppy/Mother Goose SCI1.1 format Common::SeekableReadStream *stream = getVolumeFile(src); while (ptr < mapRes->data + mapRes->size) { uint16 n = READ_LE_UINT16(ptr); ptr += 4; if (n == 0xffff) break; offset = READ_LE_UINT32(ptr); ptr += 4; // The size is not stored in the map and the entries have no order. // We need to dig into the audio resource in the volume to get the size. stream->seek(offset + 1); byte headerSize = stream->readByte(); assert(headerSize == 11 || headerSize == 12); stream->skip(5); uint32 size = stream->readUint32LE() + headerSize + 2; addResource(ResourceId(kResourceTypeAudio, n), src, offset, size); } } else { bool isEarly = (entrySize != 11); if (!isEarly) { offset = READ_LE_UINT32(ptr); ptr += 4; } while (ptr < mapRes->data + mapRes->size) { uint32 n = READ_BE_UINT32(ptr); int syncSize = 0; ptr += 4; if (n == 0xffffffff) break; if (isEarly) { offset = READ_LE_UINT32(ptr); ptr += 4; } else { offset += READ_LE_UINT24(ptr); ptr += 3; } if (isEarly || (n & 0x80)) { syncSize = READ_LE_UINT16(ptr); ptr += 2; if (syncSize > 0) addResource(ResourceId(kResourceTypeSync36, map->_volumeNumber, n & 0xffffff3f), src, offset, syncSize); } if (n & 0x40) { // This seems to define the size of raw lipsync data (at least // in kq6), may also just be general appended data. syncSize += READ_LE_UINT16(ptr); ptr += 2; } addResource(ResourceId(kResourceTypeAudio36, map->_volumeNumber, n & 0xffffff3f), src, offset + syncSize); } } return 0; }
int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { #ifndef ENABLE_SCI32 // SCI32 support is not built in. Check if this is a SCI32 game // and if it is abort here. if (_volVersion >= kResVersionSci2) return SCI_ERROR_RESMAP_NOT_FOUND; #endif uint32 offset = 0; const ResourceId mapResId(kResourceTypeMap, map->_mapNumber); Resource *mapRes = _resMap.getVal(mapResId, nullptr); if (!mapRes) { warning("Failed to open %s", mapResId.toString().c_str()); return SCI_ERROR_RESMAP_NOT_FOUND; } // Here, we allocate audio maps ourselves instead of using findResource to // do this for us. This is in order to prevent the map resources from // getting into the LRU cache. These resources must be read and then // deallocated in games with multi-disc audio in order to read the audio // maps from every CD, and LRU eviction freaks out if an unallocated // resource ends up in the LRU list. It is also not necessary for these // resources to be cached in the LRU at all, since they are only used upon // game startup to populate _resMap. assert(mapRes->_status == kResStatusNoMalloc); loadResource(mapRes); if (!mapRes->data()) { warning("Failed to read data for %s", mapResId.toString().c_str()); return SCI_ERROR_RESMAP_NOT_FOUND; } ResourceSource *src = findVolume(map, map->_volumeNumber); if (!src) { warning("Failed to find volume for %s", mapResId.toString().c_str()); return SCI_ERROR_NO_RESOURCE_FILES_FOUND; } Common::SeekableReadStream *fileStream = getVolumeFile(src); if (!fileStream) { warning("Failed to open file stream for %s", src->getLocationName().c_str()); return SCI_ERROR_NO_RESOURCE_FILES_FOUND; } const uint32 srcSize = fileStream->size(); disposeVolumeFileStream(fileStream, src); SciSpan<const byte>::const_iterator ptr = mapRes->cbegin(); uint32 entrySize = 0; if (_volVersion >= kResVersionSci2) { // The heuristic size detection is incompatible with at least Torin RU, // which is fine because it is not needed for SCI32 entrySize = 11; } else { // Heuristic to detect entry size for (int i = mapRes->size() - 1; i >= 0; --i) { if (ptr[i] == 0xff) entrySize++; else break; } } if (map->_mapNumber == 65535) { while (ptr != mapRes->cend()) { uint16 n = ptr.getUint16LE(); ptr += 2; if (n == 0xffff) break; if (entrySize == 6) { offset = ptr.getUint32LE(); ptr += 4; } else { offset += ptr.getUint24LE(); ptr += 3; } addResource(ResourceId(kResourceTypeAudio, n), src, offset, 0, map->getLocationName()); } } else if (map->_mapNumber == 0 && entrySize == 10 && ptr[3] == 0) { // QFG3 demo format // ptr[3] would be 'seq' in the normal format and cannot possibly be 0 while (ptr != mapRes->cend()) { uint16 n = ptr.getUint16BE(); ptr += 2; if (n == 0xffff) break; offset = ptr.getUint32LE(); ptr += 4; uint32 size = ptr.getUint32LE(); ptr += 4; addResource(ResourceId(kResourceTypeAudio, n), src, offset, size, map->getLocationName()); } } else if (map->_mapNumber == 0 && entrySize == 8 && (ptr + 2).getUint16LE() == 0xffff) { // LB2 Floppy/Mother Goose SCI1.1 format Common::SeekableReadStream *stream = getVolumeFile(src); while (ptr != mapRes->cend()) { uint16 n = ptr.getUint16LE(); ptr += 4; if (n == 0xffff) break; const ResourceId audioResId(kResourceTypeAudio, n); offset = ptr.getUint32LE(); ptr += 4; uint32 size; if (src->getAudioCompressionType() == 0) { // The size is not stored in the map and the entries have no order. // We need to dig into the audio resource in the volume to get the size. stream->seek(offset + 1); byte headerSize = stream->readByte(); if (headerSize != 11 && headerSize != 12) { error("Unexpected header size in %s: should be 11 or 12, got %d", audioResId.toString().c_str(), headerSize); } stream->skip(7); size = stream->readUint32LE() + headerSize + 2; } else { size = 0; } addResource(audioResId, src, offset, size, map->getLocationName()); } disposeVolumeFileStream(stream, src); } else { // EQ1CD & SQ4CD are "early" games; KQ6CD and all SCI32 are "late" games const bool isEarly = (entrySize != 11); if (!isEarly) { offset = ptr.getUint32LE(); ptr += 4; } enum { kRaveFlag = 0x40, kSyncFlag = 0x80, kEndOfMapFlag = 0xFF }; while (ptr != mapRes->cend()) { uint32 n = ptr.getUint32BE(); uint32 syncSize = 0; ptr += 4; // Checking the entire tuple breaks Torin RU and is not how SSCI // works if ((n & kEndOfMapFlag) == kEndOfMapFlag) { const uint32 bytesLeft = mapRes->cend() - ptr; if (bytesLeft >= entrySize) { warning("End of %s reached, but %u entries remain", mapResId.toString().c_str(), bytesLeft / entrySize); } break; } // GK1CD has a message whose audio36 resource has the wrong tuple and never plays. // The message tuple is 420 2 32 0 1 but the audio36 tuple is 420 2 32 3 1. bug #10819 if (g_sci->getGameId() == GID_GK1 && g_sci->isCD() && map->_mapNumber == 420 && n == 0x02200301) { n = 0x02200001; } // QFG4CD has a message whose audio36 resource has the wrong tuple and never plays. // The message tuple is 510 23 1 0 1 but the audio36 tuple is 510 199 1 0 1. bug #10848 if (g_sci->getGameId() == GID_QFG4 && g_sci->isCD() && map->_mapNumber == 510 && n == 0xc7010001) { n = 0x17010001; } // QFG4CD has an orphaned audio36 resource that additionally has the wrong tuple. // The audio36 tuple is 520 2 59 0 3. The message would be 520 2 59 0 2. bug #10849 // We restore the missing message in message.cpp. if (g_sci->getGameId() == GID_QFG4 && g_sci->isCD() && map->_mapNumber == 520 && n == 0x023b0003) { n = 0x023b0002; } if (isEarly) { offset = ptr.getUint32LE(); ptr += 4; } else { offset += ptr.getUint24LE(); ptr += 3; } if (isEarly || (n & kSyncFlag)) { syncSize = ptr.getUint16LE(); ptr += 2; // FIXME: The sync36 resource seems to be two bytes too big in KQ6CD // (bytes taken from the RAVE resource right after it) if (syncSize > 0) { // TODO: Add a mechanism to handle cases with missing resources like the ones below // // LB2CD is missing the sync resource for message 1885 1 6 30 2 but it's a duplicate // of 1885 1 6 16 2 which does have a sync resource so use that for both. bug #9956 if (g_sci->getGameId() == GID_LAURABOW2 && map->_mapNumber == 1885 && n == 0x01061002) { addResource(ResourceId(kResourceTypeSync36, map->_mapNumber, 0x01061e02), src, offset, syncSize, map->getLocationName()); } addResource(ResourceId(kResourceTypeSync36, map->_mapNumber, n & 0xffffff3f), src, offset, syncSize, map->getLocationName()); } } // Checking for this 0x40 flag breaks at least Laura Bow 2 CD 1.1 // map 448 if (g_sci->getGameId() == GID_KQ6 && (n & kRaveFlag)) { // This seems to define the size of raw lipsync data (at least // in KQ6 CD Windows). uint32 kq6HiresSyncSize = ptr.getUint16LE(); ptr += 2; if (kq6HiresSyncSize > 0) { // Rave resources do not have separate entries in the audio // map (their data was just appended to sync resources), so // we have to use the sync resource offset first and then // adjust the offset & size later, otherwise offset // validation will fail for compressed volumes (since the // relocation table in a compressed volume only contains // offsets that existed in the original audio map) Resource *res = addResource(ResourceId(kResourceTypeRave, map->_mapNumber, n & 0xffffff3f), src, offset, syncSize + kq6HiresSyncSize, map->getLocationName()); res->_fileOffset += syncSize; res->_size -= syncSize; syncSize += kq6HiresSyncSize; } } const ResourceId id(kResourceTypeAudio36, map->_mapNumber, n & 0xffffff3f); // Map 405 on CD 1 of the US release of PQ:SWAT 1.000 is broken // and points to garbage in the RESOURCE.AUD. The affected audio36 // assets seem to be able to load successfully from one of the later // CDs, so just ignore the map on this disc if (g_sci->getGameId() == GID_PQSWAT && g_sci->getLanguage() == Common::EN_ANY && map->_volumeNumber == 1 && map->_mapNumber == 405) { continue; } if (g_sci->getGameId() == GID_GK2) { // At least version 1.00 of the US release, and the German // release, of GK2 have multiple invalid audio36 map entries on // CD 6 if (map->_volumeNumber == 6 && offset + syncSize >= srcSize) { bool skip; switch (g_sci->getLanguage()) { case Common::EN_ANY: skip = (map->_mapNumber == 22 || map->_mapNumber == 160); break; case Common::DE_DEU: skip = (map->_mapNumber == 22); break; default: skip = false; } if (skip) { continue; } } // Map 2020 on CD 1 of the German release of GK2 is invalid. // This content does not appear to ever be used by the game (it // does not even exist in the US release), and there is a // correct copy of it on CD 6, so just ignore the bad copy on // CD 1 if (g_sci->getLanguage() == Common::DE_DEU && map->_volumeNumber == 1 && map->_mapNumber == 2020) { continue; } } // Map 800 and 4176 contain content that was cut from the game. The // French version of the game includes map files from the US // release, but the audio resources are French so the maps don't // match. Since the content was never used, just ignore these maps // everywhere if (g_sci->getGameId() == GID_PHANTASMAGORIA2 && (map->_mapNumber == 800 || map->_mapNumber == 4176)) { continue; } addResource(id, src, offset + syncSize, 0, map->getLocationName()); } } mapRes->unalloc(); return 0; }
void UFuncPoly::createResources() { poly = new UResPoly(); addResource(poly, this); }
void ResourceManager::addResource(Resource &resource, const Common::UString &name, ChangeID &change) { if (name.empty()) return; addResource(resource, getHash(name), change); }