mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-03-02 19:16:56 +00:00
Add directory listings to VFS
This commit is contained in:
parent
d5fdf2271e
commit
0853b3ed8e
@ -26,7 +26,7 @@ public class NativeGLView extends GLSurfaceView implements SensorEventListener {
|
||||
public NativeGLView(NativeActivity activity) {
|
||||
super(activity);
|
||||
setEGLContextClientVersion(2);
|
||||
|
||||
/*
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
try {
|
||||
Method method_setPreserveEGLContextOnPause = GLSurfaceView.class.getMethod(
|
||||
@ -42,7 +42,7 @@ public class NativeGLView extends GLSurfaceView implements SensorEventListener {
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// setEGLConfigChooser(5, 5, 5, 0, 16, 0);
|
||||
// setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
|
||||
|
@ -140,23 +140,35 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
float zoom = 1.0f;
|
||||
bool tablet = false;
|
||||
bool aspect43 = false;
|
||||
const char *zoomenv = getenv("ZOOM");
|
||||
const char *tabletenv = getenv("TABLET");
|
||||
const char *ipad = getenv("IPAD");
|
||||
|
||||
if (zoomenv) {
|
||||
zoom = atof(zoomenv);
|
||||
}
|
||||
if (tabletenv) {
|
||||
tablet = (bool)atoi(tabletenv);
|
||||
}
|
||||
|
||||
if (ipad) aspect43 = true;
|
||||
|
||||
bool landscape;
|
||||
NativeGetAppInfo(&app_name, &app_name_nice, &landscape);
|
||||
|
||||
// Change these to temporarily test other resolutions.
|
||||
aspect43 = false;
|
||||
tablet = false;
|
||||
float density = 1.0f;
|
||||
zoom = 1.5f;
|
||||
|
||||
if (landscape) {
|
||||
if (tablet) {
|
||||
pixel_xres = 1280 * zoom;
|
||||
pixel_yres = 800 * zoom;
|
||||
} else if (aspect43) {
|
||||
pixel_xres = 1024 * zoom;
|
||||
pixel_yres = 768 * zoom;
|
||||
} else {
|
||||
pixel_xres = 800 * zoom;
|
||||
pixel_yres = 480 * zoom;
|
||||
@ -168,6 +180,9 @@ int main(int argc, char *argv[]) {
|
||||
if (tablet) {
|
||||
pixel_xres = 800 * zoom;
|
||||
pixel_yres = 1280 * zoom;
|
||||
} else if (aspect43) {
|
||||
pixel_xres = 768 * zoom;
|
||||
pixel_yres = 1024 * zoom;
|
||||
} else {
|
||||
pixel_xres = 480 * zoom;
|
||||
pixel_yres = 800 * zoom;
|
||||
@ -243,7 +258,6 @@ int main(int argc, char *argv[]) {
|
||||
NativeInit(argc, (const char **)argv, path, "/tmp", "BADCOFFEE");
|
||||
#endif
|
||||
|
||||
float density = 1.0f;
|
||||
dp_xres = (float)pixel_xres * density / zoom;
|
||||
dp_yres = (float)pixel_yres * density / zoom;
|
||||
pixel_in_dps = (float)pixel_xres / dp_xres;
|
||||
@ -344,8 +358,9 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
|
||||
// The speed difference is only really noticable on Linux. On Windows you do notice it though
|
||||
// exit(0);
|
||||
|
||||
#ifdef _WIN32
|
||||
exit(0);
|
||||
#endif
|
||||
NativeShutdownGraphics();
|
||||
SDL_PauseAudio(1);
|
||||
SDL_CloseAudio();
|
||||
|
@ -191,7 +191,7 @@ size_t getFilesInDir(const char *directory, std::vector<FileInfo> *files, const
|
||||
info.name = virtualName;
|
||||
info.fullName = std::string(directory) + "/" + virtualName;
|
||||
info.isDirectory = isDirectory(info.fullName);
|
||||
|
||||
info.exists = true;
|
||||
if (!info.isDirectory) {
|
||||
std::string ext = getFileExtension(info.fullName);
|
||||
if (filter) {
|
||||
|
@ -13,6 +13,7 @@ struct FileInfo
|
||||
{
|
||||
std::string name;
|
||||
std::string fullName;
|
||||
bool exists;
|
||||
bool isDirectory;
|
||||
|
||||
bool operator <(const FileInfo &other) const {
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "base/basictypes.h"
|
||||
#pragma once
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "file/file_util.h"
|
||||
// Basic virtual file system. Used to manage assets on Android, where we have to
|
||||
// read them manually out of the APK zipfile, while being able to run on other
|
||||
// platforms as well with the appropriate directory set-up.
|
||||
@ -13,3 +15,5 @@ void VFSShutdown();
|
||||
// Always allocates an extra zero byte at the end, so that it
|
||||
// can be used for text like shader sources.
|
||||
uint8_t *VFSReadFile(const char *filename, size_t *size);
|
||||
bool VFSGetFileListing(const char *path, std::vector<FileInfo> *listing, const char *filter = 0);
|
||||
//bool VFSGetFileInfo(const char *filename, FileInfo *fileInfo);
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef ANDROID
|
||||
#include <zip.h>
|
||||
#endif
|
||||
|
||||
@ -8,7 +10,7 @@
|
||||
#include "base/logging.h"
|
||||
#include "file/zip_read.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef ANDROID
|
||||
uint8_t *ReadFromZip(zip *archive, const char* filename, size_t *size) {
|
||||
// Figure out the file size first.
|
||||
struct zip_stat zstat;
|
||||
@ -49,23 +51,24 @@ uint8_t *ReadLocalFile(const char *filename, size_t *size) {
|
||||
return contents;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef ANDROID
|
||||
|
||||
ZipAssetReader::ZipAssetReader(const char *zip_file, const char *in_zip_path) {
|
||||
ELOG("ZIP File %s", zip_file);
|
||||
zip_file_ = zip_open(zip_file, 0, NULL);
|
||||
strcpy(in_zip_path_, in_zip_path);
|
||||
if (!zip_file_) {
|
||||
ELOG("Failed to open %s as a zip file", zip_file);
|
||||
}
|
||||
// This is not really necessary.
|
||||
int numFiles = zip_get_num_files(zip_file_);
|
||||
for (int i = 0; i < numFiles; i++) {
|
||||
const char* name = zip_get_name(zip_file_, i, 0);
|
||||
if (name == NULL) {
|
||||
ELOG("Error reading zip file name at index %i : %s", i, zip_strerror(zip_file_));
|
||||
return;
|
||||
|
||||
std::vector<FileInfo> info;
|
||||
GetFileListing("assets", &info, 0);
|
||||
for (int i = 0; i < info.size(); i++) {
|
||||
if (info[i].isDirectory) {
|
||||
ILOG("Directory: %s", info[i].name.c_str());
|
||||
} else {
|
||||
ILOG("File: %s", info[i].name.c_str());
|
||||
}
|
||||
// ILOG("File %i : %s\n", i, name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,6 +83,62 @@ uint8_t *ZipAssetReader::ReadAsset(const char *path, size_t *size) {
|
||||
return ReadFromZip(zip_file_, temp_path, size);
|
||||
}
|
||||
|
||||
bool ZipAssetReader::GetFileListing(const char *path, std::vector<FileInfo> *listing, const char *filter = 0)
|
||||
{
|
||||
// We just loop through the whole ZIP file and deduce what files are in this directory, and what subdirectories there are.
|
||||
std::set<std::string> files;
|
||||
std::set<std::string> directories;
|
||||
int numFiles = zip_get_num_files(zip_file_);
|
||||
size_t pathlen = strlen(path);
|
||||
if (path[pathlen-1] == '/')
|
||||
pathlen--;
|
||||
for (int i = 0; i < numFiles; i++) {
|
||||
const char* name = zip_get_name(zip_file_, i, 0);
|
||||
if (!name)
|
||||
continue;
|
||||
// ILOG("Comparing %s %s %i", name, path, pathlen);
|
||||
if (!memcmp(name, path, pathlen)) {
|
||||
// The prefix is right. Let's see if this is a file or path.
|
||||
char *slashPos = strchr(name + pathlen + 1, '/');
|
||||
if (slashPos != 0) {
|
||||
// A directory.
|
||||
std::string dirName = std::string(name + pathlen + 1, slashPos - (name + pathlen + 1));
|
||||
directories.insert(dirName);
|
||||
} else {
|
||||
files.insert(std::string(name + pathlen + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto diter = directories.begin(); diter != directories.end(); ++diter) {
|
||||
FileInfo info;
|
||||
info.name = *diter;
|
||||
info.fullName = std::string(path);
|
||||
if (info.fullName[info.fullName.size()-1] == '/')
|
||||
info.fullName = info.fullName.substr(0, info.fullName.size() - 1);
|
||||
info.fullName += "/" + *diter;
|
||||
info.exists = true;
|
||||
info.isDirectory = true;
|
||||
listing->push_back(info);
|
||||
}
|
||||
|
||||
for (auto fiter = files.begin(); fiter != files.end(); ++fiter) {
|
||||
FileInfo info;
|
||||
info.name = *fiter;
|
||||
info.fullName = std::string(path);
|
||||
if (info.fullName[info.fullName.size()-1] == '/')
|
||||
info.fullName = info.fullName.substr(0, info.fullName.size() - 1);
|
||||
info.fullName += "/" + *fiter;
|
||||
info.exists = true;
|
||||
info.isDirectory = false;
|
||||
listing->push_back(info);
|
||||
}
|
||||
|
||||
std::sort(listing->begin(), listing->end());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint8_t *DirectoryAssetReader::ReadAsset(const char *path, size_t *size) {
|
||||
@ -95,6 +154,13 @@ uint8_t *DirectoryAssetReader::ReadAsset(const char *path, size_t *size) {
|
||||
return ReadLocalFile(new_path, size);
|
||||
}
|
||||
|
||||
bool DirectoryAssetReader::GetFileListing(const char *path, std::vector<FileInfo> *listing, const char *filter = 0)
|
||||
{
|
||||
getFilesInDir(path, listing, filter);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
struct VFSEntry {
|
||||
const char *prefix;
|
||||
AssetReader *reader;
|
||||
@ -135,3 +201,18 @@ uint8_t *VFSReadFile(const char *filename, size_t *size) {
|
||||
ELOG("Missing filesystem for %s", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool VFSGetFileListing(const char *path, std::vector<FileInfo> *listing, const char *filter)
|
||||
{
|
||||
int fn_len = strlen(path);
|
||||
for (int i = 0; i < num_entries; i++) {
|
||||
int prefix_len = strlen(entries[i].prefix);
|
||||
if (prefix_len >= fn_len) continue;
|
||||
if (0 == memcmp(path, entries[i].prefix, prefix_len)) {
|
||||
entries[i].reader->GetFileListing(path + prefix_len, listing, filter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ELOG("Missing filesystem for %s", path);
|
||||
return false;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// TODO: Move much of this code to vfs.cpp
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef ANDROID
|
||||
#include <zip.h>
|
||||
#endif
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "file/vfs.h"
|
||||
#include "file/file_util.h"
|
||||
|
||||
// Direct readers. deallocate using delete [].
|
||||
uint8_t *ReadLocalFile(const char *filename, size_t *size);
|
||||
@ -18,10 +19,12 @@ public:
|
||||
virtual ~AssetReader() {}
|
||||
// use delete[]
|
||||
virtual uint8_t *ReadAsset(const char *path, size_t *size) = 0;
|
||||
// Filter support is optional but nice to have
|
||||
virtual bool GetFileListing(const char *path, std::vector<FileInfo> *listing, const char *filter = 0) = 0;
|
||||
virtual std::string toString() const = 0;
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef ANDROID
|
||||
uint8_t *ReadFromZip(zip *archive, const char* filename, size_t *size);
|
||||
class ZipAssetReader : public AssetReader {
|
||||
public:
|
||||
@ -29,6 +32,7 @@ public:
|
||||
~ZipAssetReader();
|
||||
// use delete[]
|
||||
virtual uint8_t *ReadAsset(const char *path, size_t *size);
|
||||
virtual bool GetFileListing(const char *path, std::vector<FileInfo> *listing, const char *filter);
|
||||
virtual std::string toString() const {
|
||||
return in_zip_path_;
|
||||
}
|
||||
@ -46,6 +50,7 @@ public:
|
||||
}
|
||||
// use delete[]
|
||||
virtual uint8_t *ReadAsset(const char *path, size_t *size);
|
||||
virtual bool GetFileListing(const char *path, std::vector<FileInfo> *listing, const char *filter);
|
||||
virtual std::string toString() const {
|
||||
return path_;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user