SymbolicExpr::VisitAction preVisit(const SymbolicExpr::Ptr &node) { if (!seen.insert(getRawPointer(node)).second) return SymbolicExpr::TRUNCATE; // already processed this subexpression if (SymbolicExpr::LeafPtr leaf = node->isLeafNode()) { if (leaf->isVariable()) { if (defns->find(leaf->nameId()) == defns->end()) { defns->insert(leaf->nameId()); yices_type bvtype = yices_mk_bitvector_type(self->context, leaf->nBits()); ASSERT_not_null(bvtype); std::string name = "v" + StringUtility::numberToString(leaf->nameId()); yices_var_decl vdecl __attribute__((unused)) = yices_mk_var_decl(self->context, name.c_str(), bvtype); ASSERT_not_null(vdecl); } } else if (leaf->isMemory()) { if (defns->find(leaf->nameId()) == defns->end()) { defns->insert(leaf->nameId()); yices_type domain = yices_mk_bitvector_type(self->context, leaf->domainWidth()); yices_type range = yices_mk_bitvector_type(self->context, leaf->nBits()); yices_type ftype = yices_mk_function_type(self->context, &domain, 1, range); ASSERT_not_null(ftype); std::string name = "m" + StringUtility::numberToString(leaf->nameId()); yices_var_decl vdecl __attribute__((unused)) = yices_mk_var_decl(self->context, name.c_str(), ftype); ASSERT_not_null(vdecl); } } } return SymbolicExpr::CONTINUE; }
void Attribute::bindAsUniform( int index ) { switch( numComponents() ) { case 1: if( m_internalComponentType == GL_FLOAT ) { //printf("setting uniform tmp: %f at uniform location %i\n", *((float *)getRawPointer()), index ); glUniform1fv( index, numElements(), (float *)getRawPointer()); } else if( m_internalComponentType == GL_INT ) { glUniform1iv( index, numElements(), (int*)getRawPointer()); }else if( m_internalComponentType == SAMPLER ) { int *texIds = (int*)getRawPointer(); int textureUnits[32]; int num = numElements(); for( int i=0;i<num;++i ) { glActiveTexture(GL_TEXTURE0+g_nextTextureUnit); glBindTexture(m_textureTarget, *texIds); textureUnits[i] = g_nextTextureUnit; ++texIds; ++g_nextTextureUnit; } glUniform1iv( index, num, textureUnits); } break; case 2: if( m_internalComponentType == GL_FLOAT ) glUniform2fv( index, numElements(), (float *)getRawPointer()); break; case 3: if( m_internalComponentType == GL_FLOAT ) glUniform3fv( index, numElements(), (float *)getRawPointer()); break; case 4: if( m_internalComponentType == GL_FLOAT ) glUniform4fv( index, numElements(), (float *)getRawPointer()); break; case 9: glUniformMatrix3fv( index, numElements(), false, (float *)getRawPointer() ); break; case 16: glUniformMatrix4fv( index, numElements(), false, (float *)getRawPointer() ); break; }; }
void Attribute::bindAsUniform( int index ) { switch( numComponents() ) { case 1: if( elementComponentType() == GL_FLOAT ) { //printf("setting uniform tmp: %f at uniform location %i\n", *((float *)getRawPointer()), index ); oglUniform1fv( index, numElements(), (float *)getRawPointer()); } else if( elementComponentType() == GL_INT ) { oglUniform1iv( index, numElements(), (int*)getRawPointer()); }else if( elementComponentType() == ATTR_TYPE_SAMPLER ) { // get gl textureid unsigned int t = (unsigned int) (*(int*)getRawPointer()); // bind texture to given texture unit (index) oglActiveTexture(GL_TEXTURE0+index); glBindTexture(GL_TEXTURE_2D, t); // now set the sampler uniform to point to the textureunit int tt = index; // for now texture unit == unfiform location // this will be bad with higher number of uniforms in shader // need more clever texture unit management oglUniform1iv( index, 1, &tt); } break; case 2: if( elementComponentType() == GL_FLOAT ) oglUniform2fv( index, numElements(), (float *)getRawPointer()); break; case 3: if( elementComponentType() == GL_FLOAT ) oglUniform3fv( index, numElements(), (float *)getRawPointer()); break; case 4: if( elementComponentType() == GL_FLOAT ) oglUniform4fv( index, numElements(), (float *)getRawPointer()); break; case 9: oglUniformMatrix3fv( index, numElements(), false, (float *)getRawPointer() ); break; case 16: oglUniformMatrix4fv( index, numElements(), false, (float *)getRawPointer() ); break; }; }
SymbolicExpr::VisitAction preVisit(const SymbolicExpr::Ptr &node) { if (!seen.insert(getRawPointer(node)).second) return SymbolicExpr::TRUNCATE; // already processed this subexpression if (SymbolicExpr::LeafPtr leaf = node->isLeafNode()) { if ((leaf->isVariable() || leaf->isMemory()) && !leaf->comment().empty()) { if (!commented) { o <<"\n" <<";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n" <<"; Variable comments\n" <<";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"; commented = true; } o <<"\n; " <<leaf->toString() <<": " <<StringUtility::prefixLines(leaf->comment(), "; ", false) <<"\n"; } } return SymbolicExpr::CONTINUE; }
SymbolicExpr::VisitAction preVisit(const SymbolicExpr::Ptr &node) { if (!seen.insert(getRawPointer(node)).second) return SymbolicExpr::TRUNCATE; // already processed this subexpression if (SymbolicExpr::LeafPtr leaf = node->isLeafNode()) { if (leaf->isVariable()) { if (defns->find(leaf->nameId())==defns->end()) { defns->insert(leaf->nameId()); o <<"\n"; if (!leaf->comment().empty()) o <<StringUtility::prefixLines(leaf->comment(), "; ") <<"\n"; o <<"(define v" <<leaf->nameId() <<"::" <<get_typename(leaf) <<")\n"; } } else if (leaf->isMemory()) { if (defns->find(leaf->nameId())==defns->end()) { defns->insert(leaf->nameId()); o <<"\n"; if (!leaf->comment().empty()) o <<StringUtility::prefixLines(leaf->comment(), "; ") <<"\n"; o <<"(define m" <<leaf->nameId() <<"::" <<get_typename(leaf) <<")\n"; } } } return SymbolicExpr::CONTINUE; }
void Attribute::bindAsAttribute( int index ) { // activate and specify pointer to vertex array // should be done only when attribute has been updated oglBindBuffer(GL_ARRAY_BUFFER, m_bufferId); oglBufferData(GL_ARRAY_BUFFER, numComponents()*elementComponentSize()*numElements(), getRawPointer(), GL_STATIC_DRAW); oglBindBuffer(GL_ARRAY_BUFFER, m_bufferId); oglEnableVertexAttribArray(index); oglVertexAttribPointer(index, numComponents(), elementComponentType(), false, 0, 0); }
int32_t LiSetupOneRPL(kernel::UniqueProcessId upid, virt_ptr<LOADED_RPL> rpl, virt_ptr<TinyHeap> codeHeapTracking, virt_ptr<TinyHeap> dataHeapTracking) { int32_t result = 0; // Calculate segment bounds RplSegmentBounds bounds; bounds.data.name = "DATA"; bounds.load.name = "LOADERINFO"; bounds.text.name = "TEXT"; bounds.temp.name = "TEMP"; auto shBase = virt_cast<virt_addr>(rpl->sectionHeaderBuffer); for (auto i = 1u; i < rpl->elfHeader.shnum; ++i) { auto sectionHeader = virt_cast<rpl::SectionHeader *>(shBase + i * rpl->elfHeader.shentsize); if (sectionHeader->size == 0 || sectionHeader->type == rpl::SHT_RPL_FILEINFO || sectionHeader->type == rpl::SHT_RPL_CRCS || sectionHeader->type == rpl::SHT_RPL_IMPORTS) { continue; } if (sectionHeader->flags & rpl::SHF_ALLOC) { if ((sectionHeader->flags & rpl::SHF_EXECINSTR) && sectionHeader->type != rpl::SHT_RPL_EXPORTS) { bounds.text.min = std::min<uint32_t>(bounds.text.min, sectionHeader->addr); } else { if (sectionHeader->flags & rpl::SHF_WRITE) { bounds.data.min = std::min<uint32_t>(bounds.data.min, sectionHeader->addr); } else { bounds.load.min = std::min<uint32_t>(bounds.load.min, sectionHeader->addr); } } } else { bounds.temp.min = std::min<uint32_t>(bounds.temp.min, sectionHeader->offset); bounds.temp.max = std::max<uint32_t>(bounds.temp.max, sectionHeader->offset + sectionHeader->size); } } if (bounds.data.min == -1) { bounds.data.min = 0; } if (bounds.load.min == -1) { bounds.load.min = 0; } if (bounds.text.min == -1) { bounds.text.min = 0; } if (bounds.temp.min == -1) { bounds.temp.min = 0; } auto fileInfo = rpl->fileInfoBuffer; bounds.text.max = (bounds.text.min + fileInfo->textSize) - fileInfo->trampAdjust; bounds.data.max = bounds.data.min + fileInfo->dataSize; bounds.load.max = (bounds.load.min + fileInfo->loadSize) - fileInfo->fileInfoPad; auto textSize = static_cast<uint32_t>(bounds.text.max - bounds.text.min); auto dataSize = static_cast<uint32_t>(bounds.data.max - bounds.data.min); auto loadSize = static_cast<uint32_t>(bounds.load.max - bounds.load.min); auto tempSize = static_cast<uint32_t>(bounds.temp.max - bounds.temp.min); if (fileInfo->trampAdjust >= textSize || fileInfo->textSize - fileInfo->trampAdjust < textSize || fileInfo->dataSize < dataSize || fileInfo->loadSize - fileInfo->fileInfoPad < loadSize || fileInfo->tempSize < tempSize) { Loader_ReportError("***Bounds check failure."); Loader_ReportError("b%d: %08X %08x", 0, bounds.data.min, bounds.data.max); Loader_ReportError("b%d: %08X %08x", 1, bounds.load.min, bounds.load.max); Loader_ReportError("b%d: %08X %08x", 2, bounds.text.min, bounds.text.max); Loader_ReportError("b%d: %08X %08x", 3, bounds.temp.min, bounds.temp.max); Loader_ReportError("TrampAdj = %08X", fileInfo->trampAdjust); Loader_ReportError("Text = %08X", fileInfo->textSize); Loader_ReportError("Data = %08X", fileInfo->dataSize); Loader_ReportError("Read = %08X", fileInfo->loadSize - fileInfo->fileInfoPad); Loader_ReportError("Temp = %08X", fileInfo->tempSize); LiSetFatalError(0x18729B, rpl->fileType, 1, "LiSetupOneRPL", 0x715); result = -470042; goto error; } if (rpl->dataBuffer) { for (auto i = 1u; i < rpl->elfHeader.shnum; ++i) { auto sectionHeader = virt_cast<rpl::SectionHeader *>(shBase + i * rpl->elfHeader.shentsize); LiCheckAndHandleInterrupts(); if (sectionHeader->size && !rpl->sectionAddressBuffer[i] && (sectionHeader->flags & rpl::SHF_ALLOC) && (sectionHeader->flags & rpl::SHF_WRITE)) { result = LiSetupOneAllocSection(upid, rpl, i, sectionHeader, 1, &bounds.data, rpl->dataBuffer, fileInfo->dataAlign, 0); if (result) { goto error; } } } } if (rpl->loadBuffer) { for (auto i = 1u; i < rpl->elfHeader.shnum; ++i) { auto sectionHeader = virt_cast<rpl::SectionHeader *>(shBase + i * rpl->elfHeader.shentsize); LiCheckAndHandleInterrupts(); if (sectionHeader->size && !rpl->sectionAddressBuffer[i] && (sectionHeader->flags & rpl::SHF_ALLOC)) { if (sectionHeader->type == rpl::SHT_RPL_EXPORTS || sectionHeader->type == rpl::SHT_RPL_IMPORTS || !(sectionHeader->flags & (rpl::SHF_EXECINSTR | rpl::SHF_WRITE))) { result = LiSetupOneAllocSection(upid, rpl, i, sectionHeader, 0, &bounds.load, rpl->loadBuffer, fileInfo->loadAlign, (sectionHeader->type == rpl::SHT_RPL_IMPORTS) ? 1 : 0); if (result) { goto error; } if (sectionHeader->type == rpl::SHT_RPL_EXPORTS) { if (sectionHeader->flags & rpl::SHF_EXECINSTR) { rpl->numFuncExports = *virt_cast<uint32_t *>(rpl->sectionAddressBuffer[i]); rpl->funcExports = virt_cast<void *>(rpl->sectionAddressBuffer[i] + 8); } else { rpl->numDataExports = *virt_cast<uint32_t *>(rpl->sectionAddressBuffer[i]); rpl->dataExports = virt_cast<void *>(rpl->sectionAddressBuffer[i] + 8); } } } } } } if (fileInfo->textSize) { if (!rpl->textBuffer) { Loader_ReportError("Missing TEXT allocation."); LiSetFatalError(0x18729Bu, rpl->fileType, 1, "LiSetupOneRPL", 1918); result = -470057; goto error; } for (auto i = 1u; i < rpl->elfHeader.shnum; ++i) { auto sectionHeader = virt_cast<rpl::SectionHeader *>(shBase + i * rpl->elfHeader.shentsize); LiCheckAndHandleInterrupts(); if (sectionHeader->size && !rpl->sectionAddressBuffer[i] && (sectionHeader->flags & rpl::SHF_ALLOC) && (sectionHeader->flags & rpl::SHF_EXECINSTR) && sectionHeader->type != rpl::SHT_RPL_EXPORTS) { result = LiSetupOneAllocSection(upid, rpl, i, sectionHeader, 0, &bounds.text, virt_cast<void *>(virt_cast<virt_addr>(rpl->textBuffer) + fileInfo->trampAdjust), fileInfo->textAlign, 0); if (result) { goto error; } } } } if (bounds.temp.min != bounds.temp.max) { auto compressedRelocationsBuffer = virt_ptr<void> { nullptr }; auto compressedRelocationsBufferSize = uint32_t { 0 }; auto memoryAvailable = uint32_t { 0 }; auto tempSize = bounds.temp.max - bounds.temp.min; auto dataSize = uint32_t { 0 }; auto data = virt_ptr<void> { nullptr }; auto readBytes = 0u; result = LiCacheLineCorrectAllocEx(codeHeapTracking, tempSize, -32, &compressedRelocationsBuffer, 1, &compressedRelocationsBufferSize, &memoryAvailable, rpl->fileType); if (result) { Loader_ReportError( "*** allocation failed for {} size = {}, align = {} from {} heap; (needed {}, available {}).", "compressed relocations", tempSize, -32, "RPL Code", compressedRelocationsBufferSize, memoryAvailable); goto error; } rpl->compressedRelocationsBuffer = compressedRelocationsBuffer; rpl->compressedRelocationsBufferSize = compressedRelocationsBufferSize; result = sLiPrepareBounceBufferForReading(rpl, 0, bounds.temp.name, bounds.temp.min, &dataSize, tempSize, &data); if (result) { goto error; } while (tempSize > 0) { // TODO: Loader_UpdateHeartBeat LiCheckAndHandleInterrupts(); std::memcpy(virt_cast<void *>(virt_cast<virt_addr>(compressedRelocationsBuffer) + readBytes).getRawPointer(), data.getRawPointer(), dataSize); readBytes += dataSize; tempSize -= dataSize; if (!tempSize) { break; } result = sLiRefillBounceBufferForReading(rpl, &dataSize, tempSize, &data); if (result) { goto error; } } for (auto i = 1u; i < rpl->elfHeader.shnum; ++i) { auto sectionHeader = virt_cast<rpl::SectionHeader *>(shBase + i * rpl->elfHeader.shentsize); LiCheckAndHandleInterrupts(); if (sectionHeader->size && !rpl->sectionAddressBuffer[i]) { rpl->sectionAddressBuffer[i] = virt_cast<virt_addr>(compressedRelocationsBuffer) + (sectionHeader->offset - bounds.temp.min); bounds.temp.allocMax = std::max<uint32_t>(bounds.temp.allocMax, sectionHeader->addr + sectionHeader->size); if (bounds.temp.allocMax > bounds.temp.max) { Loader_ReportError( "***Section {} segment {} makerpl's section size was wrong: mRealTimeLimit=0x%08X, mLimit=0x%08X. Error is Loader's fault.", i, bounds.temp.name, bounds.temp.allocMax, bounds.temp.max); LiSetFatalError(0x18729Bu, rpl->fileType, 1, "LiSetupOneRPL", 2034); result = -470091; goto error; } } } } for (auto i = 0u; i < 4; ++i) { if (bounds[i].allocMax > bounds[i].max) { Loader_ReportError( "***Segment %s makerpl's segment size was wrong: mRealTimeLimit=0x%08X, mLimit=0x%08X. Error is Loader's fault.\n", bounds[i].name, bounds[i].allocMax, bounds[i].max); LiSetFatalError(0x18729Bu, rpl->fileType, 1, "LiSetupOneRPL", 2052); result = -470091; goto error; } } rpl->postTrampBuffer = align_up(virt_cast<virt_addr>(rpl->textBuffer) + fileInfo->trampAdjust + (bounds.text.allocMax - bounds.text.min), 16); rpl->textAddr = virt_cast<virt_addr>(rpl->textBuffer) + fileInfo->trampAdjust; rpl->textOffset = rpl->textAddr - bounds.text.min; rpl->textSize = static_cast<uint32_t>(bounds.text.max - bounds.text.min); rpl->dataAddr = virt_cast<virt_addr>(rpl->dataBuffer); rpl->dataOffset = rpl->dataAddr - bounds.data.min; rpl->dataSize = static_cast<uint32_t>(bounds.data.max - bounds.data.min); rpl->loadAddr = virt_cast<virt_addr>(rpl->loadBuffer); rpl->loadOffset = rpl->loadAddr - bounds.load.min; rpl->loadSize = static_cast<uint32_t>(bounds.load.max - bounds.load.min); rpl->loadStateFlags |= LoadStateFlags::LoaderSetup; result = LiCleanUpBufferAfterModuleLoaded(); if (result) { goto error; } return 0; error: if (rpl->compressedRelocationsBuffer) { LiCacheLineCorrectFreeEx(codeHeapTracking, rpl->compressedRelocationsBuffer, rpl->compressedRelocationsBufferSize); rpl->compressedRelocationsBuffer = nullptr; } LiCloseBufferIfError(); Loader_ReportError("***LiSetupOneRPL({}) failed with err={}.", rpl->moduleNameBuffer, result); return result; }
static int32_t LiSetupOneAllocSection(kernel::UniqueProcessId upid, virt_ptr<LOADED_RPL> rpl, int32_t sectionIndex, virt_ptr<rpl::SectionHeader> sectionHeader, int32_t unk_a5, SegmentBounds *bounds, virt_ptr<void> base, uint32_t baseAlign, uint32_t unk_a9) { auto globals = getGlobalStorage(); LiCheckAndHandleInterrupts(); auto sectionAddress = virt_cast<virt_addr>(base) + (sectionHeader->addr - bounds->min); rpl->sectionAddressBuffer[sectionIndex] = sectionAddress; if (!align_check(sectionAddress, sectionHeader->addralign)) { Loader_ReportError("***{} section {} alignment failure.", bounds->name, sectionIndex); Loader_ReportError("Ptr = {}", sectionAddress); Loader_ReportError("{} base = {}", bounds->name, base); Loader_ReportError("{} base align = {}", bounds->name, baseAlign); Loader_ReportError("SecHdr->addr = 0x{:08X}", sectionHeader->addr); Loader_ReportError("bound[{}].base = 0x{:08X}", bounds->name, bounds->min); LiSetFatalError(0x18729Bu, rpl->fileType, 1, "sLiSetupOneAllocSection", 1510); return -470043; } if (!unk_a9 && sectionHeader->type == rpl::SHT_NOBITS && unk_a5) { auto userHasControl = (upid == kernel::UniqueProcessId::Invalid) ? true : !!globals->userHasControl; LiClearUserBss(userHasControl, upid, virt_cast<void *>(sectionAddress), sectionHeader->size); } else { auto bytesAvailable = uint32_t { 0 }; auto sectionData = virt_ptr<void> { nullptr }; auto error = sLiPrepareBounceBufferForReading(rpl, sectionIndex, bounds->name, sectionHeader->offset, &bytesAvailable, sectionHeader->size, §ionData); if (error) { return error; } if (!unk_a9 && (sectionHeader->flags & rpl::SHF_DEFLATED)) { auto inflatedExpectedSizeBuffer = std::array<uint8_t, sizeof(uint32_t)> { }; auto readBytes = uint32_t { 0 }; while (readBytes < inflatedExpectedSizeBuffer.size()) { std::memcpy( inflatedExpectedSizeBuffer.data() + readBytes, sectionData.getRawPointer(), std::min<size_t>(bytesAvailable, inflatedExpectedSizeBuffer.size() - readBytes)); readBytes += bytesAvailable; if (readBytes >= inflatedExpectedSizeBuffer.size()) { break; } error = sLiRefillBounceBufferForReading( rpl, &bytesAvailable, static_cast<uint32_t>(inflatedExpectedSizeBuffer.size() - readBytes), §ionData); if (error) { return error; } } auto inflatedExpectedSize = *reinterpret_cast<be2_val<uint32_t> *>( inflatedExpectedSizeBuffer.data()); if (inflatedExpectedSize) { auto inflatedBytes = static_cast<uint32_t>(inflatedExpectedSize); error = ZLIB_UncompressFromStream(rpl, sectionIndex, bounds->name, sectionHeader->offset + 4, sectionHeader->size - 4, virt_cast<void *>(sectionAddress), &inflatedBytes); if (error) { Loader_ReportError( "***{} {} {} Decompression ({}->{}) failure.", rpl->moduleNameBuffer, bounds->name, sectionIndex, sectionHeader->size - 4, inflatedExpectedSize); return error; } if (inflatedBytes != inflatedExpectedSize) { Loader_ReportError( "***{} {} {} Decompression ({}->{}) failure. Anticipated uncompressed size would be {}; got {}", rpl->moduleNameBuffer, bounds->name, sectionIndex, sectionHeader->size - 4, inflatedExpectedSize, inflatedExpectedSize, inflatedBytes); LiSetFatalError(0x18729Bu, rpl->fileType, 1, "sLiSetupOneAllocSection", 1604); return -470090; } sectionHeader->size = inflatedBytes; } } else { auto bytesRead = 0u; while (true) { // TODO: Loader_UpdateHeartBeat(); LiCheckAndHandleInterrupts(); std::memcpy(virt_cast<void *>(sectionAddress + bytesRead).getRawPointer(), sectionData.getRawPointer(), bytesAvailable); bytesRead += bytesAvailable; if (bytesRead >= sectionHeader->size) { break; } error = sLiRefillBounceBufferForReading(rpl, &bytesAvailable, sectionHeader->size - bytesRead, §ionData); if (error) { return error; } } } } bounds->allocMax = std::max<uint32_t>(bounds->allocMax, sectionHeader->addr + sectionHeader->size); if (bounds->allocMax > bounds->max) { Loader_ReportError( "*** {} section {} segment {} makerpl's segment size was wrong: real time calculated size =0x{:08X} makerpl's size=0x{:08X}.", rpl->moduleNameBuffer, sectionIndex, bounds->name, bounds->allocMax, bounds->max); LiSetFatalError(0x18729Bu, rpl->fileType, 1, "sLiSetupOneAllocSection", 1676); return -470091; } return 0; }
int32_t ZLIB_UncompressFromStream(virt_ptr<LOADED_RPL> rpl, uint32_t sectionIndex, std::string_view boundsName, uint32_t fileOffset, uint32_t deflatedSize, virt_ptr<void> inflatedBuffer, uint32_t *inflatedSize) { auto inflatedBytesMax = *inflatedSize; auto deflatedBytesRemaining = deflatedSize; auto bounceBuffer = virt_ptr<void> { nullptr }; auto bounceBufferSize = uint32_t { 0 }; LiCheckAndHandleInterrupts(); auto error = sLiPrepareBounceBufferForReading(rpl, sectionIndex, boundsName, fileOffset, &bounceBufferSize, deflatedSize, &bounceBuffer); if (error) { return error; } auto stream = z_stream { }; std::memset(&stream, 0, sizeof(stream)); auto zlibError = inflateInit(&stream); if (zlibError != Z_OK) { switch (zlibError) { case Z_STREAM_ERROR: LiSetFatalError(0x18729Bu, rpl->fileType, 1, "ZLIB_UncompressFromStream", 332); return Error::ZlibStreamError; case Z_MEM_ERROR: LiSetFatalError(0x187298u, rpl->fileType, 0, "ZLIB_UncompressFromStream", 319); return Error::ZlibMemError; case Z_VERSION_ERROR: LiSetFatalError(0x18729Bu, rpl->fileType, 1, "ZLIB_UncompressFromStream", 332); return Error::ZlibVersionError; default: Loader_ReportError("***Unknown ZLIB error {} (0x{}).", zlibError, zlibError); LiSetFatalError(0x18729Bu, rpl->fileType, 1, "ZLIB_UncompressFromStream", 332); return Error::ZlibUnknownError; } } constexpr auto InflateChunkSize = 0x3000u; rpl->lastSectionCrc = 0u; stream.next_out = reinterpret_cast<Bytef *>(inflatedBuffer.getRawPointer()); while (true) { // TODO: Loader_UpdateHeartBeat(); LiCheckAndHandleInterrupts(); stream.avail_in = bounceBufferSize; stream.next_in = reinterpret_cast<Bytef *>(bounceBuffer.getRawPointer()); while (stream.avail_in) { LiCheckAndHandleInterrupts(); stream.avail_out = std::min<uInt>(InflateChunkSize, inflatedBytesMax - stream.total_out); zlibError = inflate(&stream, 0); if (zlibError != Z_OK && zlibError != Z_STREAM_END) { switch (zlibError) { case Z_STREAM_ERROR: LiSetFatalError(0x18729Bu, rpl->fileType, 1, "ZLIB_UncompressFromStream", 405); return -470086; case Z_MEM_ERROR: LiSetFatalError(0x187298u, rpl->fileType, 0, "ZLIB_UncompressFromStream", 415); error = -470084; break; case Z_DATA_ERROR: LiSetFatalError(0x18729Bu, rpl->fileType, 1, "ZLIB_UncompressFromStream", 419); error = -470087; break; default: Loader_ReportError("***Unknown ZLIB error {} (0x{}).", zlibError, zlibError); LiSetFatalError(0x18729Bu, rpl->fileType, 1, "ZLIB_UncompressFromStream", 424); error = -470100; } inflateEnd(&stream); return error; } decaf_check(stream.total_out <= inflatedBytesMax); } deflatedBytesRemaining -= bounceBufferSize; if (!deflatedBytesRemaining) { break; } error = sLiRefillBounceBufferForReading(rpl, &bounceBufferSize, deflatedBytesRemaining, &bounceBuffer); if (error) { LiSetFatalError(0x18729Bu, rpl->fileType, 1, "ZLIB_UncompressFromStream", 520); inflateEnd(&stream); *inflatedSize = stream.total_out; return -470087; } } inflateEnd(&stream); *inflatedSize = stream.total_out; return 0; }
void Attribute::bindAsAttribute( int index ) { if(m_isDirty && m_numElements) { // activate and specify pointer to vertex array // should be done only when attribute has been updated glBindBuffer(GL_ARRAY_BUFFER, m_bufferId); glBufferData(GL_ARRAY_BUFFER, numComponents()*elementComponentSize()*numElements(), getRawPointer(), GL_STATIC_DRAW); m_isDirty = false; } glBindBuffer(GL_ARRAY_BUFFER, m_bufferId); glEnableVertexAttribArray(index); if( m_internalComponentType == GL_FLOAT ) glVertexAttribPointer(index, numComponents(), m_internalComponentType, false, 0, 0); else glVertexAttribIPointer(index, numComponents(), m_internalComponentType, 0, 0); }
AttributePtr Attribute::copy() { return create( numComponents(), elementComponentType(), (unsigned char *)getRawPointer(), numElements() ); }