Merge branch 'shadps4-emu:main' into main

This commit is contained in:
smiRaphi 2025-02-24 23:48:42 +01:00 committed by GitHub
commit 1a85afb83d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 69 additions and 38 deletions

View File

@ -954,12 +954,6 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
) )
endif() endif()
set(RESOURCEFOLDER Resources/bronze.png
Resources/gold.png
Resources/platinum.png
Resources/silver.png
)
if (ENABLE_QT_GUI) if (ENABLE_QT_GUI)
qt_add_executable(shadps4 qt_add_executable(shadps4
${AUDIO_CORE} ${AUDIO_CORE}
@ -971,7 +965,6 @@ if (ENABLE_QT_GUI)
${SHADER_RECOMPILER} ${SHADER_RECOMPILER}
${VIDEO_CORE} ${VIDEO_CORE}
${EMULATOR} ${EMULATOR}
${RESOURCEFOLDER}
src/images/shadPS4.icns src/images/shadPS4.icns
) )
else() else()
@ -984,7 +977,6 @@ else()
${SHADER_RECOMPILER} ${SHADER_RECOMPILER}
${VIDEO_CORE} ${VIDEO_CORE}
${EMULATOR} ${EMULATOR}
${RESOURCEFOLDER}
src/main.cpp src/main.cpp
src/emulator.cpp src/emulator.cpp
src/emulator.h src/emulator.h
@ -1117,7 +1109,10 @@ include(CMakeRC)
cmrc_add_resource_library(embedded-resources cmrc_add_resource_library(embedded-resources
ALIAS res::embedded ALIAS res::embedded
NAMESPACE res NAMESPACE res
${RESOURCEFOLDER}) src/images/bronze.png
src/images/gold.png
src/images/platinum.png
src/images/silver.png)
target_link_libraries(shadps4 PRIVATE res::embedded) target_link_libraries(shadps4 PRIVATE res::embedded)

View File

@ -19,11 +19,11 @@ path = [
"documents/Screenshots/*", "documents/Screenshots/*",
"documents/Screenshots/Linux/*", "documents/Screenshots/Linux/*",
"externals/MoltenVK/MoltenVK_icd.json", "externals/MoltenVK/MoltenVK_icd.json",
"Resources/bronze.png",
"Resources/gold.png",
"Resources/platinum.png",
"Resources/silver.png",
"scripts/ps4_names.txt", "scripts/ps4_names.txt",
"src/images/bronze.png",
"src/images/gold.png",
"src/images/platinum.png",
"src/images/silver.png",
"src/images/about_icon.png", "src/images/about_icon.png",
"src/images/controller_icon.png", "src/images/controller_icon.png",
"src/images/discord.png", "src/images/discord.png",

View File

@ -33,13 +33,13 @@ TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::strin
std::string pathString; std::string pathString;
if (trophy_type == "P") { if (trophy_type == "P") {
pathString = "Resources/platinum.png"; pathString = "src/images/platinum.png";
} else if (trophy_type == "G") { } else if (trophy_type == "G") {
pathString = "Resources/gold.png"; pathString = "src/images/gold.png";
} else if (trophy_type == "S") { } else if (trophy_type == "S") {
pathString = "Resources/silver.png"; pathString = "src/images/silver.png";
} else if (trophy_type == "B") { } else if (trophy_type == "B") {
pathString = "Resources/bronze.png"; pathString = "src/images/bronze.png";
} }
auto resource = cmrc::res::get_filesystem(); auto resource = cmrc::res::get_filesystem();

View File

@ -315,12 +315,13 @@ int PS4_SYSV_ABI scePadRead(s32 handle, OrbisPadData* pData, s32 num) {
pData[i].angularVelocity.x = states[i].angularVelocity.x; pData[i].angularVelocity.x = states[i].angularVelocity.x;
pData[i].angularVelocity.y = states[i].angularVelocity.y; pData[i].angularVelocity.y = states[i].angularVelocity.y;
pData[i].angularVelocity.z = states[i].angularVelocity.z; pData[i].angularVelocity.z = states[i].angularVelocity.z;
pData[i].orientation = {0.0f, 0.0f, 0.0f, 1.0f};
if (engine) { if (engine) {
const auto accel_poll_rate = engine->GetAccelPollRate(); const auto gyro_poll_rate = engine->GetAccelPollRate();
if (accel_poll_rate != 0.0f) { if (gyro_poll_rate != 0.0f) {
GameController::CalculateOrientation(pData[i].acceleration, GameController::CalculateOrientation(pData[i].acceleration,
pData[i].angularVelocity, pData[i].angularVelocity,
1.0f / accel_poll_rate, pData[i].orientation); 1.0f / gyro_poll_rate, pData[i].orientation);
} }
} }
pData[i].touchData.touchNum = pData[i].touchData.touchNum =
@ -384,11 +385,12 @@ int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) {
pData->angularVelocity.x = state.angularVelocity.x; pData->angularVelocity.x = state.angularVelocity.x;
pData->angularVelocity.y = state.angularVelocity.y; pData->angularVelocity.y = state.angularVelocity.y;
pData->angularVelocity.z = state.angularVelocity.z; pData->angularVelocity.z = state.angularVelocity.z;
pData->orientation = {0.0f, 0.0f, 0.0f, 1.0f};
if (engine) { if (engine) {
const auto accel_poll_rate = engine->GetAccelPollRate(); const auto gyro_poll_rate = engine->GetAccelPollRate();
if (accel_poll_rate != 0.0f) { if (gyro_poll_rate != 0.0f) {
GameController::CalculateOrientation(pData->acceleration, pData->angularVelocity, GameController::CalculateOrientation(pData->acceleration, pData->angularVelocity,
1.0f / accel_poll_rate, pData->orientation); 1.0f / gyro_poll_rate, pData->orientation);
} }
} }
pData->touchData.touchNum = pData->touchData.touchNum =

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -182,7 +182,7 @@ void GameController::CalculateOrientation(Libraries::Pad::OrbisFVector3& acceler
// Normalize accelerometer measurement // Normalize accelerometer measurement
float norm = std::sqrt(ax * ax + ay * ay + az * az); float norm = std::sqrt(ax * ax + ay * ay + az * az);
if (norm == 0.0f) if (norm == 0.0f || deltaTime == 0.0f)
return; // Handle NaN return; // Handle NaN
norm = 1.0f / norm; norm = 1.0f / norm;
ax *= norm; ax *= norm;

View File

@ -677,7 +677,8 @@ void SettingsDialog::UpdateSettings() {
const QVector<std::string> TouchPadIndex = {"left", "center", "right", "none"}; const QVector<std::string> TouchPadIndex = {"left", "center", "right", "none"};
Config::setBackButtonBehavior(TouchPadIndex[ui->backButtonBehaviorComboBox->currentIndex()]); Config::setBackButtonBehavior(TouchPadIndex[ui->backButtonBehaviorComboBox->currentIndex()]);
Config::setIsFullscreen(ui->displayModeComboBox->currentText().toStdString() != "Windowed"); Config::setIsFullscreen(screenModeMap.value(ui->displayModeComboBox->currentText()) !=
"Windowed");
Config::setFullscreenMode( Config::setFullscreenMode(
screenModeMap.value(ui->displayModeComboBox->currentText()).toStdString()); screenModeMap.value(ui->displayModeComboBox->currentText()).toStdString());
Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked()); Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked());

View File

@ -123,7 +123,7 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
QTableWidgetItem* typeitem = new QTableWidgetItem(); QTableWidgetItem* typeitem = new QTableWidgetItem();
auto resource = cmrc::res::get_filesystem(); auto resource = cmrc::res::get_filesystem();
std::string resourceString = "Resources/" + filename; std::string resourceString = "src/images/" + filename;
auto file = resource.open(resourceString); auto file = resource.open(resourceString);
std::vector<char> imgdata(file.begin(), file.end()); std::vector<char> imgdata(file.begin(), file.end());
QImage type_icon = QImage::fromData(imgdata).scaled(QSize(64, 64), Qt::KeepAspectRatio, QImage type_icon = QImage::fromData(imgdata).scaled(QSize(64, 64), Qt::KeepAspectRatio,

View File

@ -134,13 +134,17 @@ void SDLInputEngine::Init() {
m_gyro_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_GYRO); m_gyro_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_GYRO);
LOG_INFO(Input, "Gyro initialized, poll rate: {}", m_gyro_poll_rate); LOG_INFO(Input, "Gyro initialized, poll rate: {}", m_gyro_poll_rate);
} else { } else {
LOG_ERROR(Input, "Failed to initialize gyro controls for gamepad"); LOG_ERROR(Input, "Failed to initialize gyro controls for gamepad, error: {}",
SDL_GetError());
SDL_SetGamepadSensorEnabled(m_gamepad, SDL_SENSOR_GYRO, false);
} }
if (SDL_SetGamepadSensorEnabled(m_gamepad, SDL_SENSOR_ACCEL, true)) { if (SDL_SetGamepadSensorEnabled(m_gamepad, SDL_SENSOR_ACCEL, true)) {
m_accel_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_ACCEL); m_accel_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_ACCEL);
LOG_INFO(Input, "Accel initialized, poll rate: {}", m_accel_poll_rate); LOG_INFO(Input, "Accel initialized, poll rate: {}", m_accel_poll_rate);
} else { } else {
LOG_ERROR(Input, "Failed to initialize accel controls for gamepad"); LOG_ERROR(Input, "Failed to initialize accel controls for gamepad, error: {}",
SDL_GetError());
SDL_SetGamepadSensorEnabled(m_gamepad, SDL_SENSOR_ACCEL, false);
} }
} }

View File

@ -27,8 +27,8 @@ public:
private: private:
SDL_Gamepad* m_gamepad = nullptr; SDL_Gamepad* m_gamepad = nullptr;
float m_gyro_poll_rate{}; float m_gyro_poll_rate = 0.0f;
float m_accel_poll_rate{}; float m_accel_poll_rate = 0.0f;
}; };
} // namespace Input } // namespace Input

View File

@ -27,7 +27,7 @@ void Translator::EmitScalarAlu(const GcnInst& inst) {
case Opcode::S_ADD_I32: case Opcode::S_ADD_I32:
return S_ADD_I32(inst); return S_ADD_I32(inst);
case Opcode::S_SUB_I32: case Opcode::S_SUB_I32:
return S_SUB_U32(inst); return S_SUB_I32(inst);
case Opcode::S_ADDC_U32: case Opcode::S_ADDC_U32:
return S_ADDC_U32(inst); return S_ADDC_U32(inst);
case Opcode::S_MIN_I32: case Opcode::S_MIN_I32:
@ -216,24 +216,52 @@ void Translator::EmitSOPK(const GcnInst& inst) {
void Translator::S_ADD_U32(const GcnInst& inst) { void Translator::S_ADD_U32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{GetSrc(inst.src[1])};
SetDst(inst.dst[0], ir.IAdd(src0, src1)); const IR::U32 result{ir.IAdd(src0, src1)};
// TODO: Carry out SetDst(inst.dst[0], result);
ir.SetScc(ir.Imm1(false));
// SCC = tmp >= 0x100000000ULL ? 1'1U : 1'0U;
// The above assumes tmp is a 64-bit value.
// It should be enough however to test that the truncated result is less than at least one
// of the operands. In unsigned addition the result is always bigger than both the operands,
// except in the case of overflow where the truncated result is less than both.
ir.SetScc(ir.ILessThan(result, src0, false));
} }
void Translator::S_SUB_U32(const GcnInst& inst) { void Translator::S_SUB_U32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{GetSrc(inst.src[1])};
SetDst(inst.dst[0], ir.ISub(src0, src1)); SetDst(inst.dst[0], ir.ISub(src0, src1));
// TODO: Carry out
ir.SetScc(ir.Imm1(false)); // SCC = S1.u > S0.u ? 1'1U : 1'0U;
ir.SetScc(ir.IGreaterThan(src1, src0, false));
} }
void Translator::S_ADD_I32(const GcnInst& inst) { void Translator::S_ADD_I32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{GetSrc(inst.src[1])};
SetDst(inst.dst[0], ir.IAdd(src0, src1)); const IR::U32 result{ir.IAdd(src0, src1)};
// TODO: Overflow flag SetDst(inst.dst[0], result);
// SCC = ((S0.u[31] == S1.u[31]) && (S0.u[31] != Result.u[31]));
const IR::U32 shift{ir.Imm32(31)};
const IR::U32 sign0{ir.ShiftRightLogical(src0, shift)};
const IR::U32 sign1{ir.ShiftRightLogical(src1, shift)};
const IR::U32 signr{ir.ShiftRightLogical(result, shift)};
ir.SetScc(ir.LogicalAnd(ir.IEqual(sign0, sign1), ir.INotEqual(sign0, signr)));
}
void Translator::S_SUB_I32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])};
const IR::U32 result{ir.ISub(src0, src1)};
SetDst(inst.dst[0], result);
// SCC = ((S0.u[31] != S1.u[31]) && (S0.u[31] != tmp.u[31]));
const IR::U32 shift{ir.Imm32(31)};
const IR::U32 sign0{ir.ShiftRightLogical(src0, shift)};
const IR::U32 sign1{ir.ShiftRightLogical(src1, shift)};
const IR::U32 signr{ir.ShiftRightLogical(result, shift)};
ir.SetScc(ir.LogicalAnd(ir.INotEqual(sign0, sign1), ir.INotEqual(sign0, signr)));
} }
void Translator::S_ADDC_U32(const GcnInst& inst) { void Translator::S_ADDC_U32(const GcnInst& inst) {

View File

@ -81,6 +81,7 @@ public:
void S_ADD_U32(const GcnInst& inst); void S_ADD_U32(const GcnInst& inst);
void S_SUB_U32(const GcnInst& inst); void S_SUB_U32(const GcnInst& inst);
void S_ADD_I32(const GcnInst& inst); void S_ADD_I32(const GcnInst& inst);
void S_SUB_I32(const GcnInst& inst);
void S_ADDC_U32(const GcnInst& inst); void S_ADDC_U32(const GcnInst& inst);
void S_MIN_U32(bool is_signed, const GcnInst& inst); void S_MIN_U32(bool is_signed, const GcnInst& inst);
void S_MAX_U32(bool is_signed, const GcnInst& inst); void S_MAX_U32(bool is_signed, const GcnInst& inst);