From b11c58f11c59e651d9b9bfe50ab4e6ad64083683 Mon Sep 17 00:00:00 2001 From: M4x1m3 Date: Wed, 22 Jul 2020 17:16:33 +0200 Subject: [PATCH] [simu] Persistant script store (and other stuff) --- Makefile | 2 +- ion/src/simulator/android/Makefile | 2 +- ion/src/simulator/android/build.gradle | 4 +- .../numworks/calculator/EpsilonActivity.java | 84 ----------- .../github/omega/simulator/OmegaActivity.java | 12 ++ ion/src/simulator/shared/main_sdl.cpp | 131 ++++++++++++++++++ 6 files changed, 147 insertions(+), 88 deletions(-) delete mode 100644 ion/src/simulator/android/src/java/com/numworks/calculator/EpsilonActivity.java diff --git a/Makefile b/Makefile index 7587d6b06..158ae9f57 100644 --- a/Makefile +++ b/Makefile @@ -178,7 +178,7 @@ cleanandcompile: .PHONY: start start: @echo "INFO Starting output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE)" - @$(Q) output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE) + @$(Q) output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE) -v .PHONY: clean_run clean_run: cleanandcompile diff --git a/ion/src/simulator/android/Makefile b/ion/src/simulator/android/Makefile index 271583307..11baacfd6 100644 --- a/ion/src/simulator/android/Makefile +++ b/ion/src/simulator/android/Makefile @@ -58,7 +58,7 @@ apk_deps += $(addprefix $(BUILD_DIR)/app/res/,mipmap/ic_launcher.png mipmap-v26/ $(BUILD_DIR)/%.apk: $(apk_deps) $(call rule_label,GRADLE) - $(Q) ANDROID_HOME=$(ANDROID_HOME) EPSILON_VERSION=$(EPSILON_VERSION) BUILD_DIR=$(BUILD_DIR) EPSILON_VARIANT=$* ion/src/simulator/android/gradlew -b ion/src/simulator/android/build.gradle assembleRelease + $(Q) ANDROID_HOME=$(ANDROID_HOME) EPSILON_VERSION=$(EPSILON_VERSION) OMEGA_VERSION=$(OMEGA_VERSION) BUILD_DIR=$(BUILD_DIR) EPSILON_VARIANT=$* ion/src/simulator/android/gradlew -b ion/src/simulator/android/build.gradle assembleRelease $(Q) cp $(BUILD_DIR)/app/outputs/apk/release/android-release*.apk $@ endif diff --git a/ion/src/simulator/android/build.gradle b/ion/src/simulator/android/build.gradle index 33184cff6..a620bb823 100644 --- a/ion/src/simulator/android/build.gradle +++ b/ion/src/simulator/android/build.gradle @@ -37,9 +37,9 @@ android { applicationId "io.github.omega.simulator" minSdkVersion 16 targetSdkVersion 28 - def (major, minor, patch) = System.getenv('EPSILON_VERSION').toLowerCase().tokenize('.').collect{it.toInteger()} + def (major, minor, patch) = System.getenv('OMEGA_VERSION').toLowerCase().tokenize('.').collect{it.toInteger()} versionCode major*1000000 + minor*10000 + patch * 100 - versionName System.getenv('EPSILON_VERSION') + versionName System.getenv('OMEGA_VERSION') } signingConfigs { environment { diff --git a/ion/src/simulator/android/src/java/com/numworks/calculator/EpsilonActivity.java b/ion/src/simulator/android/src/java/com/numworks/calculator/EpsilonActivity.java deleted file mode 100644 index ef056c93e..000000000 --- a/ion/src/simulator/android/src/java/com/numworks/calculator/EpsilonActivity.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.numworks.calculator; - -import java.util.Locale; - -import android.app.Activity; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.Bundle; -import android.util.Log; - -import com.google.android.gms.analytics.GoogleAnalytics; -import com.google.android.gms.analytics.Tracker; -import com.google.android.gms.analytics.HitBuilders; - -import org.libsdl.app.SDLActivity; - -public class EpsilonActivity extends SDLActivity { - private static GoogleAnalytics sAnalytics; - private static Tracker sTracker; - - protected String[] getLibraries() { - return new String[] { - "epsilon" - }; - } - - @Override - protected String[] getArguments() { - Locale currentLocale = getResources().getConfiguration().locale; - String[] arguments = {"--language", currentLocale.getLanguage()}; - return arguments; - } - - public Bitmap retrieveBitmapAsset(String identifier) { - Bitmap bitmap = null; - try { - bitmap = BitmapFactory.decodeStream( - this.getResources().getAssets().open(identifier) - ); - } catch (Exception e) { - Log.w("LoadTexture", "Coundn't load a file:" + identifier); - } - return bitmap; - } - - public void telemetryInit() { - sAnalytics = GoogleAnalytics.getInstance(this); - sTracker = sAnalytics.newTracker("UA-93775823-3"); - } - - public void telemetryScreen(String screenName) { - sTracker.setScreenName(screenName); - sTracker.send(new HitBuilders.ScreenViewBuilder().build()); - } - - public void telemetryEvent(String category, String action, String label) { - sTracker.send(new HitBuilders.EventBuilder() - .setCategory(category) - .setAction(action) - .setLabel(label) - .build() - ); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - /* This is done to hide the status bar and the bottom navigation buttons. - * - * In SDLActivity::onCreate, setWindowStyle(false) is called, which means - * the fullscreen mode is put to false. We call again the method here with - * true, in order not to modify the external sources. - * - * TODO: This was not needed for v12 of Epsilon, even though - * setWindowStyle(false) was already called in SDLActivity::onCreate. Find - * out why and make a proper fix? */ - super.onCreate(savedInstanceState); - if (!mBrokenLibraries) { - /* If mBrokenLibraries, SDL is not initialized by onCreate in - * SDLActivity.java. */ - setWindowStyle(true); - } - } - -} diff --git a/ion/src/simulator/android/src/java/io/github/omega/simulator/OmegaActivity.java b/ion/src/simulator/android/src/java/io/github/omega/simulator/OmegaActivity.java index c0b2b8962..e0613a692 100644 --- a/ion/src/simulator/android/src/java/io/github/omega/simulator/OmegaActivity.java +++ b/ion/src/simulator/android/src/java/io/github/omega/simulator/OmegaActivity.java @@ -40,9 +40,21 @@ public class OmegaActivity extends SDLActivity { return bitmap; } + @Override protected void onCreate(Bundle savedInstanceState) { + /* This is done to hide the status bar and the bottom navigation buttons. + * + * In SDLActivity::onCreate, setWindowStyle(false) is called, which means + * the fullscreen mode is put to false. We call again the method here with + * true, in order not to modify the external sources. + * + * TODO: This was not needed for v12 of Epsilon, even though + * setWindowStyle(false) was already called in SDLActivity::onCreate. Find + * out why and make a proper fix? */ super.onCreate(savedInstanceState); if (!mBrokenLibraries) { + /* If mBrokenLibraries, SDL is not initialized by onCreate in + * SDLActivity.java. */ setWindowStyle(true); } } diff --git a/ion/src/simulator/shared/main_sdl.cpp b/ion/src/simulator/shared/main_sdl.cpp index c5155c8bd..488e7e680 100644 --- a/ion/src/simulator/shared/main_sdl.cpp +++ b/ion/src/simulator/shared/main_sdl.cpp @@ -10,12 +10,20 @@ #include #include #include +#include #include #include +#include static bool argument_screen_only = false; static bool argument_fullscreen = false; static bool argument_unresizable = false; +static bool argument_volatile = false; +static char* pref_path = nullptr; +static char* file_buffer = nullptr; + +static void loadPython(std::vector* arguments); +static void savePython(); void Ion::Timing::msleep(uint32_t ms) { SDL_Delay(ms); @@ -26,10 +34,21 @@ void print_help(char * program_name) { printf("Options:\n"); printf(" -f, --fullscreen Starts the emulator in fullscreen\n"); printf(" -s, --screen-only Disable the keyboard.\n"); + printf(" -v, --volatile Disable saving and loading python scripts from file.\n"); printf(" -u, --unresizable Disable resizing the window.\n"); printf(" -h, --help Show this help menu.\n"); } +int event_filter(void* userdata, SDL_Event* e) { + if (e->type == SDL_APP_TERMINATING || e->type == SDL_APP_WILLENTERBACKGROUND) { + savePython(); + } + + return 1; +} + + + int main(int argc, char * argv[]) { std::vector arguments(argv, argv + argc); @@ -43,6 +62,8 @@ int main(int argc, char * argv[]) { argument_fullscreen = true; } else if(strcmp(argv[i], "-u")==0 || strcmp(argv[i], "--unresizable")==0) { argument_unresizable = true; + } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i], "--volatile")==0) { + argument_volatile = true; } } @@ -57,13 +78,123 @@ int main(int argc, char * argv[]) { arguments.push_back(language); } + if (!argument_volatile) { + loadPython(&arguments); + SDL_SetEventFilter(event_filter, NULL); + } + Ion::Simulator::Main::init(); + ion_main(arguments.size(), &arguments[0]); + + if (!argument_volatile) { + savePython(); + } + Ion::Simulator::Main::quit(); + if (file_buffer != nullptr) + SDL_free(file_buffer); + if (pref_path != nullptr) + SDL_free(pref_path); + return 0; } +static void loadPython(std::vector* arguments) { + pref_path = SDL_GetPrefPath("io.github.omega", "omega-simulator"); + std::string path(pref_path); + printf("Loading from %s\n", (path + "python.dat").c_str()); + + SDL_RWops* save_file = SDL_RWFromFile((path + "python.dat").c_str(), "rb"); + + if (save_file != NULL) { + // Calculate checksum + uint64_t checksum = 0; + uint64_t calc_checksum = 0; + + SDL_RWread(save_file, &checksum, sizeof(uint64_t), 1); + + uint8_t curr_check = 0; + + while(SDL_RWread(save_file, &curr_check, sizeof(uint8_t), 1)) { + calc_checksum += curr_check; + } + + if (checksum == calc_checksum) { + arguments->push_back("--code-wipe"); + arguments->push_back("true"); + + uint64_t length = SDL_RWseek(save_file, 0, RW_SEEK_END) - sizeof(uint64_t); + + SDL_RWseek(save_file, sizeof(uint64_t), RW_SEEK_SET); + + file_buffer = (char*) SDL_malloc(length); + SDL_RWread(save_file, file_buffer, length, 1); + + // printf("Length: %ld\n", length); + size_t i = 0; + while(i < length) { + uint16_t size = *(uint16_t*)(file_buffer + i); + arguments->push_back("--code-script"); + arguments->push_back((char*)(file_buffer + i + sizeof(uint16_t))); + // printf("Loaded size=%d i=%ld, %s\n", size, i+size, (char*)(file_buffer + i + sizeof(uint16_t))); + i += size + sizeof(uint16_t); + } + } + } +} + +static void savePython() { + std::string path(pref_path); + + printf("Saving to %s\n", (path + "python.dat").c_str()); + + SDL_RWops* save_file = SDL_RWFromFile((path + "python.dat").c_str(), "wb+"); + + if (save_file != NULL) { + + // Placeholder for checksum + uint64_t checksum = 0; + SDL_RWwrite(save_file, &checksum, sizeof(uint64_t), 1); + + uint16_t num = (uint16_t) Ion::Storage::sharedStorage()->numberOfRecordsWithExtension("py"); + + // Write all checksums + for(uint16_t i = 0; i < num; i++) { + Ion::Storage::Record record = Ion::Storage::sharedStorage()->recordWithExtensionAtIndex("py", i); + + const char* record_name = record.fullName(); + uint16_t record_name_len = strlen(record_name); + + Ion::Storage::Record::Data record_data = record.value(); + + uint16_t total_length = record_name_len + record_data.size; + + SDL_RWwrite(save_file, &total_length, sizeof(uint16_t), 1); + + SDL_RWwrite(save_file, record_name, record_name_len, 1); + SDL_RWwrite(save_file, ":", 1, 1); + // Remove import status, keep trailing \x00 + SDL_RWwrite(save_file, ((char*)record_data.buffer + 1), record_data.size - 1, 1); + } + + // Compute and write checksum + + SDL_RWseek(save_file, sizeof(uint64_t), RW_SEEK_SET); + uint8_t curr_check = 0; + + while(SDL_RWread(save_file, &curr_check, sizeof(uint8_t), 1)) { + checksum += curr_check; + } + + SDL_RWseek(save_file, 0, RW_SEEK_SET); + SDL_RWwrite(save_file, &checksum, sizeof(uint64_t), 1); + + SDL_RWclose(save_file); + } +} + namespace Ion { namespace Simulator { namespace Main {