This commit is contained in:
wheremyfoodat 2024-02-17 11:33:58 +02:00
parent 5ec6d8a5d5
commit c8db0098f5
12 changed files with 51 additions and 55 deletions

View file

@ -1,6 +1,5 @@
#pragma once
class AndroidUtils {
public:
static int openDocument(const char* directory, const char* mode);
};
namespace AndroidUtils {
int openDocument(const char* directory, const char* mode);
}

View file

@ -41,7 +41,8 @@ bool IOFile::open(const char* filename, const char* permissions) {
#ifdef __ANDROID__
std::string path(filename);
if(path.find("://") != std::string::npos){ //IF SAF URI
// Check if this is a URI directory, which will need special handling due to SAF
if (path.find("://") != std::string::npos ) {
handle = fdopen(AndroidUtils::openDocument(filename, permissions), permissions);
} else {
handle = std::fopen(filename, permissions);
@ -49,6 +50,7 @@ bool IOFile::open(const char* filename, const char* permissions) {
#else
handle = std::fopen(filename, permissions);
#endif
return isOpen();
}

View file

@ -32,17 +32,15 @@ public class AlberDriver {
public static native void setShaderJitEnabled(boolean enable);
public static int openDocument(String path, String mode){
public static int openDocument(String path, String mode) {
try {
mode = FileUtils.parseNativeMode(mode);
Context context = PandroidApplication.getAppContext();
Uri uri = FileUtils.obtainUri(path);
ParcelFileDescriptor parcel;
if (Objects.equals(uri.getScheme(), "game")) {
if (mode.contains("w")){
throw new IllegalArgumentException("Cannot write to rom-fs");
if (mode.contains("w")) {
throw new IllegalArgumentException("Cannot open ROM file as writable");
}
uri = FileUtils.obtainUri(GameUtils.getCurrentGame().getRealPath());
}
@ -51,7 +49,7 @@ public class AlberDriver {
parcel.close();
return fd;
} catch (Exception e){
} catch (Exception e) {
throw new RuntimeException(e);
}
}

View file

@ -2,7 +2,6 @@ package com.panda3ds.pandroid.app;
import android.os.Bundle;
import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
@ -13,7 +12,6 @@ import com.panda3ds.pandroid.app.main.GamesFragment;
import com.panda3ds.pandroid.app.main.SearchFragment;
import com.panda3ds.pandroid.app.main.SettingsFragment;
public class MainActivity extends BaseActivity implements NavigationBarView.OnItemSelectedListener {
private final GamesFragment gamesFragment = new GamesFragment();
private final SearchFragment searchFragment = new SearchFragment();

View file

@ -105,7 +105,7 @@ public class DrawerFragment extends Fragment implements DrawerLayout.DrawerListe
close();
} else if (id == R.id.exit) {
requireActivity().finish();
} else if (id == R.id.lua_script){
} else if (id == R.id.lua_script) {
new LuaDialogFragment().show(getParentFragmentManager(), null);
} else if (id == R.id.change_orientation) {
boolean isLandscape = getResources().getDisplayMetrics().widthPixels > getResources().getDisplayMetrics().heightPixels;

View file

@ -21,10 +21,8 @@ import com.panda3ds.pandroid.utils.Constants;
import com.panda3ds.pandroid.utils.FileUtils;
import com.panda3ds.pandroid.utils.GameUtils;
import com.panda3ds.pandroid.view.gamesgrid.GamesGridView;
import java.util.UUID;
public class GamesFragment extends Fragment implements ActivityResultCallback<Uri> {
private final ActivityResultContracts.OpenDocument openRomContract = new ActivityResultContracts.OpenDocument();
private ActivityResultLauncher<String[]> pickFileRequest;
@ -62,32 +60,32 @@ public class GamesFragment extends Fragment implements ActivityResultCallback<Ur
String extension = FileUtils.extension(uri);
if (extension.equals("elf") || extension.endsWith("axf")){
// For ELF and AXF files the emulator core uses the C++ iostreams API to be compatible with elfio unlike other file types
// As such, instead of writing more SAF code for operating with iostreams we just copy the ELF/AXF file to our own private directory
// And use it without caring about SAF
if (extension.equals("elf") || extension.endsWith("axf")) {
importELF(uri);
} else {
FileUtils.makeUriPermanent(uri, FileUtils.MODE_READ);
importGame(uri);
GameMetadata game = new GameMetadata(uri, FileUtils.getName(uri).split("\\.")[0], getString(R.string.unknown));
GameUtils.addGame(game);
GameUtils.launch(requireActivity(), game);
}
}
}
}
private void importGame(String uri){
GameMetadata game = new GameMetadata(uri, FileUtils.getName(uri).split("\\.")[0], getString(R.string.unknown));
GameUtils.addGame(game);
GameUtils.launch(requireActivity(), game);
}
private void importELF(String uri) {
AlertDialog dialog = new LoadingAlertDialog(requireActivity(), R.string.loading).create();
dialog.show();
new Task(()->{
new Task(() -> {
String uuid = UUID.randomUUID().toString() + "." + FileUtils.extension(uri);
String name = FileUtils.getName(uri);
FileUtils.copyFile(uri, FileUtils.getResourcePath(Constants.RESOURCE_FOLDER_ELF), uuid);
gameListView.post(()->{
gameListView.post(() -> {
dialog.hide();
GameMetadata game = new GameMetadata("elf://"+uuid, name.substring(0, name.length()-4).trim(), "");
GameMetadata game = new GameMetadata("elf://" + uuid, name.substring(0, name.length() - 4).trim(), "");
GameUtils.addGame(game);
GameUtils.launch(requireActivity(), game);
});

View file

@ -43,7 +43,7 @@ public class GameMetadata {
return romPath;
}
public String getRealPath(){
public String getRealPath() {
return GameUtils.resolvePath(romPath);
}

View file

@ -39,7 +39,7 @@ public class FileUtils {
return parseFile(path).getName();
}
public static String getResourcesPath(){
public static String getResourcesPath() {
File file = new File(getPrivatePath(), "config/resources");
if (!file.exists()) {
file.mkdirs();
@ -48,7 +48,7 @@ public class FileUtils {
return file.getAbsolutePath();
}
public static String getResourcePath(String name){
public static String getResourcePath(String name) {
File file = new File(getResourcesPath(), name);
file.mkdirs();
@ -73,9 +73,9 @@ public class FileUtils {
return file.getAbsolutePath();
}
public static String parseNativeMode(String mode){
public static String parseNativeMode(String mode) {
mode = mode.toLowerCase();
switch (mode){
switch (mode) {
case "r":
case "rb":
return "r";
@ -98,7 +98,7 @@ public class FileUtils {
return parseFile(path).exists();
}
public static void rename(String path, String newName){
public static void rename(String path, String newName) {
parseFile(path).renameTo(newName);
}
@ -234,7 +234,7 @@ public class FileUtils {
}
}
public static void updateFile(String path){
public static void updateFile(String path) {
DocumentFile file = parseFile(path);
Uri uri = file.getUri();
@ -260,12 +260,12 @@ public class FileUtils {
return parseFile(path).lastModified();
}
public static String[] listFiles(String path){
public static String[] listFiles(String path) {
DocumentFile folder = parseFile(path);
DocumentFile[] files = folder.listFiles();
String[] result = new String[files.length];
for (int i = 0; i < result.length; i++){
for (int i = 0; i < result.length; i++) {
result[i] = files[i].getName();
}
@ -278,7 +278,7 @@ public class FileUtils {
public static String extension(String uri) {
String name = getName(uri);
if (!name.contains(".")){
if (!name.contains(".")) {
return name.toLowerCase();
}
String[] parts = name.split("\\.");
@ -302,7 +302,7 @@ public class FileUtils {
out.flush();
out.close();
in.close();
} catch (Exception e){
} catch (Exception e) {
Log.e(Constants.LOG_TAG, "ERROR ON COPY FILE", e);
return false;
}

View file

@ -63,13 +63,13 @@ public class GameUtils {
writeChanges();
}
public static String resolvePath(String path){
public static String resolvePath(String path) {
String lower = path.toLowerCase();
if (!lower.contains("://")){
if (!lower.contains("://")) {
return path;
}
Uri uri = Uri.parse(path);
switch (uri.getScheme().toLowerCase()){
switch (uri.getScheme().toLowerCase()) {
case "elf":{
return FileUtils.getResourcePath(Constants.RESOURCE_FOLDER_ELF)+"/"+uri.getAuthority();
}

View file

@ -93,7 +93,7 @@ public class BasicTextEditor extends AppCompatEditText {
super.scrollTo(scrollX, scrollY);
}
public void adjustScroll(){
public void adjustScroll() {
setScroll(getScrollX(), getScrollY());
}

View file

@ -3,16 +3,17 @@ package com.panda3ds.pandroid.view.code.syntax;
import java.util.regex.Pattern;
class PatternUtils {
public static Pattern buildGenericKeywords(String... keywords){
StringBuilder builder = new StringBuilder();
builder.append("\\b(");
for (int i = 0; i < keywords.length; i++){
builder.append(keywords[i]);
if (i+1 != keywords.length){
builder.append("|");
}
}
builder.append(")\\b");
return Pattern.compile(builder.toString());
}
public static Pattern buildGenericKeywords(String... keywords) {
StringBuilder builder = new StringBuilder();
builder.append("\\b(");
for (int i = 0; i < keywords.length; i++) {
builder.append(keywords[i]);
if (i + 1 != keywords.length) {
builder.append("|");
}
}
builder.append(")\\b");
return Pattern.compile(builder.toString());
}
}

View file

@ -34,7 +34,7 @@ public class PerformanceView extends AppCompatTextView {
setShadowLayer(padding,0,0,Color.BLACK);
}
public void refresh(){
public void refresh() {
running = isShown();
if (!running) {
return;