Skip to content

Commit

Permalink
Merge branch 'main' into metal
Browse files Browse the repository at this point in the history
  • Loading branch information
SamoZ256 authored Dec 16, 2024
2 parents c6e8b5c + b53b223 commit e8c7e9d
Show file tree
Hide file tree
Showing 53 changed files with 999 additions and 392 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: "Install system dependencies"
run: |
sudo apt update -qq
sudo apt install -y clang-15 cmake freeglut3-dev libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev libudev-dev nasm ninja-build
sudo apt install -y clang-15 cmake freeglut3-dev libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev libudev-dev nasm ninja-build libbluetooth-dev
- name: "Setup cmake"
uses: jwlawson/actions-setup-cmake@v2
Expand Down Expand Up @@ -96,7 +96,7 @@ jobs:
- name: "Install system dependencies"
run: |
sudo apt update -qq
sudo apt install -y clang-15 cmake freeglut3-dev libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build appstream
sudo apt install -y clang-15 cmake freeglut3-dev libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build appstream libbluetooth-dev
- name: "Build AppImage"
run: |
Expand Down
6 changes: 3 additions & 3 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@ To compile Cemu, a recent enough compiler and STL with C++20 support is required
### Dependencies

#### For Arch and derivatives:
`sudo pacman -S --needed base-devel clang cmake freeglut git glm gtk3 libgcrypt libpulse libsecret linux-headers llvm nasm ninja systemd unzip zip`
`sudo pacman -S --needed base-devel bluez-libs clang cmake freeglut git glm gtk3 libgcrypt libpulse libsecret linux-headers llvm nasm ninja systemd unzip zip`

#### For Debian, Ubuntu and derivatives:
`sudo apt install -y cmake curl clang-15 freeglut3-dev git libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev libtool nasm ninja-build`
`sudo apt install -y cmake curl clang-15 freeglut3-dev git libbluetooth-dev libgcrypt20-dev libglm-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev libtool nasm ninja-build`

You may also need to install `libusb-1.0-0-dev` as a workaround for an issue with the vcpkg hidapi package.

At Step 3 in [Build Cemu using cmake and clang](#build-cemu-using-cmake-and-clang), use the following command instead:
`cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_C_COMPILER=/usr/bin/clang-15 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-15 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja`

#### For Fedora and derivatives:
`sudo dnf install clang cmake cubeb-devel freeglut-devel git glm-devel gtk3-devel kernel-headers libgcrypt-devel libsecret-devel libtool libusb1-devel llvm nasm ninja-build perl-core systemd-devel zlib-devel zlib-static`
`sudo dnf install bluez-libs clang cmake cubeb-devel freeglut-devel git glm-devel gtk3-devel kernel-headers libgcrypt-devel libsecret-devel libtool libusb1-devel llvm nasm ninja-build perl-core systemd-devel zlib-devel zlib-static`

### Build Cemu

Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ endif()
if (UNIX AND NOT APPLE)
option(ENABLE_WAYLAND "Build with Wayland support" ON)
option(ENABLE_FERAL_GAMEMODE "Enables Feral Interactive GameMode Support" ON)
option(ENABLE_BLUEZ "Build with Bluez support" ON)
endif()

if (APPLE)
Expand Down Expand Up @@ -189,6 +190,12 @@ if (UNIX AND NOT APPLE)
endif()
find_package(GTK3 REQUIRED)

if(ENABLE_BLUEZ)
find_package(bluez REQUIRED)
set(ENABLE_WIIMOTE ON)
add_compile_definitions(HAS_BLUEZ)
endif()

endif()

if (ENABLE_VULKAN)
Expand Down
Binary file added bin/resources/ar/‏‏cemu.mo
Binary file not shown.
Binary file modified bin/resources/de/cemu.mo
Binary file not shown.
Binary file modified bin/resources/ru/cemu.mo
Binary file not shown.
Binary file modified bin/resources/sv/cemu.mo
Binary file not shown.
20 changes: 20 additions & 0 deletions cmake/Findbluez.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: 2022 Andrea Pappacoda <[email protected]>
# SPDX-License-Identifier: ISC

find_package(bluez CONFIG)
if (NOT bluez_FOUND)
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
pkg_search_module(bluez IMPORTED_TARGET GLOBAL bluez-1.0 bluez)
if (bluez_FOUND)
add_library(bluez::bluez ALIAS PkgConfig::bluez)
endif ()
endif ()
endif ()

find_package_handle_standard_args(bluez
REQUIRED_VARS
bluez_LINK_LIBRARIES
bluez_FOUND
VERSION_VAR bluez_VERSION
)
4 changes: 2 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ if (MACOS_BUNDLE)
set(MACOSX_BUNDLE_ICON_FILE "cemu.icns")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "info.cemu.Cemu")
set(MACOSX_BUNDLE_BUNDLE_NAME "Cemu")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${CMAKE_PROJECT_VERSION})
set(MACOSX_BUNDLE_BUNDLE_VERSION ${CMAKE_PROJECT_VERSION})
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${EMULATOR_VERSION_MAJOR}.${EMULATOR_VERSION_MINOR}.${EMULATOR_VERSION_PATCH}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${EMULATOR_VERSION_MAJOR}.${EMULATOR_VERSION_MINOR}.${EMULATOR_VERSION_PATCH}")
set(MACOSX_BUNDLE_COPYRIGHT "Copyright © 2024 Cemu Project")

set(MACOSX_BUNDLE_CATEGORY "public.app-category.games")
Expand Down
8 changes: 7 additions & 1 deletion src/Cafe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,12 @@ set_property(TARGET CemuCafe PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CON

target_include_directories(CemuCafe PUBLIC "../")

if (glslang_VERSION VERSION_LESS "15.0.0")
set(glslang_target "glslang::SPIRV")
else()
set(glslang_target "glslang")
endif()

target_link_libraries(CemuCafe PRIVATE
CemuAsm
CemuAudio
Expand All @@ -609,7 +615,7 @@ target_link_libraries(CemuCafe PRIVATE
Boost::nowide
CURL::libcurl
fmt::fmt
glslang::SPIRV
${glslang_target}
ih264d
OpenSSL::Crypto
OpenSSL::SSL
Expand Down
44 changes: 26 additions & 18 deletions src/Cafe/GraphicPack/GraphicPack2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
const auto preset_name = rules.FindOption("name");
if (!preset_name)
{
cemuLog_log(LogType::Force, "Graphic pack \"{}\": Preset in line {} skipped because it has no name option defined", m_name, rules.GetCurrentSectionLineNumber());
cemuLog_log(LogType::Force, "Graphic pack \"{}\": Preset in line {} skipped because it has no name option defined", GetNormalizedPathString(), rules.GetCurrentSectionLineNumber());
continue;
}

Expand All @@ -371,7 +371,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
}
catch (const std::exception & ex)
{
cemuLog_log(LogType::Force, "Graphic pack \"{}\": Can't parse preset \"{}\": {}", m_name, *preset_name, ex.what());
cemuLog_log(LogType::Force, "Graphic pack \"{}\": Can't parse preset \"{}\": {}", GetNormalizedPathString(), *preset_name, ex.what());
}
}
else if (boost::iequals(currentSectionName, "RAM"))
Expand All @@ -385,7 +385,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
{
if (m_version <= 5)
{
cemuLog_log(LogType::Force, "Graphic pack \"{}\": [RAM] options are only available for graphic pack version 6 or higher", m_name, optionNameBuf);
cemuLog_log(LogType::Force, "Graphic pack \"{}\": [RAM] options are only available for graphic pack version 6 or higher", GetNormalizedPathString(), optionNameBuf);
throw std::exception();
}

Expand All @@ -395,12 +395,12 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
{
if (addrEnd <= addrStart)
{
cemuLog_log(LogType::Force, "Graphic pack \"{}\": start address (0x{:08x}) must be greater than end address (0x{:08x}) for {}", m_name, addrStart, addrEnd, optionNameBuf);
cemuLog_log(LogType::Force, "Graphic pack \"{}\": start address (0x{:08x}) must be greater than end address (0x{:08x}) for {}", GetNormalizedPathString(), addrStart, addrEnd, optionNameBuf);
throw std::exception();
}
else if ((addrStart & 0xFFF) != 0 || (addrEnd & 0xFFF) != 0)
{
cemuLog_log(LogType::Force, "Graphic pack \"{}\": addresses for %s are not aligned to 0x1000", m_name, optionNameBuf);
cemuLog_log(LogType::Force, "Graphic pack \"{}\": addresses for %s are not aligned to 0x1000", GetNormalizedPathString(), optionNameBuf);
throw std::exception();
}
else
Expand All @@ -410,7 +410,7 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
}
else
{
cemuLog_log(LogType::Force, "Graphic pack \"{}\": has invalid syntax for option {}", m_name, optionNameBuf);
cemuLog_log(LogType::Force, "Graphic pack \"{}\": has invalid syntax for option {}", GetNormalizedPathString(), optionNameBuf);
throw std::exception();
}
}
Expand All @@ -424,24 +424,32 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
std::unordered_map<std::string, std::vector<PresetPtr>> tmp_map;

// all vars must be defined in the default preset vars before
for (const auto& entry : m_presets)
std::vector<std::pair<std::string, std::string>> mismatchingPresetVars;
for (const auto& presetEntry : m_presets)
{
tmp_map[entry->category].emplace_back(entry);

for (auto& kv : entry->variables)
tmp_map[presetEntry->category].emplace_back(presetEntry);
for (auto& presetVar : presetEntry->variables)
{
const auto it = m_preset_vars.find(kv.first);
const auto it = m_preset_vars.find(presetVar.first);
if (it == m_preset_vars.cend())
{
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains preset variables which are not defined in the default section", m_name);
throw std::exception();
mismatchingPresetVars.emplace_back(presetEntry->name, presetVar.first);
continue;
}

// overwrite var type with default var type
kv.second.first = it->second.first;
presetVar.second.first = it->second.first;
}
}

if(!mismatchingPresetVars.empty())
{
cemuLog_log(LogType::Force, "Graphic pack \"{}\" contains preset variables which are not defined in the [Default] section:", GetNormalizedPathString());
for (const auto& [presetName, varName] : mismatchingPresetVars)
cemuLog_log(LogType::Force, "Preset: {} Variable: {}", presetName, varName);
throw std::exception();
}

// have first entry be default active for every category if no default= is set
for(auto entry : get_values(tmp_map))
{
Expand Down Expand Up @@ -471,22 +479,22 @@ GraphicPack2::GraphicPack2(fs::path rulesPath, IniParser& rules)
auto& p2 = kv.second[i + 1];
if (p1->variables.size() != p2->variables.size())
{
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains inconsistent preset variables", m_name);
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains inconsistent preset variables", GetNormalizedPathString());
throw std::exception();
}

std::set<std::string> keys1(get_keys(p1->variables).begin(), get_keys(p1->variables).end());
std::set<std::string> keys2(get_keys(p2->variables).begin(), get_keys(p2->variables).end());
if (keys1 != keys2)
{
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains inconsistent preset variables", m_name);
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" contains inconsistent preset variables", GetNormalizedPathString());
throw std::exception();
}

if(p1->is_default)
{
if(has_default)
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" has more than one preset with the default key set for the same category \"{}\"", m_name, p1->name);
cemuLog_log(LogType::Force, "Graphic pack: \"{}\" has more than one preset with the default key set for the same category \"{}\"", GetNormalizedPathString(), p1->name);
p1->active = true;
has_default = true;
}
Expand Down
28 changes: 28 additions & 0 deletions src/Cafe/HW/Espresso/Debugger/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,34 @@ bool debugger_hasPatch(uint32 address)
return false;
}

void debugger_removePatch(uint32 address)
{
for (sint32 i = 0; i < debuggerState.patches.size(); i++)
{
auto& patch = debuggerState.patches[i];
if (address < patch->address || address >= (patch->address + patch->length))
continue;
MPTR startAddress = patch->address;
MPTR endAddress = patch->address + patch->length;
// remove any breakpoints overlapping with the patch
for (auto& bp : debuggerState.breakpoints)
{
if (bp->address + 4 > startAddress && bp->address < endAddress)
{
bp->enabled = false;
debugger_updateExecutionBreakpoint(bp->address);
}
}
// restore original data
memcpy(MEMPTR<void>(startAddress).GetPtr(), patch->origData.data(), patch->length);
PPCRecompiler_invalidateRange(startAddress, endAddress);
// remove patch
delete patch;
debuggerState.patches.erase(debuggerState.patches.begin() + i);
return;
}
}

void debugger_stepInto(PPCInterpreter_t* hCPU, bool updateDebuggerWindow = true)
{
bool isRecEnabled = ppcRecompilerEnabled;
Expand Down
1 change: 1 addition & 0 deletions src/Cafe/HW/Espresso/Debugger/Debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ void debugger_updateExecutionBreakpoint(uint32 address, bool forceRestore = fals

void debugger_createPatch(uint32 address, std::span<uint8> patchData);
bool debugger_hasPatch(uint32 address);
void debugger_removePatch(uint32 address);

void debugger_forceBreak(); // force breakpoint at the next possible instruction
bool debugger_isTrapped();
Expand Down
1 change: 1 addition & 0 deletions src/Cafe/HW/Latte/Core/LattePerformanceMonitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ typedef struct
LattePerfStatCounter numGraphicPipelines;
LattePerfStatCounter numImages;
LattePerfStatCounter numImageViews;
LattePerfStatCounter numSamplers;
LattePerfStatCounter numRenderPass;
LattePerfStatCounter numFramebuffer;

Expand Down
2 changes: 2 additions & 0 deletions src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ bool LatteDecompiler_IsALUTransInstruction(bool isOP3, uint32 opcode)
opcode == ALU_OP2_INST_LSHR_INT ||
opcode == ALU_OP2_INST_MAX_INT ||
opcode == ALU_OP2_INST_MIN_INT ||
opcode == ALU_OP2_INST_MAX_UINT ||
opcode == ALU_OP2_INST_MIN_UINT ||
opcode == ALU_OP2_INST_MOVA_FLOOR ||
opcode == ALU_OP2_INST_MOVA_INT ||
opcode == ALU_OP2_INST_SETE_DX10 ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ bool _isIntegerInstruction(const LatteDecompilerALUInstruction& aluInstruction)
case ALU_OP2_INST_SUB_INT:
case ALU_OP2_INST_MAX_INT:
case ALU_OP2_INST_MIN_INT:
case ALU_OP2_INST_MAX_UINT:
case ALU_OP2_INST_MIN_UINT:
case ALU_OP2_INST_SETE_INT:
case ALU_OP2_INST_SETGT_INT:
case ALU_OP2_INST_SETGE_INT:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1415,19 +1415,23 @@ void _emitALUOP2InstructionCode(LatteDecompilerShaderContext* shaderContext, Lat
}
else if( aluInstruction->opcode == ALU_OP2_INST_ADD_INT )
_emitALUOperationBinary<LATTE_DECOMPILER_DTYPE_SIGNED_INT>(shaderContext, aluInstruction, " + ");
else if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT || aluInstruction->opcode == ALU_OP2_INST_MIN_INT )
else if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT || aluInstruction->opcode == ALU_OP2_INST_MIN_INT ||
aluInstruction->opcode == ALU_OP2_INST_MAX_UINT || aluInstruction->opcode == ALU_OP2_INST_MIN_UINT)
{
// not verified
bool isUnsigned = aluInstruction->opcode == ALU_OP2_INST_MAX_UINT || aluInstruction->opcode == ALU_OP2_INST_MIN_UINT;
auto opType = isUnsigned ? LATTE_DECOMPILER_DTYPE_UNSIGNED_INT : LATTE_DECOMPILER_DTYPE_SIGNED_INT;
_emitInstructionOutputVariableName(shaderContext, aluInstruction);
if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT )
src->add(" = max(");
src->add(" = ");
_emitTypeConversionPrefix(shaderContext, opType, outputType);
if( aluInstruction->opcode == ALU_OP2_INST_MAX_INT || aluInstruction->opcode == ALU_OP2_INST_MAX_UINT )
src->add("max(");
else
src->add(" = min(");
_emitTypeConversionPrefix(shaderContext, LATTE_DECOMPILER_DTYPE_SIGNED_INT, outputType);
_emitOperandInputCode(shaderContext, aluInstruction, 0, LATTE_DECOMPILER_DTYPE_SIGNED_INT);
src->add("min(");
_emitOperandInputCode(shaderContext, aluInstruction, 0, opType);
src->add(", ");
_emitOperandInputCode(shaderContext, aluInstruction, 1, LATTE_DECOMPILER_DTYPE_SIGNED_INT);
_emitTypeConversionSuffix(shaderContext, LATTE_DECOMPILER_DTYPE_SIGNED_INT, outputType);
_emitOperandInputCode(shaderContext, aluInstruction, 1, opType);
_emitTypeConversionSuffix(shaderContext, opType, outputType);
src->add(");" _CRLF);
}
else if( aluInstruction->opcode == ALU_OP2_INST_SUB_INT )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
#define ALU_OP2_INST_SUB_INT (0x035) // integer instruction
#define ALU_OP2_INST_MAX_INT (0x036) // integer instruction
#define ALU_OP2_INST_MIN_INT (0x037) // integer instruction
#define ALU_OP2_INST_MAX_UINT (0x038) // integer instruction
#define ALU_OP2_INST_MIN_UINT (0x039) // integer instruction
#define ALU_OP2_INST_SETE_INT (0x03A) // integer instruction
#define ALU_OP2_INST_SETGT_INT (0x03B) // integer instruction
#define ALU_OP2_INST_SETGE_INT (0x03C) // integer instruction
Expand Down
Loading

0 comments on commit e8c7e9d

Please sign in to comment.