Skip to content

Commit

Permalink
Android: Pass in the title through JNI, cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Ghabry committed May 23, 2024
1 parent 8de9de2 commit 03e2468
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,15 @@ jbyteArray readXyz(JNIEnv *env, std::istream& stream) {

extern "C"
JNIEXPORT jobject JNICALL
Java_org_easyrpg_player_game_1browser_GameScanner_findGames(JNIEnv *env, jclass clazz,
jstring jpath) {
Java_org_easyrpg_player_game_1browser_GameScanner_findGames(JNIEnv *env, jclass clazz, jstring jpath, jstring jmain_dir_name) {
EpAndroid::env = env;

const char* path = env->GetStringUTFChars(jpath, nullptr);
std::string spath(path);
env->ReleaseStringUTFChars(jpath, path);

std::vector<FilesystemView> fs_list = FileFinder::FindGames(FileFinder::Root().Create(spath));
auto root = FileFinder::Root().Create(spath);
std::vector<FilesystemView> fs_list = FileFinder::FindGames(root);

jclass jgame_class = env->FindClass("org/easyrpg/player/game_browser/Game");
jobjectArray jgame_array = env->NewObjectArray(fs_list.size(), jgame_class, nullptr);
Expand All @@ -180,15 +180,34 @@ Java_org_easyrpg_player_game_1browser_GameScanner_findGames(JNIEnv *env, jclass
return jgame_array;
}

jmethodID jgame_constructor = env->GetMethodID(jgame_class, "<init>", "(Ljava/lang/String;Ljava/lang/String;[B)V");
jmethodID jgame_constructor = env->GetMethodID(jgame_class, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[B)V");

bool game_in_main_dir = false;
if (fs_list.size() == 1) {
if (FileFinder::GetFullFilesystemPath(root) == FileFinder::GetFullFilesystemPath(fs_list[0])) {
game_in_main_dir = true;
}
}

for (size_t i = 0; i < fs_list.size(); ++i) {
auto& fs = fs_list[i];

std::string full_path = FileFinder::GetFullFilesystemPath(fs);
std::string title;
if (game_in_main_dir) {
// The main dir is URI encoded, the human readable name is in jmain_dir_name
const char* main_dir_name = env->GetStringUTFChars(jmain_dir_name, nullptr);
title = main_dir_name;
env->ReleaseStringUTFChars(jmain_dir_name, main_dir_name);
} else {
// In all other cases the folder name is "clean" and can be used
title = std::get<1>(FileFinder::GetPathAndFilename(fs.GetFullPath()));
}

std::string save_path;
if (!fs.IsFeatureSupported(Filesystem::Feature::Write)) {
// Is an archive and needs a redirected save path
save_path = std::get<1>(FileFinder::GetPathAndFilename(fs.GetFullPath()));
save_path = title;

// compatibility with original GameScanner Java code (everything after the extension dot is removed)
size_t ext = save_path.find('.');
Expand All @@ -198,25 +217,24 @@ Java_org_easyrpg_player_game_1browser_GameScanner_findGames(JNIEnv *env, jclass
}

// Very simple title graphic search: The first image in "Title" is used
auto title = fs.Subtree("Title");
auto title_fs = fs.Subtree("Title");
jbyteArray title_image = nullptr;
if (title) {
for (auto &[name, entry]: *title.ListDirectory()) {
if (title_fs) {
for (auto &[name, entry]: *title_fs.ListDirectory()) {
if (entry.type == DirectoryTree::FileType::Regular) {
if (StringView(name).ends_with(".xyz")) {
auto is = title.OpenInputStream(entry.name);
auto is = title_fs.OpenInputStream(entry.name);
title_image = readXyz(env, is);
} else if (StringView(name).ends_with(".png") ||
StringView(name).ends_with(".bmp")) {
auto is = title.OpenInputStream(entry.name);
auto is = title_fs.OpenInputStream(entry.name);
if (!is) {
// When opening of the image fails it is an unsupported archive format
// Skip this game
continue;
}

auto vec = Utils::ReadStream(is);

title_image = env->NewByteArray(vec.size());
env->SetByteArrayRegion(title_image, 0, vec.size(),
reinterpret_cast<jbyte *>(vec.data()));
Expand All @@ -226,10 +244,10 @@ Java_org_easyrpg_player_game_1browser_GameScanner_findGames(JNIEnv *env, jclass
}

// Create an instance of "Game"
jstring jgame_path = env->NewStringUTF(
("content://" + FileFinder::GetFullFilesystemPath(fs)).c_str());
jstring jgame_path = env->NewStringUTF(("content://" + full_path).c_str());
jstring jsave_path = env->NewStringUTF(save_path.c_str());
jobject jgame_object = env->NewObject(jgame_class, jgame_constructor, jgame_path, jsave_path, title_image);
jstring jtitle = env->NewStringUTF(title.c_str());
jobject jgame_object = env->NewObject(jgame_class, jgame_constructor, jgame_path, jsave_path, jtitle, title_image);

env->SetObjectArrayElement(jgame_array, i, jgame_object);
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 12 additions & 16 deletions builds/android/app/src/main/java/org/easyrpg/player/Helper.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class Helper {
/**
Expand Down Expand Up @@ -215,17 +214,21 @@ public static List<String> listChildrenDocumentID(Context context, Uri folderUri
return filesList;
}

/** List files (with DOCUMENT_ID and MIME_TYPE) in the folder pointed by "folderURI" */
public static List<String[]> listChildrenDocumentIDAndType(Context context, Uri folderUri){
/**
* List files in the folder pointed by "folderURI"
* @return Array of Document ID, mimeType, display name (filename)
*/
public static List<String[]> listChildrenDocuments(Context context, Uri folderUri){
final ContentResolver resolver = context.getContentResolver();
final Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(folderUri, DocumentsContract.getDocumentId(folderUri));
List<String[]> filesList = new ArrayList<>();
try {
Cursor c = resolver.query(childrenUri, new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID, DocumentsContract.Document.COLUMN_MIME_TYPE }, null, null, null);
Cursor c = resolver.query(childrenUri, new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID, DocumentsContract.Document.COLUMN_MIME_TYPE, DocumentsContract.Document.COLUMN_DISPLAY_NAME }, null, null, null);
while (c.moveToNext()) {
String documentID = c.getString(0);
String mimeType = c.getString(1);
filesList.add(new String[] {documentID, mimeType});
String fileName = c.getString(2);
filesList.add(new String[] {documentID, mimeType, fileName});
}
c.close();
} catch (Exception e) {
Expand All @@ -238,10 +241,10 @@ public static Uri findFileUri(Context context, Uri folderUri, String fileNameToF
final ContentResolver resolver = context.getContentResolver();
final Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(folderUri, DocumentsContract.getDocumentId(folderUri));
try {
Cursor c = resolver.query(childrenUri, new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID }, null, null, null);
Cursor c = resolver.query(childrenUri, new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID, DocumentsContract.Document.COLUMN_DISPLAY_NAME }, null, null, null);
while (c.moveToNext()) {
String documentID = c.getString(0);
String fileName = getFileNameFromDocumentID(documentID);
String fileName = c.getString(1);
if (fileName.equals(fileNameToFind)) {
Uri uri = DocumentsContract.buildDocumentUriUsingTree(folderUri, documentID);
c.close();
Expand All @@ -261,10 +264,10 @@ public static List<Uri> findFileUriWithRegex(Context context, Uri folderUri, Str
final ContentResolver resolver = context.getContentResolver();
final Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(folderUri, DocumentsContract.getDocumentId(folderUri));
try {
Cursor c = resolver.query(childrenUri, new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID }, null, null, null);
Cursor c = resolver.query(childrenUri, new String[] { DocumentsContract.Document.COLUMN_DOCUMENT_ID, DocumentsContract.Document.COLUMN_DISPLAY_NAME }, null, null, null);
while (c.moveToNext()) {
String documentID = c.getString(0);
String fileName = getFileNameFromDocumentID(documentID);
String fileName = c.getString(1);
if (fileName.matches(regex)) {
Uri uri = DocumentsContract.buildDocumentUriUsingTree(folderUri, documentID);
uriList.add(uri);
Expand All @@ -282,13 +285,6 @@ public static DocumentFile findFile(Context context, Uri folderUri, String fileN
return getFileFromURI(context, uri);
}

public static String getFileNameFromDocumentID(String documentID) {
if (documentID != null) {
return documentID.substring(documentID.lastIndexOf('/') + 1);
}
return "";
}

public static DocumentFile getFileFromURI (Context context, Uri fileURI) {
try {
return DocumentFile.fromTreeUri(context, fileURI);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ private void startGameStandalone() {
String saveDir = getExternalFilesDir(null).getAbsolutePath() + "/Save";
new File(saveDir).mkdirs();

Game project = new Game(gameDir, saveDir);
Game project = new Game(gameDir, saveDir, "", null);
project.setStandalone(true);
GameBrowserHelper.launchGame(this, project);
finish();
}
Expand Down
Loading

0 comments on commit 03e2468

Please sign in to comment.