From 577c1b268a057fa4db537d18e6c63c352e275ac3 Mon Sep 17 00:00:00 2001 From: chinosk <2248589280@qq.com> Date: Fri, 14 Jun 2024 22:49:36 +0800 Subject: [PATCH 1/4] add feature: orientation lock --- app/src/main/cpp/GakumasLocalify/Hook.cpp | 13 + .../cpp/GakumasLocalify/config/Config.cpp | 2 + .../cpp/GakumasLocalify/config/Config.hpp | 1 + .../chinosk/gakumas/localify/MainActivity.kt | 70 +- .../gakumas/localify/models/GakumasConfig.kt | 1 + app/src/main/res/drawable/start_game.xml | 5 + app/src/main/res/layout/activity_main.xml | 1014 +++++++++-------- app/src/main/res/values-zh-rCN/strings.xml | 4 + app/src/main/res/values/strings.xml | 5 + 9 files changed, 632 insertions(+), 483 deletions(-) create mode 100644 app/src/main/res/drawable/start_game.xml diff --git a/app/src/main/cpp/GakumasLocalify/Hook.cpp b/app/src/main/cpp/GakumasLocalify/Hook.cpp index 8645ace..d0c7f56 100644 --- a/app/src/main/cpp/GakumasLocalify/Hook.cpp +++ b/app/src/main/cpp/GakumasLocalify/Hook.cpp @@ -221,6 +221,15 @@ namespace GakumasLocal::HookMain { return Unity_set_position_Injected_Orig(_this, data); } + DEFINE_HOOK(void*, InternalSetOrientationAsync, (void* _this, int type, void* c, void* tc, void* mtd)) { + switch (Config::gameOrientation) { + case 1: type = 0x2; break; // FixedPortrait + case 2: type = 0x3; break; // FixedLandscape + default: break; + } + return InternalSetOrientationAsync_Orig(_this, type, c, tc, mtd); + } + DEFINE_HOOK(void, EndCameraRendering, (void* ctx, void* camera, void* method)) { EndCameraRendering_Orig(ctx, camera, method); @@ -797,6 +806,10 @@ namespace GakumasLocal::HookMain { ADD_HOOK(Internal_Log, Il2cppUtils::il2cpp_resolve_icall( "UnityEngine.DebugLogHandler::Internal_Log(UnityEngine.LogType,UnityEngine.LogOption,System.String,UnityEngine.Object)")); + ADD_HOOK(InternalSetOrientationAsync, + Il2cppUtils::GetMethodPointer("campus-submodule.Runtime.dll", "Campus.Common", + "ScreenOrientationControllerBase", "InternalSetOrientationAsync")); + ADD_HOOK(Unity_set_position_Injected, Il2cppUtils::il2cpp_resolve_icall( "UnityEngine.Transform::set_position_Injected(UnityEngine.Vector3&)")); ADD_HOOK(Unity_set_rotation_Injected, Il2cppUtils::il2cpp_resolve_icall( diff --git a/app/src/main/cpp/GakumasLocalify/config/Config.cpp b/app/src/main/cpp/GakumasLocalify/config/Config.cpp index 110f81e..b3cf550 100644 --- a/app/src/main/cpp/GakumasLocalify/config/Config.cpp +++ b/app/src/main/cpp/GakumasLocalify/config/Config.cpp @@ -9,6 +9,7 @@ namespace GakumasLocal::Config { bool enabled = true; bool forceExportResource = true; bool textTest = false; + int gameOrientation = 0; bool dumpText = false; bool enableFreeCamera = false; int targetFrameRate = 0; @@ -35,6 +36,7 @@ namespace GakumasLocal::Config { GetConfigItem(dbgMode); GetConfigItem(enabled); GetConfigItem(forceExportResource); + GetConfigItem(gameOrientation); GetConfigItem(textTest); GetConfigItem(dumpText); GetConfigItem(targetFrameRate); diff --git a/app/src/main/cpp/GakumasLocalify/config/Config.hpp b/app/src/main/cpp/GakumasLocalify/config/Config.hpp index f19ac5f..a37ea34 100644 --- a/app/src/main/cpp/GakumasLocalify/config/Config.hpp +++ b/app/src/main/cpp/GakumasLocalify/config/Config.hpp @@ -6,6 +6,7 @@ namespace GakumasLocal::Config { extern bool dbgMode; extern bool enabled; extern bool forceExportResource; + extern int gameOrientation; extern bool textTest; extern bool dumpText; extern bool enableFreeCamera; diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/MainActivity.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/MainActivity.kt index 09f3c12..b952404 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/MainActivity.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/MainActivity.kt @@ -3,17 +3,17 @@ package io.github.chinosk.gakumas.localify import android.annotation.SuppressLint import android.content.Intent -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle -import android.util.Log import android.view.KeyEvent +import android.view.View +import android.view.ViewTreeObserver +import android.widget.ScrollView import android.widget.TextView import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity import androidx.databinding.DataBindingUtil -import androidx.databinding.ObservableField -import com.google.android.material.switchmaterial.SwitchMaterial -import com.google.android.material.textfield.TextInputEditText -import com.google.android.material.textfield.TextInputLayout +import com.google.android.material.button.MaterialButton +import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.gson.Gson import com.google.gson.JsonSyntaxException import io.github.chinosk.gakumas.localify.databinding.ActivityMainBinding @@ -42,6 +42,7 @@ interface ConfigListener { fun onChangePresetQuality(level: Int) fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) fun onLodQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onGameOrientationChanged(checkedId: Int) fun onDumpTextChanged(value: Boolean) } @@ -65,6 +66,42 @@ class MainActivity : AppCompatActivity(), ConfigListener { } } showVersion() + + val scrollView: ScrollView = findViewById(R.id.scrollView) + scrollView.viewTreeObserver.addOnScrollChangedListener { onScrollChanged() } + onScrollChanged() + + val coordinatorLayout = findViewById(R.id.coordinatorLayout) + coordinatorLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + override fun onGlobalLayout() { + onScrollChanged() + coordinatorLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) + } + }) + } + + private fun onScrollChanged() { + val fab: FloatingActionButton = findViewById(R.id.fabStartGame) + val startGameButton: MaterialButton = findViewById(R.id.StartGameButton) + val scrollView: ScrollView = findViewById(R.id.scrollView) + + val location = IntArray(2) + startGameButton.getLocationOnScreen(location) + val buttonTop = location[1] + val buttonBottom = buttonTop + startGameButton.height + + val scrollViewLocation = IntArray(2) + scrollView.getLocationOnScreen(scrollViewLocation) + val scrollViewTop = scrollViewLocation[1] + val scrollViewBottom = scrollViewTop + scrollView.height + + val isButtonVisible = buttonTop >= scrollViewTop && buttonBottom <= scrollViewBottom + + if (isButtonVisible) { + fab.hide() + } else { + fab.show() + } } private fun showToast(message: String) { @@ -301,18 +338,22 @@ class MainActivity : AppCompatActivity(), ConfigListener { binding.config!!.reflectionQualityLevel = 5 } } - binding.config = binding.config - binding.notifyChange() + checkConfigAndUpdateView() saveConfig() } - private fun showTextInputLayoutHint(view: TextInputLayout) { - showToast(view.hint.toString()) + override fun onGameOrientationChanged(checkedId: Int) { + when (checkedId) { + R.id.radioButtonGameDefault -> binding.config!!.gameOrientation = 0 + R.id.radioButtonGamePortrait -> binding.config!!.gameOrientation = 1 + R.id.radioButtonGameLandscape -> binding.config!!.gameOrientation = 2 + } + saveConfig() } - fun checkConfigAndUpdateView() { - val sw = findViewById(R.id.SwitchUnlockAllLive) - sw.visibility = if (binding.config!!.dbgMode) android.view.View.VISIBLE else android.view.View.GONE + private fun checkConfigAndUpdateView() { + binding.config = binding.config + binding.notifyChange() } override fun dispatchKeyEvent(event: KeyEvent): Boolean { @@ -321,8 +362,7 @@ class MainActivity : AppCompatActivity(), ConfigListener { val origDbg = binding.config?.dbgMode if (origDbg != null) { binding.config!!.dbgMode = !origDbg - binding.config = binding.config - binding.notifyChange() + checkConfigAndUpdateView() saveConfig() showToast("TestMode: ${!origDbg}") } diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt index 266cfb0..b0a48c5 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt @@ -7,6 +7,7 @@ data class GakumasConfig ( var enabled: Boolean = true, var textTest: Boolean = false, var dumpText: Boolean = false, + var gameOrientation: Int = 0, var forceExportResource: Boolean = false, var enableFreeCamera: Boolean = false, var targetFrameRate: Int = 0, diff --git a/app/src/main/res/drawable/start_game.xml b/app/src/main/res/drawable/start_game.xml new file mode 100644 index 0000000..3f29258 --- /dev/null +++ b/app/src/main/res/drawable/start_game.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 287abf5..b0c508d 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -10,533 +10,611 @@ type="io.github.chinosk.gakumas.localify.ConfigListener" /> - - + android:padding="6sp" + tools:context=".MainActivity"> - - - - - - - - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> - + android:layout_height="wrap_content" + android:text="@string/gakumas_localify" + android:textColor="@color/black" + android:textSize="20sp" /> - - - - + android:layout_height="wrap_content" + android:textColor="@color/black" /> - - - - + android:layout_height="25sp" /> - - - - + android:layout_height="match_parent" + android:orientation="vertical" + android:stretchColumns="0"> - - + android:layout_height="match_parent"> - - - - - - + android:checked="@={config.enabled}" + android:onCheckedChanged="@{(view, value) -> listener.onEnabledChanged(value)}" + android:text="@string/enable_plugin" /> + - - - - - - - - + android:layout_height="match_parent"> - + + - - + android:layout_height="match_parent"> - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:layout_marginTop="4sp" + android:background="@drawable/table_row_border"> - + android:layout_height="match_parent" + android:orientation="vertical" + android:paddingLeft="10sp" + android:paddingRight="10sp" + android:paddingTop="10sp"> - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:weightSum="3" + android:onCheckedChanged="@{(group, checkedId) -> listener.onGameOrientationChanged(checkedId)}"> - + android:checked="@{config.gameOrientation == 0}" + android:text="@string/orientation_orig" /> - + android:checked="@{config.gameOrientation == 1}" + android:text="@string/orientation_portrait" /> - + android:checked="@{config.gameOrientation == 2}" + android:text="@string/orientation_landscape" /> - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_height="match_parent" + android:layout_marginTop="4sp" + android:background="@drawable/table_row_border"> - - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a9ae75c..bc9cb7d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -19,4 +19,8 @@ + 游戏原版 + 竖屏 + 横屏 + 方向锁定 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 676fc24..a0299f4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -19,4 +19,9 @@ High Mid Low + Original + Portrait + Landscape + Original Lock + \ No newline at end of file From ca0e6e6a9a4d9d2a6182d90699ce49357856ea80 Mon Sep 17 00:00:00 2001 From: chinosk <2248589280@qq.com> Date: Fri, 14 Jun 2024 23:02:31 +0800 Subject: [PATCH 2/4] fix typo, update workflow, update README --- .github/workflows/build.yml | 9 +++++++-- README.md | 16 +++++++++++++++- app/src/main/res/values/strings.xml | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0f35109..08e6671 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,6 +1,6 @@ name: Android CI -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: build: @@ -37,6 +37,11 @@ jobs: - name: Build with Gradle run: ./gradlew build + - uses: actions/upload-artifact@v4 + with: + name: GakumasLocalify-Unsigned-apk + path: app/build/outputs/apk/debug/app-debug.apk + - uses: ilharp/sign-android-release@v1 name: Sign app APK id: sign_app @@ -50,5 +55,5 @@ jobs: - uses: actions/upload-artifact@v4 with: - name: GakumasLocalify + name: GakumasLocalify-Signed-apk path: ${{steps.sign_app.outputs.signedFile}} diff --git a/README.md b/README.md index 1a0dc9b..86169c1 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ -# How to use +# Usage - 这是一个 XPosed 插件,已 Root 用户可以使用 [LSPosed](https://github.com/LSPosed/LSPosed),未 Root 用户可以使用 [LSPatch](https://github.com/LSPosed/LSPatch)。 @@ -32,6 +32,20 @@ +# 翻译仓库贡献列表 + + + + + + + +# Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=chinosk6/gakuen-imas-localify&type=Date)](https://star-history.com/#chinosk6/gakuen-imas-localify&Date) + + + # 特别鸣谢 - [gkmasToolkit](https://github.com/kishidanatsumi/gkmasToolkit) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a0299f4..413b5b9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,6 +22,6 @@ Original Portrait Landscape - Original Lock + Orientation Lock \ No newline at end of file From f5a88a9127f7c1806830b467ab39f1eee1a69e29 Mon Sep 17 00:00:00 2001 From: chinosk <74499927+chinosk6@users.noreply.github.com> Date: Sat, 15 Jun 2024 14:21:07 -0500 Subject: [PATCH 3/4] Font, Softer Breast (#19) * add breast parameter editer * add pre-config, add scale set * support disable replace font --- app/src/main/cpp/GakumasLocalify/Hook.cpp | 99 ++++- .../main/cpp/GakumasLocalify/Il2cppUtils.hpp | 2 +- .../cpp/GakumasLocalify/config/Config.cpp | 27 ++ .../cpp/GakumasLocalify/config/Config.hpp | 14 + .../gakumas/localify/ConfigUpdateListener.kt | 382 +++++++++++++++++ .../chinosk/gakumas/localify/MainActivity.kt | 250 +---------- .../gakumas/localify/models/GakumasConfig.kt | 15 +- app/src/main/res/layout/activity_main.xml | 392 ++++++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 14 + app/src/main/res/values/strings.xml | 14 + 10 files changed, 975 insertions(+), 234 deletions(-) create mode 100644 app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt diff --git a/app/src/main/cpp/GakumasLocalify/Hook.cpp b/app/src/main/cpp/GakumasLocalify/Hook.cpp index d0c7f56..08c182f 100644 --- a/app/src/main/cpp/GakumasLocalify/Hook.cpp +++ b/app/src/main/cpp/GakumasLocalify/Hook.cpp @@ -323,6 +323,7 @@ namespace GakumasLocal::HookMain { std::unordered_set updatedFontPtrs{}; void UpdateFont(void* TMP_Text_this) { + if (!Config::replaceFont) return; static auto get_font = Il2cppUtils::GetMethod("Unity.TextMeshPro.dll", "TMPro", "TMP_Text", "get_font"); static auto set_font = Il2cppUtils::GetMethod("Unity.TextMeshPro.dll", @@ -341,6 +342,7 @@ namespace GakumasLocal::HookMain { updatedFontPtrs.emplace(fontAsset); UpdateFontAssetData->Invoke(fontAsset); } + if (updatedFontPtrs.size() > 200) updatedFontPtrs.clear(); } set_font->Invoke(TMP_Text_this, fontAsset); } @@ -644,6 +646,11 @@ namespace GakumasLocal::HookMain { } DEFINE_HOOK(void, CampusActorController_LateUpdate, (void* _this, void* mtd)) { + static auto CampusActorController_klass = Il2cppUtils::GetClass("campus-submodule.Runtime.dll", + "Campus.Common", "CampusActorController"); + static auto rootBody_field = CampusActorController_klass->Get("_rootBody"); + static auto parentKlass = UnityResolve::Invoke("il2cpp_class_get_parent", CampusActorController_klass->address); + if (!Config::enableFreeCamera || (GKCamera::GetCameraMode() == GKCamera::CameraMode::FREE)) { if (needRestoreHides) { needRestoreHides = false; @@ -653,10 +660,6 @@ namespace GakumasLocal::HookMain { return CampusActorController_LateUpdate_Orig(_this, mtd); } - static auto CampusActorController_klass = Il2cppUtils::GetClass("campus-submodule.Runtime.dll", - "Campus.Common", "CampusActorController"); - static auto rootBody_field = CampusActorController_klass->Get("_rootBody"); - static auto parentKlass = UnityResolve::Invoke("il2cpp_class_get_parent", CampusActorController_klass->address); static auto GetHumanBodyBoneTransform_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(parentKlass, "GetHumanBodyBoneTransform", 1); static auto GetHumanBodyBoneTransform = reinterpret_cast( GetHumanBodyBoneTransform_mtd->methodPointer @@ -711,6 +714,90 @@ namespace GakumasLocal::HookMain { CampusActorController_LateUpdate_Orig(_this, mtd); } + void UpdateSwingBreastBonesData(void* initializeData) { + if (!Config::enableBreastParam) return; + static auto CampusActorAnimationInitializeData_klass = Il2cppUtils::GetClass("campus-submodule.Runtime.dll", "ActorAnimation", + "CampusActorAnimationInitializeData"); + static auto ActorSwingBreastBone_klass = Il2cppUtils::GetClass("ActorAnimation.Runtime.dll", "ActorAnimation", + "ActorSwingBreastBone"); + static auto LimitInfo_klass = Il2cppUtils::GetClass("ActorAnimation.Runtime.dll", "ActorAnimation", + "LimitInfo"); + + static auto Data_swingBreastBones_field = CampusActorAnimationInitializeData_klass->Get("swingBreastBones"); + static auto damping_field = ActorSwingBreastBone_klass->Get("damping"); + static auto stiffness_field = ActorSwingBreastBone_klass->Get("stiffness"); + static auto spring_field = ActorSwingBreastBone_klass->Get("spring"); + static auto pendulum_field = ActorSwingBreastBone_klass->Get("pendulum"); + static auto pendulumRange_field = ActorSwingBreastBone_klass->Get("pendulumRange"); + static auto average_field = ActorSwingBreastBone_klass->Get("average"); + static auto rootWeight_field = ActorSwingBreastBone_klass->Get("rootWeight"); + static auto useArmCorrection_field = ActorSwingBreastBone_klass->Get("useArmCorrection"); + static auto isDirty_field = ActorSwingBreastBone_klass->Get("k__BackingField"); + static auto leftBreast_field = ActorSwingBreastBone_klass->Get("leftBreast"); + static auto rightBreast_field = ActorSwingBreastBone_klass->Get("rightBreast"); + static auto leftBreastEnd_field = ActorSwingBreastBone_klass->Get("leftBreastEnd"); + static auto rightBreastEnd_field = ActorSwingBreastBone_klass->Get("rightBreastEnd"); + static auto limitInfo_field = ActorSwingBreastBone_klass->Get("limitInfo"); + + static auto limitInfo_useLimit_field = LimitInfo_klass->Get("useLimit"); + + auto swingBreastBones = Il2cppUtils::ClassGetFieldValue + *>(initializeData, Data_swingBreastBones_field); + + auto boneArr = swingBreastBones->ToArray(); + for (int i = 0; i < boneArr->max_length; i++) { + auto bone = boneArr->At(i); + if (!bone) continue; + + auto damping = Il2cppUtils::ClassGetFieldValue(bone, damping_field); + auto stiffness = Il2cppUtils::ClassGetFieldValue(bone, stiffness_field); + auto spring = Il2cppUtils::ClassGetFieldValue(bone, spring_field); + auto pendulum = Il2cppUtils::ClassGetFieldValue(bone, pendulum_field); + auto pendulumRange = Il2cppUtils::ClassGetFieldValue(bone, pendulumRange_field); + auto average = Il2cppUtils::ClassGetFieldValue(bone, average_field); + auto rootWeight = Il2cppUtils::ClassGetFieldValue(bone, rootWeight_field); + auto useArmCorrection = Il2cppUtils::ClassGetFieldValue(bone, useArmCorrection_field); + auto isDirty = Il2cppUtils::ClassGetFieldValue(bone, isDirty_field); + + auto limitInfo = Il2cppUtils::ClassGetFieldValue(bone, limitInfo_field); + auto useLimit = Il2cppUtils::ClassGetFieldValue(limitInfo, limitInfo_useLimit_field); + + if (Config::bUseScale) { + auto leftBreast = Il2cppUtils::ClassGetFieldValue(bone, leftBreast_field); + auto rightBreast = Il2cppUtils::ClassGetFieldValue(bone, rightBreast_field); + auto leftBreastEnd = Il2cppUtils::ClassGetFieldValue(bone, leftBreastEnd_field); + auto rightBreastEnd = Il2cppUtils::ClassGetFieldValue(bone, rightBreastEnd_field); + + const auto setScale = UnityResolve::UnityType::Vector3(Config::bScale, Config::bScale, Config::bScale); + leftBreast->SetLocalScale(setScale); + rightBreast->SetLocalScale(setScale); + leftBreastEnd->SetLocalScale(setScale); + rightBreastEnd->SetLocalScale(setScale); + } + + Log::DebugFmt("orig bone: damping: %f, stiffness: %f, spring: %f, pendulum: %f, " + "pendulumRange: %f, average: %f, rootWeight: %f, useLimit: %d, useArmCorrection: %d, isDirty: %d", + damping, stiffness, spring, pendulum, pendulumRange, average, rootWeight, useLimit, useArmCorrection, isDirty); + + Il2cppUtils::ClassSetFieldValue(limitInfo, limitInfo_useLimit_field, Config::bUseLimit); + Il2cppUtils::ClassSetFieldValue(bone, damping_field, Config::bDamping); + Il2cppUtils::ClassSetFieldValue(bone, stiffness_field, Config::bStiffness); + Il2cppUtils::ClassSetFieldValue(bone, spring_field, Config::bSpring); + Il2cppUtils::ClassSetFieldValue(bone, pendulum_field, Config::bPendulum); + Il2cppUtils::ClassSetFieldValue(bone, pendulumRange_field, Config::bPendulumRange); + Il2cppUtils::ClassSetFieldValue(bone, average_field, Config::bAverage); + Il2cppUtils::ClassSetFieldValue(bone, rootWeight_field, Config::bRootWeight); + Il2cppUtils::ClassSetFieldValue(bone, useArmCorrection_field, Config::bUseArmCorrection); + // Il2cppUtils::ClassSetFieldValue(bone, isDirty_field, Config::bIsDirty); + } + // Log::DebugFmt("\n"); + } + + DEFINE_HOOK(void, CampusActorAnimation_Setup, (void* _this, void* rootTrans, void* initializeData)) { + UpdateSwingBreastBonesData(initializeData); + return CampusActorAnimation_Setup_Orig(_this, rootTrans, initializeData); + } + void StartInjectFunctions() { const auto hookInstaller = Plugin::GetInstance().GetHookInstaller(); UnityResolve::Init(xdl_open(hookInstaller->m_il2cppLibraryPath.c_str(), RTLD_NOW), UnityResolve::Mode::Il2Cpp); @@ -797,6 +884,10 @@ namespace GakumasLocal::HookMain { Log::DebugFmt("CampusActorController.%s at %p", i->name.c_str(), i->function); }*/ + ADD_HOOK(CampusActorAnimation_Setup, + Il2cppUtils::GetMethodPointer("campus-submodule.Runtime.dll", "Campus.Common", + "CampusActorAnimation", "Setup")); + ADD_HOOK(CampusQualityManager_set_TargetFrameRate, Il2cppUtils::GetMethodPointer("campus-submodule.Runtime.dll", "Campus.Common", "CampusQualityManager", "set_TargetFrameRate")); diff --git a/app/src/main/cpp/GakumasLocalify/Il2cppUtils.hpp b/app/src/main/cpp/GakumasLocalify/Il2cppUtils.hpp index 9d0e942..8a296f2 100644 --- a/app/src/main/cpp/GakumasLocalify/Il2cppUtils.hpp +++ b/app/src/main/cpp/GakumasLocalify/Il2cppUtils.hpp @@ -157,7 +157,7 @@ namespace Il2cppUtils { template auto ClassSetFieldValue(void* obj, UnityResolve::Field* field, RType value) -> void { - return *reinterpret_cast(reinterpret_cast(obj) + field->offset) = value; + *reinterpret_cast(reinterpret_cast(obj) + field->offset) = value; } diff --git a/app/src/main/cpp/GakumasLocalify/config/Config.cpp b/app/src/main/cpp/GakumasLocalify/config/Config.cpp index b3cf550..40108e0 100644 --- a/app/src/main/cpp/GakumasLocalify/config/Config.cpp +++ b/app/src/main/cpp/GakumasLocalify/config/Config.cpp @@ -7,6 +7,7 @@ namespace GakumasLocal::Config { bool dbgMode = false; bool enabled = true; + bool replaceFont = true; bool forceExportResource = true; bool textTest = false; int gameOrientation = 0; @@ -27,6 +28,19 @@ namespace GakumasLocal::Config { int reflectionQualityLevel = 4; int lodQualityLevel = 4; + bool enableBreastParam = false; + int bUseLimit = 1; + float bDamping = 0.33f; + float bStiffness = 0.08f; + float bSpring = 1.0f; + float bPendulum = 0.055f; + float bPendulumRange = 0.15f; + float bAverage = 0.20f; + float bRootWeight = 0.5f; + bool bUseArmCorrection = true; + bool bUseScale = false; + float bScale = 1.0f; + void LoadConfig(const std::string& configStr) { try { const auto config = nlohmann::json::parse(configStr); @@ -35,6 +49,7 @@ namespace GakumasLocal::Config { GetConfigItem(dbgMode); GetConfigItem(enabled); + GetConfigItem(replaceFont); GetConfigItem(forceExportResource); GetConfigItem(gameOrientation); GetConfigItem(textTest); @@ -52,6 +67,18 @@ namespace GakumasLocal::Config { GetConfigItem(maxBufferPixel); GetConfigItem(reflectionQualityLevel); GetConfigItem(lodQualityLevel); + GetConfigItem(enableBreastParam); + GetConfigItem(bUseLimit); + GetConfigItem(bDamping); + GetConfigItem(bStiffness); + GetConfigItem(bSpring); + GetConfigItem(bPendulum); + GetConfigItem(bPendulumRange); + GetConfigItem(bAverage); + GetConfigItem(bRootWeight); + GetConfigItem(bUseArmCorrection); + GetConfigItem(bUseScale); + GetConfigItem(bScale); } catch (std::exception& e) { diff --git a/app/src/main/cpp/GakumasLocalify/config/Config.hpp b/app/src/main/cpp/GakumasLocalify/config/Config.hpp index a37ea34..8a4bec9 100644 --- a/app/src/main/cpp/GakumasLocalify/config/Config.hpp +++ b/app/src/main/cpp/GakumasLocalify/config/Config.hpp @@ -5,6 +5,7 @@ namespace GakumasLocal::Config { extern bool dbgMode; extern bool enabled; + extern bool replaceFont; extern bool forceExportResource; extern int gameOrientation; extern bool textTest; @@ -26,5 +27,18 @@ namespace GakumasLocal::Config { extern int reflectionQualityLevel; extern int lodQualityLevel; + extern bool enableBreastParam; + extern int bUseLimit; + extern float bDamping; + extern float bStiffness; + extern float bSpring; + extern float bPendulum; + extern float bPendulumRange; + extern float bAverage; + extern float bRootWeight; + extern bool bUseArmCorrection; + extern bool bUseScale; + extern float bScale; + void LoadConfig(const std::string& configStr); } diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt new file mode 100644 index 0000000..031a3f7 --- /dev/null +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt @@ -0,0 +1,382 @@ +package io.github.chinosk.gakumas.localify + +import android.view.KeyEvent +import io.github.chinosk.gakumas.localify.databinding.ActivityMainBinding + + +interface ConfigListener { + fun onClickStartGame() + fun onEnabledChanged(value: Boolean) + fun onForceExportResourceChanged(value: Boolean) + fun onTextTestChanged(value: Boolean) + fun onReplaceFontChanged(value: Boolean) + fun onEnableFreeCameraChanged(value: Boolean) + fun onTargetFpsChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onUnlockAllLiveChanged(value: Boolean) + fun onLiveCustomeDressChanged(value: Boolean) + fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onUseCustomeGraphicSettingsChanged(value: Boolean) + fun onRenderScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onQualitySettingsLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onVolumeIndexChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onMaxBufferPixelChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onChangePresetQuality(level: Int) + fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onLodQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onGameOrientationChanged(checkedId: Int) + fun onDumpTextChanged(value: Boolean) + + fun onEnableBreastParamChanged(value: Boolean) + fun onBDampingChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBStiffnessChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBSpringChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBPendulumChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBPendulumRangeChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBAverageChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBRootWeightChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBUseLimitChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBUseArmCorrectionChanged(value: Boolean) + fun onBUseScaleChanged(value: Boolean) + fun onBClickPresetChanged(index: Int) +} + + +interface ConfigUpdateListener: ConfigListener { + var binding: ActivityMainBinding + + fun pushKeyEvent(event: KeyEvent): Boolean + fun getConfigContent(): String + fun checkConfigAndUpdateView() + fun saveConfig() + + + override fun onEnabledChanged(value: Boolean) { + binding.config!!.enabled = value + saveConfig() + pushKeyEvent(KeyEvent(1145, 29)) + } + + override fun onForceExportResourceChanged(value: Boolean) { + binding.config!!.forceExportResource = value + saveConfig() + pushKeyEvent(KeyEvent(1145, 30)) + } + + override fun onReplaceFontChanged(value: Boolean) { + binding.config!!.replaceFont = value + saveConfig() + pushKeyEvent(KeyEvent(1145, 30)) + } + + override fun onTextTestChanged(value: Boolean) { + binding.config!!.textTest = value + saveConfig() + } + + override fun onDumpTextChanged(value: Boolean) { + binding.config!!.dumpText = value + saveConfig() + } + + override fun onEnableFreeCameraChanged(value: Boolean) { + binding.config!!.enableFreeCamera = value + saveConfig() + } + + override fun onUnlockAllLiveChanged(value: Boolean) { + binding.config!!.unlockAllLive = value + saveConfig() + } + + override fun onTargetFpsChanged(s: CharSequence, start: Int, before: Int, count: Int) { + try { + val valueStr = s.toString() + + val value = if (valueStr == "") { + 0 + } else { + valueStr.toInt() + } + binding.config!!.targetFrameRate = value + saveConfig() + } + catch (e: Exception) { + return + } + } + + override fun onLiveCustomeDressChanged(value: Boolean) { + binding.config!!.enableLiveCustomeDress = value + saveConfig() + } + + override fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.liveCustomeCostumeId = s.toString() + saveConfig() + } + + override fun onUseCustomeGraphicSettingsChanged(value: Boolean) { + binding.config!!.useCustomeGraphicSettings = value + saveConfig() + } + + override fun onRenderScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.renderScale = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0.0f + } + saveConfig() + } + + override fun onQualitySettingsLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.qualitySettingsLevel = try { + s.toString().toInt() + } + catch (e: Exception) { + 0 + } + saveConfig() + } + + override fun onVolumeIndexChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.volumeIndex = try { + s.toString().toInt() + } + catch (e: Exception) { + 0 + } + saveConfig() + } + + override fun onMaxBufferPixelChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.maxBufferPixel = try { + s.toString().toInt() + } + catch (e: Exception) { + 0 + } + saveConfig() + } + + override fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.liveCustomeHeadId = s.toString() + saveConfig() + } + + override fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.reflectionQualityLevel = try { + val value = s.toString().toInt() + if (value > 5) 5 else value + } + catch (e: Exception) { + 0 + } + saveConfig() + } + + override fun onLodQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.lodQualityLevel = try { + val value = s.toString().toInt() + if (value > 5) 5 else value + } + catch (e: Exception) { + 0 + } + saveConfig() + } + + override fun onChangePresetQuality(level: Int) { + when (level) { + 0 -> { + binding.config!!.renderScale = 0.5f + binding.config!!.qualitySettingsLevel = 1 + binding.config!!.volumeIndex = 0 + binding.config!!.maxBufferPixel = 1024 + binding.config!!.lodQualityLevel = 1 + binding.config!!.reflectionQualityLevel = 1 + } + 1 -> { + binding.config!!.renderScale = 0.59f + binding.config!!.qualitySettingsLevel = 1 + binding.config!!.volumeIndex = 1 + binding.config!!.maxBufferPixel = 1440 + binding.config!!.lodQualityLevel = 2 + binding.config!!.reflectionQualityLevel = 2 + } + 2 -> { + binding.config!!.renderScale = 0.67f + binding.config!!.qualitySettingsLevel = 2 + binding.config!!.volumeIndex = 2 + binding.config!!.maxBufferPixel = 2538 + binding.config!!.lodQualityLevel = 3 + binding.config!!.reflectionQualityLevel = 3 + } + 3 -> { + binding.config!!.renderScale = 0.77f + binding.config!!.qualitySettingsLevel = 3 + binding.config!!.volumeIndex = 3 + binding.config!!.maxBufferPixel = 3384 + binding.config!!.lodQualityLevel = 4 + binding.config!!.reflectionQualityLevel = 4 + } + 4 -> { + binding.config!!.renderScale = 1.0f + binding.config!!.qualitySettingsLevel = 5 + binding.config!!.volumeIndex = 4 + binding.config!!.maxBufferPixel = 8190 + binding.config!!.lodQualityLevel = 5 + binding.config!!.reflectionQualityLevel = 5 + } + } + checkConfigAndUpdateView() + saveConfig() + } + + override fun onGameOrientationChanged(checkedId: Int) { + when (checkedId) { + R.id.radioButtonGameDefault -> binding.config!!.gameOrientation = 0 + R.id.radioButtonGamePortrait -> binding.config!!.gameOrientation = 1 + R.id.radioButtonGameLandscape -> binding.config!!.gameOrientation = 2 + } + saveConfig() + } + + override fun onEnableBreastParamChanged(value: Boolean) { + binding.config!!.enableBreastParam = value + saveConfig() + checkConfigAndUpdateView() + } + + override fun onBUseArmCorrectionChanged(value: Boolean) { + binding.config!!.bUseArmCorrection = value + saveConfig() + } + + override fun onBUseScaleChanged(value: Boolean) { + binding.config!!.bUseScale = value + saveConfig() + checkConfigAndUpdateView() + } + + override fun onBDampingChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.bDamping = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBStiffnessChanged(s: CharSequence, start: Int, before: Int, count: Int){ + binding.config!!.bStiffness = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBSpringChanged(s: CharSequence, start: Int, before: Int, count: Int){ + binding.config!!.bSpring = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBPendulumChanged(s: CharSequence, start: Int, before: Int, count: Int){ + binding.config!!.bPendulum = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBPendulumRangeChanged(s: CharSequence, start: Int, before: Int, count: Int){ + binding.config!!.bPendulumRange = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBAverageChanged(s: CharSequence, start: Int, before: Int, count: Int){ + binding.config!!.bAverage = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBRootWeightChanged(s: CharSequence, start: Int, before: Int, count: Int){ + binding.config!!.bRootWeight = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBUseLimitChanged(s: CharSequence, start: Int, before: Int, count: Int){ + binding.config!!.bUseLimit = try { + s.toString().toInt() + } + catch (e: Exception) { + 0 + } + saveConfig() + } + + override fun onBScaleChanged(s: CharSequence, start: Int, before: Int, count: Int){ + binding.config!!.bScale = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + override fun onBClickPresetChanged(index: Int) { + val setData: FloatArray = when (index) { + // 0.33, 0.08, 0.7, 0.12, 0.25, 0.2, 0.8, 0, noUseArm 啥玩意 + 0 -> floatArrayOf(0.33f, 0.07f, 0.7f, 0.06f, 0.25f, 0.2f, 0.5f, 1f) + 1 -> floatArrayOf(0.365f, 0.06f, 0.62f, 0.07f, 0.25f, 0.2f, 0.5f, 1f) + 2 -> floatArrayOf(0.4f, 0.065f, 0.55f, 0.075f, 0.25f, 0.2f, 0.5f, 1f) + 3 -> floatArrayOf(0.4f, 0.065f, 0.55f, 0.075f, 0.25f, 0.2f, 0.5f, 0f) + 4 -> floatArrayOf(0.4f, 0.06f, 0.4f, 0.075f, 0.55f, 0.2f, 0.8f, 0f) + + 5 -> floatArrayOf(0.33f, 0.08f, 0.8f, 0.12f, 0.55f, 0.2f, 1.0f, 0f) + + else -> floatArrayOf(0.33f, 0.08f, 1.0f, 0.055f, 0.15f, 0.2f, 0.5f, 1f) + } + + binding.config!!.bDamping = setData[0] + binding.config!!.bStiffness = setData[1] + binding.config!!.bSpring = setData[2] + binding.config!!.bPendulum = setData[3] + binding.config!!.bPendulumRange = setData[4] + binding.config!!.bAverage = setData[5] + binding.config!!.bRootWeight = setData[6] + binding.config!!.bUseLimit = setData[7].toInt() + binding.config!!.bUseArmCorrection = true + + checkConfigAndUpdateView() + saveConfig() + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/MainActivity.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/MainActivity.kt index b952404..094d222 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/MainActivity.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/MainActivity.kt @@ -23,31 +23,8 @@ import io.github.chinosk.gakumas.localify.models.GakumasConfig import java.io.File -interface ConfigListener { - fun onClickStartGame() - fun onEnabledChanged(value: Boolean) - fun onForceExportResourceChanged(value: Boolean) - fun onTextTestChanged(value: Boolean) - fun onEnableFreeCameraChanged(value: Boolean) - fun onTargetFpsChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onUnlockAllLiveChanged(value: Boolean) - fun onLiveCustomeDressChanged(value: Boolean) - fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onUseCustomeGraphicSettingsChanged(value: Boolean) - fun onRenderScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onQualitySettingsLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onVolumeIndexChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onMaxBufferPixelChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onChangePresetQuality(level: Int) - fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onLodQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onGameOrientationChanged(checkedId: Int) - fun onDumpTextChanged(value: Boolean) -} - -class MainActivity : AppCompatActivity(), ConfigListener { - private lateinit var binding: ActivityMainBinding +class MainActivity : AppCompatActivity(), ConfigUpdateListener { + override lateinit var binding: ActivityMainBinding private val TAG = "GakumasLocalify" override fun onCreate(savedInstanceState: Bundle?) { @@ -80,6 +57,15 @@ class MainActivity : AppCompatActivity(), ConfigListener { }) } + override fun onClickStartGame() { + val intent = Intent().apply { + setClassName("com.bandainamcoent.idolmaster_gakuen", "com.google.firebase.MessagingUnityPlayerActivity") + putExtra("gkmsData", getConfigContent()) + flags = Intent.FLAG_ACTIVITY_NEW_TASK + } + startActivity(intent) + } + private fun onScrollChanged() { val fab: FloatingActionButton = findViewById(R.id.fabStartGame) val startGameButton: MaterialButton = findViewById(R.id.StartGameButton) @@ -108,7 +94,7 @@ class MainActivity : AppCompatActivity(), ConfigListener { Toast.makeText(this, message, Toast.LENGTH_SHORT).show() } - private fun getConfigContent(): String { + override fun getConfigContent(): String { val configFile = File(filesDir, "gkms-config.json") return if (configFile.exists()) { configFile.readText() @@ -119,6 +105,11 @@ class MainActivity : AppCompatActivity(), ConfigListener { } } + override fun saveConfig() { + val configFile = File(filesDir, "gkms-config.json") + configFile.writeText(Gson().toJson(binding.config!!)) + } + @SuppressLint("SetTextI18n") private fun showVersion() { val titleLabel = findViewById(R.id.textViewTitle) @@ -150,212 +141,15 @@ class MainActivity : AppCompatActivity(), ConfigListener { saveConfig() } - private fun saveConfig() { - val configFile = File(filesDir, "gkms-config.json") - configFile.writeText(Gson().toJson(binding.config!!)) - } - - override fun onEnabledChanged(value: Boolean) { - binding.config!!.enabled = value - saveConfig() - dispatchKeyEvent(KeyEvent(1145, 29)) - } - - override fun onForceExportResourceChanged(value: Boolean) { - binding.config!!.forceExportResource = value - saveConfig() - dispatchKeyEvent(KeyEvent(1145, 30)) - } - - override fun onTextTestChanged(value: Boolean) { - binding.config!!.textTest = value - saveConfig() - } - - override fun onDumpTextChanged(value: Boolean) { - binding.config!!.dumpText = value - saveConfig() - } - - override fun onEnableFreeCameraChanged(value: Boolean) { - binding.config!!.enableFreeCamera = value - saveConfig() - } - - override fun onUnlockAllLiveChanged(value: Boolean) { - binding.config!!.unlockAllLive = value - saveConfig() - } - - override fun onTargetFpsChanged(s: CharSequence, start: Int, before: Int, count: Int) { - try { - val valueStr = s.toString() - - val value = if (valueStr == "") { - 0 - } else { - valueStr.toInt() - } - binding.config!!.targetFrameRate = value - saveConfig() - } - catch (e: Exception) { - return - } - } - - override fun onLiveCustomeDressChanged(value: Boolean) { - binding.config!!.enableLiveCustomeDress = value - saveConfig() - } - - override fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int) { - binding.config!!.liveCustomeCostumeId = s.toString() - saveConfig() - } - - override fun onUseCustomeGraphicSettingsChanged(value: Boolean) { - binding.config!!.useCustomeGraphicSettings = value - saveConfig() - } - - override fun onRenderScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) { - binding.config!!.renderScale = try { - s.toString().toFloat() - } - catch (e: Exception) { - 0.0f - } - saveConfig() - } - - override fun onQualitySettingsLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) { - binding.config!!.qualitySettingsLevel = try { - s.toString().toInt() - } - catch (e: Exception) { - 0 - } - saveConfig() - } - - override fun onVolumeIndexChanged(s: CharSequence, start: Int, before: Int, count: Int) { - binding.config!!.volumeIndex = try { - s.toString().toInt() - } - catch (e: Exception) { - 0 - } - saveConfig() - } - - override fun onMaxBufferPixelChanged(s: CharSequence, start: Int, before: Int, count: Int) { - binding.config!!.maxBufferPixel = try { - s.toString().toInt() - } - catch (e: Exception) { - 0 - } - saveConfig() - } - - override fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int) { - binding.config!!.liveCustomeHeadId = s.toString() - saveConfig() - } - - override fun onClickStartGame() { - val intent = Intent().apply { - setClassName("com.bandainamcoent.idolmaster_gakuen", "com.google.firebase.MessagingUnityPlayerActivity") - putExtra("gkmsData", getConfigContent()) - flags = Intent.FLAG_ACTIVITY_NEW_TASK - } - startActivity(intent) - } - - override fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) { - binding.config!!.reflectionQualityLevel = try { - val value = s.toString().toInt() - if (value > 5) 5 else value - } - catch (e: Exception) { - 0 - } - saveConfig() - } - - override fun onLodQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) { - binding.config!!.lodQualityLevel = try { - val value = s.toString().toInt() - if (value > 5) 5 else value - } - catch (e: Exception) { - 0 - } - saveConfig() - } - - override fun onChangePresetQuality(level: Int) { - when (level) { - 0 -> { - binding.config!!.renderScale = 0.5f - binding.config!!.qualitySettingsLevel = 1 - binding.config!!.volumeIndex = 0 - binding.config!!.maxBufferPixel = 1024 - binding.config!!.lodQualityLevel = 1 - binding.config!!.reflectionQualityLevel = 1 - } - 1 -> { - binding.config!!.renderScale = 0.59f - binding.config!!.qualitySettingsLevel = 1 - binding.config!!.volumeIndex = 1 - binding.config!!.maxBufferPixel = 1440 - binding.config!!.lodQualityLevel = 2 - binding.config!!.reflectionQualityLevel = 2 - } - 2 -> { - binding.config!!.renderScale = 0.67f - binding.config!!.qualitySettingsLevel = 2 - binding.config!!.volumeIndex = 2 - binding.config!!.maxBufferPixel = 2538 - binding.config!!.lodQualityLevel = 3 - binding.config!!.reflectionQualityLevel = 3 - } - 3 -> { - binding.config!!.renderScale = 0.77f - binding.config!!.qualitySettingsLevel = 3 - binding.config!!.volumeIndex = 3 - binding.config!!.maxBufferPixel = 3384 - binding.config!!.lodQualityLevel = 4 - binding.config!!.reflectionQualityLevel = 4 - } - 4 -> { - binding.config!!.renderScale = 1.0f - binding.config!!.qualitySettingsLevel = 5 - binding.config!!.volumeIndex = 4 - binding.config!!.maxBufferPixel = 8190 - binding.config!!.lodQualityLevel = 5 - binding.config!!.reflectionQualityLevel = 5 - } - } - checkConfigAndUpdateView() - saveConfig() - } - - override fun onGameOrientationChanged(checkedId: Int) { - when (checkedId) { - R.id.radioButtonGameDefault -> binding.config!!.gameOrientation = 0 - R.id.radioButtonGamePortrait -> binding.config!!.gameOrientation = 1 - R.id.radioButtonGameLandscape -> binding.config!!.gameOrientation = 2 - } - saveConfig() - } - - private fun checkConfigAndUpdateView() { + override fun checkConfigAndUpdateView() { binding.config = binding.config binding.notifyChange() } + override fun pushKeyEvent(event: KeyEvent): Boolean { + return dispatchKeyEvent(event) + } + override fun dispatchKeyEvent(event: KeyEvent): Boolean { // Log.d(TAG, "${event.keyCode}, ${event.action}") if (MainKeyEventDispatcher.checkDbgKey(event.keyCode, event.action)) { diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt index b0a48c5..beb5763 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt @@ -1,10 +1,10 @@ package io.github.chinosk.gakumas.localify.models -import androidx.databinding.BaseObservable data class GakumasConfig ( var dbgMode: Boolean = false, var enabled: Boolean = true, + var replaceFont: Boolean = true, var textTest: Boolean = false, var dumpText: Boolean = false, var gameOrientation: Int = 0, @@ -23,4 +23,17 @@ data class GakumasConfig ( var maxBufferPixel: Int = 3384, var reflectionQualityLevel: Int = 4, // 0~5 var lodQualityLevel: Int = 4, // 0~5 + + var enableBreastParam: Boolean = false, + var bUseLimit: Int = 1, + var bDamping: Float = 0.33f, + var bStiffness: Float = 0.08f, + var bSpring: Float = 1.0f, + var bPendulum: Float = 0.055f, + var bPendulumRange: Float = 0.15f, + var bAverage: Float = 0.20f, + var bRootWeight: Float = 0.5f, + var bUseArmCorrection: Boolean = true, + var bUseScale: Boolean = false, + var bScale: Float = 1.0f ) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index b0c508d..b2217bf 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -77,6 +77,19 @@ android:text="@string/enable_plugin" /> + + + + + @@ -587,6 +600,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index bc9cb7d..1c75d80 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -2,6 +2,7 @@ Gakumas Localify Gakumas Localify 启用插件 (不可热重载) + 替换字体 启用自由视角(可热重载; 需使用实体键盘) 以上述配置启动游戏/重载配置 最大 FPS (0 为保持游戏原设置) @@ -23,4 +24,17 @@ 竖屏 横屏 方向锁定 + 启用胸部参数 + 阻尼 (Damping) + 刚度 (Stiffness) + 弹簧系数 (Spring) + 钟摆系数 (Pendulum) + 钟摆范围 (PendulumRange) + Average + RootWeight + 限制范围 (0/1) + 使用手臂矫正 + IsDirty + 应用缩放 + 胸部缩放倍率 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 413b5b9..6b6c102 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,6 +2,7 @@ Gakumas Localify Gakumas Localify Enable Plugin (Not Hot Reloadable) + Replace Font Enable Free Camera Start Game / Hot Reload Config Max FPS (0 is Use Original Settings) @@ -23,5 +24,18 @@ Portrait Landscape Orientation Lock + Enable Breast Param + Damping + Stiffness + Spring + Pendulum + Pendulum Range + Average + Root Weight + Use Limit (0/1) + Use Arm Correction + IsDirty + Use Breast Scale + Breast Scale \ No newline at end of file From 1855ae79cc1c2e9940984a8b1c5f13c8512ae475 Mon Sep 17 00:00:00 2001 From: chinosk <74499927+chinosk6@users.noreply.github.com> Date: Sun, 16 Jun 2024 11:53:50 -0500 Subject: [PATCH 4/4] Pre releases 0.0.1 (#20) * update submodule, breast limit multiplier * add type, add limit axis config * update layout * update submodule * update workflow --- .github/workflows/build.yml | 14 ++ app/src/main/assets/gakumas-local | 2 +- app/src/main/cpp/GakumasLocalify/Hook.cpp | 23 +- .../cpp/GakumasLocalify/config/Config.cpp | 16 +- .../cpp/GakumasLocalify/config/Config.hpp | 8 +- .../cpp/deps/UnityResolve/UnityResolve.hpp | 70 +++++- .../gakumas/localify/ConfigUpdateListener.kt | 111 ++++++++-- .../gakumas/localify/models/GakumasConfig.kt | 10 +- app/src/main/res/layout/activity_main.xml | 208 ++++++++++++++++-- app/src/main/res/values-zh-rCN/strings.xml | 9 +- app/src/main/res/values/strings.xml | 9 +- 11 files changed, 432 insertions(+), 48 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 08e6671..89f6156 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,6 +11,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: recursive + - name: set up android development environment uses: android-actions/setup-android@v2 @@ -18,6 +19,7 @@ jobs: run: | sdkmanager --install "cmake;3.22.1" echo "cmake.dir=/usr/local/lib/android/sdk/cmake/3.22.1" > local.properties + npm install -g pnpm - name: Setup Java JDK uses: actions/setup-java@v4.2.1 @@ -25,6 +27,18 @@ jobs: distribution: 'temurin' java-version: '21' + - name: Update Assets + run: | + git submodule foreach --recursive git pull origin main + git clone https://${{ secrets.ACCESS_TOKEN_GITHUB }}@github.com/imas-tools/gakumas-raw-txts.git app/src/main/assets/gakumas-local/gakumas-raw-txts + mv app/src/main/assets/gakumas-local/gakumas-raw-txts/Resource app/src/main/assets/gakumas-local/raw + rm -rf app/src/main/assets/gakumas-local/gakumas-raw-txts + + - name: Build Assets + run: | + mv app/src/main/assets/gakumas-local/GakumasPreTranslation/.env.sample app/src/main/assets/gakumas-local/GakumasPreTranslation/.env + cd app/src/main/assets/gakumas-local && make build-resource + - name: Write branch and commit info run: | branch=$(git rev-parse --abbrev-ref HEAD) diff --git a/app/src/main/assets/gakumas-local b/app/src/main/assets/gakumas-local index e97c861..56c568e 160000 --- a/app/src/main/assets/gakumas-local +++ b/app/src/main/assets/gakumas-local @@ -1 +1 @@ -Subproject commit e97c861d73668fdaa00c4aded70b18ead28fee02 +Subproject commit 56c568e32a84ee1351f2efcc70971b7f23d85186 diff --git a/app/src/main/cpp/GakumasLocalify/Hook.cpp b/app/src/main/cpp/GakumasLocalify/Hook.cpp index 08c182f..c538fd2 100644 --- a/app/src/main/cpp/GakumasLocalify/Hook.cpp +++ b/app/src/main/cpp/GakumasLocalify/Hook.cpp @@ -740,6 +740,9 @@ namespace GakumasLocal::HookMain { static auto limitInfo_field = ActorSwingBreastBone_klass->Get("limitInfo"); static auto limitInfo_useLimit_field = LimitInfo_klass->Get("useLimit"); + static auto limitInfo_axisX_field = LimitInfo_klass->Get("axisX"); + static auto limitInfo_axisY_field = LimitInfo_klass->Get("axisY"); + static auto limitInfo_axisZ_field = LimitInfo_klass->Get("axisZ"); auto swingBreastBones = Il2cppUtils::ClassGetFieldValue *>(initializeData, Data_swingBreastBones_field); @@ -778,8 +781,26 @@ namespace GakumasLocal::HookMain { Log::DebugFmt("orig bone: damping: %f, stiffness: %f, spring: %f, pendulum: %f, " "pendulumRange: %f, average: %f, rootWeight: %f, useLimit: %d, useArmCorrection: %d, isDirty: %d", damping, stiffness, spring, pendulum, pendulumRange, average, rootWeight, useLimit, useArmCorrection, isDirty); + if (!Config::bUseLimit) { + Il2cppUtils::ClassSetFieldValue(limitInfo, limitInfo_useLimit_field, 0); + } + else { + Il2cppUtils::ClassSetFieldValue(limitInfo, limitInfo_useLimit_field, 1); + auto axisX = Il2cppUtils::ClassGetFieldValue(limitInfo, limitInfo_axisX_field); + auto axisY = Il2cppUtils::ClassGetFieldValue(limitInfo, limitInfo_axisY_field); + auto axisZ = Il2cppUtils::ClassGetFieldValue(limitInfo, limitInfo_axisZ_field); + axisX.m_X *= Config::bLimitXx; + axisX.m_Y *= Config::bLimitXy; + axisY.m_X *= Config::bLimitYx; + axisY.m_Y *= Config::bLimitYy; + axisZ.m_X *= Config::bLimitZx; + axisZ.m_Y *= Config::bLimitZy; + Il2cppUtils::ClassSetFieldValue(limitInfo, limitInfo_axisX_field, axisX); + Il2cppUtils::ClassSetFieldValue(limitInfo, limitInfo_axisY_field, axisY); + Il2cppUtils::ClassSetFieldValue(limitInfo, limitInfo_axisZ_field, axisZ); + + } - Il2cppUtils::ClassSetFieldValue(limitInfo, limitInfo_useLimit_field, Config::bUseLimit); Il2cppUtils::ClassSetFieldValue(bone, damping_field, Config::bDamping); Il2cppUtils::ClassSetFieldValue(bone, stiffness_field, Config::bStiffness); Il2cppUtils::ClassSetFieldValue(bone, spring_field, Config::bSpring); diff --git a/app/src/main/cpp/GakumasLocalify/config/Config.cpp b/app/src/main/cpp/GakumasLocalify/config/Config.cpp index 40108e0..dae0fcd 100644 --- a/app/src/main/cpp/GakumasLocalify/config/Config.cpp +++ b/app/src/main/cpp/GakumasLocalify/config/Config.cpp @@ -29,7 +29,6 @@ namespace GakumasLocal::Config { int lodQualityLevel = 4; bool enableBreastParam = false; - int bUseLimit = 1; float bDamping = 0.33f; float bStiffness = 0.08f; float bSpring = 1.0f; @@ -40,6 +39,13 @@ namespace GakumasLocal::Config { bool bUseArmCorrection = true; bool bUseScale = false; float bScale = 1.0f; + bool bUseLimit = true; + float bLimitXx = 1.0f; + float bLimitXy = 1.0f; + float bLimitYx = 1.0f; + float bLimitYy = 1.0f; + float bLimitZx = 1.0f; + float bLimitZy = 1.0f; void LoadConfig(const std::string& configStr) { try { @@ -68,7 +74,6 @@ namespace GakumasLocal::Config { GetConfigItem(reflectionQualityLevel); GetConfigItem(lodQualityLevel); GetConfigItem(enableBreastParam); - GetConfigItem(bUseLimit); GetConfigItem(bDamping); GetConfigItem(bStiffness); GetConfigItem(bSpring); @@ -79,6 +84,13 @@ namespace GakumasLocal::Config { GetConfigItem(bUseArmCorrection); GetConfigItem(bUseScale); GetConfigItem(bScale); + GetConfigItem(bUseLimit); + GetConfigItem(bLimitXx); + GetConfigItem(bLimitXy); + GetConfigItem(bLimitYx); + GetConfigItem(bLimitYy); + GetConfigItem(bLimitZx); + GetConfigItem(bLimitZy); } catch (std::exception& e) { diff --git a/app/src/main/cpp/GakumasLocalify/config/Config.hpp b/app/src/main/cpp/GakumasLocalify/config/Config.hpp index 8a4bec9..38aaa64 100644 --- a/app/src/main/cpp/GakumasLocalify/config/Config.hpp +++ b/app/src/main/cpp/GakumasLocalify/config/Config.hpp @@ -28,7 +28,6 @@ namespace GakumasLocal::Config { extern int lodQualityLevel; extern bool enableBreastParam; - extern int bUseLimit; extern float bDamping; extern float bStiffness; extern float bSpring; @@ -39,6 +38,13 @@ namespace GakumasLocal::Config { extern bool bUseArmCorrection; extern bool bUseScale; extern float bScale; + extern bool bUseLimit; + extern float bLimitXx; + extern float bLimitXy; + extern float bLimitYx; + extern float bLimitYy; + extern float bLimitZx; + extern float bLimitZy; void LoadConfig(const std::string& configStr); } diff --git a/app/src/main/cpp/deps/UnityResolve/UnityResolve.hpp b/app/src/main/cpp/deps/UnityResolve/UnityResolve.hpp index d199bf5..e49b779 100644 --- a/app/src/main/cpp/deps/UnityResolve/UnityResolve.hpp +++ b/app/src/main/cpp/deps/UnityResolve/UnityResolve.hpp @@ -983,7 +983,75 @@ public: auto operator ==(const Vector2 x) const -> bool { return this->x == x.x && this->y == x.y; } }; - struct Vector4 { + struct Vector2Int { + int m_X, m_Y; + + Vector2Int() { m_X = m_Y = 0; } + + Vector2Int(const int f1, const int f2) { + m_X = f1; + m_Y = f2; + } + + [[nodiscard]] auto Distance(const Vector2Int& event) const -> float { + const auto dx = this->m_X - event.m_X; + const auto dy = this->m_Y - event.m_Y; + return std::sqrt(dx * dx + dy * dy); + } + + auto operator*(const int x) -> Vector2Int { + this->m_X *= x; + this->m_Y *= x; + return *this; + } + + auto operator/(const int x) -> Vector2Int { + this->m_X /= x; + this->m_Y /= x; + return *this; + } + + auto operator+(const int x) -> Vector2Int { + this->m_X += x; + this->m_Y += x; + return *this; + } + + auto operator-(const int x) -> Vector2Int { + this->m_X -= x; + this->m_Y -= x; + return *this; + } + + auto operator*(const Vector2Int x) -> Vector2Int { + this->m_X *= x.m_X; + this->m_Y *= x.m_Y; + return *this; + } + + auto operator-(const Vector2Int x) -> Vector2Int { + this->m_X -= x.m_X; + this->m_Y -= x.m_Y; + return *this; + } + + auto operator+(const Vector2Int x) -> Vector2Int { + this->m_X += x.m_X; + this->m_Y += x.m_Y; + return *this; + } + + auto operator/(const Vector2Int x) -> Vector2Int { + this->m_X /= x.m_X; + this->m_Y /= x.m_Y; + return *this; + } + + auto operator ==(const Vector2Int x) const -> bool { return this->m_X == x.m_X && this->m_Y == x.m_Y; } + }; + + + struct Vector4 { float x, y, z, w; Vector4() { x = y = z = w = 0.F; } diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt index 031a3f7..457fdf4 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt @@ -35,7 +35,13 @@ interface ConfigListener { fun onBPendulumRangeChanged(s: CharSequence, start: Int, before: Int, count: Int) fun onBAverageChanged(s: CharSequence, start: Int, before: Int, count: Int) fun onBRootWeightChanged(s: CharSequence, start: Int, before: Int, count: Int) - fun onBUseLimitChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBUseLimitChanged(value: Boolean) + fun onBLimitXxChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBLimitXyChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBLimitYxChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBLimitYyChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBLimitZxChanged(s: CharSequence, start: Int, before: Int, count: Int) + fun onBLimitZyChanged(s: CharSequence, start: Int, before: Int, count: Int) fun onBScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) fun onBUseArmCorrectionChanged(value: Boolean) fun onBUseScaleChanged(value: Boolean) @@ -332,17 +338,74 @@ interface ConfigUpdateListener: ConfigListener { saveConfig() } - override fun onBUseLimitChanged(s: CharSequence, start: Int, before: Int, count: Int){ - binding.config!!.bUseLimit = try { - s.toString().toInt() + override fun onBUseLimitChanged(value: Boolean){ + binding.config!!.bUseLimit = value + saveConfig() + checkConfigAndUpdateView() + } + + override fun onBLimitXxChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.bLimitXx = try { + s.toString().toFloat() } catch (e: Exception) { - 0 + 0f } saveConfig() } - override fun onBScaleChanged(s: CharSequence, start: Int, before: Int, count: Int){ + override fun onBLimitXyChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.bLimitXy = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBLimitYxChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.bLimitYx = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBLimitYyChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.bLimitYy = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBLimitZxChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.bLimitZx = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + override fun onBLimitZyChanged(s: CharSequence, start: Int, before: Int, count: Int) { + binding.config!!.bLimitZy = try { + s.toString().toFloat() + } + catch (e: Exception) { + 0f + } + saveConfig() + } + + + override fun onBScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) { binding.config!!.bScale = try { s.toString().toFloat() } @@ -351,18 +414,26 @@ interface ConfigUpdateListener: ConfigListener { } saveConfig() } + override fun onBClickPresetChanged(index: Int) { val setData: FloatArray = when (index) { // 0.33, 0.08, 0.7, 0.12, 0.25, 0.2, 0.8, 0, noUseArm 啥玩意 - 0 -> floatArrayOf(0.33f, 0.07f, 0.7f, 0.06f, 0.25f, 0.2f, 0.5f, 1f) - 1 -> floatArrayOf(0.365f, 0.06f, 0.62f, 0.07f, 0.25f, 0.2f, 0.5f, 1f) - 2 -> floatArrayOf(0.4f, 0.065f, 0.55f, 0.075f, 0.25f, 0.2f, 0.5f, 1f) - 3 -> floatArrayOf(0.4f, 0.065f, 0.55f, 0.075f, 0.25f, 0.2f, 0.5f, 0f) - 4 -> floatArrayOf(0.4f, 0.06f, 0.4f, 0.075f, 0.55f, 0.2f, 0.8f, 0f) + 0 -> floatArrayOf(0.33f, 0.07f, 0.7f, 0.06f, 0.25f, 0.2f, 0.5f, + 1f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f) + 1 -> floatArrayOf(0.365f, 0.06f, 0.62f, 0.07f, 0.25f, 0.2f, 0.5f, + 1f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f) + 2 -> floatArrayOf(0.4f, 0.065f, 0.55f, 0.075f, 0.25f, 0.2f, 0.5f, + 1f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f) + 3 -> floatArrayOf(0.4f, 0.065f, 0.55f, 0.075f, 0.25f, 0.2f, 0.5f, + 1f, 4.0f, 4.0f, 4.0f, 4.0f, 4.0f, 3.0f) + 4 -> floatArrayOf(0.4f, 0.06f, 0.4f, 0.075f, 0.55f, 0.2f, 0.8f, + 1f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 3.5f) - 5 -> floatArrayOf(0.33f, 0.08f, 0.8f, 0.12f, 0.55f, 0.2f, 1.0f, 0f) + 5 -> floatArrayOf(0.33f, 0.08f, 0.8f, 0.12f, 0.55f, 0.2f, 1.0f, + 0f) - else -> floatArrayOf(0.33f, 0.08f, 1.0f, 0.055f, 0.15f, 0.2f, 0.5f, 1f) + else -> floatArrayOf(0.33f, 0.08f, 1.0f, 0.055f, 0.15f, 0.2f, 0.5f, + 1f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f) } binding.config!!.bDamping = setData[0] @@ -372,7 +443,19 @@ interface ConfigUpdateListener: ConfigListener { binding.config!!.bPendulumRange = setData[4] binding.config!!.bAverage = setData[5] binding.config!!.bRootWeight = setData[6] - binding.config!!.bUseLimit = setData[7].toInt() + binding.config!!.bUseLimit = if (setData[7] == 0f) { + false + } + else { + binding.config!!.bLimitXx = setData[8] + binding.config!!.bLimitXy = setData[9] + binding.config!!.bLimitYx = setData[10] + binding.config!!.bLimitYy = setData[11] + binding.config!!.bLimitZx = setData[12] + binding.config!!.bLimitZy = setData[13] + true + } + binding.config!!.bUseArmCorrection = true checkConfigAndUpdateView() diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt index beb5763..af45b52 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt @@ -25,7 +25,6 @@ data class GakumasConfig ( var lodQualityLevel: Int = 4, // 0~5 var enableBreastParam: Boolean = false, - var bUseLimit: Int = 1, var bDamping: Float = 0.33f, var bStiffness: Float = 0.08f, var bSpring: Float = 1.0f, @@ -35,5 +34,12 @@ data class GakumasConfig ( var bRootWeight: Float = 0.5f, var bUseArmCorrection: Boolean = true, var bUseScale: Boolean = false, - var bScale: Float = 1.0f + var bScale: Float = 1.0f, + var bUseLimit: Boolean = true, + var bLimitXx: Float = 1.0f, + var bLimitXy: Float = 1.0f, + var bLimitYx: Float = 1.0f, + var bLimitYy: Float = 1.0f, + var bLimitZx: Float = 1.0f, + var bLimitZy: Float = 1.0f, ) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index b2217bf..fb5dd05 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -861,7 +861,7 @@ + android:weightSum="1"> - - - - - - - - @@ -975,6 +952,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 1c75d80..76a9cd1 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -32,9 +32,16 @@ 钟摆范围 (PendulumRange) Average RootWeight - 限制范围 (0/1) + 范围限制倍率 (0 为不限制, 1 为原版) 使用手臂矫正 IsDirty 应用缩放 胸部缩放倍率 + 启用范围限制倍率 + axisX.x + axisY.x + axisZ.x + axisX.y + axisY.y + axisZ.y \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6b6c102..0de9161 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -32,10 +32,17 @@ Pendulum Range Average Root Weight - Use Limit (0/1) + Limit Range Multiplier (0 is Unlimited) Use Arm Correction IsDirty Use Breast Scale Breast Scale + Use Limit Multiplier + axisX.x + axisY.x + axisZ.x + axisX.y + axisY.y + axisZ.y \ No newline at end of file