mirror of
				https://github.com/PancakeTAS/lsfg-vk.git
				synced 2025-10-30 07:01:10 +00:00 
			
		
		
		
	Compare commits
	
		
			2 commits
		
	
	
		
			2eec75e258
			...
			0d88e9741c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
							 | 
						0d88e9741c | ||
| 
							 | 
						07653a83e0 | 
					 6 changed files with 241 additions and 40 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,3 +0,0 @@
 | 
				
			||||||
[submodule "thirdparty/pe-parse"]
 | 
					 | 
				
			||||||
	path = thirdparty/pe-parse
 | 
					 | 
				
			||||||
	url = https://github.com/trailofbits/pe-parse
 | 
					 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,6 @@ add_compile_options(-fPIC
 | 
				
			||||||
    -Wno-deprecated-declarations
 | 
					    -Wno-deprecated-declarations
 | 
				
			||||||
    -Wno-unused-template)
 | 
					    -Wno-unused-template)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_subdirectory(thirdparty/pe-parse/pe-parser-library EXCLUDE_FROM_ALL)
 | 
					 | 
				
			||||||
add_subdirectory(framegen)
 | 
					add_subdirectory(framegen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(LSFGVK_EXCESS_DEBUG)
 | 
					if(LSFGVK_EXCESS_DEBUG)
 | 
				
			||||||
| 
						 | 
					@ -44,7 +43,6 @@ target_include_directories(lsfg-vk SYSTEM
 | 
				
			||||||
target_include_directories(lsfg-vk
 | 
					target_include_directories(lsfg-vk
 | 
				
			||||||
    PUBLIC include)
 | 
					    PUBLIC include)
 | 
				
			||||||
target_link_libraries(lsfg-vk PUBLIC
 | 
					target_link_libraries(lsfg-vk PUBLIC
 | 
				
			||||||
    pe-parse
 | 
					 | 
				
			||||||
    lsfg-vk-framegen)
 | 
					    lsfg-vk-framegen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# diagnostics
 | 
					# diagnostics
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								include/extract/dll.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								include/extract/dll.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unordered_map>
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace DLL {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// Parse all resources from a DLL file.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// *Shouldn't* cause any segmentation faults.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// @param filename Path to the DLL file.
 | 
				
			||||||
 | 
					    /// @return A map of resource IDs to their binary data.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// @throws std::runtime_error on various failure points.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    std::unordered_map<uint32_t, std::vector<uint8_t>> parse_dll(const std::string& filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										203
									
								
								src/extract/dll.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								src/extract/dll.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,203 @@
 | 
				
			||||||
 | 
					#include "extract/dll.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unordered_map>
 | 
				
			||||||
 | 
					#include <stdexcept>
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <optional>
 | 
				
			||||||
 | 
					#include <cstddef>
 | 
				
			||||||
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <utility>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <array>
 | 
				
			||||||
 | 
					#include <span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// DOS file header
 | 
				
			||||||
 | 
					struct DOSHeader {
 | 
				
			||||||
 | 
					    uint16_t magic; // 0x5A4D
 | 
				
			||||||
 | 
					    std::array<uint16_t, 29> pad;
 | 
				
			||||||
 | 
					    int32_t pe_offset; // file offset
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// PE header
 | 
				
			||||||
 | 
					struct PEHeader {
 | 
				
			||||||
 | 
					    uint32_t signature; // "PE\0\0"
 | 
				
			||||||
 | 
					    std::array<uint16_t, 1> pad1;
 | 
				
			||||||
 | 
					    uint16_t sect_count;
 | 
				
			||||||
 | 
					    std::array<uint16_t, 6> pad2;
 | 
				
			||||||
 | 
					    uint16_t opt_hdr_size;
 | 
				
			||||||
 | 
					    std::array<uint16_t, 1> pad3;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// (partial!) PE optional header
 | 
				
			||||||
 | 
					struct PEOptionalHeader {
 | 
				
			||||||
 | 
					    uint16_t magic; // 0x20B
 | 
				
			||||||
 | 
					    std::array<uint16_t, 63> pad4;
 | 
				
			||||||
 | 
					    std::pair<uint32_t, uint32_t> resource_table; // file offset/size
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Section header
 | 
				
			||||||
 | 
					struct SectionHeader {
 | 
				
			||||||
 | 
					    std::array<uint16_t, 4> pad1;
 | 
				
			||||||
 | 
					    uint32_t vsize; // virtual
 | 
				
			||||||
 | 
					    uint32_t vaddress;
 | 
				
			||||||
 | 
					    uint32_t fsize; // raw
 | 
				
			||||||
 | 
					    uint32_t foffset;
 | 
				
			||||||
 | 
					    std::array<uint16_t, 8> pad2;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Resource directory
 | 
				
			||||||
 | 
					struct ResourceDirectory {
 | 
				
			||||||
 | 
					    std::array<uint16_t, 6> pad;
 | 
				
			||||||
 | 
					    uint16_t name_count;
 | 
				
			||||||
 | 
					    uint16_t id_count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Resource directory entry
 | 
				
			||||||
 | 
					struct ResourceDirectoryEntry {
 | 
				
			||||||
 | 
					    uint32_t id;
 | 
				
			||||||
 | 
					    uint32_t offset; // high bit = directory
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Resource data entry
 | 
				
			||||||
 | 
					struct ResourceDataEntry {
 | 
				
			||||||
 | 
					    uint32_t offset;
 | 
				
			||||||
 | 
					    uint32_t size;
 | 
				
			||||||
 | 
					    std::array<uint32_t, 2> pad;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma clang diagnostic push
 | 
				
			||||||
 | 
					#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container"
 | 
				
			||||||
 | 
					namespace {
 | 
				
			||||||
 | 
					    /// Safely cast a vector to a pointer of type T
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    const T* safe_cast(const std::vector<uint8_t>& data, size_t offset) {
 | 
				
			||||||
 | 
					        const size_t end = offset + sizeof(T);
 | 
				
			||||||
 | 
					        if (end > data.size() || end < offset)
 | 
				
			||||||
 | 
					            throw std::runtime_error("Buffer overflow during safe cast");
 | 
				
			||||||
 | 
					        return reinterpret_cast<const T*>(&data.at(offset));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Safely cast a vector to a span of T
 | 
				
			||||||
 | 
					    template<typename T>
 | 
				
			||||||
 | 
					    std::span<const T> span_cast(const std::vector<uint8_t>& data, size_t offset, size_t count) {
 | 
				
			||||||
 | 
					        const size_t end = offset + (count * sizeof(T));
 | 
				
			||||||
 | 
					        if (end > data.size() || end < offset)
 | 
				
			||||||
 | 
					            throw std::runtime_error("Buffer overflow during safe cast");
 | 
				
			||||||
 | 
					        return std::span<const T>(reinterpret_cast<const T*>(&data.at(offset)), count);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#pragma clang diagnostic pop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::unordered_map<uint32_t, std::vector<uint8_t>> DLL::parse_dll(const std::string& filename) {
 | 
				
			||||||
 | 
					    std::ifstream file(filename, std::ios::binary | std::ios::ate);
 | 
				
			||||||
 | 
					    if (!file.is_open())
 | 
				
			||||||
 | 
					        throw std::runtime_error("Failed to open Lossless.dll");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const auto size = file.tellg();
 | 
				
			||||||
 | 
					    file.seekg(0, std::ios::beg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<uint8_t> data(static_cast<size_t>(size));
 | 
				
			||||||
 | 
					    if (!file.read(reinterpret_cast<char*>(data.data()), size))
 | 
				
			||||||
 | 
					        throw std::runtime_error("Failed to read Lossless.dll");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // parse dos header
 | 
				
			||||||
 | 
					    size_t fileOffset = 0;
 | 
				
			||||||
 | 
					    const auto* dosHdr = safe_cast<const DOSHeader>(data, 0);
 | 
				
			||||||
 | 
					    if (dosHdr->magic != 0x5A4D)
 | 
				
			||||||
 | 
					        throw std::runtime_error("Invalid DOS header magic number");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // parse pe header
 | 
				
			||||||
 | 
					    fileOffset += static_cast<size_t>(dosHdr->pe_offset);
 | 
				
			||||||
 | 
					    const auto* peHdr = safe_cast<const PEHeader>(data, fileOffset);
 | 
				
			||||||
 | 
					    if (peHdr->signature != 0x00004550)
 | 
				
			||||||
 | 
					        throw std::runtime_error("Invalid PE header signature");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // parse optional pe header
 | 
				
			||||||
 | 
					    fileOffset += sizeof(PEHeader);
 | 
				
			||||||
 | 
					    const auto* peOptHdr = safe_cast<const PEOptionalHeader>(data, fileOffset);
 | 
				
			||||||
 | 
					    if (peOptHdr->magic != 0x20B)
 | 
				
			||||||
 | 
					        throw std::runtime_error("Unsupported PE format (not PE32+)");
 | 
				
			||||||
 | 
					    const auto& [rsrc_rva, rsrc_size] = peOptHdr->resource_table;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // locate section containing resources
 | 
				
			||||||
 | 
					    std::optional<size_t> rsrc_offset;
 | 
				
			||||||
 | 
					    fileOffset += peHdr->opt_hdr_size;
 | 
				
			||||||
 | 
					    const auto sectHdrs = span_cast<const SectionHeader>(data, fileOffset, peHdr->sect_count);
 | 
				
			||||||
 | 
					    for (const auto& sectHdr : sectHdrs) {
 | 
				
			||||||
 | 
					        if (rsrc_rva < sectHdr.vaddress || rsrc_rva > (sectHdr.vaddress + sectHdr.vsize))
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rsrc_offset.emplace((rsrc_rva - sectHdr.vaddress) + sectHdr.foffset);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!rsrc_offset)
 | 
				
			||||||
 | 
					        throw std::runtime_error("Failed to locate resource section");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // parse resource directory
 | 
				
			||||||
 | 
					    fileOffset = rsrc_offset.value();
 | 
				
			||||||
 | 
					    const auto* rsrcDir = safe_cast<const ResourceDirectory>(data, fileOffset);
 | 
				
			||||||
 | 
					    if (rsrcDir->id_count < 3)
 | 
				
			||||||
 | 
					        throw std::runtime_error("Incorrect resource directory");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // find resource table with data type
 | 
				
			||||||
 | 
					    std::optional<size_t> rsrc_tbl_offset;
 | 
				
			||||||
 | 
					    fileOffset = rsrc_offset.value() + sizeof(ResourceDirectory);
 | 
				
			||||||
 | 
					    const auto rsrcDirEntries = span_cast<const ResourceDirectoryEntry>(
 | 
				
			||||||
 | 
					        data, fileOffset, rsrcDir->name_count + rsrcDir->id_count);
 | 
				
			||||||
 | 
					    for (const auto& rsrcDirEntry : rsrcDirEntries) {
 | 
				
			||||||
 | 
					        if (rsrcDirEntry.id != 10) // RT_RCDATA
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        if ((rsrcDirEntry.offset & 0x80000000) == 0)
 | 
				
			||||||
 | 
					            throw std::runtime_error("Expected resource directory, but found data entry");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rsrc_tbl_offset.emplace(rsrcDirEntry.offset & 0x7FFFFFFF);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!rsrc_tbl_offset)
 | 
				
			||||||
 | 
					        throw std::runtime_error("Failed to locate RT_RCDATA directory");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // parse data type resource directory
 | 
				
			||||||
 | 
					    fileOffset = rsrc_offset.value() + rsrc_tbl_offset.value();
 | 
				
			||||||
 | 
					    const auto* rsrcTbl = safe_cast<const ResourceDirectory>(data, fileOffset);
 | 
				
			||||||
 | 
					    if (rsrcTbl->id_count < 1)
 | 
				
			||||||
 | 
					        throw std::runtime_error("Incorrect RT_RCDATA directory");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // collect all resources
 | 
				
			||||||
 | 
					    fileOffset += sizeof(ResourceDirectory);
 | 
				
			||||||
 | 
					    const auto rsrcTblEntries = span_cast<const ResourceDirectoryEntry>(
 | 
				
			||||||
 | 
					        data, fileOffset, rsrcTbl->name_count + rsrcTbl->id_count);
 | 
				
			||||||
 | 
					    std::unordered_map<uint32_t, std::vector<uint8_t>> resources;
 | 
				
			||||||
 | 
					    for (const auto& rsrcTblEntry : rsrcTblEntries) {
 | 
				
			||||||
 | 
					        if ((rsrcTblEntry.offset & 0x80000000) == 0)
 | 
				
			||||||
 | 
					            throw std::runtime_error("Expected resource directory, but found data entry");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // skip over language directory
 | 
				
			||||||
 | 
					        fileOffset = rsrc_offset.value() + (rsrcTblEntry.offset & 0x7FFFFFFF);
 | 
				
			||||||
 | 
					        const auto* langDir = safe_cast<const ResourceDirectory>(data, fileOffset);
 | 
				
			||||||
 | 
					        if (langDir->id_count < 1)
 | 
				
			||||||
 | 
					            throw std::runtime_error("Incorrect language directory");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fileOffset += sizeof(ResourceDirectory);
 | 
				
			||||||
 | 
					        const auto* langDirEntry = safe_cast<const ResourceDirectoryEntry>(data, fileOffset);
 | 
				
			||||||
 | 
					        if ((langDirEntry->offset & 0x80000000) != 0)
 | 
				
			||||||
 | 
					            throw std::runtime_error("Expected resource data entry, but found directory");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // parse resource data entry
 | 
				
			||||||
 | 
					        fileOffset = rsrc_offset.value() + (langDirEntry->offset & 0x7FFFFFFF);
 | 
				
			||||||
 | 
					        const auto* entry = safe_cast<const ResourceDataEntry>(data, fileOffset);
 | 
				
			||||||
 | 
					        if (entry->offset < rsrc_rva || entry->offset > (rsrc_rva + rsrc_size))
 | 
				
			||||||
 | 
					            throw std::runtime_error("Resource data entry points outside resource section");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // extract resource
 | 
				
			||||||
 | 
					        std::vector<uint8_t> resource(entry->size);
 | 
				
			||||||
 | 
					        fileOffset = (entry->offset - rsrc_rva) + rsrc_offset.value();
 | 
				
			||||||
 | 
					        if (fileOffset + entry->size > data.size())
 | 
				
			||||||
 | 
					            throw std::runtime_error("Resource data entry points outside file");
 | 
				
			||||||
 | 
					        std::copy_n(&data.at(fileOffset), entry->size, resource.data());
 | 
				
			||||||
 | 
					        resources.emplace(rsrcTblEntry.id, std::move(resource));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return resources;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,16 +1,14 @@
 | 
				
			||||||
#include "extract/extract.hpp"
 | 
					#include "extract/extract.hpp"
 | 
				
			||||||
#include "config/config.hpp"
 | 
					#include "config/config.hpp"
 | 
				
			||||||
 | 
					#include "extract/dll.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <pe-parse/parse.h>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <unordered_map>
 | 
					#include <unordered_map>
 | 
				
			||||||
#include <filesystem>
 | 
					#include <filesystem>
 | 
				
			||||||
#include <algorithm>
 | 
					 | 
				
			||||||
#include <stdexcept>
 | 
					#include <stdexcept>
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
#include <cstdlib>
 | 
					#include <cstdlib>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <utility>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include <array>
 | 
					#include <array>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,22 +71,11 @@ const std::unordered_map<std::string, uint32_t> nameIdxTable = {{
 | 
				
			||||||
}};
 | 
					}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
    auto& pshaders() {
 | 
					    auto& shaders() {
 | 
				
			||||||
        static std::unordered_map<uint32_t, std::array<std::vector<uint8_t>, 2>> shaderData;
 | 
					        static std::unordered_map<uint32_t, std::array<std::vector<uint8_t>, 2>> shaderData;
 | 
				
			||||||
        return shaderData;
 | 
					        return shaderData;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int on_resource(void* ptr, const peparse::resource& res) {
 | 
					 | 
				
			||||||
        if (res.type != peparse::RT_RCDATA || res.buf == nullptr || res.buf->bufLen <= 0)
 | 
					 | 
				
			||||||
            return 0;
 | 
					 | 
				
			||||||
        std::vector<uint8_t> resource_data(res.buf->bufLen);
 | 
					 | 
				
			||||||
        std::copy_n(res.buf->buf, res.buf->bufLen, resource_data.data());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto* shaders = reinterpret_cast<std::unordered_map<uint32_t, std::vector<uint8_t>>*>(ptr);
 | 
					 | 
				
			||||||
        shaders->emplace(res.name, std::move(resource_data));
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const std::vector<std::filesystem::path> PATHS{{
 | 
					    const std::vector<std::filesystem::path> PATHS{{
 | 
				
			||||||
        ".local/share/Steam/steamapps/common",
 | 
					        ".local/share/Steam/steamapps/common",
 | 
				
			||||||
        ".steam/steam/steamapps/common",
 | 
					        ".steam/steam/steamapps/common",
 | 
				
			||||||
| 
						 | 
					@ -121,44 +108,39 @@ namespace {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Extract::extractShaders() {
 | 
					void Extract::extractShaders() {
 | 
				
			||||||
    if (!pshaders().empty())
 | 
					    if (!shaders().empty())
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::unordered_map<uint32_t, std::vector<uint8_t>> shaders{};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // parse the dll
 | 
					    // parse the dll
 | 
				
			||||||
    peparse::parsed_pe* dll = peparse::ParsePEFromFile(getDllPath().c_str());
 | 
					    const auto resources = DLL::parse_dll(getDllPath());
 | 
				
			||||||
    if (!dll)
 | 
					    std::cerr << "lsfg-vk: Extracted " << resources.size() << " resources from dll.\n";
 | 
				
			||||||
        throw std::runtime_error("Unable to read Lossless.dll, is it installed?");
 | 
					 | 
				
			||||||
    peparse::IterRsrc(dll, on_resource, reinterpret_cast<void*>(&shaders));
 | 
					 | 
				
			||||||
    peparse::DestructParsedPE(dll);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // ensure all shaders are present
 | 
					    // ensure all shaders are present
 | 
				
			||||||
    for (const auto& [name, idx] : nameIdxTable) {
 | 
					    for (const auto& [name, idx] : nameIdxTable) {
 | 
				
			||||||
        auto fp16 = shaders.find(idx);
 | 
					        auto fp16 = resources.find(idx);
 | 
				
			||||||
        if (fp16 == shaders.end())
 | 
					        if (fp16 == resources.end())
 | 
				
			||||||
            throw std::runtime_error("Shader not found: " + name + " (FP16).\n- Is Lossless Scaling up to date?");
 | 
					            throw std::runtime_error("Shader not found: " + name + " (FP16).\n- Is Lossless Scaling up to date?");
 | 
				
			||||||
        auto fp32 = shaders.find(idx + FP);
 | 
					        auto fp32 = resources.find(idx + FP);
 | 
				
			||||||
        if (fp32 == shaders.end())
 | 
					        if (fp32 == resources.end())
 | 
				
			||||||
            throw std::runtime_error("Shader not found: " + name + " (FP32).\n- Is Lossless Scaling up to date?");
 | 
					            throw std::runtime_error("Shader not found: " + name + " (FP32).\n- Is Lossless Scaling up to date?");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pshaders().emplace(idx, std::array<std::vector<uint8_t>, 2>{
 | 
					        shaders().emplace(idx, std::array<std::vector<uint8_t>, 2>{
 | 
				
			||||||
            std::move(fp32->second),
 | 
					            fp32->second,
 | 
				
			||||||
            std::move(fp16->second)
 | 
					            fp16->second
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::vector<uint8_t> Extract::getShader(const std::string& name, bool fp16) {
 | 
					std::vector<uint8_t> Extract::getShader(const std::string& name, bool fp16) {
 | 
				
			||||||
    if (pshaders().empty())
 | 
					    if (shaders().empty())
 | 
				
			||||||
        throw std::runtime_error("Shaders are not loaded.");
 | 
					        throw std::runtime_error("Shaders are not loaded.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto hit = nameIdxTable.find(name);
 | 
					    auto hit = nameIdxTable.find(name);
 | 
				
			||||||
    if (hit == nameIdxTable.end())
 | 
					    if (hit == nameIdxTable.end())
 | 
				
			||||||
        throw std::runtime_error("Shader hash not found: " + name);
 | 
					        throw std::runtime_error("Shader hash not found: " + name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto sit = pshaders().find(hit->second);
 | 
					    auto sit = shaders().find(hit->second);
 | 
				
			||||||
    if (sit == pshaders().end())
 | 
					    if (sit == shaders().end())
 | 
				
			||||||
        throw std::runtime_error("Shader not found: " + name);
 | 
					        throw std::runtime_error("Shader not found: " + name);
 | 
				
			||||||
    return fp16 ? sit->second.at(1) : sit->second.at(0);
 | 
					    return fp16 ? sit->second.at(1) : sit->second.at(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								thirdparty/pe-parse
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								thirdparty/pe-parse
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
Subproject commit 31ac5966503689d5693cd9fb520bd525a8710e17
 | 
					 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue