static void on_Button_pressed( GtkButton * button,gpointer user_data ) { urlItem * item; if ( (int)user_data ) { gchar * str= strdup( gtk_entry_get_text( GTK_ENTRY( URLEntry ) ) ); if ( str ) { if ( strncmp( str,"http://",7 ) && strncmp( str,"ftp://",6 ) && strncmp( str,"mms://",6 ) && strncmp( str,"pnm://",6 ) && strncmp( str,"rtsp://",7 ) ) { gchar * tmp; tmp=malloc( strlen( str ) + 8 ); sprintf( tmp,"http://%s",str ); free( str ); str=tmp; } URLComboEntrys=g_list_prepend( URLComboEntrys,(gchar *)str ); item=calloc( 1,sizeof( urlItem ) ); item->url=gstrdup( str ); listSet( gtkAddURLItem,item ); uiSetFileName( NULL,str,STREAMTYPE_STREAM ); guiInfo.NewPlay=GUI_FILE_NEW; uiEventHandling( evPlay,0 ); } } HideURLDialogBox(); }
/** * @brief Issue a command to the GUI. * * @note The GUI is controlled by giving it commands. * * @param what command to be performed * @param data pointer to data needed for the command * * @return #True (ok) or #False (error) */ int gui(int what, void *data) { static float last_balance = -1.0f; #ifdef CONFIG_DVDREAD dvd_priv_t *dvd; #endif int idata = (intptr_t)data, msg, state; stream_t *stream = NULL; sh_audio_t *sh_audio; mixer_t *mixer; float l, r, b; plItem *next = NULL; switch (what) { case GUI_SET_CONTEXT: guiInfo.mpcontext = data; break; case GUI_SET_STATE: switch (idata) { case GUI_STOP: case GUI_PLAY: // if ( !gtkShowVideoWindow ) wsWindowVisibility( &guiApp.videoWindow,wsHideWindow ); case GUI_PAUSE: guiInfo.Playing = idata; break; } uiState(); break; case GUI_REDRAW: uiEvent(ivRedraw, 0); if (!guiInfo.Playing || !guiInfo.VideoWindow) wsEvents(); /* else it's handled by the vo driver calling GUI_HANDLE_X_EVENT */ wsMouseAutohide(); gtkEvents(); break; case GUI_RUN_COMMAND: mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] GUI_RUN_COMMAND: %d\n", idata); switch (idata) { case MP_CMD_VO_FULLSCREEN: uiEvent(evFullScreen, True); break; case MP_CMD_PLAY_TREE_STEP: uiEvent(evNext, 0); break; case -MP_CMD_PLAY_TREE_STEP: uiEvent(evPrev, 0); break; case MP_CMD_STOP: uiEvent(evStop, 0); break; case MP_CMD_QUIT: uiEvent(evExit, 0); break; } break; case GUI_RUN_MESSAGE: mp_msg(MSGT_GPLAYER, MSGL_DBG2, "[interface] GUI_RUN_MESSAGE: %s\n", (const char *)data); msg = appFindMessage((const char *)data); if ((msg == evMenu) || appFindItem(msg)) uiEvent(msg, 0); break; case GUI_PREPARE: uiEvent(ivRedraw, True); wsMouseVisibility(&guiApp.videoWindow, wsHideMouseCursor); usec_sleep(20000); wsEvents(); if (guiInfo.MediumChanged == GUI_MEDIUM_NEW) { audio_id = -1; video_id = -1; dvdsub_id = -1; vobsub_id = -1; stream_cache_size = -1; autosync = 0; force_fps = 0; } switch (guiInfo.StreamType) { case STREAMTYPE_FILE: case STREAMTYPE_STREAM: filename = guiInfo.Filename; break; case STREAMTYPE_CDDA: { char tmp[512]; sprintf(tmp, "cdda://%d", guiInfo.Track); uiSetFile(NULL, tmp, SAME_STREAMTYPE); } break; case STREAMTYPE_VCD: { char tmp[512]; sprintf(tmp, "vcd://%d", guiInfo.Track); uiSetFile(NULL, tmp, SAME_STREAMTYPE); } break; case STREAMTYPE_DVD: { char tmp[512]; sprintf(tmp, "dvd://%d", guiInfo.Track); uiSetFile(NULL, tmp, SAME_STREAMTYPE); } #ifdef CONFIG_DVDREAD dvd_chapter = guiInfo.Chapter; dvd_angle = guiInfo.Angle; #endif break; case STREAMTYPE_TV: case STREAMTYPE_DVB: { char tmp[512]; sprintf(tmp, "%s://", guiTV[gui_tv_digital].SchemeName); uiSetFile(NULL, tmp, SAME_STREAMTYPE); } } /* video opts */ if (!video_driver_list) { int i = 0; while (video_out_drivers[i++]) { if (video_out_drivers[i - 1]->control(VOCTRL_GUISUPPORT, NULL) == VO_TRUE) { listSet(&video_driver_list, video_out_drivers[i - 1]->info->short_name); break; } } } if (!video_driver_list && !video_driver_list[0]) { gmp_msg(MSGT_GPLAYER, MSGL_FATAL, MSGTR_GUI_MSG_VideoOutError); mplayer(MPLAYER_EXIT_GUI, EXIT_ERROR, 0); } { int i = 0; guiInfo.VideoWindow = False; while (video_out_drivers[i++]) { if ((video_driver_list && !gstrcmp(video_driver_list[0], video_out_drivers[i - 1]->info->short_name)) && (video_out_drivers[i - 1]->control(VOCTRL_GUISUPPORT, NULL) == VO_TRUE)) { guiInfo.VideoWindow = True; break; } } } if (video_driver_list && !gstrcmp(video_driver_list[0], "dxr3")) if (guiInfo.StreamType != STREAMTYPE_DVD && guiInfo.StreamType != STREAMTYPE_VCD) if (gtkVfLAVC) add_vf("lavc", NULL); if (gtkVfPP) add_vf("pp", NULL); switch (guiInfo.Rotation) { static const char *argvf[] = { "_oldargs_", NULL, NULL }; case -1: remove_vf("rotate"); remove_vf("flip"); remove_vf("mirror"); break; case 1: argvf[1] = "1"; add_vf("rotate", argvf); remove_vf("flip"); remove_vf("mirror"); break; case 2: argvf[1] = "2"; add_vf("rotate", argvf); remove_vf("flip"); remove_vf("mirror"); break; case 8: remove_vf("rotate"); add_vf("flip", NULL); add_vf("mirror", NULL); break; } /* audio opts */ // if ( ao_plugin_cfg.plugin_list ) { free( ao_plugin_cfg.plugin_list ); ao_plugin_cfg.plugin_list=NULL; } if (gtkAONorm) listRepl(&af_cfg.list, "volnorm", "volnorm"); if (gtkEnableAudioEqualizer) listRepl(&af_cfg.list, "equalizer", "equalizer"); if (gtkAOExtraStereo) { char *name; name = malloc(12 + 20 + 1); snprintf(name, 12 + 20, "extrastereo=%f", gtkAOExtraStereoMul); name[12 + 20] = 0; listRepl(&af_cfg.list, "extrastereo", name); free(name); } if (audio_driver_list && !gstrncmp(audio_driver_list[0], "oss", 3)) { mixer_device = gtkAOOSSMixer; mixer_channel = gtkAOOSSMixerChannel; if (gtkAOOSSDevice) { char *tmp; tmp = calloc(1, strlen(gtkAOOSSDevice) + 7); sprintf(tmp, "oss:%s", gtkAOOSSDevice); listSet(&audio_driver_list, tmp); free(tmp); } } if (audio_driver_list && !gstrncmp(audio_driver_list[0], "alsa", 4)) { mixer_device = gtkAOALSAMixer; mixer_channel = gtkAOALSAMixerChannel; if (gtkAOALSADevice) { char *tmp; tmp = calloc(1, strlen(gtkAOALSADevice) + 14); sprintf(tmp, "alsa:device=%s", gtkAOALSADevice); listSet(&audio_driver_list, tmp); free(tmp); } } if (audio_driver_list && !gstrncmp(audio_driver_list[0], "sdl", 3)) { if (gtkAOSDLDriver) { char *tmp; tmp = calloc(1, strlen(gtkAOSDLDriver) + 10); sprintf(tmp, "sdl:%s", gtkAOSDLDriver); listSet(&audio_driver_list, tmp); free(tmp); } } if (audio_driver_list && !gstrncmp(audio_driver_list[0], "esd", 3)) { if (gtkAOESDDevice) { char *tmp; tmp = calloc(1, strlen(gtkAOESDDevice) + 10); sprintf(tmp, "esd:%s", gtkAOESDDevice); listSet(&audio_driver_list, tmp); free(tmp); } } /* subtitle */ // subdata->filename=gstrdup( guiInfo.SubtitleFilename ); stream_dump_type = 0; if (gtkSubDumpMPSub) stream_dump_type = 4; if (gtkSubDumpSrt) stream_dump_type = 6; gtkSubDumpMPSub = gtkSubDumpSrt = False; /* misc */ if (gtkCacheOn) stream_cache_size = gtkCacheSize; if (gtkAutoSyncOn) autosync = gtkAutoSync; if (guiInfo.AudioFilename) audio_stream = gstrdup(guiInfo.AudioFilename); else if (guiInfo.MediumChanged == GUI_MEDIUM_NEW) nfree(audio_stream); // audio_stream = NULL; guiInfo.MediumChanged = False; ass_enabled = gtkASS.enabled; ass_use_margins = gtkASS.use_margins; ass_top_margin = gtkASS.top_margin; ass_bottom_margin = gtkASS.bottom_margin; break; case GUI_SET_STREAM: if (guiInfo.StreamType == STREAMTYPE_PLAYLIST) guiInfo.mpcontext->file_format = DEMUXER_TYPE_PLAYLIST; else { stream = data; guiInfo.StreamType = stream->type; } switch (guiInfo.StreamType) { case STREAMTYPE_FILE: case STREAMTYPE_STREAM: guiInfo.Tracks = (uintptr_t)listMgr(PLAYLIST_ITEM_GET_POS, 0); break; case STREAMTYPE_CDDA: guiInfo.Tracks = 0; stream_control(stream, STREAM_CTRL_GET_NUM_TITLES, &guiInfo.Tracks); if (stream_control(stream, STREAM_CTRL_GET_CURRENT_TITLE, &guiInfo.Track) == STREAM_OK) guiInfo.Track++; break; case STREAMTYPE_VCD: guiInfo.Tracks = 0; stream_control(stream, STREAM_CTRL_GET_NUM_TITLES, &guiInfo.Tracks); if (stream_control(stream, STREAM_CTRL_GET_CURRENT_TITLE, &guiInfo.Track) == STREAM_OK) guiInfo.Track++; break; case STREAMTYPE_DVD: guiInfo.Tracks = 0; stream_control(stream, STREAM_CTRL_GET_NUM_TITLES, &guiInfo.Tracks); guiInfo.Chapters = 0; stream_control(stream, STREAM_CTRL_GET_NUM_CHAPTERS, &guiInfo.Chapters); guiInfo.Angles = 0; stream_control(stream, STREAM_CTRL_GET_NUM_ANGLES, &guiInfo.Angles); if (stream_control(stream, STREAM_CTRL_GET_CURRENT_TITLE, &guiInfo.Track) == STREAM_OK) guiInfo.Track++; // guiInfo.Chapter will be set by mplayer guiInfo.Angle = 1; stream_control(stream, STREAM_CTRL_GET_ANGLE, &guiInfo.Angle); #ifdef CONFIG_DVDREAD dvd = stream->priv; guiInfo.AudioStreams = dvd->nr_of_channels; memcpy(guiInfo.AudioStream, dvd->audio_streams, sizeof(dvd->audio_streams)); guiInfo.Subtitles = dvd->nr_of_subtitles; memcpy(guiInfo.Subtitle, dvd->subtitles, sizeof(dvd->subtitles)); #endif break; case STREAMTYPE_TV: case STREAMTYPE_DVB: guiInfo.Tracks = guiInfo.Track = 1; break; } break; case GUI_SET_VIDEO: /* video */ guiInfo.sh_video = data; nfree(guiInfo.CodecName); if (guiInfo.sh_video) guiInfo.CodecName = strdup(guiInfo.sh_video->codec->name); state = (isSeekableStreamtype ? btnReleased : btnDisabled); btnSet(evForward10sec, state); btnSet(evBackward10sec, state); btnSet(evForward1min, state); btnSet(evBackward1min, state); btnSet(evForward10min, state); btnSet(evBackward10min, state); btnSet(evSetMoviePosition, state); if (video_driver_list && !gstrcmp(video_driver_list[0], "dxr3") && (((demuxer_t *)mpctx_get_demuxer(guiInfo.mpcontext))->file_format != DEMUXER_TYPE_MPEG_PS) && !gtkVfLAVC) { gtkMessageBox(MSGBOX_FATAL, MSGTR_GUI_MSG_DXR3NeedsLavc); return False; } break; case GUI_SET_AUDIO: sh_audio = data; if (sh_audio) { guiInfo.AudioChannels = sh_audio->channels; guiInfo.AudioPassthrough = (gstrcmp(sh_audio->ad_driver->info->short_name, "hwac3") == 0); if (!guiInfo.sh_video) { guiInfo.VideoWindow = False; guiInfo.VideoWidth = 0; guiInfo.VideoHeight = 0; } } else { guiInfo.AudioChannels = 0; guiInfo.AudioPassthrough = False; } if (guiInfo.AudioPassthrough) btnSet(evSetVolume, btnDisabled); if (guiInfo.AudioChannels < 2 || guiInfo.AudioPassthrough) btnSet(evSetBalance, btnDisabled); if (last_balance < 0.0f) { uiEvent(ivSetVolume, guiInfo.Volume); if (guiInfo.AudioChannels == 2 && !guiInfo.AudioPassthrough) uiEvent(ivSetBalance, guiInfo.Balance); last_balance = guiInfo.Balance; } if (gtkEnableAudioEqualizer) { equalizer_t eq; unsigned int i, j; for (i = 0; i < FF_ARRAY_ELEMS(gtkEquChannels); i++) { for (j = 0; j < FF_ARRAY_ELEMS(*gtkEquChannels); j++) { eq.channel = i; eq.band = j; eq.gain = gtkEquChannels[i][j]; mplayer(MPLAYER_SET_EQUALIZER, 0, &eq); } } } // These must be done here (in the last call from MPlayer before // playback starts) and not in GUI_SETUP_VIDEO_WINDOW, because... // ...without video there will be no call to GUI_SETUP_VIDEO_WINDOW if (!guiInfo.VideoWindow) { wsWindowVisibility(&guiApp.videoWindow, wsHideWindow); btnSet(evFullScreen, gtkLoadFullscreen ? btnPressed : btnReleased); } // ...option variable fullscreen determines whether MPlayer will handle // the window given by WinID as fullscreen window (and will do aspect // scaling then) or not - quite rubbish fullscreen = gtkLoadFullscreen; break; case GUI_SET_VOLUME_BALANCE: mixer = data; mixer_getvolume(mixer, &l, &r); guiInfo.Volume = FFMAX(l, r); mixer_getbalance(mixer, &b); guiInfo.Balance = (b + 1.0) * 50.0; // transform -1..1 to 0..100 if (guiInfo.Balance != last_balance) { uiEvent(ivSetVolume, guiInfo.Volume); last_balance = guiInfo.Balance; } break; case GUI_SETUP_VIDEO_WINDOW: guiInfo.VideoWidth = vo_dwidth; guiInfo.VideoHeight = vo_dheight; if (!guiApp.videoWindow.isFullScreen || !guiApp.videoWindow.Mapped) { if (!guiApp.videoWindow.isFullScreen) wsWindowResize(&guiApp.videoWindow, guiInfo.VideoWidth, guiInfo.VideoHeight); if (!guiApp.videoWindow.Mapped) wsWindowVisibility(&guiApp.videoWindow, wsShowWindow); } if (gtkLoadFullscreen ^ guiApp.videoWindow.isFullScreen) uiEvent(evFullScreen, True); if (guiWinID >= 0) wsWindowMove(&guiApp.mainWindow, True, 0, guiInfo.VideoHeight); wsWindowBackground(&guiApp.videoWindow, -1, -1, -1); break; case GUI_HANDLE_X_EVENT: wsEvent(data); break; case GUI_END_PLAY: guiInfo.sh_video = NULL; btnSet(evSetVolume, btnReleased); btnSet(evSetBalance, btnReleased); uiEvent(ivRedraw, True); if (guiInfo.Playing) { if (!guiInfo.PlaylistNext) { guiInfo.PlaylistNext = True; break; } if (guiInfo.StreamType == STREAMTYPE_CDDA && guiInfo.Track < guiInfo.Tracks) { uiNext(); break; } next = listMgr(PLAYLIST_ITEM_GET_NEXT, 0); } if (next) { uiSetFile(next->path, next->name, STREAMTYPE_FILE); guiInfo.MediumChanged = GUI_MEDIUM_NEW; guiInfo.Track = (uintptr_t)listMgr(PLAYLIST_ITEM_GET_POS, next); } else { if (guiInfo.MediumChanged == GUI_MEDIUM_NEW) break; filename = NULL; if (isPlaylistStreamtype) { plItem *curr = listMgr(PLAYLIST_ITEM_GET_CURR, 0); if (!curr) uiUnsetFile(); else if ((curr != listMgr(PLAYLIST_GET, 0)) && guiInfo.Playing) { curr = listMgr(PLAYLIST_ITEM_SET_CURR, listMgr(PLAYLIST_GET, 0)); uiSetFile(curr->path, curr->name, STREAMTYPE_FILE); guiInfo.Track = 1; } } else if (guiInfo.Playing) { int first = (guiInfo.StreamType == STREAMTYPE_VCD ? 2 : 1); if (guiInfo.Track != first) { uiUnsetMedia(True); guiInfo.Track = first; } if (guiInfo.StreamType == STREAMTYPE_DVD) { guiInfo.Chapter = 1; guiInfo.Angle = 1; } } guiInfo.ElapsedTime = 0; guiInfo.Position = 0.0f; if (gtkShowVideoWindow) { guiInfo.VideoWindow = True; if (!guiApp.videoWindow.isFullScreen) wsWindowResize(&guiApp.videoWindow, guiApp.video.width, guiApp.video.height); if (!guiApp.videoWindow.Mapped) wsWindowVisibility(&guiApp.videoWindow, wsShowWindow); if (gtkLoadFullscreen ^ guiApp.videoWindow.isFullScreen) uiEvent(evFullScreen, False); } else { wsWindowVisibility(&guiApp.videoWindow, wsHideWindow); guiInfo.VideoWindow = False; btnSet(evFullScreen, gtkLoadFullscreen ? btnPressed : btnReleased); } gui(GUI_SET_STATE, (void *)GUI_STOP); wsWindowRedraw(&guiApp.videoWindow); wsMouseVisibility(&guiApp.videoWindow, wsShowMouseCursor); wsEvents(); } break; } return True; }
never_inline s32 savedata_op( PPUThread& CPU, u32 operation, u32 version, vm::cptr<char> dirName, u32 errDialog, vm::ptr<CellSaveDataSetList> setList, vm::ptr<CellSaveDataSetBuf> setBuf, vm::ptr<CellSaveDataListCallback> funcList, vm::ptr<CellSaveDataFixedCallback> funcFixed, vm::ptr<CellSaveDataStatCallback> funcStat, vm::ptr<CellSaveDataFileCallback> funcFile, u32 container, u32 unknown, // 0, 2, 6 vm::ptr<void> userdata, u32 userId, vm::ptr<CellSaveDataDoneCallback> funcDone) { // TODO: check arguments // try to lock the mutex (not sure how it originally works; std::try_to_lock makes it non-blocking) std::unique_lock<std::mutex> lock(g_savedata_dialog->mutex, std::try_to_lock); if (!lock) { return CELL_SAVEDATA_ERROR_BUSY; } // path of the specified user (00000001 by default) const std::string base_dir = fmt::format("/dev_hdd0/home/%08d/savedata/", userId ? userId : 1u); vm::stackvar<CellSaveDataCBResult> result(CPU); result->userdata = userdata; // probably should be assigned only once (allows the callback to change it) SaveDataEntry save_entry; if (setList) { std::vector<SaveDataEntry> save_entries; vm::stackvar<CellSaveDataListGet> listGet(CPU); listGet->dirNum = 0; listGet->dirListNum = 0; listGet->dirList.set(setBuf->buf.addr()); memset(listGet->reserved, 0, sizeof(listGet->reserved)); const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" }); for (const auto entry : vfsDir(base_dir)) { if (entry->flags & DirEntry_TypeFile) { continue; } for (const auto& prefix : prefix_list) { if (entry->name.substr(0, prefix.size()) == prefix) { // Count the amount of matches and the amount of listed directories if (listGet->dirListNum++ < setBuf->dirListMax) { listGet->dirNum++; // PSF parameters vfsFile f(base_dir + entry->name + "/PARAM.SFO"); const PSFLoader psf(f); if (!psf) { break; } SaveDataEntry save_entry2; save_entry2.dirName = psf.GetString("SAVEDATA_DIRECTORY"); save_entry2.listParam = psf.GetString("SAVEDATA_LIST_PARAM"); save_entry2.title = psf.GetString("TITLE"); save_entry2.subtitle = psf.GetString("SUB_TITLE"); save_entry2.details = psf.GetString("DETAIL"); save_entry2.size = 0; for (const auto entry2 : vfsDir(base_dir + entry->name)) { save_entry2.size += entry2->size; } save_entry2.atime = entry->access_time; save_entry2.mtime = entry->modify_time; save_entry2.ctime = entry->create_time; //save_entry2.iconBuf = NULL; // TODO: Here should be the PNG buffer //save_entry2.iconBufSize = 0; // TODO: Size of the PNG file save_entry2.isNew = false; save_entries.push_back(save_entry2); } break; } } } // Sort the entries { const u32 order = setList->sortOrder; const u32 type = setList->sortType; if (order > CELL_SAVEDATA_SORTORDER_ASCENT || type > CELL_SAVEDATA_SORTTYPE_SUBTITLE) { // error } std::sort(save_entries.begin(), save_entries.end(), [=](const SaveDataEntry& entry1, const SaveDataEntry& entry2) { if (order == CELL_SAVEDATA_SORTORDER_DESCENT && type == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME) { return entry1.mtime >= entry2.mtime; } if (order == CELL_SAVEDATA_SORTORDER_DESCENT && type == CELL_SAVEDATA_SORTTYPE_SUBTITLE) { return entry1.subtitle >= entry2.subtitle; } if (order == CELL_SAVEDATA_SORTORDER_ASCENT && type == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME) { return entry1.mtime < entry2.mtime; } if (order == CELL_SAVEDATA_SORTORDER_ASCENT && type == CELL_SAVEDATA_SORTTYPE_SUBTITLE) { return entry1.subtitle < entry2.subtitle; } return true; }); } // Fill the listGet->dirList array auto dir_list = listGet->dirList.get_ptr(); for (const auto& entry : save_entries) { auto& dir = *dir_list++; strcpy_trunc(dir.dirName, entry.dirName); strcpy_trunc(dir.listParam, entry.listParam); memset(dir.reserved, 0, sizeof(dir.reserved)); } s32 selected = -1; if (funcList) { vm::stackvar<CellSaveDataListSet> listSet(CPU); // List Callback funcList(CPU, result, listGet, listSet); if (result->result < 0) { return CELL_SAVEDATA_ERROR_CBRESULT; } // Clean save data list save_entries.erase(std::remove_if(save_entries.begin(), save_entries.end(), [&listSet](const SaveDataEntry& entry) -> bool { for (u32 i = 0; i < listSet->fixedListNum; i++) { if (entry.dirName == listSet->fixedList[i].dirName) { return false; } } return true; }), save_entries.end()); // Focus save data s32 focused = -1; switch (const u32 pos_type = listSet->focusPosition) { case CELL_SAVEDATA_FOCUSPOS_DIRNAME: { for (s32 i = 0; i < save_entries.size(); i++) { if (save_entries[i].dirName == listSet->focusDirName.get_ptr()) { focused = i; break; } } break; } case CELL_SAVEDATA_FOCUSPOS_LISTHEAD: { focused = save_entries.empty() ? -1 : 0; break; } case CELL_SAVEDATA_FOCUSPOS_LISTTAIL: { focused = save_entries.size() - 1; break; } case CELL_SAVEDATA_FOCUSPOS_LATEST: { s64 max = INT64_MIN; for (s32 i = 0; i < save_entries.size(); i++) { if (save_entries[i].mtime > max) { focused = i; max = save_entries[i].mtime; } } break; } case CELL_SAVEDATA_FOCUSPOS_OLDEST: { s64 min = INT64_MAX; for (s32 i = 0; i < save_entries.size(); i++) { if (save_entries[i].mtime < min) { focused = i; min = save_entries[i].mtime; } } break; } case CELL_SAVEDATA_FOCUSPOS_NEWDATA: { break; } default: { cellSysutil.Error("savedata_op(): unknown listSet->focusPosition (0x%x)", pos_type); return CELL_SAVEDATA_ERROR_PARAM; } } // Display Save Data List selected = g_savedata_dialog->ShowSaveDataList(save_entries, focused, listSet); if (selected == -1) { if (listSet->newData) { save_entry.dirName = listSet->newData->dirName.get_ptr(); } else { return CELL_OK; // ??? } } } if (funcFixed) { vm::stackvar<CellSaveDataFixedSet> fixedSet(CPU); // Fixed Callback funcFixed(CPU, result, listGet, fixedSet); if (result->result < 0) { return CELL_SAVEDATA_ERROR_CBRESULT; } for (s32 i = 0; i < save_entries.size(); i++) { if (save_entries[i].dirName == fixedSet->dirName.get_ptr()) { selected = i; break; } } if (selected == -1) { save_entry.dirName = fixedSet->dirName.get_ptr(); } } if (selected >= 0) { if (selected < save_entries.size()) { save_entry.dirName = std::move(save_entries[selected].dirName); } else { throw EXCEPTION("Invalid savedata selected"); } } } if (dirName) { save_entry.dirName = dirName.get_ptr(); } std::string dir_path = base_dir + save_entry.dirName + "/"; std::string sfo_path = dir_path + "PARAM.SFO"; PSFLoader psf; // Load PARAM.SFO { vfsFile f(sfo_path); psf.Load(f); } // Get save stats { vm::stackvar<CellSaveDataStatGet> statGet(CPU); vm::stackvar<CellSaveDataStatSet> statSet(CPU); std::string dir_local_path; Emu.GetVFS().GetDevice(dir_path, dir_local_path); fs::stat_t dir_info; if (!fs::stat(dir_local_path, dir_info)) { // error } statGet->hddFreeSizeKB = 40 * 1024 * 1024; // 40 GB statGet->isNewData = save_entry.isNew = !psf; statGet->dir.atime = save_entry.atime = dir_info.atime; statGet->dir.mtime = save_entry.mtime = dir_info.mtime; statGet->dir.ctime = save_entry.ctime = dir_info.ctime; strcpy_trunc(statGet->dir.dirName, save_entry.dirName); statGet->getParam.attribute = psf.GetInteger("ATTRIBUTE"); // ??? strcpy_trunc(statGet->getParam.title, save_entry.title = psf.GetString("TITLE")); strcpy_trunc(statGet->getParam.subTitle, save_entry.subtitle = psf.GetString("SUB_TITLE")); strcpy_trunc(statGet->getParam.detail, save_entry.details = psf.GetString("DETAIL")); strcpy_trunc(statGet->getParam.listParam, save_entry.listParam = psf.GetString("SAVEDATA_LIST_PARAM")); statGet->bind = 0; statGet->sizeKB = save_entry.size / 1024; statGet->sysSizeKB = 0; // This is the size of system files, but PARAM.SFO is very small and PARAM.PDF is not used statGet->fileNum = 0; statGet->fileList.set(setBuf->buf.addr()); statGet->fileListNum = 0; memset(statGet->reserved, 0, sizeof(statGet->reserved)); auto file_list = statGet->fileList.get_ptr(); for (const auto entry : vfsDir(dir_path)) { // only files, system files ignored, fileNum is limited by setBuf->fileListMax if (entry->flags & DirEntry_TypeFile && entry->name != "PARAM.SFO" && statGet->fileListNum++ < setBuf->fileListMax) { statGet->fileNum++; auto& file = *file_list++; if (entry->name == "ICON0.PNG") { file.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_ICON0; } else if (entry->name == "ICON1.PAM") { file.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_ICON1; } else if (entry->name == "PIC1.PNG") { file.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_PIC1; } else if (entry->name == "SND0.AT3") { file.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_SND0; } else if (psf.GetInteger("*" + entry->name)) // let's put the list of protected files in PARAM.SFO (int param = 1 if protected) { file.fileType = CELL_SAVEDATA_FILETYPE_SECUREFILE; } else { file.fileType = CELL_SAVEDATA_FILETYPE_NORMALFILE; } file.size = entry->size; file.atime = entry->access_time; file.mtime = entry->modify_time; file.ctime = entry->create_time; strcpy_trunc(file.fileName, entry->name); } } // Stat Callback funcStat(CPU, result, statGet, statSet); if (result->result < 0) { return CELL_SAVEDATA_ERROR_CBRESULT; } // Update PARAM.SFO if (statSet->setParam) { psf.Clear(); psf.SetString("ACCOUNT_ID", ""); // ??? psf.SetInteger("ATTRIBUTE", statSet->setParam->attribute); psf.SetString("CATEGORY", "SD"); // ??? psf.SetString("PARAMS", ""); // ??? psf.SetString("PARAMS2", ""); // ??? psf.SetInteger("PARENTAL_LEVEL", 0); // ??? psf.SetString("DETAIL", statSet->setParam->detail); psf.SetString("SAVEDATA_DIRECTORY", save_entry.dirName); psf.SetString("SAVEDATA_LIST_PARAM", statSet->setParam->listParam); psf.SetString("SUB_TITLE", statSet->setParam->subTitle); psf.SetString("TITLE", statSet->setParam->title); } switch (const u32 mode = statSet->reCreateMode & 0xffff) { case CELL_SAVEDATA_RECREATE_NO: case CELL_SAVEDATA_RECREATE_NO_NOBROKEN: { break; } case CELL_SAVEDATA_RECREATE_YES: case CELL_SAVEDATA_RECREATE_YES_RESET_OWNER: { // kill it with fire for (const auto entry : vfsDir(dir_path)) { if (entry->flags & DirEntry_TypeFile) { Emu.GetVFS().RemoveFile(dir_path + entry->name); } } break; } default: { cellSysutil.Error("savedata_op(): unknown statSet->reCreateMode (0x%x)", statSet->reCreateMode); return CELL_SAVEDATA_ERROR_PARAM; } } } // Create save directory if necessary if (psf && save_entry.isNew && !Emu.GetVFS().CreateDir(dir_path)) { // Let's ignore this error for now } // Enter the loop where the save files are read/created/deleted vm::stackvar<CellSaveDataFileGet> fileGet(CPU); vm::stackvar<CellSaveDataFileSet> fileSet(CPU); fileGet->excSize = 0; memset(fileGet->reserved, 0, sizeof(fileGet->reserved)); while (funcFile) { funcFile(CPU, result, fileGet, fileSet); if (result->result < 0) { return CELL_SAVEDATA_ERROR_CBRESULT; } if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM) { break; } std::string file_path; switch (const u32 type = fileSet->fileType) { case CELL_SAVEDATA_FILETYPE_SECUREFILE: case CELL_SAVEDATA_FILETYPE_NORMALFILE: { file_path = fileSet->fileName.get_ptr(); break; } case CELL_SAVEDATA_FILETYPE_CONTENT_ICON0: { file_path = "ICON0.PNG"; break; } case CELL_SAVEDATA_FILETYPE_CONTENT_ICON1: { file_path = "ICON1.PAM"; break; } case CELL_SAVEDATA_FILETYPE_CONTENT_PIC1: { file_path = "PIC1.PNG"; break; } case CELL_SAVEDATA_FILETYPE_CONTENT_SND0: { file_path = "SND0.AT3"; break; } default: { cellSysutil.Error("savedata_op(): unknown fileSet->fileType (0x%x)", type); return CELL_SAVEDATA_ERROR_PARAM; } } psf.SetInteger("*" + file_path, fileSet->fileType == CELL_SAVEDATA_FILETYPE_SECUREFILE); std::string local_path; Emu.GetVFS().GetDevice(dir_path + file_path, local_path); switch (const u32 op = fileSet->fileOperation) { case CELL_SAVEDATA_FILEOP_READ: { fs::file file(local_path, o_read); file.seek(fileSet->fileOffset); fileGet->excSize = static_cast<u32>(file.read(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize))); break; } case CELL_SAVEDATA_FILEOP_WRITE: { fs::file file(local_path, o_write | o_create); file.seek(fileSet->fileOffset); fileGet->excSize = static_cast<u32>(file.write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize))); file.trunc(file.seek(0, from_cur)); // truncate break; } case CELL_SAVEDATA_FILEOP_DELETE: { fs::remove_file(local_path); fileGet->excSize = 0; break; } case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC: { fs::file file(local_path, o_write | o_create); file.seek(fileSet->fileOffset); fileGet->excSize = static_cast<u32>(file.write(fileSet->fileBuf.get_ptr(), std::min<u32>(fileSet->fileSize, fileSet->fileBufSize))); break; } default: { cellSysutil.Error("savedata_op(): unknown fileSet->fileOperation (0x%x)", op); return CELL_SAVEDATA_ERROR_PARAM; } } } // Write PARAM.SFO if (psf) { vfsFile f(sfo_path, vfsWriteNew); psf.Save(f); } return CELL_OK; }
void startSearch() { int currentNodeID = 0; //Current node while starting is 0 init_Dfs(); //Initialize the stack spine init_motors(); run(); int nextNodeID; addNeigbourNodesToFrontier(currentNodeID); addToSet(&markedNodes,currentNodeID); push(&spine, currentNodeID); nextNodeID = DecideNextNode(currentNodeID); int cnt = 0; while(1) { //scanAndSearch(); //openCV code if(objectFound == true) { // Functionality here TBD printf("Obj found: %d",cnt); cnt ++; rotate360(); objectFound = false; /* while(isObjectClose() == 0) moveForward(); // Provided by the motor library if(distanceTravelledFromPrevNode == distanceToNextNode) addToSet(&markedNodes,currentNodeID); //?? Who updates the current position of the object */ //Keep track of the distance so that obj position is known //Keep track of where we are in the graph } else { printf("Spine. \n"); printStack(&spine); printf("\n\n"); printf("Next node to be traversed: %d\n", nextNodeID); moveToNextNode(currentNodeID,nextNodeID); //Move to the next node currentNodeID = nextNodeID; addToSet(&markedNodes,currentNodeID); //Current Node has been traversed. Add to the set addNeigbourNodesToFrontier(currentNodeID); //Adding frontier nodes from the new current node removeNodeFromSet(&frontierNodes,currentNodeID); //Removing the current node from frontier printf("Done nodes : \n"); listSet(markedNodes); printf("Frontier Nodes : \n"); listSet(frontierNodes); if (checkIfNeighborExistsInFrontier(currentNodeID)) //Check if neighbor exists in frontier { // If so visit there push(&spine, currentNodeID); //Change nextNodeID = DecideNextNode(currentNodeID); } else { if(isStackEmpty(&spine)) return ; // Done traversing. Stop else { nextNodeID = pop(&spine); } } } } }