Parent Directory
|
Revision Log
|
Patch
--- trunk/pcsx2/IopBios.cpp 2010/09/07 03:24:11 31 +++ trunk/pcsx2/IopBios.cpp 2010/09/07 11:08:22 62 @@ -25,6 +25,61 @@ #define O_BINARY 0 #endif +// set this to 0 to disable rewriting 'host:' paths! +#define USE_HOST_REWRITE 1 + +#if USE_HOST_REWRITE +# ifdef WIN32 + // disable this if you DON'T want "host:/usr/local/" paths + // to get rewritten into host:/ +# define HOST_REWRITE_USR_LOCAL 1 +# else + // unix/linux users might want to set it to 1 + // if they DO want to keep demos from accessing their systems' /usr/local +# define HOST_REWRITE_USR_LOCAL 0 +# endif + +static char HostRoot[1024]; +#endif + +void Hle_SetElfPath(const char* elfFileName) +{ +#if USE_HOST_REWRITE + DevCon.WriteLn("HLE Host: Will load ELF: %s\n", elfFileName); + + const char* pos1 = strrchr(elfFileName,'/'); + const char* pos2 = strrchr(elfFileName,'\\'); + + if(pos2 > pos1) // we want the LAST path separator + pos1=pos2; + + if(!pos1) // if pos1 is NULL, then pos2 was not > pos1, so it must also be NULL + { + Console.Warning("HLE Warning: ELF does not have a path!!\n"); + + // use %CD%/host/ + getcwd(HostRoot,1000); // save the other 23 chars to append /host/ :P + HostRoot[1000]=0; // Be Safe. + + char* last = HostRoot + strlen(HostRoot) - 1; + + if((*last!='/') && (*last!='\\')) // PathAppend()-ish + last++; + + strcpy(last,"/host/"); + + return; + } + + int len = pos1-elfFileName+1; + memcpy(HostRoot,elfFileName,len); // include the / (or \\) + HostRoot[len] = 0; + + Console.WriteLn("HLE Host: Set 'host:' root path to: %s\n", HostRoot); + +#endif +} + namespace R3000A { #define v0 (psxRegs.GPR.n.v0) @@ -52,7 +107,7 @@ fd = hostfd; } - static __forceinline int translate_error(int err) + static __fi int translate_error(int err) { if (err >= 0) return err; @@ -75,10 +130,59 @@ { const char *path = strchr(name, ':') + 1; - if (flags != IOP_O_RDONLY) - return -IOP_EROFS; + // host: actually DOES let you write! + //if (flags != IOP_O_RDONLY) + // return -IOP_EROFS; + + // WIP code. Works well on win32, not so sure on unixes + // TODO: get rid of dependency on CWD/PWD +#if USE_HOST_REWRITE + // we want filenames to be relative to pcs2dir / host + + static char pathMod[1024]; + + // partial "rooting", + // it will NOT avoid a path like "../../x" from escaping the pcsx2 folder! + +#if HOST_REWRITE_USR_LOCAL + const char *_local_root = "/usr/local/"; + if(strncmp(path,_local_root,strlen(_local_root))==0) + { + strcpy(pathMod,HostRoot); + strcat(pathMod,path+strlen(_local_root)); + } + else +#endif + if((path[0] == '/') || (path[0] == '\\') || (isalpha(path[0]) && (path[1] == ':'))) // absolute NATIVE path (X:\blah) + { + // TODO: allow some way to use native paths in non-windows platforms + // maybe hack it so linux prefixes the path with "X:"? ;P + // or have all platforms use a common prefix for native paths + strcpy(pathMod,path); + } + else // relative paths + { + strcpy(pathMod,HostRoot); + strcat(pathMod,path); + } +#else + const char* pathMod = path; +#endif + + int native_flags = O_BINARY; // necessary in Windows. + + switch(flags&IOP_O_RDWR) + { + case IOP_O_RDONLY: native_flags |= O_RDONLY; break; + case IOP_O_WRONLY: native_flags |= O_WRONLY; break; + case IOP_O_RDWR: native_flags |= O_RDWR; break; + } + + if(flags&IOP_O_APPEND) native_flags |= O_APPEND; + if(flags&IOP_O_CREAT) native_flags |= O_CREAT; + if(flags&IOP_O_TRUNC) native_flags |= O_TRUNC; - int hostfd = ::open(path, O_BINARY | O_RDONLY); + int hostfd = ::open(pathMod, native_flags); if (hostfd < 0) return translate_error(hostfd); @@ -121,6 +225,11 @@ { return translate_error(::read(fd, buf, count)); } + + virtual int write(void *buf, u32 count) + { + return translate_error(::write(fd, buf, count)); + } }; namespace ioman { @@ -248,7 +357,7 @@ else { v0 = allocfd(file); - if (v0 < 0) + if ((s32)v0 < 0) file->close(); } @@ -311,17 +420,26 @@ int write_HLE() { - int fd = a0; + s32 fd = a0; + u32 buf = a1; + u32 count = a2; -#ifdef PCSX2_DEVBUILD if (fd == 1) // stdout { - Console.Write(ConColor_IOP, L"%s", ShiftJIS_ConvertString(Ra1, a2).c_str()); + iopConLog(ShiftJIS_ConvertString(Ra1, a2)); pc = ra; v0 = a2; return 1; } -#endif + else if (IOManFile *file = getfd<IOManFile>(fd)) + { + if (!iopVirtMemR<void>(buf)) + return 0; + + v0 = file->write(iopVirtMemW<void>(buf), count); + pc = ra; + return 1; + } return 0; } @@ -330,14 +448,23 @@ namespace sysmem { int Kprintf_HLE() { - char tmp[1024], tmp2[1024]; - char *ptmp = tmp; - int n=1, i=0, j = 0; - + // Emulate the expected Kprintf functionality: iopMemWrite32(sp, a0); iopMemWrite32(sp + 4, a1); iopMemWrite32(sp + 8, a2); iopMemWrite32(sp + 12, a3); + pc = ra; + + + // From here we're intercepting the Kprintf and piping it to our console, complete with + // printf-style formatting processing. This part can be skipped if the user has the + // console disabled. + + if (!SysConsole.iopConsole.IsActive()) return 1; + + char tmp[1024], tmp2[1024]; + char *ptmp = tmp; + int n=1, i=0, j = 0; while (Ra0[i]) { @@ -414,12 +541,8 @@ } } *ptmp = 0; + iopConLog( ShiftJIS_ConvertString(tmp, 1023) ); - // Use "%s" even though it seems indirect: this avoids chaos if/when the IOP decides - // to feed us strings that contain percentages or other printf formatting control chars. - Console.Write( ConColor_IOP, L"%s", ShiftJIS_ConvertString(tmp).c_str(), 1023 ); - - pc = ra; return 1; } } @@ -497,12 +620,11 @@ irxHLE irxImportHLE(const char libname[8], u16 index) { -#ifdef PCSX2_DEVBUILD // debugging output MODULE(sysmem) EXPORT_H( 14, Kprintf) END_MODULE -#endif + MODULE(ioman) EXPORT_H( 4, open) EXPORT_H( 5, close)
ViewVC Help | |
Powered by ViewVC 1.1.22 |