Merge pull request #458 from Xele02/testsceio

Improve sceIo for passing autotest
This commit is contained in:
Henrik Rydgård 2013-01-21 00:21:48 -08:00
commit e370f653fb
11 changed files with 114 additions and 45 deletions

View file

@ -70,15 +70,6 @@ static inline int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **res
}
#endif
// No thread safe
#ifdef _WIN32
inline struct tm* localtime_r (const time_t *clock, struct tm *result) {
if (!clock || !result) return NULL;
memcpy(result,localtime(clock),sizeof(*result));
return result;
}
#endif
// This namespace has various generic functions related to files and paths.
// The code still needs a ton of cleanup.

View file

@ -37,6 +37,15 @@ enum {
NUM_PATH_INDICES
};
// No thread safe
#ifdef _WIN32
inline struct tm* localtime_r (const time_t *clock, struct tm *result) {
if (!clock || !result) return NULL;
memcpy(result,localtime(clock),sizeof(*result));
return result;
}
#endif
namespace File
{

View file

@ -203,13 +203,9 @@ bool DirectoryFileSystem::RmDir(const std::string &dirname) {
bool DirectoryFileSystem::RenameFile(const std::string &from, const std::string &to) {
std::string fullTo = to;
// TO filename may not include path. Intention is that it uses FROM's path
if (to.find("/") != std::string::npos) {
size_t offset = from.find_last_of("/");
if (offset != std::string::npos) {
fullTo = from.substr(0, offset + 1) + to;
}
}
// Rename only work for filename in current directory
std::string fullFrom = GetLocalPath(from);
#if HOST_IS_CASE_SENSITIVE
@ -495,16 +491,20 @@ PSPFileInfo DirectoryFileSystem::GetFileInfo(std::string filename) {
if (x.type != FILETYPE_DIRECTORY)
{
struct stat64 s;
stat64(fullName.c_str(), &s);
#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA data;
GetFileAttributesEx(fullName.c_str(), GetFileExInfoStandard, &data);
x.size = data.nFileSizeLow | ((u64)data.nFileSizeHigh<<32);
#else
x.size = File::GetSize(fullName);
//TODO
x.size = s.st_size;
#endif
x.mtime = File::GetModifTime(fullName);
x.access = s.st_mode & 0x1FF;
localtime_r((time_t*)&s.st_atime,&x.atime);
localtime_r((time_t*)&s.st_ctime,&x.ctime);
localtime_r((time_t*)&s.st_mtime,&x.mtime);
}
return x;
@ -559,12 +559,18 @@ std::vector<PSPFileInfo> DirectoryFileSystem::GetDirListing(std::string path) {
while ((dirp = readdir(dp)) != NULL) {
PSPFileInfo entry;
struct stat s;
stat(dirp->d_name, &s);
std::string fullName = GetLocalPath(path) + "/"+dirp->d_name;
stat(fullName.c_str(), &s);
if (S_ISDIR(s.st_mode))
entry.type = FILETYPE_DIRECTORY;
else
entry.type = FILETYPE_NORMAL;
entry.access = s.st_mode & 0x1FF;
entry.name = dirp->d_name;
entry.size = s.st_size;
localtime_r((time_t*)&s.st_atime,&entry.atime);
localtime_r((time_t*)&s.st_ctime,&entry.ctime);
localtime_r((time_t*)&s.st_mtime,&entry.mtime);
myVector.push_back(entry);
}
closedir(dp);

View file

@ -64,6 +64,8 @@ struct PSPFileInfo
p.Do(access);
p.Do(exists);
p.Do(type);
p.Do(atime);
p.Do(ctime);
p.Do(mtime);
p.Do(isOnSectorSystem);
p.Do(startSector);
@ -79,6 +81,8 @@ struct PSPFileInfo
bool exists;
FileType type;
tm atime;
tm ctime;
tm mtime;
bool isOnSectorSystem;

View file

@ -71,8 +71,9 @@ static bool RealPath(const std::string &currentDirectory, const std::string &inP
size_t inLen = inPath.length();
if (inLen == 0)
{
ERROR_LOG(HLE, "RealPath: inPath is empty");
return false;
WARN_LOG(HLE, "RealPath: inPath is empty");
outPath = currentDirectory;
return true;
}
size_t inColon = inPath.find(':');

View file

@ -147,6 +147,7 @@ public:
p.Do(closePending);
p.Do(pendingAsyncResult);
p.Do(sectorBlockMode);
p.Do(openMode);
p.DoMarker("File");
}
@ -163,6 +164,7 @@ public:
bool closePending;
PSPFileInfo info;
u32 openMode;
};
static void TellFsThreadEnded (SceUID threadID) {
@ -288,6 +290,17 @@ void __IoCompleteAsyncIO(SceUID id) {
}
}
void __IoCopyDate(ScePspDateTime& date_out, const tm& date_in)
{
date_out.year = date_in.tm_year+1900;
date_out.month = date_in.tm_mon+1;
date_out.day = date_in.tm_mday;
date_out.hour = date_in.tm_hour;
date_out.minute = date_in.tm_min;
date_out.second = date_in.tm_sec;
date_out.microsecond = 0;
}
void __IoGetStat(SceIoStat *stat, PSPFileInfo &info) {
memset(stat, 0xfe, sizeof(SceIoStat));
stat->st_size = (s64) info.size;
@ -298,9 +311,12 @@ void __IoGetStat(SceIoStat *stat, PSPFileInfo &info) {
else
type = SCE_STM_FREG, attr = TYPE_FILE;
stat->st_mode = type; //0777 | type;
stat->st_mode = type | info.access;
stat->st_attr = attr;
stat->st_size = info.size;
__IoCopyDate(stat->st_atime, info.atime);
__IoCopyDate(stat->st_ctime, info.ctime);
__IoCopyDate(stat->st_mtime, info.mtime);
stat->st_private[0] = info.startSector;
}
@ -319,7 +335,7 @@ u32 sceIoGetstat(const char *filename, u32 addr) {
}
} else {
DEBUG_LOG(HLE, "sceIoGetstat(%s, %08x) : FILE NOT FOUND", filename, addr);
return SCE_KERNEL_ERROR_NOFILE;
return ERROR_ERRNO_FILE_NOT_FOUND;
}
}
@ -333,7 +349,11 @@ u32 sceIoRead(int id, u32 data_addr, int size) {
u32 error;
FileNode *f = kernelObjects.Get < FileNode > (id, error);
if (f) {
if (Memory::IsValidAddress(data_addr)) {
if(!(f->openMode & FILEACCESS_READ))
{
return ERROR_KERNEL_BAD_FILE_DESCRIPTOR;
}
else if (Memory::IsValidAddress(data_addr)) {
u8 *data = (u8*) Memory::GetPointer(data_addr);
f->asyncResult = (u32) pspFileSystem.ReadFile(f->handle, data, size);
DEBUG_LOG(HLE, "%i=sceIoRead(%d, %08x , %i)", f->asyncResult, id, data_addr, size);
@ -367,9 +387,16 @@ u32 sceIoWrite(int id, void *data_ptr, int size)
u32 error;
FileNode *f = kernelObjects.Get < FileNode > (id, error);
if (f) {
u8 *data = (u8*) data_ptr;
f->asyncResult = (u32) pspFileSystem.WriteFile(f->handle, data, size);
return f->asyncResult;
if(!(f->openMode & FILEACCESS_WRITE))
{
return ERROR_KERNEL_BAD_FILE_DESCRIPTOR;
}
else
{
u8 *data = (u8*) data_ptr;
f->asyncResult = (u32) pspFileSystem.WriteFile(f->handle, data, size);
return f->asyncResult;
}
} else {
ERROR_LOG(HLE, "sceIoWrite ERROR: no file open");
return error;
@ -421,16 +448,23 @@ s64 sceIoLseek(int id, s64 offset, int whence) {
FileNode *f = kernelObjects.Get < FileNode > (id, error);
if (f) {
FileMove seek = FILEMOVE_BEGIN;
bool outOfBound = false;
int newPos = 0;
switch (whence) {
case 0:
newPos = offset;
break;
case 1:
newPos = pspFileSystem.GetSeekPos(f->handle) + offset;
seek = FILEMOVE_CURRENT;
break;
case 2:
newPos = f->info.size + offset;
seek = FILEMOVE_END;
break;
}
if(newPos < 0 || newPos > f->info.size)
return -1;
f->asyncResult = (u32) pspFileSystem.SeekFile(f->handle, (s32) offset, seek);
DEBUG_LOG(HLE, "%i = sceIoLseek(%d,%i,%i)", f->asyncResult, id, (int) offset, whence);
@ -448,16 +482,23 @@ u32 sceIoLseek32(int id, int offset, int whence) {
DEBUG_LOG(HLE, "sceIoLseek32(%d,%08x,%i)", id, (int) offset, whence);
FileMove seek = FILEMOVE_BEGIN;
bool outOfBound = false;
int newPos = 0;
switch (whence) {
case 0:
newPos = offset;
break;
case 1:
newPos = pspFileSystem.GetSeekPos(f->handle) + offset;
seek = FILEMOVE_CURRENT;
break;
case 2:
newPos = f->info.size + offset;
seek = FILEMOVE_END;
break;
}
if(newPos < 0 || newPos > f->info.size)
return -1;
f->asyncResult = (u32) pspFileSystem.SeekFile(f->handle, (s32) offset, seek);
return f->asyncResult;
@ -494,6 +535,7 @@ u32 sceIoOpen(const char* filename, int flags, int mode) {
f->fullpath = filename;
f->asyncResult = id;
f->info = info;
f->openMode = access;
DEBUG_LOG(HLE, "%i=sceIoOpen(%s, %08x, %08x)", id, filename, flags, mode);
return id;
}
@ -505,10 +547,12 @@ u32 sceIoClose(int id) {
u32 sceIoRemove(const char *filename) {
DEBUG_LOG(HLE, "sceIoRemove(%s)", filename);
if (pspFileSystem.DeleteFile(filename))
return 0;
else
return -1;
if(!pspFileSystem.GetFileInfo(filename).exists)
return ERROR_ERRNO_FILE_NOT_FOUND;
pspFileSystem.DeleteFile(filename);
return 0;
}
u32 sceIoMkdir(const char *dirname, int mode) {
@ -760,16 +804,19 @@ u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 outPtr,
u32 sceIoRename(const char *from, const char *to) {
DEBUG_LOG(HLE, "sceIoRename(%s, %s)", from, to);
if (pspFileSystem.RenameFile(from, to))
return 0;
else
return -1;
if(!pspFileSystem.GetFileInfo(from).exists)
return ERROR_ERRNO_FILE_NOT_FOUND;
if(!pspFileSystem.RenameFile(from, to))
WARN_LOG(HLE, "Could not move %s to %s\n",from, to);
return 0;
}
u32 sceIoChdir(const char *dirname) {
pspFileSystem.ChDir(dirname);
DEBUG_LOG(HLE, "sceIoChdir(%s)", dirname);
return 1;
pspFileSystem.ChDir(dirname);
return 0;
}
int sceIoChangeAsyncPriority(int id, int priority)
@ -954,11 +1001,15 @@ public:
u32 sceIoDopen(const char *path) {
DEBUG_LOG(HLE, "sceIoDopen(\"%s\")", path);
if(!pspFileSystem.GetFileInfo(path).exists)
{
return ERROR_ERRNO_FILE_NOT_FOUND;
}
DirListing *dir = new DirListing();
SceUID id = kernelObjects.Create(dir);
// TODO: ERROR_ERRNO_FILE_NOT_FOUND
dir->listing = pspFileSystem.GetDirListing(path);
dir->index = 0;
dir->name = std::string(path);

View file

@ -129,7 +129,7 @@ bool Load_PSP_ELF_PBP(const char *filename, std::string *error_string)
path = ReplaceAll(path, "/", "\\");
#endif
DirectoryFileSystem *fs = new DirectoryFileSystem(&pspFileSystem, path);
pspFileSystem.Mount("umd0:/", fs);
pspFileSystem.Mount("umd0:", fs);
std::string finalName = "umd0:/" + file + extension;
return __KernelLoadExec(finalName.c_str(), 0, error_string);

View file

@ -783,9 +783,9 @@ u32 TransformDrawEngine::ComputeHash() {
u32 TransformDrawEngine::ComputeFastDCID() {
u32 hash = 0;
for (int i = 0; i < numDrawCalls; i++) {
hash ^= (u32)drawCalls[i].verts;
hash ^= *(u32*)&drawCalls[i].verts;
hash = _rotl(hash, 13);
hash ^= (u32)drawCalls[i].inds;
hash ^= *(u32*)&drawCalls[i].inds;
hash = _rotl(hash, 13);
hash ^= (u32)drawCalls[i].vertType;
hash = _rotl(hash, 13);

View file

@ -157,6 +157,13 @@ int main(int argc, const char* argv[])
g_Config.bFirstRun = false;
g_Config.bIgnoreBadMemAccess = true;
#if defined(ANDROID)
#elif defined(BLACKBERRY) || defined(__SYMBIAN32__)
#else
g_Config.memCardDirectory = std::string(getenv("HOME"))+"/.ppsspp/";
g_Config.flashDirectory = g_Config.memCardDirectory+"/flash/";
#endif
std::string error_string;
if (!PSP_Init(coreParameter, &error_string)) {

2
native

@ -1 +1 @@
Subproject commit b5037341aaca775e806be4b6a7bf109a47e0c655
Subproject commit 464240f7034b8defe5a60513c1e88bf6dc1c94c2

@ -1 +1 @@
Subproject commit 3e830600f66d1f5235ff5b7cad4e2346af66445a
Subproject commit 31e3915d4e4302e5e7dc2f6c2a4f191c420f38f9