Skip to content

Commit

Permalink
Milestone 1 - Processes & Threads
Browse files Browse the repository at this point in the history
Reworks the API a fair bit and adds documentation to almost everything.
  • Loading branch information
PixelyIon committed Sep 24, 2019
1 parent 62cb561 commit 9e1e06c
Show file tree
Hide file tree
Showing 43 changed files with 2,022 additions and 681 deletions.
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,11 @@ fabric.properties
.idea/caches/build_file_checksums.ser

# Android Studio captures folder
captures/
captures/

# VSCode
.vscode/

# Android Studio
.cxx/

110 changes: 110 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/discord.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
LightSwitch, a Nintendo Switch emulator for Android
Skyline, a Nintendo Switch emulator for Android
=============

LightSwitch is an experimental Nintendo Switch emulator for Android phones, licensed under GPLv3. Please refer to the [license file](https://github.com/lightswitch-emu/lightswitch/blob/master/LICENSE) for more information. It currently does not run any games, nor Homebrew. It has no graphical output as of now.
Skyline is an experimental Nintendo Switch emulator for Android phones, licensed under GPLv3. Please refer to the [license file](https://github.com/lightswitch-emu/lightswitch/blob/master/LICENSE) for more information. It currently does not run any games, nor Homebrew. It has no graphical output as of now.

### Contact
You can contact the core developers of LightSwitch at our [Discord](https://discord.gg/XnbXNQM). If you have any questions, feel free to ask.
You can contact the core developers of Skyline at our [Discord](https://discord.gg/XnbXNQM). If you have any questions, feel free to ask.
18 changes: 11 additions & 7 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ cmake_minimum_required(VERSION 3.8)
project(Lightswitch VERSION 1 LANGUAGES CXX)
set_property(GLOBAL PROPERTY CMAKE_CXX_STANDARD 17 PROPERTY CMAKE_CXX_STANDARD_REQUIRED TRUE)

set(BUILD_TESTS FALSE)
set(BUILD_TESTING OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -flto=full")
add_subdirectory("libraries/tinyxml2")
add_subdirectory("libraries/fmt")

Expand All @@ -14,13 +16,15 @@ include_directories(${source_DIR})

add_library(lightswitch SHARED
${source_DIR}/lightswitch.cpp
${source_DIR}/switch/os/os.cpp
${source_DIR}/switch/os/ipc.cpp
${source_DIR}/switch/os/svc.cpp
${source_DIR}/switch/hw/cpu.cpp
${source_DIR}/switch/hw/memory.cpp
${source_DIR}/switch/common.cpp
${source_DIR}/switch/nce.cpp
${source_DIR}/switch/os.cpp
${source_DIR}/switch/loader/nro.cpp
${source_DIR}/switch/kernel/ipc.cpp
${source_DIR}/switch/kernel/svc.cpp
${source_DIR}/switch/kernel/service.cpp
${source_DIR}/switch/kernel/types/KProcess.cpp
${source_DIR}/switch/kernel/types/KThread.cpp
)
target_link_libraries(lightswitch fmt tinyxml2)
target_link_libraries(lightswitch fmt tinyxml2 android)
target_compile_options(lightswitch PRIVATE -Wno-c++17-extensions)
4 changes: 1 addition & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ android {
buildToolsVersion "29.0.0"
defaultConfig {
applicationId "lightswitch.emu"
minSdkVersion 24
minSdkVersion 26
targetSdkVersion 29
versionCode 1
versionName "1.0"
Expand All @@ -16,11 +16,9 @@ android {
buildTypes {
release {
minifyEnabled true
useProguard false
}
debug {
minifyEnabled false
useProguard false
}
}
externalNativeBuild {
Expand Down
37 changes: 17 additions & 20 deletions app/src/main/cpp/lightswitch.cpp
Original file line number Diff line number Diff line change
@@ -1,46 +1,43 @@
#include <jni.h>
#include <string>
#include <pthread.h>
#include <csignal>
#include <string>
#include <thread>
#include <pthread.h>
#include "switch/device.h"
#include "switch/common.h"
#include "switch/os.h"

std::thread *emu_thread;
bool halt = false;

void thread_main(std::string rom_path, std::string pref_path, std::string log_path) {
auto log = std::make_shared<lightSwitch::Logger>(log_path);
log->write(lightSwitch::Logger::INFO, "Launching ROM {0}", rom_path);

auto settings = std::make_shared<lightSwitch::Settings>(pref_path);
try {
lightSwitch::device device(log, settings);
device.run(rom_path);

log->write(lightSwitch::Logger::INFO, "Emulation has ended.");
lightSwitch::kernel::OS os(log, settings);
log->Write(lightSwitch::Logger::INFO, "Launching ROM {}", rom_path);
os.Execute(rom_path);
log->Write(lightSwitch::Logger::INFO, "Emulation has ended");
} catch (std::exception &e) {
log->write(lightSwitch::Logger::ERROR, e.what());
log->Write(lightSwitch::Logger::ERROR, e.what());
} catch (...) {
log->write(lightSwitch::Logger::ERROR, "An unknown exception has occurred.");
log->Write(lightSwitch::Logger::ERROR, "An unknown exception has occurred");
}
}

extern "C"
JNIEXPORT void JNICALL
Java_emu_lightswitch_MainActivity_loadFile(JNIEnv *env, jobject instance, jstring rom_path_, jstring pref_path_, jstring log_path_) {
const char *rom_path = env->GetStringUTFChars(rom_path_, 0);
const char *pref_path = env->GetStringUTFChars(pref_path_, 0);
const char *log_path = env->GetStringUTFChars(log_path_, 0);
extern "C" JNIEXPORT void JNICALL Java_emu_lightswitch_MainActivity_loadFile(JNIEnv *env, jobject instance, jstring rom_path_, jstring pref_path_, jstring log_path_) {
const char *rom_path = env->GetStringUTFChars(rom_path_, nullptr);
const char *pref_path = env->GetStringUTFChars(pref_path_, nullptr);
const char *log_path = env->GetStringUTFChars(log_path_, nullptr);

if (emu_thread) {
halt=true; // This'll cause execution to stop after the next breakpoint
halt = true; // This'll cause execution to stop after the next breakpoint
emu_thread->join();
}
// Running on UI thread is not a good idea, any crashes and such will be propagated

// Running on UI thread is not a good idea as the UI will remain unresponsive
emu_thread = new std::thread(thread_main, std::string(rom_path, strlen(rom_path)), std::string(pref_path, strlen(pref_path)), std::string(log_path, strlen(log_path)));

env->ReleaseStringUTFChars(rom_path_, rom_path);
env->ReleaseStringUTFChars(pref_path_, pref_path);
env->ReleaseStringUTFChars(log_path_, log_path);
}
}
58 changes: 41 additions & 17 deletions app/src/main/cpp/switch/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,36 @@
#include <syslog.h>

namespace lightSwitch {
// Settings
namespace memory {
Permission::Permission() {
r = 0;
w = 0;
x = 0;
}

Permission::Permission(bool read, bool write, bool execute) {
r = read;
w = write;
x = execute;
}

bool Permission::operator==(const Permission &rhs) const { return (this->r == rhs.r && this->w == rhs.w && this->x == rhs.x); }

bool Permission::operator!=(const Permission &rhs) const { return !operator==(rhs); }

int Permission::get() const {
int perm = 0;
if (r) perm |= PROT_READ;
if (w) perm |= PROT_WRITE;
if (x) perm |= PROT_EXEC;
return perm;
}
}

Settings::Settings(std::string pref_xml) {
tinyxml2::XMLDocument pref;
if (pref.LoadFile(pref_xml.c_str())) {
syslog(LOG_ERR, "TinyXML2 Error: %s", pref.ErrorStr());
throw pref.ErrorID();
}
if (pref.LoadFile(pref_xml.c_str()))
throw exception("TinyXML2 Error: " + std::string(pref.ErrorStr()));
tinyxml2::XMLElement *elem = pref.LastChild()->FirstChild()->ToElement();
while (elem) {
switch (elem->Value()[0]) {
Expand Down Expand Up @@ -55,26 +78,27 @@ namespace lightSwitch {
}
}

// Logger
Logger::Logger(std::string log_path) {
Logger::Logger(const std::string & log_path) {
log_file.open(log_path, std::ios::app);
write_header("Logging started");
WriteHeader("Logging started");
}

Logger::~Logger() {
write_header("Logging ended");
WriteHeader("Logging ended");
}

void Logger::write(Logger::LogLevel level, std::string str) {
if (level == DEBUG && debug_build)
return;
syslog(level_syslog[level], "%s", str.c_str());
log_file << "1|" << level_str[level] << "|" << str << "\n";
void Logger::WriteHeader(const std::string& str) {
syslog(LOG_ALERT, "%s", str.c_str());
log_file << "0|" << str << "\n";
log_file.flush();
}

void Logger::write_header(std::string str) {
log_file << "0|" << str << "\n";
void Logger::Write(const LogLevel level, const std::string& str) {
#ifdef NDEBUG
if (level == DEBUG) return;
#endif
syslog(level_syslog[level], "%s", str.c_str());
log_file << "1|" << level_str[level] << "|" << str << "\n";
log_file.flush();
}
}
}
Loading

0 comments on commit 9e1e06c

Please sign in to comment.