Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Work #160

Merged
merged 22 commits into from
May 18, 2024
Merged

Work #160

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion asm/entry.asm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ jmpEntry PROC
AND RSP, -10h

; copy entry param to stack
ADD RSP, 24
ADD RSP, 40
push [RSI+24]
push [RSI+16]
push [RSI+8]
push [RSI]
; -
Expand Down
44 changes: 35 additions & 9 deletions core/dmem/types/directmem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ int DirectMemory::free(off_t start, size_t len) {
return Ok;
}

if (itHeap->first != addr || itHeap->second.size != len) {
if (len != 0 && (itHeap->first != addr || itHeap->second.size != len)) {
LOG_ERR(L"free Error| start:0x%08llx len:0x%08llx != start:0x%08llx len:0x%08llx", addr, len, itHeap->first, itHeap->second.size);
}

Expand Down Expand Up @@ -313,8 +313,9 @@ int DirectMemory::map(uint64_t vaddr, off_t offset, size_t len, int prot, int fl
MemoryInfo* info = nullptr;
if (flags & (int)filesystem::SceMapMode::FIXED) {
for (auto& item: m_objects) {
if (item.second.state == MemoryState::Reserved && item.first <= vaddr && (item.first + item.second.size) > (vaddr + len)) {
info = &item.second;
if (item.second.state == MemoryState::Reserved && item.first <= vaddr && item.second.size >= len) {
info = &item.second;
desVaddr = info->addr;
}
}
}
Expand All @@ -324,7 +325,7 @@ int DirectMemory::map(uint64_t vaddr, off_t offset, size_t len, int prot, int fl
// -

// Check if Commit needed
if (info->state == MemoryState::Free) {
if (info->state == MemoryState::Free || info->state == MemoryState::Reserved) {
MEM_ADDRESS_REQUIREMENTS addressReqs = {0};
MEM_EXTENDED_PARAMETER extendedParams = {0};

Expand All @@ -335,8 +336,11 @@ int DirectMemory::map(uint64_t vaddr, off_t offset, size_t len, int prot, int fl
extendedParams.Type = MemExtendedParameterAddressRequirements;
extendedParams.Pointer = &addressReqs;

void* ptr = VirtualAlloc2(NULL, (void*)desVaddr, info->size, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, convProtection(prot),
desVaddr != 0 ? 0 : &extendedParams, desVaddr != 0 ? 0 : 1);
uint32_t flags = MEM_COMMIT;
if (info->state != MemoryState::Reserved) {
flags |= MEM_RESERVE | MEM_WRITE_WATCH;
}
void* ptr = VirtualAlloc2(NULL, (void*)desVaddr, info->size, flags, convProtection(prot), desVaddr != 0 ? 0 : &extendedParams, desVaddr != 0 ? 0 : 1);
if (ptr == 0) {
auto const err = GetLastError();
LOG_ERR(L"Commit Error| addr:0x%08llx len:0x%08llx err:%d", info->addr, info->size, GetLastError());
Expand Down Expand Up @@ -432,10 +436,32 @@ uint64_t DirectMemory::size() const {

int DirectMemory::getAvailableSize(uint32_t start, uint32_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) const {
LOG_USE_MODULE(DirectMemory);
LOG_DEBUG(L"availableSize: start:0x%08llx end:0x%08llx alignment:0x%08llx", start, end, alignment);
LOG_DEBUG(L"availableSize: start:0x%lx end:0x%lx alignment:0x%08llx", start, end, alignment);

auto itItem = m_objects.lower_bound(DIRECTMEM_START + start);
if (m_objects.empty() || itItem == m_objects.end()) {
*startOut = start;
*sizeOut = std::min(SCE_KERNEL_MAIN_DMEM_SIZE, (uint64_t)end - start);
return Ok;
}

*startOut = start;
*sizeOut = (itItem->second.addr - DIRECTMEM_START) - start;
// if (itItem->second.addr + itItem->second.size >= DIRECTMEM_START + end) {
// *startOut = end;
// *sizeOut = 0;
// return Ok;
// }

// *startOut = start;
// *sizeOut = 0;

// auto itEnd = m_objects.lower_bound(DIRECTMEM_START + end);
// for (; itItem != itEnd; ++itItem) {
// *startOut = (itItem->second.addr + itItem->second.size) - DIRECTMEM_START;
// }

*startOut = m_usedSize;
*sizeOut = SCE_KERNEL_MAIN_DMEM_SIZE - m_usedSize;
// if (*startOut > end) *sizeOut = end - *startOut;

return Ok;
}
Expand Down
8 changes: 6 additions & 2 deletions core/fileManager/fileManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ class FileManager: public IFileManager {

if ((*dir->m_file) == endDir) return 0;

#pragma pack(push, 1)

struct DataStruct {
uint32_t fileno;
uint16_t reclen;
Expand All @@ -228,6 +230,8 @@ class FileManager: public IFileManager {
char name[256];
};

#pragma pack(pop, 1)

auto count = dir->count;
int n = 0;

Expand All @@ -237,15 +241,15 @@ class FileManager: public IFileManager {
auto const filename = (*dir->m_file)->path().filename().string();
if (sizeof(DataStruct) + std::min(filename.size(), 255llu) >= nbytes) break;

item->fileno = 0;
item->fileno = count;
item->type = ((*dir->m_file)->is_regular_file() ? 8 : 4);
item->namlen = filename.copy(item->name, 255);
item->name[item->namlen] = '\0';

n += sizeof(DataStruct);
item->reclen = sizeof(DataStruct);

LOG_DEBUG(L"KernelGetdirentries[%d]: %S %u offset:%u count:%u", handle, item->name, item->type, item->reclen, count);
LOG_DEBUG(L"KernelGetdirentries[%d]: %S %u offset:%u count:%u", handle, item->name, item->type, n, count);

std::error_code err;
(*dir->m_file).increment(err);
Expand Down
20 changes: 9 additions & 11 deletions core/kernel/pthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,13 @@ int join(ScePthread_obj obj, void** value) {
auto thread = getPthread(obj);
thread->p.join();

LOG_USE_MODULE(pthread);
LOG_DEBUG(L"Delete thread:%d", thread->unique_id);
// Cleanup thread
thread->~PthreadPrivate();
delete[] obj;
if (!thread->detached) {
LOG_USE_MODULE(pthread);
LOG_DEBUG(L"Delete thread:%d", thread->unique_id);
// Cleanup thread
thread->~PthreadPrivate();
delete[] obj;
}
// -
return Ok;
}
Expand Down Expand Up @@ -802,10 +804,7 @@ int cancel(ScePthread_obj obj) {
auto thread = getPthread(obj);
// todo cancel
// int result = ::pthread_cancel(thread->p);

LOG_USE_MODULE(pthread);
LOG_ERR(L" todo cancel| %S id:%d", thread->name.data(), thread->unique_id);
// LOG_TRACE(L"thread cancel| threadId:%d name:%S result:%d", thread->unique_id, thread->name.c_str(), result);
thread->p.interrupt();

return Ok;
}
Expand Down Expand Up @@ -1219,15 +1218,14 @@ void cleanup_thread() {
func(arg);
thread->cleanupFuncs.pop_back();
}
accessRuntimeLinker().destroyTLSKeys(getSelf());

auto thread_dtors = *getThreadDtors();

if (thread_dtors != nullptr) {
thread_dtors();
}

accessRuntimeLinker().destroyTLSKeys(getSelf());

accessMemoryManager()->unregisterStack((uint64_t)thread->attr.getStackAddr());

// Delete here if detached, else in join()
Expand Down
6 changes: 3 additions & 3 deletions core/runtime/runtimeLinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,13 +691,13 @@ void RuntimeLinker::destroyTLSKeys(uint8_t* obj) {

std::unique_lock const lock(m_mutex_int);

m_threadList.erase(pthread::getThreadId(obj));

for (uint64_t n = m_countcreatePrograms; n < m_dtvKeys.size(); ++n, ++pDtvKey) {
if (m_dtvKeys[n].destructor != nullptr) {
m_dtvKeys[n].destructor((void*)pDtvKey[n]);
if (pDtvKey[n] != 0) m_dtvKeys[n].destructor((void*)pDtvKey[n]);
}
}

m_threadList.erase(pthread::getThreadId(obj));
}

void RuntimeLinker::stopModules() {
Expand Down
59 changes: 25 additions & 34 deletions modules/libSceAudioOut/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ struct PortOut {
int userId = 0;
SceAudioOutPortType type = SceAudioOutPortType::MAIN;
uint8_t sampleSize = 0;
uint32_t sampleRate = 0;
uint32_t samplesNum = 0;
uint32_t freq = 0;
uint32_t queued = 0;
SceAudioOutParamFormat format = SceAudioOutParamFormat::FLOAT_MONO;
uint64_t lastOutputTime = 0;
Expand All @@ -31,6 +31,8 @@ struct PortOut {
float volumeModifier = 0.5f;
std::vector<uint8_t> mixedAudio;
std::string deviceName;

SDL_AudioSpec audioSpec;
};

class PortsOut {
Expand Down Expand Up @@ -70,16 +72,7 @@ class PortsOut {
*/
if (port.deviceName.compare(0, std::string::npos, devName, 0, port.deviceName.length()) != 0) continue;

SDL_AudioSpec fmt {
.freq = static_cast<int>(port.freq),
.format = port.sdlFormat,
.channels = static_cast<uint8_t>(port.channelsNum),
.samples = static_cast<uint16_t>(port.samplesNum),
.callback = nullptr,
.userdata = nullptr,
};

if ((port.device = SDL_OpenAudioDevice(devName, 0, &fmt, NULL, 0)) == 0) {
if ((port.device = SDL_OpenAudioDevice(devName, 0, &port.audioSpec, NULL, 0)) == 0) {
LOG_ERR(L"Failed to reopen %S audio device: %S", devName, SDL_GetError());
return;
}
Expand Down Expand Up @@ -167,7 +160,7 @@ void syncPort(PortOut* port) {
const uint32_t bytesize = bytesize_1ch * port->channelsNum;

if (port->device == 0) {
float duration = bytesize_1ch / float(port->freq * port->sampleSize);
float duration = bytesize_1ch / float(port->sampleRate * port->sampleSize);
SDL_Delay(int(duration * 1000)); // Pretending that we playing something
return;
}
Expand Down Expand Up @@ -200,20 +193,19 @@ int writeOut(PortOut* port, const void* ptr, bool sync = true) {
return port->samplesNum;
}

const uint32_t bytesize = bytesize_1ch * port->channelsNum;
const int maxVolume = SDL_MIX_MAXVOLUME * port->volumeModifier;
auto& mixed = port->mixedAudio;
const int maxVolume = SDL_MIX_MAXVOLUME * port->volumeModifier;
auto& mixed = port->mixedAudio;
std::fill(mixed.begin(), mixed.end(), 0);

for (int i = 0; i < port->channelsNum; i++) {
for (int i = 0; i < port->audioSpec.channels; i++) {
auto ch_offset = i * bytesize_1ch;
SDL_MixAudioFormat(mixed.data() + ch_offset, ((const uint8_t*)ptr) + ch_offset, port->sdlFormat, bytesize_1ch,
maxVolume * ((float)port->volume[i] / AudioOut::VOLUME_0DB));
}

if (SDL_GetAudioDeviceStatus(port->device) != SDL_AUDIO_PLAYING) SDL_PauseAudioDevice(port->device, 0);

int ret = SDL_QueueAudio(port->device, mixed.data(), bytesize);
int ret = SDL_QueueAudio(port->device, mixed.data(), port->audioSpec.size);
if (ret == 0) port->queued = SDL_GetQueuedAudioSize(port->device);
if (sync) syncPort(port);

Expand All @@ -237,7 +229,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutInit(void) {
return Err::AudioOut::OUT_OF_MEMORY;
}

EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type, int32_t index, uint32_t len, uint32_t freq, uint32_t param) {
EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type, int32_t index, uint32_t numSamples, uint32_t sampleRate, uint32_t param) {
if (!audioInited) return Err::AudioOut::NOT_INIT;
LOG_USE_MODULE(libSceAudioOut);
LOG_TRACE(L"%S", __FUNCTION__);
Expand All @@ -260,8 +252,8 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type
int handle;
if (auto port = pimpl->portsOut.AcquirePort(type, &handle)) {
port->userId = userId;
port->samplesNum = len;
port->freq = freq;
port->samplesNum = numSamples;
port->sampleRate = sampleRate;
port->format = SceAudioOutParamFormat(param & 0x0000007F);

if ((param & 0x000F0000) != 0) {
Expand Down Expand Up @@ -322,6 +314,15 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type
port->volumeModifier = 0.5f;
}

SDL_AudioSpec audioSpec = {
.freq = static_cast<int>(sampleRate),
.format = port->sdlFormat,
.channels = static_cast<uint8_t>(port->channelsNum),
.samples = static_cast<uint16_t>(port->samplesNum),
.callback = nullptr,
.userdata = nullptr,
};

if (type == SceAudioOutPortType::PADSPK) {
auto& devn = (*jData)["padspeakers"][userId - 1];

Expand All @@ -344,9 +345,8 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type
port->volume[i] = AudioOut::MIXLEVEL_PADSPK_0DB;
}
} else {
SDL_AudioSpec fmt_curr;
if ((*jData)["device"] == "[default]") {
if (SDL_GetDefaultAudioInfo((char**)&dname, &fmt_curr, 0) != 0) {
if (SDL_GetDefaultAudioInfo((char**)&dname, &port->audioSpec, 0) != 0) {
LOG_ERR(L"Failed to get the default audio device, port #%d is nulled! (%S)", handle, SDL_GetError());
port->device = 0;
return handle;
Expand All @@ -362,7 +362,7 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type
} catch (const json::exception& e) {
LOG_ERR(L"Invalid audio device name: %S, falling back to default", e.what());
dname = NULL;
if (SDL_GetDefaultAudioInfo((char**)&dname, &fmt_curr, 0) != 0) {
if (SDL_GetDefaultAudioInfo((char**)&dname, &port->audioSpec, 0) != 0) {
LOG_ERR(L"Falling back to default device failed, port #%d is nulled! (%S)", handle, SDL_GetError());
port->device = 0;
return handle;
Expand All @@ -375,24 +375,15 @@ EXPORT SYSV_ABI int32_t sceAudioOutOpen(int32_t userId, SceAudioOutPortType type
}
}

SDL_AudioSpec fmt {
.freq = static_cast<int>(freq),
.format = port->sdlFormat,
.channels = static_cast<uint8_t>(port->channelsNum),
.samples = static_cast<uint16_t>(port->samplesNum),
.callback = nullptr,
.userdata = nullptr,
};

if ((port->device = SDL_OpenAudioDevice(dname, 0, &fmt, NULL, 0)) == 0) {
if ((port->device = SDL_OpenAudioDevice(dname, 0, &audioSpec, &port->audioSpec, 0)) == 0) {
LOG_ERR(L"Failed to open %S audio device: %S", getDevName(type), SDL_GetError());
// Since audio connect/disconnect event is implemented now, we can fall through there.
// The audio device will be opened automatically when available.
} else {
LOG_INFO(L"%S audio device %S opened for user #%d", getDevName(type), dname, userId);
}

port->mixedAudio.resize(port->sampleSize * port->samplesNum * port->channelsNum);
port->mixedAudio.resize(port->audioSpec.size);
port->deviceName.assign(dname);
return handle;
}
Expand Down
Loading
Loading