diff --git a/game/android_api.cpp b/game/android_api.cpp index 8f33405..bc9bce5 100755 --- a/game/android_api.cpp +++ b/game/android_api.cpp @@ -2,9 +2,55 @@ #include "main_code.h" +JavaVM* localJavaVirtualMachine = 0; + +JNIEXPORT void JNICALL Java_fishrungames_doublehitballs_JniWrapper_SetJavaVM(JNIEnv * env, jobject obj) +{ + env->GetJavaVM(&localJavaVirtualMachine); +} + JNIEXPORT void JNICALL Java_fishrungames_doublehitballs_JniWrapper_Init(JNIEnv * env, jobject obj, jint width, jint height) { JniInitApp(width, height, width, height); -} +} +std::stringstream LoadFileFromAndroid(const std::string& fileName) +{ + *Console << "LoadFileFromAndroid called \n"; + JNIEnv* jEnv; + localJavaVirtualMachine->GetEnv((void**)&jEnv, JNI_VERSION_1_4); + + jclass jniWrapper = jEnv->FindClass("fishrungames/doublehitballs/JniWrapper"); + + jstring jFileName = jEnv->NewStringUTF(fileName.c_str()); + + jmethodID jLoadFile = jEnv->GetStaticMethodID(jniWrapper, "LoadFile", "(Ljava/lang/String;)Ljava/lang/String;"); + + jstring jFileContent = (jstring)jEnv->CallStaticObjectMethod(jniWrapper, jLoadFile, jFileName); + + jboolean jCopy = false; + std::stringstream ss; + ss << jEnv->GetStringUTFChars(jFileContent, &jCopy); + + *Console << ss.str(); + + return ss; +} + +void SaveFileToAndroid(const std::string& fileName, const std::string& fileContent) +{ + *Console << "SaveFileToAndroid called \n"; + + JNIEnv* jEnv; + localJavaVirtualMachine->GetEnv((void**)&jEnv, JNI_VERSION_1_4); + + jclass jniWrapper = jEnv->FindClass("fishrungames/doublehitballs/JniWrapper"); + + jstring jFileName = jEnv->NewStringUTF(fileName.c_str()); + jstring jFileContent = jEnv->NewStringUTF(fileContent.c_str()); + + jmethodID jSaveFile = jEnv->GetStaticMethodID(jniWrapper, "SaveFile", "(Ljava/lang/String;Ljava/lang/String;)V"); + + jEnv->CallStaticVoidMethod(jniWrapper, jSaveFile, jFileName, jFileContent); +} \ No newline at end of file diff --git a/game/android_api.h b/game/android_api.h old mode 100644 new mode 100755 index 5e6f4c3..f380003 --- a/game/android_api.h +++ b/game/android_api.h @@ -8,6 +8,9 @@ #include #include +#include +#include + #include "boost/shared_ptr.hpp" #include "main_code.h" @@ -18,8 +21,13 @@ using namespace SE; extern "C" { + JNIEXPORT void JNICALL Java_fishrungames_doublehitballs_JniWrapper_SetJavaVM(JNIEnv * env, jobject obj); + JNIEXPORT void JNICALL Java_fishrungames_doublehitballs_JniWrapper_Init(JNIEnv * env, jobject obj, jint width, jint height); }; +std::stringstream LoadFileFromAndroid(const std::string& fileName); + +void SaveFileToAndroid(const std::string& fileName, const std::string& fileContent); #endif diff --git a/game/gamecode.cpp b/game/gamecode.cpp index 6c68ff3..b72f785 100755 --- a/game/gamecode.cpp +++ b/game/gamecode.cpp @@ -464,14 +464,14 @@ TGameLevel::TGameLevel(int levelStar, int levelIndex) TGameLevel::~TGameLevel() { } - -int TGameLevel::getStarIndex() -{ - return levelStar; -} - + +int TGameLevel::getStarIndex() +{ + return levelStar; +} + int TGameLevel::getLevelIndex() -{ +{ return levelIndex; } @@ -694,9 +694,9 @@ void TGameLevel::ReloadLevel() ReloadBlockInstansingList(Renderer->GetScreenWidth()); -} - -/* +} + +/* void TGameLevel::setBackground(const std::string& textureName) { BkgTexture = textureName; @@ -1328,7 +1328,6 @@ void TGameLevel::Update(size_t dt) } } - if (noMoreBlocks && LevelState != CONST_LEVELSTATE_FINISH_FREEZE) { Application->SaveUserProgress(levelStar, levelIndex); diff --git a/game/main_code.cpp b/game/main_code.cpp index e764ce7..65a71ca 100755 --- a/game/main_code.cpp +++ b/game/main_code.cpp @@ -5,6 +5,7 @@ #include #include "include/Engine.h" +#include "android_api.h" #include "menucode.h" @@ -55,7 +56,7 @@ TMyApplication* Application; int currentStar; -std::vector finishedLevels; +int currentLevel; void TMyApplication::LoadUserProgress() { @@ -63,17 +64,22 @@ void TMyApplication::LoadUserProgress() try { +#ifdef TARGET_WIN32 boost::property_tree::json_parser::read_json(ST::PathToResources + "levels/user_progress.json", userProgressJson); - currentStar = userProgressJson.get("currentStar"); - for (auto& index : userProgressJson.get_child("finishedLevels")) - { - finishedLevels.push_back(index.second.get_value()); - } +#endif + +#ifdef TARGET_ANDROID + auto ss = LoadFileFromAndroid("user_progress.json"); + boost::property_tree::json_parser::read_json(ss, userProgressJson); +#endif + + currentStar = userProgressJson.get("currentStar"); + currentLevel = userProgressJson.get("currentLevel"); } catch (...) { currentStar = 0; - finishedLevels.clear(); + currentLevel = 0; } } @@ -84,38 +90,45 @@ void TMyApplication::SaveUserProgress(int levelStar, int levelIndex) return; } - auto iter = std::find(finishedLevels.begin(), finishedLevels.end(), levelIndex); - if (iter != finishedLevels.end()) + if (levelIndex < currentLevel) + { + return; + } + + if (currentStar == Menu.GalaxMenu.galaxies[0].Stars.size()) { return; } - finishedLevels.push_back(levelIndex); + currentLevel += 1; - if (finishedLevels.size() == Menu.GalaxMenu.galaxies[0].Stars[currentStar].selectionMenu.gameLevels.size()) + if (currentLevel == Menu.GalaxMenu.galaxies[0].Stars[currentStar].selectionMenu.gameLevels.size()) { - finishedLevels.clear(); + currentLevel = 0; - if (currentStar < Menu.GalaxMenu.galaxies[0].Stars.size() - 1) + currentStar += 1; + + if (currentStar == Menu.GalaxMenu.galaxies[0].Stars.size()) { - currentStar += 1; + } } boost::property_tree::ptree userProgressJson; userProgressJson.put("currentStar", currentStar); + userProgressJson.put("currentLevel", currentLevel); - boost::property_tree::ptree finishedLevelsTree; - for (int index : finishedLevels) - { - boost::property_tree::ptree finishedLevel; - finishedLevel.put_value(index); - finishedLevelsTree.push_back(std::make_pair("", finishedLevel)); - } +#ifdef TARGET_WIN32 + boost::property_tree::json_parser::write_json(ST::PathToResources + "levels/user_progress.json", userProgressJson); +#endif - userProgressJson.put_child("finishedLevels", finishedLevelsTree); - boost::property_tree::json_parser::write_json(ST::PathToResources + "levels/user_progress.json", userProgressJson); +#ifdef TARGET_ANDROID + std::stringstream ss; + boost::property_tree::json_parser::write_json(ss, userProgressJson); + + SaveFileToAndroid("user_progress.json", ss.str()); +#endif } @@ -203,7 +216,6 @@ void TMyApplication::InnerInit() else { std::cout << "menu error" << std::endl; } - } void TMyApplication::InnerDeinit() @@ -607,8 +619,10 @@ void TMyApplication::LoadGalaxyUi() modal_background->onMouseUpSignal.connect( [modal_background, this](Vector2f v, int i) { - modal_background->setVisibility(false); - Menu.GalaxMenu.setTimerActivity(false); + PerformInMainThreadAsync([modal_background, this]() { + modal_background->setVisibility(false); + Menu.GalaxMenu.setTimerActivity(false); + }); }); } @@ -686,11 +700,13 @@ void TMyApplication::SetupGalaxyUi(size_t levelStar) currentLevelButton->onMouseUpSignal.connect( [this, modal_background, levelStar, levelIndex](Vector2f v, int i) { - modal_background->setVisibility(false); + PerformInMainThreadAsync([this, modal_background, levelStar, levelIndex]() { + modal_background->setVisibility(false); - std::shared_ptr lvl = this->Menu.GalaxMenu.galaxies[0].Stars[levelStar].selectionMenu.gameLevels[levelIndex]; - lvl->ReloadLevel(); - this->GoFromMenuToGame(lvl); + std::shared_ptr lvl = this->Menu.GalaxMenu.galaxies[0].Stars[levelStar].selectionMenu.gameLevels[levelIndex]; + lvl->ReloadLevel(); + this->GoFromMenuToGame(lvl); + }); }); } @@ -825,7 +841,7 @@ void TMyApplication::InnerOnMouseMove(TMouseState& mouseState) { bool TMyApplication::IsLevelOpened(int levelStar, int levelIndex) { - return levelStar <= currentStar; + return levelStar <= currentStar && levelIndex <= currentLevel; } diff --git a/proj.android-studio/app/build.gradle b/proj.android-studio/app/build.gradle index 2df2738..b64bb4a 100755 --- a/proj.android-studio/app/build.gradle +++ b/proj.android-studio/app/build.gradle @@ -6,18 +6,14 @@ android { buildToolsVersion "28.0.0" defaultConfig { applicationId "fishrungames.DoubleHitBalls" - minSdkVersion 24 + minSdkVersion 19 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { - - abiFilters "armeabi-v7a", "x86" - - arguments "-DANDROID_STL=c++_shared" - + abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86' cppFlags "-std=c++17 -frtti -fexceptions -fsigned-char -Wno-c++11-narrowing" } } @@ -38,6 +34,13 @@ android { assets.srcDirs = ['../../assets/'] } } + splits { + abi { + enable true + reset() + include 'arm64-v8a', 'armeabi-v7a', 'x86' + } + } } dependencies { diff --git a/proj.android-studio/app/src/main/java/fishrungames/doublehitballs/GL2JNIActivity.java b/proj.android-studio/app/src/main/java/fishrungames/doublehitballs/GL2JNIActivity.java index b0d7479..32f841e 100755 --- a/proj.android-studio/app/src/main/java/fishrungames/doublehitballs/GL2JNIActivity.java +++ b/proj.android-studio/app/src/main/java/fishrungames/doublehitballs/GL2JNIActivity.java @@ -36,6 +36,8 @@ public class GL2JNIActivity extends Activity EngineWrapper.LoadSalmonEngineLibrary(); EngineWrapper.SetActivityInstance(this); EngineWrapper.SetupEnviroment(); + JniWrapper.SetJavaVM(); + JniWrapper.SetContext(this); String apkFilePath = null; ApplicationInfo appInfo = null; diff --git a/proj.android-studio/app/src/main/java/fishrungames/doublehitballs/JniWrapper.java b/proj.android-studio/app/src/main/java/fishrungames/doublehitballs/JniWrapper.java index d2b6498..fd281cb 100755 --- a/proj.android-studio/app/src/main/java/fishrungames/doublehitballs/JniWrapper.java +++ b/proj.android-studio/app/src/main/java/fishrungames/doublehitballs/JniWrapper.java @@ -1,11 +1,52 @@ package fishrungames.doublehitballs; +import android.content.Context; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; + public class JniWrapper { + static Context context = null; + + public static void SetContext(Context context) + { + JniWrapper.context = context; + } + static { System.loadLibrary("DoubleHitBalls"); } public static native void Init(int width, int height); + public static native void SetJavaVM(); + public static String LoadFile(String fileName) + { + try { + File file = new File(context.getFilesDir(), fileName); + FileInputStream inputStream = new FileInputStream(file); + byte[] data = new byte[(int) file.length()]; + inputStream.read(data); + inputStream.close(); + return new String(data, "UTF-8"); + } catch (Exception e) { + Log.d("SaveFile", "Failed to save a file."); + } + return ""; + } + + public static void SaveFile(String fileName, String fileContent) + { + try { + File file = new File(context.getFilesDir(), fileName); + FileOutputStream outputStream = new FileOutputStream(file); + outputStream.write(fileContent.getBytes()); + outputStream.close(); + } catch (Exception e) { + Log.d("SaveFile", "Failed to save a file."); + } + } } \ No newline at end of file