mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-14 16:07:39 +00:00
869 lines
18 KiB
C++
869 lines
18 KiB
C++
/* ScummVMDS - Scumm Interpreter DS Port
|
|
* Copyright (C) 2002-2004 The ScummVM project and Neil Millstone
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "str.h"
|
|
#include "fs.h"
|
|
#include "common/util.h"
|
|
#include <NDS/ARM9/console.h> //basic print funcionality
|
|
#include "ds-fs.h"
|
|
#include "dsmain.h"
|
|
#include "gba_nds_fat.h"
|
|
|
|
namespace DS {
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// DSFileSystemNode - Flash ROM file system using Zip files
|
|
//////////////////////////////////////////////////////////////
|
|
|
|
ZipFile* DSFileSystemNode::_zipFile = NULL;
|
|
char currentDir[128];
|
|
|
|
DSFileSystemNode::DSFileSystemNode() {
|
|
_displayName = "ds:/";
|
|
_path = "ds:/";
|
|
_isValid = true;
|
|
_isDirectory = true;
|
|
_path = "ds:/";
|
|
|
|
/* if (!_archive) {
|
|
_archive = (GBFS_FILE *) find_first_gbfs_file(scummdata);
|
|
if (!_archive) consolePrintf("No GBFS archive found!\n");
|
|
}*/
|
|
|
|
if (!_zipFile) {
|
|
_zipFile = new ZipFile();
|
|
}
|
|
}
|
|
|
|
DSFileSystemNode::DSFileSystemNode(const String& path) {
|
|
// consolePrintf("--%s ",path.c_str());
|
|
|
|
char disp[128];
|
|
char* pathStr = (char *) path.c_str();
|
|
|
|
|
|
int lastSlash = 3;
|
|
for (int r = 0; r < (int) strlen(pathStr) - 1; r++) {
|
|
if (path[r] == '\\') {
|
|
lastSlash = r;
|
|
}
|
|
}
|
|
|
|
strcpy(disp, pathStr + lastSlash + 1);
|
|
|
|
_displayName = String(disp);
|
|
_path = path;
|
|
// _isValid = true;
|
|
// _isDirectory = false;
|
|
|
|
|
|
|
|
if (!strncmp(pathStr, "ds:/", 4)) {
|
|
pathStr += 4;
|
|
}
|
|
|
|
|
|
if (*pathStr == '\0') {
|
|
_isValid = true;
|
|
_isDirectory = true;
|
|
return;
|
|
}
|
|
|
|
_zipFile->setAllFilesVisible(true);
|
|
if (_zipFile->findFile(pathStr)) {
|
|
_isValid = true;
|
|
_isDirectory = _zipFile->isDirectory();
|
|
} else {
|
|
_isValid = false;
|
|
_isDirectory = false;
|
|
}
|
|
_zipFile->setAllFilesVisible(false);
|
|
|
|
// consolePrintf("%s - Found: %d, Dir: %d\n", pathStr, _isValid, _isDirectory);
|
|
}
|
|
|
|
DSFileSystemNode::DSFileSystemNode(const String& path, bool isDir) {
|
|
// consolePrintf("--%s ",path.c_str());
|
|
|
|
char disp[128];
|
|
char* pathStr = (char *) path.c_str();
|
|
int lastSlash = 3;
|
|
for (int r = 0; r < (int) strlen(pathStr) - 1; r++) {
|
|
if (path[r] == '\\') {
|
|
lastSlash = r;
|
|
}
|
|
}
|
|
|
|
strcpy(disp, pathStr + lastSlash + 1);
|
|
|
|
_displayName = String(disp);
|
|
_path = path;
|
|
_isValid = true;
|
|
_isDirectory = isDir;
|
|
|
|
// consolePrintf("Found: %d, Dir: %d\n", _isValid, _isDirectory);
|
|
}
|
|
|
|
DSFileSystemNode::DSFileSystemNode(const DSFileSystemNode* node) {
|
|
|
|
}
|
|
|
|
AbstractFilesystemNode* DSFileSystemNode::parent() const {
|
|
// consolePrintf("parent\n");
|
|
DSFileSystemNode *p;
|
|
|
|
if (_path != "ds:/") {
|
|
char *path = (char *) _path.c_str();
|
|
int lastSlash = 4;
|
|
|
|
for (int r = 4; r < (int) strlen((char *) path); r++) {
|
|
if (path[r] == '\\') {
|
|
lastSlash = r;
|
|
}
|
|
}
|
|
|
|
p = new DSFileSystemNode(String(path, lastSlash));
|
|
((DSFileSystemNode *) (p))->_isDirectory = true;
|
|
} else {
|
|
p = new DSFileSystemNode();
|
|
}
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
AbstractFilesystemNode *DSFileSystemNode::child(const Common::String& n) const {
|
|
if (_path.lastChar() == '\\') {
|
|
return new DSFileSystemNode(_path + n);
|
|
} else {
|
|
return new DSFileSystemNode(_path + "\\" + n);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
bool DSFileSystemNode::listDir(AbstractFSList &dirList, ListMode mode) const {
|
|
// consolePrintf("Listdir\n");
|
|
|
|
|
|
// consolePrintf("Directory\n");
|
|
|
|
|
|
char temp[128];
|
|
strcpy(temp, _path.c_str());
|
|
|
|
// consolePrintf("This dir: %s\n", temp);
|
|
|
|
if ((temp[0] == 'd') && (temp[1] == 's') && (temp[2] == ':') && (temp[3] == '/')) {
|
|
if (strlen(temp) != 4) {
|
|
_zipFile->changeDirectory(&temp[4]);
|
|
} else {
|
|
_zipFile->changeToRoot();
|
|
|
|
/* // This is the root dir, so add the RAM folder
|
|
DSFileSystemNode* dsfsn = new DSFileSystemNode("ds:/ram");
|
|
dsfsn->_isDirectory = true;
|
|
dirList->push_back(wrap(dsfsn));*/
|
|
}
|
|
} else {
|
|
_zipFile->changeDirectory(temp);
|
|
}
|
|
|
|
|
|
|
|
if (_zipFile->restartFile()) {
|
|
do {
|
|
char n[128];
|
|
_zipFile->getFileName(n);
|
|
|
|
// consolePrintf("file: %s\n", n);
|
|
if ( (_zipFile->isDirectory() && ((mode == FilesystemNode::kListDirectoriesOnly) || (mode == FilesystemNode::kListAll)) )
|
|
|| (!_zipFile->isDirectory() && ((mode == FilesystemNode::kListFilesOnly) || (mode == FilesystemNode::kListAll)) ) )
|
|
{
|
|
DSFileSystemNode* dsfsn = new DSFileSystemNode("ds:/" + String(n), _zipFile->isDirectory());
|
|
dsfsn->_isDirectory = _zipFile->isDirectory();
|
|
dirList.push_back((dsfsn));
|
|
}
|
|
|
|
} while (_zipFile->skipFile());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// GBAMPFileSystemNode - File system using GBA Movie Player and CF card
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
GBAMPFileSystemNode::GBAMPFileSystemNode() {
|
|
_displayName = "mp:/";
|
|
_path = "mp:/";
|
|
_isValid = true;
|
|
_isDirectory = true;
|
|
_path = "mp:/";
|
|
}
|
|
|
|
GBAMPFileSystemNode::GBAMPFileSystemNode(const String& path) {
|
|
// consolePrintf("'%s'",path.c_str());
|
|
|
|
char disp[128];
|
|
char* pathStr = (char *) path.c_str();
|
|
int lastSlash = 3;
|
|
for (int r = 0; r < (int) strlen(pathStr) - 1; r++) {
|
|
if ((path[r] == '\\') || (path[r] == '/')) {
|
|
lastSlash = r;
|
|
}
|
|
}
|
|
|
|
strcpy(disp, pathStr + lastSlash + 1);
|
|
|
|
char check[128];
|
|
int success;
|
|
|
|
memset(check, 0, 128);
|
|
if (strlen(pathStr) > 3) {
|
|
strcpy(check, pathStr + 3);
|
|
if (check[strlen(check) - 1] == '/') {
|
|
check[strlen(check) - 1] = 0;
|
|
}
|
|
success = FAT_FileExists(check);
|
|
} else {
|
|
success = FT_DIR;
|
|
}
|
|
// consolePrintf("Path: %s (%d)\n", check, success);
|
|
|
|
_displayName = String(disp);
|
|
_path = path;
|
|
_isValid = success == FT_FILE;
|
|
_isDirectory = success == FT_DIR;
|
|
}
|
|
|
|
GBAMPFileSystemNode::GBAMPFileSystemNode(const String& path, bool isDirectory) {
|
|
// consolePrintf("'%s'",path.c_str());
|
|
|
|
char disp[128];
|
|
char* pathStr = (char *) path.c_str();
|
|
int lastSlash = 3;
|
|
for (int r = 0; r < (int) strlen(pathStr) - 1; r++) {
|
|
if ((path[r] == '\\') || (path[r] == '/')) {
|
|
lastSlash = r;
|
|
}
|
|
}
|
|
|
|
strcpy(disp, pathStr + lastSlash + 1);
|
|
|
|
_displayName = String(disp);
|
|
_path = path;
|
|
_isValid = true;
|
|
_isDirectory = isDirectory;
|
|
}
|
|
|
|
|
|
GBAMPFileSystemNode::GBAMPFileSystemNode(const GBAMPFileSystemNode* node) {
|
|
|
|
}
|
|
|
|
|
|
AbstractFilesystemNode* GBAMPFileSystemNode::parent() const {
|
|
// consolePrintf("parent\n");
|
|
GBAMPFileSystemNode *p;
|
|
|
|
if (_path != "mp:/") {
|
|
char *path = (char *) _path.c_str();
|
|
int lastSlash = 4;
|
|
|
|
for (int r = 4; r < (int) strlen((char *) path); r++) {
|
|
if (path[r] == '/') {
|
|
lastSlash = r;
|
|
}
|
|
}
|
|
|
|
p = new GBAMPFileSystemNode(String(path, lastSlash));
|
|
p->_isDirectory = true;
|
|
} else {
|
|
p = new GBAMPFileSystemNode();
|
|
}
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
AbstractFilesystemNode *GBAMPFileSystemNode::child(const Common::String& n) const {
|
|
if (_path.lastChar() == '\\') {
|
|
return new DSFileSystemNode(_path + n);
|
|
} else {
|
|
return new DSFileSystemNode(_path + "\\" + n);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool GBAMPFileSystemNode::listDir(AbstractFSList& dirList, ListMode mode) const {
|
|
// consolePrintf("Listdir\n");
|
|
|
|
enum { TYPE_NO_MORE = 0, TYPE_FILE = 1, TYPE_DIR = 2 };
|
|
|
|
char temp[128], fname[128], *path, *pathTemp;
|
|
strcpy(temp, _path.c_str());
|
|
|
|
path = temp + 3;
|
|
|
|
pathTemp = path;
|
|
while (*pathTemp) {
|
|
if (*pathTemp == '\\') {
|
|
*pathTemp = '/';
|
|
}
|
|
pathTemp++;
|
|
}
|
|
|
|
|
|
// consolePrintf("This dir: %s\n", path);
|
|
FAT_chdir(path);
|
|
|
|
int entryType = FAT_FindFirstFile(fname);
|
|
|
|
while (entryType != TYPE_NO_MORE) {
|
|
|
|
if ( ((entryType == TYPE_DIR) && ((mode == FilesystemNode::kListDirectoriesOnly) || (mode == FilesystemNode::kListAll)))
|
|
|| ((entryType == TYPE_FILE) && ((mode == FilesystemNode::kListFilesOnly) || (mode == FilesystemNode::kListAll))) ) {
|
|
GBAMPFileSystemNode* dsfsn;
|
|
|
|
if (strcmp(fname, ".") && strcmp(fname, "..")) {
|
|
|
|
if (!strcmp(path, "/")) {
|
|
dsfsn = new GBAMPFileSystemNode("mp:" + String(path) + String(fname), entryType == TYPE_DIR);
|
|
} else {
|
|
dsfsn = new GBAMPFileSystemNode("mp:" + String(path) + String("/") + String(fname), entryType == TYPE_DIR);
|
|
}
|
|
|
|
// dsfsn->_isDirectory = entryType == DIR;
|
|
dirList.push_back((dsfsn));
|
|
}
|
|
|
|
|
|
} else {
|
|
// consolePrintf("Skipping %s\n", fname);
|
|
}
|
|
|
|
entryType = FAT_FindNextFile(fname);
|
|
}
|
|
|
|
// consolePrintf("No more");
|
|
|
|
FAT_chdir("/");
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// Stdio replacements
|
|
#define MAX_FILE_HANDLES 32
|
|
|
|
bool inited = false;
|
|
DS::fileHandle handle[MAX_FILE_HANDLES];
|
|
|
|
FILE* std_fopen(const char* name, const char* mode) {
|
|
|
|
|
|
|
|
if (!inited) {
|
|
for (int r = 0; r < MAX_FILE_HANDLES; r++) {
|
|
handle[r].used = false;
|
|
}
|
|
inited = true;
|
|
currentDir[0] = '\0';
|
|
}
|
|
|
|
|
|
|
|
|
|
char* realName = (char *) name;
|
|
|
|
// Remove file system prefix
|
|
if ((name[0] == 'd') && (name[1] == 's') && (name[2] == ':') && (name[3] == '/')) {
|
|
realName += 4;
|
|
}
|
|
|
|
if ((name[0] == 'm') && (name[1] == 'p') && (name[2] == ':') && (name[3] == '/')) {
|
|
realName += 4;
|
|
}
|
|
|
|
// consolePrintf("Open file:");
|
|
// consolePrintf("'%s', [%s]", realName, mode);
|
|
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
FAT_chdir("/");
|
|
|
|
char* p = realName;
|
|
while (*p) {
|
|
if (*p == '\\') *p = '/';
|
|
p++;
|
|
}
|
|
|
|
FAT_FILE* result = FAT_fopen(realName, mode);
|
|
|
|
if (result == 0) {
|
|
// consolePrintf("Error code %d\n", result);
|
|
//consolePrintf("Opening file %s\n", realName);
|
|
} else {
|
|
// consolePrintf("Opened file %d\n", result);
|
|
}
|
|
// MT_memoryReport();
|
|
|
|
return (fileHandle *) result;
|
|
}
|
|
|
|
|
|
// Fail to open file for writing. It's in ROM!
|
|
|
|
// Allocate a file handle
|
|
int r = 0;
|
|
while (handle[r].used) r++;
|
|
|
|
if (strchr(mode, 'w')) {
|
|
// consolePrintf("Writing %s\n", realName);
|
|
handle[r].sramFile = (DSSaveFile *) DSSaveFileManager::instance()->openSavefile(realName, true);
|
|
} else {
|
|
// consolePrintf("Reading %s\n", realName);
|
|
handle[r].sramFile = (DSSaveFile *) DSSaveFileManager::instance()->openSavefile(realName, false);
|
|
}
|
|
|
|
|
|
if (handle[r].sramFile) {
|
|
handle[r].used = true;
|
|
handle[r].pos = 0;
|
|
handle[r].data = NULL;
|
|
handle[r].size = handle[r].sramFile->getSize();
|
|
// consolePrintf("Found it");
|
|
return &handle[r];
|
|
}
|
|
|
|
// consolePrintf("Not in SRAM!");
|
|
|
|
char* data;
|
|
|
|
ZipFile* zip = DSFileSystemNode::getZip();
|
|
if (!zip) {
|
|
// consolePrintf("No zip yet!");
|
|
return NULL;
|
|
}
|
|
|
|
// Grab the data if it exists
|
|
|
|
zip->setAllFilesVisible(true);
|
|
|
|
if (currentDir[0] != 0) {
|
|
char nameWithPath[128];
|
|
sprintf(nameWithPath, "%s\%s", currentDir, realName);
|
|
strcpy(realName, nameWithPath);
|
|
}
|
|
|
|
// consolePrintf("fopen(%s, %s)\n", realName, name);
|
|
|
|
if (zip->findFile(realName)) {
|
|
data = zip->getFile();
|
|
zip->setAllFilesVisible(false);
|
|
|
|
// Allocate a file handle
|
|
int r = 0;
|
|
while (handle[r].used) r++;
|
|
|
|
|
|
handle[r].used = true;
|
|
handle[r].pos = 0;
|
|
handle[r].data = data;
|
|
handle[r].size = zip->getFileSize();
|
|
|
|
// consolePrintf("Opened file %d: %s (%s) ", r, realName, name);
|
|
return &handle[r];
|
|
} else {
|
|
zip->setAllFilesVisible(false);
|
|
// consolePrintf("Not found: %s (%s) ", realName, name);
|
|
return NULL;
|
|
}
|
|
}
|
|
void std_fclose(FILE* handle) {
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
FAT_fclose((FAT_FILE *) handle);
|
|
return;
|
|
}
|
|
|
|
handle->used = false;
|
|
if (handle->sramFile) {
|
|
delete handle->sramFile;
|
|
handle->sramFile = NULL;
|
|
}
|
|
}
|
|
|
|
size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
|
|
|
// consolePrintf("fread %d,%d %d ", size, numItems, ptr);
|
|
|
|
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
|
|
|
|
int bytes = FAT_fread((void *) ptr, size, numItems, (FAT_FILE *) handle);
|
|
if (!std_feof(handle)) {
|
|
return numItems;
|
|
} else {
|
|
// consolePrintf("Read past end of file: %d read out of %d\n", bytes / size, numItems);
|
|
return bytes / size;
|
|
}
|
|
return numItems;
|
|
|
|
/* int item = 0;
|
|
u8* data = (u8 *) ptr;
|
|
while ((item < numItems) && (!FAT_feof((FAT_FILE *) handle))) {
|
|
|
|
|
|
int bytes = 0;
|
|
while ((bytes < size) && (!FAT_feof((FAT_FILE *) handle))) {
|
|
*data++ = FAT_fgetc((FAT_FILE *) handle);
|
|
bytes++;
|
|
}
|
|
|
|
item++;
|
|
|
|
}
|
|
|
|
return item;*/
|
|
|
|
|
|
int items = 0;
|
|
|
|
//for (int r = 0; r < numItems; r++) {
|
|
if (!std_feof(handle)) {
|
|
|
|
|
|
|
|
/* for (int t = 0; t < size; t++) {
|
|
if (feof(handle)) eof = true;
|
|
*(((char *) (ptr)) + r * size + t) = getc(handle);
|
|
}*/
|
|
int left = size * numItems;
|
|
int bytesRead = -1;
|
|
while ((left > 0) && (!FAT_feof((FAT_FILE *) handle))) {
|
|
int amount = left > 8192? 8192: left;
|
|
// do {
|
|
bytesRead = FAT_fread((void *) ptr, 1, amount, (FAT_FILE *) handle);
|
|
/* if (bytesRead == 0) {
|
|
consolePrintf("Pos:%d items:%d num:%d amount:%d read:%d\n", ftell(handle), items, numItems, amount, bytesRead);
|
|
left++;
|
|
|
|
int pos = ftell(handle);
|
|
|
|
fseek(handle, 0, SEEK_SET);
|
|
int c = getc(handle);
|
|
fseek(handle, pos - 1024, SEEK_SET);
|
|
fread(ptr, 1024, 1, handle);
|
|
swiWaitForVBlank();
|
|
//while (true);
|
|
}*/
|
|
//} while (bytesRead == 0);
|
|
left -= bytesRead;
|
|
ptr = ((char *) (ptr)) + bytesRead;
|
|
}
|
|
|
|
items = numItems - (left / size);
|
|
|
|
|
|
|
|
|
|
// FAT_fread((void *) ptr, size, 1, ((int) (handle)) - 1);
|
|
// ptr = ((char *) (ptr)) + size;
|
|
|
|
}
|
|
//}
|
|
|
|
// consolePrintf("...done %d \n", items)
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
if (handle->sramFile) {
|
|
int bytes = 0;
|
|
int result = 1;
|
|
//consolePrintf("fread size=", size * numItems);
|
|
for (int r = 0; (r < (s32) size * (s32) numItems) && (result > 0); r++) {
|
|
result = handle->sramFile->read((void *) ( ((char *) (ptr)) + r), 1);
|
|
bytes += result;
|
|
//consolePrintf("'%d',", ((char *) (ptr))[0]);
|
|
}
|
|
|
|
handle->pos += bytes;
|
|
|
|
return bytes / size;
|
|
}
|
|
|
|
|
|
if (handle->pos + size * numItems > handle->size) {
|
|
numItems = (handle->size - handle->pos) / size;
|
|
if (numItems < 0) numItems = 0;
|
|
}
|
|
|
|
// consolePrintf("read %d ", size * numItems);
|
|
|
|
memcpy((void *) ptr, handle->data + handle->pos, size * numItems);
|
|
|
|
handle->pos += size * numItems;
|
|
|
|
|
|
return numItems;
|
|
}
|
|
|
|
size_t std_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) {
|
|
if ((handle == stdin)) return 0;
|
|
|
|
if ((handle == stderr) || (handle == stdout)) {
|
|
// consolePrintf((char *) ptr);
|
|
return size;
|
|
}
|
|
|
|
//consolePrintf("fwrite size=%d\n", size * numItems);
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
|
|
FAT_fwrite(((char *) (ptr)), size, numItems, (FAT_FILE *) handle);
|
|
return numItems;
|
|
|
|
int length = size * numItems;
|
|
int pos = 0;
|
|
|
|
while (pos < length) {
|
|
int amount = length > 512? 512: length;
|
|
|
|
FAT_fwrite(((char *) (ptr)) + pos, 1, amount, (FAT_FILE *) handle);
|
|
length -= amount;
|
|
pos += amount;
|
|
}
|
|
|
|
return numItems;
|
|
}
|
|
|
|
|
|
if (handle->sramFile) {
|
|
handle->sramFile->write(ptr, size);
|
|
return size;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void std_fprintf(FILE* handle, const char* fmt, ...) {
|
|
consolePrintf(fmt);
|
|
}
|
|
|
|
bool std_feof(FILE* handle) {
|
|
// consolePrintf("feof ");
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
return FAT_feof((FAT_FILE *) handle);
|
|
}
|
|
|
|
if (handle->sramFile) {
|
|
return handle->sramFile->eos();
|
|
}
|
|
|
|
// consolePrintf("feof %s", handle->pos >= handle->size? "true": "false");
|
|
return handle->pos >= handle->size;
|
|
}
|
|
|
|
void std_fflush(FILE* handle) {
|
|
// consolePrintf("fflush ");
|
|
}
|
|
|
|
char* std_fgets(char* str, int size, FILE* file) {
|
|
// consolePrintf("fgets file=%d ", file);
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
|
|
char* s = str;
|
|
while ((*s++ = std_getc(file)) >= 32) {
|
|
// consolePrintf("%d ", *s);
|
|
}
|
|
*s = 0;
|
|
|
|
// consolePrintf("Read:%s\n", str);
|
|
|
|
return str;
|
|
}
|
|
|
|
|
|
if (file->sramFile) {
|
|
file->pos--;
|
|
int p = -1;
|
|
do {
|
|
file->pos++;
|
|
p++;
|
|
file->sramFile->read((char *) &str[p], 1);
|
|
// consolePrintf("%d,", str[p]);
|
|
} while ((str[p] >= 32) && (!feof(file)) && (p < size));
|
|
str[p + 1] = 0;
|
|
file->pos++;
|
|
// consolePrintf("Read:%s\n", str);
|
|
return str;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
long int std_ftell(FILE* handle) {
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
return FAT_ftell((FAT_FILE *) handle);
|
|
}
|
|
|
|
return handle->pos;
|
|
}
|
|
|
|
int std_fseek(FILE* handle, long int offset, int whence) {
|
|
// consolePrintf("fseek %d %d ", offset, whence);
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
return FAT_fseek((FAT_FILE *) handle, offset, whence);
|
|
}
|
|
|
|
|
|
switch (whence) {
|
|
case SEEK_CUR: {
|
|
handle->pos += offset;
|
|
break;
|
|
}
|
|
|
|
case SEEK_SET: {
|
|
handle->pos = offset;
|
|
break;
|
|
}
|
|
|
|
case SEEK_END: {
|
|
handle->pos = handle->size + offset;
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
handle->pos = offset;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void std_clearerr(FILE* handle) {
|
|
// consolePrintf("clearerr ");
|
|
}
|
|
|
|
int std_getc(FILE* handle) {
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
char c;
|
|
FAT_fread(&c, 1, 1, (FAT_FILE *) handle);
|
|
|
|
return c;
|
|
}
|
|
|
|
// consolePrintf("fgetc ");
|
|
return 0; // Not supported yet
|
|
}
|
|
|
|
char* std_getcwd(char* dir, int dunno) {
|
|
// consolePrintf("getcwd ");
|
|
dir[0] = '\0';
|
|
return dir; // Not supported yet
|
|
}
|
|
|
|
void std_cwd(char* dir) {
|
|
char buffer[128];
|
|
strcpy(buffer, dir);
|
|
char* realName = buffer;
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
if ((strlen(dir) >= 4) && (dir[0] == 'm') && (dir[1] == 'p') && (dir[2] == ':') && (dir[3] == '/')) {
|
|
realName += 4;
|
|
}
|
|
|
|
// consolePrintf("Real cwd:%d\n", realName);
|
|
|
|
char* p = realName;
|
|
while (*p) {
|
|
if (*p == '\\') *p = '/';
|
|
p++;
|
|
}
|
|
|
|
// consolePrintf("Real cwd:%d\n", realName);
|
|
FAT_chdir(realName);
|
|
} else {
|
|
if ((strlen(dir) >= 4) && (dir[0] == 'd') && (dir[1] == 's') && (dir[2] == ':') && (dir[3] == '/')) {
|
|
realName += 4;
|
|
}
|
|
|
|
char* p = realName;
|
|
while (*p) {
|
|
if (*p == '\\') *p = '/';
|
|
p++;
|
|
}
|
|
|
|
strcpy(currentDir, realName);
|
|
if (*(currentDir + strlen(currentDir) - 1) == '/') {
|
|
*(currentDir + strlen(currentDir) - 1) = '\0';
|
|
}
|
|
consolePrintf("CWD: %s\n", currentDir);
|
|
}
|
|
}
|
|
|
|
int std_ferror(FILE* handle) {
|
|
return 0;
|
|
}
|
|
|
|
} // namespace DS
|
|
|
|
// These functions are added to AbstractFileSystemNode and are therefore outside
|
|
// the DS namespace.
|
|
|
|
AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
|
|
// consolePrintf("New node");
|
|
|
|
if (DS::isGBAMPAvailable()) {
|
|
return new DS::GBAMPFileSystemNode();
|
|
} else {
|
|
return new DS::DSFileSystemNode();
|
|
}
|
|
}
|
|
|
|
AbstractFilesystemNode* AbstractFilesystemNode::getNodeForPath(const String& path) {
|
|
if (DS::isGBAMPAvailable()) {
|
|
return new DS::GBAMPFileSystemNode(path);
|
|
} else {
|
|
return new DS::DSFileSystemNode(path);
|
|
}
|
|
}
|