Update to v091r11 release.
byuu says:
This release refines HSU1 support as a bidirectional protocol, nests SFC
manifests as "release/cartridge" and "release/information" (but release/
is not guaranteed to be finalized just yet), removes the database
integration, and adds support for ananke.
ananke represents inevitability. It's a library that, when installed,
higan can use to load files from the command-line, and also from a new
File -> Load Game menu option.
I need to change the build rules a bit for it to work on Windows (need
to make phoenix a DLL, basically), but it works now on Linux.
Right now, it only takes *.sfc file names, looks them up in the included
database, converts them to game folders, and returns the game folder
path for higan to load.
The idea is to continue expanding it to support everything we can that
I don't want in the higan core:
- load *.sfc, *.smc, *.swc, *.fig files
- remove SNES copier headers
- split apart merged firmware files
- pull in external firmware files (eg dsp1b.rom - these are staying
merged, just as SPC7110 prg+dat are merged)
- load *.zip and *.7z archives
- prompt for selection on multi-file archives
- generate manifest files based on heuristics
- apply BPS patches
The "Load" menu option has been renamed to "Library", to represent games
in your library. I'm going to add some sort of suffix to indicate
unverified games, and use a different folder icon for those (eg
manifests built on heuristics rather than from the database.)
So basically, to future end users:
File -> Load Game will be how they play games.
Library -> (specific system) can be thought of as an infinitely-sized
recent games list.
purify will likely become a simple stub that invokes ananke's functions.
No reason to duplicate all that code.
2012-11-05 08:22:50 +00:00
|
|
|
#ifndef NALL_DIRECTORY_HPP
|
|
|
|
#define NALL_DIRECTORY_HPP
|
|
|
|
|
|
|
|
#include <nall/file.hpp>
|
|
|
|
#include <nall/intrinsics.hpp>
|
|
|
|
#include <nall/sort.hpp>
|
|
|
|
#include <nall/string.hpp>
|
|
|
|
#include <nall/vector.hpp>
|
|
|
|
|
|
|
|
#if defined(PLATFORM_WINDOWS)
|
|
|
|
#include <nall/windows/utf8.hpp>
|
|
|
|
#else
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace nall {
|
|
|
|
|
|
|
|
struct directory {
|
|
|
|
static bool create(const string &pathname, unsigned permissions = 0755); //recursive
|
|
|
|
static bool remove(const string &pathname); //recursive
|
|
|
|
static bool exists(const string &pathname);
|
Update to ananke v00r02 release.
byuu says:
This should be basically final now.
Works with all media types (nes, sfc, gb, gbc, gba, bs, st), strips
headers, can use internal or external firmware, imports saves on first
run.
Added a custom file dialog. It seems both GTK+ and Windows XP have
(un)intelligent file sorting, which puts eg "ActRaiser 2 (NA)" before
"ActRaiser (NA)". So, screw 'em.
2012-12-24 05:48:23 +00:00
|
|
|
|
|
|
|
static lstring folders(const string &pathname, const string &pattern = "*") {
|
|
|
|
lstring folders = directory::ufolders(pathname, pattern);
|
|
|
|
folders.sort();
|
|
|
|
return folders;
|
|
|
|
}
|
|
|
|
|
|
|
|
static lstring files(const string &pathname, const string &pattern = "*") {
|
|
|
|
lstring files = directory::ufiles(pathname, pattern);
|
|
|
|
files.sort();
|
|
|
|
return files;
|
|
|
|
}
|
|
|
|
|
|
|
|
static lstring contents(const string &pathname, const string &pattern = "*") {
|
|
|
|
lstring folders = directory::ufolders(pathname); //pattern search of contents should only filter files
|
|
|
|
lstring files = directory::ufiles(pathname, pattern);
|
|
|
|
folders.sort();
|
|
|
|
files.sort();
|
|
|
|
for(auto &file : files) folders.append(file);
|
|
|
|
return folders;
|
|
|
|
}
|
|
|
|
|
|
|
|
static lstring ifolders(const string &pathname, const string &pattern = "*") {
|
|
|
|
lstring folders = ufolders(pathname, pattern);
|
|
|
|
folders.isort();
|
|
|
|
return folders;
|
|
|
|
}
|
|
|
|
|
|
|
|
static lstring ifiles(const string &pathname, const string &pattern = "*") {
|
|
|
|
lstring files = ufiles(pathname, pattern);
|
|
|
|
files.isort();
|
|
|
|
return files;
|
|
|
|
}
|
|
|
|
|
|
|
|
static lstring icontents(const string &pathname, const string &pattern = "*") {
|
|
|
|
lstring folders = directory::ufolders(pathname); //pattern search of contents should only filter files
|
|
|
|
lstring files = directory::ufiles(pathname, pattern);
|
|
|
|
folders.isort();
|
|
|
|
files.isort();
|
|
|
|
for(auto &file : files) folders.append(file);
|
|
|
|
return folders;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
//internal functions; these return unsorted lists
|
|
|
|
static lstring ufolders(const string &pathname, const string &pattern = "*");
|
|
|
|
static lstring ufiles(const string &pathname, const string &pattern = "*");
|
Update to v091r11 release.
byuu says:
This release refines HSU1 support as a bidirectional protocol, nests SFC
manifests as "release/cartridge" and "release/information" (but release/
is not guaranteed to be finalized just yet), removes the database
integration, and adds support for ananke.
ananke represents inevitability. It's a library that, when installed,
higan can use to load files from the command-line, and also from a new
File -> Load Game menu option.
I need to change the build rules a bit for it to work on Windows (need
to make phoenix a DLL, basically), but it works now on Linux.
Right now, it only takes *.sfc file names, looks them up in the included
database, converts them to game folders, and returns the game folder
path for higan to load.
The idea is to continue expanding it to support everything we can that
I don't want in the higan core:
- load *.sfc, *.smc, *.swc, *.fig files
- remove SNES copier headers
- split apart merged firmware files
- pull in external firmware files (eg dsp1b.rom - these are staying
merged, just as SPC7110 prg+dat are merged)
- load *.zip and *.7z archives
- prompt for selection on multi-file archives
- generate manifest files based on heuristics
- apply BPS patches
The "Load" menu option has been renamed to "Library", to represent games
in your library. I'm going to add some sort of suffix to indicate
unverified games, and use a different folder icon for those (eg
manifests built on heuristics rather than from the database.)
So basically, to future end users:
File -> Load Game will be how they play games.
Library -> (specific system) can be thought of as an infinitely-sized
recent games list.
purify will likely become a simple stub that invokes ananke's functions.
No reason to duplicate all that code.
2012-11-05 08:22:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#if defined(PLATFORM_WINDOWS)
|
|
|
|
inline bool directory::create(const string &pathname, unsigned permissions) {
|
|
|
|
string path;
|
|
|
|
lstring list = string{pathname}.transform("\\", "/").rtrim<1>("/").split("/");
|
|
|
|
bool result = true;
|
|
|
|
for(auto &part : list) {
|
|
|
|
path.append(part, "/");
|
|
|
|
result &= (_wmkdir(utf16_t(path)) == 0);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool directory::remove(const string &pathname) {
|
|
|
|
lstring list = directory::contents(pathname);
|
|
|
|
for(auto &name : list) {
|
|
|
|
if(name.endswith("/")) directory::remove({pathname, name});
|
|
|
|
else file::remove({pathname, name});
|
|
|
|
}
|
|
|
|
return _wrmdir(utf16_t(pathname)) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool directory::exists(const string &pathname) {
|
|
|
|
string name = pathname;
|
|
|
|
name.trim<1>("\"");
|
|
|
|
DWORD result = GetFileAttributes(utf16_t(name));
|
|
|
|
if(result == INVALID_FILE_ATTRIBUTES) return false;
|
|
|
|
return (result & FILE_ATTRIBUTE_DIRECTORY);
|
|
|
|
}
|
|
|
|
|
Update to ananke v00r02 release.
byuu says:
This should be basically final now.
Works with all media types (nes, sfc, gb, gbc, gba, bs, st), strips
headers, can use internal or external firmware, imports saves on first
run.
Added a custom file dialog. It seems both GTK+ and Windows XP have
(un)intelligent file sorting, which puts eg "ActRaiser 2 (NA)" before
"ActRaiser (NA)". So, screw 'em.
2012-12-24 05:48:23 +00:00
|
|
|
inline lstring directory::ufolders(const string &pathname, const string &pattern) {
|
Update to v091r11 release.
byuu says:
This release refines HSU1 support as a bidirectional protocol, nests SFC
manifests as "release/cartridge" and "release/information" (but release/
is not guaranteed to be finalized just yet), removes the database
integration, and adds support for ananke.
ananke represents inevitability. It's a library that, when installed,
higan can use to load files from the command-line, and also from a new
File -> Load Game menu option.
I need to change the build rules a bit for it to work on Windows (need
to make phoenix a DLL, basically), but it works now on Linux.
Right now, it only takes *.sfc file names, looks them up in the included
database, converts them to game folders, and returns the game folder
path for higan to load.
The idea is to continue expanding it to support everything we can that
I don't want in the higan core:
- load *.sfc, *.smc, *.swc, *.fig files
- remove SNES copier headers
- split apart merged firmware files
- pull in external firmware files (eg dsp1b.rom - these are staying
merged, just as SPC7110 prg+dat are merged)
- load *.zip and *.7z archives
- prompt for selection on multi-file archives
- generate manifest files based on heuristics
- apply BPS patches
The "Load" menu option has been renamed to "Library", to represent games
in your library. I'm going to add some sort of suffix to indicate
unverified games, and use a different folder icon for those (eg
manifests built on heuristics rather than from the database.)
So basically, to future end users:
File -> Load Game will be how they play games.
Library -> (specific system) can be thought of as an infinitely-sized
recent games list.
purify will likely become a simple stub that invokes ananke's functions.
No reason to duplicate all that code.
2012-11-05 08:22:50 +00:00
|
|
|
lstring list;
|
|
|
|
string path = pathname;
|
|
|
|
path.transform("/", "\\");
|
|
|
|
if(!strend(path, "\\")) path.append("\\");
|
|
|
|
path.append("*");
|
|
|
|
HANDLE handle;
|
|
|
|
WIN32_FIND_DATA data;
|
|
|
|
handle = FindFirstFile(utf16_t(path), &data);
|
|
|
|
if(handle != INVALID_HANDLE_VALUE) {
|
|
|
|
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
|
|
|
|
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
|
|
string name = (const char*)utf8_t(data.cFileName);
|
|
|
|
if(wildcard(name, pattern)) list.append(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while(FindNextFile(handle, &data) != false) {
|
|
|
|
if(wcscmp(data.cFileName, L".") && wcscmp(data.cFileName, L"..")) {
|
|
|
|
if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
|
|
string name = (const char*)utf8_t(data.cFileName);
|
|
|
|
if(wildcard(name, pattern)) list.append(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FindClose(handle);
|
|
|
|
}
|
|
|
|
for(auto &name : list) name.append("/"); //must append after sorting
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
Update to ananke v00r02 release.
byuu says:
This should be basically final now.
Works with all media types (nes, sfc, gb, gbc, gba, bs, st), strips
headers, can use internal or external firmware, imports saves on first
run.
Added a custom file dialog. It seems both GTK+ and Windows XP have
(un)intelligent file sorting, which puts eg "ActRaiser 2 (NA)" before
"ActRaiser (NA)". So, screw 'em.
2012-12-24 05:48:23 +00:00
|
|
|
inline lstring directory::ufiles(const string &pathname, const string &pattern) {
|
Update to v091r11 release.
byuu says:
This release refines HSU1 support as a bidirectional protocol, nests SFC
manifests as "release/cartridge" and "release/information" (but release/
is not guaranteed to be finalized just yet), removes the database
integration, and adds support for ananke.
ananke represents inevitability. It's a library that, when installed,
higan can use to load files from the command-line, and also from a new
File -> Load Game menu option.
I need to change the build rules a bit for it to work on Windows (need
to make phoenix a DLL, basically), but it works now on Linux.
Right now, it only takes *.sfc file names, looks them up in the included
database, converts them to game folders, and returns the game folder
path for higan to load.
The idea is to continue expanding it to support everything we can that
I don't want in the higan core:
- load *.sfc, *.smc, *.swc, *.fig files
- remove SNES copier headers
- split apart merged firmware files
- pull in external firmware files (eg dsp1b.rom - these are staying
merged, just as SPC7110 prg+dat are merged)
- load *.zip and *.7z archives
- prompt for selection on multi-file archives
- generate manifest files based on heuristics
- apply BPS patches
The "Load" menu option has been renamed to "Library", to represent games
in your library. I'm going to add some sort of suffix to indicate
unverified games, and use a different folder icon for those (eg
manifests built on heuristics rather than from the database.)
So basically, to future end users:
File -> Load Game will be how they play games.
Library -> (specific system) can be thought of as an infinitely-sized
recent games list.
purify will likely become a simple stub that invokes ananke's functions.
No reason to duplicate all that code.
2012-11-05 08:22:50 +00:00
|
|
|
lstring list;
|
|
|
|
string path = pathname;
|
|
|
|
path.transform("/", "\\");
|
|
|
|
if(!strend(path, "\\")) path.append("\\");
|
|
|
|
path.append("*");
|
|
|
|
HANDLE handle;
|
|
|
|
WIN32_FIND_DATA data;
|
|
|
|
handle = FindFirstFile(utf16_t(path), &data);
|
|
|
|
if(handle != INVALID_HANDLE_VALUE) {
|
|
|
|
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
|
|
|
string name = (const char*)utf8_t(data.cFileName);
|
|
|
|
if(wildcard(name, pattern)) list.append(name);
|
|
|
|
}
|
|
|
|
while(FindNextFile(handle, &data) != false) {
|
|
|
|
if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
|
|
|
string name = (const char*)utf8_t(data.cFileName);
|
|
|
|
if(wildcard(name, pattern)) list.append(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FindClose(handle);
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
inline bool directory::create(const string &pathname, unsigned permissions) {
|
|
|
|
string path;
|
|
|
|
lstring list = string{pathname}.rtrim<1>("/").split("/");
|
|
|
|
bool result = true;
|
|
|
|
for(auto &part : list) {
|
|
|
|
path.append(part, "/");
|
|
|
|
result &= (mkdir(path, permissions) == 0);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool directory::remove(const string &pathname) {
|
|
|
|
lstring list = directory::contents(pathname);
|
|
|
|
for(auto &name : list) {
|
|
|
|
if(name.endswith("/")) directory::remove({pathname, name});
|
|
|
|
else file::remove({pathname, name});
|
|
|
|
}
|
|
|
|
return rmdir(pathname) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool directory::exists(const string &pathname) {
|
|
|
|
DIR *dp = opendir(pathname);
|
|
|
|
if(!dp) return false;
|
|
|
|
closedir(dp);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
Update to ananke v00r02 release.
byuu says:
This should be basically final now.
Works with all media types (nes, sfc, gb, gbc, gba, bs, st), strips
headers, can use internal or external firmware, imports saves on first
run.
Added a custom file dialog. It seems both GTK+ and Windows XP have
(un)intelligent file sorting, which puts eg "ActRaiser 2 (NA)" before
"ActRaiser (NA)". So, screw 'em.
2012-12-24 05:48:23 +00:00
|
|
|
inline lstring directory::ufolders(const string &pathname, const string &pattern) {
|
Update to v091r11 release.
byuu says:
This release refines HSU1 support as a bidirectional protocol, nests SFC
manifests as "release/cartridge" and "release/information" (but release/
is not guaranteed to be finalized just yet), removes the database
integration, and adds support for ananke.
ananke represents inevitability. It's a library that, when installed,
higan can use to load files from the command-line, and also from a new
File -> Load Game menu option.
I need to change the build rules a bit for it to work on Windows (need
to make phoenix a DLL, basically), but it works now on Linux.
Right now, it only takes *.sfc file names, looks them up in the included
database, converts them to game folders, and returns the game folder
path for higan to load.
The idea is to continue expanding it to support everything we can that
I don't want in the higan core:
- load *.sfc, *.smc, *.swc, *.fig files
- remove SNES copier headers
- split apart merged firmware files
- pull in external firmware files (eg dsp1b.rom - these are staying
merged, just as SPC7110 prg+dat are merged)
- load *.zip and *.7z archives
- prompt for selection on multi-file archives
- generate manifest files based on heuristics
- apply BPS patches
The "Load" menu option has been renamed to "Library", to represent games
in your library. I'm going to add some sort of suffix to indicate
unverified games, and use a different folder icon for those (eg
manifests built on heuristics rather than from the database.)
So basically, to future end users:
File -> Load Game will be how they play games.
Library -> (specific system) can be thought of as an infinitely-sized
recent games list.
purify will likely become a simple stub that invokes ananke's functions.
No reason to duplicate all that code.
2012-11-05 08:22:50 +00:00
|
|
|
lstring list;
|
|
|
|
DIR *dp;
|
|
|
|
struct dirent *ep;
|
|
|
|
dp = opendir(pathname);
|
|
|
|
if(dp) {
|
|
|
|
while(ep = readdir(dp)) {
|
|
|
|
if(!strcmp(ep->d_name, ".")) continue;
|
|
|
|
if(!strcmp(ep->d_name, "..")) continue;
|
|
|
|
if(ep->d_type & DT_DIR) {
|
|
|
|
if(wildcard(ep->d_name, pattern)) list.append(ep->d_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(dp);
|
|
|
|
}
|
|
|
|
for(auto &name : list) name.append("/"); //must append after sorting
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
Update to ananke v00r02 release.
byuu says:
This should be basically final now.
Works with all media types (nes, sfc, gb, gbc, gba, bs, st), strips
headers, can use internal or external firmware, imports saves on first
run.
Added a custom file dialog. It seems both GTK+ and Windows XP have
(un)intelligent file sorting, which puts eg "ActRaiser 2 (NA)" before
"ActRaiser (NA)". So, screw 'em.
2012-12-24 05:48:23 +00:00
|
|
|
inline lstring directory::ufiles(const string &pathname, const string &pattern) {
|
Update to v091r11 release.
byuu says:
This release refines HSU1 support as a bidirectional protocol, nests SFC
manifests as "release/cartridge" and "release/information" (but release/
is not guaranteed to be finalized just yet), removes the database
integration, and adds support for ananke.
ananke represents inevitability. It's a library that, when installed,
higan can use to load files from the command-line, and also from a new
File -> Load Game menu option.
I need to change the build rules a bit for it to work on Windows (need
to make phoenix a DLL, basically), but it works now on Linux.
Right now, it only takes *.sfc file names, looks them up in the included
database, converts them to game folders, and returns the game folder
path for higan to load.
The idea is to continue expanding it to support everything we can that
I don't want in the higan core:
- load *.sfc, *.smc, *.swc, *.fig files
- remove SNES copier headers
- split apart merged firmware files
- pull in external firmware files (eg dsp1b.rom - these are staying
merged, just as SPC7110 prg+dat are merged)
- load *.zip and *.7z archives
- prompt for selection on multi-file archives
- generate manifest files based on heuristics
- apply BPS patches
The "Load" menu option has been renamed to "Library", to represent games
in your library. I'm going to add some sort of suffix to indicate
unverified games, and use a different folder icon for those (eg
manifests built on heuristics rather than from the database.)
So basically, to future end users:
File -> Load Game will be how they play games.
Library -> (specific system) can be thought of as an infinitely-sized
recent games list.
purify will likely become a simple stub that invokes ananke's functions.
No reason to duplicate all that code.
2012-11-05 08:22:50 +00:00
|
|
|
lstring list;
|
|
|
|
DIR *dp;
|
|
|
|
struct dirent *ep;
|
|
|
|
dp = opendir(pathname);
|
|
|
|
if(dp) {
|
|
|
|
while(ep = readdir(dp)) {
|
|
|
|
if(!strcmp(ep->d_name, ".")) continue;
|
|
|
|
if(!strcmp(ep->d_name, "..")) continue;
|
|
|
|
if((ep->d_type & DT_DIR) == 0) {
|
|
|
|
if(wildcard(ep->d_name, pattern)) list.append(ep->d_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(dp);
|
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|