diff --git a/ElevenMPV-A-Common/include/ipc.h b/ElevenMPV-A-Common/include/ipc.h index abdc935..4fee57a 100644 --- a/ElevenMPV-A-Common/include/ipc.h +++ b/ElevenMPV-A-Common/include/ipc.h @@ -8,7 +8,9 @@ typedef enum IpcCmd { EMPVA_IPC_PLAY, EMPVA_IPC_FF, EMPVA_IPC_REW, - EMPVA_IPC_INFO + EMPVA_IPC_INFO, + EMPVA_IPC_APP_STOP, + EMPVA_IPC_APP_START } IpcCmd; typedef enum IpcFlag { diff --git a/ElevenMPV-A-ShellPlugin/main.cpp b/ElevenMPV-A-ShellPlugin/main.cpp index 5b75535..1fa4578 100644 --- a/ElevenMPV-A-ShellPlugin/main.cpp +++ b/ElevenMPV-A-ShellPlugin/main.cpp @@ -72,6 +72,24 @@ int setup_stage1() } +void startMainThread() +{ + if (mainThread == SCE_NULL) { + mainThread = new ImposeThread(SCE_KERNEL_LOWEST_PRIORITY_USER, SCE_KERNEL_4KiB, "ElevenMPVA::ShellControl"); + mainThread->Start(); + } +} + +void stopMainThread() +{ + if (mainThread != SCE_NULL) { + mainThread->Cancel(); + mainThread->Join(); + delete mainThread; + mainThread = SCE_NULL; + } +} + void setup_stage2() { topText = new wstring(); @@ -80,13 +98,13 @@ void setup_stage2() ipcPipeRX = sceKernelCreateMsgPipe("ElevenMPVA::ShellIPC_RX", SCE_KERNEL_MSG_PIPE_TYPE_USER_MAIN, IPC_PIPE_ATTR, sizeof(IpcDataRX), SCE_NULL); ipcPipeTX = sceKernelCreateMsgPipe("ElevenMPVA::ShellIPC_TX", SCE_KERNEL_MSG_PIPE_TYPE_USER_MAIN, IPC_PIPE_ATTR, sizeof(IpcDataTX), SCE_NULL); - mainThread = new ImposeThread(SCE_KERNEL_LOWEST_PRIORITY_USER, SCE_KERNEL_4KiB, "ElevenMPVA::ShellControl"); - mainThread->Start(); + startMainThread(); rxThread = new RxThread(SCE_KERNEL_LOWEST_PRIORITY_USER, SCE_KERNEL_4KiB, "ElevenMPVA::ShellRx"); rxThread->Start(); } +/* void cleanup() { IpcDataRX ipcDataRX; @@ -113,6 +131,7 @@ void cleanup() if (hookId[0] > 0) taiHookRelease(hookId[0], hookRef[0]); } +*/ int findWidgets() { @@ -254,6 +273,12 @@ SceVoid RxThread::EntryFunction() case EMPVA_IPC_DEACTIVATE: imposeIpcActive = SCE_FALSE; break; + case EMPVA_IPC_APP_STOP: + stopMainThread(); + break; + case EMPVA_IPC_APP_START: + startMainThread(); + break; case EMPVA_IPC_INFO: if ((ipcDataRX.flags & EMPVA_IPC_REFRESH_PBBT) == EMPVA_IPC_REFRESH_PBBT) { @@ -325,6 +350,10 @@ SceVoid ImposeThread::EntryFunction() extern "C" { + #include + + SCE_MODULE_INFO(ElevenMPV_A_ShellPlugin, 2, 1, 1) + typedef struct SceShellAudioBGMState { int bgmPortOwnerId; int bgmPortPriority; @@ -360,7 +389,7 @@ extern "C" { int module_stop(SceSize args, const void * argp) { - cleanup(); + //cleanup(); return SCE_KERNEL_STOP_SUCCESS; } diff --git a/ElevenMPV-A-libScePafPreload/prx.c b/ElevenMPV-A-libScePafPreload/prx.c index 88e87e3..49d5aaf 100644 --- a/ElevenMPV-A-libScePafPreload/prx.c +++ b/ElevenMPV-A-libScePafPreload/prx.c @@ -47,10 +47,10 @@ int __module_start(SceSize argc, void *args) if (ret < 0) { ret = sceAppMgrGrowMemory3(16 * 1024 * 1024, 1); // 32 MB if (ret == 0) - init_param.global_heap_size = 14 * 1024 * 1024; + init_param.global_heap_size = 12 * 1024 * 1024; } else - init_param.global_heap_size = 25 * 1024 * 1024; + init_param.global_heap_size = 26 * 1024 * 1024; #else init_param.global_heap_size = 12 * 1024 * 1024; #endif diff --git a/ElevenMPV-A/CONTENTS/empva_plugin.rco b/ElevenMPV-A/CONTENTS/empva_plugin.rco index 35f8bbe..e646914 100644 Binary files a/ElevenMPV-A/CONTENTS/empva_plugin.rco and b/ElevenMPV-A/CONTENTS/empva_plugin.rco differ diff --git a/ElevenMPV-A/CONTENTS/module/libInvidious.suprx b/ElevenMPV-A/CONTENTS/module/libInvidious.suprx index 87bc2f7..e4aab81 100644 Binary files a/ElevenMPV-A/CONTENTS/module/libInvidious.suprx and b/ElevenMPV-A/CONTENTS/module/libInvidious.suprx differ diff --git a/ElevenMPV-A/CONTENTS/module/libNetMedia.suprx b/ElevenMPV-A/CONTENTS/module/libNetMedia.suprx index 87662a1..4a87e64 100644 Binary files a/ElevenMPV-A/CONTENTS/module/libNetMedia.suprx and b/ElevenMPV-A/CONTENTS/module/libNetMedia.suprx differ diff --git a/ElevenMPV-A/CONTENTS/module/libScePafPreload.suprx b/ElevenMPV-A/CONTENTS/module/libScePafPreload.suprx index 556ce60..a496543 100644 Binary files a/ElevenMPV-A/CONTENTS/module/libScePafPreload.suprx and b/ElevenMPV-A/CONTENTS/module/libScePafPreload.suprx differ diff --git a/ElevenMPV-A/CONTENTS/module/libcurl.suprx b/ElevenMPV-A/CONTENTS/module/libcurl.suprx new file mode 100644 index 0000000..4f24bd4 Binary files /dev/null and b/ElevenMPV-A/CONTENTS/module/libcurl.suprx differ diff --git a/ElevenMPV-A/CONTENTS/module/shell_plugin.suprx b/ElevenMPV-A/CONTENTS/module/shell_plugin.suprx index 0c17b42..be0c2fd 100644 Binary files a/ElevenMPV-A/CONTENTS/module/shell_plugin.suprx and b/ElevenMPV-A/CONTENTS/module/shell_plugin.suprx differ diff --git a/ElevenMPV-A/ElevenMPV-A.vcxproj b/ElevenMPV-A/ElevenMPV-A.vcxproj index 042cbe2..ef72a62 100644 --- a/ElevenMPV-A/ElevenMPV-A.vcxproj +++ b/ElevenMPV-A/ElevenMPV-A.vcxproj @@ -45,13 +45,13 @@ _DEBUG;%(PreprocessorDefinitions); true NotUsing - $(ProjectDir)include;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\user;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\common;$(ProjectDir)libs\include;$(ProjectDir)include\audio;$(ProjectDir)include\menus;$(SolutionDir)ElevenMPV-A-Common\include;%(AdditionalIncludeDirectories) + $(ProjectDir)include;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\user;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\common;$(ProjectDir)libs\include;$(ProjectDir)include\audio;$(ProjectDir)include\menus;$(SolutionDir)ElevenMPV-A-Common\include;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\user\psp2_compat;%(AdditionalIncludeDirectories) Cpp11 Thumb2 Level3 - -lopusfile;-lopus;-lvorbisfile;-lvorbis;-logg;-lxmp-lite;-lnestegg;-lShellAudio;-lSceSysmem_stub;-lSceKernelForMono_stub;-lSceThreadMgr_stub;-lSceThreadmgrCoredumpTime_stub;-lSceModuleMgr_stub;-lSceProcessMgr_stub;-lSceLibRng_stub;-lSceAppMgr_stub;-lSceAppMgrUser_stub;-lSceAppUtil_stub;-lSceAudio_stub;-lSceCtrl_stub;-lSceDisplay_stub;-lScePower_stub;-lSceShellSvc_stub;-lSceShellUtil_stub;-lSceSysmodule_stub;-lSceMotion_stub;-lSceDbg_stub;-lSceAudiocodec_stub;-ltaihenUnsafe_stub;-lScePafThread_stub;-lScePafStdc_stub;-lScePafToplevel_stub;-lScePafResource_stub;-lScePafWidget_stub;-lScePafMisc_stub;-lScePafCommon_stub;-lScePafGraphics_stub;-lSceLibKernel_stub;-lSceNet_stub;-lSceNetCtl_stub;-lSceHttp_stub;-lSceSsl_stub;-lSceAppSettings_stub;-lScebXCe_stub;-lSceIniFileProcessor_stub;-lSceCommonGuiDialog_stub;-lSceIpmi_stub;-lNetMedia_stub;-lLocalMedia_stub;-lInvidious_stub;-lsnc;%(AdditionalDependencies) + -lopusfile;-lopus;-lvorbisfile;-lvorbis;-logg;-lxmp-lite;-lnestegg;-lShellAudio;-lSceSysmem_stub;-lSceKernelForMono_stub;-lSceThreadMgr_stub;-lSceThreadmgrCoredumpTime_stub;-lSceModuleMgr_stub;-lSceProcessMgr_stub;-lSceLibRng_stub;-lSceAppMgr_stub;-lSceAppMgrUser_stub;-lSceAppUtil_stub;-lSceAudio_stub;-lSceCtrl_stub;-lSceDisplay_stub;-lScePower_stub;-lSceShellSvc_stub;-lSceShellUtil_stub;-lSceSysmodule_stub;-lSceMotion_stub;-lSceDbg_stub;-lSceAudiocodec_stub;-ltaihenUnsafe_stub;-lScePafThread_stub;-lScePafStdc_stub;-lScePafToplevel_stub;-lScePafResource_stub;-lScePafWidget_stub;-lScePafMisc_stub;-lScePafCommon_stub;-lScePafGraphics_stub;-lSceLibKernel_stub;-lSceNet_stub;-lSceNetCtl_stub;-lcurl_stub;-lSceAppSettings_stub;-lScebXCe_stub;-lSceIniFileProcessor_stub;-lSceCommonGuiDialog_stub;-lSceIpmi_stub;-lNetMedia_stub;-lLocalMedia_stub;-lInvidious_stub;-lsnc;%(AdditionalDependencies) $(SCE_PSP2_SDK_DIR)\target\lib\vdsuite;$(ProjectDir)libs\lib;%(AdditionalLibraryDirectories) FullMapFile --no-standard-libraries @@ -72,13 +72,13 @@ copy /Y "$(OutDir)param.sfo" "$(ProjectDir)CONTENTS/sce_sys/param.sfo" NDEBUG;SCE_DBG_LOGGING_ENABLED=0;%(PreprocessorDefinitions) Level3 NotUsing - $(ProjectDir)include;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\user;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\common;$(ProjectDir)libs\include;$(ProjectDir)include\audio;$(ProjectDir)include\menus;$(SolutionDir)ElevenMPV-A-Common\include;%(AdditionalIncludeDirectories) + $(ProjectDir)include;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\user;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\common;$(ProjectDir)libs\include;$(ProjectDir)include\audio;$(ProjectDir)include\menus;$(SolutionDir)ElevenMPV-A-Common\include;$(SCE_PSP2_SDK_DIR)\target\include\vdsuite\user\psp2_compat;%(AdditionalIncludeDirectories) Cpp11 Thumb2 StripSymsAndDebug - -lopusfile;-lopus;-lvorbisfile;-lvorbis;-logg;-lxmp-lite;-lnestegg;-lShellAudio;-lSceSysmem_stub;-lSceThreadMgr_stub;-lSceThreadmgrCoredumpTime_stub;-lSceModuleMgr_stub;-lSceProcessMgr_stub;-lSceLibRng_stub;-lSceAppMgr_stub;-lSceAppMgrUser_stub;-lSceAppUtil_stub;-lSceAudio_stub;-lSceCtrl_stub;-lSceDisplay_stub;-lScePower_stub;-lSceShellSvc_stub;-lSceShellUtil_stub;-lSceSysmodule_stub;-lSceMotion_stub;-lSceAudiocodec_stub;-ltaihenUnsafe_stub;-lScePafThread_stub;-lScePafStdc_stub;-lScePafToplevel_stub;-lScePafResource_stub;-lScePafWidget_stub;-lScePafMisc_stub;-lScePafCommon_stub;-lScePafGraphics_stub;-lSceLibKernel_stub;-lSceNet_stub;-lSceNetCtl_stub;-lSceHttp_stub;-lSceSsl_stub;-lSceAppSettings_stub;-lScebXCe_stub;-lSceIniFileProcessor_stub;-lSceCommonGuiDialog_stub;-lSceIpmi_stub;-lNetMedia_stub;-lLocalMedia_stub;-lInvidious_stub;-lsnc;%(AdditionalDependencies) + -lSceHttp_stub;-lSceSsl_stub;-lopusfile;-lopus;-lvorbisfile;-lvorbis;-logg;-lxmp-lite;-lnestegg;-lShellAudio;-lSceSysmem_stub;-lSceThreadMgr_stub;-lSceThreadmgrCoredumpTime_stub;-lSceModuleMgr_stub;-lSceProcessMgr_stub;-lSceLibRng_stub;-lSceAppMgr_stub;-lSceAppMgrUser_stub;-lSceAppUtil_stub;-lSceAudio_stub;-lSceCtrl_stub;-lSceDisplay_stub;-lScePower_stub;-lSceShellSvc_stub;-lSceShellUtil_stub;-lSceSysmodule_stub;-lSceMotion_stub;-lSceAudiocodec_stub;-ltaihen_stub;-ltaihenUnsafe_stub;-lScePafThread_stub;-lScePafStdc_stub;-lScePafToplevel_stub;-lScePafResource_stub;-lScePafWidget_stub;-lScePafMisc_stub;-lScePafCommon_stub;-lScePafGraphics_stub;-lSceLibKernel_stub;-lSceNet_stub;-lSceNetCtl_stub;-lcurl_stub;-lSceAppSettings_stub;-lScebXCe_stub;-lSceIniFileProcessor_stub;-lSceCommonGuiDialog_stub;-lSceIpmi_stub;-lNetMedia_stub;-lLocalMedia_stub;-lInvidious_stub;-lsnc;%(AdditionalDependencies) $(SCE_PSP2_SDK_DIR)\target\lib\vdsuite;$(ProjectDir)libs\lib;%(AdditionalLibraryDirectories) --no-standard-libraries %(AdditionalOptions) StripFuncsAndData @@ -108,6 +108,7 @@ copy /Y "$(OutDir)param.sfo" "$(ProjectDir)CONTENTS/sce_sys/param.sfo" + @@ -134,6 +135,7 @@ copy /Y "$(OutDir)param.sfo" "$(ProjectDir)CONTENTS/sce_sys/param.sfo" + diff --git a/ElevenMPV-A/ElevenMPV-A.vcxproj.filters b/ElevenMPV-A/ElevenMPV-A.vcxproj.filters index 98173ed..52f49e5 100644 --- a/ElevenMPV-A/ElevenMPV-A.vcxproj.filters +++ b/ElevenMPV-A/ElevenMPV-A.vcxproj.filters @@ -113,6 +113,9 @@ Source Files + + Source Files + @@ -163,5 +166,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/ElevenMPV-A/RES_RCO/empva_plugin.xml b/ElevenMPV-A/RES_RCO/empva_plugin.xml index b076985..997bbec 100644 --- a/ElevenMPV-A/RES_RCO/empva_plugin.xml +++ b/ElevenMPV-A/RES_RCO/empva_plugin.xml @@ -17,7 +17,7 @@ - + @@ -388,26 +388,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/ElevenMPV-A/RES_RCO/locale/empva_locale_ch.xml b/ElevenMPV-A/RES_RCO/locale/empva_locale_ch.xml index 141919b..28d6e1a 100644 --- a/ElevenMPV-A/RES_RCO/locale/empva_locale_ch.xml +++ b/ElevenMPV-A/RES_RCO/locale/empva_locale_ch.xml @@ -1,7 +1,6 @@ - diff --git a/ElevenMPV-A/RES_RCO/locale/empva_locale_de.xml b/ElevenMPV-A/RES_RCO/locale/empva_locale_de.xml index 6122189..296c992 100644 --- a/ElevenMPV-A/RES_RCO/locale/empva_locale_de.xml +++ b/ElevenMPV-A/RES_RCO/locale/empva_locale_de.xml @@ -1,7 +1,6 @@ - diff --git a/ElevenMPV-A/RES_RCO/locale/empva_locale_en.xml b/ElevenMPV-A/RES_RCO/locale/empva_locale_en.xml index 10be214..424b22c 100644 --- a/ElevenMPV-A/RES_RCO/locale/empva_locale_en.xml +++ b/ElevenMPV-A/RES_RCO/locale/empva_locale_en.xml @@ -1,7 +1,6 @@ - diff --git a/ElevenMPV-A/RES_RCO/locale/empva_locale_fr.xml b/ElevenMPV-A/RES_RCO/locale/empva_locale_fr.xml index 5440f8a..1613302 100644 --- a/ElevenMPV-A/RES_RCO/locale/empva_locale_fr.xml +++ b/ElevenMPV-A/RES_RCO/locale/empva_locale_fr.xml @@ -1,7 +1,6 @@ - diff --git a/ElevenMPV-A/RES_RCO/locale/empva_locale_ja.xml b/ElevenMPV-A/RES_RCO/locale/empva_locale_ja.xml index e0bb50c..5c98598 100644 --- a/ElevenMPV-A/RES_RCO/locale/empva_locale_ja.xml +++ b/ElevenMPV-A/RES_RCO/locale/empva_locale_ja.xml @@ -1,7 +1,6 @@ - diff --git a/ElevenMPV-A/RES_RCO/locale/empva_locale_pt-br.xml b/ElevenMPV-A/RES_RCO/locale/empva_locale_pt-br.xml index 48b9c14..d2e5e8a 100644 --- a/ElevenMPV-A/RES_RCO/locale/empva_locale_pt-br.xml +++ b/ElevenMPV-A/RES_RCO/locale/empva_locale_pt-br.xml @@ -1,7 +1,6 @@ - diff --git a/ElevenMPV-A/RES_RCO/locale/empva_locale_ru.xml b/ElevenMPV-A/RES_RCO/locale/empva_locale_ru.xml index 5538da2..ed9f126 100644 --- a/ElevenMPV-A/RES_RCO/locale/empva_locale_ru.xml +++ b/ElevenMPV-A/RES_RCO/locale/empva_locale_ru.xml @@ -1,7 +1,6 @@ - diff --git a/ElevenMPV-A/RES_RCO/locale/empva_locale_zh.xml b/ElevenMPV-A/RES_RCO/locale/empva_locale_zh.xml index 96799b9..4a17d99 100644 --- a/ElevenMPV-A/RES_RCO/locale/empva_locale_zh.xml +++ b/ElevenMPV-A/RES_RCO/locale/empva_locale_zh.xml @@ -1,7 +1,6 @@ - diff --git a/ElevenMPV-A/include/curl_file.h b/ElevenMPV-A/include/curl_file.h new file mode 100644 index 0000000..7e89363 --- /dev/null +++ b/ElevenMPV-A/include/curl_file.h @@ -0,0 +1,113 @@ +#ifndef _ELEVENMPV_CURL_FILE_H_ +#define _ELEVENMPV_CURL_FILE_H_ + +#include +#include +#include + +#define CURL_FILE_UA "Mozilla/5.0 (PlayStation Vita 3.74) AppleWebKit/537.73 (KHTML, like Gecko) Silk/3.2" + +using namespace paf; + +class CurlFile : public paf::File +{ +public: + + class CurlFileStat : public HttpFileStat + { + }; + + class OpenArg : public paf::File::OpenArg + { + public: + + enum Opt + { + Opt_ResolveTimeOut = 1, + Opt_ConnectTimeOut = 2, + Opt_SendTimeOut = 4, + Opt_RecvTimeOut = 8 + }; + + OpenArg(); + + ~OpenArg(); + + SceVoid SetUrl(const char *url); + + SceVoid SetUrl(paf::Url *url); + + SceInt32 SetOpt(SceInt32 optValue, Opt optType); + + SceVoid SetUseShare(bool use); + + SceUInt32 fileType; + string userAgent; + SceInt32 sslFlags; + + string url; + SceInt32 resolveTimeout; + SceInt32 connectTimeout; + SceInt32 sendTimeout; + SceInt32 recvTimeout; + bool useShare; + }; + + CurlFile(); + + virtual SceInt32 GetFileType() const; + virtual SceInt32 GetCapability() const; + virtual SceOff GetFileSize() const; + virtual SceInt32 Open(const CurlFile::OpenArg *param); + virtual SceInt32 OpenAsync(const CurlFile::OpenArg *param); + virtual SceInt32 Close(); + virtual SceInt32 CloseAsync(); + virtual bool IsOpened() const; + virtual bool IsEof(); + virtual SceInt32 Abort(); + virtual SceInt32 Read(void *buf, SceSize nbyte); + virtual SceInt32 ReadAsync(void *buf, SceSize nbyte); + virtual SceInt32 Write(const void *buf, SceSize nbyte); // not supported + virtual SceInt32 WriteAsync(const void *buf, SceSize nbyte); // not supported + virtual SceOff Seek(SceOff offset, SceInt32 whence); + virtual SceInt32 SeekAsync(SceOff offset, SceInt32 whence); + virtual SceInt32 Flush(); + virtual SceInt32 FlushAsync(); + virtual SceInt32 WaitAsync(SceInt64 *pResult); + virtual SceInt32 PollAsync(SceInt64 *pResult); + virtual SceInt32 GetStat(FileStat *stat); + virtual SceInt32 SetPriority(SceInt32 ioPriority); + + virtual ~CurlFile(); + + SceInt32 GetResponseCode(SceInt32 *code); + + static SharedPtr Open(const char *path, SceUInt32 flag, SceUInt32 mode, SceInt32 *error, bool useShare = false); + + static SharedPtr Open(const SceWChar16 *url, SceInt32 *error, SceUInt32 flag, bool useShare = false); + + static SharedPtr Open(const char *url, SceInt32 *error, SceUInt32 flag, bool useShare = false); + + static SceInt32 GetStat(const char *url, CurlFileStat *stat, bool useShare = false); + + static SceVoid InitShare(); + + static SceVoid TermShare(); + +private: + + static SceSize DownloadCore(char *buffer, SceSize size, SceSize nitems, ScePVoid userdata); + static SceVoid ShareLock(CURL *handle, curl_lock_data data, curl_lock_access access, ScePVoid userptr); + static SceVoid ShareUnlock(CURL *handle, curl_lock_data data, ScePVoid userptr); + + thread::RMutex *lock; + CURL *curl; + curl_off_t contentLength; + ScePVoid buf; + SceUInt32 posInBuf; + SceUInt32 maxBuf; + SceOff pos; + bool isOpened; +}; + +#endif diff --git a/ElevenMPV-A/include/yt_utils.h b/ElevenMPV-A/include/yt_utils.h index 1d25413..8d35438 100644 --- a/ElevenMPV-A/include/yt_utils.h +++ b/ElevenMPV-A/include/yt_utils.h @@ -9,6 +9,11 @@ #include "netmedia.h" #include "downloader.h" +extern "C" +{ + int curl_global_memmanager_set_np(void*(*)(unsigned int), void(*)(void *), void*(*)(void *, unsigned int)); +} + using namespace paf; class YTUtils @@ -92,7 +97,17 @@ class YTUtils static SceVoid NMDeallocate(ScePVoid argP, ScePVoid argMemory); - static SceBool DowbloadFile(char *url, ScePVoid *ppBuf, SceSize *pBufSize); + class InvDownloadData + { + public: + + ScePVoid buf; + SceUInt32 pos; + }; + + static SceBool InvDownload(char *url, ScePVoid *ppBuf, SceSize *pBufSize); + + static SceSize InvDownloadCore(char *buffer, SceSize size, SceSize nitems, ScePVoid userdata); }; #endif diff --git a/ElevenMPV-A/libs/include/__youtube_parser.hpp b/ElevenMPV-A/libs/include/__youtube_parser.hpp deleted file mode 100644 index 0bc519b..0000000 --- a/ElevenMPV-A/libs/include/__youtube_parser.hpp +++ /dev/null @@ -1,175 +0,0 @@ -#pragma once -#include -#include -#include - -#define TT_PORTABLE - -#ifdef TT_PRX -#define PRX_EXPORT __declspec(dllexport) -#else -#define PRX_EXPORT -#endif - -PRX_EXPORT void youtube_change_content_language(std::string language_code); - -// util function -PRX_EXPORT int youtube_set_audio_bitrate_limit(int limit); -PRX_EXPORT std::string youtube_get_video_thumbnail_url_by_id(const std::string &id); -PRX_EXPORT std::string youtube_get_video_thumbnail_hq_url_by_id(const std::string &id); -PRX_EXPORT std::string youtube_get_video_url_by_id(const std::string &id); -PRX_EXPORT std::string get_video_id_from_thumbnail_url(const std::string &url); -PRX_EXPORT bool youtube_is_valid_video_id(const std::string &id); -PRX_EXPORT bool is_youtube_url(const std::string &url); -PRX_EXPORT bool is_youtube_thumbnail_url(const std::string &url); - -enum class YouTubePageType { - VIDEO, - CHANNEL, - SEARCH, - INVALID -}; -PRX_EXPORT YouTubePageType youtube_get_page_type(std::string url); - -#ifdef TT_PORTABLE -struct YouTubeChannelSuccinct { - std::string name; - std::string url; - std::string icon_url; - std::string subscribers; - std::string video_num; -}; -struct YouTubeVideoSuccinct { - std::string url; - std::string title; - std::string duration_text; - std::string publish_date; - std::string views_str; - std::string author; - std::string thumbnail_url; -}; -struct YouTubePlaylistSuccinct { - std::string url; - std::string title; - std::string video_count_str; - std::string thumbnail_url; -}; - -struct YouTubeSuccinctItem { - // TODO : use union or std::variant - enum { - VIDEO, - CHANNEL, - PLAYLIST - } type; - YouTubeVideoSuccinct video; - YouTubeChannelSuccinct channel; - YouTubePlaylistSuccinct playlist; - - YouTubeSuccinctItem() = default; - YouTubeSuccinctItem(YouTubeVideoSuccinct video) : type(VIDEO), video(video) {} - YouTubeSuccinctItem(YouTubeChannelSuccinct channel) : type(CHANNEL), channel(channel) {} - YouTubeSuccinctItem(YouTubePlaylistSuccinct playlist) : type(PLAYLIST), playlist(playlist) {} - - std::string get_url() const { return type == VIDEO ? video.url : type == CHANNEL ? channel.url : playlist.url; } - std::string get_thumbnail_url() const { return type == VIDEO ? video.thumbnail_url : type == CHANNEL ? channel.icon_url : playlist.thumbnail_url; } - std::string get_name() const { return type == VIDEO ? video.title : type == CHANNEL ? channel.name : playlist.title; } -}; - - -struct YouTubeSearchResult { - std::string error; - int estimated_result_num; - std::vector results; - - std::string continue_token; - std::string continue_key; - - bool has_continue() const { return continue_token != "" && continue_key != ""; } -}; -PRX_EXPORT YouTubeSearchResult *youtube_parse_search(std::string url); -PRX_EXPORT YouTubeSearchResult *youtube_parse_search(char *url); -// takes the previous result, returns the new result with both old items and new items -PRX_EXPORT YouTubeSearchResult *youtube_continue_search(const YouTubeSearchResult &prev_result); -PRX_EXPORT YouTubeSearchResult *youtube_parse_search_word(char *search_word); - - -struct YouTubeVideoDetail { - std::string error; - std::string url; - std::string title; - YouTubeChannelSuccinct author; - std::string audio_stream_url; - int duration_ms; - bool is_livestream; - enum class LivestreamType { - PREMIERE, - LIVESTREAM, - }; - LivestreamType livestream_type; - bool is_upcoming; - std::string playability_status; - std::string playability_reason; - int stream_fragment_len; // used only for livestreams - - struct Playlist { - std::string id; - std::string title; - std::string author_name; - int total_videos; - std::vector videos; - int selected_index; - }; - Playlist playlist; - - std::string continue_key; // innertube key - - bool needs_timestamp_adjusting() const { return is_livestream && livestream_type == LivestreamType::PREMIERE; } - bool is_playable() const { return playability_status == "OK" && ((audio_stream_url != "")); } -}; -// this function does not load comments; call youtube_video_page_load_more_comments() if necessary -PRX_EXPORT YouTubeVideoDetail *youtube_parse_video_page(std::string url); -PRX_EXPORT YouTubeVideoDetail *youtube_parse_video_page(char *url); - -struct YouTubeChannelDetail { - std::string id; - std::string error; - std::string name; - std::string url; - std::string url_original; - std::string icon_url; - std::string banner_url; - std::string description; - std::string subscriber_count_str; - std::vector videos; - - std::string continue_token; - std::string continue_key; - - bool has_continue() const { return continue_token != "" && continue_key != ""; } -}; -PRX_EXPORT YouTubeChannelDetail *youtube_parse_channel_page(std::string url); -PRX_EXPORT YouTubeChannelDetail *youtube_parse_channel_page(char *url); -// takes the previous result, returns the new result with both old items and new items -PRX_EXPORT YouTubeChannelDetail *youtube_channel_page_continue(const YouTubeChannelDetail &prev_result); - -PRX_EXPORT void youtube_destroy_struct(YouTubeChannelDetail *s); -PRX_EXPORT void youtube_destroy_struct(YouTubeVideoDetail *s); -PRX_EXPORT void youtube_destroy_struct(YouTubeSearchResult *s); - -PRX_EXPORT void youtube_change_content_language(const char *language_code); - -// util function -PRX_EXPORT void youtube_get_video_thumbnail_url_by_id(const char *id, char *url, int urlLen); -PRX_EXPORT void youtube_get_video_thumbnail_hq_url_by_id(const char *id, char *url, int urlLen); -PRX_EXPORT void youtube_get_video_url_by_id(const char *id, char *url, int urlLen); -PRX_EXPORT void get_video_id_from_thumbnail_url(const char *url, char *id, int idLen); -PRX_EXPORT bool youtube_is_valid_video_id(const char *id); -PRX_EXPORT bool is_youtube_url(const char *url); -PRX_EXPORT bool is_youtube_thumbnail_url(const char *url); -PRX_EXPORT YouTubePageType youtube_get_page_type(const char *url); - -#else -#endif - - diff --git a/ElevenMPV-A/libs/include/__youtube_parser_old.hpp b/ElevenMPV-A/libs/include/__youtube_parser_old.hpp deleted file mode 100644 index 04f8693..0000000 --- a/ElevenMPV-A/libs/include/__youtube_parser_old.hpp +++ /dev/null @@ -1,401 +0,0 @@ -#pragma once - -#include -#include -#include - -#define TT_PORTABLE - -#ifdef TT_PRX -#define PRX_EXPORT __declspec(dllexport) -#else -#define PRX_EXPORT -#endif - -PRX_EXPORT void youtube_change_content_language(std::string language_code); - -// util function -PRX_EXPORT std::string youtube_get_video_thumbnail_url_by_id(const std::string &id); -PRX_EXPORT std::string youtube_get_video_url_by_id(const std::string &id); -PRX_EXPORT std::string get_video_id_from_thumbnail_url(const std::string &url); -PRX_EXPORT bool youtube_is_valid_video_id(const std::string &id); -PRX_EXPORT bool is_youtube_url(const std::string &url); -PRX_EXPORT bool is_youtube_thumbnail_url(const std::string &url); - -enum class YouTubePageType { - VIDEO, - CHANNEL, - SEARCH, - INVALID -}; -PRX_EXPORT YouTubePageType youtube_get_page_type(std::string url); - -#ifdef TT_PORTABLE -struct YouTubeChannelSuccinct { - std::string name; - std::string url; - std::string icon_url; - std::string subscribers; - std::string video_num; -}; -struct YouTubeVideoSuccinct { - std::string url; - std::string title; - std::string duration_text; - std::string publish_date; - std::string views_str; - std::string author; - std::string thumbnail_url; -}; -struct YouTubePlaylistSuccinct { - std::string url; - std::string title; - std::string video_count_str; - std::string thumbnail_url; -}; - -struct YouTubeSuccinctItem { - // TODO : use union or std::variant - enum { - VIDEO, - CHANNEL, - PLAYLIST - } type; - YouTubeVideoSuccinct video; - YouTubeChannelSuccinct channel; - YouTubePlaylistSuccinct playlist; - - YouTubeSuccinctItem() = default; - YouTubeSuccinctItem(YouTubeVideoSuccinct video) : type(VIDEO), video(video) {} - YouTubeSuccinctItem(YouTubeChannelSuccinct channel) : type(CHANNEL), channel(channel) {} - YouTubeSuccinctItem(YouTubePlaylistSuccinct playlist) : type(PLAYLIST), playlist(playlist) {} - - std::string get_url() const { return type == VIDEO ? video.url : type == CHANNEL ? channel.url : playlist.url; } - std::string get_thumbnail_url() const { return type == VIDEO ? video.thumbnail_url : type == CHANNEL ? channel.icon_url : playlist.thumbnail_url; } - std::string get_name() const { return type == VIDEO ? video.title : type == CHANNEL ? channel.name : playlist.title; } -}; - - -struct YouTubeSearchResult { - std::string error; - int estimated_result_num; - std::vector results; - - std::string continue_token; - std::string continue_key; - - bool has_continue() const { return continue_token != "" && continue_key != ""; } -}; -PRX_EXPORT YouTubeSearchResult *youtube_parse_search(std::string url); -PRX_EXPORT YouTubeSearchResult *youtube_parse_search(char *url); -// takes the previous result, returns the new result with both old items and new items -PRX_EXPORT YouTubeSearchResult *youtube_continue_search(const YouTubeSearchResult &prev_result); -PRX_EXPORT YouTubeSearchResult *youtube_parse_search_word(char *search_word); - - -struct YouTubeVideoDetail { - std::string error; - std::string url; - std::string title; - std::string description; - YouTubeChannelSuccinct author; - std::string audio_stream_url; - std::map video_stream_urls; // first : video size (144p, 240p, 360p ...) - std::string both_stream_url; - int duration_ms; - bool is_livestream; - enum class LivestreamType { - PREMIERE, - LIVESTREAM, - }; - LivestreamType livestream_type; - bool is_upcoming; - std::string playability_status; - std::string playability_reason; - int stream_fragment_len; // used only for livestreams - std::string like_count_str; - std::string dislike_count_str; - std::string publish_date; - std::string views_str; - - // caption-related data - std::string caption_base_url; - struct CaptionBaseLanguage { - std::string name; // e.g. "English", "Japanese" - std::string id; // e.g. "en", "ja" - std::string base_url; // empty string for instances in caption_translated_languages - bool is_translatable; - }; - struct CaptionTranslationLanguage { - std::string name; - std::string id; - }; - std::vector caption_base_languages; - std::vector caption_translation_languages; - struct CaptionPiece { - float start_time; - float end_time; - std::string content; - }; - using Caption = std::vector; - std::map, Caption> caption_data; - - std::vector suggestions; - struct Playlist { - std::string id; - std::string title; - std::string author_name; - int total_videos; - std::vector videos; - int selected_index; - }; - Playlist playlist; - - struct Comment { - YouTubeChannelSuccinct author; - std::string content; - std::string id; - - int reply_num; - std::vector replies; - std::string continue_key; // innertube key, equals to YouTubeChannelDetail.continue_key - std::string replies_continue_token; - bool has_more_replies() const { return replies_continue_token != ""; } - }; - std::vector comments; - - std::string continue_key; // innertube key - std::string suggestions_continue_token; - std::string comment_continue_token; - int comment_continue_type; // -1 : unavailable, 0 : using watch_comments, 1 : using innertube - bool comments_disabled; - - bool has_more_suggestions() const { return continue_key != "" && suggestions_continue_token != ""; } - bool has_more_comments() const { return comment_continue_type != -1; } - bool needs_timestamp_adjusting() const { return is_livestream && livestream_type == LivestreamType::PREMIERE; } - bool is_playable() const { return playability_status == "OK" && (both_stream_url != "" || (audio_stream_url != "" && video_stream_urls.size())); } -}; -// this function does not load comments; call youtube_video_page_load_more_comments() if necessary -PRX_EXPORT YouTubeVideoDetail *youtube_parse_video_page(std::string url); -PRX_EXPORT YouTubeVideoDetail *youtube_parse_video_page(char *url); -PRX_EXPORT YouTubeVideoDetail *youtube_video_page_load_more_suggestions(const YouTubeVideoDetail &prev_result); -PRX_EXPORT YouTubeVideoDetail *youtube_video_page_load_more_comments(const YouTubeVideoDetail &prev_result); -PRX_EXPORT YouTubeVideoDetail::Comment *youtube_video_page_load_more_replies(const YouTubeVideoDetail::Comment &comment); -PRX_EXPORT YouTubeVideoDetail *youtube_video_page_load_caption(const YouTubeVideoDetail &prev_result, const std::string &base_lang_id, const std::string &translation_lang_id); - - - -struct YouTubeChannelDetail { - std::string id; - std::string error; - std::string name; - std::string url; - std::string url_original; - std::string icon_url; - std::string banner_url; - std::string description; - std::string subscriber_count_str; - std::vector videos; - - std::string continue_token; - std::string continue_key; - - bool has_continue() const { return continue_token != "" && continue_key != ""; } -}; -PRX_EXPORT YouTubeChannelDetail *youtube_parse_channel_page(std::string url); -PRX_EXPORT YouTubeChannelDetail *youtube_parse_channel_page(char *url); -// takes the previous result, returns the new result with both old items and new items -PRX_EXPORT YouTubeChannelDetail *youtube_channel_page_continue(const YouTubeChannelDetail &prev_result); - -PRX_EXPORT void youtube_destroy_struct(YouTubeChannelDetail *s); -PRX_EXPORT void youtube_destroy_struct(YouTubeVideoDetail *s); -PRX_EXPORT void youtube_destroy_struct(YouTubeSearchResult *s); - -PRX_EXPORT void youtube_change_content_language(const char *language_code); - -// util function -PRX_EXPORT void youtube_get_video_thumbnail_url_by_id(const char *id, char *url, int urlLen); -PRX_EXPORT void youtube_get_video_thumbnail_hq_url_by_id(const char *id, char *url, int urlLen); -PRX_EXPORT void youtube_get_video_url_by_id(const char *id, char *url, int urlLen); -PRX_EXPORT void get_video_id_from_thumbnail_url(const char *url, char *id, int idLen); -PRX_EXPORT bool youtube_is_valid_video_id(const char *id); -PRX_EXPORT bool is_youtube_url(const char *url); -PRX_EXPORT bool is_youtube_thumbnail_url(const char *url); -PRX_EXPORT YouTubePageType youtube_get_page_type(const char *url); - -#else - -struct YouTubeChannelSuccinct { - std::string name; - std::string url; - std::string icon_url; - std::string subscribers; - std::string video_num; -}; -struct YouTubeVideoSuccinct { - std::string url; - std::string title; - std::string duration_text; - std::string publish_date; - std::string views_str; - std::string author; - std::string thumbnail_url; -}; -struct YouTubePlaylistSuccinct { - std::string url; - std::string title; - std::string video_count_str; - std::string thumbnail_url; -}; - -struct YouTubeSuccinctItem { - // TODO : use union or std::variant - enum { - VIDEO, - CHANNEL, - PLAYLIST - } type; - YouTubeVideoSuccinct video; - YouTubeChannelSuccinct channel; - YouTubePlaylistSuccinct playlist; - - YouTubeSuccinctItem () = default; - YouTubeSuccinctItem (YouTubeVideoSuccinct video) : type(VIDEO), video(video) {} - YouTubeSuccinctItem (YouTubeChannelSuccinct channel) : type(CHANNEL), channel(channel) {} - YouTubeSuccinctItem (YouTubePlaylistSuccinct playlist) : type(PLAYLIST), playlist(playlist) {} - - std::string get_url() const { return type == VIDEO ? video.url : type == CHANNEL ? channel.url : playlist.url; } - std::string get_thumbnail_url() const { return type == VIDEO ? video.thumbnail_url : type == CHANNEL ? channel.icon_url : playlist.thumbnail_url; } - std::string get_name() const { return type == VIDEO ? video.title : type == CHANNEL ? channel.name : playlist.title; } -}; - - -struct YouTubeSearchResult { - std::string error; - int estimated_result_num; - std::vector results; - - std::string continue_token; - std::string continue_key; - - bool has_continue() const { return continue_token != "" && continue_key != ""; } -}; -PRX_EXPORT YouTubeSearchResult youtube_parse_search(std::string url); -// takes the previous result, returns the new result with both old items and new items -PRX_EXPORT YouTubeSearchResult youtube_continue_search(const YouTubeSearchResult &prev_result); - - -struct YouTubeVideoDetail { - std::string error; - std::string url; - std::string title; - std::string description; - YouTubeChannelSuccinct author; - std::string audio_stream_url; - std::map video_stream_urls; // first : video size (144p, 240p, 360p ...) - std::string both_stream_url; - int duration_ms; - bool is_livestream; - enum class LivestreamType { - PREMIERE, - LIVESTREAM, - }; - LivestreamType livestream_type; - bool is_upcoming; - std::string playability_status; - std::string playability_reason; - int stream_fragment_len; // used only for livestreams - std::string like_count_str; - std::string dislike_count_str; - std::string publish_date; - std::string views_str; - - // caption-related data - std::string caption_base_url; - struct CaptionBaseLanguage { - std::string name; // e.g. "English", "Japanese" - std::string id; // e.g. "en", "ja" - std::string base_url; // empty string for instances in caption_translated_languages - bool is_translatable; - }; - struct CaptionTranslationLanguage { - std::string name; - std::string id; - }; - std::vector caption_base_languages; - std::vector caption_translation_languages; - struct CaptionPiece { - float start_time; - float end_time; - std::string content; - }; - using Caption = std::vector; - std::map, Caption> caption_data; - - std::vector suggestions; - struct Playlist { - std::string id; - std::string title; - std::string author_name; - int total_videos; - std::vector videos; - int selected_index; - }; - Playlist playlist; - - struct Comment { - YouTubeChannelSuccinct author; - std::string content; - std::string id; - - int reply_num; - std::vector replies; - std::string continue_key; // innertube key, equals to YouTubeChannelDetail.continue_key - std::string replies_continue_token; - bool has_more_replies() const { return replies_continue_token != ""; } - }; - std::vector comments; - - std::string continue_key; // innertube key - std::string suggestions_continue_token; - std::string comment_continue_token; - int comment_continue_type; // -1 : unavailable, 0 : using watch_comments, 1 : using innertube - bool comments_disabled; - - bool has_more_suggestions() const { return continue_key != "" && suggestions_continue_token != ""; } - bool has_more_comments() const { return comment_continue_type != -1; } - bool needs_timestamp_adjusting() const { return is_livestream && livestream_type == LivestreamType::PREMIERE; } - bool is_playable() const { return playability_status == "OK" && (both_stream_url != "" || (audio_stream_url != "" && video_stream_urls.size())); } -}; -// this function does not load comments; call youtube_video_page_load_more_comments() if necessary -PRX_EXPORT YouTubeVideoDetail youtube_parse_video_page(std::string url); -PRX_EXPORT YouTubeVideoDetail youtube_video_page_load_more_suggestions(const YouTubeVideoDetail &prev_result); -PRX_EXPORT YouTubeVideoDetail youtube_video_page_load_more_comments(const YouTubeVideoDetail &prev_result); -PRX_EXPORT YouTubeVideoDetail::Comment youtube_video_page_load_more_replies(const YouTubeVideoDetail::Comment &comment); -PRX_EXPORT YouTubeVideoDetail youtube_video_page_load_caption(const YouTubeVideoDetail &prev_result, const std::string &base_lang_id, const std::string &translation_lang_id); - - - -struct YouTubeChannelDetail { - std::string id; - std::string error; - std::string name; - std::string url; - std::string url_original; - std::string icon_url; - std::string banner_url; - std::string description; - std::string subscriber_count_str; - std::vector videos; - - std::string continue_token; - std::string continue_key; - - bool has_continue() const { return continue_token != "" && continue_key != ""; } -}; -PRX_EXPORT YouTubeChannelDetail youtube_parse_channel_page(std::string url); -// takes the previous result, returns the new result with both old items and new items -PRX_EXPORT YouTubeChannelDetail youtube_channel_page_continue(const YouTubeChannelDetail &prev_result); -#endif - - diff --git a/ElevenMPV-A/libs/include/dr_flac.h b/ElevenMPV-A/libs/include/dr_flac.h index bbb04c6..00142b3 100644 --- a/ElevenMPV-A/libs/include/dr_flac.h +++ b/ElevenMPV-A/libs/include/dr_flac.h @@ -229,8 +229,6 @@ QUICK NOTES #include #include -#define memcpy sce_paf_memcpy -#define memset sce_paf_memset #define malloc sce_paf_malloc #define free sce_paf_free #define realloc sce_paf_realloc diff --git a/ElevenMPV-A/libs/include/invidious.h b/ElevenMPV-A/libs/include/invidious.h index 72d02ec..50dac8c 100644 --- a/ElevenMPV-A/libs/include/invidious.h +++ b/ElevenMPV-A/libs/include/invidious.h @@ -36,6 +36,14 @@ typedef enum InvSort INV_SORT_MAX } InvSort; +typedef enum InvCommentSort +{ + INV_COMMENT_SORT_TOP, + INV_COMMENT_SORT_NEW, + + INV_COMMENT_SORT_MAX +} InvCommentSort; + typedef enum InvDate { INV_DATE_HOUR, @@ -48,8 +56,18 @@ typedef enum InvDate INV_DATE_MAX } InvDate; +typedef enum InvHlsQuality +{ + INV_HLS_QUALITY_LOW, + INV_HLS_QUALITY_MEDIUM, + INV_HLS_QUALITY_HIGH, + + INV_HLS_QUALITY_MAX +} InvHlsQuality; + typedef struct InvItemVideo { + ScePVoid reserved; const char *title; const char *id; const char *author; @@ -63,7 +81,9 @@ typedef struct InvItemVideo const char *audioMqUrl; const char *audioHqUrl; SceInt32 lengthSec; - ScePVoid reserved; + SceBool isLive; + const char *description; + const char *published; } InvItemVideo; typedef struct InvItemPlaylist @@ -85,8 +105,18 @@ typedef struct InvItemChannel SceInt32 subCount; } InvItemChannel; +typedef struct InvItemComment +{ + ScePVoid reserved; + const char *author; + const char *thmbUrl; + const char *content; + const char *continuation; +} InvItemComment; + typedef struct InvItem { + ScePVoid reserved; InvItemType type; union { @@ -94,7 +124,6 @@ typedef struct InvItem InvItemPlaylist *playlistItem; InvItemChannel *channelItem; }; - ScePVoid reserved; } InvItem; INV_EXPORT SceInt32 invInit(InvAllocator allocator, InvDeallocator deallocator, InvDownloader downloader); @@ -107,8 +136,14 @@ INV_EXPORT SceInt32 invParseSearch(const char *request, SceInt32 page, InvItemTy INV_EXPORT SceInt32 invParseVideo(const char *videoId, InvItemVideo **item); +INV_EXPORT SceInt32 invParseComments(const char *videoId, const char *continuation, InvCommentSort sort, InvItemComment **item); + INV_EXPORT SceInt32 invCleanupVideo(InvItemVideo *item); INV_EXPORT SceInt32 invCleanupSearch(InvItem *items); +INV_EXPORT SceInt32 invCleanupComments(InvItemComment *item); + +INV_EXPORT SceInt32 invGetHlsUrl(const char *videoId, InvHlsQuality quality, char *hlsUrl, SceInt32 sizeOfUrl); + SCE_CDECL_END diff --git a/ElevenMPV-A/source/audio/audio.cpp b/ElevenMPV-A/source/audio/audio.cpp index 40f86bc..630fe07 100644 --- a/ElevenMPV-A/source/audio/audio.cpp +++ b/ElevenMPV-A/source/audio/audio.cpp @@ -7,6 +7,7 @@ #include "audio.h" #include "vitaaudiolib.h" #include "utils.h" +#include "curl_file.h" enum Audio_BgmMode { @@ -119,8 +120,7 @@ SceVoid audio::YoutubePlayerCoverLoaderJob::Run() ui::BusyIndicator *playerBusyInd; Rgba col; SceInt32 res; - SceUInt32 retryCount = 0; - SharedPtr fres; + SharedPtr fres; searchParam.hash = EMPVAUtils::GetHash("plane_player_cover"); playerCover = g_player_page->GetChild(&searchParam, 0); @@ -132,13 +132,7 @@ SceVoid audio::YoutubePlayerCoverLoaderJob::Run() if (g_currentCoverSurf != SCE_NULL) menu::displayfiles::Page::ResetBgPlaneTex(); - fres = HttpFile::Open(url.c_str(), &res, 0); - - while (res < 0 && retryCount != 3) { - fres = HttpFile::Open(url.c_str(), &res, 0); - retryCount++; - } - + fres = CurlFile::Open(url.c_str(), &res, 0, true); if (res < 0) { playerBusyInd->Stop(); return; diff --git a/ElevenMPV-A/source/audio/youtube_opus.cpp b/ElevenMPV-A/source/audio/youtube_opus.cpp index 1b7c195..48ec4a1 100644 --- a/ElevenMPV-A/source/audio/youtube_opus.cpp +++ b/ElevenMPV-A/source/audio/youtube_opus.cpp @@ -172,7 +172,7 @@ SceVoid audio::YoutubeDecoder::Decode(ScePVoid stream, SceUInt32 length, ScePVoi nestegg_packet_count(packet, &uret); if (uret == 1) { - unsigned char* data; + unsigned char* data = SCE_NULL; ret = nestegg_packet_data(packet, 0, &data, &uret); if (ret == 0) { const int samples = opus_decode(opusDec, data, uret, (opus_int16 *)stream, maxSamples, 0); diff --git a/ElevenMPV-A/source/curl_file.cpp b/ElevenMPV-A/source/curl_file.cpp new file mode 100644 index 0000000..76237d9 --- /dev/null +++ b/ElevenMPV-A/source/curl_file.cpp @@ -0,0 +1,573 @@ +#include +#include +#include + +#include "curl_file.h" + +using namespace paf; + +static CURLSH *s_share = SCE_NULL; +static thread::RMutex *s_shareLock = SCE_NULL; + +CurlFile::OpenArg::OpenArg() +{ + fileType = 3; + userAgent = CURL_FILE_UA; + sslFlags = 0; + + url = ""; + resolveTimeout = -1; + connectTimeout = -1; + sendTimeout = -1; + recvTimeout = -1; + useShare = false; +} + +CurlFile::OpenArg::~OpenArg() +{ + +} + +SceVoid CurlFile::OpenArg::SetUseShare(bool use) +{ + useShare = use; +} + +SceVoid CurlFile::OpenArg::SetUrl(const char *url) +{ + this->url = url; +} + +SceVoid CurlFile::OpenArg::SetUrl(paf::Url *url) +{ + ScePVoid pobj = (ScePVoid)url; + paf::swstring *swsurl = (paf::swstring *)(pobj + 0x38); + this->url = swsurl->string; +} + +SceInt32 CurlFile::OpenArg::SetOpt(SceInt32 optValue, Opt optType) +{ + SceInt32 ret; + + if (optValue < 0) { + ret = 0x80AF008F; + } + else { + if ((optType & 1U) != 0) { + resolveTimeout = optValue; + } + if ((optType & 2U) != 0) { + connectTimeout = optValue; + } + if ((optType & 4U) != 0) { + sendTimeout = optValue; + } + if ((optType & 8U) != 0) { + recvTimeout = optValue; + } + ret = 0; + } + + return ret; +} + +CurlFile::CurlFile() +{ + lock = new thread::RMutex("ScePafCurlFileCsLock", 0); + curl = SCE_NULL; + pos = 0; + contentLength = -1; + isOpened = false; +} + +CurlFile::~CurlFile() +{ + if (isOpened) { + Close(); + } + delete lock; +} + +SceInt32 CurlFile::GetFileType() const +{ + return 3; +} + +SceInt32 CurlFile::GetCapability() const +{ + return 0x7BF7; +} + +SceOff CurlFile::GetFileSize() const +{ + lock->Lock(); + + if (!isOpened) { + lock->Unlock(); + return 0x80AF5029; + } + + lock->Unlock(); + + return contentLength; +} + +SceInt32 CurlFile::Open(const CurlFile::OpenArg *param) +{ + lock->Lock(); + + if (!param) { + lock->Unlock(); + return 0x80AF5002; + } + + if (GetFileType() != param->fileType) { + lock->Unlock(); + return 0x80AF5002; + } + + if (isOpened) { + lock->Unlock(); + return 0x80AF5028; + } + + curl = curl_easy_init(); + if (!curl) { + lock->Unlock(); + return 0x80AF5003; + } + + if (param->useShare) { + if (!s_share) + InitShare(); + curl_easy_setopt(curl, CURLOPT_SHARE, s_share); + } + + curl_easy_setopt(curl, CURLOPT_URL, param->url.c_str()); + curl_easy_setopt(curl, CURLOPT_USERAGENT, param->userAgent.c_str()); + curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, DownloadCore); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); + + //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + if (param->connectTimeout != -1) { + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, param->connectTimeout); + } + + if (param->recvTimeout != -1) { + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, param->recvTimeout); + } + + curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); + + CURLcode ret = curl_easy_perform(curl); + if (ret != CURLE_OK) { + curl_easy_cleanup(curl); + lock->Unlock(); + return 0x80AF5022; + } + + ret = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &contentLength); + if (ret != CURLE_OK) { + curl_easy_cleanup(curl); + lock->Unlock(); + return 0x80AF5022; + } + + if (contentLength < 0) + contentLength = 0; + + curl_easy_setopt(curl, CURLOPT_NOBODY, 0L); + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); + + isOpened = true; + + lock->Unlock(); + + return 0; +} + +SceInt32 CurlFile::OpenAsync(const CurlFile::OpenArg *param) +{ + lock->Lock(); + lock->Unlock(); + sceClibPrintf("[CurlFile] Async API is not supported\n"); + return 0x80AF5004; +} + +SceInt32 CurlFile::Close() +{ + lock->Lock(); + + if (!isOpened) { + lock->Unlock(); + return 0x80AF5029; + } + + curl_easy_cleanup(curl); + curl = SCE_NULL; + pos = 0; + isOpened = false; + + lock->Unlock(); + + return 0; +} + +SceInt32 CurlFile::CloseAsync() +{ + lock->Lock(); + lock->Unlock(); + sceClibPrintf("[CurlFile] Async API is not supported\n"); + return 0x80AF5004; +} + +bool CurlFile::IsOpened() const +{ + return isOpened; +} + +bool CurlFile::IsEof() +{ + lock->Lock(); + lock->Unlock(); + return false; +} + +SceInt32 CurlFile::Abort() +{ + lock->Lock(); + lock->Unlock(); + return 0; +} + +SceInt32 CurlFile::Read(void *buffer, SceSize nbyte) +{ + lock->Lock(); + + if (!isOpened) { + lock->Unlock(); + return 0x80AF5029; + } + + if (!buffer) { + lock->Unlock(); + return 0x80AF5002; + } + + if (nbyte == 0) { + lock->Unlock(); + return 0; + } + + if (contentLength != nbyte) { + char range[32]; + sce_paf_snprintf(range, 31, "%lld-%u", pos, nbyte - 1); + + curl_easy_setopt(curl, CURLOPT_RANGE, range); + } + + buf = buffer; + posInBuf = 0; + maxBuf = nbyte; + CURLcode ret = curl_easy_perform(curl); + if (ret != CURLE_OK) { + lock->Unlock(); + return 0x80AF5004; + } + + pos += posInBuf; + + lock->Unlock(); + + return posInBuf; +} + +SceInt32 CurlFile::ReadAsync(void *buf, SceSize nbyte) +{ + lock->Lock(); + lock->Unlock(); + sceClibPrintf("[CurlFile] Async API is not supported\n"); + return 0x80AF5004; +} + +SceInt32 CurlFile::Write(const void *buf, SceSize nbyte) +{ + return 0x80AF5004; +} + +SceInt32 CurlFile::WriteAsync(const void *buf, SceSize nbyte) +{ + return 0x80AF5004; +} + +SceOff CurlFile::Seek(SceOff offset, SceInt32 whence) +{ + SceOff ret = 0; + + lock->Lock(); + + if (!isOpened) { + lock->Unlock(); + return 0x80AF5029; + } + + switch (whence) { + case SCE_SEEK_CUR: + if (pos + offset < 0) { + lock->Unlock(); + return 0x80AF5002; + } + pos += offset; + break; + case SCE_SEEK_SET: + if (offset < 0) { + lock->Unlock(); + return 0x80AF5002; + } + pos = offset; + break; + case SCE_SEEK_END: + if (contentLength == 0 || offset > 0) { + lock->Unlock(); + return 0x80AF5002; + } + pos = contentLength + offset; + } + + lock->Unlock(); + + return pos; +} + +SceInt32 CurlFile::SeekAsync(SceOff offset, SceInt32 whence) +{ + lock->Lock(); + lock->Unlock(); + sceClibPrintf("[CurlFile] Async API is not supported\n"); + return 0x80AF5004; +} + +SceInt32 CurlFile::Flush() +{ + lock->Lock(); + lock->Unlock(); + return 0x80AF5004; +} + +SceInt32 CurlFile::FlushAsync() +{ + lock->Lock(); + lock->Unlock(); + return 0x80AF5004; +} + +SceInt32 CurlFile::WaitAsync(SceInt64 *pResult) +{ + lock->Lock(); + lock->Unlock(); + sceClibPrintf("[CurlFile] Async API is not supported\n"); + return 0x80AF5004; +} + +SceInt32 CurlFile::PollAsync(SceInt64 *pResult) +{ + lock->Lock(); + lock->Unlock(); + sceClibPrintf("[CurlFile] Async API is not supported\n"); + return 0x80AF5004; +} + +SceInt32 CurlFile::GetStat(FileStat *stat) +{ + lock->Lock(); + + if (!isOpened) { + lock->Unlock(); + return 0x80AF5029; + } + + stat->st_size = contentLength; + + lock->Unlock(); + + return 0; +} + +SceInt32 CurlFile::SetPriority(SceInt32 ioPriority) +{ + return 0x80AF5005; +} + +SceInt32 CurlFile::GetResponseCode(SceInt32 *code) +{ + lock->Lock(); + + if (!isOpened) { + lock->Unlock(); + return 0x80AF5029; + } + + CURLcode ret = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); + if (ret != CURLE_OK) { + lock->Unlock(); + return 0x80AF5022; + } + + lock->Unlock(); + + return 0; +} + +SharedPtr CurlFile::Open(const char *path, SceUInt32 flag, SceUInt32 mode, SceInt32 *error, bool useShare) +{ + if (!path) { + *error = 0x80AF5002; + return SharedPtr(); + } + + CurlFile::OpenArg oarg; + oarg.SetUrl(path); + oarg.SetUseShare(useShare); + + CurlFile *file = new CurlFile(); + + SceInt32 ret = file->Open(&oarg); + *error = ret; + if (ret != 0) { + delete file; + return SharedPtr(); + } + + return SharedPtr(file); +} + +SharedPtr CurlFile::Open(const SceWChar16 *url, SceInt32 *error, SceUInt32 flag, bool useShare) +{ + wstring text16; + string text8; + + if (!url) { + *error = 0x80AF5002; + return SharedPtr(); + } + + text16 = (wchar_t *)url; + + ccc::UTF16toUTF8(&text16, &text8); + + return CurlFile::Open(text8.c_str(), flag, 0, error); +} + +SharedPtr CurlFile::Open(const char *url, SceInt32 *error, SceUInt32 flag, bool useShare) +{ + return CurlFile::Open(url, flag, 0, error); +} + +SceInt32 CurlFile::GetStat(const char *url, CurlFileStat *stat, bool useShare) +{ + CURL *curl = curl_easy_init(); + if (!curl) { + return 0x80AF5003; + } + + if (useShare) { + if (!s_share) + InitShare(); + curl_easy_setopt(curl, CURLOPT_SHARE, s_share); + } + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_USERAGENT, CURL_FILE_UA); + curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); + + //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + CURLcode ret = curl_easy_perform(curl); + if (ret != CURLE_OK) { + curl_easy_cleanup(curl); + return 0x80AF5022; + } + + curl_off_t contentLength = -1; + ret = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &contentLength); + curl_easy_cleanup(curl); + if (ret != CURLE_OK) { + return 0x80AF5022; + } + + if (contentLength < 0) + contentLength = 0; + + stat->st_size = contentLength; + + return 0; +} + +SceSize CurlFile::DownloadCore(char *buffer, SceSize size, SceSize nitems, ScePVoid userdata) +{ + CurlFile *obj = (CurlFile *)userdata; + SceSize toCopy = size * nitems; + + if (toCopy != 0) { + if (obj->posInBuf + toCopy > obj->maxBuf) { + return 0; + } + sce_paf_memcpy(obj->buf + obj->posInBuf, buffer, toCopy); + obj->posInBuf += toCopy; + return toCopy; + } + + return 0; +} + +SceVoid CurlFile::InitShare() +{ + if (!s_shareLock) + s_shareLock = new thread::RMutex("ScePafCurlFileShareLock", 1); + + if (!s_share) { + s_share = curl_share_init(); + curl_share_setopt(s_share, CURLSHOPT_LOCKFUNC, ShareLock); + curl_share_setopt(s_share, CURLSHOPT_UNLOCKFUNC, ShareUnlock); + curl_share_setopt(s_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); + curl_share_setopt(s_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); + curl_share_setopt(s_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); + curl_share_setopt(s_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_PSL); + } +} + +SceVoid CurlFile::TermShare() +{ + if (s_share) { + curl_share_cleanup(s_share); + s_share = SCE_NULL; + } + + if (s_shareLock) { + delete s_shareLock; + s_shareLock = SCE_NULL; + } +} + +SceVoid CurlFile::ShareLock(CURL *handle, curl_lock_data data, curl_lock_access access, ScePVoid userptr) +{ + s_shareLock->Lock(); +} + +SceVoid CurlFile::ShareUnlock(CURL *handle, curl_lock_data data, ScePVoid userptr) +{ + s_shareLock->Unlock(); +} \ No newline at end of file diff --git a/ElevenMPV-A/source/main.cpp b/ElevenMPV-A/source/main.cpp index 8e0eb63..cd39a7b 100644 --- a/ElevenMPV-A/source/main.cpp +++ b/ElevenMPV-A/source/main.cpp @@ -53,7 +53,7 @@ static const EMPVAUtils::MemState k_ytModeLimit = EMPVAUtils::MemState_Mid; SceVoid menu::main::PagemodeButtonCB::PagemodeButtonCBFun(SceInt32 eventId, paf::ui::Widget *self, SceInt32 a3, ScePVoid pUserData) { - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; rco::Element searchParam; menu::settings::Settings *config = menu::settings::Settings::GetInstance(); SceUInt32 currentPagemode = EMPVAUtils::GetPagemode(); @@ -66,7 +66,7 @@ SceVoid menu::main::PagemodeButtonCB::PagemodeButtonCBFun(SceInt32 eventId, paf: if (currentPagemode == menu::settings::Settings::PageMode_Normal) { - if (sceSysmoduleIsLoaded(SCE_SYSMODULE_HTTPS)) { + if (sceSysmoduleIsLoaded(SCE_SYSMODULE_NET)) { if (EMPVAUtils::GetMemStatus() > k_ytModeLimit) { menu::youtube::Base::FirstTimeInit(); } @@ -151,8 +151,8 @@ SceVoid pluginLoadCB(Plugin *plugin) ui::Widget *buttonPagemode = SCE_NULL; rco::Element searchParam; - Plugin::PageInitParam rwiParam; - Plugin::TemplateInitParam tmpParam; + Plugin::PageOpenParam rwiParam; + Plugin::TemplateOpenParam tmpParam; string initCwd; SceUInt32 pagemode = menu::settings::Settings::PageMode_Normal; @@ -286,7 +286,7 @@ int main() //fwParam.optionalFeatureFlags = Framework::InitParam::FeatureFlag_DisableInternalCallbackChecks; if (EMPVAUtils::GetMemStatus() == EMPVAUtils::MemState_Full) { - fwParam.defaultSurfacePoolSize = 18 * 1024 * 1024; + fwParam.defaultSurfacePoolSize = 20 * 1024 * 1024; fwParam.textSurfaceCacheSize = 2 * 1024 * 1024; } else if (EMPVAUtils::GetMemStatus() == EMPVAUtils::MemState_Mid) { diff --git a/ElevenMPV-A/source/menus/menu_audioplayer.cpp b/ElevenMPV-A/source/menus/menu_audioplayer.cpp index 1ac6397..8523603 100644 --- a/ElevenMPV-A/source/menus/menu_audioplayer.cpp +++ b/ElevenMPV-A/source/menus/menu_audioplayer.cpp @@ -253,7 +253,7 @@ SceVoid menu::audioplayer::Audioplayer::RegularTask(ScePVoid pUserData) SceInt32 motionCom = 0; SceUInt32 ipcCom = 0; SceCtrlData ctrlData; - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; ui::Widget *commonWidget; rco::Element searchParam; @@ -414,12 +414,12 @@ SceVoid menu::audioplayer::Audioplayer::RegularTask(ScePVoid pUserData) SceVoid menu::audioplayer::Audioplayer::Return() { rco::Element searchParam; - Plugin::PageInitParam rwiParam; + Plugin::PageOpenParam rwiParam; *(SceUInt32 *)g_settingsButtonCB->pUserData = menu::settings::SettingsButtonCB::Parent_Player; // Hide (disable) displayfiles page - g_rootPage->PlayEffectReverse(100.0f, effect::EffectType_Fadein1, SCE_NULL); + ui::Widget::SetControlFlags(g_rootPage, 0); // Get player widgets searchParam.hash = EMPVAUtils::GetHash("plane_player_bg"); @@ -456,7 +456,7 @@ SceVoid menu::audioplayer::BackButtonCB::BackButtonCBFun(SceInt32 eventId, ui::W *(SceUInt32 *)g_settingsButtonCB->pUserData = menu::settings::SettingsButtonCB::Parent_Displayfiles; // Show (enable) displayfiles page - g_rootPage->PlayEffect(-1000.0f, effect::EffectType_Fadein1, SCE_NULL); + ui::Widget::SetControlFlags(g_rootPage, 1); // Get hashes for animations and play them in reverse searchParam.hash = EMPVAUtils::GetHash("plane_player_bg"); @@ -573,8 +573,8 @@ menu::audioplayer::Audioplayer::Audioplayer(const char *cwd, menu::displayfiles: wstring text16; string fullPath; rco::Element searchParam; - Plugin::PageInitParam rwiParam; - Plugin::TemplateInitParam tmpParam; + Plugin::PageOpenParam rwiParam; + Plugin::TemplateOpenParam tmpParam; ui::Widget *playerCover = SCE_NULL; ui::Widget *commonWidget; ui::Widget *numText; @@ -589,7 +589,7 @@ menu::audioplayer::Audioplayer::Audioplayer(const char *cwd, menu::displayfiles: s_timerPof = 0; // Hide (disable) root page - g_rootPage->PlayEffectReverse(100.0f, effect::EffectType_Fadein1, SCE_NULL); + ui::Widget::SetControlFlags(g_rootPage, 0); searchParam.hash = EMPVAUtils::GetHash("displayfiles_pagemode_button"); ui::Widget *buttonPagemode = g_rootPage->GetChild(&searchParam, 0); diff --git a/ElevenMPV-A/source/menus/menu_displayfiles.cpp b/ElevenMPV-A/source/menus/menu_displayfiles.cpp index 9fcf7e5..bbaaabb 100644 --- a/ElevenMPV-A/source/menus/menu_displayfiles.cpp +++ b/ElevenMPV-A/source/menus/menu_displayfiles.cpp @@ -198,7 +198,7 @@ menu::displayfiles::Page::Page(const char* path) } rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; cwd = new string(path); diff --git a/ElevenMPV-A/source/menus/menu_settings.cpp b/ElevenMPV-A/source/menus/menu_settings.cpp index 830314e..132085f 100644 --- a/ElevenMPV-A/source/menus/menu_settings.cpp +++ b/ElevenMPV-A/source/menus/menu_settings.cpp @@ -43,7 +43,7 @@ menu::settings::Settings::Settings() pluginParam.resourcePath = "vs0:vsh/common/app_settings_plugin.rco"; pluginParam.scopeName = "__main__"; - pluginParam.pluginCreateCB = AppSettings::PluginCreateCB; + pluginParam.pluginSetParamCB = AppSettings::PluginCreateCB; pluginParam.pluginInitCB = AppSettings::PluginInitCB; pluginParam.pluginStartCB = AppSettings::PluginStartCB; pluginParam.pluginStopCB = AppSettings::PluginStopCB; @@ -326,11 +326,11 @@ SceVoid menu::settings::Settings::CBTerm() switch (s_callerMode) { case menu::settings::SettingsButtonCB::Parent_Player: // Show (enable) player page - g_player_page->PlayEffect(-1000.0f, effect::EffectType_Fadein1, SCE_NULL); + ui::Widget::SetControlFlags(g_player_page, 1); break; case menu::settings::SettingsButtonCB::Parent_Displayfiles: // Show (enable) displayfiles page - g_rootPage->PlayEffect(-1000.0f, effect::EffectType_Fadein1, SCE_NULL); + ui::Widget::SetControlFlags(g_rootPage, 1); break; } @@ -458,11 +458,11 @@ SceVoid menu::settings::SettingsButtonCB::SettingsButtonCBFun(SceInt32 eventId, switch (callerMode) { case Parent_Player: // Hide (disable) player page - g_player_page->PlayEffectReverse(100.0f, effect::EffectType_Fadein1, SCE_NULL); + ui::Widget::SetControlFlags(g_player_page, 0); break; case Parent_Displayfiles: // Hide (disable) displayfiles page - g_rootPage->PlayEffectReverse(100.0f, effect::EffectType_Fadein1, SCE_NULL); + ui::Widget::SetControlFlags(g_rootPage, 0); break; } diff --git a/ElevenMPV-A/source/menus/youtube/menu_youtube_base.cpp b/ElevenMPV-A/source/menus/youtube/menu_youtube_base.cpp index 59e5237..2d54f89 100644 --- a/ElevenMPV-A/source/menus/youtube/menu_youtube_base.cpp +++ b/ElevenMPV-A/source/menus/youtube/menu_youtube_base.cpp @@ -18,6 +18,7 @@ #include "dialog.h" #include "utils.h" #include "yt_utils.h" +#include "curl_file.h" using namespace paf; @@ -27,7 +28,7 @@ static SceInt32 s_netCtlStateCbId = SCE_UID_INVALID_UID; SceVoid menu::youtube::Base::netCtlStateCB(SceInt32 event_type, ScePVoid arg) { - s_netCheckThread = new NetCheckThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_4KiB, "EMPVA::NetCheckThread"); + s_netCheckThread = new NetCheckThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_16KiB, "EMPVA::NetCheckThread"); s_netCheckThread->Start(); } @@ -35,20 +36,20 @@ SceVoid menu::youtube::Base::NetCheckThread::EntryFunction() { rco::Element searchParam; ui::Widget *button; - HttpFile::OpenArg testHttp; - HttpFile testFile; - SceInt32 ret = -1; + CurlFile::OpenArg testHttp; + CurlFile testFile; + SceInt32 ret = SCE_NET_CTL_ERROR_NOT_AVAIL; //sceShellUtilLock(SCE_SHELL_UTIL_LOCK_TYPE_PS_BTN); Dialog::OpenPleaseWait(g_empvaPlugin, SCE_NULL, EMPVAUtils::GetString("msg_wait")); testHttp.SetUrl("https://www.youtube.com/s/desktop/b75d77f8/img/favicon_32x32.png"); - testHttp.SetOpt(10000000, HttpFile::OpenArg::Opt_ResolveTimeOut); - testHttp.SetOpt(10000000, HttpFile::OpenArg::Opt_ConnectTimeOut); + testHttp.SetOpt(10000000, CurlFile::OpenArg::Opt_ResolveTimeOut); + testHttp.SetOpt(10000000, CurlFile::OpenArg::Opt_ConnectTimeOut); + testHttp.SetUseShare(true); ret = testFile.Open(&testHttp); - if (ret == SCE_OK) testFile.Close(); @@ -56,13 +57,7 @@ SceVoid menu::youtube::Base::NetCheckThread::EntryFunction() if (ret != SCE_OK) { - if (ret == SCE_HTTP_ERROR_SSL) { - Dialog::OpenError(g_empvaPlugin, ret, EMPVAUtils::GetString("msg_netcheck_fail")); - } - else { - Dialog::OpenError(g_empvaPlugin, ret, EMPVAUtils::GetString("msg_error_server_peer_connect_timeout")); - } - + Dialog::OpenError(g_empvaPlugin, ret, EMPVAUtils::GetString("msg_error_server_peer_connect_timeout")); Dialog::WaitEnd(); searchParam.hash = EMPVAUtils::GetHash("displayfiles_pagemode_button"); @@ -98,6 +93,12 @@ SceVoid menu::youtube::VideoButtonCB::VideoButtonCBFun(SceInt32 eventId, ui::Wid SceVoid menu::youtube::SearchActionButtonCB::SearchActionButtonCBFun(SceInt32 eventId, paf::ui::Widget *self, SceInt32 a3, ScePVoid pUserData) { + if (eventId == 0x1000000B) + { + ui::TextBox *tb = (ui::TextBox *)self; + tb->Hide(); + } + switch (s_currentYtMode) { case menu::youtube::Base::Mode_Search: menu::youtube::SearchPage::SearchActionButtonOp(); @@ -114,7 +115,7 @@ SceVoid menu::youtube::Base::InitCommon() ui::Widget *btMenu; ui::Widget *commonWidget; - s_netCheckThread = new NetCheckThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_4KiB, "EMPVA::NetCheckJob"); + s_netCheckThread = new NetCheckThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_256KiB, "EMPVA::NetCheckJob"); s_netCheckThread->Start(); searchParam.hash = EMPVAUtils::GetHash("yt_plane_bottommenu"); @@ -291,7 +292,7 @@ SceUInt32 menu::youtube::Base::GetCurrentMode() SceVoid menu::youtube::Base::FirstTimeInit() { rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; ui::Widget *commonWidget; ui::Widget *ytTopPlane; ui::Widget *btMenu; @@ -310,12 +311,10 @@ SceVoid menu::youtube::Base::FirstTimeInit() auto searchActionButtonCB = new menu::youtube::SearchActionButtonCB(); commonWidget->RegisterEventCallback(0x10000008, searchActionButtonCB, 0); - /* searchParam.hash = EMPVAUtils::GetHash("yt_text_box_top_search"); commonWidget = ytTopPlane->GetChild(&searchParam, 0); searchActionButtonCB = new menu::youtube::SearchActionButtonCB(); - commonWidget->RegisterEventCallback(0x10000008, searchActionButtonCB, 0); - */ + commonWidget->RegisterEventCallback(0x1000000B, searchActionButtonCB, 0); searchParam.hash = EMPVAUtils::GetHash("yt_plane_bottommenu"); btMenu = g_rootPage->GetChild(&searchParam, 0); @@ -354,13 +353,15 @@ SceInt32 menu::youtube::Base::InitYtStuff() SceInt32 ret = 0; SceInt32 quality = 0; - sceSysmoduleLoadModule(SCE_SYSMODULE_HTTPS); sceSysmoduleLoadModule(SCE_SYSMODULE_NET); - sceSysmoduleLoadModule(SCE_SYSMODULE_SSL); + new Module("app0:module/libcurl.suprx", 0, 0, 0); new Module("app0:module/libInvidious.suprx", 0, 0, 0); new Module("app0:module/libNetMedia.suprx", 0, 0, 0); + /* curl */ + curl_global_memmanager_set_np(sce_paf_malloc, sce_paf_free, sce_paf_realloc); + /* libnet */ param.memory = sce_paf_malloc(k_netMemSize); param.size = k_netMemSize; @@ -376,17 +377,7 @@ SceInt32 menu::youtube::Base::InitYtStuff() SCE_DBG_LOG_ERROR("[EMPVA_PLUGIN_BASE] sceNetCtlInit() error: 0x%08X\n", ret); } - ret = sceSslInit(300 * 1024); - if (ret < 0) { - SCE_DBG_LOG_ERROR("[EMPVA_PLUGIN_BASE] sceSslInit() error: 0x%08X\n", ret); - } - - ret = sceHttpInit(40 * 1024); - if (ret < 0) { - SCE_DBG_LOG_ERROR("[EMPVA_PLUGIN_BASE] sceHttpInit() error: 0x%08X\n", ret); - } - - ret = invInit(sce_paf_malloc, sce_paf_free, SCE_NULL); + ret = invInit(sce_paf_malloc, sce_paf_free, YTUtils::InvDownload); if (ret < 0) { SCE_DBG_LOG_ERROR("[EMPVA_PLUGIN_BASE] invInit() error: 0x%08X\n", ret); } diff --git a/ElevenMPV-A/source/menus/youtube/menu_youtube_fav.cpp b/ElevenMPV-A/source/menus/youtube/menu_youtube_fav.cpp index 59e35da..c1c1617 100644 --- a/ElevenMPV-A/source/menus/youtube/menu_youtube_fav.cpp +++ b/ElevenMPV-A/source/menus/youtube/menu_youtube_fav.cpp @@ -10,6 +10,7 @@ #include "menu_audioplayer.h" #include "utils.h" #include "yt_utils.h" +#include "curl_file.h" #include "invidious.h" using namespace paf; @@ -24,12 +25,12 @@ SceVoid menu::youtube::FavParserThread::CreateVideoButton(FavPage *page, const c string text8; InvItemVideo *vidInfo; rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; ui::Widget *box; ui::Widget *button; ui::Widget *subtext; VideoButtonCB *buttonCB; - SharedPtr fres; + SharedPtr fres; graph::Surface *tmbTex; res = invParseVideo(data, &vidInfo); @@ -78,7 +79,7 @@ SceVoid menu::youtube::FavParserThread::CreateVideoButton(FavPage *page, const c button->RegisterEventCallback(ui::EventMain_Decide, buttonCB, 0); thread::s_mainThreadMutex.Unlock(); - fres = HttpFile::Open(vidInfo->thmbUrl, &res, 0); + fres = CurlFile::Open(vidInfo->thmbUrl, &res, 0, true); invCleanupVideo(vidInfo); if (res < 0) { return; @@ -101,7 +102,7 @@ SceVoid menu::youtube::FavParserThread::CreateVideoButton(FavPage *page, const c SceVoid menu::youtube::FavParserThread::EntryFunction() { rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; ui::Widget *commonWidget; SceUInt32 prevResNum = 0; SceInt32 parseRes = 0; diff --git a/ElevenMPV-A/source/menus/youtube/menu_youtube_history.cpp b/ElevenMPV-A/source/menus/youtube/menu_youtube_history.cpp index 6fc182c..5c2652c 100644 --- a/ElevenMPV-A/source/menus/youtube/menu_youtube_history.cpp +++ b/ElevenMPV-A/source/menus/youtube/menu_youtube_history.cpp @@ -10,6 +10,7 @@ #include "menu_audioplayer.h" #include "utils.h" #include "yt_utils.h" +#include "curl_file.h" #include "invidious.h" using namespace paf; @@ -24,12 +25,12 @@ SceVoid menu::youtube::HistoryParserThread::CreateVideoButton(HistoryPage *page, string text8; InvItemVideo *vidInfo; rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; ui::Widget *box; ui::Widget *button; ui::Widget *subtext; VideoButtonCB *buttonCB; - SharedPtr fres; + SharedPtr fres; graph::Surface *tmbTex; char vidCount[30]; @@ -89,7 +90,7 @@ SceVoid menu::youtube::HistoryParserThread::CreateVideoButton(HistoryPage *page, button->RegisterEventCallback(ui::EventMain_Decide, buttonCB, 0); thread::s_mainThreadMutex.Unlock(); - fres = HttpFile::Open(vidInfo->thmbUrl, &res, 0); + fres = CurlFile::Open(vidInfo->thmbUrl, &res, 0, true); invCleanupVideo(vidInfo); if (res < 0) { return; @@ -112,7 +113,7 @@ SceVoid menu::youtube::HistoryParserThread::CreateVideoButton(HistoryPage *page, SceVoid menu::youtube::HistoryParserThread::EntryFunction() { rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; char *entryData; YTUtils::GetHistLog()->Reset(); diff --git a/ElevenMPV-A/source/menus/youtube/menu_youtube_search.cpp b/ElevenMPV-A/source/menus/youtube/menu_youtube_search.cpp index afc8d24..b1d7dc5 100644 --- a/ElevenMPV-A/source/menus/youtube/menu_youtube_search.cpp +++ b/ElevenMPV-A/source/menus/youtube/menu_youtube_search.cpp @@ -9,6 +9,7 @@ #include "menu_audioplayer.h" #include "utils.h" #include "yt_utils.h" +#include "curl_file.h" #include "invidious.h" using namespace paf; @@ -22,12 +23,12 @@ SceVoid menu::youtube::SearchParserThread::CreateVideoButton(SearchPage *page, S wstring subtext16; string text8; rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; ui::Widget *box; ui::Widget *button; ui::Widget *subtext; VideoButtonCB *buttonCB; - SharedPtr fres; + SharedPtr fres; graph::Surface *tmbTex; if (page->parseResult[index].type == INV_ITEM_TYPE_CHANNEL || @@ -64,7 +65,7 @@ SceVoid menu::youtube::SearchParserThread::CreateVideoButton(SearchPage *page, S text8 += page->parseResult[index].videoItem->author; ccc::UTF8toUTF16(&text8, &subtext16); - fres = HttpFile::Open(page->parseResult[index].videoItem->thmbUrl, &res, 0); + fres = CurlFile::Open(page->parseResult[index].videoItem->thmbUrl, &res, 0, true); thread::s_mainThreadMutex.Lock(); buttonCB = new VideoButtonCB; @@ -124,7 +125,7 @@ SceVoid menu::youtube::SearchParserThread::CreateVideoButton(SearchPage *page, S SceVoid menu::youtube::SearchParserThread::EntryFunction() { rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; + Plugin::TemplateOpenParam tmpParam; ui::Widget *commonWidget; searchParam.hash = EMPVAUtils::GetHash("yt_button_btmenu_right"); diff --git a/ElevenMPV-A/source/paf_libc_bridge.cpp b/ElevenMPV-A/source/paf_libc_bridge.cpp index 700eb47..c0cc1c1 100644 --- a/ElevenMPV-A/source/paf_libc_bridge.cpp +++ b/ElevenMPV-A/source/paf_libc_bridge.cpp @@ -24,21 +24,4 @@ extern "C" { { return (float)ldexpf((float)x, y); } -} - -namespace std { - int _Xout_of_range(char const*) - { - return 0; - } - - int _Xlength_error(char const*) - { - return 0; - } - - int _Syserror_map(int) - { - return 0; - } } \ No newline at end of file diff --git a/ElevenMPV-A/source/utils.cpp b/ElevenMPV-A/source/utils.cpp index 863fe90..f58bb1e 100644 --- a/ElevenMPV-A/source/utils.cpp +++ b/ElevenMPV-A/source/utils.cpp @@ -24,7 +24,6 @@ static SceBool s_isDeactivatedByPowerCB = SCE_FALSE; static char s_titleid[12]; -static SceUID s_shellPluginUID = SCE_UID_INVALID_UID; static SceUID s_shellPid = SCE_UID_INVALID_UID; static SceUID s_ipcPipeRX = SCE_UID_INVALID_UID; @@ -243,20 +242,27 @@ SceVoid EMPVAUtils::Init() sceAppMgrAppParamGetString(SCE_KERNEL_PROCESS_ID_SELF, 12, s_titleid, 12); task::Register(EMPVAUtils::AppWatchdogTask, SCE_NULL); - SceInt32 ret = sceAppMgrGetIdByName(&s_shellPid, "NPXS19999"); - if (ret >= 0) { - sce_paf_snprintf(pluginPath, 256, "ux0:app/%s/module/shell_plugin.suprx", s_titleid); - s_shellPluginUID = taiLoadStartModuleForPid(s_shellPid, pluginPath, 0, SCE_NULL, 0); - sce_paf_memset(pluginPath, 0, sizeof(pluginPath)); - sce_paf_snprintf(pluginPath, 256, "ux0:app/%s/module/download_enabler_empva.suprx", s_titleid); - taiLoadStartModuleForPid(s_shellPid, pluginPath, 0, SCE_NULL, 0); + s_ipcPipeRX = sceKernelOpenMsgPipe("ElevenMPVA::ShellIPC_RX"); + if (s_ipcPipeRX <= 0) { + SceInt32 ret = sceAppMgrGetIdByName(&s_shellPid, "NPXS19999"); + if (ret >= 0) { + sce_paf_snprintf(pluginPath, 256, "ux0:app/%s/module/shell_plugin.suprx", s_titleid); + taiLoadStartModuleForPid(s_shellPid, pluginPath, 0, SCE_NULL, 0); + sce_paf_memset(pluginPath, 0, sizeof(pluginPath)); + sce_paf_snprintf(pluginPath, 256, "ux0:app/%s/module/download_enabler_empva.suprx", s_titleid); + taiLoadStartModuleForPid(s_shellPid, pluginPath, 0, SCE_NULL, 0); - if (s_shellPluginUID > 0) { s_ipcPipeRX = sceKernelOpenMsgPipe("ElevenMPVA::ShellIPC_RX"); s_ipcPipeTX = sceKernelOpenMsgPipe("ElevenMPVA::ShellIPC_TX"); } } + IpcDataRX packet; + packet.cmd = EMPVA_IPC_APP_START; + + if (s_ipcPipeRX > 0) + sceKernelSendMsgPipe(s_ipcPipeRX, &packet, sizeof(IpcDataRX), SCE_KERNEL_MSG_PIPE_MODE_WAIT | SCE_KERNEL_MSG_PIPE_MODE_FULL, SCE_NULL, SCE_NULL); + if (!SCE_PAF_IS_DOLCE) { SceUID powerCbid = sceKernelCreateCallback("EMPVA::PowerCb", 0, EMPVAUtils::PowerCallback, SCE_NULL); scePowerRegisterCallback(powerCbid); @@ -274,9 +280,10 @@ SceVoid EMPVAUtils::Init() SceVoid EMPVAUtils::Exit() { SceInt32 ret; - - if (s_shellPluginUID > 0) - taiStopUnloadModuleForPid(s_shellPid, s_shellPluginUID, 0, SCE_NULL, 0, SCE_NULL, &ret); + IpcDataRX packet; + packet.cmd = EMPVA_IPC_APP_STOP; + if (s_ipcPipeRX > 0) + sceKernelSendMsgPipe(s_ipcPipeRX, &packet, sizeof(IpcDataRX), SCE_KERNEL_MSG_PIPE_MODE_WAIT | SCE_KERNEL_MSG_PIPE_MODE_FULL, SCE_NULL, SCE_NULL); YTUtils::Term(SCE_TRUE); sceKernelExitProcess(0); } @@ -284,7 +291,7 @@ SceVoid EMPVAUtils::Exit() SceVoid EMPVAUtils::Activate() { audio::GenericDecoder *currentDecoder = SCE_NULL; - ui::Widget *scene; + ScePVoid ctx; if (g_currentPlayerInstance != SCE_NULL) { if (g_currentPlayerInstance->GetCore()) @@ -295,8 +302,8 @@ SceVoid EMPVAUtils::Activate() system::ResumeTouchInput(SCE_TOUCH_PORT_FRONT); - scene = s_frameworkInstance->GetCurrentPage(); - scene->unk_0D6 = 0; + ctx = s_frameworkInstance->GetUiContext(); + *(SceInt32 *)(ctx + 0xD6) = 0; if (currentDecoder) { if ((currentDecoder->IsPaused() || !currentDecoder->isPlaying) && EMPVAUtils::IsDecoderUsed()) @@ -311,7 +318,7 @@ SceVoid EMPVAUtils::Activate() SceVoid EMPVAUtils::Deactivate() { audio::GenericDecoder *currentDecoder = SCE_NULL; - ui::Widget *scene; + ScePVoid ctx; if (g_currentPlayerInstance != SCE_NULL) { if (g_currentPlayerInstance->GetCore()) @@ -322,8 +329,8 @@ SceVoid EMPVAUtils::Deactivate() system::SuspendTouchInput(SCE_TOUCH_PORT_FRONT); - scene = s_frameworkInstance->GetCurrentPage(); - scene->unk_0D6 = 1; + ctx = s_frameworkInstance->GetUiContext(); + *(SceInt32 *)(ctx + 0xD6) = 1; if (currentDecoder) { if (currentDecoder->IsPaused() || !currentDecoder->isPlaying) diff --git a/ElevenMPV-A/source/yt_utils.cpp b/ElevenMPV-A/source/yt_utils.cpp index 9a6fbf6..0024c56 100644 --- a/ElevenMPV-A/source/yt_utils.cpp +++ b/ElevenMPV-A/source/yt_utils.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "yt_utils.h" #include "netmedia.h" @@ -17,6 +18,7 @@ static SceAvPlayerFileReplacement s_fio; static SceNmHandle s_nmHandle = SCE_NULL; static SceAvPlayerMemAllocator s_nmAllocator; static Downloader *s_downloader = SCE_NULL; +static CURL *s_curl = SCE_NULL; ScePVoid YTUtils::NMAllocate(ScePVoid argP, SceUInt32 argAlignment, SceUInt32 argSize) { @@ -28,25 +30,6 @@ SceVoid YTUtils::NMDeallocate(ScePVoid argP, ScePVoid argMemory) sce_paf_free(argMemory); } -SceBool YTUtils::DowbloadFile(char *url, ScePVoid *ppBuf, SceSize *pBufSize) -{ - SceInt32 ret = 0; - - SharedPtr file = paf::HttpFile::Open(url, SCE_O_RDONLY, 0, &ret); - if (ret != SCE_OK) - return SCE_FALSE; - - char *buf = (char *)sce_paf_malloc(SCE_KERNEL_256KiB); - - *pBufSize = file->Read(buf, SCE_KERNEL_256KiB); - - file->Close(); - - *ppBuf = buf; - - return SCE_TRUE; -} - SceInt32 YTUtils::Log::GetNext(char *data) { SceInt32 ret; @@ -210,6 +193,18 @@ SceVoid YTUtils::Init() s_favLog = new YTUtils::FavLog(); if (!s_downloader) s_downloader = new Downloader(); + if (!s_curl) { + s_curl = curl_easy_init(); + curl_easy_setopt(s_curl, CURLOPT_USERAGENT, "Mozilla/5.0 (PlayStation Vita 3.74) AppleWebKit/537.73 (KHTML, like Gecko) Silk/3.2"); + curl_easy_setopt(s_curl, CURLOPT_TIMEOUT, 5L); + curl_easy_setopt(s_curl, CURLOPT_ACCEPT_ENCODING, ""); + curl_easy_setopt(s_curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(s_curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(s_curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(s_curl, CURLOPT_HTTPGET, 1L); + curl_easy_setopt(s_curl, CURLOPT_TCP_KEEPALIVE, 1L); + curl_easy_setopt(s_curl, CURLOPT_NOPROGRESS, 1L); + } if (!s_nmHandle) { @@ -225,7 +220,7 @@ SceVoid YTUtils::Init() SceVoid YTUtils::Term(SceBool isFullTerm) { - if (isFullTerm) { + if (!isFullTerm) { if (s_histLog) { s_histLog->Flush(); } @@ -243,10 +238,17 @@ SceVoid YTUtils::Term(SceBool isFullTerm) s_favLog = SCE_NULL; } + if (s_curl) { + curl_easy_cleanup(s_curl); + s_curl = SCE_NULL; + } + + /* if (s_nmHandle) { NETMediaDeInit(s_nmHandle, &s_nmAllocator); s_nmHandle = SCE_NULL; } + */ if (s_menuLock != SCE_UID_INVALID_UID) { sceKernelDeleteEventFlag(s_menuLock); @@ -293,3 +295,48 @@ SceVoid YTUtils::WaitMenuParsers() { sceKernelWaitEventFlag(s_menuLock, 1, SCE_KERNEL_EVF_WAITMODE_OR, SCE_NULL, SCE_NULL); } + +SceSize YTUtils::InvDownloadCore(char *buffer, SceSize size, SceSize nitems, ScePVoid userdata) +{ + InvDownloadData *dw = (InvDownloadData *)userdata; + SceSize toCopy = size * nitems; + + if (dw->pos > SCE_KERNEL_256KiB) + return 0; + + if (toCopy != 0) { + sce_paf_memcpy(dw->buf + dw->pos, buffer, toCopy); + dw->pos += toCopy; + return toCopy; + } + + return 0; +} + +SceBool YTUtils::InvDownload(char *url, ScePVoid *ppBuf, SceSize *pBufSize) +{ + if (!s_curl) + return SCE_FALSE; + + InvDownloadData dw; + dw.buf = sce_paf_malloc(SCE_KERNEL_256KiB); + dw.pos = 0; + + if (!dw.buf) { + return SCE_FALSE; + } + + curl_easy_setopt(s_curl, CURLOPT_URL, url); + curl_easy_setopt(s_curl, CURLOPT_WRITEFUNCTION, InvDownloadCore); + curl_easy_setopt(s_curl, CURLOPT_WRITEDATA, &dw); + + if (curl_easy_perform(s_curl) != CURLE_OK) { + sce_paf_free(dw.buf); + return SCE_FALSE; + } + + *ppBuf = dw.buf; + *pBufSize = dw.pos; + + return SCE_TRUE; +}