Merge branch 'shadps4-emu:main' into main
@ -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)
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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();
|
||||
|
@ -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 =
|
||||
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
@ -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;
|
||||
|
@ -677,7 +677,8 @@ void SettingsDialog::UpdateSettings() {
|
||||
|
||||
const QVector<std::string> 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());
|
||||
|
@ -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<char> imgdata(file.begin(), file.end());
|
||||
QImage type_icon = QImage::fromData(imgdata).scaled(QSize(64, 64), Qt::KeepAspectRatio,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|