diff --git a/CMakeLists.txt b/CMakeLists.txt index 820d46f9d..0437c0ebb 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -954,12 +954,6 @@ set(QT_GUI src/qt_gui/about_dialog.cpp ) endif() -set(RESOURCEFOLDER Resources/bronze.png - Resources/gold.png - Resources/platinum.png - Resources/silver.png -) - if (ENABLE_QT_GUI) qt_add_executable(shadps4 ${AUDIO_CORE} @@ -971,7 +965,6 @@ if (ENABLE_QT_GUI) ${SHADER_RECOMPILER} ${VIDEO_CORE} ${EMULATOR} - ${RESOURCEFOLDER} src/images/shadPS4.icns ) else() @@ -984,7 +977,6 @@ else() ${SHADER_RECOMPILER} ${VIDEO_CORE} ${EMULATOR} - ${RESOURCEFOLDER} src/main.cpp src/emulator.cpp src/emulator.h @@ -1117,7 +1109,10 @@ include(CMakeRC) cmrc_add_resource_library(embedded-resources ALIAS res::embedded 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) diff --git a/REUSE.toml b/REUSE.toml index 9c6ada42a..d8f31c2f2 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -19,11 +19,11 @@ path = [ "documents/Screenshots/*", "documents/Screenshots/Linux/*", "externals/MoltenVK/MoltenVK_icd.json", - "Resources/bronze.png", - "Resources/gold.png", - "Resources/platinum.png", - "Resources/silver.png", "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/controller_icon.png", "src/images/discord.png", diff --git a/src/core/libraries/np_trophy/trophy_ui.cpp b/src/core/libraries/np_trophy/trophy_ui.cpp index 2b909e5cf..efa02e9c4 100644 --- a/src/core/libraries/np_trophy/trophy_ui.cpp +++ b/src/core/libraries/np_trophy/trophy_ui.cpp @@ -33,13 +33,13 @@ TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::strin std::string pathString; if (trophy_type == "P") { - pathString = "Resources/platinum.png"; + pathString = "src/images/platinum.png"; } else if (trophy_type == "G") { - pathString = "Resources/gold.png"; + pathString = "src/images/gold.png"; } else if (trophy_type == "S") { - pathString = "Resources/silver.png"; + pathString = "src/images/silver.png"; } else if (trophy_type == "B") { - pathString = "Resources/bronze.png"; + pathString = "src/images/bronze.png"; } auto resource = cmrc::res::get_filesystem(); diff --git a/src/core/libraries/pad/pad.cpp b/src/core/libraries/pad/pad.cpp index bcc90c49b..2e5973144 100644 --- a/src/core/libraries/pad/pad.cpp +++ b/src/core/libraries/pad/pad.cpp @@ -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.y = states[i].angularVelocity.y; pData[i].angularVelocity.z = states[i].angularVelocity.z; + pData[i].orientation = {0.0f, 0.0f, 0.0f, 1.0f}; if (engine) { - const auto accel_poll_rate = engine->GetAccelPollRate(); - if (accel_poll_rate != 0.0f) { + const auto gyro_poll_rate = engine->GetAccelPollRate(); + if (gyro_poll_rate != 0.0f) { GameController::CalculateOrientation(pData[i].acceleration, pData[i].angularVelocity, - 1.0f / accel_poll_rate, pData[i].orientation); + 1.0f / gyro_poll_rate, pData[i].orientation); } } 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.y = state.angularVelocity.y; pData->angularVelocity.z = state.angularVelocity.z; + pData->orientation = {0.0f, 0.0f, 0.0f, 1.0f}; if (engine) { - const auto accel_poll_rate = engine->GetAccelPollRate(); - if (accel_poll_rate != 0.0f) { + const auto gyro_poll_rate = engine->GetAccelPollRate(); + if (gyro_poll_rate != 0.0f) { GameController::CalculateOrientation(pData->acceleration, pData->angularVelocity, - 1.0f / accel_poll_rate, pData->orientation); + 1.0f / gyro_poll_rate, pData->orientation); } } pData->touchData.touchNum = diff --git a/Resources/bronze.png b/src/images/bronze.png similarity index 100% rename from Resources/bronze.png rename to src/images/bronze.png diff --git a/Resources/gold.png b/src/images/gold.png similarity index 100% rename from Resources/gold.png rename to src/images/gold.png diff --git a/Resources/platinum.png b/src/images/platinum.png similarity index 100% rename from Resources/platinum.png rename to src/images/platinum.png diff --git a/Resources/silver.png b/src/images/silver.png similarity index 100% rename from Resources/silver.png rename to src/images/silver.png diff --git a/src/input/controller.cpp b/src/input/controller.cpp index ae54553f4..bb8db9a7c 100644 --- a/src/input/controller.cpp +++ b/src/input/controller.cpp @@ -182,7 +182,7 @@ void GameController::CalculateOrientation(Libraries::Pad::OrbisFVector3& acceler // Normalize accelerometer measurement float norm = std::sqrt(ax * ax + ay * ay + az * az); - if (norm == 0.0f) + if (norm == 0.0f || deltaTime == 0.0f) return; // Handle NaN norm = 1.0f / norm; ax *= norm; diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index ce6f59937..9a946658f 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -677,7 +677,8 @@ void SettingsDialog::UpdateSettings() { const QVector TouchPadIndex = {"left", "center", "right", "none"}; Config::setBackButtonBehavior(TouchPadIndex[ui->backButtonBehaviorComboBox->currentIndex()]); - Config::setIsFullscreen(ui->displayModeComboBox->currentText().toStdString() != "Windowed"); + Config::setIsFullscreen(screenModeMap.value(ui->displayModeComboBox->currentText()) != + "Windowed"); Config::setFullscreenMode( screenModeMap.value(ui->displayModeComboBox->currentText()).toStdString()); Config::setIsMotionControlsEnabled(ui->motionControlsCheckBox->isChecked()); diff --git a/src/qt_gui/trophy_viewer.cpp b/src/qt_gui/trophy_viewer.cpp index 9a0f33eed..63e9f04dd 100644 --- a/src/qt_gui/trophy_viewer.cpp +++ b/src/qt_gui/trophy_viewer.cpp @@ -123,7 +123,7 @@ void TrophyViewer::PopulateTrophyWidget(QString title) { QTableWidgetItem* typeitem = new QTableWidgetItem(); auto resource = cmrc::res::get_filesystem(); - std::string resourceString = "Resources/" + filename; + std::string resourceString = "src/images/" + filename; auto file = resource.open(resourceString); std::vector imgdata(file.begin(), file.end()); QImage type_icon = QImage::fromData(imgdata).scaled(QSize(64, 64), Qt::KeepAspectRatio, diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index 943746e3f..80d196147 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -134,13 +134,17 @@ void SDLInputEngine::Init() { m_gyro_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_GYRO); LOG_INFO(Input, "Gyro initialized, poll rate: {}", m_gyro_poll_rate); } 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)) { m_accel_poll_rate = SDL_GetGamepadSensorDataRate(m_gamepad, SDL_SENSOR_ACCEL); LOG_INFO(Input, "Accel initialized, poll rate: {}", m_accel_poll_rate); } 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); } } diff --git a/src/sdl_window.h b/src/sdl_window.h index 9acd2b16b..03ba0797b 100644 --- a/src/sdl_window.h +++ b/src/sdl_window.h @@ -27,8 +27,8 @@ public: private: SDL_Gamepad* m_gamepad = nullptr; - float m_gyro_poll_rate{}; - float m_accel_poll_rate{}; + float m_gyro_poll_rate = 0.0f; + float m_accel_poll_rate = 0.0f; }; } // namespace Input diff --git a/src/shader_recompiler/frontend/translate/scalar_alu.cpp b/src/shader_recompiler/frontend/translate/scalar_alu.cpp index b5c7c98ae..39f972848 100644 --- a/src/shader_recompiler/frontend/translate/scalar_alu.cpp +++ b/src/shader_recompiler/frontend/translate/scalar_alu.cpp @@ -27,7 +27,7 @@ void Translator::EmitScalarAlu(const GcnInst& inst) { case Opcode::S_ADD_I32: return S_ADD_I32(inst); case Opcode::S_SUB_I32: - return S_SUB_U32(inst); + return S_SUB_I32(inst); case Opcode::S_ADDC_U32: return S_ADDC_U32(inst); case Opcode::S_MIN_I32: @@ -216,24 +216,52 @@ void Translator::EmitSOPK(const GcnInst& inst) { void Translator::S_ADD_U32(const GcnInst& inst) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src1{GetSrc(inst.src[1])}; - SetDst(inst.dst[0], ir.IAdd(src0, src1)); - // TODO: Carry out - ir.SetScc(ir.Imm1(false)); + const IR::U32 result{ir.IAdd(src0, src1)}; + SetDst(inst.dst[0], result); + + // 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) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src1{GetSrc(inst.src[1])}; 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) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src1{GetSrc(inst.src[1])}; - SetDst(inst.dst[0], ir.IAdd(src0, src1)); - // TODO: Overflow flag + const IR::U32 result{ir.IAdd(src0, src1)}; + 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) { diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 190129e5f..2fd48a051 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -81,6 +81,7 @@ public: void S_ADD_U32(const GcnInst& inst); void S_SUB_U32(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_MIN_U32(bool is_signed, const GcnInst& inst); void S_MAX_U32(bool is_signed, const GcnInst& inst);