1
0

add feature: orientation lock

This commit is contained in:
chinosk 2024-06-14 22:49:36 +08:00
parent d92831443f
commit 577c1b268a
No known key found for this signature in database
GPG Key ID: 00610B08C1BF7BE9
9 changed files with 632 additions and 483 deletions

View File

@ -221,6 +221,15 @@ namespace GakumasLocal::HookMain {
return Unity_set_position_Injected_Orig(_this, data); 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)) { DEFINE_HOOK(void, EndCameraRendering, (void* ctx, void* camera, void* method)) {
EndCameraRendering_Orig(ctx, camera, method); EndCameraRendering_Orig(ctx, camera, method);
@ -797,6 +806,10 @@ namespace GakumasLocal::HookMain {
ADD_HOOK(Internal_Log, Il2cppUtils::il2cpp_resolve_icall( ADD_HOOK(Internal_Log, Il2cppUtils::il2cpp_resolve_icall(
"UnityEngine.DebugLogHandler::Internal_Log(UnityEngine.LogType,UnityEngine.LogOption,System.String,UnityEngine.Object)")); "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( ADD_HOOK(Unity_set_position_Injected, Il2cppUtils::il2cpp_resolve_icall(
"UnityEngine.Transform::set_position_Injected(UnityEngine.Vector3&)")); "UnityEngine.Transform::set_position_Injected(UnityEngine.Vector3&)"));
ADD_HOOK(Unity_set_rotation_Injected, Il2cppUtils::il2cpp_resolve_icall( ADD_HOOK(Unity_set_rotation_Injected, Il2cppUtils::il2cpp_resolve_icall(

View File

@ -9,6 +9,7 @@ namespace GakumasLocal::Config {
bool enabled = true; bool enabled = true;
bool forceExportResource = true; bool forceExportResource = true;
bool textTest = false; bool textTest = false;
int gameOrientation = 0;
bool dumpText = false; bool dumpText = false;
bool enableFreeCamera = false; bool enableFreeCamera = false;
int targetFrameRate = 0; int targetFrameRate = 0;
@ -35,6 +36,7 @@ namespace GakumasLocal::Config {
GetConfigItem(dbgMode); GetConfigItem(dbgMode);
GetConfigItem(enabled); GetConfigItem(enabled);
GetConfigItem(forceExportResource); GetConfigItem(forceExportResource);
GetConfigItem(gameOrientation);
GetConfigItem(textTest); GetConfigItem(textTest);
GetConfigItem(dumpText); GetConfigItem(dumpText);
GetConfigItem(targetFrameRate); GetConfigItem(targetFrameRate);

View File

@ -6,6 +6,7 @@ namespace GakumasLocal::Config {
extern bool dbgMode; extern bool dbgMode;
extern bool enabled; extern bool enabled;
extern bool forceExportResource; extern bool forceExportResource;
extern int gameOrientation;
extern bool textTest; extern bool textTest;
extern bool dumpText; extern bool dumpText;
extern bool enableFreeCamera; extern bool enableFreeCamera;

View File

@ -3,17 +3,17 @@ package io.github.chinosk.gakumas.localify
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
import android.view.View
import android.view.ViewTreeObserver
import android.widget.ScrollView
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.databinding.ObservableField import com.google.android.material.button.MaterialButton
import com.google.android.material.switchmaterial.SwitchMaterial import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonSyntaxException import com.google.gson.JsonSyntaxException
import io.github.chinosk.gakumas.localify.databinding.ActivityMainBinding import io.github.chinosk.gakumas.localify.databinding.ActivityMainBinding
@ -42,6 +42,7 @@ interface ConfigListener {
fun onChangePresetQuality(level: Int) fun onChangePresetQuality(level: Int)
fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int)
fun onLodQualityLevelChanged(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 onDumpTextChanged(value: Boolean)
} }
@ -65,6 +66,42 @@ class MainActivity : AppCompatActivity(), ConfigListener {
} }
} }
showVersion() showVersion()
val scrollView: ScrollView = findViewById(R.id.scrollView)
scrollView.viewTreeObserver.addOnScrollChangedListener { onScrollChanged() }
onScrollChanged()
val coordinatorLayout = findViewById<View>(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) { private fun showToast(message: String) {
@ -301,18 +338,22 @@ class MainActivity : AppCompatActivity(), ConfigListener {
binding.config!!.reflectionQualityLevel = 5 binding.config!!.reflectionQualityLevel = 5
} }
} }
binding.config = binding.config checkConfigAndUpdateView()
binding.notifyChange()
saveConfig() saveConfig()
} }
private fun showTextInputLayoutHint(view: TextInputLayout) { override fun onGameOrientationChanged(checkedId: Int) {
showToast(view.hint.toString()) 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() { private fun checkConfigAndUpdateView() {
val sw = findViewById<SwitchMaterial>(R.id.SwitchUnlockAllLive) binding.config = binding.config
sw.visibility = if (binding.config!!.dbgMode) android.view.View.VISIBLE else android.view.View.GONE binding.notifyChange()
} }
override fun dispatchKeyEvent(event: KeyEvent): Boolean { override fun dispatchKeyEvent(event: KeyEvent): Boolean {
@ -321,8 +362,7 @@ class MainActivity : AppCompatActivity(), ConfigListener {
val origDbg = binding.config?.dbgMode val origDbg = binding.config?.dbgMode
if (origDbg != null) { if (origDbg != null) {
binding.config!!.dbgMode = !origDbg binding.config!!.dbgMode = !origDbg
binding.config = binding.config checkConfigAndUpdateView()
binding.notifyChange()
saveConfig() saveConfig()
showToast("TestMode: ${!origDbg}") showToast("TestMode: ${!origDbg}")
} }

View File

@ -7,6 +7,7 @@ data class GakumasConfig (
var enabled: Boolean = true, var enabled: Boolean = true,
var textTest: Boolean = false, var textTest: Boolean = false,
var dumpText: Boolean = false, var dumpText: Boolean = false,
var gameOrientation: Int = 0,
var forceExportResource: Boolean = false, var forceExportResource: Boolean = false,
var enableFreeCamera: Boolean = false, var enableFreeCamera: Boolean = false,
var targetFrameRate: Int = 0, var targetFrameRate: Int = 0,

View File

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#000000" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M9.31,6.71c-0.39,0.39 -0.39,1.02 0,1.41L13.19,12l-3.88,3.88c-0.39,0.39 -0.39,1.02 0,1.41 0.39,0.39 1.02,0.39 1.41,0l4.59,-4.59c0.39,-0.39 0.39,-1.02 0,-1.41L10.72,6.7c-0.38,-0.38 -1.02,-0.38 -1.41,0.01z"/>
</vector>

View File

@ -10,6 +10,12 @@
type="io.github.chinosk.gakumas.localify.ConfigListener" /> type="io.github.chinosk.gakumas.localify.ConfigListener" />
</data> </data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -17,6 +23,7 @@
tools:context=".MainActivity"> tools:context=".MainActivity">
<ScrollView <ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
@ -244,6 +251,64 @@
</TableRow> </TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="4sp"
android:background="@drawable/table_row_border">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="10sp"
android:paddingRight="10sp"
android:paddingTop="10sp">
<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/orientation_lock"
android:textColor="@color/material_dynamic_neutral0"/>
<RadioGroup
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="3"
android:onCheckedChanged="@{(group, checkedId) -> listener.onGameOrientationChanged(checkedId)}">
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/radioButtonGameDefault"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="@{config.gameOrientation == 0}"
android:text="@string/orientation_orig" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/radioButtonGamePortrait"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="@{config.gameOrientation == 1}"
android:text="@string/orientation_portrait" />
<com.google.android.material.radiobutton.MaterialRadioButton
android:id="@+id/radioButtonGameLandscape"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="@{config.gameOrientation == 2}"
android:text="@string/orientation_landscape" />
</RadioGroup>
</LinearLayout>
</TableRow>
<TableRow <TableRow
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -539,4 +604,17 @@
</ScrollView> </ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabStartGame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/start_game"
android:visibility="gone"
android:onClick="@{() -> listener.onClickStartGame()}"
android:contentDescription="startGameFab" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout> </layout>

View File

@ -19,4 +19,8 @@
<string name="hign"></string> <string name="hign"></string>
<string name="middle"></string> <string name="middle"></string>
<string name="low"></string> <string name="low"></string>
<string name="orientation_orig">游戏原版</string>
<string name="orientation_portrait">竖屏</string>
<string name="orientation_landscape">横屏</string>
<string name="orientation_lock">方向锁定</string>
</resources> </resources>

View File

@ -19,4 +19,9 @@
<string name="hign">High</string> <string name="hign">High</string>
<string name="middle">Mid</string> <string name="middle">Mid</string>
<string name="low">Low</string> <string name="low">Low</string>
<string name="orientation_orig">Original</string>
<string name="orientation_portrait">Portrait</string>
<string name="orientation_landscape">Landscape</string>
<string name="orientation_lock">Original Lock</string>
</resources> </resources>