diff --git a/builds/android/app/src/gamebrowser/org_easyrpg_player_game_browser.cpp b/builds/android/app/src/gamebrowser/org_easyrpg_player_game_browser.cpp index 15e1954f35..dc3ded6f8a 100644 --- a/builds/android/app/src/gamebrowser/org_easyrpg_player_game_browser.cpp +++ b/builds/android/app/src/gamebrowser/org_easyrpg_player_game_browser.cpp @@ -364,6 +364,11 @@ Java_org_easyrpg_player_game_1browser_GameScanner_findGames(JNIEnv *env, jclass, env->CallVoidMethod(jgame_object, jset_title_method, jtitle); } + // Set folder name + jstring jfolder = env->NewStringUTF(game_dir_name.c_str()); + jmethodID jset_folder_name_method = env->GetMethodID(jgame_class, "setGameFolderName", "(Ljava/lang/String;)V"); + env->CallVoidMethod(jgame_object, jset_folder_name_method, jfolder); + env->SetObjectArrayElement(jgame_array, i, jgame_object); } @@ -397,11 +402,6 @@ Java_org_easyrpg_player_game_1browser_Game_reencodeTitle(JNIEnv *env, jobject th if (encoding == "auto") { auto det_encodings = lcf::ReaderUtil::DetectEncodings(title); for (auto &det_enc: det_encodings) { - if (det_enc == "UTF-16BE" || det_enc == "UTF-16LE") { - // Skip obviously wrong title encodings - continue; - } - if (lcf::Encoder encoder(det_enc); encoder.IsOk()) { encoder.Encode(title); break; diff --git a/builds/android/app/src/main/java/org/easyrpg/player/button_mapping/VirtualButton.java b/builds/android/app/src/main/java/org/easyrpg/player/button_mapping/VirtualButton.java index 57ae8ebcdc..b2a2d40007 100644 --- a/builds/android/app/src/main/java/org/easyrpg/player/button_mapping/VirtualButton.java +++ b/builds/android/app/src/main/java/org/easyrpg/player/button_mapping/VirtualButton.java @@ -205,9 +205,17 @@ public char getAppropriateChar(int keyCode) { char charButton; if (keyCode == ENTER) { - charButton = 'A'; + if (SettingsManager.getShowZXasAB()) { + charButton = 'A'; + } else { + charButton = 'Z'; + } } else if (keyCode == CANCEL) { - charButton = 'B'; + if (SettingsManager.getShowZXasAB()) { + charButton = 'B'; + } else { + charButton = 'X'; + } } else if (keyCode == SHIFT) { charButton = 'S'; } else if (keyCode == KEY_0) { diff --git a/builds/android/app/src/main/java/org/easyrpg/player/game_browser/Game.java b/builds/android/app/src/main/java/org/easyrpg/player/game_browser/Game.java index fb2286582c..ce3df09710 100644 --- a/builds/android/app/src/main/java/org/easyrpg/player/game_browser/Game.java +++ b/builds/android/app/src/main/java/org/easyrpg/player/game_browser/Game.java @@ -16,10 +16,15 @@ public class Game implements Comparable { final static char escapeCode = '\u0001'; + final static String cacheVersion = "1"; /** The title shown in the Game Browser */ private String title; /** Bytes of the title string in an unspecified encoding */ private byte[] titleRaw = null; + /** Human readable version of the game directory. Shown in the game browser + * when the specific setting is enabled. + */ + private String gameFolderName; /** Path to the game folder (forwarded via --project-path */ private final String gameFolderPath; /** Relative path to the save directory, made absolute by launchGame (forwarded via --save-path) */ @@ -46,12 +51,20 @@ public Game(String gameFolderPath, String saveFolder, byte[] titleScreen) { this.isFavorite = isFavoriteFromSettings(); } - public String getTitle() { + public String getDisplayTitle() { String customTitle = getCustomTitle(); if (!customTitle.isEmpty()) { return customTitle; } + if (SettingsManager.getGameBrowserLabelMode() == 0) { + return getTitle(); + } else { + return gameFolderName; + } + } + + public String getTitle() { return title; } @@ -81,6 +94,14 @@ public void setSavePath(String path) { savePath = path; } + public String getGameFolderName() { + return gameFolderName; + } + + public void setGameFolderName(String gameFolderName) { + this.gameFolderName = gameFolderName; + } + public boolean isFavorite() { return isFavorite; } @@ -106,7 +127,7 @@ public int compareTo(Game game) { if (!this.isFavorite() && game.isFavorite()) { return 1; } - return this.getTitle().compareTo(game.getTitle()); + return this.getDisplayTitle().compareTo(game.getDisplayTitle()); } /** @@ -149,35 +170,37 @@ public void setStandalone(boolean standalone) { @NonNull @Override public String toString() { - return getTitle(); + return getDisplayTitle(); } public static Game fromCacheEntry(Context context, String cache) { String[] entries = cache.split(String.valueOf(escapeCode)); - if (entries.length != 5) { + if (entries.length != 7 || !entries[0].equals(cacheVersion)) { return null; } - String savePath = entries[0]; - DocumentFile gameFolder = DocumentFile.fromTreeUri(context, Uri.parse(entries[1])); + String savePath = entries[1]; + DocumentFile gameFolder = DocumentFile.fromTreeUri(context, Uri.parse(entries[2])); if (gameFolder == null) { return null; } - String title = entries[2]; + String gameFolderName = entries[3]; + + String title = entries[4]; byte[] titleRaw = null; - if (!entries[3].equals("null")) { - titleRaw = Base64.decode(entries[3], 0); + if (!entries[5].equals("null")) { + titleRaw = Base64.decode(entries[5], 0); } byte[] titleScreen = null; - if (!entries[4].equals("null")) { - titleScreen = Base64.decode(entries[4], 0); + if (!entries[6].equals("null")) { + titleScreen = Base64.decode(entries[6], 0); } - Game g = new Game(entries[1], savePath, titleScreen); + Game g = new Game(entries[2], savePath, titleScreen); g.setTitle(title); g.titleRaw = titleRaw; @@ -185,6 +208,8 @@ public static Game fromCacheEntry(Context context, String cache) { g.reencodeTitle(); } + g.setGameFolderName(gameFolderName); + return g; } @@ -192,19 +217,23 @@ public String toCacheEntry() { StringBuilder sb = new StringBuilder(); // Cache structure: savePath | gameFolderPath | title | titleRaw | titleScreen - sb.append(savePath); + sb.append(cacheVersion); // 0 sb.append(escapeCode); - sb.append(gameFolderPath); + sb.append(savePath); // 1 sb.append(escapeCode); - sb.append(title); + sb.append(gameFolderPath); // 2 sb.append(escapeCode); - if (titleRaw != null) { + sb.append(gameFolderName); // 3 + sb.append(escapeCode); + sb.append(title); // 4 + sb.append(escapeCode); + if (titleRaw != null) { // 5 sb.append(Base64.encodeToString(titleRaw, Base64.NO_WRAP)); } else { sb.append("null"); } sb.append(escapeCode); - if (titleScreen != null) { + if (titleScreen != null) { // 6 ByteArrayOutputStream baos = new ByteArrayOutputStream(); titleScreen.compress(Bitmap.CompressFormat.PNG, 90, baos); byte[] b = baos.toByteArray(); @@ -215,4 +244,5 @@ public String toCacheEntry() { return sb.toString(); } + } diff --git a/builds/android/app/src/main/java/org/easyrpg/player/game_browser/GameBrowserActivity.java b/builds/android/app/src/main/java/org/easyrpg/player/game_browser/GameBrowserActivity.java index f6fa1cb5dd..b4068bf4b4 100644 --- a/builds/android/app/src/main/java/org/easyrpg/player/game_browser/GameBrowserActivity.java +++ b/builds/android/app/src/main/java/org/easyrpg/player/game_browser/GameBrowserActivity.java @@ -131,7 +131,10 @@ public boolean onOptionsItemSelected(MenuItem item) { // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); - if (id == R.id.refresh) { + if (id == R.id.view) { + openView(); + return true; + } else if (id == R.id.refresh) { scanGamesAndDisplayResult(true); return true; } else if (id == R.id.menu) { @@ -161,6 +164,26 @@ public boolean onNavigationItemSelected(MenuItem item) { return true; } + public void openView() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + + String[] choices_list = { + this.getResources().getString(R.string.view_show_game_title), + this.getResources().getString(R.string.view_show_game_folder) + }; + + builder + .setTitle(R.string.view_show_title_desc) + .setSingleChoiceItems(choices_list, SettingsManager.getGameBrowserLabelMode(), null) + .setPositiveButton(R.string.ok, (dialog, id) -> { + int selectedPosition = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); + SettingsManager.setGameBrowserLabelMode(selectedPosition); + displayGamesList(); + }) + .setNegativeButton(R.string.cancel, null); + builder.show(); + } + public void scanGamesAndDisplayResult(boolean forceScan) { // Verify that a scan isn't processing // TODO : Make the use of isScanProcessing synchronized (not really useful) @@ -307,7 +330,7 @@ public void onBindViewHolder(final ViewHolder holder, final int position) { final Game game = gameList.get(position); // Title - holder.title.setText(game.getTitle()); + holder.title.setText(game.getDisplayTitle()); holder.title.setOnClickListener(v -> launchGame(position, false)); // TitleScreen Image @@ -391,7 +414,7 @@ public void chooseRegion(final Context context, final ViewHolder holder, final G if (!selectedEncoding.equals(encoding)) { game.setEncoding(selectedEncoding); - holder.title.setText(game.getTitle()); + holder.title.setText(game.getDisplayTitle()); } }) .setNegativeButton(R.string.cancel, null); @@ -411,12 +434,12 @@ public void renameGame(final Context context, final ViewHolder holder, final Gam .setTitle(R.string.game_rename) .setPositiveButton(R.string.ok, (dialog, id) -> { game.setCustomTitle(input.getText().toString()); - holder.title.setText(game.getTitle()); + holder.title.setText(game.getDisplayTitle()); }) .setNegativeButton(R.string.cancel, null) .setNeutralButton(R.string.revert, (dialog, id) -> { game.setCustomTitle(""); - holder.title.setText(game.getTitle()); + holder.title.setText(game.getDisplayTitle()); }); builder.show(); } diff --git a/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsEnum.java b/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsEnum.java index d06a03c0ba..fd95651fc4 100644 --- a/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsEnum.java +++ b/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsEnum.java @@ -27,8 +27,9 @@ enum SettingsEnum { FONT1_URI("Font1"), FONT2_URI("Font2"), FONT1_SIZE("Font1Size"), - FONT2_SIZE("Font2Size") - + FONT2_SIZE("Font2Size"), + GAME_BROWSER_LABEL_MODE("GAME_BROWSER_LABEL_MODE"), + SHOW_ZX_AS_AB("SHOW_ZX_AS_AB") ; diff --git a/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsInputActivity.java b/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsInputActivity.java index 924c3b4d62..4c7bcbd3ee 100644 --- a/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsInputActivity.java +++ b/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsInputActivity.java @@ -37,6 +37,10 @@ public void onCreate(Bundle savedInstanceState) { enableVibrateWhenSlidingCheckbox.setChecked(SettingsManager.isVibrateWhenSlidingDirectionEnabled()); enableVibrateWhenSlidingCheckbox.setOnClickListener(this); + CheckBox showZXasABcheckbox = findViewById(R.id.settings_show_zx_as_ab); + showZXasABcheckbox.setChecked(SettingsManager.getShowZXasAB()); + showZXasABcheckbox.setOnClickListener(this); + configureFastForwardButton(); configureLayoutTransparencySystem(); configureLayoutSizeSystem(); @@ -57,6 +61,8 @@ public void onClick(View v) { enableVibrateWhenSlidingCheckbox.setEnabled(c.isChecked()); } else if (id == R.id.settings_vibrate_when_sliding){ SettingsManager.setVibrateWhenSlidingDirectionEnabled(((CheckBox) v).isChecked()); + } else if (id == R.id.settings_show_zx_as_ab) { + SettingsManager.setShowZXasAB(((CheckBox)v).isChecked()); } } diff --git a/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsManager.java b/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsManager.java index 0c414d7ba1..b4052c858a 100644 --- a/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsManager.java +++ b/builds/android/app/src/main/java/org/easyrpg/player/settings/SettingsManager.java @@ -50,6 +50,8 @@ public class SettingsManager { GAMES_FOLDER_NAME = "games", SAVES_FOLDER_NAME = "saves", FONTS_FOLDER_NAME = "fonts"; public static int FAST_FORWARD_MODE_HOLD = 0, FAST_FORWARD_MODE_TAP = 1; + private static int gameBrowserLabelMode = 0; + private static boolean showZXasAB = false; private static List imageSizeOption = Arrays.asList("nearest", "integer", "bilinear"); private static List gameResolutionOption = Arrays.asList("original", "widescreen", "ultrawide"); @@ -102,6 +104,10 @@ private static void loadSettings(Context context) { if (gameResolution == -1) { gameResolution = 0; } + + gameBrowserLabelMode = sharedPref.getInt(GAME_BROWSER_LABEL_MODE.toString(), 0); + + showZXasAB = sharedPref.getBoolean(SHOW_ZX_AS_AB.toString(), false); } public static Set getFavoriteGamesList() { @@ -488,4 +494,24 @@ public static void setSpeedModifierA(int speedModifierA) { configIni.input.set(SPEED_MODIFIER_A.toString(), speedModifierA); configIni.save(); } + + public static int getGameBrowserLabelMode() { + return gameBrowserLabelMode; + } + + public static void setGameBrowserLabelMode(int i) { + gameBrowserLabelMode = i; + editor.putInt(SettingsEnum.GAME_BROWSER_LABEL_MODE.toString(), i); + editor.commit(); + } + + public static boolean getShowZXasAB() { + return showZXasAB; + } + + public static void setShowZXasAB(boolean b) { + showZXasAB = b; + editor.putBoolean(SHOW_ZX_AS_AB.toString(), b); + editor.commit(); + } } diff --git a/builds/android/app/src/main/res/drawable/ic_view_list_black.xml b/builds/android/app/src/main/res/drawable/ic_view_list_black.xml new file mode 100644 index 0000000000..5bd7d75227 --- /dev/null +++ b/builds/android/app/src/main/res/drawable/ic_view_list_black.xml @@ -0,0 +1,9 @@ + + + diff --git a/builds/android/app/src/main/res/drawable/ic_view_list_white.xml b/builds/android/app/src/main/res/drawable/ic_view_list_white.xml new file mode 100644 index 0000000000..66e48da984 --- /dev/null +++ b/builds/android/app/src/main/res/drawable/ic_view_list_white.xml @@ -0,0 +1,9 @@ + + + diff --git a/builds/android/app/src/main/res/layout/activity_settings_inputs.xml b/builds/android/app/src/main/res/layout/activity_settings_inputs.xml index 0e28455957..3c17030c59 100644 --- a/builds/android/app/src/main/res/layout/activity_settings_inputs.xml +++ b/builds/android/app/src/main/res/layout/activity_settings_inputs.xml @@ -25,6 +25,13 @@ android:text="@string/vibrate_when_sliding_direction" android:textSize="20sp"/> + + + diff --git a/builds/android/app/src/main/res/values/strings.xml b/builds/android/app/src/main/res/values/strings.xml index cc2cab0c65..1b18f85de4 100644 --- a/builds/android/app/src/main/res/values/strings.xml +++ b/builds/android/app/src/main/res/values/strings.xml @@ -50,6 +50,10 @@ The Download folder cannot be used as the EasyRPG folder. The selected folder contains other files and cannot be used as the EasyRPG folder. When you remove all files inside the folder you can use it as the EasyRPG folder. The selected folder cannot be used as the EasyRPG folder. This problem can occur for various reasons, for example if you have selected the root directory or a storage location in the cloud.\n\n + View + Choose how games are named + Use the title + Use the folder name Toggle virtual buttons @@ -93,6 +97,7 @@ Please tell us in detail what went wrong.\n\n Sound effect volume Input layout transparency: Ignore button size settings and use this instead: + Display Z and X buttons as A and B No read access on %1$s Quick access Fast-forward button mode: diff --git a/src/exe_reader.cpp b/src/exe_reader.cpp index 29eb08476c..4785f021a8 100644 --- a/src/exe_reader.cpp +++ b/src/exe_reader.cpp @@ -39,7 +39,7 @@ EXEReader::EXEReader(Filesystem_Stream::InputStream core) : corefile(std::move(c switch (machine) { case 0x14c: - file_info.machine_type = MachineType::i386; + file_info.machine_type = MachineType::x86; break; case 0x8664: file_info.machine_type = MachineType::amd64; diff --git a/src/exe_reader.h b/src/exe_reader.h index 80899cfc7e..15abb5ded8 100644 --- a/src/exe_reader.h +++ b/src/exe_reader.h @@ -45,13 +45,13 @@ class EXEReader { enum class MachineType { Unknown, - i386, + x86, amd64 }; static constexpr auto kMachineTypes = lcf::makeEnumTags( "Unknown", - "i386", + "x86", "amd64" );