Generate save state IDs for homebrew using the elf or directory name where applicable.

This commit is contained in:
Henrik Rydgard 2015-09-23 19:29:39 +02:00
parent 4b8666dc5d
commit 8996f58693
19 changed files with 141 additions and 118 deletions

View File

@ -1,6 +1,8 @@
#pragma once
#ifdef _WIN32
#pragma warning(disable:4091)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

View File

@ -483,6 +483,32 @@ bool GetModifTime(const std::string &filename, tm &return_time) {
}
}
std::string GetDir(const std::string &path) {
if (path == "/")
return path;
int n = (int)path.size() - 1;
while (n >= 0 && path[n] != '\\' && path[n] != '/')
n--;
std::string cutpath = n > 0 ? path.substr(0, n) : "";
for (size_t i = 0; i < cutpath.size(); i++) {
if (cutpath[i] == '\\') cutpath[i] = '/';
}
#ifndef _WIN32
if (!cutpath.size()) {
return "/";
}
#endif
return cutpath;
}
std::string GetFilename(std::string path) {
size_t off = GetDir(path).size() + 1;
if (off < path.size())
return path.substr(off);
else
return path;
}
// Returns the size of file (64bit)
// TODO: Add a way to return an error.
u64 GetFileSize(const std::string &filename) {

View File

@ -67,6 +67,12 @@ bool IsDirectory(const std::string &filename);
// Returns file attributes.
bool GetFileDetails(const std::string &filename, FileDetails *details);
// Extracts the directory from a path.
std::string GetDir(const std::string &path);
// Extracts the filename from a path.
std::string GetFilename(std::string path);
// Returns struct with modification date of file
bool GetModifTime(const std::string &filename, tm &return_time);

View File

@ -20,6 +20,8 @@
#include <base/stringutil.h>
#include "Common.h"
long parseHexLong(std::string s);
long parseLong(std::string s);
std::string StringFromFormat(const char* format, ...);

View File

@ -786,21 +786,21 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
// Fix issue from switching from uint (hex in .ini) to int (dec)
// -1 is okay, though. We'll just ignore recent stuff if it is.
if (iMaxRecent == 0)
if (iMaxRecent == 0)
iMaxRecent = 30;
if (iMaxRecent > 0) {
recentIsos.clear();
for (int i = 0; i < iMaxRecent; i++) {
char keyName[64];
std::string fileName;
if (iMaxRecent > 0) {
recentIsos.clear();
for (int i = 0; i < iMaxRecent; i++) {
char keyName[64];
std::string fileName;
snprintf(keyName, sizeof(keyName), "FileName%d", i);
if (recent->Get(keyName, &fileName, "") && !fileName.empty()) {
recentIsos.push_back(fileName);
}
}
}
snprintf(keyName, sizeof(keyName), "FileName%d", i);
if (recent->Get(keyName, &fileName, "") && !fileName.empty()) {
recentIsos.push_back(fileName);
}
}
}
auto pinnedPaths = iniFile.GetOrCreateSection("PinnedPaths")->ToMap();
vPinnedPaths.clear();

View File

@ -199,7 +199,7 @@ static int sceHeapCreateHeap(const char* name, u32 heapSize, int attr, u32 param
}
heap->address = addr;
// Some of the heap is reseved by the implementation (the first 128 bytes, and 8 after each block.)
// Some of the heap is reserved by the implementation (the first 128 bytes, and 8 after each block.)
heap->alloc.Init(heap->address + 128, heap->size - 128);
heapList[heap->address] = heap;
DEBUG_LOG(HLE, "%08x=sceHeapCreateHeap(%s, %08x, %08x, %08x)", heap->address, name, heapSize, attr, paramsPtr);

View File

@ -19,6 +19,7 @@
#include <cstdio>
#include "file/file_util.h"
#include "Common/FileUtil.h"
#include "Core/FileLoaders/CachingFileLoader.h"
#include "Core/FileLoaders/DiskCachingFileLoader.h"
@ -40,8 +41,7 @@ FileLoader *ConstructFileLoader(const std::string &filename) {
}
// TODO : improve, look in the file more
IdentifiedFileType Identify_File(FileLoader *fileLoader)
{
IdentifiedFileType Identify_File(FileLoader *fileLoader) {
if (fileLoader == nullptr) {
ERROR_LOG(LOADER, "Invalid fileLoader");
return FILETYPE_ERROR;
@ -87,26 +87,19 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader)
if (fileLoader->IsDirectory()) {
std::string filename = fileLoader->Path();
if (filename.size() > 4) {
FileInfo fileInfo;
// Check for existence of EBOOT.PBP, as required for "Directory games".
if (getFileInfo((filename + "/EBOOT.PBP").c_str(), &fileInfo)) {
if (fileInfo.exists) {
return FILETYPE_PSP_PBP_DIRECTORY;
}
if (File::Exists((filename + "/EBOOT.PBP").c_str())) {
return FILETYPE_PSP_PBP_DIRECTORY;
}
// check if it's a disc directory
if (getFileInfo((filename + "/PSP_GAME").c_str(), &fileInfo)) {
if (fileInfo.exists) {
return FILETYPE_PSP_DISC_DIRECTORY;
}
if (File::Exists((filename + "/PSP_GAME").c_str())) {
return FILETYPE_PSP_DISC_DIRECTORY;
}
// Not that, okay, let's guess it's a savedata directory if it has a param.sfo...
if (getFileInfo((filename + "/PARAM.SFO").c_str(), &fileInfo)) {
if (fileInfo.exists) {
return FILETYPE_PSP_SAVEDATA_DIRECTORY;
}
if (File::Exists((filename + "/PARAM.SFO").c_str())) {
return FILETYPE_PSP_SAVEDATA_DIRECTORY;
}
}
@ -179,7 +172,7 @@ IdentifiedFileType Identify_File(FileLoader *fileLoader)
// Let's check if we got pointed to a PBP within such a directory.
// If so we just move up and return the directory itself as the game.
std::string path = getDir(filename);
std::string path = File::GetDir(filename);
// If loading from memstick...
size_t pos = path.find("/PSP/GAME/");
if (pos != std::string::npos) {

View File

@ -293,16 +293,38 @@ namespace SaveState
static const char *SCREENSHOT_EXTENSION = "jpg";
// Slot utilities
std::string GenerateSaveSlotFilename(int slot, const char *extension)
std::string GenerateSaveSlotFilename(const std::string &gameFilename, int slot, const char *extension)
{
char discID[256];
char temp[2048];
snprintf(discID, sizeof(discID), "%s_%s",
g_paramSFO.GetValueString("DISC_ID").c_str(),
g_paramSFO.GetValueString("DISC_VERSION").c_str());
snprintf(temp, sizeof(temp), "ms0:/PSP/PPSSPP_STATE/%s_%i.%s", discID, slot, extension);
std::string discId = g_paramSFO.GetValueString("DISC_ID");
std::string fullDiscId;
if (discId.size()) {
fullDiscId = StringFromFormat("%s_%s",
g_paramSFO.GetValueString("DISC_ID").c_str(),
g_paramSFO.GetValueString("DISC_VERSION").c_str());
} else {
// Okay, no discId. Probably homebrew, let's use the last part of the path name.
if (File::IsDirectory(gameFilename)) {
// EBOOT.PBP directory, most likely.
std::string path = gameFilename;
size_t slash = path.rfind('/'); // Always '/', not '\\', as we're in a virtual directory
if (slash != std::string::npos && slash < path.size() - 1)
path = path.substr(slash + 1);
fullDiscId = path;
} else {
// Probably a loose elf.
std::string fn = File::GetFilename(gameFilename);
size_t dot = fn.rfind('.');
if (dot != std::string::npos) {
fullDiscId = fn.substr(0, dot);
} else {
fullDiscId = "elf"; // Fallback
}
}
}
std::string temp = StringFromFormat("ms0:/PSP/PPSSPP_STATE/%s_%i.%s", fullDiscId.c_str(), slot, extension);
std::string hostPath;
if (pspFileSystem.GetHostPath(std::string(temp), hostPath)) {
if (pspFileSystem.GetHostPath(temp, hostPath)) {
return hostPath;
} else {
return "";
@ -318,15 +340,14 @@ namespace SaveState
{
I18NCategory *sy = GetI18NCategory("System");
g_Config.iCurrentStateSlot = (g_Config.iCurrentStateSlot + 1) % SaveState::SAVESTATESLOTS;
char msg[128];
snprintf(msg, sizeof(msg), "%s: %d", sy->T("Savestate Slot"), g_Config.iCurrentStateSlot + 1);
std::string msg = StringFromFormat("%s: %d", sy->T("Savestate Slot"), g_Config.iCurrentStateSlot + 1);
osm.Show(msg);
NativeMessageReceived("slotchanged", "");
}
void LoadSlot(int slot, Callback callback, void *cbUserData)
void LoadSlot(const std::string &gameFilename, int slot, Callback callback, void *cbUserData)
{
std::string fn = GenerateSaveSlotFilename(slot, STATE_EXTENSION);
std::string fn = GenerateSaveSlotFilename(gameFilename, slot, STATE_EXTENSION);
if (!fn.empty()) {
Load(fn, callback, cbUserData);
} else {
@ -337,10 +358,10 @@ namespace SaveState
}
}
void SaveSlot(int slot, Callback callback, void *cbUserData)
void SaveSlot(const std::string &gameFilename, int slot, Callback callback, void *cbUserData)
{
std::string fn = GenerateSaveSlotFilename(slot, STATE_EXTENSION);
std::string shot = GenerateSaveSlotFilename(slot, SCREENSHOT_EXTENSION);
std::string fn = GenerateSaveSlotFilename(gameFilename, slot, STATE_EXTENSION);
std::string shot = GenerateSaveSlotFilename(gameFilename, slot, SCREENSHOT_EXTENSION);
if (!fn.empty()) {
auto renameCallback = [=](bool status, void *data) {
if (status) {
@ -364,15 +385,15 @@ namespace SaveState
}
}
bool HasSaveInSlot(int slot)
bool HasSaveInSlot(const std::string &gameFilename, int slot)
{
std::string fn = GenerateSaveSlotFilename(slot, STATE_EXTENSION);
std::string fn = GenerateSaveSlotFilename(gameFilename, slot, STATE_EXTENSION);
return File::Exists(fn);
}
bool HasScreenshotInSlot(int slot)
bool HasScreenshotInSlot(const std::string &gameFilename, int slot)
{
std::string fn = GenerateSaveSlotFilename(slot, SCREENSHOT_EXTENSION);
std::string fn = GenerateSaveSlotFilename(gameFilename, slot, SCREENSHOT_EXTENSION);
return File::Exists(fn);
}
@ -392,11 +413,11 @@ namespace SaveState
return false;
}
int GetNewestSlot() {
int GetNewestSlot(const std::string &gameFilename) {
int newestSlot = -1;
tm newestDate = {0};
for (int i = 0; i < SAVESTATESLOTS; i++) {
std::string fn = GenerateSaveSlotFilename(i, STATE_EXTENSION);
std::string fn = GenerateSaveSlotFilename(gameFilename, i, STATE_EXTENSION);
if (File::Exists(fn)) {
tm time;
bool success = File::GetModifTime(fn, time);
@ -409,8 +430,8 @@ namespace SaveState
return newestSlot;
}
std::string GetSlotDateAsString(int slot) {
std::string fn = GenerateSaveSlotFilename(slot, STATE_EXTENSION);
std::string GetSlotDateAsString(const std::string &gameFilename, int slot) {
std::string fn = GenerateSaveSlotFilename(gameFilename, slot, STATE_EXTENSION);
if (File::Exists(fn)) {
tm time;
if (File::GetModifTime(fn, time)) {

View File

@ -33,19 +33,19 @@ namespace SaveState
// Cycle through the 5 savestate slots
void NextSlot();
void SaveSlot(int slot, Callback callback, void *cbUserData = 0);
void LoadSlot(int slot, Callback callback, void *cbUserData = 0);
void SaveSlot(const std::string &gameFilename, int slot, Callback callback, void *cbUserData = 0);
void LoadSlot(const std::string &gameFilename, int slot, Callback callback, void *cbUserData = 0);
// Checks whether there's an existing save in the specified slot.
bool HasSaveInSlot(int slot);
bool HasScreenshotInSlot(int slot);
bool HasSaveInSlot(const std::string &gameFilename, int slot);
bool HasScreenshotInSlot(const std::string &gameFilename, int slot);
int GetCurrentSlot();
// Returns -1 if there's no newest slot.
int GetNewestSlot();
int GetNewestSlot(const std::string &gameFilename);
std::string GetSlotDateAsString(int slot);
std::string GenerateSaveSlotFilename(int slot, const char *extension);
std::string GetSlotDateAsString(const std::string &gameFilename, int slot);
std::string GenerateSaveSlotFilename(const std::string &gameFilename, int slot, const char *extension);
// Load the specified file into the current state (async.)
// Warning: callback will be called on a different thread.

View File

@ -16,6 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#ifdef _WIN32
#pragma warning(disable:4091)
#include "Common/CommonWindows.h"
#include <ShlObj.h>
#include <string>

View File

@ -180,12 +180,14 @@ void SaveStateActionFinished(bool result, void *userdata)
void MainWindow::qlstateAct()
{
SaveState::LoadSlot(0, SaveStateActionFinished, this);
std::string gamePath = PSP_CoreParameter().fileToStart;
SaveState::LoadSlot(gamePath, 0, SaveStateActionFinished, this);
}
void MainWindow::qsstateAct()
{
SaveState::SaveSlot(0, SaveStateActionFinished, this);
std::string gamePath = PSP_CoreParameter().fileToStart;
SaveState::SaveSlot(gamePath, 0, SaveStateActionFinished, this);
}
void MainWindow::lstateAct()

View File

@ -254,8 +254,8 @@ void EmuScreen::sendMessage(const char *message, const char *value) {
if (saveStatePreview_) {
int curSlot = SaveState::GetCurrentSlot();
std::string fn;
if (SaveState::HasSaveInSlot(curSlot)) {
fn = SaveState::GenerateSaveSlotFilename(curSlot, "jpg");
if (SaveState::HasSaveInSlot(gamePath_, curSlot)) {
fn = SaveState::GenerateSaveSlotFilename(gamePath_, curSlot, "jpg");
}
saveStatePreview_->SetFilename(fn);
@ -366,11 +366,11 @@ void EmuScreen::onVKeyDown(int virtualKeyCode) {
}
break;
case VIRTKEY_SAVE_STATE:
SaveState::SaveSlot(g_Config.iCurrentStateSlot, SaveState::Callback());
SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, SaveState::Callback());
break;
case VIRTKEY_LOAD_STATE:
if (SaveState::HasSaveInSlot(g_Config.iCurrentStateSlot)) {
SaveState::LoadSlot(g_Config.iCurrentStateSlot, SaveState::Callback());
if (SaveState::HasSaveInSlot(gamePath_, g_Config.iCurrentStateSlot)) {
SaveState::LoadSlot(gamePath_, g_Config.iCurrentStateSlot, SaveState::Callback());
}
break;
case VIRTKEY_NEXT_SLOT:
@ -948,9 +948,9 @@ void EmuScreen::deviceLost() {
void EmuScreen::autoLoad() {
//check if save state has save, if so, load
int lastSlot = SaveState::GetNewestSlot();
int lastSlot = SaveState::GetNewestSlot(gamePath_);
if (g_Config.bEnableAutoLoad && lastSlot != -1) {
SaveState::LoadSlot(lastSlot, SaveState::Callback(), 0);
SaveState::LoadSlot(gamePath_, lastSlot, SaveState::Callback(), 0);
g_Config.iCurrentStateSlot = lastSlot;
}
}

View File

@ -311,7 +311,7 @@ public:
info_->path = gamePath_;
info_->fileType = Identify_File(info_->GetFileLoader());
// Fallback title
info_->title = getFilename(info_->path);
info_->title = File::GetFilename(info_->path);
switch (info_->fileType) {
case FILETYPE_PSP_PBP:
@ -384,7 +384,7 @@ public:
case FILETYPE_PSP_ELF:
handleELF:
// An elf on its own has no usable information, no icons, no nothing.
info_->title = getFilename(filename);
info_->title = File::GetFilename(filename);
info_->id = "ELF000000";
info_->id_version = "ELF000000_1.00";
info_->paramSFOLoaded = true;

View File

@ -792,7 +792,6 @@ void MainScreen::CreateViews() {
TextView *ver = rightColumnItems->Add(new TextView(versionString, new LinearLayoutParams(Margins(70, -6, 0, 0))));
ver->SetSmall(true);
ver->SetClip(false);
#if defined(_WIN32) || defined(USING_QT_UI)
rightColumnItems->Add(new Choice(mm->T("Load","Load...")))->OnClick.Handle(this, &MainScreen::OnLoadFile);
#endif

View File

@ -140,7 +140,7 @@ private:
class SaveSlotView : public UI::LinearLayout {
public:
SaveSlotView(int slot, UI::LayoutParams *layoutParams = nullptr);
SaveSlotView(const std::string &gamePath, int slot, UI::LayoutParams *layoutParams = nullptr);
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override {
w = 500; h = 90;
@ -157,7 +157,7 @@ public:
}
std::string GetScreenshotTitle() const {
return SaveState::GetSlotDateAsString(slot_);
return SaveState::GetSlotDateAsString(gamePath_, slot_);
}
UI::Event OnStateLoaded;
@ -173,13 +173,14 @@ private:
UI::Button *loadStateButton_;
int slot_;
std::string gamePath_;
std::string screenshotFilename_;
};
SaveSlotView::SaveSlotView(int slot, UI::LayoutParams *layoutParams) : UI::LinearLayout(UI::ORIENT_HORIZONTAL, layoutParams), slot_(slot) {
SaveSlotView::SaveSlotView(const std::string &gameFilename, int slot, UI::LayoutParams *layoutParams) : UI::LinearLayout(UI::ORIENT_HORIZONTAL, layoutParams), gamePath_(gameFilename), slot_(slot) {
using namespace UI;
screenshotFilename_ = SaveState::GenerateSaveSlotFilename(slot, "jpg");
screenshotFilename_ = SaveState::GenerateSaveSlotFilename(gamePath_, slot, "jpg");
PrioritizedWorkQueue *wq = g_gameInfoCache.WorkQueue();
Add(new Spacer(5));
@ -197,11 +198,11 @@ SaveSlotView::SaveSlotView(int slot, UI::LayoutParams *layoutParams) : UI::Linea
fv->OnClick.Handle(this, &SaveSlotView::OnScreenshotClick);
if (SaveState::HasSaveInSlot(slot)) {
if (SaveState::HasSaveInSlot(gamePath_, slot)) {
loadStateButton_ = buttons->Add(new Button(pa->T("Load State"), new LinearLayoutParams(0.0, G_VCENTER)));
loadStateButton_->OnClick.Handle(this, &SaveSlotView::OnLoadState);
std::string dateStr = SaveState::GetSlotDateAsString(slot_);
std::string dateStr = SaveState::GetSlotDateAsString(gamePath_, slot_);
std::vector<std::string> dateStrs;
SplitString(dateStr, ' ', dateStrs);
if (!dateStrs.empty() && !dateStrs[0].empty()) {
@ -226,7 +227,7 @@ void SaveSlotView::Draw(UIContext &dc) {
UI::EventReturn SaveSlotView::OnLoadState(UI::EventParams &e) {
g_Config.iCurrentStateSlot = slot_;
SaveState::LoadSlot(slot_, SaveState::Callback(), 0);
SaveState::LoadSlot(gamePath_, slot_, SaveState::Callback(), 0);
UI::EventParams e2;
e2.v = this;
OnStateLoaded.Trigger(e2);
@ -235,7 +236,7 @@ UI::EventReturn SaveSlotView::OnLoadState(UI::EventParams &e) {
UI::EventReturn SaveSlotView::OnSaveState(UI::EventParams &e) {
g_Config.iCurrentStateSlot = slot_;
SaveState::SaveSlot(slot_, SaveState::Callback(), 0);
SaveState::SaveSlot(gamePath_, slot_, SaveState::Callback(), 0);
UI::EventParams e2;
e2.v = this;
OnStateSaved.Trigger(e2);
@ -283,7 +284,7 @@ void GamePauseScreen::CreateViews() {
leftColumnItems->Add(new Spacer(0.0));
leftColumnItems->SetSpacing(10.0);
for (int i = 0; i < NUM_SAVESLOTS; i++) {
SaveSlotView *slot = leftColumnItems->Add(new SaveSlotView(i, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
SaveSlotView *slot = leftColumnItems->Add(new SaveSlotView(gamePath_, i, new LayoutParams(FILL_PARENT, WRAP_CONTENT)));
slot->OnStateLoaded.Handle(this, &GamePauseScreen::OnState);
slot->OnStateSaved.Handle(this, &GamePauseScreen::OnState);
slot->OnScreenshotClicked.Handle(this, &GamePauseScreen::OnScreenshotClicked);
@ -355,7 +356,7 @@ void GamePauseScreen::dialogFinished(const Screen *dialog, DialogResult dr) {
ScreenshotViewScreen *s = (ScreenshotViewScreen *)dialog;
int slot = s->GetSlot();
g_Config.iCurrentStateSlot = slot;
SaveState::LoadSlot(slot, SaveState::Callback(), 0);
SaveState::LoadSlot(gamePath_, slot, SaveState::Callback(), 0);
finishNextFrame_ = true;
}
@ -365,7 +366,7 @@ UI::EventReturn GamePauseScreen::OnScreenshotClicked(UI::EventParams &e) {
SaveSlotView *v = static_cast<SaveSlotView *>(e.v);
int slot = v->GetSlot();
g_Config.iCurrentStateSlot = v->GetSlot();
if (SaveState::HasSaveInSlot(slot)) {
if (SaveState::HasSaveInSlot(gamePath_, slot)) {
std::string fn = v->GetScreenshotFilename();
std::string title = v->GetScreenshotTitle();
I18NCategory *pa = GetI18NCategory("Pause");

View File

@ -24,7 +24,7 @@
class GamePauseScreen : public UIDialogScreenWithGameBackground {
public:
GamePauseScreen(const std::string &filename) : UIDialogScreenWithGameBackground(filename), finishNextFrame_(false) {}
GamePauseScreen(const std::string &filename) : UIDialogScreenWithGameBackground(filename), finishNextFrame_(false), gamePath_(filename) {}
virtual ~GamePauseScreen();
void onFinish(DialogResult result) override;
@ -58,6 +58,7 @@ private:
// hack
bool finishNextFrame_;
std::string gamePath_;
};
class PrioritizedWorkQueue;

View File

@ -578,7 +578,7 @@ namespace MainWindow {
case ID_FILE_QUICKLOADSTATE:
{
SetCursor(LoadCursor(0, IDC_WAIT));
SaveState::LoadSlot(g_Config.iCurrentStateSlot, SaveStateActionFinished);
SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
break;
}
@ -587,14 +587,14 @@ namespace MainWindow {
if (KeyMap::g_controllerMap[VIRTKEY_LOAD_STATE].empty())
{
SetCursor(LoadCursor(0, IDC_WAIT));
SaveState::LoadSlot(g_Config.iCurrentStateSlot, SaveStateActionFinished);
SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
}
break;
}
case ID_FILE_QUICKSAVESTATE:
{
SetCursor(LoadCursor(0, IDC_WAIT));
SaveState::SaveSlot(g_Config.iCurrentStateSlot, SaveStateActionFinished);
SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
break;
}
@ -603,7 +603,7 @@ namespace MainWindow {
if (KeyMap::g_controllerMap[VIRTKEY_SAVE_STATE].empty())
{
SetCursor(LoadCursor(0, IDC_WAIT));
SaveState::SaveSlot(g_Config.iCurrentStateSlot, SaveStateActionFinished);
SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
break;
}
}

View File

@ -309,34 +309,6 @@ size_t getFilesInDir(const char *directory, std::vector<FileInfo> *files, const
return foundEntries;
}
std::string getDir(const std::string &path)
{
if (path == "/")
return path;
int n = (int)path.size() - 1;
while (n >= 0 && path[n] != '\\' && path[n] != '/')
n--;
std::string cutpath = n > 0 ? path.substr(0, n) : "";
for (size_t i = 0; i < cutpath.size(); i++)
{
if (cutpath[i] == '\\') cutpath[i] = '/';
}
#ifndef _WIN32
if (!cutpath.size()) {
return "/";
}
#endif
return cutpath;
}
std::string getFilename(std::string path) {
size_t off = getDir(path).size() + 1;
if (off < path.size())
return path.substr(off);
else
return path;
}
#ifdef _WIN32
// Returns a vector with the device names
std::vector<std::string> getWindowsDrives()

View File

@ -28,8 +28,6 @@ struct FileInfo {
};
std::string getFileExtension(const std::string &fn);
std::string getDir(const std::string &path);
std::string getFilename(std::string path);
bool getFileInfo(const char *path, FileInfo *fileInfo);
FILE *openCFile(const std::string &filename, const char *mode);
@ -37,7 +35,6 @@ enum {
GETFILES_GETHIDDEN = 1
};
size_t getFilesInDir(const char *directory, std::vector<FileInfo> *files, const char *filter = 0, int flags = 0);
std::string getDir(const std::string &path);
#ifdef _WIN32
std::vector<std::string> getWindowsDrives();