mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[simu] Persistant script store (and other stuff)
This commit is contained in:
2
Makefile
2
Makefile
@@ -178,7 +178,7 @@ cleanandcompile:
|
|||||||
.PHONY: start
|
.PHONY: start
|
||||||
start:
|
start:
|
||||||
@echo "INFO Starting output/$(BUILD_TYPE)/simulator/$(HOST)/epsilon.$(EXE)"
|
@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
|
.PHONY: clean_run
|
||||||
clean_run: cleanandcompile
|
clean_run: cleanandcompile
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ apk_deps += $(addprefix $(BUILD_DIR)/app/res/,mipmap/ic_launcher.png mipmap-v26/
|
|||||||
|
|
||||||
$(BUILD_DIR)/%.apk: $(apk_deps)
|
$(BUILD_DIR)/%.apk: $(apk_deps)
|
||||||
$(call rule_label,GRADLE)
|
$(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 $@
|
$(Q) cp $(BUILD_DIR)/app/outputs/apk/release/android-release*.apk $@
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ android {
|
|||||||
applicationId "io.github.omega.simulator"
|
applicationId "io.github.omega.simulator"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 28
|
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
|
versionCode major*1000000 + minor*10000 + patch * 100
|
||||||
versionName System.getenv('EPSILON_VERSION')
|
versionName System.getenv('OMEGA_VERSION')
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
environment {
|
environment {
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -40,9 +40,21 @@ public class OmegaActivity extends SDLActivity {
|
|||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
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);
|
super.onCreate(savedInstanceState);
|
||||||
if (!mBrokenLibraries) {
|
if (!mBrokenLibraries) {
|
||||||
|
/* If mBrokenLibraries, SDL is not initialized by onCreate in
|
||||||
|
* SDLActivity.java. */
|
||||||
setWindowStyle(true);
|
setWindowStyle(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,20 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ion/timing.h>
|
#include <ion/timing.h>
|
||||||
#include <ion/events.h>
|
#include <ion/events.h>
|
||||||
|
#include <ion/storage.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
static bool argument_screen_only = false;
|
static bool argument_screen_only = false;
|
||||||
static bool argument_fullscreen = false;
|
static bool argument_fullscreen = false;
|
||||||
static bool argument_unresizable = 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<const char *>* arguments);
|
||||||
|
static void savePython();
|
||||||
|
|
||||||
void Ion::Timing::msleep(uint32_t ms) {
|
void Ion::Timing::msleep(uint32_t ms) {
|
||||||
SDL_Delay(ms);
|
SDL_Delay(ms);
|
||||||
@@ -26,10 +34,21 @@ void print_help(char * program_name) {
|
|||||||
printf("Options:\n");
|
printf("Options:\n");
|
||||||
printf(" -f, --fullscreen Starts the emulator in fullscreen\n");
|
printf(" -f, --fullscreen Starts the emulator in fullscreen\n");
|
||||||
printf(" -s, --screen-only Disable the keyboard.\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(" -u, --unresizable Disable resizing the window.\n");
|
||||||
printf(" -h, --help Show this help menu.\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[]) {
|
int main(int argc, char * argv[]) {
|
||||||
std::vector<const char *> arguments(argv, argv + argc);
|
std::vector<const char *> arguments(argv, argv + argc);
|
||||||
|
|
||||||
@@ -43,6 +62,8 @@ int main(int argc, char * argv[]) {
|
|||||||
argument_fullscreen = true;
|
argument_fullscreen = true;
|
||||||
} else if(strcmp(argv[i], "-u")==0 || strcmp(argv[i], "--unresizable")==0) {
|
} else if(strcmp(argv[i], "-u")==0 || strcmp(argv[i], "--unresizable")==0) {
|
||||||
argument_unresizable = true;
|
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);
|
arguments.push_back(language);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!argument_volatile) {
|
||||||
|
loadPython(&arguments);
|
||||||
|
SDL_SetEventFilter(event_filter, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
Ion::Simulator::Main::init();
|
Ion::Simulator::Main::init();
|
||||||
|
|
||||||
ion_main(arguments.size(), &arguments[0]);
|
ion_main(arguments.size(), &arguments[0]);
|
||||||
|
|
||||||
|
if (!argument_volatile) {
|
||||||
|
savePython();
|
||||||
|
}
|
||||||
|
|
||||||
Ion::Simulator::Main::quit();
|
Ion::Simulator::Main::quit();
|
||||||
|
|
||||||
|
if (file_buffer != nullptr)
|
||||||
|
SDL_free(file_buffer);
|
||||||
|
if (pref_path != nullptr)
|
||||||
|
SDL_free(pref_path);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void loadPython(std::vector<const char *>* 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 Ion {
|
||||||
namespace Simulator {
|
namespace Simulator {
|
||||||
namespace Main {
|
namespace Main {
|
||||||
|
|||||||
Reference in New Issue
Block a user