diff --git a/app/src/main/cpp/GakumasLocalify/Hook.cpp b/app/src/main/cpp/GakumasLocalify/Hook.cpp index 47c44b8..fb6dc25 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); @@ -770,6 +779,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 65fef6c..d4dc9e6 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 + Orientation Lock + \ No newline at end of file