Compare commits
25 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3370546a7a | ||
|
|
20576ebb43 | ||
|
|
6f81160160 | ||
|
|
266e086706 | ||
|
|
9561a2f5b1 | ||
|
|
bc8699a9fa | ||
|
|
073714a762 | ||
|
|
4ae75bec50 | ||
|
|
31527ccd25 | ||
|
|
268878f895 | ||
|
|
d00b7be2d6 | ||
|
|
708e5b027f | ||
|
|
c33c9c76bf | ||
|
|
888e814130 | ||
|
|
cad53179ed | ||
|
|
3c313a43fd | ||
|
|
45bdbf538c | ||
|
|
14db101148 | ||
|
|
ea89cf8639 | ||
|
|
054732210e | ||
|
|
e609bc1c6a | ||
|
|
499c89790b | ||
|
|
75bf2c20eb | ||
|
|
017a18f42e | ||
|
|
669a9a644d |
13
dist/qt_themes/default/style.qss
vendored
13
dist/qt_themes/default/style.qss
vendored
@@ -58,6 +58,19 @@ QPushButton#GPUStatusBarButton:!checked {
|
||||
color: #109010;
|
||||
}
|
||||
|
||||
QPushButton#DockingStatusBarButton {
|
||||
min-width: 0px;
|
||||
color: #000000;
|
||||
border: 1px solid transparent;
|
||||
background-color: transparent;
|
||||
padding: 0px 3px 0px 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QPushButton#DockingStatusBarButton:hover {
|
||||
border: 1px solid #76797C;
|
||||
}
|
||||
|
||||
QPushButton#buttonRefreshDevices {
|
||||
min-width: 21px;
|
||||
min-height: 21px;
|
||||
|
||||
13
dist/qt_themes/qdarkstyle/style.qss
vendored
13
dist/qt_themes/qdarkstyle/style.qss
vendored
@@ -1304,6 +1304,19 @@ QPushButton#GPUStatusBarButton:!checked {
|
||||
color: #40dd40;
|
||||
}
|
||||
|
||||
QPushButton#DockingStatusBarButton {
|
||||
min-width: 0px;
|
||||
color: #ffffff;
|
||||
border: 1px solid transparent;
|
||||
background-color: transparent;
|
||||
padding: 0px 3px 0px 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QPushButton#DockingStatusBarButton:hover {
|
||||
border: 1px solid #76797C;
|
||||
}
|
||||
|
||||
QPushButton#buttonRefreshDevices {
|
||||
min-width: 23px;
|
||||
min-height: 23px;
|
||||
|
||||
@@ -2207,6 +2207,19 @@ QPushButton#GPUStatusBarButton:!checked {
|
||||
color: #40dd40;
|
||||
}
|
||||
|
||||
QPushButton#DockingStatusBarButton {
|
||||
min-width: 0px;
|
||||
color: #ffffff;
|
||||
border: 1px solid transparent;
|
||||
background-color: transparent;
|
||||
padding: 0px 3px 0px 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QPushButton#DockingStatusBarButton:hover {
|
||||
border: 1px solid #76797C;
|
||||
}
|
||||
|
||||
QPushButton#buttonRefreshDevices {
|
||||
min-width: 19px;
|
||||
min-height: 19px;
|
||||
|
||||
@@ -58,6 +58,7 @@ add_library(common STATIC
|
||||
div_ceil.h
|
||||
dynamic_library.cpp
|
||||
dynamic_library.h
|
||||
elf.h
|
||||
error.cpp
|
||||
error.h
|
||||
expected.h
|
||||
|
||||
333
src/common/elf.h
Normal file
333
src/common/elf.h
Normal file
@@ -0,0 +1,333 @@
|
||||
// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
#include "common_types.h"
|
||||
|
||||
namespace Common {
|
||||
namespace ELF {
|
||||
|
||||
/* Type for a 16-bit quantity. */
|
||||
using Elf32_Half = u16;
|
||||
using Elf64_Half = u16;
|
||||
|
||||
/* Types for signed and unsigned 32-bit quantities. */
|
||||
using Elf32_Word = u32;
|
||||
using Elf32_Sword = s32;
|
||||
using Elf64_Word = u32;
|
||||
using Elf64_Sword = s32;
|
||||
|
||||
/* Types for signed and unsigned 64-bit quantities. */
|
||||
using Elf32_Xword = u64;
|
||||
using Elf32_Sxword = s64;
|
||||
using Elf64_Xword = u64;
|
||||
using Elf64_Sxword = s64;
|
||||
|
||||
/* Type of addresses. */
|
||||
using Elf32_Addr = u32;
|
||||
using Elf64_Addr = u64;
|
||||
|
||||
/* Type of file offsets. */
|
||||
using Elf32_Off = u32;
|
||||
using Elf64_Off = u64;
|
||||
|
||||
/* Type for section indices, which are 16-bit quantities. */
|
||||
using Elf32_Section = u16;
|
||||
using Elf64_Section = u16;
|
||||
|
||||
/* Type for version symbol information. */
|
||||
using Elf32_Versym = Elf32_Half;
|
||||
using Elf64_Versym = Elf64_Half;
|
||||
|
||||
constexpr size_t ElfIdentSize = 16;
|
||||
|
||||
/* The ELF file header. This appears at the start of every ELF file. */
|
||||
|
||||
struct Elf32_Ehdr {
|
||||
std::array<u8, ElfIdentSize> e_ident; /* Magic number and other info */
|
||||
Elf32_Half e_type; /* Object file type */
|
||||
Elf32_Half e_machine; /* Architecture */
|
||||
Elf32_Word e_version; /* Object file version */
|
||||
Elf32_Addr e_entry; /* Entry point virtual address */
|
||||
Elf32_Off e_phoff; /* Program header table file offset */
|
||||
Elf32_Off e_shoff; /* Section header table file offset */
|
||||
Elf32_Word e_flags; /* Processor-specific flags */
|
||||
Elf32_Half e_ehsize; /* ELF header size in bytes */
|
||||
Elf32_Half e_phentsize; /* Program header table entry size */
|
||||
Elf32_Half e_phnum; /* Program header table entry count */
|
||||
Elf32_Half e_shentsize; /* Section header table entry size */
|
||||
Elf32_Half e_shnum; /* Section header table entry count */
|
||||
Elf32_Half e_shstrndx; /* Section header string table index */
|
||||
};
|
||||
|
||||
struct Elf64_Ehdr {
|
||||
std::array<u8, ElfIdentSize> e_ident; /* Magic number and other info */
|
||||
Elf64_Half e_type; /* Object file type */
|
||||
Elf64_Half e_machine; /* Architecture */
|
||||
Elf64_Word e_version; /* Object file version */
|
||||
Elf64_Addr e_entry; /* Entry point virtual address */
|
||||
Elf64_Off e_phoff; /* Program header table file offset */
|
||||
Elf64_Off e_shoff; /* Section header table file offset */
|
||||
Elf64_Word e_flags; /* Processor-specific flags */
|
||||
Elf64_Half e_ehsize; /* ELF header size in bytes */
|
||||
Elf64_Half e_phentsize; /* Program header table entry size */
|
||||
Elf64_Half e_phnum; /* Program header table entry count */
|
||||
Elf64_Half e_shentsize; /* Section header table entry size */
|
||||
Elf64_Half e_shnum; /* Section header table entry count */
|
||||
Elf64_Half e_shstrndx; /* Section header string table index */
|
||||
};
|
||||
|
||||
constexpr u8 ElfClass32 = 1; /* 32-bit objects */
|
||||
constexpr u8 ElfClass64 = 2; /* 64-bit objects */
|
||||
constexpr u8 ElfData2Lsb = 1; /* 2's complement, little endian */
|
||||
constexpr u8 ElfVersionCurrent = 1; /* EV_CURRENT */
|
||||
constexpr u8 ElfOsAbiNone = 0; /* System V ABI */
|
||||
|
||||
constexpr u16 ElfTypeNone = 0; /* No file type */
|
||||
constexpr u16 ElfTypeRel = 0; /* Relocatable file */
|
||||
constexpr u16 ElfTypeExec = 0; /* Executable file */
|
||||
constexpr u16 ElfTypeDyn = 0; /* Shared object file */
|
||||
|
||||
constexpr u16 ElfMachineArm = 40; /* ARM */
|
||||
constexpr u16 ElfMachineAArch64 = 183; /* ARM AARCH64 */
|
||||
|
||||
constexpr std::array<u8, ElfIdentSize> Elf32Ident{
|
||||
0x7f, 'E', 'L', 'F', ElfClass32, ElfData2Lsb, ElfVersionCurrent, ElfOsAbiNone};
|
||||
|
||||
constexpr std::array<u8, ElfIdentSize> Elf64Ident{
|
||||
0x7f, 'E', 'L', 'F', ElfClass64, ElfData2Lsb, ElfVersionCurrent, ElfOsAbiNone};
|
||||
|
||||
/* Section header. */
|
||||
|
||||
struct Elf32_Shdr {
|
||||
Elf32_Word sh_name; /* Section name (string tbl index) */
|
||||
Elf32_Word sh_type; /* Section type */
|
||||
Elf32_Word sh_flags; /* Section flags */
|
||||
Elf32_Addr sh_addr; /* Section virtual addr at execution */
|
||||
Elf32_Off sh_offset; /* Section file offset */
|
||||
Elf32_Word sh_size; /* Section size in bytes */
|
||||
Elf32_Word sh_link; /* Link to another section */
|
||||
Elf32_Word sh_info; /* Additional section information */
|
||||
Elf32_Word sh_addralign; /* Section alignment */
|
||||
Elf32_Word sh_entsize; /* Entry size if section holds table */
|
||||
};
|
||||
|
||||
struct Elf64_Shdr {
|
||||
Elf64_Word sh_name; /* Section name (string tbl index) */
|
||||
Elf64_Word sh_type; /* Section type */
|
||||
Elf64_Xword sh_flags; /* Section flags */
|
||||
Elf64_Addr sh_addr; /* Section virtual addr at execution */
|
||||
Elf64_Off sh_offset; /* Section file offset */
|
||||
Elf64_Xword sh_size; /* Section size in bytes */
|
||||
Elf64_Word sh_link; /* Link to another section */
|
||||
Elf64_Word sh_info; /* Additional section information */
|
||||
Elf64_Xword sh_addralign; /* Section alignment */
|
||||
Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||
};
|
||||
|
||||
constexpr u32 ElfShnUndef = 0; /* Undefined section */
|
||||
|
||||
constexpr u32 ElfShtNull = 0; /* Section header table entry unused */
|
||||
constexpr u32 ElfShtProgBits = 1; /* Program data */
|
||||
constexpr u32 ElfShtSymtab = 2; /* Symbol table */
|
||||
constexpr u32 ElfShtStrtab = 3; /* String table */
|
||||
constexpr u32 ElfShtRela = 4; /* Relocation entries with addends */
|
||||
constexpr u32 ElfShtDynamic = 6; /* Dynamic linking information */
|
||||
constexpr u32 ElfShtNobits = 7; /* Program space with no data (bss) */
|
||||
constexpr u32 ElfShtRel = 9; /* Relocation entries, no addends */
|
||||
constexpr u32 ElfShtDynsym = 11; /* Dynamic linker symbol table */
|
||||
|
||||
/* Symbol table entry. */
|
||||
|
||||
struct Elf32_Sym {
|
||||
Elf32_Word st_name; /* Symbol name (string tbl index) */
|
||||
Elf32_Addr st_value; /* Symbol value */
|
||||
Elf32_Word st_size; /* Symbol size */
|
||||
u8 st_info; /* Symbol type and binding */
|
||||
u8 st_other; /* Symbol visibility */
|
||||
Elf32_Section st_shndx; /* Section index */
|
||||
};
|
||||
|
||||
struct Elf64_Sym {
|
||||
Elf64_Word st_name; /* Symbol name (string tbl index) */
|
||||
u8 st_info; /* Symbol type and binding */
|
||||
u8 st_other; /* Symbol visibility */
|
||||
Elf64_Section st_shndx; /* Section index */
|
||||
Elf64_Addr st_value; /* Symbol value */
|
||||
Elf64_Xword st_size; /* Symbol size */
|
||||
};
|
||||
|
||||
/* How to extract and insert information held in the st_info field. */
|
||||
|
||||
static inline u8 ElfStBind(u8 st_info) {
|
||||
return st_info >> 4;
|
||||
}
|
||||
static inline u8 ElfStType(u8 st_info) {
|
||||
return st_info & 0xf;
|
||||
}
|
||||
static inline u8 ElfStInfo(u8 st_bind, u8 st_type) {
|
||||
return static_cast<u8>((st_bind << 4) + (st_type & 0xf));
|
||||
}
|
||||
|
||||
constexpr u8 ElfBindLocal = 0; /* Local symbol */
|
||||
constexpr u8 ElfBindGlobal = 1; /* Global symbol */
|
||||
constexpr u8 ElfBindWeak = 2; /* Weak symbol */
|
||||
|
||||
constexpr u8 ElfTypeUnspec = 0; /* Symbol type is unspecified */
|
||||
constexpr u8 ElfTypeObject = 1; /* Symbol is a data object */
|
||||
constexpr u8 ElfTypeFunc = 2; /* Symbol is a code object */
|
||||
|
||||
static inline u8 ElfStVisibility(u8 st_other) {
|
||||
return static_cast<u8>(st_other & 0x3);
|
||||
}
|
||||
|
||||
constexpr u8 ElfVisibilityDefault = 0; /* Default symbol visibility rules */
|
||||
constexpr u8 ElfVisibilityInternal = 1; /* Processor specific hidden class */
|
||||
constexpr u8 ElfVisibilityHidden = 2; /* Sym unavailable in other modules */
|
||||
constexpr u8 ElfVisibilityProtected = 3; /* Not preemptible, not exported */
|
||||
|
||||
/* Relocation table entry without addend (in section of type ShtRel). */
|
||||
|
||||
struct Elf32_Rel {
|
||||
Elf32_Addr r_offset; /* Address */
|
||||
Elf32_Word r_info; /* Relocation type and symbol index */
|
||||
};
|
||||
|
||||
/* Relocation table entry with addend (in section of type ShtRela). */
|
||||
|
||||
struct Elf32_Rela {
|
||||
Elf32_Addr r_offset; /* Address */
|
||||
Elf32_Word r_info; /* Relocation type and symbol index */
|
||||
Elf32_Sword r_addend; /* Addend */
|
||||
};
|
||||
|
||||
struct Elf64_Rela {
|
||||
Elf64_Addr r_offset; /* Address */
|
||||
Elf64_Xword r_info; /* Relocation type and symbol index */
|
||||
Elf64_Sxword r_addend; /* Addend */
|
||||
};
|
||||
|
||||
/* How to extract and insert information held in the r_info field. */
|
||||
|
||||
static inline u32 Elf32RelSymIndex(Elf32_Word r_info) {
|
||||
return r_info >> 8;
|
||||
}
|
||||
static inline u8 Elf32RelType(Elf32_Word r_info) {
|
||||
return static_cast<u8>(r_info & 0xff);
|
||||
}
|
||||
static inline Elf32_Word Elf32RelInfo(u32 sym_index, u8 type) {
|
||||
return (sym_index << 8) + type;
|
||||
}
|
||||
static inline u32 Elf64RelSymIndex(Elf64_Xword r_info) {
|
||||
return static_cast<u32>(r_info >> 32);
|
||||
}
|
||||
static inline u32 Elf64RelType(Elf64_Xword r_info) {
|
||||
return r_info & 0xffffffff;
|
||||
}
|
||||
static inline Elf64_Xword Elf64RelInfo(u32 sym_index, u32 type) {
|
||||
return (static_cast<Elf64_Xword>(sym_index) << 32) + type;
|
||||
}
|
||||
|
||||
constexpr u32 ElfArmCopy = 20; /* Copy symbol at runtime */
|
||||
constexpr u32 ElfArmGlobDat = 21; /* Create GOT entry */
|
||||
constexpr u32 ElfArmJumpSlot = 22; /* Create PLT entry */
|
||||
constexpr u32 ElfArmRelative = 23; /* Adjust by program base */
|
||||
|
||||
constexpr u32 ElfAArch64Copy = 1024; /* Copy symbol at runtime */
|
||||
constexpr u32 ElfAArch64GlobDat = 1025; /* Create GOT entry */
|
||||
constexpr u32 ElfAArch64JumpSlot = 1026; /* Create PLT entry */
|
||||
constexpr u32 ElfAArch64Relative = 1027; /* Adjust by program base */
|
||||
|
||||
/* Program segment header. */
|
||||
|
||||
struct Elf32_Phdr {
|
||||
Elf32_Word p_type; /* Segment type */
|
||||
Elf32_Off p_offset; /* Segment file offset */
|
||||
Elf32_Addr p_vaddr; /* Segment virtual address */
|
||||
Elf32_Addr p_paddr; /* Segment physical address */
|
||||
Elf32_Word p_filesz; /* Segment size in file */
|
||||
Elf32_Word p_memsz; /* Segment size in memory */
|
||||
Elf32_Word p_flags; /* Segment flags */
|
||||
Elf32_Word p_align; /* Segment alignment */
|
||||
};
|
||||
|
||||
struct Elf64_Phdr {
|
||||
Elf64_Word p_type; /* Segment type */
|
||||
Elf64_Word p_flags; /* Segment flags */
|
||||
Elf64_Off p_offset; /* Segment file offset */
|
||||
Elf64_Addr p_vaddr; /* Segment virtual address */
|
||||
Elf64_Addr p_paddr; /* Segment physical address */
|
||||
Elf64_Xword p_filesz; /* Segment size in file */
|
||||
Elf64_Xword p_memsz; /* Segment size in memory */
|
||||
Elf64_Xword p_align; /* Segment alignment */
|
||||
};
|
||||
|
||||
/* Legal values for p_type (segment type). */
|
||||
|
||||
constexpr u32 ElfPtNull = 0; /* Program header table entry unused */
|
||||
constexpr u32 ElfPtLoad = 1; /* Loadable program segment */
|
||||
constexpr u32 ElfPtDynamic = 2; /* Dynamic linking information */
|
||||
constexpr u32 ElfPtInterp = 3; /* Program interpreter */
|
||||
constexpr u32 ElfPtNote = 4; /* Auxiliary information */
|
||||
constexpr u32 ElfPtPhdr = 6; /* Entry for header table itself */
|
||||
constexpr u32 ElfPtTls = 7; /* Thread-local storage segment */
|
||||
|
||||
/* Legal values for p_flags (segment flags). */
|
||||
|
||||
constexpr u32 ElfPfExec = 0; /* Segment is executable */
|
||||
constexpr u32 ElfPfWrite = 1; /* Segment is writable */
|
||||
constexpr u32 ElfPfRead = 2; /* Segment is readable */
|
||||
|
||||
/* Dynamic section entry. */
|
||||
|
||||
struct Elf32_Dyn {
|
||||
Elf32_Sword d_tag; /* Dynamic entry type */
|
||||
union {
|
||||
Elf32_Word d_val; /* Integer value */
|
||||
Elf32_Addr d_ptr; /* Address value */
|
||||
} d_un;
|
||||
};
|
||||
|
||||
struct Elf64_Dyn {
|
||||
Elf64_Sxword d_tag; /* Dynamic entry type */
|
||||
union {
|
||||
Elf64_Xword d_val; /* Integer value */
|
||||
Elf64_Addr d_ptr; /* Address value */
|
||||
} d_un;
|
||||
};
|
||||
|
||||
/* Legal values for d_tag (dynamic entry type). */
|
||||
|
||||
constexpr u32 ElfDtNull = 0; /* Marks end of dynamic section */
|
||||
constexpr u32 ElfDtNeeded = 1; /* Name of needed library */
|
||||
constexpr u32 ElfDtPltRelSz = 2; /* Size in bytes of PLT relocs */
|
||||
constexpr u32 ElfDtPltGot = 3; /* Processor defined value */
|
||||
constexpr u32 ElfDtHash = 4; /* Address of symbol hash table */
|
||||
constexpr u32 ElfDtStrtab = 5; /* Address of string table */
|
||||
constexpr u32 ElfDtSymtab = 6; /* Address of symbol table */
|
||||
constexpr u32 ElfDtRela = 7; /* Address of Rela relocs */
|
||||
constexpr u32 ElfDtRelasz = 8; /* Total size of Rela relocs */
|
||||
constexpr u32 ElfDtRelaent = 9; /* Size of one Rela reloc */
|
||||
constexpr u32 ElfDtStrsz = 10; /* Size of string table */
|
||||
constexpr u32 ElfDtSyment = 11; /* Size of one symbol table entry */
|
||||
constexpr u32 ElfDtInit = 12; /* Address of init function */
|
||||
constexpr u32 ElfDtFini = 13; /* Address of termination function */
|
||||
constexpr u32 ElfDtRel = 17; /* Address of Rel relocs */
|
||||
constexpr u32 ElfDtRelsz = 18; /* Total size of Rel relocs */
|
||||
constexpr u32 ElfDtRelent = 19; /* Size of one Rel reloc */
|
||||
constexpr u32 ElfDtPltRel = 20; /* Type of reloc in PLT */
|
||||
constexpr u32 ElfDtTextRel = 22; /* Reloc might modify .text */
|
||||
constexpr u32 ElfDtJmpRel = 23; /* Address of PLT relocs */
|
||||
constexpr u32 ElfDtBindNow = 24; /* Process relocations of object */
|
||||
constexpr u32 ElfDtInitArray = 25; /* Array with addresses of init fct */
|
||||
constexpr u32 ElfDtFiniArray = 26; /* Array with addresses of fini fct */
|
||||
constexpr u32 ElfDtInitArraySz = 27; /* Size in bytes of DT_INIT_ARRAY */
|
||||
constexpr u32 ElfDtFiniArraySz = 28; /* Size in bytes of DT_FINI_ARRAY */
|
||||
constexpr u32 ElfDtSymtabShndx = 34; /* Address of SYMTAB_SHNDX section */
|
||||
|
||||
} // namespace ELF
|
||||
} // namespace Common
|
||||
@@ -3,73 +3,14 @@
|
||||
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/elf.h"
|
||||
#include "core/arm/symbols.h"
|
||||
#include "core/core.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
using namespace Common::ELF;
|
||||
|
||||
namespace Core {
|
||||
namespace {
|
||||
|
||||
constexpr u64 ELF_DYNAMIC_TAG_NULL = 0;
|
||||
constexpr u64 ELF_DYNAMIC_TAG_STRTAB = 5;
|
||||
constexpr u64 ELF_DYNAMIC_TAG_SYMTAB = 6;
|
||||
constexpr u64 ELF_DYNAMIC_TAG_SYMENT = 11;
|
||||
|
||||
enum class ELFSymbolType : u8 {
|
||||
None = 0,
|
||||
Object = 1,
|
||||
Function = 2,
|
||||
Section = 3,
|
||||
File = 4,
|
||||
Common = 5,
|
||||
TLS = 6,
|
||||
};
|
||||
|
||||
enum class ELFSymbolBinding : u8 {
|
||||
Local = 0,
|
||||
Global = 1,
|
||||
Weak = 2,
|
||||
};
|
||||
|
||||
enum class ELFSymbolVisibility : u8 {
|
||||
Default = 0,
|
||||
Internal = 1,
|
||||
Hidden = 2,
|
||||
Protected = 3,
|
||||
};
|
||||
|
||||
struct ELF64Symbol {
|
||||
u32 name_index;
|
||||
union {
|
||||
u8 info;
|
||||
|
||||
BitField<0, 4, ELFSymbolType> type;
|
||||
BitField<4, 4, ELFSymbolBinding> binding;
|
||||
};
|
||||
ELFSymbolVisibility visibility;
|
||||
u16 sh_index;
|
||||
u64 value;
|
||||
u64 size;
|
||||
};
|
||||
static_assert(sizeof(ELF64Symbol) == 0x18, "ELF64Symbol has incorrect size.");
|
||||
|
||||
struct ELF32Symbol {
|
||||
u32 name_index;
|
||||
u32 value;
|
||||
u32 size;
|
||||
union {
|
||||
u8 info;
|
||||
|
||||
BitField<0, 4, ELFSymbolType> type;
|
||||
BitField<4, 4, ELFSymbolBinding> binding;
|
||||
};
|
||||
ELFSymbolVisibility visibility;
|
||||
u16 sh_index;
|
||||
};
|
||||
static_assert(sizeof(ELF32Symbol) == 0x10, "ELF32Symbol has incorrect size.");
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
namespace Symbols {
|
||||
|
||||
template <typename Word, typename ELFSymbol, typename ByteReader>
|
||||
@@ -110,15 +51,15 @@ static Symbols GetSymbols(ByteReader ReadBytes) {
|
||||
const Word value = ReadWord(dynamic_index + sizeof(Word));
|
||||
dynamic_index += 2 * sizeof(Word);
|
||||
|
||||
if (tag == ELF_DYNAMIC_TAG_NULL) {
|
||||
if (tag == ElfDtNull) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (tag == ELF_DYNAMIC_TAG_STRTAB) {
|
||||
if (tag == ElfDtStrtab) {
|
||||
string_table_offset = value;
|
||||
} else if (tag == ELF_DYNAMIC_TAG_SYMTAB) {
|
||||
} else if (tag == ElfDtSymtab) {
|
||||
symbol_table_offset = value;
|
||||
} else if (tag == ELF_DYNAMIC_TAG_SYMENT) {
|
||||
} else if (tag == ElfDtSyment) {
|
||||
symbol_entry_size = value;
|
||||
}
|
||||
}
|
||||
@@ -134,14 +75,14 @@ static Symbols GetSymbols(ByteReader ReadBytes) {
|
||||
ELFSymbol symbol{};
|
||||
ReadBytes(&symbol, symbol_index, sizeof(ELFSymbol));
|
||||
|
||||
VAddr string_offset = string_table_offset + symbol.name_index;
|
||||
VAddr string_offset = string_table_offset + symbol.st_name;
|
||||
std::string name;
|
||||
for (u8 c = Read8(string_offset); c != 0; c = Read8(++string_offset)) {
|
||||
name += static_cast<char>(c);
|
||||
}
|
||||
|
||||
symbol_index += symbol_entry_size;
|
||||
out[name] = std::make_pair(symbol.value, symbol.size);
|
||||
out[name] = std::make_pair(symbol.st_value, symbol.st_size);
|
||||
}
|
||||
|
||||
return out;
|
||||
@@ -152,9 +93,9 @@ Symbols GetSymbols(VAddr base, Core::Memory::Memory& memory, bool is_64) {
|
||||
[&](void* ptr, size_t offset, size_t size) { memory.ReadBlock(base + offset, ptr, size); }};
|
||||
|
||||
if (is_64) {
|
||||
return GetSymbols<u64, ELF64Symbol>(ReadBytes);
|
||||
return GetSymbols<u64, Elf64_Sym>(ReadBytes);
|
||||
} else {
|
||||
return GetSymbols<u32, ELF32Symbol>(ReadBytes);
|
||||
return GetSymbols<u32, Elf32_Sym>(ReadBytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,9 +105,9 @@ Symbols GetSymbols(std::span<const u8> data, bool is_64) {
|
||||
}};
|
||||
|
||||
if (is_64) {
|
||||
return GetSymbols<u64, ELF64Symbol>(ReadBytes);
|
||||
return GetSymbols<u64, Elf64_Sym>(ReadBytes);
|
||||
} else {
|
||||
return GetSymbols<u32, ELF32Symbol>(ReadBytes);
|
||||
return GetSymbols<u32, Elf32_Sym>(ReadBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,15 +20,16 @@ template <typename Readable, typename Buffer, typename Callback>
|
||||
static void AsyncReceiveInto(Readable& r, Buffer& buffer, Callback&& c) {
|
||||
static_assert(std::is_trivial_v<Buffer>);
|
||||
auto boost_buffer{boost::asio::buffer(&buffer, sizeof(Buffer))};
|
||||
r.async_read_some(boost_buffer, [&](const boost::system::error_code& error, size_t bytes_read) {
|
||||
if (!error.failed()) {
|
||||
const u8* buffer_start = reinterpret_cast<const u8*>(&buffer);
|
||||
std::span<const u8> received_data{buffer_start, buffer_start + bytes_read};
|
||||
c(received_data);
|
||||
}
|
||||
r.async_read_some(
|
||||
boost_buffer, [&, c](const boost::system::error_code& error, size_t bytes_read) {
|
||||
if (!error.failed()) {
|
||||
const u8* buffer_start = reinterpret_cast<const u8*>(&buffer);
|
||||
std::span<const u8> received_data{buffer_start, buffer_start + bytes_read};
|
||||
c(received_data);
|
||||
}
|
||||
|
||||
AsyncReceiveInto(r, buffer, c);
|
||||
});
|
||||
AsyncReceiveInto(r, buffer, c);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Readable, typename Buffer>
|
||||
@@ -65,7 +66,7 @@ public:
|
||||
}
|
||||
stopped = true;
|
||||
|
||||
signal_pipe.write_some(boost::asio::buffer(&thread, sizeof(thread)));
|
||||
boost::asio::write(signal_pipe, boost::asio::buffer(&thread, sizeof(thread)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,7 +75,7 @@ public:
|
||||
}
|
||||
|
||||
void WriteToClient(std::span<const u8> data) override {
|
||||
client_socket.write_some(boost::asio::buffer(data.data(), data.size_bytes()));
|
||||
boost::asio::write(client_socket, boost::asio::buffer(data.data(), data.size_bytes()));
|
||||
}
|
||||
|
||||
void SetActiveThread(Kernel::KThread* thread) override {
|
||||
|
||||
@@ -61,6 +61,7 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
|
||||
}
|
||||
|
||||
last_update_timestamp = shared_memory->gesture_lifo.timestamp;
|
||||
UpdateGestureSharedMemory(gesture, time_difference);
|
||||
}
|
||||
|
||||
void Controller_Gesture::ReadTouchInput() {
|
||||
@@ -94,8 +95,7 @@ bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture,
|
||||
return false;
|
||||
}
|
||||
|
||||
void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
|
||||
GestureProperties& gesture,
|
||||
void Controller_Gesture::UpdateGestureSharedMemory(GestureProperties& gesture,
|
||||
f32 time_difference) {
|
||||
GestureType type = GestureType::Idle;
|
||||
GestureAttribute attributes{};
|
||||
|
||||
@@ -107,8 +107,7 @@ private:
|
||||
bool ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference);
|
||||
|
||||
// Updates the shared memory to the next state
|
||||
void UpdateGestureSharedMemory(u8* data, std::size_t size, GestureProperties& gesture,
|
||||
f32 time_difference);
|
||||
void UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference);
|
||||
|
||||
// Initializes new gesture
|
||||
void NewGesture(GestureProperties& gesture, GestureType& type, GestureAttribute& attributes);
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_shared_memory.h"
|
||||
#include "core/hle/kernel/k_transfer_memory.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/service/hid/errors.h"
|
||||
#include "core/hle/service/hid/irs.h"
|
||||
|
||||
namespace Service::HID {
|
||||
@@ -38,21 +40,32 @@ IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
|
||||
}
|
||||
|
||||
void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
|
||||
applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::DeactivateIrsensor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
|
||||
applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_IRS, "called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_DEBUG(Service_IRS, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||
rb.Push(ResultSuccess);
|
||||
@@ -60,35 +73,109 @@ void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
IrCameraHandle camera_handle;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
|
||||
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
|
||||
parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
IrCameraHandle camera_handle;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
PackedMomentProcessorConfig processor_config;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
|
||||
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
|
||||
parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
IrCameraHandle camera_handle;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
PackedClusteringProcessorConfig processor_config;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x40, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
|
||||
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
|
||||
parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
IrCameraHandle camera_handle;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
PackedImageTransferProcessorConfig processor_config;
|
||||
u32 transfer_memory_size;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
const auto t_mem_handle{ctx.GetCopyHandle(0)};
|
||||
|
||||
auto t_mem =
|
||||
system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, "
|
||||
"applet_resource_user_id={}",
|
||||
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
|
||||
parameters.transfer_memory_size, parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
IrCameraHandle camera_handle;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
|
||||
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
|
||||
parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 5};
|
||||
rb.Push(ResultSuccess);
|
||||
@@ -97,71 +184,195 @@ void IRS::GetImageTransferProcessorState(Kernel::HLERequestContext& ctx) {
|
||||
}
|
||||
|
||||
void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
|
||||
const auto processor_config{rp.PopRaw<PackedTeraPluginProcessorConfig>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, mode={}, mcu_version={}.{}, "
|
||||
"applet_resource_user_id={}",
|
||||
camera_handle.npad_type, camera_handle.npad_id, processor_config.mode,
|
||||
processor_config.required_mcu_version.major,
|
||||
processor_config.required_mcu_version.minor, applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::GetNpadIrCameraHandle(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
|
||||
|
||||
if (npad_id > Core::HID::NpadIdType::Player8 && npad_id != Core::HID::NpadIdType::Invalid &&
|
||||
npad_id != Core::HID::NpadIdType::Handheld) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(InvalidNpadId);
|
||||
return;
|
||||
}
|
||||
|
||||
IrCameraHandle camera_handle{
|
||||
.npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)),
|
||||
.npad_type = Core::HID::NpadStyleIndex::None,
|
||||
};
|
||||
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called, npad_id={}, camera_npad_id={}, camera_npad_type={}",
|
||||
npad_id, camera_handle.npad_id, camera_handle.npad_type);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw<u32>(device_handle);
|
||||
rb.PushRaw(camera_handle);
|
||||
}
|
||||
|
||||
void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
|
||||
const auto processor_config{rp.PopRaw<PackedPointingProcessorConfig>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(
|
||||
Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, mcu_version={}.{}, applet_resource_user_id={}",
|
||||
camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major,
|
||||
processor_config.required_mcu_version.minor, applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::SuspendImageProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
IrCameraHandle camera_handle;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
|
||||
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
|
||||
parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::CheckFirmwareVersion(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
|
||||
const auto mcu_version{rp.PopRaw<PackedMcuVersion>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(
|
||||
Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}, mcu_version={}.{}",
|
||||
camera_handle.npad_type, camera_handle.npad_id, applet_resource_user_id, mcu_version.major,
|
||||
mcu_version.minor);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::SetFunctionLevel(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
IrCameraHandle camera_handle;
|
||||
PackedFunctionLevel function_level;
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
|
||||
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
|
||||
parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
IrCameraHandle camera_handle;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
PackedImageTransferProcessorExConfig processor_config;
|
||||
u64 transfer_memory_size;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
const auto t_mem_handle{ctx.GetCopyHandle(0)};
|
||||
|
||||
auto t_mem =
|
||||
system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, transfer_memory_size={}, "
|
||||
"applet_resource_user_id={}",
|
||||
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
|
||||
parameters.transfer_memory_size, parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto camera_handle{rp.PopRaw<IrCameraHandle>()};
|
||||
const auto processor_config{rp.PopRaw<PackedIrLedProcessorConfig>()};
|
||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, light_target={}, mcu_version={}.{} "
|
||||
"applet_resource_user_id={}",
|
||||
camera_handle.npad_type, camera_handle.npad_id, processor_config.light_target,
|
||||
processor_config.required_mcu_version.major,
|
||||
processor_config.required_mcu_version.minor, applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
IrCameraHandle camera_handle;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_IRS,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
|
||||
parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
|
||||
parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
}
|
||||
|
||||
void IRS::ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
PackedFunctionLevel function_level;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(Service_IRS, "(STUBBED) called, function_level={}, applet_resource_user_id={}",
|
||||
parameters.function_level.function_level, parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hid/hid_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Core {
|
||||
@@ -17,6 +18,235 @@ public:
|
||||
~IRS() override;
|
||||
|
||||
private:
|
||||
// This is nn::irsensor::IrCameraStatus
|
||||
enum IrCameraStatus : u32 {
|
||||
Available,
|
||||
Unsupported,
|
||||
Unconnected,
|
||||
};
|
||||
|
||||
// This is nn::irsensor::IrCameraInternalStatus
|
||||
enum IrCameraInternalStatus : u32 {
|
||||
Stopped,
|
||||
FirmwareUpdateNeeded,
|
||||
Unkown2,
|
||||
Unkown3,
|
||||
Unkown4,
|
||||
FirmwareVersionRequested,
|
||||
FirmwareVersionIsInvalid,
|
||||
Ready,
|
||||
Setting,
|
||||
};
|
||||
|
||||
// This is nn::irsensor::detail::StatusManager::IrSensorMode
|
||||
enum IrSensorMode : u64 {
|
||||
None,
|
||||
MomentProcessor,
|
||||
ClusteringProcessor,
|
||||
ImageTransferProcessor,
|
||||
PointingProcessorMarker,
|
||||
TeraPluginProcessor,
|
||||
IrLedProcessor,
|
||||
};
|
||||
|
||||
// This is nn::irsensor::ImageProcessorStatus
|
||||
enum ImageProcessorStatus : u8 {
|
||||
stopped,
|
||||
running,
|
||||
};
|
||||
|
||||
// This is nn::irsensor::ImageTransferProcessorFormat
|
||||
enum ImageTransferProcessorFormat : u8 {
|
||||
Size320x240,
|
||||
Size160x120,
|
||||
Size80x60,
|
||||
Size40x30,
|
||||
Size20x15,
|
||||
};
|
||||
|
||||
// This is nn::irsensor::AdaptiveClusteringMode
|
||||
enum AdaptiveClusteringMode : u8 {
|
||||
StaticFov,
|
||||
DynamicFov,
|
||||
};
|
||||
|
||||
// This is nn::irsensor::AdaptiveClusteringTargetDistance
|
||||
enum AdaptiveClusteringTargetDistance : u8 {
|
||||
Near,
|
||||
Middle,
|
||||
Far,
|
||||
};
|
||||
|
||||
// This is nn::irsensor::IrsHandAnalysisMode
|
||||
enum IrsHandAnalysisMode : u8 {
|
||||
Silhouette,
|
||||
Image,
|
||||
SilhoueteAndImage,
|
||||
SilhuetteOnly,
|
||||
};
|
||||
|
||||
// This is nn::irsensor::IrSensorFunctionLevel
|
||||
enum IrSensorFunctionLevel : u8 {
|
||||
unknown0,
|
||||
unknown1,
|
||||
unknown2,
|
||||
unknown3,
|
||||
unknown4,
|
||||
};
|
||||
|
||||
// This is nn::irsensor::IrCameraHandle
|
||||
struct IrCameraHandle {
|
||||
u8 npad_id{};
|
||||
Core::HID::NpadStyleIndex npad_type{Core::HID::NpadStyleIndex::None};
|
||||
INSERT_PADDING_BYTES(2);
|
||||
};
|
||||
static_assert(sizeof(IrCameraHandle) == 4, "IrCameraHandle is an invalid size");
|
||||
|
||||
struct IrsRect {
|
||||
s16 x;
|
||||
s16 y;
|
||||
s16 width;
|
||||
s16 height;
|
||||
};
|
||||
|
||||
// This is nn::irsensor::PackedMcuVersion
|
||||
struct PackedMcuVersion {
|
||||
u16 major;
|
||||
u16 minor;
|
||||
};
|
||||
static_assert(sizeof(PackedMcuVersion) == 4, "PackedMcuVersion is an invalid size");
|
||||
|
||||
// This is nn::irsensor::MomentProcessorConfig
|
||||
struct MomentProcessorConfig {
|
||||
u64 exposire_time;
|
||||
u8 light_target;
|
||||
u8 gain;
|
||||
u8 is_negative_used;
|
||||
INSERT_PADDING_BYTES(7);
|
||||
IrsRect window_of_interest;
|
||||
u8 preprocess;
|
||||
u8 preprocess_intensity_threshold;
|
||||
INSERT_PADDING_BYTES(5);
|
||||
};
|
||||
static_assert(sizeof(MomentProcessorConfig) == 0x28,
|
||||
"MomentProcessorConfig is an invalid size");
|
||||
|
||||
// This is nn::irsensor::PackedMomentProcessorConfig
|
||||
struct PackedMomentProcessorConfig {
|
||||
u64 exposire_time;
|
||||
u8 light_target;
|
||||
u8 gain;
|
||||
u8 is_negative_used;
|
||||
INSERT_PADDING_BYTES(5);
|
||||
IrsRect window_of_interest;
|
||||
PackedMcuVersion required_mcu_version;
|
||||
u8 preprocess;
|
||||
u8 preprocess_intensity_threshold;
|
||||
INSERT_PADDING_BYTES(2);
|
||||
};
|
||||
static_assert(sizeof(PackedMomentProcessorConfig) == 0x20,
|
||||
"PackedMomentProcessorConfig is an invalid size");
|
||||
|
||||
// This is nn::irsensor::ClusteringProcessorConfig
|
||||
struct ClusteringProcessorConfig {
|
||||
u64 exposire_time;
|
||||
u32 light_target;
|
||||
u32 gain;
|
||||
u8 is_negative_used;
|
||||
INSERT_PADDING_BYTES(7);
|
||||
IrsRect window_of_interest;
|
||||
u32 pixel_count_min;
|
||||
u32 pixel_count_max;
|
||||
u32 object_intensity_min;
|
||||
u8 is_external_light_filter_enabled;
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(ClusteringProcessorConfig) == 0x30,
|
||||
"ClusteringProcessorConfig is an invalid size");
|
||||
|
||||
// This is nn::irsensor::PackedClusteringProcessorConfig
|
||||
struct PackedClusteringProcessorConfig {
|
||||
u64 exposire_time;
|
||||
u8 light_target;
|
||||
u8 gain;
|
||||
u8 is_negative_used;
|
||||
INSERT_PADDING_BYTES(5);
|
||||
IrsRect window_of_interest;
|
||||
PackedMcuVersion required_mcu_version;
|
||||
u32 pixel_count_min;
|
||||
u32 pixel_count_max;
|
||||
u32 object_intensity_min;
|
||||
u8 is_external_light_filter_enabled;
|
||||
INSERT_PADDING_BYTES(2);
|
||||
};
|
||||
static_assert(sizeof(PackedClusteringProcessorConfig) == 0x30,
|
||||
"PackedClusteringProcessorConfig is an invalid size");
|
||||
|
||||
// This is nn::irsensor::PackedImageTransferProcessorConfig
|
||||
struct PackedImageTransferProcessorConfig {
|
||||
u64 exposire_time;
|
||||
u8 light_target;
|
||||
u8 gain;
|
||||
u8 is_negative_used;
|
||||
INSERT_PADDING_BYTES(5);
|
||||
PackedMcuVersion required_mcu_version;
|
||||
u8 format;
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(PackedImageTransferProcessorConfig) == 0x18,
|
||||
"PackedImageTransferProcessorConfig is an invalid size");
|
||||
|
||||
// This is nn::irsensor::PackedTeraPluginProcessorConfig
|
||||
struct PackedTeraPluginProcessorConfig {
|
||||
PackedMcuVersion required_mcu_version;
|
||||
u8 mode;
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(PackedTeraPluginProcessorConfig) == 0x8,
|
||||
"PackedTeraPluginProcessorConfig is an invalid size");
|
||||
|
||||
// This is nn::irsensor::PackedPointingProcessorConfig
|
||||
struct PackedPointingProcessorConfig {
|
||||
IrsRect window_of_interest;
|
||||
PackedMcuVersion required_mcu_version;
|
||||
};
|
||||
static_assert(sizeof(PackedPointingProcessorConfig) == 0xC,
|
||||
"PackedPointingProcessorConfig is an invalid size");
|
||||
|
||||
// This is nn::irsensor::PackedFunctionLevel
|
||||
struct PackedFunctionLevel {
|
||||
IrSensorFunctionLevel function_level;
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(PackedFunctionLevel) == 0x4, "PackedFunctionLevel is an invalid size");
|
||||
|
||||
// This is nn::irsensor::PackedImageTransferProcessorExConfig
|
||||
struct PackedImageTransferProcessorExConfig {
|
||||
u64 exposire_time;
|
||||
u8 light_target;
|
||||
u8 gain;
|
||||
u8 is_negative_used;
|
||||
INSERT_PADDING_BYTES(5);
|
||||
PackedMcuVersion required_mcu_version;
|
||||
ImageTransferProcessorFormat origin_format;
|
||||
ImageTransferProcessorFormat trimming_format;
|
||||
u16 trimming_start_x;
|
||||
u16 trimming_start_y;
|
||||
u8 is_external_light_filter_enabled;
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(PackedImageTransferProcessorExConfig) == 0x20,
|
||||
"PackedImageTransferProcessorExConfig is an invalid size");
|
||||
|
||||
// This is nn::irsensor::PackedIrLedProcessorConfig
|
||||
struct PackedIrLedProcessorConfig {
|
||||
PackedMcuVersion required_mcu_version;
|
||||
u8 light_target;
|
||||
INSERT_PADDING_BYTES(3);
|
||||
};
|
||||
static_assert(sizeof(PackedIrLedProcessorConfig) == 0x8,
|
||||
"PackedIrLedProcessorConfig is an invalid size");
|
||||
|
||||
void ActivateIrsensor(Kernel::HLERequestContext& ctx);
|
||||
void DeactivateIrsensor(Kernel::HLERequestContext& ctx);
|
||||
void GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx);
|
||||
@@ -35,8 +265,6 @@ private:
|
||||
void RunIrLedProcessor(Kernel::HLERequestContext& ctx);
|
||||
void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
|
||||
void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
|
||||
|
||||
const u32 device_handle{0xABCD};
|
||||
};
|
||||
|
||||
class IRS_SYS final : public ServiceFramework<IRS_SYS> {
|
||||
|
||||
@@ -11,10 +11,13 @@
|
||||
#include "common/alignment.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/div_ceil.h"
|
||||
#include "common/elf.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/service/jit/jit_context.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
using namespace Common::ELF;
|
||||
|
||||
namespace Service::JIT {
|
||||
|
||||
constexpr std::array<u8, 8> SVC0_ARM64 = {
|
||||
@@ -26,25 +29,6 @@ constexpr std::array HELPER_FUNCTIONS{
|
||||
"_stop", "_resolve", "_panic", "memcpy", "memmove", "memset",
|
||||
};
|
||||
|
||||
struct Elf64_Dyn {
|
||||
u64 d_tag;
|
||||
u64 d_un;
|
||||
};
|
||||
|
||||
struct Elf64_Rela {
|
||||
u64 r_offset;
|
||||
u64 r_info;
|
||||
s64 r_addend;
|
||||
};
|
||||
|
||||
static constexpr u32 Elf64_RelaType(const Elf64_Rela* rela) {
|
||||
return static_cast<u32>(rela->r_info);
|
||||
}
|
||||
|
||||
constexpr int DT_RELA = 7; /* Address of Rela relocs */
|
||||
constexpr int DT_RELASZ = 8; /* Total size of Rela relocs */
|
||||
constexpr int R_AARCH64_RELATIVE = 1027; /* Adjust by program base. */
|
||||
|
||||
constexpr size_t STACK_ALIGN = 16;
|
||||
|
||||
class JITContextImpl;
|
||||
@@ -206,17 +190,17 @@ public:
|
||||
if (!dyn.d_tag) {
|
||||
break;
|
||||
}
|
||||
if (dyn.d_tag == DT_RELA) {
|
||||
rela_dyn = dyn.d_un;
|
||||
if (dyn.d_tag == ElfDtRela) {
|
||||
rela_dyn = dyn.d_un.d_ptr;
|
||||
}
|
||||
if (dyn.d_tag == DT_RELASZ) {
|
||||
num_rela = dyn.d_un / sizeof(Elf64_Rela);
|
||||
if (dyn.d_tag == ElfDtRelasz) {
|
||||
num_rela = dyn.d_un.d_val / sizeof(Elf64_Rela);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_rela; i++) {
|
||||
const auto rela{callbacks->ReadMemory<Elf64_Rela>(rela_dyn + i * sizeof(Elf64_Rela))};
|
||||
if (Elf64_RelaType(&rela) != R_AARCH64_RELATIVE) {
|
||||
if (Elf64RelType(rela.r_info) != ElfAArch64Relative) {
|
||||
continue;
|
||||
}
|
||||
const VAddr contents{callbacks->MemoryRead64(rela.r_offset)};
|
||||
|
||||
@@ -89,14 +89,6 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer,
|
||||
|
||||
LOG_DEBUG(Service_NVFlinger, "acquiring slot={}", slot);
|
||||
|
||||
// If the front buffer is still being tracked, update its slot state
|
||||
if (core->StillTracking(*front)) {
|
||||
slots[slot].acquire_called = true;
|
||||
slots[slot].needs_cleanup_on_release = false;
|
||||
slots[slot].buffer_state = BufferState::Acquired;
|
||||
slots[slot].fence = Fence::NoFence();
|
||||
}
|
||||
|
||||
// If the buffer has previously been acquired by the consumer, set graphic_buffer to nullptr to
|
||||
// avoid unnecessarily remapping this buffer on the consumer side.
|
||||
if (out_buffer->acquire_called) {
|
||||
@@ -139,26 +131,11 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc
|
||||
++current;
|
||||
}
|
||||
|
||||
if (slots[slot].buffer_state == BufferState::Acquired) {
|
||||
slots[slot].fence = release_fence;
|
||||
slots[slot].buffer_state = BufferState::Free;
|
||||
slots[slot].buffer_state = BufferState::Free;
|
||||
|
||||
listener = core->connected_producer_listener;
|
||||
listener = core->connected_producer_listener;
|
||||
|
||||
LOG_DEBUG(Service_NVFlinger, "releasing slot {}", slot);
|
||||
} else if (slots[slot].needs_cleanup_on_release) {
|
||||
LOG_DEBUG(Service_NVFlinger, "releasing a stale buffer slot {} (state = {})", slot,
|
||||
slots[slot].buffer_state);
|
||||
|
||||
slots[slot].needs_cleanup_on_release = false;
|
||||
|
||||
return Status::StaleBufferSlot;
|
||||
} else {
|
||||
LOG_ERROR(Service_NVFlinger, "attempted to release buffer slot {} but its state was {}",
|
||||
slot, slots[slot].buffer_state);
|
||||
|
||||
return Status::BadValue;
|
||||
}
|
||||
LOG_DEBUG(Service_NVFlinger, "releasing slot {}", slot);
|
||||
|
||||
core->SignalDequeueCondition();
|
||||
}
|
||||
|
||||
@@ -84,10 +84,6 @@ void BufferQueueCore::FreeBufferLocked(s32 slot) {
|
||||
|
||||
slots[slot].graphic_buffer.reset();
|
||||
|
||||
if (slots[slot].buffer_state == BufferState::Acquired) {
|
||||
slots[slot].needs_cleanup_on_release = true;
|
||||
}
|
||||
|
||||
slots[slot].buffer_state = BufferState::Free;
|
||||
slots[slot].frame_number = UINT32_MAX;
|
||||
slots[slot].acquire_called = false;
|
||||
|
||||
@@ -31,7 +31,6 @@ struct BufferSlot final {
|
||||
u64 frame_number{};
|
||||
Fence fence;
|
||||
bool acquire_called{};
|
||||
bool needs_cleanup_on_release{};
|
||||
bool attached_by_consumer{};
|
||||
bool is_preallocated{};
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <memory>
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/elf.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/kernel/code_set.h"
|
||||
#include "core/hle/kernel/k_page_table.h"
|
||||
@@ -13,159 +14,7 @@
|
||||
#include "core/loader/elf.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ELF Header Constants
|
||||
|
||||
// File type
|
||||
enum ElfType {
|
||||
ET_NONE = 0,
|
||||
ET_REL = 1,
|
||||
ET_EXEC = 2,
|
||||
ET_DYN = 3,
|
||||
ET_CORE = 4,
|
||||
ET_LOPROC = 0xFF00,
|
||||
ET_HIPROC = 0xFFFF,
|
||||
};
|
||||
|
||||
// Machine/Architecture
|
||||
enum ElfMachine {
|
||||
EM_NONE = 0,
|
||||
EM_M32 = 1,
|
||||
EM_SPARC = 2,
|
||||
EM_386 = 3,
|
||||
EM_68K = 4,
|
||||
EM_88K = 5,
|
||||
EM_860 = 7,
|
||||
EM_MIPS = 8
|
||||
};
|
||||
|
||||
// File version
|
||||
#define EV_NONE 0
|
||||
#define EV_CURRENT 1
|
||||
|
||||
// Identification index
|
||||
#define EI_MAG0 0
|
||||
#define EI_MAG1 1
|
||||
#define EI_MAG2 2
|
||||
#define EI_MAG3 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EI_VERSION 6
|
||||
#define EI_PAD 7
|
||||
#define EI_NIDENT 16
|
||||
|
||||
// Sections constants
|
||||
|
||||
// Section types
|
||||
#define SHT_NULL 0
|
||||
#define SHT_PROGBITS 1
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_STRTAB 3
|
||||
#define SHT_RELA 4
|
||||
#define SHT_HASH 5
|
||||
#define SHT_DYNAMIC 6
|
||||
#define SHT_NOTE 7
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
#define SHT_SHLIB 10
|
||||
#define SHT_DYNSYM 11
|
||||
#define SHT_LOPROC 0x70000000
|
||||
#define SHT_HIPROC 0x7FFFFFFF
|
||||
#define SHT_LOUSER 0x80000000
|
||||
#define SHT_HIUSER 0xFFFFFFFF
|
||||
|
||||
// Section flags
|
||||
enum ElfSectionFlags {
|
||||
SHF_WRITE = 0x1,
|
||||
SHF_ALLOC = 0x2,
|
||||
SHF_EXECINSTR = 0x4,
|
||||
SHF_MASKPROC = 0xF0000000,
|
||||
};
|
||||
|
||||
// Segment types
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7FFFFFFF
|
||||
|
||||
// Segment flags
|
||||
#define PF_X 0x1
|
||||
#define PF_W 0x2
|
||||
#define PF_R 0x4
|
||||
#define PF_MASKPROC 0xF0000000
|
||||
|
||||
typedef unsigned int Elf32_Addr;
|
||||
typedef unsigned short Elf32_Half;
|
||||
typedef unsigned int Elf32_Off;
|
||||
typedef signed int Elf32_Sword;
|
||||
typedef unsigned int Elf32_Word;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ELF file header
|
||||
|
||||
struct Elf32_Ehdr {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
};
|
||||
|
||||
// Section header
|
||||
struct Elf32_Shdr {
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
};
|
||||
|
||||
// Segment header
|
||||
struct Elf32_Phdr {
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
};
|
||||
|
||||
// Symbol table entry
|
||||
struct Elf32_Sym {
|
||||
Elf32_Word st_name;
|
||||
Elf32_Addr st_value;
|
||||
Elf32_Word st_size;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf32_Half st_shndx;
|
||||
};
|
||||
|
||||
// Relocation entries
|
||||
struct Elf32_Rel {
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
};
|
||||
using namespace Common::ELF;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ElfReader class
|
||||
@@ -193,11 +42,11 @@ public:
|
||||
}
|
||||
|
||||
// Quick accessors
|
||||
ElfType GetType() const {
|
||||
return (ElfType)(header->e_type);
|
||||
u16 GetType() const {
|
||||
return header->e_type;
|
||||
}
|
||||
ElfMachine GetMachine() const {
|
||||
return (ElfMachine)(header->e_machine);
|
||||
u16 GetMachine() const {
|
||||
return header->e_machine;
|
||||
}
|
||||
VAddr GetEntryPoint() const {
|
||||
return entryPoint;
|
||||
@@ -220,13 +69,13 @@ public:
|
||||
const u8* GetSectionDataPtr(int section) const {
|
||||
if (section < 0 || section >= header->e_shnum)
|
||||
return nullptr;
|
||||
if (sections[section].sh_type != SHT_NOBITS)
|
||||
if (sections[section].sh_type != ElfShtNobits)
|
||||
return GetPtr(sections[section].sh_offset);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
bool IsCodeSection(int section) const {
|
||||
return sections[section].sh_type == SHT_PROGBITS;
|
||||
return sections[section].sh_type == ElfShtProgBits;
|
||||
}
|
||||
const u8* GetSegmentPtr(int segment) {
|
||||
return GetPtr(segments[segment].p_offset);
|
||||
@@ -256,7 +105,7 @@ ElfReader::ElfReader(void* ptr) {
|
||||
}
|
||||
|
||||
const char* ElfReader::GetSectionName(int section) const {
|
||||
if (sections[section].sh_type == SHT_NULL)
|
||||
if (sections[section].sh_type == ElfShtNull)
|
||||
return nullptr;
|
||||
|
||||
int name_offset = sections[section].sh_name;
|
||||
@@ -272,7 +121,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) {
|
||||
LOG_DEBUG(Loader, "String section: {}", header->e_shstrndx);
|
||||
|
||||
// Should we relocate?
|
||||
relocate = (header->e_type != ET_EXEC);
|
||||
relocate = (header->e_type != ElfTypeExec);
|
||||
|
||||
if (relocate) {
|
||||
LOG_DEBUG(Loader, "Relocatable module");
|
||||
@@ -288,7 +137,7 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) {
|
||||
u64 total_image_size = 0;
|
||||
for (unsigned int i = 0; i < header->e_phnum; ++i) {
|
||||
const Elf32_Phdr* p = &segments[i];
|
||||
if (p->p_type == PT_LOAD) {
|
||||
if (p->p_type == ElfPtLoad) {
|
||||
total_image_size += (p->p_memsz + 0xFFF) & ~0xFFF;
|
||||
}
|
||||
}
|
||||
@@ -303,14 +152,14 @@ Kernel::CodeSet ElfReader::LoadInto(VAddr vaddr) {
|
||||
LOG_DEBUG(Loader, "Type: {} Vaddr: {:08X} Filesz: {:08X} Memsz: {:08X} ", p->p_type,
|
||||
p->p_vaddr, p->p_filesz, p->p_memsz);
|
||||
|
||||
if (p->p_type == PT_LOAD) {
|
||||
if (p->p_type == ElfPtLoad) {
|
||||
Kernel::CodeSet::Segment* codeset_segment;
|
||||
u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X);
|
||||
if (permission_flags == (PF_R | PF_X)) {
|
||||
u32 permission_flags = p->p_flags & (ElfPfRead | ElfPfWrite | ElfPfExec);
|
||||
if (permission_flags == (ElfPfRead | ElfPfExec)) {
|
||||
codeset_segment = &codeset.CodeSegment();
|
||||
} else if (permission_flags == (PF_R)) {
|
||||
} else if (permission_flags == (ElfPfRead)) {
|
||||
codeset_segment = &codeset.RODataSegment();
|
||||
} else if (permission_flags == (PF_R | PF_W)) {
|
||||
} else if (permission_flags == (ElfPfRead | ElfPfWrite)) {
|
||||
codeset_segment = &codeset.DataSegment();
|
||||
} else {
|
||||
LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i,
|
||||
|
||||
@@ -595,8 +595,8 @@ void Maxwell3D::DrawArrays() {
|
||||
|
||||
std::optional<u64> Maxwell3D::GetQueryResult() {
|
||||
switch (regs.query.query_get.select) {
|
||||
case Regs::QuerySelect::Zero:
|
||||
return 0;
|
||||
case Regs::QuerySelect::Payload:
|
||||
return regs.query.query_sequence;
|
||||
case Regs::QuerySelect::SamplesPassed:
|
||||
// Deferred.
|
||||
rasterizer->Query(regs.query.QueryAddress(), QueryType::SamplesPassed,
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
};
|
||||
|
||||
enum class QuerySelect : u32 {
|
||||
Zero = 0,
|
||||
Payload = 0,
|
||||
TimeElapsed = 2,
|
||||
TransformFeedbackPrimitivesGenerated = 11,
|
||||
PrimitivesGenerated = 18,
|
||||
|
||||
@@ -187,7 +187,7 @@ if (ENABLE_QT_TRANSLATION)
|
||||
# Update source TS file if enabled
|
||||
if (GENERATE_QT_TRANSLATION)
|
||||
get_target_property(SRCS yuzu SOURCES)
|
||||
qt5_create_translation(QM_FILES
|
||||
qt_create_translation(QM_FILES
|
||||
${SRCS}
|
||||
${UIS}
|
||||
${YUZU_QT_LANGUAGES}/en.ts
|
||||
@@ -203,7 +203,7 @@ if (ENABLE_QT_TRANSLATION)
|
||||
list(REMOVE_ITEM LANGUAGES_TS ${YUZU_QT_LANGUAGES}/en.ts)
|
||||
|
||||
# Compile TS files to QM files
|
||||
qt5_add_translation(LANGUAGES_QM ${LANGUAGES_TS})
|
||||
qt_add_translation(LANGUAGES_QM ${LANGUAGES_TS})
|
||||
|
||||
# Build a QRC file from the QM file list
|
||||
set(LANGUAGES_QRC ${CMAKE_CURRENT_BINARY_DIR}/languages.qrc)
|
||||
@@ -215,7 +215,7 @@ if (ENABLE_QT_TRANSLATION)
|
||||
file(APPEND ${LANGUAGES_QRC} "</qresource></RCC>")
|
||||
|
||||
# Add the QRC file to package in all QM files
|
||||
qt5_add_resources(LANGUAGES ${LANGUAGES_QRC})
|
||||
qt_add_resources(LANGUAGES ${LANGUAGES_QRC})
|
||||
else()
|
||||
set(LANGUAGES)
|
||||
endif()
|
||||
@@ -236,8 +236,13 @@ if (APPLE)
|
||||
set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
|
||||
elseif(WIN32)
|
||||
# compile as a win32 gui application instead of a console application
|
||||
target_link_libraries(yuzu PRIVATE Qt5::WinMain)
|
||||
if (QT_VERSION VERSION_GREATER 6)
|
||||
target_link_libraries(yuzu PRIVATE Qt6::EntryPointPrivate)
|
||||
else()
|
||||
target_link_libraries(yuzu PRIVATE Qt5::WinMain)
|
||||
endif()
|
||||
if(MSVC)
|
||||
target_link_libraries(yuzu PRIVATE version.lib)
|
||||
set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
||||
elseif(MINGW)
|
||||
set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "-Wl,--subsystem,windows")
|
||||
@@ -247,7 +252,7 @@ endif()
|
||||
create_target_directory_groups(yuzu)
|
||||
|
||||
target_link_libraries(yuzu PRIVATE common core input_common video_core)
|
||||
target_link_libraries(yuzu PRIVATE Boost::boost glad Qt5::Widgets)
|
||||
target_link_libraries(yuzu PRIVATE Boost::boost glad Qt::Widgets)
|
||||
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
|
||||
|
||||
target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include)
|
||||
@@ -255,7 +260,7 @@ if (NOT WIN32)
|
||||
target_include_directories(yuzu PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS})
|
||||
endif()
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
target_link_libraries(yuzu PRIVATE Qt5::DBus)
|
||||
target_link_libraries(yuzu PRIVATE Qt::DBus)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(yuzu PRIVATE
|
||||
@@ -291,7 +296,7 @@ if (USE_DISCORD_PRESENCE)
|
||||
endif()
|
||||
|
||||
if (YUZU_USE_QT_WEB_ENGINE)
|
||||
target_link_libraries(yuzu PRIVATE Qt5::WebEngineCore Qt5::WebEngineWidgets)
|
||||
target_link_libraries(yuzu PRIVATE Qt::WebEngineCore Qt::WebEngineWidgets)
|
||||
target_compile_definitions(yuzu PRIVATE -DYUZU_USE_QT_WEB_ENGINE)
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -752,7 +752,7 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
|
||||
input_subsystem->GetMouse()->MouseMove(x, y, touch_x, touch_y, center_x, center_y);
|
||||
|
||||
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
|
||||
QCursor::setPos(mapToGlobal({center_x, center_y}));
|
||||
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
|
||||
}
|
||||
|
||||
emit MouseActivity();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <mutex>
|
||||
|
||||
#include <QImage>
|
||||
#include <QStringList>
|
||||
#include <QThread>
|
||||
#include <QTouchEvent>
|
||||
#include <QWidget>
|
||||
@@ -20,7 +21,6 @@
|
||||
class GRenderWindow;
|
||||
class GMainWindow;
|
||||
class QKeyEvent;
|
||||
class QStringList;
|
||||
|
||||
namespace Core {
|
||||
enum class SystemResultStatus : u32;
|
||||
|
||||
@@ -71,28 +71,28 @@ const std::array<int, 2> Config::default_ringcon_analogs{{
|
||||
// UISetting::values.shortcuts, which is alphabetically ordered.
|
||||
// clang-format off
|
||||
const std::array<UISettings::Shortcut, 22> Config::default_hotkeys{{
|
||||
{QStringLiteral("Audio Mute/Unmute"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Audio Volume Down"), QStringLiteral("Main Window"), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Audio Volume Up"), QStringLiteral("Main Window"), {QStringLiteral("+"), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral("Change Adapting Filter"), QStringLiteral("Main Window"), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Change GPU Accuracy"), QStringLiteral("Main Window"), {QStringLiteral("F9"), QStringLiteral("Home+R"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), QStringLiteral("Home+Plus"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Exit yuzu"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), QStringLiteral("Home+Minus"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral("Load/Remove Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral("TAS Record"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("TAS Reset"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("TAS Start/Stop"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle Framerate Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+U"), QStringLiteral("Home+Y"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F9"), QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("+"), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change GPU Accuracy")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F9"), QStringLiteral("Home+R"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Continue/Pause Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F4"), QStringLiteral("Home+Plus"), Qt::WindowShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Esc"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit yuzu")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+Q"), QStringLiteral("Home+Minus"), Qt::WindowShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F6"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F5"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Filter Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Framerate Limit")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+U"), QStringLiteral("Home+Y"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Mouse Panning")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F9"), QStringLiteral(""), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Status Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+S"), QStringLiteral(""), Qt::WindowShortcut}},
|
||||
}};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -61,14 +61,18 @@ ConfigureHotkeys::~ConfigureHotkeys() = default;
|
||||
|
||||
void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) {
|
||||
for (const auto& group : registry.hotkey_groups) {
|
||||
auto* parent_item = new QStandardItem(group.first);
|
||||
auto* parent_item =
|
||||
new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(group.first)));
|
||||
parent_item->setEditable(false);
|
||||
parent_item->setData(group.first);
|
||||
for (const auto& hotkey : group.second) {
|
||||
auto* action = new QStandardItem(hotkey.first);
|
||||
auto* action =
|
||||
new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(hotkey.first)));
|
||||
auto* keyseq =
|
||||
new QStandardItem(hotkey.second.keyseq.toString(QKeySequence::NativeText));
|
||||
auto* controller_keyseq = new QStandardItem(hotkey.second.controller_keyseq);
|
||||
action->setEditable(false);
|
||||
action->setData(hotkey.first);
|
||||
keyseq->setEditable(false);
|
||||
controller_keyseq->setEditable(false);
|
||||
parent_item->appendRow({action, keyseq, controller_keyseq});
|
||||
@@ -93,6 +97,16 @@ void ConfigureHotkeys::RetranslateUI() {
|
||||
ui->retranslateUi(this);
|
||||
|
||||
model->setHorizontalHeaderLabels({tr("Action"), tr("Hotkey"), tr("Controller Hotkey")});
|
||||
for (int key_id = 0; key_id < model->rowCount(); key_id++) {
|
||||
QStandardItem* parent = model->item(key_id, 0);
|
||||
parent->setText(
|
||||
QCoreApplication::translate("Hotkeys", qPrintable(parent->data().toString())));
|
||||
for (int key_column_id = 0; key_column_id < parent->rowCount(); key_column_id++) {
|
||||
QStandardItem* action = parent->child(key_column_id, name_column);
|
||||
action->setText(
|
||||
QCoreApplication::translate("Hotkeys", qPrintable(action->data().toString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigureHotkeys::Configure(QModelIndex index) {
|
||||
@@ -273,10 +287,10 @@ void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) {
|
||||
const QStandardItem* controller_keyseq =
|
||||
parent->child(key_column_id, controller_column);
|
||||
for (auto& [group, sub_actions] : registry.hotkey_groups) {
|
||||
if (group != parent->text())
|
||||
if (group != parent->data())
|
||||
continue;
|
||||
for (auto& [action_name, hotkey] : sub_actions) {
|
||||
if (action_name != action->text())
|
||||
if (action_name != action->data())
|
||||
continue;
|
||||
hotkey.keyseq = QKeySequence(keyseq->text());
|
||||
hotkey.controller_keyseq = controller_keyseq->text();
|
||||
|
||||
@@ -151,6 +151,8 @@ void ConfigureMotionTouch::ConnectEvents() {
|
||||
&ConfigureMotionTouch::OnConfigureTouchCalibration);
|
||||
connect(ui->touch_from_button_config_btn, &QPushButton::clicked, this,
|
||||
&ConfigureMotionTouch::OnConfigureTouchFromButton);
|
||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
|
||||
&ConfigureMotionTouch::ApplyConfiguration);
|
||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, [this] {
|
||||
if (CanCloseDialog()) {
|
||||
reject();
|
||||
|
||||
@@ -293,22 +293,5 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ConfigureMotionTouch</receiver>
|
||||
<slot>ApplyConfiguration()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>20</x>
|
||||
<y>20</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -130,8 +130,7 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||
// Guard if during game and set to game-specific value
|
||||
if (Settings::values.rng_seed.UsingGlobal()) {
|
||||
if (ui->rng_seed_checkbox->isChecked()) {
|
||||
Settings::values.rng_seed.SetValue(
|
||||
ui->rng_seed_edit->text().toULongLong(nullptr, 16));
|
||||
Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16));
|
||||
} else {
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
}
|
||||
@@ -142,8 +141,7 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||
case ConfigurationShared::CheckState::Off:
|
||||
Settings::values.rng_seed.SetGlobal(false);
|
||||
if (ui->rng_seed_checkbox->isChecked()) {
|
||||
Settings::values.rng_seed.SetValue(
|
||||
ui->rng_seed_edit->text().toULongLong(nullptr, 16));
|
||||
Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16));
|
||||
} else {
|
||||
Settings::values.rng_seed.SetValue(std::nullopt);
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ void GameList::DonePopulating(const QStringList& watch_list) {
|
||||
// Also artificially caps the watcher to a certain number of directories
|
||||
constexpr int LIMIT_WATCH_DIRECTORIES = 5000;
|
||||
constexpr int SLICE_SIZE = 25;
|
||||
int len = std::min(watch_list.length(), LIMIT_WATCH_DIRECTORIES);
|
||||
int len = std::min(static_cast<int>(watch_list.size()), LIMIT_WATCH_DIRECTORIES);
|
||||
for (int i = 0; i < len; i += SLICE_SIZE) {
|
||||
watcher->addPaths(watch_list.mid(i, i + SLICE_SIZE));
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
@@ -183,7 +183,7 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size
|
||||
|
||||
void LoadingScreen::paintEvent(QPaintEvent* event) {
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
opt.initFrom(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
QWidget::paintEvent(event);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <memory>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QtGlobal>
|
||||
|
||||
#if !QT_CONFIG(movie)
|
||||
#define YUZU_QT_MOVIE_MISSING 1
|
||||
@@ -88,4 +89,6 @@ private:
|
||||
std::size_t slow_shader_first_value = 0;
|
||||
};
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
Q_DECLARE_METATYPE(VideoCore::LoadCallbackStage);
|
||||
#endif
|
||||
|
||||
@@ -198,6 +198,59 @@ static void RemoveCachedContents() {
|
||||
Common::FS::RemoveDirRecursively(offline_system_data);
|
||||
}
|
||||
|
||||
static void LogRuntimes() {
|
||||
#ifdef _MSC_VER
|
||||
// It is possible that the name of the dll will change.
|
||||
// vcruntime140.dll is for 2015 and onwards
|
||||
constexpr char runtime_dll_name[] = "vcruntime140.dll";
|
||||
UINT sz = GetFileVersionInfoSizeA(runtime_dll_name, nullptr);
|
||||
bool runtime_version_inspection_worked = false;
|
||||
if (sz > 0) {
|
||||
std::vector<u8> buf(sz);
|
||||
if (GetFileVersionInfoA(runtime_dll_name, 0, sz, buf.data())) {
|
||||
VS_FIXEDFILEINFO* pvi;
|
||||
sz = sizeof(VS_FIXEDFILEINFO);
|
||||
if (VerQueryValueA(buf.data(), "\\", reinterpret_cast<LPVOID*>(&pvi), &sz)) {
|
||||
if (pvi->dwSignature == VS_FFI_SIGNATURE) {
|
||||
runtime_version_inspection_worked = true;
|
||||
LOG_INFO(Frontend, "MSVC Compiler: {} Runtime: {}.{}.{}.{}", _MSC_VER,
|
||||
pvi->dwProductVersionMS >> 16, pvi->dwProductVersionMS & 0xFFFF,
|
||||
pvi->dwProductVersionLS >> 16, pvi->dwProductVersionLS & 0xFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!runtime_version_inspection_worked) {
|
||||
LOG_INFO(Frontend, "Unable to inspect {}", runtime_dll_name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static QString PrettyProductName() {
|
||||
#ifdef _WIN32
|
||||
// After Windows 10 Version 2004, Microsoft decided to switch to a different notation: 20H2
|
||||
// With that notation change they changed the registry key used to denote the current version
|
||||
QSettings windows_registry(
|
||||
QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"),
|
||||
QSettings::NativeFormat);
|
||||
const QString release_id = windows_registry.value(QStringLiteral("ReleaseId")).toString();
|
||||
if (release_id == QStringLiteral("2009")) {
|
||||
const u32 current_build = windows_registry.value(QStringLiteral("CurrentBuild")).toUInt();
|
||||
const QString display_version =
|
||||
windows_registry.value(QStringLiteral("DisplayVersion")).toString();
|
||||
const u32 ubr = windows_registry.value(QStringLiteral("UBR")).toUInt();
|
||||
u32 version = 10;
|
||||
if (current_build >= 22000) {
|
||||
version = 11;
|
||||
}
|
||||
return QStringLiteral("Windows %1 Version %2 (Build %3.%4)")
|
||||
.arg(QString::number(version), display_version, QString::number(current_build),
|
||||
QString::number(ubr));
|
||||
}
|
||||
#endif
|
||||
return QSysInfo::prettyProductName();
|
||||
}
|
||||
|
||||
GMainWindow::GMainWindow()
|
||||
: ui{std::make_unique<Ui::MainWindow>()}, system{std::make_unique<Core::System>()},
|
||||
input_subsystem{std::make_shared<InputCommon::InputSubsystem>()},
|
||||
@@ -243,6 +296,7 @@ GMainWindow::GMainWindow()
|
||||
const auto yuzu_build_version = override_build.empty() ? yuzu_build : override_build;
|
||||
|
||||
LOG_INFO(Frontend, "yuzu Version: {}", yuzu_build_version);
|
||||
LogRuntimes();
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
const auto& caps = Common::GetCPUCaps();
|
||||
std::string cpu_string = caps.cpu_string;
|
||||
@@ -259,7 +313,7 @@ GMainWindow::GMainWindow()
|
||||
}
|
||||
LOG_INFO(Frontend, "Host CPU: {}", cpu_string);
|
||||
#endif
|
||||
LOG_INFO(Frontend, "Host OS: {}", QSysInfo::prettyProductName().toStdString());
|
||||
LOG_INFO(Frontend, "Host OS: {}", PrettyProductName().toStdString());
|
||||
LOG_INFO(Frontend, "Host RAM: {:.2f} GiB",
|
||||
Common::GetMemInfo().TotalPhysicalMemory / f64{1_GiB});
|
||||
LOG_INFO(Frontend, "Host Swap: {:.2f} GiB", Common::GetMemInfo().TotalSwapMemory / f64{1_GiB});
|
||||
@@ -827,12 +881,11 @@ void GMainWindow::InitializeWidgets() {
|
||||
|
||||
// Setup Dock button
|
||||
dock_status_button = new QPushButton();
|
||||
dock_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
|
||||
dock_status_button->setObjectName(QStringLiteral("DockingStatusBarButton"));
|
||||
dock_status_button->setFocusPolicy(Qt::NoFocus);
|
||||
connect(dock_status_button, &QPushButton::clicked, this, &GMainWindow::OnToggleDockedMode);
|
||||
dock_status_button->setText(tr("DOCK"));
|
||||
dock_status_button->setCheckable(true);
|
||||
dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
|
||||
UpdateDockedButton();
|
||||
statusBar()->insertPermanentWidget(0, dock_status_button);
|
||||
|
||||
gpu_accuracy_button = new QPushButton();
|
||||
@@ -1587,7 +1640,7 @@ void GMainWindow::StoreRecentFile(const QString& filename) {
|
||||
|
||||
void GMainWindow::UpdateRecentFiles() {
|
||||
const int num_recent_files =
|
||||
std::min(UISettings::values.recent_files.size(), max_recent_files_item);
|
||||
std::min(static_cast<int>(UISettings::values.recent_files.size()), max_recent_files_item);
|
||||
|
||||
for (int i = 0; i < num_recent_files; i++) {
|
||||
const QString text = QStringLiteral("&%1. %2").arg(i + 1).arg(
|
||||
@@ -2862,7 +2915,7 @@ void GMainWindow::OnToggleDockedMode() {
|
||||
}
|
||||
|
||||
Settings::values.use_docked_mode.SetValue(!is_docked);
|
||||
dock_status_button->setChecked(!is_docked);
|
||||
UpdateDockedButton();
|
||||
OnDockedModeChanged(is_docked, !is_docked, *system);
|
||||
}
|
||||
|
||||
@@ -3228,6 +3281,12 @@ void GMainWindow::UpdateGPUAccuracyButton() {
|
||||
}
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateDockedButton() {
|
||||
const bool is_docked = Settings::values.use_docked_mode.GetValue();
|
||||
dock_status_button->setChecked(is_docked);
|
||||
dock_status_button->setText(is_docked ? tr("DOCKED") : tr("HANDHELD"));
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateFilterText() {
|
||||
const auto filter = Settings::values.scaling_filter.GetValue();
|
||||
switch (filter) {
|
||||
@@ -3271,10 +3330,10 @@ void GMainWindow::UpdateAAText() {
|
||||
}
|
||||
|
||||
void GMainWindow::UpdateStatusButtons() {
|
||||
dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
|
||||
renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() ==
|
||||
Settings::RendererBackend::Vulkan);
|
||||
UpdateGPUAccuracyButton();
|
||||
UpdateDockedButton();
|
||||
UpdateFilterText();
|
||||
UpdateAAText();
|
||||
}
|
||||
@@ -3325,7 +3384,7 @@ void GMainWindow::CenterMouseCursor() {
|
||||
const int center_x = render_window->width() / 2;
|
||||
const int center_y = render_window->height() / 2;
|
||||
|
||||
QCursor::setPos(mapToGlobal({center_x, center_y}));
|
||||
QCursor::setPos(mapToGlobal(QPoint{center_x, center_y}));
|
||||
}
|
||||
|
||||
void GMainWindow::OnMouseActivity() {
|
||||
|
||||
@@ -320,6 +320,7 @@ private:
|
||||
void MigrateConfigFiles();
|
||||
void UpdateWindowTitle(std::string_view title_name = {}, std::string_view title_version = {},
|
||||
std::string_view gpu_vendor = {});
|
||||
void UpdateDockedButton();
|
||||
void UpdateFilterText();
|
||||
void UpdateAAText();
|
||||
void UpdateStatusBar();
|
||||
|
||||
Reference in New Issue
Block a user