mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-17 22:49:17 +01:00
c005d7df74
What was added: * Framebuffer * NativeActivity * NV Services * IOCTL Handler * NV Devices: * * /dev/nvmap - 0xC0080101, 0xC0080103, 0xC0200104, 0xC0180105, 0xC00C0109, 0xC008010E * * /dev/nvhost-as-gpu * * /dev/nvhost-channel - 0x40044801, 0xC0104809, 0xC010480B, 0xC018480C, 0x4004480D, 0xC020481A, 0x40084714 * * /dev/nvhost-ctrl * * /dev/nvhost-ctrl-gpu - 0x80044701, 0x80284702, 0xC0184706, 0xC0B04705, 0x80084714 * SVCs: * * SetMemoryAttribute * * CreateTransferMemory * * ResetSignal * * GetSystemTick * Addition of Compact Logger What was fixed: * SVCs: * * SetHeapSize * * SetMemoryAttribute * * QueryMemory * A release build would not set CMAKE_BUILD_TYPE to "RELEASE" * The logger code was simplified
116 lines
4.6 KiB
C++
116 lines
4.6 KiB
C++
#include "skyline/common.h"
|
|
#include "skyline/os.h"
|
|
#include <unistd.h>
|
|
#include <jni.h>
|
|
#include <android/native_window_jni.h>
|
|
#include <android/native_activity.h>
|
|
#include <csignal>
|
|
|
|
bool Halt{};
|
|
uint faultCount{};
|
|
ANativeActivity *Activity{};
|
|
ANativeWindow *Window{};
|
|
AInputQueue *Queue{};
|
|
std::thread *uiThread{};
|
|
|
|
void GameThread(const std::string &prefPath, const std::string &logPath, const std::string &romPath) {
|
|
while (!Window)
|
|
sched_yield();
|
|
setpriority(PRIO_PROCESS, static_cast<id_t>(getpid()), skyline::constant::PriorityAn.second);
|
|
auto settings = std::make_shared<skyline::Settings>(prefPath);
|
|
auto logger = std::make_shared<skyline::Logger>(logPath, static_cast<skyline::Logger::LogLevel>(std::stoi(settings->GetString("log_level"))));
|
|
//settings->List(logger); // (Uncomment when you want to print out all settings strings)
|
|
auto start = std::chrono::steady_clock::now();
|
|
try {
|
|
skyline::kernel::OS os(logger, settings, Window);
|
|
logger->Info("Launching ROM {}", romPath);
|
|
os.Execute(romPath);
|
|
logger->Info("Emulation has ended");
|
|
} catch (std::exception &e) {
|
|
logger->Error(e.what());
|
|
} catch (...) {
|
|
logger->Error("An unknown exception has occurred");
|
|
}
|
|
auto end = std::chrono::steady_clock::now();
|
|
logger->Info("Done in: {} ms", (std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()));
|
|
Window = nullptr;
|
|
Halt = true;
|
|
}
|
|
|
|
void UIThread(const std::string &prefPath, const std::string &logPath, const std::string &romPath) {
|
|
while (!Queue)
|
|
sched_yield();
|
|
std::thread gameThread(GameThread, std::string(prefPath), std::string(logPath), std::string(romPath));
|
|
AInputEvent *event{};
|
|
while (!Halt) {
|
|
if (AInputQueue_getEvent(Queue, &event) >= -1) {
|
|
if (AKeyEvent_getKeyCode(event) == AKEYCODE_BACK)
|
|
Halt = true;
|
|
AInputQueue_finishEvent(Queue, event, true);
|
|
}
|
|
}
|
|
Queue = nullptr;
|
|
gameThread.join();
|
|
Halt = false;
|
|
ANativeActivity_finish(Activity);
|
|
}
|
|
|
|
void onNativeWindowCreated(ANativeActivity *activity, ANativeWindow *window) {
|
|
Window = window;
|
|
}
|
|
|
|
void onInputQueueCreated(ANativeActivity *activity, AInputQueue *queue) {
|
|
Queue = queue;
|
|
}
|
|
|
|
void onNativeWindowDestroyed(ANativeActivity *activity, ANativeWindow *window) {
|
|
Halt = true;
|
|
while (Window)
|
|
sched_yield();
|
|
}
|
|
|
|
void onInputQueueDestroyed(ANativeActivity *activity, AInputQueue *queue) {
|
|
Halt = true;
|
|
while (Queue)
|
|
sched_yield();
|
|
}
|
|
|
|
void signalHandler(int signal) {
|
|
syslog(LOG_ERR, "Halting program due to signal: %s", strsignal(signal));
|
|
if (faultCount > 2)
|
|
pthread_kill(uiThread->native_handle(), SIGKILL);
|
|
else
|
|
ANativeActivity_finish(Activity);
|
|
faultCount++;
|
|
}
|
|
|
|
JNIEXPORT void ANativeActivity_onCreate(ANativeActivity *activity, void *savedState, size_t savedStateSize) {
|
|
Activity = activity;
|
|
Halt = false;
|
|
faultCount = 0;
|
|
JNIEnv *env = activity->env;
|
|
jobject intent = env->CallObjectMethod(activity->clazz, env->GetMethodID(env->GetObjectClass(activity->clazz), "getIntent", "()Landroid/content/Intent;"));
|
|
jclass icl = env->GetObjectClass(intent);
|
|
jmethodID gse = env->GetMethodID(icl, "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
|
|
auto jsRom = reinterpret_cast<jstring>(env->CallObjectMethod(intent, gse, env->NewStringUTF("rom")));
|
|
auto jsPrefs = reinterpret_cast<jstring>(env->CallObjectMethod(intent, gse, env->NewStringUTF("prefs")));
|
|
auto jsLog = reinterpret_cast<jstring>(env->CallObjectMethod(intent, gse, env->NewStringUTF("log")));
|
|
const char *romPath = env->GetStringUTFChars(jsRom, nullptr);
|
|
const char *prefPath = env->GetStringUTFChars(jsPrefs, nullptr);
|
|
const char *logPath = env->GetStringUTFChars(jsLog, nullptr);
|
|
std::signal(SIGTERM, signalHandler);
|
|
std::signal(SIGSEGV, signalHandler);
|
|
std::signal(SIGINT, signalHandler);
|
|
std::signal(SIGILL, signalHandler);
|
|
std::signal(SIGABRT, signalHandler);
|
|
std::signal(SIGFPE, signalHandler);
|
|
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
|
|
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
|
|
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
|
|
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
|
|
uiThread = new std::thread(UIThread, std::string(prefPath), std::string(logPath), std::string(romPath));
|
|
env->ReleaseStringUTFChars(jsRom, romPath);
|
|
env->ReleaseStringUTFChars(jsPrefs, prefPath);
|
|
env->ReleaseStringUTFChars(jsLog, logPath);
|
|
}
|