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 0d79654
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 158 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 0d79654

Please sign in to comment.