mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-12-05 23:03:46 +00:00
ea9ce0fba7
The savedata for each game is stored in /savedata/<ProgramID> for NCCH files. ELF files and 3DSX files use the folder 0 because they have no ID information Got rid of the code duplication in File and Directory Files that deal with the host machine's file system now live in DiskFile, similarly for directories and DiskDirectory and archives with DiskArchive. FS_U: Use the correct error code when a file wasn't found
115 lines
2.7 KiB
C++
115 lines
2.7 KiB
C++
// Copyright 2014 Citra Emulator Project / PPSSPP Project
|
|
// Licensed under GPLv2
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <algorithm>
|
|
|
|
#include "common/common.h"
|
|
|
|
#include "core/core.h"
|
|
#include "core/hle/kernel/kernel.h"
|
|
#include "core/hle/kernel/thread.h"
|
|
|
|
namespace Kernel {
|
|
|
|
Handle g_main_thread = 0;
|
|
ObjectPool g_object_pool;
|
|
u64 g_program_id = 0;
|
|
|
|
ObjectPool::ObjectPool() {
|
|
next_id = INITIAL_NEXT_ID;
|
|
}
|
|
|
|
Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) {
|
|
if (range_top > MAX_COUNT) {
|
|
range_top = MAX_COUNT;
|
|
}
|
|
if (next_id >= range_bottom && next_id < range_top) {
|
|
range_bottom = next_id++;
|
|
}
|
|
for (int i = range_bottom; i < range_top; i++) {
|
|
if (!occupied[i]) {
|
|
occupied[i] = true;
|
|
pool[i] = obj;
|
|
pool[i]->handle = i + HANDLE_OFFSET;
|
|
return i + HANDLE_OFFSET;
|
|
}
|
|
}
|
|
LOG_ERROR(Kernel, "Unable to allocate kernel object, too many objects slots in use.");
|
|
return 0;
|
|
}
|
|
|
|
bool ObjectPool::IsValid(Handle handle) const {
|
|
int index = handle - HANDLE_OFFSET;
|
|
if (index < 0)
|
|
return false;
|
|
if (index >= MAX_COUNT)
|
|
return false;
|
|
|
|
return occupied[index];
|
|
}
|
|
|
|
void ObjectPool::Clear() {
|
|
for (int i = 0; i < MAX_COUNT; i++) {
|
|
//brutally clear everything, no validation
|
|
if (occupied[i])
|
|
delete pool[i];
|
|
occupied[i] = false;
|
|
}
|
|
pool.fill(nullptr);
|
|
next_id = INITIAL_NEXT_ID;
|
|
}
|
|
|
|
Object* &ObjectPool::operator [](Handle handle)
|
|
{
|
|
_dbg_assert_msg_(Kernel, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ");
|
|
return pool[handle - HANDLE_OFFSET];
|
|
}
|
|
|
|
void ObjectPool::List() {
|
|
for (int i = 0; i < MAX_COUNT; i++) {
|
|
if (occupied[i]) {
|
|
if (pool[i]) {
|
|
LOG_DEBUG(Kernel, "KO %i: %s \"%s\"", i + HANDLE_OFFSET, pool[i]->GetTypeName().c_str(),
|
|
pool[i]->GetName().c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int ObjectPool::GetCount() const {
|
|
return std::count(occupied.begin(), occupied.end(), true);
|
|
}
|
|
|
|
Object* ObjectPool::CreateByIDType(int type) {
|
|
LOG_ERROR(Kernel, "Unimplemented: %d.", type);
|
|
return nullptr;
|
|
}
|
|
|
|
/// Initialize the kernel
|
|
void Init() {
|
|
Kernel::ThreadingInit();
|
|
}
|
|
|
|
/// Shutdown the kernel
|
|
void Shutdown() {
|
|
Kernel::ThreadingShutdown();
|
|
|
|
g_object_pool.Clear(); // Free all kernel objects
|
|
}
|
|
|
|
/**
|
|
* Loads executable stored at specified address
|
|
* @entry_point Entry point in memory of loaded executable
|
|
* @return True on success, otherwise false
|
|
*/
|
|
bool LoadExec(u32 entry_point) {
|
|
Core::g_app_core->SetPC(entry_point);
|
|
|
|
// 0x30 is the typical main thread priority I've seen used so far
|
|
g_main_thread = Kernel::SetupMainThread(0x30);
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace
|