Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/features' into work
Browse files Browse the repository at this point in the history
  • Loading branch information
SysRay committed May 8, 2024
2 parents 10fa8fb + 4161cbb commit 89f3201
Show file tree
Hide file tree
Showing 38 changed files with 1,000 additions and 575 deletions.
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,5 @@ jobs:
name: psOff-emu
path: |
_build/_Install/*
!_build/_Install/debug/*
!_build/_Install/vulkan-1.dll
!_build/_Install/*_test.exe
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,11 @@ add_executable(psoff
main.cpp
)

add_dependencies(psoff logging core psOff_utility)
add_dependencies(psoff logging core psOff_utility gamereport)

target_link_libraries(psoff PRIVATE
core.lib
gamereport.lib
psOff_utility
libboost_filesystem
$<TARGET_OBJECTS:asmHelper>
Expand Down
6 changes: 4 additions & 2 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ add_subdirectory(initParams)
add_subdirectory(timer)
add_subdirectory(systemContent)
add_subdirectory(networking)
add_subdirectory(hotkeys)
add_subdirectory(trophies)
add_subdirectory(fileManager)
add_subdirectory(memory)
Expand All @@ -24,6 +25,7 @@ add_library(core SHARED
$<TARGET_OBJECTS:timer>
$<TARGET_OBJECTS:systemContent>
$<TARGET_OBJECTS:networking>
$<TARGET_OBJECTS:hotkeys>
$<TARGET_OBJECTS:trophies>
$<TARGET_OBJECTS:videoout>
$<TARGET_OBJECTS:fileManager>
Expand All @@ -33,7 +35,7 @@ add_library(core SHARED
$<TARGET_OBJECTS:runtime>
)

add_dependencies(core logging third_party config_emu gamereport psoff_render)
add_dependencies(core logging third_party config_emu psoff_render)
target_link_libraries(core PRIVATE
libboost_url
libboost_thread
Expand All @@ -42,12 +44,12 @@ target_link_libraries(core PRIVATE
libboost_filesystem
sdl2
psoff_render.lib
gamereport.lib
OptickCore
psOff_utility
config_emu.lib
onecore.lib
IPHLPAPI.lib
Dbghelp.lib
wepoll.lib
Ws2_32.lib
libcrypto.lib
Expand Down
7 changes: 7 additions & 0 deletions core/hotkeys/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
add_library(hotkeys OBJECT
hotkeys.cpp
)

add_dependencies(hotkeys third_party config_emu)

target_compile_definitions(hotkeys PUBLIC WIN32_LEAN_AND_MEAN)
149 changes: 149 additions & 0 deletions core/hotkeys/hotkeys.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#define __APICALL_EXTERN
#include "hotkeys.h"
#undef __APICALL_EXTERN

#include "config_emu.h"

#include <unordered_map>

class Hotkeys: public IHotkeys {
private:
struct HkBacks {
HkCommand cmd;
HkFunc func;
};

struct KBind {
SDL_Keycode kc;
uint16_t mod;
};

std::vector<HkBacks> m_cbacks = {};
std::array<KBind, (size_t)HkCommand::COMMANDS_MAX> m_binds = {{SDLK_UNKNOWN, 0}};
uint32_t m_state = 0;

HkCommand lookupCommand(SDL_Keycode kc, uint16_t mod) {
for (uint32_t c = uint32_t(HkCommand::UNKNOWN); c < uint32_t(HkCommand::COMMANDS_MAX); ++c) {
auto& bind = m_binds[(uint32_t)c];
if (kc == bind.kc && mod == bind.mod) return HkCommand(c);
}

return HkCommand::UNKNOWN;
}

public:
Hotkeys() {
static std::unordered_map<std::string, HkCommand> map = {
{"gamereport.send", HkCommand::GAMEREPORT_SEND_REPORT},
{"overlay.open", HkCommand::OVERLAY_MENU},

{"controller.l3", HkCommand::CONTROLLER_L3},
{"controller.r3", HkCommand::CONTROLLER_R3},
{"controller.options", HkCommand::CONTROLLER_OPTIONS},
{"controller.dpad_up", HkCommand::CONTROLLER_DPAD_UP},
{"controller.dpad_right", HkCommand::CONTROLLER_DPAD_RIGHT},
{"controller.dpad_down", HkCommand::CONTROLLER_DPAD_DOWN},
{"controller.dpad_left", HkCommand::CONTROLLER_DPAD_LEFT},
{"controller.l2", HkCommand::CONTROLLER_L2},
{"controller.r2", HkCommand::CONTROLLER_R2},
{"controller.l1", HkCommand::CONTROLLER_L1},
{"controller.r1", HkCommand::CONTROLLER_R1},
{"controller.triangle", HkCommand::CONTROLLER_TRIANGLE},
{"controller.circle", HkCommand::CONTROLLER_CIRCLE},
{"controller.cross", HkCommand::CONTROLLER_CROSS},
{"controller.square", HkCommand::CONTROLLER_SQUARE},
{"controller.touchpad", HkCommand::CONTROLLER_TOUCH_PAD},
{"controller.lx+", HkCommand::CONTROLLER_LX_UP},
{"controller.lx-", HkCommand::CONTROLLER_LX_DOWN},
{"controller.ly+", HkCommand::CONTROLLER_LY_UP},
{"controller.ly-", HkCommand::CONTROLLER_LY_DOWN},
{"controller.rx+", HkCommand::CONTROLLER_RX_UP},
{"controller.rx-", HkCommand::CONTROLLER_RX_DOWN},
{"controller.ry+", HkCommand::CONTROLLER_RY_UP},
{"controller.ry-", HkCommand::CONTROLLER_RY_DOWN},
};

auto readBind = [](std::string& str, KBind* kb) -> bool {
if (str.length() == 0) return false;
auto delim = str.find_last_of("||");
if (delim != std::string::npos) {
auto mod = str.substr(0, delim - 1);
auto key = str.substr(delim + 1);
kb->kc = SDL_GetScancodeFromName(key.c_str());

switch (SDL_GetScancodeFromName(mod.c_str())) {
case SDL_SCANCODE_LALT: kb->mod = KMOD_LALT; return true;
case SDL_SCANCODE_LCTRL: kb->mod = KMOD_LCTRL; return true;
case SDL_SCANCODE_LSHIFT: kb->mod = KMOD_LSHIFT; return true;

case SDL_SCANCODE_RALT: kb->mod = KMOD_RALT; return true;
case SDL_SCANCODE_RCTRL: kb->mod = KMOD_RCTRL; return true;
case SDL_SCANCODE_RSHIFT: kb->mod = KMOD_RSHIFT; return true;

default: return false;
}
}

if ((kb->kc = SDL_GetScancodeFromName(str.c_str())) != SDL_SCANCODE_UNKNOWN) {
kb->mod = 0x0000;
return true;
}

return false;
};

auto [lock, jData] = accessConfig()->accessModule(ConfigModFlag::CONTROLS);
for (auto& [bname, sdlkeys]: (*jData)["keybinds"].items()) {
auto it = map.find(bname.c_str());
if (it == map.end()) continue;
std::string temp;
sdlkeys.get_to(temp);

auto& bind = m_binds[(uint32_t)it->second];
if (!readBind(temp, &bind)) {
printf("Missing key binding for \"%s\"!\n", bname.c_str());
bind = {0, 0};
continue;
}

for (uint32_t c = uint32_t(HkCommand::UNKNOWN); c < uint32_t(HkCommand::COMMANDS_MAX); ++c) {
auto& tbind = m_binds[(uint32_t)c];
if (bind.kc == SDL_SCANCODE_UNKNOWN || tbind.kc == SDL_SCANCODE_UNKNOWN) continue;
if (tbind.kc == bind.kc && tbind.mod == bind.mod && (uint32_t)it->second != c) {
printf("Key conflict found! Please rebind your \"%s\" key.\n", bname.c_str());
bind = {0, 0};
continue;
}
}
}
}

void registerCallback(HkCommand cmd, HkFunc func) final { m_cbacks.emplace_back(cmd, func); }

bool isPressed(HkCommand cmd) final { return (m_state & (1ull << (uint8_t)cmd)) != 0; }

int32_t isPressedEx(HkCommand cmd1, HkCommand cmd2, int32_t ifcmd1, int32_t ifcmd2, int32_t def) final {
return isPressed(cmd1) ? ifcmd1 : (isPressed(cmd2) ? ifcmd2 : def);
}

void update(const SDL_KeyboardEvent* event) final {
bool pressed = event->type == SDL_KEYDOWN;
HkCommand cmd = lookupCommand(event->keysym.scancode, event->keysym.mod & 0x03C3);
if (cmd == HkCommand::UNKNOWN) return;
uint32_t bit = (1ull << (uint8_t)cmd);

if (pressed && ((m_state & bit) == 0)) {
for (auto& hkc: m_cbacks)
if (hkc.cmd == cmd) hkc.func(cmd);

m_state |= bit;
} else if (!pressed && ((m_state & bit) != 0)) {
m_state &= ~bit;
}
}
};

IHotkeys& accessHotkeys() {
static Hotkeys ih;
return ih;
}
72 changes: 72 additions & 0 deletions core/hotkeys/hotkeys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#pragma once

#include "utility/utility.h"

#include <SDL2/SDL.h>
#include <functional>

enum class HkCommand {
UNKNOWN = 0,

// System commands
GAMEREPORT_SEND_REPORT,
OVERLAY_MENU,

// Gamepad emulation
CONTROLLER_L3,
CONTROLLER_R3,
CONTROLLER_OPTIONS,
CONTROLLER_DPAD_UP,
CONTROLLER_DPAD_RIGHT,
CONTROLLER_DPAD_DOWN,
CONTROLLER_DPAD_LEFT,
CONTROLLER_L2,
CONTROLLER_R2,
CONTROLLER_L1,
CONTROLLER_R1,
CONTROLLER_TRIANGLE,
CONTROLLER_CIRCLE,
CONTROLLER_CROSS,
CONTROLLER_SQUARE,
CONTROLLER_TOUCH_PAD,
CONTROLLER_LX_UP,
CONTROLLER_LX_DOWN,
CONTROLLER_LY_UP,
CONTROLLER_LY_DOWN,
CONTROLLER_RX_UP,
CONTROLLER_RX_DOWN,
CONTROLLER_RY_UP,
CONTROLLER_RY_DOWN,

/**
* Warning! If this value ever exceeds 32 you should increase
* the size of `m_state` variable in `class Hotkeys` aswell!
*/
COMMANDS_MAX,
};

typedef std::function<void(HkCommand)> HkFunc;

class IHotkeys {
CLASS_NO_COPY(IHotkeys);
CLASS_NO_MOVE(IHotkeys);

public:
IHotkeys() = default;
virtual ~IHotkeys() = default;

virtual void registerCallback(HkCommand cmd, HkFunc func) = 0;
virtual bool isPressed(HkCommand cmd) = 0;
virtual int32_t isPressedEx(HkCommand cmd1, HkCommand cmd2, int32_t ifcmd1, int32_t ifcmd2, int32_t def) = 0;
virtual void update(const SDL_KeyboardEvent* event) = 0;
};

#if defined(__APICALL_EXTERN)
#define __APICALL __declspec(dllexport)
#elif defined(__APICALL_IMPORT)
#define __APICALL __declspec(dllimport)
#else
#define __APICALL
#endif
__APICALL IHotkeys& accessHotkeys();
#undef __APICALL
2 changes: 1 addition & 1 deletion core/kernel/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ int open(const char* path, SceOpen flags, SceKernelMode kernelMode) {
return getErr(ErrCode::_EINVAL);
}

if (std::string_view(path).starts_with("/dev")) {
if (std::string_view(path).starts_with("/dev/")) {
return open_dev(path, flags, kernelMode);
}

Expand Down
54 changes: 48 additions & 6 deletions core/runtime/util/exceptionHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
#include "core/memory/memory.h"
#include "core/runtime/util/virtualmemory.h"
#include "logging.h"
#include "utility/progloc.h"

#include <boost/stacktrace.hpp>
#include <magic_enum/magic_enum.hpp>
#include <mutex>

// clang-format off
#include <windows.h>
#include <psapi.h>
#include <DbgHelp.h>
// clang-format on

LOG_DEFINE_MODULE(ExceptionHandler);
Expand Down Expand Up @@ -74,12 +75,50 @@ std::optional<std::pair<uint64_t, std::string>> findModule(uint64_t address) {
return std::nullopt;
}

bool tryGetSymName(PSYMBOL_INFO sym, const void* addr, std::string& name) {
auto proc = GetCurrentProcess();

static std::once_flag init;
std::call_once(init, [proc]() {
LOG_USE_MODULE(ExceptionHandler);
auto dir = std::filesystem::path(util::getProgramLoc()) / "debug";
if (!SymInitializeW(proc, dir.c_str(), true)) {
LOG_ERR(L"Failed to initialize the debug information");
}
});

// Just to be sure that the previous call won't break anything
::memset(sym, 0, sizeof(SYMBOL_INFO));
sym->SizeOfStruct = sizeof(SYMBOL_INFO);
sym->MaxNameLen = 1024;

DWORD disp = 0;

IMAGEHLP_LINE64 line = {
.SizeOfStruct = sizeof(IMAGEHLP_LINE64),
};

if (SymFromAddr(proc, (uint64_t)addr, nullptr, sym)) {
name.assign(sym->Name);
if (SymGetLineFromAddr64(proc, sym->Address, &disp, &line)) {
name += std::format(" ({}:{}:{})", line.FileName, line.LineNumber, disp);
}

return true;
}

return false;
}

void stackTrace(uint64_t addr) {
LOG_USE_MODULE(ExceptionHandler);

bool foundStart = false;
size_t countTraces = 0;

std::vector<char> sym;
sym.resize(1024 + sizeof(SYMBOL_INFO));

// Stack trace
for (auto& trace: boost::stacktrace::basic_stacktrace()) {
if (!foundStart) {
Expand All @@ -96,8 +135,11 @@ void stackTrace(uint64_t addr) {
}

std::string fileName;
int lineNumber = 0;
DWORD displacement = 0;

if (!tryGetSymName((PSYMBOL_INFO)sym.data(), trace.address(), fileName)) {
// Failed to get the source file name, clearing the string
fileName.clear();
}

auto optModuleInfo = findModule((uint64_t)trace.address());

Expand All @@ -111,9 +153,9 @@ void stackTrace(uint64_t addr) {
}
} else {
if (optModuleInfo) {
LOG_ERR(L"0x%08llx\t %S at %llu base:0x%08llx %S", trace.address(), fileName.c_str(), lineNumber, optModuleInfo->first, optModuleInfo->second.c_str());
LOG_ERR(L"0x%08llx base:0x%08llx %S\n\t%S", trace.address(), optModuleInfo->first, optModuleInfo->second.c_str(), fileName.c_str());
} else {
LOG_ERR(L"0x%08llx\t %S at %llu", trace.address(), fileName.c_str(), lineNumber);
LOG_ERR(L"0x%08llx\n\t %S", trace.address(), fileName.c_str());
}
}
}
Expand Down Expand Up @@ -186,4 +228,4 @@ void install(uint64_t imageAddr, uint64_t handlerDstAddr, uint64_t imageSize) {

flushInstructionCache((uint64_t)&functionTable->handlerCode, sizeof(JmpHandlerData));
}
} // namespace ExceptionHandler
} // namespace ExceptionHandler
Loading

0 comments on commit 89f3201

Please sign in to comment.