mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-20 03:24:49 +00:00
Merge branch 'main' into fontlib
This commit is contained in:
commit
3e2b111aea
21 changed files with 3265 additions and 866 deletions
21
.github/ISSUE_TEMPLATE/app-bug-report.yaml
vendored
21
.github/ISSUE_TEMPLATE/app-bug-report.yaml
vendored
|
@ -53,3 +53,24 @@ body:
|
|||
placeholder: "Example: Windows 11, Arch Linux, MacOS 15"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: cpu
|
||||
attributes:
|
||||
label: CPU
|
||||
placeholder: "Example: Intel Core i7-8700"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: gpu
|
||||
attributes:
|
||||
label: GPU
|
||||
placeholder: "Example: nVidia GTX 1650"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: ram
|
||||
attributes:
|
||||
label: Amount of RAM in GB
|
||||
placeholder: "Example: 16 GB"
|
||||
validations:
|
||||
required: true
|
||||
|
|
|
@ -450,8 +450,6 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
|||
src/core/libraries/audio3d/audio3d.cpp
|
||||
src/core/libraries/audio3d/audio3d.h
|
||||
src/core/libraries/audio3d/audio3d_error.h
|
||||
src/core/libraries/audio3d/audio3d_impl.cpp
|
||||
src/core/libraries/audio3d/audio3d_impl.h
|
||||
src/core/libraries/game_live_streaming/gamelivestreaming.cpp
|
||||
src/core/libraries/game_live_streaming/gamelivestreaming.h
|
||||
src/core/libraries/remote_play/remoteplay.cpp
|
||||
|
|
2
externals/libpng
vendored
2
externals/libpng
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 34005e3d3d373c0c36898cc55eae48a79c8238a1
|
||||
Subproject commit c1cc0f3f4c3d4abd11ca68c59446a29ff6f95003
|
|
@ -191,6 +191,7 @@ int PS4_SYSV_ABI sceAudioOutGetPortState(s32 handle, OrbisAudioOutPortState* sta
|
|||
case OrbisAudioOutPort::Main:
|
||||
case OrbisAudioOutPort::Bgm:
|
||||
case OrbisAudioOutPort::Voice:
|
||||
case OrbisAudioOutPort::Audio3d:
|
||||
state->output = 1;
|
||||
state->channel = port.format_info.num_channels > 2 ? 2 : port.format_info.num_channels;
|
||||
break;
|
||||
|
@ -316,7 +317,7 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
|||
return ORBIS_AUDIO_OUT_ERROR_NOT_INIT;
|
||||
}
|
||||
if ((port_type < OrbisAudioOutPort::Main || port_type > OrbisAudioOutPort::Padspk) &&
|
||||
(port_type != OrbisAudioOutPort::Aux)) {
|
||||
(port_type != OrbisAudioOutPort::Audio3d && port_type != OrbisAudioOutPort::Aux)) {
|
||||
LOG_ERROR(Lib_AudioOut, "Invalid port type");
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,15 @@ class PortBackend;
|
|||
constexpr s32 SCE_AUDIO_OUT_NUM_PORTS = 22;
|
||||
constexpr s32 SCE_AUDIO_OUT_VOLUME_0DB = 32768; // max volume value
|
||||
|
||||
enum class OrbisAudioOutPort { Main = 0, Bgm = 1, Voice = 2, Personal = 3, Padspk = 4, Aux = 127 };
|
||||
enum class OrbisAudioOutPort {
|
||||
Main = 0,
|
||||
Bgm = 1,
|
||||
Voice = 2,
|
||||
Personal = 3,
|
||||
Padspk = 4,
|
||||
Audio3d = 126,
|
||||
Aux = 127,
|
||||
};
|
||||
|
||||
enum class OrbisAudioOutParamFormat : u32 {
|
||||
S16Mono = 0,
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <SDL3/SDL_audio.h>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/audio/audioout.h"
|
||||
#include "core/libraries/audio/audioout_error.h"
|
||||
#include "core/libraries/audio3d/audio3d.h"
|
||||
#include "core/libraries/audio3d/audio3d_error.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
@ -10,331 +15,577 @@
|
|||
|
||||
namespace Libraries::Audio3d {
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dInitialize(s64 iReserved) {
|
||||
LOG_INFO(Lib_Audio3d, "iReserved = {}", iReserved);
|
||||
return ORBIS_OK;
|
||||
static constexpr u32 AUDIO3D_SAMPLE_RATE = 48000;
|
||||
|
||||
static constexpr AudioOut::OrbisAudioOutParamFormat AUDIO3D_OUTPUT_FORMAT =
|
||||
AudioOut::OrbisAudioOutParamFormat::S16Stereo;
|
||||
static constexpr u32 AUDIO3D_OUTPUT_NUM_CHANNELS = 2;
|
||||
static constexpr u32 AUDIO3D_OUTPUT_BUFFER_FRAMES = 0x100;
|
||||
|
||||
static std::unique_ptr<Audio3dState> state;
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(const s32 handle) {
|
||||
LOG_INFO(Lib_Audio3d, "called, handle = {}", handle);
|
||||
return AudioOut::sceAudioOutClose(handle);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dTerminate() {
|
||||
// TODO: When not initialized or some ports still open, return ORBIS_AUDIO3D_ERROR_NOT_READY
|
||||
LOG_INFO(Lib_Audio3d, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* parameters) {
|
||||
if (parameters == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "Invalid OpenParameters ptr");
|
||||
return;
|
||||
}
|
||||
|
||||
parameters->size_this = sizeof(OrbisAudio3dOpenParameters);
|
||||
parameters->granularity = 256;
|
||||
parameters->rate = OrbisAudio3dRate::Rate48000;
|
||||
parameters->max_objects = 512;
|
||||
parameters->queue_depth = 2;
|
||||
parameters->buffer_mode = OrbisAudio3dBufferMode::AdvanceAndPush;
|
||||
parameters->num_beds = 2;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortOpen(OrbisUserServiceUserId iUserId,
|
||||
const OrbisAudio3dOpenParameters* pParameters,
|
||||
OrbisAudio3dPortId* pId) {
|
||||
LOG_INFO(Lib_Audio3d, "iUserId = {}", iUserId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortClose(OrbisAudio3dPortId uiPortId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortSetAttribute(OrbisAudio3dPortId uiPortId,
|
||||
OrbisAudio3dAttributeId uiAttributeId,
|
||||
const void* pAttribute, size_t szAttribute) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiAttributeId = {}, szAttribute = {}", uiPortId,
|
||||
uiAttributeId, szAttribute);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortFlush(OrbisAudio3dPortId uiPortId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortAdvance(OrbisAudio3dPortId uiPortId) {
|
||||
LOG_TRACE(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortPush(OrbisAudio3dPortId uiPortId, OrbisAudio3dBlocking eBlocking) {
|
||||
LOG_TRACE(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported(OrbisAudio3dPortId uiPortId,
|
||||
OrbisAudio3dAttributeId* pCapabilities,
|
||||
u32* pNumCapabilities) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(OrbisAudio3dPortId uiPortId, u32* pQueueLevel,
|
||||
u32* pQueueAvailable) {
|
||||
LOG_TRACE(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dObjectReserve(OrbisAudio3dPortId uiPortId, OrbisAudio3dObjectId* pId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dObjectUnreserve(OrbisAudio3dPortId uiPortId,
|
||||
OrbisAudio3dObjectId uiObjectId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiObjectId = {}", uiPortId, uiObjectId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dObjectSetAttributes(OrbisAudio3dPortId uiPortId,
|
||||
OrbisAudio3dObjectId uiObjectId,
|
||||
size_t szNumAttributes,
|
||||
const OrbisAudio3dAttribute* pAttributeArray) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiObjectId = {}, szNumAttributes = {}", uiPortId,
|
||||
uiObjectId, szNumAttributes);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dBedWrite(OrbisAudio3dPortId uiPortId, u32 uiNumChannels,
|
||||
OrbisAudio3dFormat eFormat, const void* pBuffer,
|
||||
u32 uiNumSamples) {
|
||||
LOG_TRACE(Lib_Audio3d, "uiPortId = {}, uiNumChannels = {}, uiNumSamples = {}", uiPortId,
|
||||
uiNumChannels, uiNumSamples);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dBedWrite2(OrbisAudio3dPortId uiPortId, u32 uiNumChannels,
|
||||
OrbisAudio3dFormat eFormat, const void* pBuffer,
|
||||
u32 uiNumSamples, OrbisAudio3dOutputRoute eOutputRoute,
|
||||
bool bRestricted) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiNumChannels = {}, uiNumSamples = {}, bRestricted = {}",
|
||||
uiPortId, uiNumChannels, uiNumSamples, bRestricted);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
size_t PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize(u32 uiNumSpeakers, bool bIs3d) {
|
||||
LOG_INFO(Lib_Audio3d, "uiNumSpeakers = {}, bIs3d = {}", uiNumSpeakers, bIs3d);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI
|
||||
sceAudio3dCreateSpeakerArray(OrbisAudio3dSpeakerArrayHandle* pHandle,
|
||||
const OrbisAudio3dSpeakerArrayParameters* pParameters) {
|
||||
if (pHandle == nullptr || pParameters == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArray parameters");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
LOG_INFO(Lib_Audio3d, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray(OrbisAudio3dSpeakerArrayHandle handle) {
|
||||
if (handle == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
LOG_INFO(Lib_Audio3d, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients(OrbisAudio3dSpeakerArrayHandle handle,
|
||||
OrbisAudio3dPosition pos, float fSpread,
|
||||
float* pCoefficients,
|
||||
u32 uiNumCoefficients) {
|
||||
LOG_INFO(Lib_Audio3d, "fSpread = {}, uiNumCoefficients = {}", fSpread, uiNumCoefficients);
|
||||
if (handle == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2(OrbisAudio3dSpeakerArrayHandle handle,
|
||||
OrbisAudio3dPosition pos, float fSpread,
|
||||
float* pCoefficients,
|
||||
u32 uiNumCoefficients, bool bHeightAware,
|
||||
float fDownmixSpreadRadius) {
|
||||
s32 PS4_SYSV_ABI
|
||||
sceAudio3dAudioOutOpen(const OrbisAudio3dPortId port_id, const OrbisUserServiceUserId user_id,
|
||||
s32 type, const s32 index, const u32 len, const u32 freq,
|
||||
const AudioOut::OrbisAudioOutParamExtendedInformation param) {
|
||||
LOG_INFO(Lib_Audio3d,
|
||||
"fSpread = {}, uiNumCoefficients = {}, bHeightAware = {}, fDownmixSpreadRadius = {}",
|
||||
fSpread, uiNumCoefficients, bHeightAware, fDownmixSpreadRadius);
|
||||
if (handle == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle");
|
||||
"called, port_id = {}, user_id = {}, type = {}, index = {}, len = {}, freq = {}",
|
||||
port_id, user_id, type, index, len, freq);
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (len != state->ports[port_id].parameters.granularity) {
|
||||
LOG_ERROR(Lib_Audio3d, "len != state->ports[port_id].parameters.granularity");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return sceAudioOutOpen(user_id, static_cast<AudioOut::OrbisAudioOutPort>(type), index, len,
|
||||
freq, param);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(const s32 handle, void* ptr) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, handle = {}, ptr = {}", handle, ptr);
|
||||
|
||||
if (!ptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "!ptr");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (handle < 0 || (handle & 0xFFFF) > 25) {
|
||||
LOG_ERROR(Lib_Audio3d, "handle < 0 || (handle & 0xFFFF) > 25");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
return AudioOut::sceAudioOutOutput(handle, ptr);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(AudioOut::OrbisAudioOutOutputParam* param,
|
||||
const u32 num) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, param = {}, num = {}", static_cast<void*>(param), num);
|
||||
|
||||
if (!param || !num) {
|
||||
LOG_ERROR(Lib_Audio3d, "!param || !num");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return AudioOut::sceAudioOutOutputs(param, num);
|
||||
}
|
||||
|
||||
static s32 PortQueueAudio(Port& port, const OrbisAudio3dPcm& pcm, const u32 num_channels) {
|
||||
// Audio3d output is configured for stereo signed 16-bit PCM. Convert the data to match.
|
||||
const SDL_AudioSpec src_spec = {
|
||||
.format = pcm.format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_S16 ? SDL_AUDIO_S16LE
|
||||
: SDL_AUDIO_F32LE,
|
||||
.channels = static_cast<int>(num_channels),
|
||||
.freq = AUDIO3D_SAMPLE_RATE,
|
||||
};
|
||||
constexpr SDL_AudioSpec dst_spec = {
|
||||
.format = SDL_AUDIO_S16LE,
|
||||
.channels = AUDIO3D_OUTPUT_NUM_CHANNELS,
|
||||
.freq = AUDIO3D_SAMPLE_RATE,
|
||||
};
|
||||
const auto src_size = pcm.num_samples *
|
||||
(pcm.format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_S16 ? 2 : 4) *
|
||||
num_channels;
|
||||
|
||||
u8* dst_data;
|
||||
int dst_len;
|
||||
if (!SDL_ConvertAudioSamples(&src_spec, static_cast<u8*>(pcm.sample_buffer),
|
||||
static_cast<int>(src_size), &dst_spec, &dst_data, &dst_len)) {
|
||||
LOG_ERROR(Lib_Audio3d, "SDL_ConvertAudioSamples failed: {}", SDL_GetError());
|
||||
return ORBIS_AUDIO3D_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
port.queue.emplace_back(AudioData{
|
||||
.sample_buffer = dst_data,
|
||||
.num_samples = pcm.num_samples,
|
||||
});
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite(const OrbisAudio3dPortId port_id, const u32 num_channels,
|
||||
const OrbisAudio3dFormat format, void* buffer,
|
||||
const u32 num_samples) {
|
||||
return sceAudio3dBedWrite2(port_id, num_channels, format, buffer, num_samples,
|
||||
OrbisAudio3dOutputRoute::ORBIS_AUDIO3D_OUTPUT_BOTH, false);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite2(const OrbisAudio3dPortId port_id, const u32 num_channels,
|
||||
const OrbisAudio3dFormat format, void* buffer,
|
||||
const u32 num_samples,
|
||||
const OrbisAudio3dOutputRoute output_route,
|
||||
const bool restricted) {
|
||||
LOG_DEBUG(
|
||||
Lib_Audio3d,
|
||||
"called, port_id = {}, num_channels = {}, format = {}, num_samples = {}, output_route "
|
||||
"= {}, restricted = {}",
|
||||
port_id, num_channels, magic_enum::enum_name(format), num_samples,
|
||||
magic_enum::enum_name(output_route), restricted);
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (output_route > OrbisAudio3dOutputRoute::ORBIS_AUDIO3D_OUTPUT_BOTH) {
|
||||
LOG_ERROR(Lib_Audio3d, "output_route > ORBIS_AUDIO3D_OUTPUT_BOTH");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (format > OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_FLOAT) {
|
||||
LOG_ERROR(Lib_Audio3d, "format > ORBIS_AUDIO3D_FORMAT_FLOAT");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (num_channels != 2 && num_channels != 8) {
|
||||
LOG_ERROR(Lib_Audio3d, "num_channels != 2 && num_channels != 8");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!buffer || !num_samples) {
|
||||
LOG_ERROR(Lib_Audio3d, "!buffer || !num_samples");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_FLOAT) {
|
||||
if ((reinterpret_cast<uintptr_t>(buffer) & 3) != 0) {
|
||||
LOG_ERROR(Lib_Audio3d, "buffer & 3 != 0");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
} else if (format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_S16) {
|
||||
if ((reinterpret_cast<uintptr_t>(buffer) & 1) != 0) {
|
||||
LOG_ERROR(Lib_Audio3d, "buffer & 1 != 0");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
return PortQueueAudio(state->ports[port_id],
|
||||
OrbisAudio3dPcm{
|
||||
.format = format,
|
||||
.sample_buffer = buffer,
|
||||
.num_samples = num_samples,
|
||||
},
|
||||
num_channels);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dCreateSpeakerArray() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* params) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called");
|
||||
if (params) {
|
||||
*params = OrbisAudio3dOpenParameters{
|
||||
.size_this = 0x20,
|
||||
.granularity = 0x100,
|
||||
.rate = OrbisAudio3dRate::ORBIS_AUDIO3D_RATE_48000,
|
||||
.max_objects = 512,
|
||||
.queue_depth = 2,
|
||||
.buffer_mode = OrbisAudio3dBufferMode::ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH,
|
||||
};
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOpen(OrbisAudio3dPortId uiPortId, OrbisUserServiceUserId userId,
|
||||
s32 type, s32 index, u32 len, u32 freq, u32 param) {
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dInitialize(const s64 reserved) {
|
||||
LOG_INFO(Lib_Audio3d, "called, reserved = {}", reserved);
|
||||
|
||||
if (reserved != 0) {
|
||||
LOG_ERROR(Lib_Audio3d, "reserved != 0");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (state) {
|
||||
LOG_ERROR(Lib_Audio3d, "already initialized");
|
||||
return ORBIS_AUDIO3D_ERROR_NOT_READY;
|
||||
}
|
||||
|
||||
state = std::make_unique<Audio3dState>();
|
||||
|
||||
if (const auto init_ret = AudioOut::sceAudioOutInit();
|
||||
init_ret < 0 && init_ret != ORBIS_AUDIO_OUT_ERROR_ALREADY_INIT) {
|
||||
return init_ret;
|
||||
}
|
||||
|
||||
AudioOut::OrbisAudioOutParamExtendedInformation ext_info{};
|
||||
ext_info.data_format.Assign(AUDIO3D_OUTPUT_FORMAT);
|
||||
state->audio_out_handle =
|
||||
AudioOut::sceAudioOutOpen(0xFF, AudioOut::OrbisAudioOutPort::Audio3d, 0,
|
||||
AUDIO3D_OUTPUT_BUFFER_FRAMES, AUDIO3D_SAMPLE_RATE, ext_info);
|
||||
if (state->audio_out_handle < 0) {
|
||||
return state->audio_out_handle;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectReserve(const OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dObjectId* object_id) {
|
||||
LOG_INFO(Lib_Audio3d, "called, port_id = {}, object_id = {}", port_id,
|
||||
static_cast<void*>(object_id));
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (!object_id) {
|
||||
LOG_ERROR(Lib_Audio3d, "!object_id");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
static int last_id = 0;
|
||||
*object_id = ++last_id;
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectSetAttributes(const OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dObjectId object_id,
|
||||
const u64 num_attributes,
|
||||
const OrbisAudio3dAttribute* attribute_array) {
|
||||
LOG_DEBUG(Lib_Audio3d,
|
||||
"called, port_id = {}, object_id = {}, num_attributes = {}, attribute_array = {}",
|
||||
port_id, object_id, num_attributes, fmt::ptr(attribute_array));
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
auto& port = state->ports[port_id];
|
||||
|
||||
for (u64 i = 0; i < num_attributes; i++) {
|
||||
const auto& attribute = attribute_array[i];
|
||||
|
||||
switch (attribute.attribute_id) {
|
||||
case OrbisAudio3dAttributeId::ORBIS_AUDIO3D_ATTRIBUTE_PCM: {
|
||||
const auto pcm = static_cast<OrbisAudio3dPcm*>(attribute.value);
|
||||
// Object audio has 1 channel.
|
||||
if (const auto ret = PortQueueAudio(port, *pcm, 1); ret != ORBIS_OK) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR(Lib_Audio3d, "Unsupported attribute ID: {:#x}",
|
||||
static_cast<u32>(attribute.attribute_id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectUnreserve() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortAdvance(const OrbisAudio3dPortId port_id) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, port_id = {}", port_id);
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (state->ports[port_id].parameters.buffer_mode ==
|
||||
OrbisAudio3dBufferMode::ORBIS_AUDIO3D_BUFFER_NO_ADVANCE) {
|
||||
LOG_ERROR(Lib_Audio3d, "port doesn't have advance capability");
|
||||
return ORBIS_AUDIO3D_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
auto& port = state->ports[port_id];
|
||||
if (port.current_buffer.has_value()) {
|
||||
// Free existing buffer before replacing.
|
||||
SDL_free(port.current_buffer->sample_buffer);
|
||||
}
|
||||
|
||||
if (!port.queue.empty()) {
|
||||
port.current_buffer = port.queue.front();
|
||||
port.queue.pop_front();
|
||||
} else {
|
||||
// Nothing to advance to.
|
||||
LOG_DEBUG(Lib_Audio3d, "Port advance with no buffer queued");
|
||||
port.current_buffer = std::nullopt;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortClose() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortCreate() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortDestroy() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortFlush() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortFreeState() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetList() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetParameters() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(const OrbisAudio3dPortId port_id, u32* queue_level,
|
||||
u32* queue_available) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, port_id = {}, queue_level = {}, queue_available = {}", port_id,
|
||||
static_cast<void*>(queue_level), static_cast<void*>(queue_available));
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (!queue_level && !queue_available) {
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
const auto port = state->ports[port_id];
|
||||
const size_t size = port.queue.size();
|
||||
|
||||
if (queue_level) {
|
||||
*queue_level = size;
|
||||
}
|
||||
|
||||
if (queue_available) {
|
||||
*queue_available = port.parameters.queue_depth - size;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetState() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetStatus() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(const OrbisUserServiceUserId user_id,
|
||||
const OrbisAudio3dOpenParameters* parameters,
|
||||
OrbisAudio3dPortId* port_id) {
|
||||
LOG_INFO(Lib_Audio3d, "called, user_id = {}, parameters = {}, id = {}", user_id,
|
||||
static_cast<const void*>(parameters), static_cast<void*>(port_id));
|
||||
|
||||
if (!state) {
|
||||
LOG_ERROR(Lib_Audio3d, "!initialized");
|
||||
return ORBIS_AUDIO3D_ERROR_NOT_READY;
|
||||
}
|
||||
|
||||
if (!parameters || !port_id) {
|
||||
LOG_ERROR(Lib_Audio3d, "!parameters || !id");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
const int id = static_cast<int>(state->ports.size()) + 1;
|
||||
|
||||
if (id > 3) {
|
||||
LOG_ERROR(Lib_Audio3d, "id > 3");
|
||||
return ORBIS_AUDIO3D_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
*port_id = id;
|
||||
std::memcpy(&state->ports[id].parameters, parameters, sizeof(OrbisAudio3dOpenParameters));
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortPush(const OrbisAudio3dPortId port_id,
|
||||
const OrbisAudio3dBlocking blocking) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, port_id = {}, blocking = {}", port_id,
|
||||
magic_enum::enum_name(blocking));
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
const auto& port = state->ports[port_id];
|
||||
if (port.parameters.buffer_mode !=
|
||||
OrbisAudio3dBufferMode::ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH) {
|
||||
LOG_ERROR(Lib_Audio3d, "port doesn't have push capability");
|
||||
return ORBIS_AUDIO3D_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!port.current_buffer.has_value()) {
|
||||
// Nothing to push.
|
||||
LOG_DEBUG(Lib_Audio3d, "Port push with no buffer ready");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// TODO: Implement asynchronous blocking mode.
|
||||
const auto& [sample_buffer, num_samples] = port.current_buffer.value();
|
||||
return AudioOut::sceAudioOutOutput(state->audio_out_handle, sample_buffer);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortQueryDebug() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortSetAttribute(const OrbisAudio3dPortId port_id,
|
||||
const OrbisAudio3dAttributeId attribute_id,
|
||||
void* attribute, const u64 attribute_size) {
|
||||
LOG_INFO(Lib_Audio3d,
|
||||
"uiPortId = {}, userId = {}, type = {}, index = {}, len = {}, freq = {}, param = {}",
|
||||
uiPortId, userId, type, index, len, freq, param);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
"called, port_id = {}, attribute_id = {}, attribute = {}, attribute_size = {}",
|
||||
port_id, static_cast<u32>(attribute_id), attribute, attribute_size);
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(s32 handle) {
|
||||
LOG_INFO(Lib_Audio3d, "handle = {}", handle);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(s32 handle, const void* ptr) {
|
||||
LOG_TRACE(Lib_Audio3d, "handle = {}", handle);
|
||||
if (ptr == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid Output ptr");
|
||||
if (!attribute) {
|
||||
LOG_ERROR(Lib_Audio3d, "!attribute");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(::Libraries::AudioOut::OrbisAudioOutOutputParam* param,
|
||||
s32 num) {
|
||||
LOG_INFO(Lib_Audio3d, "num = {}", num);
|
||||
if (param == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid OutputParam ptr");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortCreate(u32 uiGranularity, OrbisAudio3dRate eRate, s64 iReserved,
|
||||
OrbisAudio3dPortId* pId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiGranularity = {}, iReserved = {}", uiGranularity, iReserved);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortDestroy(OrbisAudio3dPortId uiPortId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Audio3dPrivate
|
||||
|
||||
const char* PS4_SYSV_ABI sceAudio3dStrError(int iErrorCode) {
|
||||
LOG_ERROR(Lib_Audio3d, "(PRIVATE) called, iErrorCode = {}", iErrorCode);
|
||||
return "NOT_IMPLEMENTED";
|
||||
}
|
||||
|
||||
// Audio3dDebug
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortQueryDebug() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortQueryDebug called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetList() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortGetList called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetParameters() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortGetParameters called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetState() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortGetState called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortFreeState() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortFreeState called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Unknown
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetBufferLevel() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dReportRegisterHandler() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetStatus() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dReportUnregisterHandler() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dReportRegisterHandler() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dSetGpuRenderer() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dReportUnregisterHandler() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dStrError() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dSetGpuRenderer() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dTerminate() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("pZlOm1aF3aA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutClose);
|
||||
LIB_FUNCTION("ucEsi62soTo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutOpen);
|
||||
LIB_FUNCTION("7NYEzJ9SJbM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dAudioOutOutput);
|
||||
LIB_FUNCTION("HbxYY27lK6E", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dAudioOutOutputs);
|
||||
LIB_FUNCTION("9tEwE0GV0qo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite);
|
||||
LIB_FUNCTION("xH4Q9UILL3o", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite2);
|
||||
LIB_FUNCTION("lvWMW6vEqFU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dCreateSpeakerArray);
|
||||
LIB_FUNCTION("8hm6YdoQgwg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dDeleteSpeakerArray);
|
||||
LIB_FUNCTION("Im+jOoa5WAI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetDefaultOpenParameters);
|
||||
LIB_FUNCTION("kEqqyDkmgdI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetSpeakerArrayMemorySize);
|
||||
LIB_FUNCTION("-R1DukFq7Dk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetSpeakerArrayMixCoefficients);
|
||||
LIB_FUNCTION("-Re+pCWvwjQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetSpeakerArrayMixCoefficients2);
|
||||
LIB_FUNCTION("-pzYDZozm+M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortQueryDebug);
|
||||
LIB_FUNCTION("1HXxo-+1qCw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dObjectUnreserve);
|
||||
LIB_FUNCTION("UmCvjSmuZIw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dInitialize);
|
||||
LIB_FUNCTION("jO2tec4dJ2M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dObjectReserve);
|
||||
LIB_FUNCTION("4uyHN9q4ZeU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dObjectSetAttributes);
|
||||
LIB_FUNCTION("7NYEzJ9SJbM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dAudioOutOutput);
|
||||
LIB_FUNCTION("8hm6YdoQgwg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dDeleteSpeakerArray);
|
||||
LIB_FUNCTION("1HXxo-+1qCw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dObjectUnreserve);
|
||||
LIB_FUNCTION("lw0qrdSjZt8", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortAdvance);
|
||||
LIB_FUNCTION("OyVqOeVNtSk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortClose);
|
||||
LIB_FUNCTION("UHFOgVNz0kk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortCreate);
|
||||
LIB_FUNCTION("Mw9mRQtWepY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortDestroy);
|
||||
LIB_FUNCTION("ZOGrxWLgQzE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFlush);
|
||||
LIB_FUNCTION("uJ0VhGcxCTQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFreeState);
|
||||
LIB_FUNCTION("9ZA23Ia46Po", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetAttributesSupported);
|
||||
LIB_FUNCTION("9tEwE0GV0qo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite);
|
||||
LIB_FUNCTION("Aacl5qkRU6U", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dStrError);
|
||||
LIB_FUNCTION("CKHlRW2E9dA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetState);
|
||||
LIB_FUNCTION("HbxYY27lK6E", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dAudioOutOutputs);
|
||||
LIB_FUNCTION("Im+jOoa5WAI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetDefaultOpenParameters);
|
||||
LIB_FUNCTION("Mw9mRQtWepY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortDestroy);
|
||||
LIB_FUNCTION("OyVqOeVNtSk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortClose);
|
||||
LIB_FUNCTION("QfNXBrKZeI0", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dReportRegisterHandler);
|
||||
LIB_FUNCTION("QqgTQQdzEMY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetBufferLevel);
|
||||
LIB_FUNCTION("SEggctIeTcI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetList);
|
||||
LIB_FUNCTION("UHFOgVNz0kk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortCreate);
|
||||
LIB_FUNCTION("UmCvjSmuZIw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dInitialize);
|
||||
LIB_FUNCTION("VEVhZ9qd4ZY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortPush);
|
||||
LIB_FUNCTION("WW1TS2iz5yc", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dTerminate);
|
||||
LIB_FUNCTION("XeDDK0xJWQA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortOpen);
|
||||
LIB_FUNCTION("YaaDbDwKpFM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetQueueLevel);
|
||||
LIB_FUNCTION("Yq9bfUQ0uJg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortSetAttribute);
|
||||
LIB_FUNCTION("ZOGrxWLgQzE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFlush);
|
||||
LIB_FUNCTION("flPcUaXVXcw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetParameters);
|
||||
LIB_FUNCTION("YaaDbDwKpFM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetQueueLevel);
|
||||
LIB_FUNCTION("CKHlRW2E9dA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetState);
|
||||
LIB_FUNCTION("iRX6GJs9tvE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetStatus);
|
||||
LIB_FUNCTION("jO2tec4dJ2M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dObjectReserve);
|
||||
LIB_FUNCTION("kEqqyDkmgdI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetSpeakerArrayMemorySize);
|
||||
LIB_FUNCTION("lvWMW6vEqFU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dCreateSpeakerArray);
|
||||
LIB_FUNCTION("lw0qrdSjZt8", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortAdvance);
|
||||
LIB_FUNCTION("pZlOm1aF3aA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutClose);
|
||||
LIB_FUNCTION("XeDDK0xJWQA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortOpen);
|
||||
LIB_FUNCTION("VEVhZ9qd4ZY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortPush);
|
||||
LIB_FUNCTION("-pzYDZozm+M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortQueryDebug);
|
||||
LIB_FUNCTION("Yq9bfUQ0uJg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortSetAttribute);
|
||||
LIB_FUNCTION("QfNXBrKZeI0", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dReportRegisterHandler);
|
||||
LIB_FUNCTION("psv2gbihC1A", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dReportUnregisterHandler);
|
||||
LIB_FUNCTION("uJ0VhGcxCTQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFreeState);
|
||||
LIB_FUNCTION("ucEsi62soTo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutOpen);
|
||||
LIB_FUNCTION("xH4Q9UILL3o", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite2);
|
||||
LIB_FUNCTION("yEYXcbAGK14", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dSetGpuRenderer);
|
||||
LIB_FUNCTION("Aacl5qkRU6U", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dStrError);
|
||||
LIB_FUNCTION("WW1TS2iz5yc", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dTerminate);
|
||||
};
|
||||
|
||||
} // namespace Libraries::Audio3d
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
#include <optional>
|
||||
#include <queue>
|
||||
|
||||
#include <stddef.h>
|
||||
#include "common/types.h"
|
||||
#include "core/libraries/audio/audioout.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
|
@ -13,123 +15,131 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::Audio3d {
|
||||
|
||||
class Audio3d;
|
||||
|
||||
using OrbisUserServiceUserId = s32;
|
||||
using OrbisAudio3dPortId = u32;
|
||||
using OrbisAudio3dObjectId = u32;
|
||||
using OrbisAudio3dAttributeId = u32;
|
||||
|
||||
enum class OrbisAudio3dFormat {
|
||||
S16 = 0,
|
||||
Float = 1,
|
||||
enum class OrbisAudio3dRate : u32 {
|
||||
ORBIS_AUDIO3D_RATE_48000 = 0,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dRate {
|
||||
Rate48000 = 0,
|
||||
enum class OrbisAudio3dBufferMode : u32 {
|
||||
ORBIS_AUDIO3D_BUFFER_NO_ADVANCE = 0,
|
||||
ORBIS_AUDIO3D_BUFFER_ADVANCE_NO_PUSH = 1,
|
||||
ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH = 2,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dBufferMode { NoAdvance = 0, AdvanceNoPush = 1, AdvanceAndPush = 2 };
|
||||
|
||||
enum class OrbisAudio3dBlocking {
|
||||
Async = 0,
|
||||
Sync = 1,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dPassthrough {
|
||||
None = 0,
|
||||
Left = 1,
|
||||
Right = 2,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dOutputRoute {
|
||||
Both = 0,
|
||||
HmuOnly = 1,
|
||||
TvOnly = 2,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dAmbisonics : u32 {
|
||||
None = ~0U,
|
||||
W = 0,
|
||||
X = 1,
|
||||
Y = 2,
|
||||
Z = 3,
|
||||
R = 4,
|
||||
S = 5,
|
||||
T = 6,
|
||||
U = 7,
|
||||
V = 8,
|
||||
K = 9,
|
||||
L = 10,
|
||||
M = 11,
|
||||
N = 12,
|
||||
O = 13,
|
||||
P = 14,
|
||||
Q = 15
|
||||
};
|
||||
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePcm = 0x00000001;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePriority = 0x00000002;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePosition = 0x00000003;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeSpread = 0x00000004;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeGain = 0x00000005;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePassthrough = 0x00000006;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeResetState = 0x00000007;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeApplicationSpecific = 0x00000008;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeAmbisonics = 0x00000009;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeRestricted = 0x0000000A;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeOutputRoute = 0x0000000B;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeLateReverbLevel = 0x00010001;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeDownmixSpreadRadius = 0x00010002;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeDownmixSpreadHeightAware = 0x00010003;
|
||||
|
||||
struct OrbisAudio3dSpeakerArray;
|
||||
using OrbisAudio3dSpeakerArrayHandle = OrbisAudio3dSpeakerArray*; // head
|
||||
|
||||
struct OrbisAudio3dOpenParameters {
|
||||
size_t size_this;
|
||||
u64 size_this;
|
||||
u32 granularity;
|
||||
OrbisAudio3dRate rate;
|
||||
u32 max_objects;
|
||||
u32 queue_depth;
|
||||
OrbisAudio3dBufferMode buffer_mode;
|
||||
char padding[32];
|
||||
int : 32;
|
||||
u32 num_beds;
|
||||
};
|
||||
|
||||
struct OrbisAudio3dAttribute {
|
||||
OrbisAudio3dAttributeId attribute_id;
|
||||
char padding[32];
|
||||
const void* p_value;
|
||||
size_t value;
|
||||
enum class OrbisAudio3dFormat : u32 {
|
||||
ORBIS_AUDIO3D_FORMAT_S16 = 0,
|
||||
ORBIS_AUDIO3D_FORMAT_FLOAT = 1,
|
||||
};
|
||||
|
||||
struct OrbisAudio3dPosition {
|
||||
float fX;
|
||||
float fY;
|
||||
float fZ;
|
||||
enum class OrbisAudio3dOutputRoute : u32 {
|
||||
ORBIS_AUDIO3D_OUTPUT_BOTH = 0,
|
||||
ORBIS_AUDIO3D_OUTPUT_HMU_ONLY = 1,
|
||||
ORBIS_AUDIO3D_OUTPUT_TV_ONLY = 2,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dBlocking : u32 {
|
||||
ORBIS_AUDIO3D_BLOCKING_ASYNC = 0,
|
||||
ORBIS_AUDIO3D_BLOCKING_SYNC = 1,
|
||||
};
|
||||
|
||||
struct OrbisAudio3dPcm {
|
||||
OrbisAudio3dFormat format;
|
||||
const void* sample_buffer;
|
||||
void* sample_buffer;
|
||||
u32 num_samples;
|
||||
};
|
||||
|
||||
struct OrbisAudio3dSpeakerArrayParameters {
|
||||
OrbisAudio3dPosition* speaker_position;
|
||||
u32 num_speakers;
|
||||
bool is_3d;
|
||||
void* buffer;
|
||||
size_t size;
|
||||
enum class OrbisAudio3dAttributeId : u32 {
|
||||
ORBIS_AUDIO3D_ATTRIBUTE_PCM = 1,
|
||||
};
|
||||
|
||||
struct OrbisAudio3dApplicationSpecific {
|
||||
size_t size_this;
|
||||
u8 application_specific[32];
|
||||
using OrbisAudio3dPortId = u32;
|
||||
using OrbisAudio3dObjectId = u32;
|
||||
|
||||
struct OrbisAudio3dAttribute {
|
||||
OrbisAudio3dAttributeId attribute_id;
|
||||
int : 32;
|
||||
void* value;
|
||||
u64 value_size;
|
||||
};
|
||||
|
||||
void PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* sParameters);
|
||||
struct AudioData {
|
||||
u8* sample_buffer;
|
||||
u32 num_samples;
|
||||
};
|
||||
|
||||
struct Port {
|
||||
OrbisAudio3dOpenParameters parameters{};
|
||||
std::deque<AudioData> queue; // Only stores PCM buffers for now
|
||||
std::optional<AudioData> current_buffer{};
|
||||
};
|
||||
|
||||
struct Audio3dState {
|
||||
std::unordered_map<OrbisAudio3dPortId, Port> ports;
|
||||
s32 audio_out_handle;
|
||||
};
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(s32 handle);
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOpen(OrbisAudio3dPortId port_id, OrbisUserServiceUserId user_id,
|
||||
s32 type, s32 index, u32 len, u32 freq,
|
||||
AudioOut::OrbisAudioOutParamExtendedInformation param);
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(s32 handle, void* ptr);
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(AudioOut::OrbisAudioOutOutputParam* param, u32 num);
|
||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite(OrbisAudio3dPortId port_id, u32 num_channels,
|
||||
OrbisAudio3dFormat format, void* buffer, u32 num_samples);
|
||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite2(OrbisAudio3dPortId port_id, u32 num_channels,
|
||||
OrbisAudio3dFormat format, void* buffer, u32 num_samples,
|
||||
OrbisAudio3dOutputRoute output_route, bool restricted);
|
||||
s32 PS4_SYSV_ABI sceAudio3dCreateSpeakerArray();
|
||||
s32 PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray();
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* params);
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize();
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients();
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2();
|
||||
s32 PS4_SYSV_ABI sceAudio3dInitialize(s64 reserved);
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectReserve(OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dObjectId* object_id);
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectSetAttributes(OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dObjectId object_id, u64 num_attributes,
|
||||
const OrbisAudio3dAttribute* attribute_array);
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectUnreserve();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortAdvance(OrbisAudio3dPortId port_id);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortClose();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortCreate();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortDestroy();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortFlush();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortFreeState();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetList();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetParameters();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(OrbisAudio3dPortId port_id, u32* queue_level,
|
||||
u32* queue_available);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetState();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetStatus();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(OrbisUserServiceUserId user_id,
|
||||
const OrbisAudio3dOpenParameters* parameters,
|
||||
OrbisAudio3dPortId* port_id);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortPush(OrbisAudio3dPortId port_id, OrbisAudio3dBlocking blocking);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortQueryDebug();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortSetAttribute(OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dAttributeId attribute_id, void* attribute,
|
||||
u64 attribute_size);
|
||||
s32 PS4_SYSV_ABI sceAudio3dReportRegisterHandler();
|
||||
s32 PS4_SYSV_ABI sceAudio3dReportUnregisterHandler();
|
||||
s32 PS4_SYSV_ABI sceAudio3dSetGpuRenderer();
|
||||
s32 PS4_SYSV_ABI sceAudio3dStrError();
|
||||
s32 PS4_SYSV_ABI sceAudio3dTerminate();
|
||||
|
||||
void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym);
|
||||
} // namespace Libraries::Audio3d
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
constexpr int ORBIS_AUDIO3D_ERROR_UNKNOWN = 0x80EA0001;
|
||||
constexpr int ORBIS_AUDIO3D_ERROR_INVALID_PORT = 0x80EA0002;
|
||||
constexpr int ORBIS_AUDIO3D_ERROR_INVALID_OBJECT = 0x80EA0003;
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "audio3d_error.h"
|
||||
#include "audio3d_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/kernel.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Audio3d {} // namespace Libraries::Audio3d
|
|
@ -1,16 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "audio3d.h"
|
||||
|
||||
namespace Libraries::Audio3d {
|
||||
|
||||
class Audio3d {
|
||||
public:
|
||||
private:
|
||||
using OrbisAudio3dPluginId = u32;
|
||||
};
|
||||
|
||||
} // namespace Libraries::Audio3d
|
|
@ -104,6 +104,20 @@ s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handl
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceVideoOutDeleteVblankEvent(Kernel::SceKernelEqueue eq, s32 handle) {
|
||||
auto* port = driver->GetPort(handle);
|
||||
if (port == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (eq == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE;
|
||||
}
|
||||
eq->RemoveEvent(handle, Kernel::SceKernelEvent::Filter::VideoOut);
|
||||
port->vblank_events.erase(find(port->vblank_events.begin(), port->vblank_events.end(), eq));
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses,
|
||||
s32 bufferNum, const BufferAttribute* attribute) {
|
||||
if (!addresses || !attribute) {
|
||||
|
@ -166,7 +180,7 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev) {
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev) {
|
||||
if (ev == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
@ -194,7 +208,7 @@ int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev) {
|
|||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64_t* data) {
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, s64* data) {
|
||||
if (ev == nullptr || data == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
@ -211,6 +225,17 @@ int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetEventCount(const Kernel::SceKernelEvent* ev) {
|
||||
if (ev == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
if (ev->filter != Kernel::SceKernelEvent::Filter::VideoOut) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT;
|
||||
}
|
||||
|
||||
return (ev->data >> 0xc) & 0xf;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) {
|
||||
if (!status) {
|
||||
LOG_ERROR(Lib_VideoOut, "Flip status is null");
|
||||
|
@ -447,12 +472,16 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("U2JJtSqNKZI", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetEventId);
|
||||
LIB_FUNCTION("rWUTcKdkUzQ", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutGetEventData);
|
||||
LIB_FUNCTION("Mt4QHHkxkOc", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutGetEventCount);
|
||||
LIB_FUNCTION("DYhhWbJSeRg", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutColorSettingsSetGamma);
|
||||
LIB_FUNCTION("pv9CI5VC+R0", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutAdjustColor);
|
||||
LIB_FUNCTION("-Ozn0F1AFRg", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutDeleteFlipEvent);
|
||||
LIB_FUNCTION("oNOQn3knW6s", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutDeleteVblankEvent);
|
||||
LIB_FUNCTION("pjkDsgxli6c", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutModeSetAny_);
|
||||
LIB_FUNCTION("N1bEoJ4SRw4", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
|
|
|
@ -516,9 +516,11 @@ void MainWindow::CreateConnects() {
|
|||
Config::setIconSize(36);
|
||||
Config::setSliderPosition(0);
|
||||
} else {
|
||||
m_game_grid_frame->icon_size = 69;
|
||||
ui->sizeSlider->setValue(0); // icone_size - 36
|
||||
Config::setIconSizeGrid(69);
|
||||
Config::setSliderPositionGrid(0);
|
||||
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -529,9 +531,11 @@ void MainWindow::CreateConnects() {
|
|||
Config::setIconSize(64);
|
||||
Config::setSliderPosition(28);
|
||||
} else {
|
||||
m_game_grid_frame->icon_size = 97;
|
||||
ui->sizeSlider->setValue(28);
|
||||
Config::setIconSizeGrid(97);
|
||||
Config::setSliderPositionGrid(28);
|
||||
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -542,9 +546,11 @@ void MainWindow::CreateConnects() {
|
|||
Config::setIconSize(128);
|
||||
Config::setSliderPosition(92);
|
||||
} else {
|
||||
m_game_grid_frame->icon_size = 161;
|
||||
ui->sizeSlider->setValue(92);
|
||||
Config::setIconSizeGrid(160);
|
||||
Config::setSliderPositionGrid(91);
|
||||
Config::setIconSizeGrid(161);
|
||||
Config::setSliderPositionGrid(92);
|
||||
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -555,9 +561,11 @@ void MainWindow::CreateConnects() {
|
|||
Config::setIconSize(256);
|
||||
Config::setSliderPosition(220);
|
||||
} else {
|
||||
m_game_grid_frame->icon_size = 256;
|
||||
ui->sizeSlider->setValue(220);
|
||||
Config::setIconSizeGrid(256);
|
||||
Config::setSliderPositionGrid(220);
|
||||
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
|
||||
}
|
||||
});
|
||||
// List
|
||||
|
@ -577,6 +585,7 @@ void MainWindow::CreateConnects() {
|
|||
ui->sizeSlider->setEnabled(true);
|
||||
ui->sizeSlider->setSliderPosition(slider_pos);
|
||||
ui->mw_searchbar->setText("");
|
||||
SetLastIconSizeBullet();
|
||||
});
|
||||
// Grid
|
||||
connect(ui->setlistModeGridAct, &QAction::triggered, m_dock_widget.data(), [this]() {
|
||||
|
@ -595,6 +604,7 @@ void MainWindow::CreateConnects() {
|
|||
ui->sizeSlider->setEnabled(true);
|
||||
ui->sizeSlider->setSliderPosition(slider_pos_grid);
|
||||
ui->mw_searchbar->setText("");
|
||||
SetLastIconSizeBullet();
|
||||
});
|
||||
// Elf Viewer
|
||||
connect(ui->setlistElfAct, &QAction::triggered, m_dock_widget.data(), [this]() {
|
||||
|
@ -606,6 +616,7 @@ void MainWindow::CreateConnects() {
|
|||
isTableList = false;
|
||||
ui->sizeSlider->setDisabled(true);
|
||||
Config::setTableMode(2);
|
||||
SetLastIconSizeBullet();
|
||||
});
|
||||
|
||||
// Cheats/Patches Download.
|
||||
|
@ -1031,19 +1042,37 @@ void MainWindow::SetLastUsedTheme() {
|
|||
void MainWindow::SetLastIconSizeBullet() {
|
||||
// set QAction bullet point if applicable
|
||||
int lastSize = Config::getIconSize();
|
||||
switch (lastSize) {
|
||||
case 36:
|
||||
ui->setIconSizeTinyAct->setChecked(true);
|
||||
break;
|
||||
case 64:
|
||||
ui->setIconSizeSmallAct->setChecked(true);
|
||||
break;
|
||||
case 128:
|
||||
ui->setIconSizeMediumAct->setChecked(true);
|
||||
break;
|
||||
case 256:
|
||||
ui->setIconSizeLargeAct->setChecked(true);
|
||||
break;
|
||||
int lastSizeGrid = Config::getIconSizeGrid();
|
||||
if (isTableList) {
|
||||
switch (lastSize) {
|
||||
case 36:
|
||||
ui->setIconSizeTinyAct->setChecked(true);
|
||||
break;
|
||||
case 64:
|
||||
ui->setIconSizeSmallAct->setChecked(true);
|
||||
break;
|
||||
case 128:
|
||||
ui->setIconSizeMediumAct->setChecked(true);
|
||||
break;
|
||||
case 256:
|
||||
ui->setIconSizeLargeAct->setChecked(true);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (lastSizeGrid) {
|
||||
case 69:
|
||||
ui->setIconSizeTinyAct->setChecked(true);
|
||||
break;
|
||||
case 97:
|
||||
ui->setIconSizeSmallAct->setChecked(true);
|
||||
break;
|
||||
case 161:
|
||||
ui->setIconSizeMediumAct->setChecked(true);
|
||||
break;
|
||||
case 256:
|
||||
ui->setIconSizeLargeAct->setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1892,43 +1892,43 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Copy GPU Buffers:\nGets around race conditions involving GPU submits.\nMay or may not help with PM4 type 0 crashes.</source>
|
||||
<translation type="unfinished">Copy GPU Buffers:\nGets around race conditions involving GPU submits.\nMay or may not help with PM4 type 0 crashes.</translation>
|
||||
<translation>نسخ مخازن الذاكرة الخاصة بالـ GPU:\nيتجاوز مشكلة التزامن المتعلقة بتقديمات GPU.\n قد يساعد أو لا يساعد في حل أعطال PM4 من النوع 0.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Host Debug Markers:\nInserts emulator-side information like markers for specific AMDGPU commands around Vulkan commands, as well as giving resources debug names.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</source>
|
||||
<translation type="unfinished">Host Debug Markers:\nInserts emulator-side information like markers for specific AMDGPU commands around Vulkan commands, as well as giving resources debug names.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</translation>
|
||||
<translation>علامات تصحيح الأخطاء للمضيف:\nقوم بإدراج معلومات في المحاكي مثل علامات للأوامر AMDGPU المرتبطة بأوامر فولكن، إضافةً إلى تخصيص أسماء لتصحيح الأخطاء للموارد.\nمن الأفضل تفعيل تشخيص الأعطال عند تفعيل هذه الخاصية.\nمفيد لبرامج مثل أداة تصحيح الأخطاء الرسومية.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Guest Debug Markers:\nInserts any debug markers the game itself has added to the command buffer.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</source>
|
||||
<translation type="unfinished">Guest Debug Markers:\nInserts any debug markers the game itself has added to the command buffer.\nIf you have this enabled, you should enable Crash Diagnostics.\nUseful for programs like RenderDoc.</translation>
|
||||
<translation>علامات تصحيح الضيف:\nيُدخل أي علامات تصحيح أضافتها اللعبة بنفسها إلى ذاكرة أوامر الرسوميات.\nإذا تم التفعيل الأفضل تمكين "تشخيص الأعطال".\nمفيد لبرامج مثل دوك.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Data Path:\nThe folder where game save data will be saved.</source>
|
||||
<translation type="unfinished">Save Data Path:\nThe folder where game save data will be saved.</translation>
|
||||
<translation>مسار حفظ البيانات:\nالمجلد الذي سيتم فيه حفظ بيانات تخزين اللعبة.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Browse:\nBrowse for a folder to set as the save data path.</source>
|
||||
<translation type="unfinished">Browse:\nBrowse for a folder to set as the save data path.</translation>
|
||||
<translation>تصفح:\nاختر مجلدًا لتحديده كمكان لحفظ بيانات التخزين.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Release</source>
|
||||
<translation type="unfinished">Release</translation>
|
||||
<translation>إصدار</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Nightly</source>
|
||||
<translation type="unfinished">Nightly</translation>
|
||||
<translation>إصدار ليلي</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Set the volume of the background music.</source>
|
||||
<translation type="unfinished">Set the volume of the background music.</translation>
|
||||
<translation>ضبط صوت الموسيقى في الخلفية.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable Motion Controls</source>
|
||||
<translation type="unfinished">Enable Motion Controls</translation>
|
||||
<translation>تفعيل التحكم بالحركة</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Save Data Path</source>
|
||||
<translation type="unfinished">Save Data Path</translation>
|
||||
<translation>مسار بيانات الحفظ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Browse</source>
|
||||
|
@ -1936,15 +1936,15 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>async</source>
|
||||
<translation type="unfinished">async</translation>
|
||||
<translation>غير متزامن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>sync</source>
|
||||
<translation type="unfinished">sync</translation>
|
||||
<translation>متزامن</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Auto Select</source>
|
||||
<translation type="unfinished">Auto Select</translation>
|
||||
<translation>تلقائي</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Directory to install games</source>
|
||||
|
@ -1952,11 +1952,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Directory to save data</source>
|
||||
<translation type="unfinished">Directory to save data</translation>
|
||||
<translation>مسار الحفظ لبيانات الألعاب</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Video</source>
|
||||
<translation type="unfinished">Video</translation>
|
||||
<translation>الفيديو</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Display Mode</source>
|
||||
|
@ -1992,7 +1992,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Separate Log Files:\nWrites a separate logfile for each game.</source>
|
||||
<translation type="unfinished">Separate Log Files:\nWrites a separate logfile for each game.</translation>
|
||||
<translation>ملفات السجل المنفصلة:\nيتم كتابة سجل منفصل لكل لعبه.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Trophy Notification Position</source>
|
||||
|
@ -2028,7 +2028,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Portable user folder:\nStores shadPS4 settings and data that will be applied only to the shadPS4 build located in the current folder. Restart the app after creating the portable user folder to begin using it.</source>
|
||||
<translation type="unfinished">Portable user folder:\nStores shadPS4 settings and data that will be applied only to the shadPS4 build located in the current folder. Restart the app after creating the portable user folder to begin using it.</translation>
|
||||
<translation>مجلد المستخدم القابل للنقل:\nتخزين إعدادات وبيانات المحاكي التي ستُطبق فقط على هذا الإصدار في المجلد الحالي. بعد إنشاء مجلد المستخدم القابل للنقل، يجب إعادة تشغيل التطبيق للبدء في استخدامه.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot create portable user folder</source>
|
||||
|
@ -2040,7 +2040,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Portable user folder created</source>
|
||||
<translation type="unfinished">Portable user folder created</translation>
|
||||
<translation>تم إنشاء مجلد مستخدم محمول</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 successfully created.</source>
|
||||
|
@ -2048,7 +2048,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\ntrophy.wav OR trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\nNote: The sound will only work in QT versions.</source>
|
||||
<translation type="unfinished">Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\ntrophy.wav OR trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\nNote: The sound will only work in QT versions.</translation>
|
||||
<translation>افتح مجلد الصور/الأصوات الخاصة بالجوائز المخصصة:\nيمكنك إضافة صور مخصصة للجوائز وصوت مرفق.\nأضف الملفات إلى مجلد custom_trophy بالأسماء التالية:\ntrophy.wav أو trophy.mp3، bronze.png، gold.png، platinum.png، silver.png\nملاحظة: الصوت سيعمل فقط في الإصدارات التي تستخدم QT.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<name>AboutDialog</name>
|
||||
<message>
|
||||
<source>About shadPS4</source>
|
||||
<translation type="unfinished">About shadPS4</translation>
|
||||
<translation>Over shadPS4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shadPS4 is an experimental open-source emulator for the PlayStation 4.</source>
|
||||
|
@ -582,7 +582,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for reading</source>
|
||||
<translation type="unfinished">Could not open the file for reading</translation>
|
||||
<translation/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for writing</source>
|
||||
|
|
2081
src/qt_gui/translations/sl_SI.ts
Normal file
2081
src/qt_gui/translations/sl_SI.ts
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -267,12 +267,12 @@ Id EmitFPFrexpSig64(EmitContext& ctx, Id value) {
|
|||
|
||||
Id EmitFPFrexpExp32(EmitContext& ctx, Id value) {
|
||||
const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f32, value);
|
||||
return ctx.OpCompositeExtract(ctx.U32[1], frexp, 1);
|
||||
return ctx.OpBitcast(ctx.U32[1], ctx.OpCompositeExtract(ctx.S32[1], frexp, 1));
|
||||
}
|
||||
|
||||
Id EmitFPFrexpExp64(EmitContext& ctx, Id value) {
|
||||
const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f64, value);
|
||||
return ctx.OpCompositeExtract(ctx.U32[1], frexp, 1);
|
||||
return ctx.OpBitcast(ctx.U32[1], ctx.OpCompositeExtract(ctx.S32[1], frexp, 1));
|
||||
}
|
||||
|
||||
Id EmitFPOrdEqual16(EmitContext& ctx, Id lhs, Id rhs) {
|
||||
|
|
|
@ -153,9 +153,9 @@ void EmitContext::DefineArithmeticTypes() {
|
|||
|
||||
full_result_i32x2 = Name(TypeStruct(S32[1], S32[1]), "full_result_i32x2");
|
||||
full_result_u32x2 = Name(TypeStruct(U32[1], U32[1]), "full_result_u32x2");
|
||||
frexp_result_f32 = Name(TypeStruct(F32[1], U32[1]), "frexp_result_f32");
|
||||
frexp_result_f32 = Name(TypeStruct(F32[1], S32[1]), "frexp_result_f32");
|
||||
if (info.uses_fp64) {
|
||||
frexp_result_f64 = Name(TypeStruct(F64[1], U32[1]), "frexp_result_f64");
|
||||
frexp_result_f64 = Name(TypeStruct(F64[1], S32[1]), "frexp_result_f64");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2784,8 +2784,7 @@ constexpr std::array<InstFormat, 256> InstructionFormatDS = {{
|
|||
// 62 = DS_APPEND
|
||||
{InstClass::DsAppendCon, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32},
|
||||
// 63 = DS_ORDERED_COUNT
|
||||
{InstClass::GdsOrdCnt, InstCategory::DataShare, 3, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::GdsOrdCnt, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32},
|
||||
// 64 = DS_ADD_U64
|
||||
{InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64,
|
||||
ScalarType::Uint64},
|
||||
|
|
|
@ -1010,8 +1010,10 @@ void Translator::V_CMP_CLASS_F32(const GcnInst& inst) {
|
|||
value = ir.FPIsNan(src0);
|
||||
} else if ((class_mask & IR::FloatClassFunc::Infinity) == IR::FloatClassFunc::Infinity) {
|
||||
value = ir.FPIsInf(src0);
|
||||
} else if ((class_mask & IR::FloatClassFunc::Negative) == IR::FloatClassFunc::Negative) {
|
||||
value = ir.FPLessThanEqual(src0, ir.Imm32(-0.f));
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
UNREACHABLE_MSG("Unsupported float class mask: {:#x}", static_cast<u32>(class_mask));
|
||||
}
|
||||
} else {
|
||||
// We don't know the type yet, delay its resolution.
|
||||
|
|
|
@ -25,6 +25,7 @@ enum class FloatClassFunc : u32 {
|
|||
|
||||
NaN = SignalingNan | QuietNan,
|
||||
Infinity = PositiveInfinity | NegativeInfinity,
|
||||
Negative = NegativeInfinity | NegativeNormal | NegativeDenorm | NegativeZero,
|
||||
Finite = NegativeNormal | NegativeDenorm | NegativeZero | PositiveNormal | PositiveDenorm |
|
||||
PositiveZero,
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue