diff --git a/android/app/src/main/java/io/github/kichikuou/system3/GameActivity.kt b/android/app/src/main/java/io/github/kichikuou/system3/GameActivity.kt
index 3ddda93..f01b960 100644
--- a/android/app/src/main/java/io/github/kichikuou/system3/GameActivity.kt
+++ b/android/app/src/main/java/io/github/kichikuou/system3/GameActivity.kt
@@ -22,6 +22,10 @@ import android.media.MediaPlayer
import android.os.Bundle
import android.text.InputType
import android.util.Log
+import android.view.ContextMenu
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
import android.widget.EditText
import org.libsdl.app.SDLActivity
import java.io.File
@@ -44,6 +48,7 @@ class GameActivity : SDLActivity() {
super.onCreate(savedInstanceState)
gameRoot = File(intent.getStringExtra(EXTRA_GAME_ROOT))
cdda = CddaPlayer(File(gameRoot, Launcher.PLAYLIST_FILE))
+ registerForContextMenu(mLayout)
}
override fun onStop() {
@@ -97,6 +102,34 @@ class GameActivity : SDLActivity() {
.show()
}
+ private var menuShown = false
+ private fun openMenu() {
+ if (menuShown)
+ return
+ openContextMenu(mLayout)
+ menuShown = true
+ }
+
+ override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
+ super.onCreateContextMenu(menu, v, menuInfo)
+ menuInflater.inflate(R.menu.game_menu, menu)
+ }
+
+ override fun onContextItemSelected(item: MenuItem): Boolean {
+ return when (item.itemId) {
+ R.id.quit_game -> {
+ finish()
+ true
+ }
+ else -> super.onOptionsItemSelected(item)
+ }
+ }
+
+ override fun onContextMenuClosed(menu: Menu?) {
+ super.onContextMenuClosed(menu)
+ menuShown = false
+ }
+
// The functions below are called in the SDL thread by JNI.
@Suppress("unused") fun cddaStart(track: Int, loop: Boolean) = cdda.start(track, loop)
@Suppress("unused") fun cddaStop() = cdda.stop()
@@ -118,6 +151,10 @@ class GameActivity : SDLActivity() {
}
return result[0]
}
+
+ @Suppress("unused") fun popupMenu() {
+ runOnUiThread { openMenu() }
+ }
}
private class CddaPlayer(private val playlistPath: File) {
diff --git a/android/app/src/main/res/menu/game_menu.xml b/android/app/src/main/res/menu/game_menu.xml
new file mode 100644
index 0000000..40698c6
--- /dev/null
+++ b/android/app/src/main/res/menu/game_menu.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/values-ja/strings.xml b/android/app/src/main/res/values-ja/strings.xml
index afe6f4f..cad5acd 100644
--- a/android/app/src/main/res/values-ja/strings.xml
+++ b/android/app/src/main/res/values-ja/strings.xml
@@ -3,6 +3,7 @@
System3
セーブデータをエクスポート
セーブデータをインポート
+ ゲーム終了
キャンセル
System3 のファイル (*.dat) が見つかりません。
ファイルを選択
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index 585392a..ccbb015 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -2,6 +2,7 @@
System3
Export Save Files
Import Save Files
+ Quit Game
Cancel
Cannot find System3 game files (*.dat).
Choose a file
@@ -11,7 +12,7 @@
Install from ZIP
Extracting %s
No save/ folder in the ZIP archive.
- OK
+ OK
Failed to export save files.
Imported successfully.
Exported successfully.
diff --git a/src/android/nact_android.cpp b/src/android/nact_android.cpp
index 1672a74..d303198 100644
--- a/src/android/nact_android.cpp
+++ b/src/android/nact_android.cpp
@@ -47,6 +47,15 @@ void NACT::output_console(const char *format, ...)
#endif
}
-void NACT::on_syswmevent(SDL_SysWMmsg* msg)
+bool NACT::handle_platform_event(const SDL_Event& e)
{
+ if (e.type == SDL_FINGERDOWN && SDL_GetNumTouchFingers(e.tfinger.touchId) == 3) {
+ JNILocalFrame jni(16);
+ if (jni.env()) {
+ jmethodID mid = jni.GetMethodID("popupMenu", "()V");
+ jni.env()->CallVoidMethod(jni.context(), mid);
+ return true;
+ }
+ }
+ return false;
}
diff --git a/src/emscripten/nact_emscripten.cpp b/src/emscripten/nact_emscripten.cpp
index 74c337f..d552e09 100644
--- a/src/emscripten/nact_emscripten.cpp
+++ b/src/emscripten/nact_emscripten.cpp
@@ -42,6 +42,7 @@ void NACT::output_console(const char *format, ...)
#endif
}
-void NACT::on_syswmevent(SDL_SysWMmsg* msg)
+bool NACT::handle_platform_event(const SDL_Event& e)
{
+ return false;
}
diff --git a/src/linux/nact_linux.cpp b/src/linux/nact_linux.cpp
index d9db398..537f2c3 100644
--- a/src/linux/nact_linux.cpp
+++ b/src/linux/nact_linux.cpp
@@ -24,6 +24,7 @@ void NACT::output_console(const char *format, ...)
#endif
}
-void NACT::on_syswmevent(SDL_SysWMmsg* msg)
+bool NACT::handle_platform_event(const SDL_Event& e)
{
+ return false;
}
diff --git a/src/sys/mako.h b/src/sys/mako.h
index 9e0db3e..42472a7 100644
--- a/src/sys/mako.h
+++ b/src/sys/mako.h
@@ -43,7 +43,7 @@ public:
#ifdef _WIN32
void select_sound(BGMDevice dev);
- void on_mci_notify(SDL_SysWMmsg* msg);
+ void on_mci_notify(const SDL_SysWMmsg* msg);
#endif
#ifdef __EMSCRIPTEN__
void select_synthesizer(bool use_fm);
diff --git a/src/sys/nact.h b/src/sys/nact.h
index 6b07a6c..46057eb 100644
--- a/src/sys/nact.h
+++ b/src/sys/nact.h
@@ -267,7 +267,7 @@ public:
private:
void pump_events();
- void on_syswmevent(SDL_SysWMmsg* msg);
+ bool handle_platform_event(const SDL_Event& e);
};
class NACT_Sys1 final : public NACT {
diff --git a/src/sys/nact_input.cpp b/src/sys/nact_input.cpp
index 2294e5d..ed874b7 100644
--- a/src/sys/nact_input.cpp
+++ b/src/sys/nact_input.cpp
@@ -19,6 +19,9 @@ void NACT::pump_events()
{
SDL_Event e;
while (SDL_PollEvent(&e)) {
+ if (handle_platform_event(e))
+ continue;
+
switch (e.type) {
case SDL_QUIT:
terminate = true;
@@ -40,10 +43,6 @@ void NACT::pump_events()
case SDL_APP_DIDENTERFOREGROUND:
ags->flush_screen(false);
break;
-
- case SDL_SYSWMEVENT:
- on_syswmevent(e.syswm.msg);
- break;
}
}
}
diff --git a/src/win/mako.cpp b/src/win/mako.cpp
index 377be9e..f6d143f 100644
--- a/src/win/mako.cpp
+++ b/src/win/mako.cpp
@@ -200,7 +200,7 @@ public:
return playing;
}
- bool on_mci_notify(SDL_SysWMmsg* msg) {
+ bool on_mci_notify(const SDL_SysWMmsg* msg) {
if (msg->msg.win.lParam != mci_thread->device_id())
return true;
switch (msg->msg.win.wParam) {
@@ -421,7 +421,7 @@ bool MAKO::check_pcm()
return !PlaySound(null_wav, NULL, SND_ASYNC | SND_MEMORY | SND_NOSTOP);
}
-void MAKO::on_mci_notify(SDL_SysWMmsg* msg)
+void MAKO::on_mci_notify(const SDL_SysWMmsg* msg)
{
if (!music)
return;
diff --git a/src/win/nact_win.cpp b/src/win/nact_win.cpp
index 5027378..974b7e5 100644
--- a/src/win/nact_win.cpp
+++ b/src/win/nact_win.cpp
@@ -130,8 +130,12 @@ void NACT::output_console(const char *format, ...)
#endif
}
-void NACT::on_syswmevent(SDL_SysWMmsg* msg)
+bool NACT::handle_platform_event(const SDL_Event& e)
{
+ if (e.type != SDL_SYSWMEVENT)
+ return false;
+ const SDL_SysWMmsg* msg = e.syswm.msg;
+
switch (msg->msg.win.msg) {
case WM_COMMAND:
switch (msg->msg.win.wParam) {
@@ -171,4 +175,5 @@ void NACT::on_syswmevent(SDL_SysWMmsg* msg)
mako->on_mci_notify(msg);
break;
}
+ return true;
}