int main( int argc, char *argv[] ) { tf::options o; o.register_option(tf::option("help", "Displays help", false, false, "help", 'h')); o.register_option(tf::option("loglevel", "Logging level (DEBUG, INFO, WARNING, ERROR)", false, true, "loglevel", 'l')); o.register_option(tf::option("url", "URL to connect to", true, true, "url", 'u')); o.register_option(tf::option("rate", "Sending message rate", false, true, "rate", 'r')); o.register_option(tf::option("count", "Number of messages to send", false, true, "count", 'c')); try { o.parse(argc, argv); } catch (const tf::option_exception &e) { ERROR_LOG(e.what()); o.printUsage(); return 1; } std::string loglevel; if (o.get("loglevel", loglevel)) { if (loglevel == "DEBUG") { LOG_LEVEL(tf::logger::debug); } else if (loglevel == "INFO") { LOG_LEVEL(tf::logger::info); } else if (loglevel == "WARNING") { LOG_LEVEL(tf::logger::warning); } else if (loglevel == "ERROR") { LOG_LEVEL(tf::logger::error); } else { ERROR_LOG("Invalid log level"); return 1; } } else { LOG_LEVEL(tf::logger::warning); } const size_t count = o.get("count", 1000ul); const size_t rate = o.get("rate", 100ul); try { using TimeType = std::chrono::high_resolution_clock::time_point; using ResultsType = std::pair<TimeType, TimeType>; std::vector<ResultsType> m_times(count); fp::Session::initialise(); if (std::thread::hardware_concurrency() >= 4) { fp::Session::assign_to_cpu({2, 3}); } else if (std::thread::hardware_concurrency() >= 2) { fp::Session::assign_to_cpu({0, 1}); } const std::string url = o.getWithDefault("url", ""); fp::BlockingQueue queue; auto transport = fp::make_realm_connection(url.c_str(), ""); if (!transport->valid()) { ERROR_LOG("Failed to create transport"); return 1; } uint32_t id = 0; bool shutdown = false; fp::MutableMessage sendMsg; sendMsg.setSubject("TEST.PERF.SOURCE"); sendMsg.addScalarField("id", id); auto duration = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::microseconds(1000000) / rate); INFO_LOG("Sending a message every " << duration.count() << " us"); queue.registerEvent(duration, [&](fp::TimerEvent *event) noexcept { if (id < count) { sendMsg.clear(); sendMsg.setSubject("TEST.PERF.SOURCE"); sendMsg.addScalarField("id", id); m_times[id].first = std::chrono::high_resolution_clock::now(); if (transport->sendMessage(sendMsg) == fp::OK) { DEBUG_LOG("Message send successfully: " << sendMsg); } else { ERROR_LOG("Failed to send message"); exit(1); } id++; } }); fp::Subscriber subscriber(transport, "TEST.PERF.SINK", [&](const fp::Subscriber *event, const fp::Message *recvMsg) noexcept { DEBUG_LOG("Received message from sink: " << *recvMsg); // std::chrono::high_resolution_clock::time_point t = std::chrono::high_resolution_clock::now(); uint32_t recv_id = 0; if (recvMsg->getScalarField("id", recv_id)) { DEBUG_LOG("Processing message: " << recv_id); uint64_t ts = 0; if (recvMsg->getScalarField("timestamp", ts)) { std::chrono::microseconds dur(ts); std::chrono::time_point<std::chrono::high_resolution_clock> t(dur); m_times[recv_id].second = t; } } if (recv_id >= count - 1) { shutdown = true; } }); queue.addSubscriber(subscriber); while (!shutdown) { queue.dispatch(); } fp::Session::destroy(); std::vector<std::chrono::microseconds> latencies; latencies.reserve(count); std::transform(m_times.begin(), m_times.end(), std::back_inserter(latencies), [&](auto &result) { return std::chrono::duration_cast<std::chrono::microseconds>(result.second - result.first); }); std::future<double> avg = std::async(std::launch::async, [&latencies]() { uint64_t total = 0; std::for_each(latencies.begin(), latencies.end(), [&total](auto &v) { total += v.count(); }); return static_cast<double>(total) / latencies.size(); }); std::future<std::chrono::microseconds> min = std::async(std::launch::async, [&latencies]() { return *std::min_element(latencies.begin(), latencies.end()); }); std::future<std::chrono::microseconds> max = std::async(std::launch::async, [&latencies]() { return *std::max_element(latencies.begin(), latencies.end()); }); auto find_p = [&](size_t p) { size_t index = std::floor((static_cast<double>(100 - p) / 100.0) * latencies.size()); std::nth_element(latencies.begin(), latencies.begin() + index, latencies.end(), std::greater<std::chrono::microseconds>()); return latencies[index]; }; std::future<std::chrono::microseconds> p99 = std::async(std::launch::async, std::bind(find_p, 95)); std::future<std::chrono::microseconds> p90 = std::async(std::launch::async, std::bind(find_p, 90)); std::future<std::chrono::microseconds> p50 = std::async(std::launch::async, std::bind(find_p, 50)); INFO_LOG("Avg round trip: " << avg.get() << " us"); INFO_LOG("Min round trip: " << min.get().count() << " us"); INFO_LOG("Max round trip: " << max.get().count() << " us"); INFO_LOG("P99 round trip: " << p99.get().count() << " us"); INFO_LOG("P90 round trip: " << p90.get().count() << " us"); INFO_LOG("P50 round trip: " << p50.get().count() << " us"); } catch (const std::exception &stde) { ERROR_LOG("Internal error: " << stde.what()); return 1; } }
u32 sceIoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, u32 outlen) { u32 error; FileNode *f = kernelObjects.Get<FileNode>(id, error); if (error) { return error; } //KD Hearts: //56:46:434 HLE\sceIo.cpp:886 E[HLE]: UNIMPL 0=sceIoIoctrl id: 0000011f, cmd 04100001, indataPtr 08b313d8, inlen 00000010, outdataPtr 00000000, outLen 0 // 0000000 // TODO: This kind of stuff should be moved to the devices (wherever that would be) // and does not belong in this file. Same thing with Devctl. switch (cmd) { // Define decryption key (amctrl.prx DRM) case 0x04100001: if (Memory::IsValidAddress(indataPtr) && inlen == 16) { u8 keybuf[16]; memcpy(keybuf, Memory::GetPointer(indataPtr), 16); ERROR_LOG(HLE, "PGD DRM not yet supported, sorry."); } break; // Get UMD sector size case 0x01020003: INFO_LOG(HLE, "sceIoIoCtl: Asked for sector size of file %i", id); if (Memory::IsValidAddress(outdataPtr) && outlen == 4) { Memory::Write_U32(f->info.sectorSize, outdataPtr); } break; // Get UMD file pointer case 0x01020004: INFO_LOG(HLE, "sceIoIoCtl: Asked for fpointer of file %i", id); if (Memory::IsValidAddress(outdataPtr) && outlen >= 4) { Memory::Write_U32(f->info.fpointer, outdataPtr); } break; // Get UMD file start sector . case 0x01020006: INFO_LOG(HLE, "sceIoIoCtl: Asked for start sector of file %i", id); if (Memory::IsValidAddress(outdataPtr) && outlen >= 4) { Memory::Write_U32(f->info.startSector, outdataPtr); } break; // Get UMD file size in bytes. case 0x01020007: INFO_LOG(HLE, "sceIoIoCtl: Asked for size of file %i", id); if (Memory::IsValidAddress(outdataPtr) && outlen >= 8) { Memory::Write_U64(f->info.size, outdataPtr); } break; default: ERROR_LOG(HLE, "UNIMPL 0=sceIoIoctl id: %08x, cmd %08x, indataPtr %08x, inlen %08x, outdataPtr %08x, outLen %08x", id,cmd,indataPtr,inlen,outdataPtr,outlen); break; } return 0; }
void NativeInit(int argc, const char *argv[], const char *savegame_directory, const char *external_directory, const char *installID) { EnableFZ(); setlocale( LC_ALL, "C" ); std::string user_data_path = savegame_directory; isMessagePending = false; // We want this to be FIRST. #ifndef USING_QT_UI #ifdef BLACKBERRY // Packed assets are included in app/native/ dir VFSRegister("", new DirectoryAssetReader("app/native/assets/")); #elif defined(IOS) VFSRegister("", new DirectoryAssetReader(external_directory)); user_data_path += "/"; #elif defined(__APPLE__) char program_path[4090]; uint32_t program_path_size = sizeof(program_path); _NSGetExecutablePath(program_path,&program_path_size); *(strrchr(program_path, '/')+1) = '\0'; char assets_path[4096]; sprintf(assets_path,"%sassets/",program_path); VFSRegister("", new DirectoryAssetReader(assets_path)); VFSRegister("", new DirectoryAssetReader("assets/")); #else VFSRegister("", new DirectoryAssetReader("assets/")); #endif #endif VFSRegister("", new DirectoryAssetReader(user_data_path.c_str())); host = new NativeHost(); #ifndef _WIN32 logger = new AndroidLogger(); LogManager::Init(); LogManager *logman = LogManager::GetInstance(); ILOG("Logman: %p", logman); config_filename = user_data_path + "/ppsspp.ini"; g_Config.Load(config_filename.c_str()); #endif const char *fileToLog = 0; const char *stateToLoad = 0; bool gfxLog = false; // Parse command line LogTypes::LOG_LEVELS logLevel = LogTypes::LINFO; for (int i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'd': // Enable debug logging // Note that you must also change the max log level in Log.h. logLevel = LogTypes::LDEBUG; break; case 'g': gfxLog = true; break; case 'j': g_Config.bJit = true; g_Config.bSaveSettings = false; break; case 'i': g_Config.bJit = false; g_Config.bSaveSettings = false; break; case '-': if (!strncmp(argv[i], "--log=", strlen("--log=")) && strlen(argv[i]) > strlen("--log=")) fileToLog = argv[i] + strlen("--log="); if (!strncmp(argv[i], "--state=", strlen("--state=")) && strlen(argv[i]) > strlen("--state=")) stateToLoad = argv[i] + strlen("--state="); break; } } else { if (boot_filename.empty()) { boot_filename = argv[i]; if (!File::Exists(boot_filename)) { fprintf(stderr, "File not found: %s\n", boot_filename.c_str()); exit(1); } } else { fprintf(stderr, "Can only boot one file"); exit(1); } } } if (fileToLog != NULL) LogManager::GetInstance()->ChangeFileLog(fileToLog); #ifndef _WIN32 if (g_Config.currentDirectory == "") { #if defined(ANDROID) g_Config.currentDirectory = external_directory; #elif defined(BLACKBERRY) || defined(__SYMBIAN32__) || defined(MEEGO_EDITION_HARMATTAN) || defined(IOS) || defined(_WIN32) g_Config.currentDirectory = savegame_directory; #else g_Config.currentDirectory = getenv("HOME"); #endif } #if defined(ANDROID) g_Config.internalDataDirectory = savegame_directory; // Maybe there should be an option to use internal memory instead, but I think // that for most people, using external memory (SDCard/USB Storage) makes the // most sense. g_Config.memCardDirectory = std::string(external_directory) + "/"; g_Config.flashDirectory = std::string(external_directory)+"/flash/"; #elif defined(BLACKBERRY) || defined(__SYMBIAN32__) || defined(MEEGO_EDITION_HARMATTAN) || defined(IOS) || defined(_WIN32) g_Config.memCardDirectory = user_data_path; #ifdef BLACKBERRY g_Config.flashDirectory = "app/native/assets/flash/"; #elif defined(IOS) g_Config.flashDirectory = std::string(external_directory) + "flash0/"; #elif defined(MEEGO_EDITION_HARMATTAN) g_Config.flashDirectory = "/opt/PPSSPP/flash/"; #else g_Config.flashDirectory = user_data_path+"/flash/"; #endif #else g_Config.memCardDirectory = std::string(getenv("HOME"))+"/.ppsspp/"; g_Config.flashDirectory = g_Config.memCardDirectory+"/flash/"; #endif for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) { LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i; logman->SetEnable(type, true); logman->SetLogLevel(type, gfxLog && i == LogTypes::G3D ? LogTypes::LDEBUG : logLevel); #ifdef ANDROID logman->AddListener(type, logger); #endif } #ifdef __SYMBIAN32__ g_Config.bHardwareTransform = true; g_Config.bUseVBO = false; #endif // Special hack for G3D as it's very spammy. Need to make a flag for this. if (!gfxLog) logman->SetLogLevel(LogTypes::G3D, LogTypes::LERROR); INFO_LOG(BOOT, "Logger inited."); #else g_Config.memCardDirectory = "MemStick/"; #endif i18nrepo.LoadIni(g_Config.languageIni); if (!boot_filename.empty() && stateToLoad != NULL) SaveState::Load(stateToLoad); g_gameInfoCache.Init(); }
void DMAWrite(u32 addr, u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMAWrite: %08x bytes, from %08x to device", m_strName.c_str(), size, addr);}
s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize) { switch (_Parameter) { case IOCTL_GET_STATS: { if (_BufferOutSize < 0x1c) return -1017; WARN_LOG(WII_IPC_FILEIO, "FS: GET STATS - returning static values for now"); NANDStat fs; //TODO: scrape the real amounts from somewhere... fs.BlockSize = 0x4000; fs.FreeUserBlocks = 0x5DEC; fs.UsedUserBlocks = 0x1DD4; fs.FreeSysBlocks = 0x10; fs.UsedSysBlocks = 0x02F0; fs.Free_INodes = 0x146B; fs.Used_Inodes = 0x0394; *(NANDStat*)Memory::GetPointer(_BufferOut) = fs; return FS_RESULT_OK; } break; case IOCTL_CREATE_DIR: { _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); u32 Addr = _BufferIn; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u16 GroupID = Memory::Read_U16(Addr); Addr += 2; std::string DirName(HLE_IPC_BuildFilename(Memory::GetString(Addr, 64))); Addr += 64; Addr += 9; // owner attribs, permission u8 Attribs = Memory::Read_U8(Addr); INFO_LOG(WII_IPC_FILEIO, "FS: CREATE_DIR %s, OwnerID %#x, GroupID %#x, Attributes %#x", DirName.c_str(), OwnerID, GroupID, Attribs); DirName += DIR_SEP; File::CreateFullPath(DirName); _dbg_assert_msg_(WII_IPC_FILEIO, File::IsDirectory(DirName), "FS: CREATE_DIR %s failed", DirName.c_str()); return FS_RESULT_OK; } break; case IOCTL_SET_ATTR: { u32 Addr = _BufferIn; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u16 GroupID = Memory::Read_U16(Addr); Addr += 2; std::string Filename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn, 64)); Addr += 64; u8 OwnerPerm = Memory::Read_U8(Addr); Addr += 1; u8 GroupPerm = Memory::Read_U8(Addr); Addr += 1; u8 OtherPerm = Memory::Read_U8(Addr); Addr += 1; u8 Attributes = Memory::Read_U8(Addr); Addr += 1; INFO_LOG(WII_IPC_FILEIO, "FS: SetAttrib %s", Filename.c_str()); DEBUG_LOG(WII_IPC_FILEIO, " OwnerID: 0x%08x", OwnerID); DEBUG_LOG(WII_IPC_FILEIO, " GroupID: 0x%04x", GroupID); DEBUG_LOG(WII_IPC_FILEIO, " OwnerPerm: 0x%02x", OwnerPerm); DEBUG_LOG(WII_IPC_FILEIO, " GroupPerm: 0x%02x", GroupPerm); DEBUG_LOG(WII_IPC_FILEIO, " OtherPerm: 0x%02x", OtherPerm); DEBUG_LOG(WII_IPC_FILEIO, " Attributes: 0x%02x", Attributes); return FS_RESULT_OK; } break; case IOCTL_GET_ATTR: { _dbg_assert_msg_(WII_IPC_FILEIO, _BufferOutSize == 76, " GET_ATTR needs an 76 bytes large output buffer but it is %i bytes large", _BufferOutSize); u32 OwnerID = 0; u16 GroupID = 0x3031; // this is also known as makercd, 01 (0x3031) for nintendo and 08 (0x3038) for MH3 etc std::string Filename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn, 64)); u8 OwnerPerm = 0x3; // read/write u8 GroupPerm = 0x3; // read/write u8 OtherPerm = 0x3; // read/write u8 Attributes = 0x00; // no attributes if (File::IsDirectory(Filename)) { INFO_LOG(WII_IPC_FILEIO, "FS: GET_ATTR Directory %s - all permission flags are set", Filename.c_str()); } else { if (File::Exists(Filename)) { INFO_LOG(WII_IPC_FILEIO, "FS: GET_ATTR %s - all permission flags are set", Filename.c_str()); } else { INFO_LOG(WII_IPC_FILEIO, "FS: GET_ATTR unknown %s", Filename.c_str()); return FS_FILE_NOT_EXIST; } } // write answer to buffer if (_BufferOutSize == 76) { u32 Addr = _BufferOut; Memory::Write_U32(OwnerID, Addr); Addr += 4; Memory::Write_U16(GroupID, Addr); Addr += 2; memcpy(Memory::GetPointer(Addr), Memory::GetPointer(_BufferIn), 64); Addr += 64; Memory::Write_U8(OwnerPerm, Addr); Addr += 1; Memory::Write_U8(GroupPerm, Addr); Addr += 1; Memory::Write_U8(OtherPerm, Addr); Addr += 1; Memory::Write_U8(Attributes, Addr); Addr += 1; } return FS_RESULT_OK; } break; case IOCTL_DELETE_FILE: { _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); int Offset = 0; std::string Filename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn+Offset, 64)); Offset += 64; if (File::Delete(Filename)) { INFO_LOG(WII_IPC_FILEIO, "FS: DeleteFile %s", Filename.c_str()); } else if (File::DeleteDir(Filename)) { INFO_LOG(WII_IPC_FILEIO, "FS: DeleteDir %s", Filename.c_str()); } else { WARN_LOG(WII_IPC_FILEIO, "FS: DeleteFile %s - failed!!!", Filename.c_str()); } return FS_RESULT_OK; } break; case IOCTL_RENAME_FILE: { _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); int Offset = 0; std::string Filename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn+Offset, 64)); Offset += 64; std::string FilenameRename = HLE_IPC_BuildFilename(Memory::GetString(_BufferIn+Offset, 64)); Offset += 64; // try to make the basis directory File::CreateFullPath(FilenameRename); // if there is already a file, delete it if (File::Exists(Filename) && File::Exists(FilenameRename)) { File::Delete(FilenameRename); } // finally try to rename the file if (File::Rename(Filename, FilenameRename)) { INFO_LOG(WII_IPC_FILEIO, "FS: Rename %s to %s", Filename.c_str(), FilenameRename.c_str()); } else { ERROR_LOG(WII_IPC_FILEIO, "FS: Rename %s to %s - failed", Filename.c_str(), FilenameRename.c_str()); return FS_FILE_NOT_EXIST; } return FS_RESULT_OK; } break; case IOCTL_CREATE_FILE: { _dbg_assert_(WII_IPC_FILEIO, _BufferOutSize == 0); u32 Addr = _BufferIn; u32 OwnerID = Memory::Read_U32(Addr); Addr += 4; u16 GroupID = Memory::Read_U16(Addr); Addr += 2; std::string Filename(HLE_IPC_BuildFilename(Memory::GetString(Addr, 64))); Addr += 64; u8 OwnerPerm = Memory::Read_U8(Addr); Addr++; u8 GroupPerm = Memory::Read_U8(Addr); Addr++; u8 OtherPerm = Memory::Read_U8(Addr); Addr++; u8 Attributes = Memory::Read_U8(Addr); Addr++; INFO_LOG(WII_IPC_FILEIO, "FS: CreateFile %s", Filename.c_str()); DEBUG_LOG(WII_IPC_FILEIO, " OwnerID: 0x%08x", OwnerID); DEBUG_LOG(WII_IPC_FILEIO, " GroupID: 0x%04x", GroupID); DEBUG_LOG(WII_IPC_FILEIO, " OwnerPerm: 0x%02x", OwnerPerm); DEBUG_LOG(WII_IPC_FILEIO, " GroupPerm: 0x%02x", GroupPerm); DEBUG_LOG(WII_IPC_FILEIO, " OtherPerm: 0x%02x", OtherPerm); DEBUG_LOG(WII_IPC_FILEIO, " Attributes: 0x%02x", Attributes); // check if the file already exist if (File::Exists(Filename)) { WARN_LOG(WII_IPC_FILEIO, "\tresult = FS_RESULT_EXISTS"); return FS_FILE_EXIST; } // create the file File::CreateFullPath(Filename); // just to be sure bool Result = File::CreateEmptyFile(Filename); if (!Result) { ERROR_LOG(WII_IPC_FILEIO, "CWII_IPC_HLE_Device_fs: couldn't create new file"); PanicAlert("CWII_IPC_HLE_Device_fs: couldn't create new file"); return FS_RESULT_FATAL; } INFO_LOG(WII_IPC_FILEIO, "\tresult = FS_RESULT_OK"); return FS_RESULT_OK; } break; case IOCTL_SHUTDOWN: { INFO_LOG(WII_IPC_FILEIO, "Wii called Shutdown()"); // TODO: stop emulation } break; default: ERROR_LOG(WII_IPC_FILEIO, "CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter); PanicAlert("CWII_IPC_HLE_Device_fs::IOCtl: ni 0x%x", _Parameter); break; } return FS_RESULT_FATAL; }
// FastRun - inspired by GCemu (to imitate the JIT so that they can be compared). void Interpreter::Run() { while (!PowerPC::GetState()) { //we have to check exceptions at branches apparently (or maybe just rfi?) if (SConfig::GetInstance().bEnableDebugging) { #ifdef SHOW_HISTORY PCBlockVec.push_back(PC); if (PCBlockVec.size() > ShowBlocks) PCBlockVec.erase(PCBlockVec.begin()); #endif // Debugging friendly version of inner loop. Tries to do the timing as similarly to the // JIT as possible. Does not take into account that some instructions take multiple cycles. while (PowerPC::ppcState.downcount > 0) { m_EndBlock = false; int i; for (i = 0; !m_EndBlock; i++) { #ifdef SHOW_HISTORY PCVec.push_back(PC); if (PCVec.size() > ShowSteps) PCVec.erase(PCVec.begin()); #endif //2: check for breakpoint if (PowerPC::breakpoints.IsAddressBreakPoint(PC)) { #ifdef SHOW_HISTORY NOTICE_LOG(POWERPC, "----------------------------"); NOTICE_LOG(POWERPC, "Blocks:"); for (int j = 0; j < PCBlockVec.size(); j++) NOTICE_LOG(POWERPC, "PC: 0x%08x", PCBlockVec.at(j)); NOTICE_LOG(POWERPC, "----------------------------"); NOTICE_LOG(POWERPC, "Steps:"); for (int j = 0; j < PCVec.size(); j++) { // Write space if (j > 0) { if (PCVec.at(j) != PCVec.at(j-1) + 4) NOTICE_LOG(POWERPC, ""); } NOTICE_LOG(POWERPC, "PC: 0x%08x", PCVec.at(j)); } #endif INFO_LOG(POWERPC, "Hit Breakpoint - %08x", PC); CCPU::Break(); if (PowerPC::breakpoints.IsTempBreakPoint(PC)) PowerPC::breakpoints.Remove(PC); Host_UpdateDisasmDialog(); return; } SingleStepInner(); } PowerPC::ppcState.downcount -= i; } } else { // "fast" version of inner loop. well, it's not so fast. while (PowerPC::ppcState.downcount > 0) { m_EndBlock = false; int cycles = 0; while (!m_EndBlock) { cycles += SingleStepInner(); } PowerPC::ppcState.downcount -= cycles; } } CoreTiming::Advance(); if (PowerPC::ppcState.Exceptions) { PowerPC::CheckExceptions(); PC = NPC; } } // Let the waiting thread know we are done leaving PowerPC::FinishStateMove(); }
void ImmWrite(u32 data, u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s ImmWrite: %08x", m_strName.c_str(), data);}
bool CWII_IPC_HLE_Device_net_ssl::IOCtlV(u32 _CommandAddress) { SIOCtlVBuffer CommandBuffer(_CommandAddress); u32 _BufferIn = 0, _BufferIn2 = 0, _BufferIn3 = 0; u32 BufferInSize = 0, BufferInSize2 = 0, BufferInSize3 = 0; u32 BufferOut = 0, BufferOut2 = 0, BufferOut3 = 0; u32 BufferOutSize = 0, BufferOutSize2 = 0, BufferOutSize3 = 0; if (CommandBuffer.InBuffer.size() > 0) { _BufferIn = CommandBuffer.InBuffer.at(0).m_Address; BufferInSize = CommandBuffer.InBuffer.at(0).m_Size; } if (CommandBuffer.InBuffer.size() > 1) { _BufferIn2 = CommandBuffer.InBuffer.at(1).m_Address; BufferInSize2 = CommandBuffer.InBuffer.at(1).m_Size; } if (CommandBuffer.InBuffer.size() > 2) { _BufferIn3 = CommandBuffer.InBuffer.at(2).m_Address; BufferInSize3 = CommandBuffer.InBuffer.at(2).m_Size; } if (CommandBuffer.PayloadBuffer.size() > 0) { BufferOut = CommandBuffer.PayloadBuffer.at(0).m_Address; BufferOutSize = CommandBuffer.PayloadBuffer.at(0).m_Size; } if (CommandBuffer.PayloadBuffer.size() > 1) { BufferOut2 = CommandBuffer.PayloadBuffer.at(1).m_Address; BufferOutSize2 = CommandBuffer.PayloadBuffer.at(1).m_Size; } if (CommandBuffer.PayloadBuffer.size() > 2) { BufferOut3 = CommandBuffer.PayloadBuffer.at(2).m_Address; BufferOutSize3 = CommandBuffer.PayloadBuffer.at(2).m_Size; } switch (CommandBuffer.Parameter) { case IOCTLV_NET_SSL_NEW: { int verifyOption = Memory::Read_U32(BufferOut); const char * hostname = (const char*) Memory::GetPointer(BufferOut2); int freeSSL = this->getSSLFreeID(); if (freeSSL) { int sslID = freeSSL - 1; int ret = ssl_init(&_SSL[sslID].ctx); if (ret) { // Cleanup possibly dirty ctx memset(&_SSL[sslID].ctx, 0, sizeof(ssl_context)); goto _SSL_NEW_ERROR; } entropy_init(&_SSL[sslID].entropy); ssl_set_rng(&_SSL[sslID].ctx, entropy_func, &_SSL[sslID].entropy); // For some reason we can't use TLSv1.2, v1.1 and below are fine! ssl_set_max_version(&_SSL[sslID].ctx, SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_2); ssl_set_session(&_SSL[sslID].ctx, &_SSL[sslID].session); ssl_set_endpoint(&_SSL[sslID].ctx, SSL_IS_CLIENT); ssl_set_authmode(&_SSL[sslID].ctx, SSL_VERIFY_NONE); ssl_set_renegotiation(&_SSL[sslID].ctx, SSL_RENEGOTIATION_ENABLED); memcpy(_SSL[sslID].hostname, hostname, min((int)BufferOutSize2, NET_SSL_MAX_HOSTNAME_LEN)); _SSL[sslID].hostname[NET_SSL_MAX_HOSTNAME_LEN-1] = '\0'; ssl_set_hostname(&_SSL[sslID].ctx, _SSL[sslID].hostname); _SSL[sslID].active = true; Memory::Write_U32(freeSSL, _BufferIn); } else { _SSL_NEW_ERROR: Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_NEW (%d, %s) " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", verifyOption, hostname, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_SHUTDOWN: { int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { ssl_close_notify(&_SSL[sslID].ctx); ssl_session_free(&_SSL[sslID].session); ssl_free(&_SSL[sslID].ctx); x509_crt_free(&_SSL[sslID].cacert); x509_crt_free(&_SSL[sslID].clicert); memset(&_SSL[sslID].ctx, 0, sizeof(ssl_context)); memset(&_SSL[sslID].session, 0, sizeof(ssl_session)); memset(&_SSL[sslID].entropy, 0, sizeof(entropy_context)); memset(_SSL[sslID].hostname, 0, NET_SSL_MAX_HOSTNAME_LEN); _SSL[sslID].active = false; Memory::Write_U32(SSL_OK, _BufferIn); } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SHUTDOWN " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_SETROOTCA: { INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { int ret = x509_crt_parse_der( &_SSL[sslID].cacert, Memory::GetPointer(BufferOut2), BufferOutSize2); if (ret) { Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); } else { ssl_set_ca_chain(&_SSL[sslID].ctx, &_SSL[sslID].cacert, NULL, _SSL[sslID].hostname); Memory::Write_U32(SSL_OK, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCA = %d", ret); } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); } break; } case IOCTLV_NET_SSL_SETBUILTINCLIENTCERT: { INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX)); int ret = x509_crt_parse_file(&_SSL[sslID].clicert, (cert_base_path + "clientca.pem").c_str()); int pk_ret = pk_parse_keyfile(&_SSL[sslID].pk, (cert_base_path + "clientcakey.pem").c_str(), NULL); if (ret || pk_ret) { x509_crt_free(&_SSL[sslID].clicert); pk_free(&_SSL[sslID].pk); memset(&_SSL[sslID].clicert, 0, sizeof(x509_crt)); memset(&_SSL[sslID].pk, 0, sizeof(pk_context)); Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); } else { ssl_set_own_cert(&_SSL[sslID].ctx, &_SSL[sslID].clicert, &_SSL[sslID].pk); Memory::Write_U32(SSL_OK, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = (%d, %d)", ret, pk_ret); } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID); } break; } case IOCTLV_NET_SSL_REMOVECLIENTCERT: { INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_REMOVECLIENTCERT " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { x509_crt_free(&_SSL[sslID].clicert); pk_free(&_SSL[sslID].pk); memset(&_SSL[sslID].clicert, 0, sizeof(x509_crt)); memset(&_SSL[sslID].pk, 0, sizeof(pk_context)); ssl_set_own_cert(&_SSL[sslID].ctx, NULL, NULL); Memory::Write_U32(SSL_OK, _BufferIn); } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID); } break; } case IOCTLV_NET_SSL_SETBUILTINROOTCA: { int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { std::string cert_base_path(File::GetUserPath(D_WIIUSER_IDX)); int ret = x509_crt_parse_file(&_SSL[sslID].cacert, (cert_base_path + "rootca.pem").c_str()); if (ret) { x509_crt_free(&_SSL[sslID].clicert); Memory::Write_U32(SSL_ERR_FAILED, _BufferIn); } else { ssl_set_ca_chain(&_SSL[sslID].ctx, &_SSL[sslID].cacert, NULL, _SSL[sslID].hostname); Memory::Write_U32(SSL_OK, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA = %d", ret); } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_CONNECT: { int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { _SSL[sslID].sockfd = Memory::Read_U32(BufferOut2); INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT socket = %d", _SSL[sslID].sockfd); ssl_set_bio(&_SSL[sslID].ctx, net_recv, &_SSL[sslID].sockfd, net_send, &_SSL[sslID].sockfd); Memory::Write_U32(SSL_OK, _BufferIn); } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_CONNECT " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_DOHANDSHAKE: { int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { WiiSockMan &sm = WiiSockMan::getInstance(); sm.doSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_DOHANDSHAKE); return false; } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); } break; } case IOCTLV_NET_SSL_WRITE: { int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { WiiSockMan &sm = WiiSockMan::getInstance(); sm.doSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_WRITE); return false; } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_WRITE " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); INFO_LOG(WII_IPC_SSL, "%s", Memory::GetPointer(BufferOut2)); break; } case IOCTLV_NET_SSL_READ: { int ret = 0; int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { WiiSockMan &sm = WiiSockMan::getInstance(); sm.doSock(_SSL[sslID].sockfd, _CommandAddress, IOCTLV_NET_SSL_READ); return false; } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_READ(%d)" "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", ret, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_SETROOTCADEFAULT: { int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { Memory::Write_U32(SSL_OK, _BufferIn); } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); } INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETROOTCADEFAULT " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } case IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT: { INFO_LOG(WII_IPC_SSL, "IOCTLV_NET_SSL_SETCLIENTCERTDEFAULT " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); int sslID = Memory::Read_U32(BufferOut) - 1; if (SSLID_VALID(sslID)) { Memory::Write_U32(SSL_OK, _BufferIn); } else { Memory::Write_U32(SSL_ERR_ID, _BufferIn); } break; } default: ERROR_LOG(WII_IPC_SSL, "%i " "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), " "BufferIn3: (%08x, %i), BufferOut: (%08x, %i), " "BufferOut2: (%08x, %i), BufferOut3: (%08x, %i)", CommandBuffer.Parameter, _BufferIn, BufferInSize, _BufferIn2, BufferInSize2, _BufferIn3, BufferInSize3, BufferOut, BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3); break; } // SSL return codes are written to BufferIn Memory::Write_U32(0, _CommandAddress+4); return true; }
static u32 sceMp4Init() { INFO_LOG(ME, "sceMp4Init()"); return 0; }
int PSPSaveDialog::Update(int animSpeed) { if (GetStatus() != SCE_UTILITY_STATUS_RUNNING) return SCE_ERROR_UTILITY_INVALID_STATUS; if (!param.GetPspParam()) { ChangeStatusShutdown(SAVEDATA_SHUTDOWN_DELAY_US); return 0; } if (pendingStatus != SCE_UTILITY_STATUS_RUNNING) { // We're actually done, we're just waiting to tell the game that. return 0; } // The struct may have been updated by the game. This happens in "Where Is My Heart?" // Check if it has changed, reload it. // TODO: Cut down on preloading? This rebuilds the list from scratch. int size = Memory::Read_U32(requestAddr); if (memcmp(Memory::GetPointer(requestAddr), &originalRequest, size) != 0) { memset(&request, 0, sizeof(request)); Memory::Memcpy(&request, requestAddr, size); Memory::Memcpy(&originalRequest, requestAddr, size); param.SetPspParam(&request); } UpdateButtons(); UpdateFade(animSpeed); okButtonImg = I_CIRCLE; cancelButtonImg = I_CROSS; okButtonFlag = CTRL_CIRCLE; cancelButtonFlag = CTRL_CROSS; if (param.GetPspParam()->common.buttonSwap == 1) { okButtonImg = I_CROSS; cancelButtonImg = I_CIRCLE; okButtonFlag = CTRL_CROSS; cancelButtonFlag = CTRL_CIRCLE; } I18NCategory *d = GetI18NCategory("Dialog"); switch (display) { case DS_SAVE_LIST_CHOICE: StartDraw(); DisplaySaveList(); DisplaySaveDataInfo1(); DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL); DisplayBanner(DB_SAVE); if (IsButtonPressed(cancelButtonFlag)) { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL; StartFade(false); } else if (IsButtonPressed(okButtonFlag)) { // Save exist, ask user confirm if (param.GetFileInfo(currentSelectedSave).size > 0) { yesnoChoice = 0; display = DS_SAVE_CONFIRM_OVERWRITE; } else { display = DS_SAVE_SAVING; if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) { param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save display = DS_SAVE_DONE; } else display = DS_SAVE_LIST_CHOICE; // This will probably need error message ? } } EndDraw(); break; case DS_SAVE_CONFIRM: StartDraw(); DisplaySaveIcon(); DisplaySaveDataInfo2(); DisplayMessage(d->T("Confirm Save", "Do you want to save this data?"), true); DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL); DisplayBanner(DB_SAVE); if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL; StartFade(false); } else if (IsButtonPressed(okButtonFlag)) { display = DS_SAVE_SAVING; if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) { param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save display = DS_SAVE_DONE; } else { // TODO: This should probably show an error message? StartFade(false); } } EndDraw(); break; case DS_SAVE_CONFIRM_OVERWRITE: StartDraw(); DisplaySaveIcon(); DisplaySaveDataInfo2(); DisplayMessage(d->T("Confirm Overwrite","Do you want to overwrite the data?"), true); DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL); DisplayBanner(DB_SAVE); if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) { if (param.GetPspParam()->mode != SCE_UTILITY_SAVEDATA_TYPE_SAVE) display = DS_SAVE_LIST_CHOICE; else { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL; StartFade(false); } } else if (IsButtonPressed(okButtonFlag)) { display = DS_SAVE_SAVING; if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) { param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save display = DS_SAVE_DONE; } else { // TODO: This should probably show an error message? if (param.GetPspParam()->mode != SCE_UTILITY_SAVEDATA_TYPE_SAVE) display = DS_SAVE_LIST_CHOICE; else StartFade(false); } } EndDraw(); break; case DS_SAVE_SAVING: StartDraw(); DisplaySaveIcon(); DisplaySaveDataInfo2(); DisplayMessage(d->T("Saving","Saving\nPlease Wait...")); DisplayBanner(DB_SAVE); EndDraw(); break; case DS_SAVE_DONE: StartDraw(); DisplaySaveIcon(); DisplaySaveDataInfo2(); DisplayMessage(d->T("Save completed")); DisplayButtons(DS_BUTTON_CANCEL); DisplayBanner(DB_SAVE); if (IsButtonPressed(cancelButtonFlag)) { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_SUCCESS; // Set the save to use for autosave and autoload param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx); StartFade(false); } EndDraw(); break; case DS_LOAD_LIST_CHOICE: StartDraw(); DisplaySaveList(); DisplaySaveDataInfo1(); DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL); DisplayBanner(DB_LOAD); if (IsButtonPressed(cancelButtonFlag)) { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL; StartFade(false); } else if (IsButtonPressed(okButtonFlag)) { display = DS_LOAD_LOADING; if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave)) display = DS_LOAD_DONE; } EndDraw(); break; case DS_LOAD_CONFIRM: StartDraw(); DisplaySaveIcon(); DisplaySaveDataInfo2(); DisplayMessage(d->T("ConfirmLoad", "Load this data?"), true); DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL); DisplayBanner(DB_LOAD); if (IsButtonPressed(cancelButtonFlag) || (IsButtonPressed(okButtonFlag) && yesnoChoice == 0)) { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL; StartFade(false); } else if (IsButtonPressed(okButtonFlag)) { display = DS_LOAD_LOADING; if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave)) display = DS_LOAD_DONE; else { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL; StartFade(false); } } EndDraw(); break; case DS_LOAD_LOADING: StartDraw(); DisplaySaveIcon(); DisplaySaveDataInfo2(); DisplayMessage(d->T("Loading","Loading\nPlease Wait...")); DisplayBanner(DB_LOAD); EndDraw(); break; case DS_LOAD_DONE: StartDraw(); DisplaySaveIcon(); DisplaySaveDataInfo2(); DisplayMessage(d->T("Load completed")); DisplayButtons(DS_BUTTON_CANCEL); DisplayBanner(DB_LOAD); // Allow OK to be pressed as well to confirm the save. // The PSP only allows cancel, but that's generally not great UX. // Allowing this here makes it quicker for most users to get into the actual game. if (IsButtonPressed(cancelButtonFlag) || IsButtonPressed(okButtonFlag)) { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_SUCCESS; // Set the save to use for autosave and autoload param.SetSelectedSave(param.GetFileInfo(currentSelectedSave).idx); StartFade(false); } EndDraw(); break; case DS_LOAD_NODATA: StartDraw(); DisplayMessage(d->T("There is no data")); DisplayButtons(DS_BUTTON_CANCEL); DisplayBanner(DB_LOAD); if (IsButtonPressed(cancelButtonFlag)) { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA; StartFade(false); } EndDraw(); break; case DS_DELETE_LIST_CHOICE: StartDraw(); DisplaySaveList(); DisplaySaveDataInfo1(); DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL); DisplayBanner(DB_DELETE); if (IsButtonPressed(cancelButtonFlag)) { param.GetPspParam()->common.result = SCE_UTILITY_DIALOG_RESULT_CANCEL; StartFade(false); } else if (IsButtonPressed(okButtonFlag)) { yesnoChoice = 0; display = DS_DELETE_CONFIRM; } EndDraw(); break; case DS_DELETE_CONFIRM: StartDraw(); DisplaySaveIcon(); DisplaySaveDataInfo2(); DisplayMessage(d->T("DeleteConfirm", "This save data will be deleted.\nAre you sure you want to continue?"), true); DisplayButtons(DS_BUTTON_OK | DS_BUTTON_CANCEL); DisplayBanner(DB_DELETE); if (IsButtonPressed(cancelButtonFlag)) display = DS_DELETE_LIST_CHOICE; else if (IsButtonPressed(okButtonFlag)) { if (yesnoChoice == 0) display = DS_DELETE_LIST_CHOICE; else { display = DS_DELETE_DELETING; if (param.Delete(param.GetPspParam(),currentSelectedSave)) { param.SetPspParam(param.GetPspParam()); // Optim : Just Update modified save display = DS_DELETE_DONE; } else display = DS_DELETE_LIST_CHOICE; // This will probably need error message ? } } EndDraw(); break; case DS_DELETE_DELETING: StartDraw(); DisplayMessage(d->T("Deleting","Deleting\nPlease Wait...")); DisplayBanner(DB_DELETE); EndDraw(); break; case DS_DELETE_DONE: StartDraw(); DisplayMessage(d->T("Delete completed")); DisplayButtons(DS_BUTTON_CANCEL); DisplayBanner(DB_DELETE); if (IsButtonPressed(cancelButtonFlag)) { if (param.GetFilenameCount() == 0) display = DS_DELETE_NODATA; else display = DS_DELETE_LIST_CHOICE; } EndDraw(); break; case DS_DELETE_NODATA: StartDraw(); DisplayMessage(d->T("There is no data")); DisplayButtons(DS_BUTTON_CANCEL); DisplayBanner(DB_DELETE); if (IsButtonPressed(cancelButtonFlag)) { param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA; StartFade(false); } EndDraw(); break; case DS_NONE: // For action which display nothing { switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode) { case SCE_UTILITY_SAVEDATA_TYPE_LOAD: // Only load and exit case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave)) param.GetPspParam()->common.result = 0; else param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_LOAD_NO_DATA; ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; case SCE_UTILITY_SAVEDATA_TYPE_SAVE: // Only save and exit case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: if (param.Save(param.GetPspParam(), GetSelectedSaveDirName())) param.GetPspParam()->common.result = 0; else param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_SAVE_MS_NOSPACE; ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; case SCE_UTILITY_SAVEDATA_TYPE_SIZES: param.GetPspParam()->common.result = param.GetSizes(param.GetPspParam()); ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; case SCE_UTILITY_SAVEDATA_TYPE_LIST: param.GetList(param.GetPspParam()); param.GetPspParam()->common.result = 0; ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; case SCE_UTILITY_SAVEDATA_TYPE_FILES: param.GetPspParam()->common.result = param.GetFilesList(param.GetPspParam()); ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE: { bool result = param.GetSize(param.GetPspParam()); // TODO: According to JPCSP, should test/verify this part but seems edge casey. if (MemoryStick_State() != PSP_MEMORYSTICK_STATE_DRIVER_READY) param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_MEMSTICK; else if (result) param.GetPspParam()->common.result = 0; else param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); } break; case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA: DEBUG_LOG(SCEUTILITY, "sceUtilitySavedata DELETEDATA: %s", param.GetPspParam()->saveName); param.GetPspParam()->common.result = param.DeleteData(param.GetPspParam()); ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; //case SCE_UTILITY_SAVEDATA_TYPE_AUTODELETE: case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE: if (param.Delete(param.GetPspParam(), param.GetSelectedSave())) param.GetPspParam()->common.result = 0; else param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_DELETE_NO_DATA; ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; // TODO: Should reset the directory's other files. case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA: case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE: if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE)) param.GetPspParam()->common.result = 0; else param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA: case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE: if (param.Save(param.GetPspParam(), GetSelectedSaveDirName(), param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE)) param.GetPspParam()->common.result = 0; else param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; case SCE_UTILITY_SAVEDATA_TYPE_READDATA: case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE: if (param.Load(param.GetPspParam(), GetSelectedSaveDirName(), currentSelectedSave, param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE)) param.GetPspParam()->common.result = 0; else if (param.secureCanSkip(param.GetPspParam(),param.GetPspParam()->mode == SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE)) { INFO_LOG(SCEUTILITY,"Has not been saved yet, just skip."); param.GetPspParam()->common.result = 0; } else param.GetPspParam()->common.result = SCE_UTILITY_SAVEDATA_ERROR_RW_NO_DATA; // not sure if correct code ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; default: ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; } } break; default: ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0); break; } if (status == SCE_UTILITY_STATUS_FINISHED || pendingStatus == SCE_UTILITY_STATUS_FINISHED) Memory::Memcpy(requestAddr, &request, request.common.size); return 0; }
LinkedShader::LinkedShader(Shader *vs, Shader *fs, u32 vertType, bool useHWTransform, LinkedShader *previous) : useHWTransform_(useHWTransform), program(0), dirtyUniforms(0) { PROFILE_THIS_SCOPE("shaderlink"); program = glCreateProgram(); vs_ = vs; glAttachShader(program, vs->shader); glAttachShader(program, fs->shader); // Bind attribute locations to fixed locations so that they're // the same in all shaders. We use this later to minimize the calls to // glEnableVertexAttribArray and glDisableVertexAttribArray. glBindAttribLocation(program, ATTR_POSITION, "position"); glBindAttribLocation(program, ATTR_TEXCOORD, "texcoord"); glBindAttribLocation(program, ATTR_NORMAL, "normal"); glBindAttribLocation(program, ATTR_W1, "w1"); glBindAttribLocation(program, ATTR_W2, "w2"); glBindAttribLocation(program, ATTR_COLOR0, "color0"); glBindAttribLocation(program, ATTR_COLOR1, "color1"); #ifndef USING_GLES2 if (gstate_c.featureFlags & GPU_SUPPORTS_DUALSOURCE_BLEND) { // Dual source alpha glBindFragDataLocationIndexed(program, 0, 0, "fragColor0"); glBindFragDataLocationIndexed(program, 0, 1, "fragColor1"); } else if (gl_extensions.VersionGEThan(3, 3, 0)) { glBindFragDataLocation(program, 0, "fragColor0"); } #endif glLinkProgram(program); GLint linkStatus = GL_FALSE; glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) { GLint bufLength = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = new char[bufLength]; glGetProgramInfoLog(program, bufLength, NULL, buf); #ifdef ANDROID ELOG("Could not link program:\n %s", buf); #endif ERROR_LOG(G3D, "Could not link program:\n %s", buf); ERROR_LOG(G3D, "VS desc:\n%s\n", vs->GetShaderString(SHADER_STRING_SHORT_DESC).c_str()); ERROR_LOG(G3D, "FS desc:\n%s\n", fs->GetShaderString(SHADER_STRING_SHORT_DESC).c_str()); std::string vs_source = vs->GetShaderString(SHADER_STRING_SOURCE_CODE); std::string fs_source = fs->GetShaderString(SHADER_STRING_SOURCE_CODE); ERROR_LOG(G3D, "VS:\n%s\n", vs_source.c_str()); ERROR_LOG(G3D, "FS:\n%s\n", fs_source.c_str()); Reporting::ReportMessage("Error in shader program link: info: %s / fs: %s / vs: %s", buf, fs_source.c_str(), vs_source.c_str()); #ifdef SHADERLOG OutputDebugStringUTF8(buf); OutputDebugStringUTF8(vs_source.c_str()); OutputDebugStringUTF8(fs_source.c_str()); #endif delete [] buf; // we're dead! } // Prevent a buffer overflow. numBones = 0; return; } INFO_LOG(G3D, "Linked shader: vs %i fs %i", (int)vs->shader, (int)fs->shader); u_tex = glGetUniformLocation(program, "tex"); u_proj = glGetUniformLocation(program, "u_proj"); u_proj_through = glGetUniformLocation(program, "u_proj_through"); u_texenv = glGetUniformLocation(program, "u_texenv"); u_fogcolor = glGetUniformLocation(program, "u_fogcolor"); u_fogcoef = glGetUniformLocation(program, "u_fogcoef"); u_alphacolorref = glGetUniformLocation(program, "u_alphacolorref"); u_alphacolormask = glGetUniformLocation(program, "u_alphacolormask"); u_stencilReplaceValue = glGetUniformLocation(program, "u_stencilReplaceValue"); u_testtex = glGetUniformLocation(program, "testtex"); u_fbotex = glGetUniformLocation(program, "fbotex"); u_blendFixA = glGetUniformLocation(program, "u_blendFixA"); u_blendFixB = glGetUniformLocation(program, "u_blendFixB"); u_fbotexSize = glGetUniformLocation(program, "u_fbotexSize"); // Transform u_view = glGetUniformLocation(program, "u_view"); u_world = glGetUniformLocation(program, "u_world"); u_texmtx = glGetUniformLocation(program, "u_texmtx"); if (vertTypeGetWeightMask(vertType) != GE_VTYPE_WEIGHT_NONE) numBones = TranslateNumBones(vertTypeGetNumBoneWeights(vertType)); else numBones = 0; u_depthRange = glGetUniformLocation(program, "u_depthRange"); #ifdef USE_BONE_ARRAY u_bone = glGetUniformLocation(program, "u_bone"); #else for (int i = 0; i < 8; i++) { char name[10]; sprintf(name, "u_bone%i", i); u_bone[i] = glGetUniformLocation(program, name); } #endif // Lighting, texturing u_ambient = glGetUniformLocation(program, "u_ambient"); u_matambientalpha = glGetUniformLocation(program, "u_matambientalpha"); u_matdiffuse = glGetUniformLocation(program, "u_matdiffuse"); u_matspecular = glGetUniformLocation(program, "u_matspecular"); u_matemissive = glGetUniformLocation(program, "u_matemissive"); u_uvscaleoffset = glGetUniformLocation(program, "u_uvscaleoffset"); u_texclamp = glGetUniformLocation(program, "u_texclamp"); u_texclampoff = glGetUniformLocation(program, "u_texclampoff"); for (int i = 0; i < 4; i++) { char temp[64]; sprintf(temp, "u_lightpos%i", i); u_lightpos[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightdir%i", i); u_lightdir[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightatt%i", i); u_lightatt[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightangle%i", i); u_lightangle[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightspotCoef%i", i); u_lightspotCoef[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightambient%i", i); u_lightambient[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightdiffuse%i", i); u_lightdiffuse[i] = glGetUniformLocation(program, temp); sprintf(temp, "u_lightspecular%i", i); u_lightspecular[i] = glGetUniformLocation(program, temp); } attrMask = 0; if (-1 != glGetAttribLocation(program, "position")) attrMask |= 1 << ATTR_POSITION; if (-1 != glGetAttribLocation(program, "texcoord")) attrMask |= 1 << ATTR_TEXCOORD; if (-1 != glGetAttribLocation(program, "normal")) attrMask |= 1 << ATTR_NORMAL; if (-1 != glGetAttribLocation(program, "w1")) attrMask |= 1 << ATTR_W1; if (-1 != glGetAttribLocation(program, "w2")) attrMask |= 1 << ATTR_W2; if (-1 != glGetAttribLocation(program, "color0")) attrMask |= 1 << ATTR_COLOR0; if (-1 != glGetAttribLocation(program, "color1")) attrMask |= 1 << ATTR_COLOR1; availableUniforms = 0; if (u_proj != -1) availableUniforms |= DIRTY_PROJMATRIX; if (u_proj_through != -1) availableUniforms |= DIRTY_PROJTHROUGHMATRIX; if (u_texenv != -1) availableUniforms |= DIRTY_TEXENV; if (u_alphacolorref != -1) availableUniforms |= DIRTY_ALPHACOLORREF; if (u_alphacolormask != -1) availableUniforms |= DIRTY_ALPHACOLORMASK; if (u_fogcolor != -1) availableUniforms |= DIRTY_FOGCOLOR; if (u_fogcoef != -1) availableUniforms |= DIRTY_FOGCOEF; if (u_texenv != -1) availableUniforms |= DIRTY_TEXENV; if (u_uvscaleoffset != -1) availableUniforms |= DIRTY_UVSCALEOFFSET; if (u_texclamp != -1) availableUniforms |= DIRTY_TEXCLAMP; if (u_world != -1) availableUniforms |= DIRTY_WORLDMATRIX; if (u_view != -1) availableUniforms |= DIRTY_VIEWMATRIX; if (u_texmtx != -1) availableUniforms |= DIRTY_TEXMATRIX; if (u_stencilReplaceValue != -1) availableUniforms |= DIRTY_STENCILREPLACEVALUE; if (u_blendFixA != -1 || u_blendFixB != -1 || u_fbotexSize != -1) availableUniforms |= DIRTY_SHADERBLEND; if (u_depthRange != -1) availableUniforms |= DIRTY_DEPTHRANGE; // Looping up to numBones lets us avoid checking u_bone[i] #ifdef USE_BONE_ARRAY if (u_bone != -1) { for (int i = 0; i < numBones; i++) { availableUniforms |= DIRTY_BONEMATRIX0 << i; } } #else for (int i = 0; i < numBones; i++) { if (u_bone[i] != -1) availableUniforms |= DIRTY_BONEMATRIX0 << i; } #endif if (u_ambient != -1) availableUniforms |= DIRTY_AMBIENT; if (u_matambientalpha != -1) availableUniforms |= DIRTY_MATAMBIENTALPHA; if (u_matdiffuse != -1) availableUniforms |= DIRTY_MATDIFFUSE; if (u_matemissive != -1) availableUniforms |= DIRTY_MATEMISSIVE; if (u_matspecular != -1) availableUniforms |= DIRTY_MATSPECULAR; for (int i = 0; i < 4; i++) { if (u_lightdir[i] != -1 || u_lightspecular[i] != -1 || u_lightpos[i] != -1) availableUniforms |= DIRTY_LIGHT0 << i; } glUseProgram(program); // Default uniform values glUniform1i(u_tex, 0); glUniform1i(u_fbotex, 1); glUniform1i(u_testtex, 2); // The rest, use the "dirty" mechanism. dirtyUniforms = DIRTY_ALL; use(vertType, previous); }
int PSPSaveDialog::Init(int paramAddr) { // Ignore if already running if (GetStatus() != SCE_UTILITY_STATUS_NONE) { ERROR_LOG_REPORT(SCEUTILITY, "A save request is already running, not starting a new one"); return SCE_ERROR_UTILITY_INVALID_STATUS; } requestAddr = paramAddr; int size = Memory::Read_U32(requestAddr); memset(&request, 0, sizeof(request)); // Only copy the right size to support different save request format if (size != SAVEDATA_DIALOG_SIZE_V1 && size != SAVEDATA_DIALOG_SIZE_V2 && size != SAVEDATA_DIALOG_SIZE_V3) { ERROR_LOG_REPORT(SCEUTILITY, "sceUtilitySavedataInitStart: invalid size %d", size); return SCE_ERROR_UTILITY_INVALID_PARAM_SIZE; } Memory::Memcpy(&request, requestAddr, size); Memory::Memcpy(&originalRequest, requestAddr, size); int retval = param.SetPspParam(&request); const u32 mode = (u32)param.GetPspParam()->mode; const char *modeName = mode < ARRAY_SIZE(utilitySavedataTypeNames) ? utilitySavedataTypeNames[mode] : "UNKNOWN"; INFO_LOG(SCEUTILITY,"sceUtilitySavedataInitStart(%08x) - %s (%d)", paramAddr, modeName, mode); INFO_LOG(SCEUTILITY,"sceUtilitySavedataInitStart(%08x) : Game key (hex): %s", paramAddr, param.GetKey(param.GetPspParam()).c_str()); yesnoChoice = 1; switch ((SceUtilitySavedataFocus)(u32)param.GetPspParam()->focus) { case SCE_UTILITY_SAVEDATA_FOCUS_NAME: currentSelectedSave = param.GetSaveNameIndex(param.GetPspParam()); break; case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTLIST: currentSelectedSave = param.GetFirstListSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_LASTLIST: currentSelectedSave = param.GetLastListSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_LATEST: currentSelectedSave = param.GetLatestSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_OLDEST: currentSelectedSave = param.GetOldestSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTDATA: currentSelectedSave = param.GetFirstDataSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_LASTDATA: currentSelectedSave = param.GetLastDataSave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY: currentSelectedSave = param.GetFirstEmptySave(); break; case SCE_UTILITY_SAVEDATA_FOCUS_LASTEMPTY: currentSelectedSave = param.GetLastEmptySave(); break; default: WARN_LOG(SCEUTILITY, "Unknown save list focus option: %d", param.GetPspParam()->focus); currentSelectedSave = 0; break; } switch ((SceUtilitySavedataType)(u32)param.GetPspParam()->mode) { case SCE_UTILITY_SAVEDATA_TYPE_LOAD: DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetSaveName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if (param.GetFileInfo(0).size != 0) display = DS_LOAD_CONFIRM; else display = DS_LOAD_NODATA; break; case SCE_UTILITY_SAVEDATA_TYPE_AUTOLOAD: DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetSaveName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); display = DS_NONE; // Is this necessary? // currentSelectedSave = param.GetSelectedSave(); break; case SCE_UTILITY_SAVEDATA_TYPE_LISTLOAD: DEBUG_LOG(SCEUTILITY, "Loading. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if(param.GetFilenameCount() == 0) display = DS_LOAD_NODATA; else display = DS_LOAD_LIST_CHOICE; break; case SCE_UTILITY_SAVEDATA_TYPE_SAVE: DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if (param.GetFileInfo(0).size != 0) { yesnoChoice = 0; display = DS_SAVE_CONFIRM_OVERWRITE; } else display = DS_SAVE_CONFIRM; break; case SCE_UTILITY_SAVEDATA_TYPE_AUTOSAVE: DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); display = DS_NONE; // Is this necessary? // currentSelectedSave = param.GetSelectedSave(); break; case SCE_UTILITY_SAVEDATA_TYPE_LISTSAVE: DEBUG_LOG(SCEUTILITY, "Saving. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); display = DS_SAVE_LIST_CHOICE; break; case SCE_UTILITY_SAVEDATA_TYPE_LISTDELETE: DEBUG_LOG(SCEUTILITY, "Delete. Title: %s Save: %s File: %s", param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); if(param.GetFilenameCount() == 0) display = DS_DELETE_NODATA; else display = DS_DELETE_LIST_CHOICE; break; case SCE_UTILITY_SAVEDATA_TYPE_SIZES: case SCE_UTILITY_SAVEDATA_TYPE_LIST: case SCE_UTILITY_SAVEDATA_TYPE_FILES: case SCE_UTILITY_SAVEDATA_TYPE_GETSIZE: case SCE_UTILITY_SAVEDATA_TYPE_SINGLEDELETE: case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATASECURE: case SCE_UTILITY_SAVEDATA_TYPE_MAKEDATA: case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATASECURE: case SCE_UTILITY_SAVEDATA_TYPE_WRITEDATA: case SCE_UTILITY_SAVEDATA_TYPE_READDATASECURE: case SCE_UTILITY_SAVEDATA_TYPE_READDATA: case SCE_UTILITY_SAVEDATA_TYPE_DELETEDATA: display = DS_NONE; break; case SCE_UTILITY_SAVEDATA_TYPE_DELETE: // When run on a PSP, displays a list of all saves on the PSP. Weird. (Not really, it's to let you free up space) display = DS_DELETE_LIST_CHOICE; break; default: { ERROR_LOG_REPORT(SCEUTILITY, "Load/Save function %d not coded. Title: %s Save: %s File: %s", (SceUtilitySavedataType)(u32)param.GetPspParam()->mode, param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); param.GetPspParam()->common.result = 0; ChangeStatusInit(SAVEDATA_INIT_DELAY_US); display = DS_NONE; return 0; // Return 0 should allow the game to continue, but missing function must be implemented and returning the right value or the game can block. } break; } if (retval < 0) { ChangeStatusShutdown(SAVEDATA_SHUTDOWN_DELAY_US); } else { ChangeStatusInit(SAVEDATA_INIT_DELAY_US); } UpdateButtons(); StartFade(true); /*INFO_LOG(SCEUTILITY,"Dump Param :"); INFO_LOG(SCEUTILITY,"size : %d",param.GetPspParam()->size); INFO_LOG(SCEUTILITY,"language : %d",param.GetPspParam()->language); INFO_LOG(SCEUTILITY,"buttonSwap : %d",param.GetPspParam()->buttonSwap); INFO_LOG(SCEUTILITY,"result : %d",param.GetPspParam()->common.result); INFO_LOG(SCEUTILITY,"mode : %d",param.GetPspParam()->mode); INFO_LOG(SCEUTILITY,"bind : %d",param.GetPspParam()->bind); INFO_LOG(SCEUTILITY,"overwriteMode : %d",param.GetPspParam()->overwriteMode); INFO_LOG(SCEUTILITY,"gameName : %s",param.GetGameName(param.GetPspParam()).c_str()); INFO_LOG(SCEUTILITY,"saveName : %s",param.GetPspParam()->saveName); INFO_LOG(SCEUTILITY,"saveNameList : %08x",*((unsigned int*)¶m.GetPspParam()->saveNameList)); INFO_LOG(SCEUTILITY,"fileName : %s",param.GetPspParam()->fileName); INFO_LOG(SCEUTILITY,"dataBuf : %08x",*((unsigned int*)¶m.GetPspParam()->dataBuf)); INFO_LOG(SCEUTILITY,"dataBufSize : %u",param.GetPspParam()->dataBufSize); INFO_LOG(SCEUTILITY,"dataSize : %u",param.GetPspParam()->dataSize); INFO_LOG(SCEUTILITY,"sfo title : %s",param.GetPspParam()->sfoParam.title); INFO_LOG(SCEUTILITY,"sfo savedataTitle : %s",param.GetPspParam()->sfoParam.savedataTitle); INFO_LOG(SCEUTILITY,"sfo detail : %s",param.GetPspParam()->sfoParam.detail); INFO_LOG(SCEUTILITY,"icon0 data : %08x",*((unsigned int*)¶m.GetPspParam()->icon0FileData.buf)); INFO_LOG(SCEUTILITY,"icon0 size : %u",param.GetPspParam()->icon0FileData.bufSize); INFO_LOG(SCEUTILITY,"icon1 data : %08x",*((unsigned int*)¶m.GetPspParam()->icon1FileData.buf)); INFO_LOG(SCEUTILITY,"icon1 size : %u",param.GetPspParam()->icon1FileData.bufSize); INFO_LOG(SCEUTILITY,"pic1 data : %08x",*((unsigned int*)¶m.GetPspParam()->pic1FileData.buf)); INFO_LOG(SCEUTILITY,"pic1 size : %u",param.GetPspParam()->pic1FileData.bufSize); INFO_LOG(SCEUTILITY,"snd0 data : %08x",*((unsigned int*)¶m.GetPspParam()->snd0FileData.buf)); INFO_LOG(SCEUTILITY,"snd0 size : %u",param.GetPspParam()->snd0FileData.bufSize);*/ return retval; }
void GCMemcardDirectory::FlushToFile() { int errors = 0; DEntry invalid; for (u16 i = 0; i < m_saves.size(); ++i) { if (m_saves[i].m_dirty) { if (BE32(m_saves[i].m_gci_header.Gamecode) != 0xFFFFFFFF) { m_saves[i].m_dirty = false; if (m_saves[i].m_filename.empty()) { std::string defaultSaveName = m_SaveDirectory + m_saves[i].m_gci_header.GCI_FileName(); // Check to see if another file is using the same name // This seems unlikely except in the case of file corruption // otherwise what user would name another file this way? for (int j = 0; File::Exists(defaultSaveName) && j < 10; ++j) { defaultSaveName.insert(defaultSaveName.end() - 4, '0'); } if (File::Exists(defaultSaveName)) PanicAlertT("Failed to find new filename\n %s\n will be overwritten", defaultSaveName.c_str()); m_saves[i].m_filename = defaultSaveName; } File::IOFile GCI(m_saves[i].m_filename, "wb"); if (GCI) { GCI.WriteBytes(&m_saves[i].m_gci_header, DENTRY_SIZE); GCI.WriteBytes(m_saves[i].m_save_data.data(), BLOCK_SIZE * m_saves[i].m_save_data.size()); if (GCI.IsGood()) { Core::DisplayMessage( StringFromFormat("Wrote save contents to %s", m_saves[i].m_filename.c_str()), 4000); } else { ++errors; Core::DisplayMessage( StringFromFormat("Failed to write save contents to %s", m_saves[i].m_filename.c_str()), 4000); ERROR_LOG(EXPANSIONINTERFACE, "Failed to save data to %s", m_saves[i].m_filename.c_str()); } } } else if (m_saves[i].m_filename.length() != 0) { m_saves[i].m_dirty = false; std::string &oldname = m_saves[i].m_filename; std::string deletedname = oldname + ".deleted"; if (File::Exists(deletedname)) File::Delete(deletedname); File::Rename(oldname, deletedname); m_saves[i].m_filename.clear(); m_saves[i].m_save_data.clear(); m_saves[i].m_used_blocks.clear(); } } // Unload the save data for any game that is not running // we could use !m_dirty, but some games have multiple gci files and may not write to them simultaneously // this ensures that the save data for all of the current games gci files are stored in the savestate u32 gamecode = BE32(m_saves[i].m_gci_header.Gamecode); if (gamecode != m_GameId && gamecode != 0xFFFFFFFF && m_saves[i].m_save_data.size()) { INFO_LOG(EXPANSIONINTERFACE, "Flushing savedata to disk for %s", m_saves[i].m_filename.c_str()); m_saves[i].m_save_data.clear(); } } #if _WRITE_MC_HEADER u8 mc[BLOCK_SIZE * MC_FST_BLOCKS]; Read(0, BLOCK_SIZE * MC_FST_BLOCKS, mc); File::IOFile hdrfile(m_SaveDirectory + MC_HDR, "wb"); hdrfile.WriteBytes(mc, BLOCK_SIZE * MC_FST_BLOCKS); #endif }
s32 GCMemcardDirectory::Write(u32 destaddress, s32 length, u8 *srcaddress) { if (length != 0x80) INFO_LOG(EXPANSIONINTERFACE, "WRITING TO %x, len %x", destaddress, length); s32 block = destaddress / BLOCK_SIZE; u32 offset = destaddress % BLOCK_SIZE; s32 extra = 0; // used for write calls that are across multiple blocks if (offset + length > BLOCK_SIZE) { extra = length + offset - BLOCK_SIZE; length -= extra; // verify that we haven't calculated a length beyond BLOCK_SIZE _dbg_assert_msg_(EXPANSIONINTERFACE, (destaddress + length) % BLOCK_SIZE == 0, "Memcard directory Write Logic Error"); } if (m_LastBlock != block) { switch (block) { case 0: m_LastBlock = block; m_LastBlockAddress = (u8 *)&m_hdr; break; case 1: case 2: { m_LastBlock = -1; s32 bytes_written = 0; while (length > 0) { s32 to_write = std::min<s32>(DENTRY_SIZE, length); bytes_written += DirectoryWrite(destaddress + bytes_written, to_write, srcaddress + bytes_written); length -= to_write; } return bytes_written; } case 3: m_LastBlock = block; m_LastBlockAddress = (u8 *)&m_bat1; break; case 4: m_LastBlock = block; m_LastBlockAddress = (u8 *)&m_bat2; break; default: m_LastBlock = SaveAreaRW(block, true); if (m_LastBlock == -1) { PanicAlertT("Report: GCIFolder Writing to unallocated block %x", block); exit(0); } } } memcpy(m_LastBlockAddress + offset, srcaddress, length); if (extra) extra = Write(destaddress + length, extra, srcaddress + length); return length + extra; }
// Deletes the given directory and anything under it. Returns true on success. bool DeleteDirRecursively(const std::string &directory) { INFO_LOG(COMMON, "DeleteDirRecursively: %s", directory.c_str()); #ifdef _WIN32 // Find the first file in the directory. WIN32_FIND_DATA ffd; HANDLE hFind = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd); if (hFind == INVALID_HANDLE_VALUE) { FindClose(hFind); return false; } // windows loop do { const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); #else struct dirent dirent, *result = NULL; DIR *dirp = opendir(directory.c_str()); if (!dirp) return false; // non windows loop while (!readdir_r(dirp, &dirent, &result) && result) { const std::string virtualName = result->d_name; #endif // check for "." and ".." if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || ((virtualName[0] == '.') && (virtualName[1] == '.') && (virtualName[2] == '\0'))) continue; std::string newPath = directory + DIR_SEP_CHR + virtualName; if (IsDirectory(newPath)) { if (!DeleteDirRecursively(newPath)) { #ifndef _WIN32 closedir(dirp); #endif return false; } } else { if (!FileUtil::Delete(newPath)) { #ifndef _WIN32 closedir(dirp); #endif return false; } } #ifdef _WIN32 } while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); #else } closedir(dirp); #endif FileUtil::DeleteDir(directory); return true; }
void EmuThread::run() { running = true; setCurrentThreadName("EmuThread"); host->UpdateUI(); host->InitGL(0); EmuThread_LockDraw(true); #ifndef USING_GLES2 glewInit(); #endif NativeInitGraphics(); INFO_LOG(BOOT, "Starting up hardware."); QElapsedTimer timer; EmuThread_LockDraw(false); while(running) { //UpdateGamepad(*input_state); timer.start(); gameMutex->lock(); bool gRun = gameRunning; gameMutex->unlock(); if(gRun) { EmuThread_LockDraw(true); if(needInitGame) { CoreParameter coreParameter; coreParameter.fileToStart = fileToStart.toStdString(); coreParameter.enableSound = true; coreParameter.gpuCore = GPU_GLES; coreParameter.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER; coreParameter.enableDebugging = true; coreParameter.printfEmuLog = false; coreParameter.headLess = false; coreParameter.renderWidth = (480 * g_Config.iWindowZoom) * (g_Config.SSAntiAliasing + 1); coreParameter.renderHeight = (272 * g_Config.iWindowZoom) * (g_Config.SSAntiAliasing + 1); coreParameter.outputWidth = dp_xres; coreParameter.outputHeight = dp_yres; coreParameter.pixelWidth = pixel_xres; coreParameter.pixelHeight = pixel_yres; coreParameter.startPaused = !g_Config.bAutoRun; std::string error_string; if (!PSP_Init(coreParameter, &error_string)) { ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str()); FinalShutdown(); return; } LayoutGamepad(dp_xres, dp_yres); _dbg_update_(); host->UpdateDisassembly(); Core_EnableStepping(coreParameter.startPaused ? TRUE : FALSE); #ifdef _DEBUG host->UpdateMemView(); #endif host->BootDone(); needInitGame = false; } glstate.Restore(); glViewport(0, 0, pixel_xres, pixel_yres); Matrix4x4 ortho; ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f); glsl_bind(UIShader_Get()); glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr()); ReapplyGfxState(); Core_Run(); // Hopefully coreState is now CORE_NEXTFRAME if (coreState == CORE_NEXTFRAME) { // set back to running for the next frame coreState = CORE_RUNNING; qint64 time = timer.elapsed(); const int frameTime = (1.0f/60.0f) * 1000; if(time < frameTime) { EmuThread_LockDraw(false); msleep(frameTime-time); EmuThread_LockDraw(true); } timer.start(); } fbo_unbind(); UIShader_Prepare(); uiTexture->Bind(0); glViewport(0, 0, pixel_xres, pixel_yres); ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL); //if (g_Config.bShowTouchControls) // DrawGamepad(ui_draw2d); glsl_bind(UIShader_Get()); ui_draw2d.End(); ui_draw2d.Flush(); // Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it? #if defined(USING_GLES2) bool hasDiscard = false; // TODO if (hasDiscard) { //glDiscardFramebuffer(GL_COLOR_EXT | GL_DEPTH_EXT | GL_STENCIL_EXT); } #endif glWindow->swapBuffers(); EmuThread_LockDraw(false); } else { EmuThread_LockDraw(true); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); time_update(); float t = (float)frames_ / 60.0f; frames_++; float alpha = t; if (t > 1.0f) alpha = 1.0f; float alphaText = alpha; //if (t > 2.0f) alphaText = 3.0f - t; glstate.Restore(); glViewport(0, 0, pixel_xres, pixel_yres); Matrix4x4 ortho; ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f); glsl_bind(UIShader_Get()); glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr()); ReapplyGfxState(); UIShader_Prepare(); glViewport(0, 0, pixel_xres, pixel_yres); UIBegin(UIShader_Get()); DrawBackground(alpha); ui_draw2d.SetFontScale(1.5f, 1.5f); ui_draw2d.DrawText(UBUNTU48, "PPSSPP", dp_xres / 2, dp_yres / 2 - 30, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); ui_draw2d.SetFontScale(1.0f, 1.0f); ui_draw2d.DrawText(UBUNTU24, "Created by Henrik Rydgard", dp_xres / 2, dp_yres / 2 + 40, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); ui_draw2d.DrawText(UBUNTU24, "Free Software under GPL 2.0", dp_xres / 2, dp_yres / 2 + 70, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); ui_draw2d.DrawText(UBUNTU24, "www.ppsspp.org", dp_xres / 2, dp_yres / 2 + 130, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER); UIEnd(); glsl_bind(UIShader_Get()); ui_draw2d.Flush(); glWindow->swapBuffers(); EmuThread_LockDraw(false); qint64 time = timer.elapsed(); const int frameTime = (1.0f/60.0f) * 1000; if(time < frameTime) { msleep(frameTime-time); } timer.start(); } } if(gameRunning) { stopGame(); } }
CARDUCode::CARDUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc) { INFO_LOG(DSPHLE, "CARDUCode - initialized"); }
u32 scePowerGetPllClockFrequencyInt() { INFO_LOG(HLE,"%i=scePowerGetPllClockFrequencyInt()", pllFreq); return pllFreq; }
int main(int argc, char* argv[]) { arg_start = argv[0]; arg_end = argv[argc-1] + strlen(argv[argc - 1]) + 1; env_start = environ[0]; if (argc != 2) exit(-1); daemon_start(); INFO_LOG ("async_server %s, report bugs to <*****@*****.**>", VERSION); load_config_file(argv[1]); check_single(); if (config_get_strval("proc_name", NULL)) { set_title("%s-MAIN", config_get_strval("proc_name", NULL)); } else { set_title("%s-MAIN", arg_start); } load_work_file(config_get_strval("work_conf", "")); if (-1 == log_init(config_get_strval("log_dir", "./"), (log_lvl_t)config_get_intval("log_level", 8), config_get_intval("log_size", 33554432), config_get_intval("log_maxfiles", 100), "main_")) { BOOT_LOG(-1, "log init"); } init_warning_system(); plugin_load(config_get_strval("plugin_file", "")); shmq_init(g_work_confs.size(), config_get_intval("shmq_size", 8388608)); int max_connect = config_get_intval("max_connect", 10000); if (max_connect <= 4096) max_connect = 4096; g_max_connect = max_connect; int max_pkg_len = config_get_intval("max_pkg_len", 16384); if (max_pkg_len <= 4096) max_pkg_len = 4096; g_max_pkg_len = max_pkg_len; const char * bind_ip = config_get_strval("bind_ip", NULL); if (NULL == bind_ip) { BOOT_LOG(-1, "unspecified bind_ip"); return -1; } if (0 != get_ip_by_name(bind_ip, g_bind_ip)) { strncpy(g_bind_ip, bind_ip, 16); } if (g_plugin.plugin_init) { if (g_plugin.plugin_init(PROC_MAIN) != 0) BOOT_LOG(-1, "plugin_init init failed PROC_MAIN"); } for (uint32_t i = 0; i < g_work_confs.size(); ++i) g_work_confs[i].pid = fork_work(i); pid_t conn_pid = fork_conn(); while (!g_stop) { int status = 0; pid_t p = waitpid(-1, &status, 0); if(-1 == p) continue; if (WEXITSTATUS(status) == 10) { if (p == conn_pid) { conn_pid = -1; } else { for (uint32_t i = 0; i < g_work_confs.size(); ++i) { if (g_work_confs[i].pid == p) { g_work_confs[i].pid = -1; break; } } } } else { if (p == conn_pid) { conn_pid = fork_conn(); send_warning_msg("conn core", 0, 0, 0, config_get_strval("bind_ip", "0.0.0.0")); ERROR_LOG("conn core"); } else { for (uint32_t i = 0; i < g_work_confs.size(); ++i) { if (g_work_confs[i].pid == p) { ERROR_LOG("work core, id: %u, pid: %d", g_work_confs[i].id, p); g_work_confs[i].pid = fork_work(i); send_warning_msg("work core", g_work_confs[i].id, 0, 0, config_get_strval("bind_ip", "0.0.0.0")); break; } } } } } for (uint32_t i = 0; i < g_work_confs.size(); ++i) { if (g_work_confs[i].pid != -1) kill(g_work_confs[i].pid, SIGTERM); } if (conn_pid != -1) kill(conn_pid, SIGTERM); while (true) { int ret = 0; for (uint32_t i = 0; i < g_work_confs.size(); ++i) { if (g_work_confs[i].pid != -1) ret = 1; } if (ret || conn_pid != -1) { int status = 0; pid_t p = waitpid(-1, &status, 0); if(-1 == p) continue; if (p == conn_pid) { conn_pid = -1; } else { for (uint32_t i = 0; i < g_work_confs.size(); ++i) { if (g_work_confs[i].pid == p) { g_work_confs[i].pid = -1; break; } } } } else { break; } } if (g_plugin.plugin_fini) g_plugin.plugin_fini(PROC_MAIN); }
u32 scePowerGetBusClockFrequencyInt() { INFO_LOG(HLE,"%i=scePowerGetBusClockFrequencyInt()", busFreq); return busFreq; }
u32 ImmRead (u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s ImmRead", m_strName.c_str()); return 0;}
ReturnCode ES::ImportContentEnd(Context& context, u32 content_fd) { INFO_LOG(IOS_ES, "ImportContentEnd: content fd %08x", content_fd); if (!context.title_import_export.valid || !context.title_import_export.content.valid) return ES_EINVAL; std::vector<u8> decrypted_data(context.title_import_export.content.buffer.size()); const ReturnCode decrypt_ret = m_ios.GetIOSC().Decrypt( context.title_import_export.key_handle, context.title_import_export.content.iv.data(), context.title_import_export.content.buffer.data(), context.title_import_export.content.buffer.size(), decrypted_data.data(), PID_ES); if (decrypt_ret != IPC_SUCCESS) return decrypt_ret; IOS::ES::Content content_info; context.title_import_export.tmd.FindContentById(context.title_import_export.content.id, &content_info); if (!CheckIfContentHashMatches(decrypted_data, content_info)) { ERROR_LOG(IOS_ES, "ImportContentEnd: Hash for content %08x doesn't match", content_info.id); return ES_HASH_MISMATCH; } const auto fs = m_ios.GetFS(); std::string content_path; if (content_info.IsShared()) { IOS::ES::SharedContentMap shared_content{fs}; content_path = shared_content.AddSharedContent(content_info.sha1); } else { content_path = GetImportContentPath(context.title_import_export.tmd.GetTitleId(), context.title_import_export.content.id); } const std::string temp_path = "/tmp/" + content_path.substr(content_path.find_last_of('/') + 1, std::string::npos); { const auto file = fs->CreateAndOpenFile(PID_KERNEL, PID_KERNEL, temp_path, FS::Mode::ReadWrite, FS::Mode::ReadWrite, FS::Mode::None); if (!file || !file->Write(decrypted_data.data(), content_info.size)) { ERROR_LOG(IOS_ES, "ImportContentEnd: Failed to write to %s", temp_path.c_str()); return ES_EIO; } } const FS::ResultCode rename_result = fs->Rename(PID_KERNEL, PID_KERNEL, temp_path, content_path); if (rename_result != FS::ResultCode::Success) { fs->Delete(PID_KERNEL, PID_KERNEL, temp_path); ERROR_LOG(IOS_ES, "ImportContentEnd: Failed to move content to %s", content_path.c_str()); return FS::ConvertResult(rename_result); } context.title_import_export.content = {}; return IPC_SUCCESS; }
void DMARead (u32 addr, u32 size) override {INFO_LOG(EXPANSIONINTERFACE, "EXI DUMMY %s DMARead: %08x bytes, from device to %08x", m_strName.c_str(), size, addr);}
bool Load_PSP_ISO(const char *filename, std::string *error_string) { ISOFileSystem *umd2 = new ISOFileSystem(&pspFileSystem, constructBlockDevice(filename)); // Parse PARAM.SFO //pspFileSystem.Mount("host0:",umd2); pspFileSystem.Mount("umd0:", umd2); pspFileSystem.Mount("umd1:", umd2); pspFileSystem.Mount("disc0:", umd2); pspFileSystem.Mount("umd:", umd2); std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO"); PSPFileInfo fileInfo = pspFileSystem.GetFileInfo(sfoPath.c_str()); if (fileInfo.exists) { u8 *paramsfo = new u8[(size_t)fileInfo.size]; u32 fd = pspFileSystem.OpenFile(sfoPath, FILEACCESS_READ); pspFileSystem.ReadFile(fd, paramsfo, fileInfo.size); pspFileSystem.CloseFile(fd); if (g_paramSFO.ReadSFO(paramsfo, (size_t)fileInfo.size)) { char title[1024]; sprintf(title, "%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str()); INFO_LOG(LOADER, "%s", title); host->SetWindowTitle(title); } delete [] paramsfo; } std::string bootpath("disc0:/PSP_GAME/SYSDIR/EBOOT.BIN"); // bypass patchers if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.OLD").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.OLD"; } // bypass another patchers if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.DAT").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.DAT"; } // bypass more patchers if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.BI").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.BI"; } if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.LLD").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.LLD"; } if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/OLD_EBOOT.BIN").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/OLD_EBOOT.BIN"; } if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.123").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.123"; } if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT_LRC_CH.BIN").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT_LRC_CH.BIN"; } if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/BOOT0.OLD").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/BOOT0.OLD"; } if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/BOOT1.OLD").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/BOOT1.OLD"; } if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/BINOT.BIN").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/BINOT.BIN"; } if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.FRY").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.FRY"; } if (pspFileSystem.GetFileInfo("disc0:/PSP_GAME/SYSDIR/EBOOT.Z.Y").exists) { bootpath = "disc0:/PSP_GAME/SYSDIR/EBOOT.Z.Y"; } bool hasEncrypted = false; u32 fd; if ((fd = pspFileSystem.OpenFile(bootpath, FILEACCESS_READ)) != 0) { u8 head[4]; pspFileSystem.ReadFile(fd, head, 4); if (memcmp(head, "~PSP", 4) == 0 || memcmp(head, "\x7F""ELF", 4) == 0) { hasEncrypted = true; } pspFileSystem.CloseFile(fd); } if (!hasEncrypted) { // try unencrypted BOOT.BIN bootpath = "disc0:/PSP_GAME/SYSDIR/BOOT.BIN"; } INFO_LOG(LOADER,"Loading %s...", bootpath.c_str()); return __KernelLoadExec(bootpath.c_str(), 0, error_string); }
IPCCommandResult CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) { u32 ReturnValue = FS_RESULT_OK; SIOCtlVBuffer CommandBuffer(_CommandAddress); // Prepare the out buffer(s) with zeros as a safety precaution // to avoid returning bad values for (u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; i++) { Memory::Memset(CommandBuffer.PayloadBuffer[i].m_Address, 0, CommandBuffer.PayloadBuffer[i].m_Size); } switch (CommandBuffer.Parameter) { case IOCTLV_READ_DIR: { // the Wii uses this function to define the type (dir or file) std::string DirName(HLE_IPC_BuildFilename(Memory::GetString( CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size))); INFO_LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s", DirName.c_str()); if (!File::Exists(DirName)) { WARN_LOG(WII_IPC_FILEIO, "FS: Search not found: %s", DirName.c_str()); ReturnValue = FS_FILE_NOT_EXIST; break; } else if (!File::IsDirectory(DirName)) { // It's not a directory, so error. // Games don't usually seem to care WHICH error they get, as long as it's < // Well the system menu CARES! WARN_LOG(WII_IPC_FILEIO, "\tNot a directory - return FS_RESULT_FATAL"); ReturnValue = FS_RESULT_FATAL; break; } // make a file search CFileSearch::XStringVector Directories; Directories.push_back(DirName); CFileSearch::XStringVector Extensions; Extensions.push_back("*.*"); CFileSearch FileSearch(Extensions, Directories); // it is one if ((CommandBuffer.InBuffer.size() == 1) && (CommandBuffer.PayloadBuffer.size() == 1)) { size_t numFile = FileSearch.GetFileNames().size(); INFO_LOG(WII_IPC_FILEIO, "\t%lu files found", (unsigned long)numFile); Memory::Write_U32((u32)numFile, CommandBuffer.PayloadBuffer[0].m_Address); } else { u32 MaxEntries = Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address); memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, CommandBuffer.PayloadBuffer[0].m_Size); size_t numFiles = 0; char* pFilename = (char*)Memory::GetPointer((u32)(CommandBuffer.PayloadBuffer[0].m_Address)); for (size_t i=0; i<FileSearch.GetFileNames().size(); i++) { if (i >= MaxEntries) break; std::string name, ext; SplitPath(FileSearch.GetFileNames()[i], nullptr, &name, &ext); std::string FileName = name + ext; // Decode entities of invalid file system characters so that // games (such as HP:HBP) will be able to find what they expect. for (const Common::replace_t& r : replacements) { for (size_t j = 0; (j = FileName.find(r.second, j)) != FileName.npos; ++j) FileName.replace(j, r.second.length(), 1, r.first); } strcpy(pFilename, FileName.c_str()); pFilename += FileName.length(); *pFilename++ = 0x00; // termination numFiles++; INFO_LOG(WII_IPC_FILEIO, "\tFound: %s", FileName.c_str()); } Memory::Write_U32((u32)numFiles, CommandBuffer.PayloadBuffer[1].m_Address); } ReturnValue = FS_RESULT_OK; } break; case IOCTLV_GETUSAGE: { _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer.size() == 2); _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[0].m_Size == 4); _dbg_assert_(WII_IPC_FILEIO, CommandBuffer.PayloadBuffer[1].m_Size == 4); // this command sucks because it asks of the number of used // fsBlocks and inodes // It should be correct, but don't count on it... std::string relativepath = Memory::GetString(CommandBuffer.InBuffer[0].m_Address, CommandBuffer.InBuffer[0].m_Size); std::string path(HLE_IPC_BuildFilename(relativepath)); u32 fsBlocks = 0; u32 iNodes = 0; INFO_LOG(WII_IPC_FILEIO, "IOCTL_GETUSAGE %s", path.c_str()); if (File::IsDirectory(path)) { // LPFaint99: After I found that setting the number of inodes to the number of children + 1 for the directory itself // I decided to compare with sneek which has the following 2 special cases which are // Copyright (C) 2009-2011 crediar http://code.google.com/p/sneek/ if ((relativepath.compare(0, 16, "/title/00010001") == 0 ) || (relativepath.compare(0, 16, "/title/00010005") == 0 )) { fsBlocks = 23; // size is size/0x4000 iNodes = 42; // empty folders return a FileCount of 1 } else { File::FSTEntry parentDir; // add one for the folder itself, allows some games to create their save files // R8XE52 (Jurassic: The Hunted), STEETR (Tetris Party Deluxe) now create their saves with this change iNodes = 1 + File::ScanDirectoryTree(path, parentDir); u64 totalSize = ComputeTotalFileSize(parentDir); // "Real" size, to be converted to nand blocks fsBlocks = (u32)(totalSize / (16 * 1024)); // one bock is 16kb } ReturnValue = FS_RESULT_OK; INFO_LOG(WII_IPC_FILEIO, "FS: fsBlock: %i, iNodes: %i", fsBlocks, iNodes); } else { fsBlocks = 0; iNodes = 0; ReturnValue = FS_RESULT_OK; WARN_LOG(WII_IPC_FILEIO, "FS: fsBlock failed, cannot find directory: %s", path.c_str()); } Memory::Write_U32(fsBlocks, CommandBuffer.PayloadBuffer[0].m_Address); Memory::Write_U32(iNodes, CommandBuffer.PayloadBuffer[1].m_Address); } break; default: PanicAlert("CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter); break; } Memory::Write_U32(ReturnValue, _CommandAddress+4); return IPC_FS_REPLY; }
// copies file srcFilename to destFilename, returns true on success bool Copy(const std::string &srcFilename, const std::string &destFilename) { INFO_LOG(COMMON, "Copy: %s --> %s", srcFilename.c_str(), destFilename.c_str()); #ifdef _WIN32 if (CopyFile(Common::UTF8ToTStr(srcFilename).c_str(), Common::UTF8ToTStr(destFilename).c_str(), FALSE)) return true; ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); return false; #else // buffer size #define BSIZE 1024 char buffer[BSIZE]; // Open input file FILE *input = fopen(srcFilename.c_str(), "rb"); if (!input) { ERROR_LOG(COMMON, "Copy: input failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); return false; } // open output file FILE *output = fopen(destFilename.c_str(), "wb"); if (!output) { fclose(input); ERROR_LOG(COMMON, "Copy: output failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); return false; } // copy loop while (!feof(input)) { // read input int rnum = fread(buffer, sizeof(char), BSIZE, input); if (rnum != BSIZE) { if (ferror(input) != 0) { ERROR_LOG(COMMON, "Copy: failed reading from source, %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); goto bail; } } // write output int wnum = fwrite(buffer, sizeof(char), rnum, output); if (wnum != rnum) { ERROR_LOG(COMMON, "Copy: failed writing to output, %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); goto bail; } } // close files fclose(input); fclose(output); return true; bail: if (input) fclose(input); if (output) fclose(output); return false; #endif }
static u32 sceUtilityUnloadAvModule(u32 module) { INFO_LOG(SCEUTILITY,"0=sceUtilityUnloadAvModule(%i)", module); return hleDelayResult(0, "utility av module unloaded", 800); }
// Scans the directory tree gets, starting from _Directory and adds the // results into parentEntry. Returns the number of files+directories found u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) { INFO_LOG(COMMON, "ScanDirectoryTree: directory %s", directory.c_str()); // How many files + directories we found u32 foundEntries = 0; #ifdef _WIN32 // Find the first file in the directory. WIN32_FIND_DATA ffd; HANDLE hFind = FindFirstFile(Common::UTF8ToTStr(directory + "\\*").c_str(), &ffd); if (hFind == INVALID_HANDLE_VALUE) { FindClose(hFind); return foundEntries; } // windows loop do { FSTEntry entry; const std::string virtualName(Common::TStrToUTF8(ffd.cFileName)); #else struct dirent dirent, *result = NULL; DIR *dirp = opendir(directory.c_str()); if (!dirp) return 0; // non windows loop while (!readdir_r(dirp, &dirent, &result) && result) { FSTEntry entry; const std::string virtualName(result->d_name); #endif // check for "." and ".." if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || ((virtualName[0] == '.') && (virtualName[1] == '.') && (virtualName[2] == '\0'))) continue; entry.virtualName = virtualName; entry.physicalName = directory; entry.physicalName += DIR_SEP + entry.virtualName; if (IsDirectory(entry.physicalName.c_str())) { entry.isDirectory = true; // is a directory, lets go inside entry.size = ScanDirectoryTree(entry.physicalName, entry); foundEntries += (u32)entry.size; } else { // is a file entry.isDirectory = false; entry.size = GetSize(entry.physicalName.c_str()); } ++foundEntries; // Push into the tree parentEntry.children.push_back(entry); #ifdef _WIN32 } while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); #else } closedir(dirp); #endif // Return number of entries found. return foundEntries; }
int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) { MpegContext *ctx = getMpegCtx(mpeg); if (!ctx) { WARN_LOG(HLE, "sceMpegGetAvcAu(%08x, %08x, %08x, %08x): bad mpeg handle", mpeg, streamId, auAddr, attrAddr); return -1; } SceMpegRingBuffer mpegRingbuffer; Memory::ReadStruct(ctx->mpegRingbufferAddr, &mpegRingbuffer); SceMpegAu sceAu; sceAu.read(auAddr); if (mpegRingbuffer.packetsRead == 0 || mpegRingbuffer.packetsFree == mpegRingbuffer.packets) { DEBUG_LOG(HLE, "PSP_ERROR_MPEG_NO_DATA=sceMpegGetAvcAu(%08x, %08x, %08x, %08x)", mpeg, streamId, auAddr, attrAddr); sceAu.pts = -1; sceAu.dts = -1; sceAu.write(auAddr); // TODO: Does this really reschedule? return hleDelayResult(PSP_ERROR_MPEG_NO_DATA, "mpeg get avc", mpegDecodeErrorDelayMs); } auto streamInfo = ctx->streamMap.find(streamId); if (streamInfo == ctx->streamMap.end()) { ERROR_LOG(HLE, "sceMpegGetAvcAu - bad stream id %i", streamId); return -1; } if (streamInfo->second.needsReset) { sceAu.pts = 0; streamInfo->second.needsReset = false; } /*// Wait for audio if too much ahead if (ctx->atracRegistered && (ctx->mediaengine->getVideoTimeStamp() > ctx->mediaengine->getAudioTimeStamp() + getMaxAheadTimestamp(mpegRingbuffer))) { ERROR_LOG(HLE, "sceMpegGetAvcAu - video too much ahead"); // TODO: Does this really reschedule? return hleDelayResult(PSP_ERROR_MPEG_NO_DATA, "mpeg get avc", mpegDecodeErrorDelayMs); }*/ int result = 0; sceAu.pts = ctx->mediaengine->getVideoTimeStamp() + ctx->mpegFirstTimestamp; sceAu.dts = sceAu.pts - videoTimestampStep; if (ctx->mediaengine->IsVideoEnd()) { INFO_LOG(HLE, "video end reach. pts: %i dts: %i", (int)sceAu.pts, (int)ctx->mediaengine->getLastTimeStamp()); mpegRingbuffer.packetsFree = mpegRingbuffer.packets; Memory::WriteStruct(ctx->mpegRingbufferAddr, &mpegRingbuffer); result = PSP_ERROR_MPEG_NO_DATA; } // The avcau struct may have been modified by mediaengine, write it back. sceAu.write(auAddr); if (Memory::IsValidAddress(attrAddr)) { Memory::Write_U32(1, attrAddr); } DEBUG_LOG(HLE, "%x=sceMpegGetAvcAu(%08x, %08x, %08x, %08x)", result, mpeg, streamId, auAddr, attrAddr); // TODO: sceMpegGetAvcAu seems to modify esSize, and delay when it's > 1000 or something. // There's definitely more to it, but ultimately it seems games should expect it to delay randomly. return hleDelayResult(result, "mpeg get avc", 100); }
void Config::Save() { if (jitForcedOff) { // if JIT has been forced off, we don't want to screw up the user's ppsspp.ini g_Config.bJit = true; } if (iniFilename_.size() && g_Config.bSaveSettings) { saveGameConfig(gameId_); CleanRecent(); IniFile iniFile; if (!iniFile.Load(iniFilename_.c_str())) { ERROR_LOG(LOADER, "Error saving config - can't read ini %s", iniFilename_.c_str()); } // Need to do this somewhere... bFirstRun = false; IterateSettings(iniFile, [&](IniFile::Section *section, ConfigSetting *setting) { if (!bGameSpecific || !setting->perGame_) { setting->Set(section); } }); IniFile::Section *recent = iniFile.GetOrCreateSection("Recent"); recent->Set("MaxRecent", iMaxRecent); for (int i = 0; i < iMaxRecent; i++) { char keyName[64]; snprintf(keyName, sizeof(keyName), "FileName%d", i); if (i < (int)recentIsos.size()) { recent->Set(keyName, recentIsos[i]); } else { recent->Delete(keyName); // delete the nonexisting FileName } } IniFile::Section *pinnedPaths = iniFile.GetOrCreateSection("PinnedPaths"); pinnedPaths->Clear(); for (size_t i = 0; i < vPinnedPaths.size(); ++i) { char keyName[64]; snprintf(keyName, sizeof(keyName), "Path%d", (int)i); pinnedPaths->Set(keyName, vPinnedPaths[i]); } IniFile::Section *control = iniFile.GetOrCreateSection("Control"); control->Delete("DPadRadius"); if (!iniFile.Save(iniFilename_.c_str())) { ERROR_LOG(LOADER, "Error saving config - can't write ini %s", iniFilename_.c_str()); return; } INFO_LOG(LOADER, "Config saved: %s", iniFilename_.c_str()); if (!bGameSpecific) //otherwise we already did this in saveGameConfig() { IniFile controllerIniFile; if (!controllerIniFile.Load(controllerIniFilename_.c_str())) { ERROR_LOG(LOADER, "Error saving config - can't read ini %s", controllerIniFilename_.c_str()); } KeyMap::SaveToIni(controllerIniFile); if (!controllerIniFile.Save(controllerIniFilename_.c_str())) { ERROR_LOG(LOADER, "Error saving config - can't write ini %s", controllerIniFilename_.c_str()); return; } INFO_LOG(LOADER, "Controller config saved: %s", controllerIniFilename_.c_str()); } } else { INFO_LOG(LOADER, "Not saving config"); } if (jitForcedOff) { // force JIT off again just in case Config::Save() is called without exiting PPSSPP g_Config.bJit = false; } }