From 8c015d75bcec97f6dfbc0f934fabf87b702ee392 Mon Sep 17 00:00:00 2001 From: GrapheneCt <57592952+GrapheneCt@users.noreply.github.com> Date: Tue, 27 Dec 2022 05:13:35 +0200 Subject: [PATCH] Fixed YouTube page navigation --- .../module/download_enabler_netstream.suprx | Bin 5952 -> 6016 bytes NetStream/CONTENTS/netstream_plugin.rcd | 7 + NetStream/CONTENTS/netstream_plugin.rco | Bin 620944 -> 621520 bytes NetStream/NetStream.vcxproj | 6 +- NetStream/NetStream.vcxproj.filters | 12 + NetStream/RES_RCO/netstream_plugin.xml | 16 + NetStream/include/http_server_browser.h | 2 + NetStream/include/local_server_browser.h | 52 +++ NetStream/include/menus/menu_local.h | 114 ++++++ NetStream/include/netstream_plugin.h | 7 + NetStream/source/downloader.cpp | 10 - NetStream/source/http_server_browser.cpp | 14 +- NetStream/source/local_server_browser.cpp | 157 ++++++++ NetStream/source/menus/menu_first.cpp | 5 + NetStream/source/menus/menu_local.cpp | 305 ++++++++++++++++ NetStream/source/menus/menu_player.cpp | 63 ---- NetStream/source/menus/menu_settings.cpp | 2 +- NetStream/source/menus/menu_youtube.cpp | 2 + NetStream/source/menus/menu_youtube_fav.cpp | 337 ------------------ .../source/menus/menu_youtube_history.cpp | 178 --------- .../source/menus/menu_youtube_search.cpp | 329 ----------------- 21 files changed, 692 insertions(+), 926 deletions(-) create mode 100644 NetStream/include/local_server_browser.h create mode 100644 NetStream/include/menus/menu_local.h create mode 100644 NetStream/source/local_server_browser.cpp create mode 100644 NetStream/source/menus/menu_local.cpp delete mode 100644 NetStream/source/menus/menu_player.cpp delete mode 100644 NetStream/source/menus/menu_youtube_fav.cpp delete mode 100644 NetStream/source/menus/menu_youtube_history.cpp delete mode 100644 NetStream/source/menus/menu_youtube_search.cpp diff --git a/NetStream/CONTENTS/module/download_enabler_netstream.suprx b/NetStream/CONTENTS/module/download_enabler_netstream.suprx index 7217f7df36e48db84489e53864462e71bc2d98a7..edce56c2e4a7a9ef1a2bc9f5ed93ebd0b347bb17 100644 GIT binary patch delta 1925 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 Pw(zGi$HjlY)Box}p%gpI diff --git a/NetStream/CONTENTS/netstream_plugin.rcd b/NetStream/CONTENTS/netstream_plugin.rcd index 090daf9..8f0a5c7 100644 --- a/NetStream/CONTENTS/netstream_plugin.rcd +++ b/NetStream/CONTENTS/netstream_plugin.rcd @@ -13,6 +13,13 @@ key:e950a63a(0) id:plane_browser_root_page_http key:0225f81e(0) id:busyindicator_loader_page_http key:3d5b0c73(0) id:button_back_page_http key:82e2e83c(0) id:button_settings_page_http +key:1332c3df(0) id:page_local +key:a7a58bf5(0) id:plane_base_bg_page_local +key:de4604fd(0) id:template_ref_top_title_bar_page_local +key:137b43f7(0) id:plane_browser_root_page_local +key:262eecf2(0) id:busyindicator_loader_page_local +key:e24ed91b(0) id:button_back_page_local +key:6ce20cb2(0) id:button_settings_page_local key:d9d437d7(0) id:page_youtube key:86efefd3(0) id:plane_base_bg_page_youtube key:a1049fc2(0) id:template_ref_top_title_bar_page_youtube diff --git a/NetStream/CONTENTS/netstream_plugin.rco b/NetStream/CONTENTS/netstream_plugin.rco index b9a868726954ae53bd3a5227cfbadd0de8885d2c..766cfd9c2b1b8772a3ac45848cec1034448369ad 100644 GIT binary patch delta 12529 zcmb7K4OCUvmA;QZpU)>gegu5H$9+5%0YM)G6GT8nL_!eJ5Q7NDUqmHF5|UD50@Jap zOvlL>H`Af1Nli*q+c7OkY-=0qkkoeU8k0q5(N<@r8PZ9*T#oHv$4*I?jq`oy-t%~& zv2o6Fd+yz5|9pF&ea^Yu`;Pq2{ED${#{GWuHIN&A{OQ_^sI-o!_f)#t=Nd*k#@wkdf2TUybq?z1 zA<`H7YFx}09Es2{qCm&M8;v1few!3bnGP22jL6}-SUDS=wb5k{<)VjgqYgyvCN}`X zx(~e{ycwWg5Zhu9z0mtjw5B-2$g_#EU>h^!r!F&UJXSWxML1KWtVoh(65hetqcbjr-p15vx3awT?sHE(HxtQwf{ z!Q>8zQFQ>srZX`M*EI1g2#Hm0sn_q6&%{;wiGn7YFi9gcgr$G8Y$({sbM zMJ!j*58I@JP35|A9FokLNwPo2`1IIKIKp;OValOXD(n zk~U+=>j|kYDpC2QrNmIHW`)YANZ)TmvDYT8=;XwpY5yj!wSV?iaxEcAwybi>g;^EK z65V%UDW%z@H3PP$Ua&k>*fglO!OPls69K=_A(0s^nRzu=XG9B}zEXj1yEkhVgRv`=~hT_PoNtUxo8M$xT z4hd3A<{=+_ps+OsLiQzlbLZRQ3vEXYYG^Xa1Vd+ivz4>Hq);4Ld9&dx%f&*Vqw(3? zHN082F}-VWm~)YrBDu-I%mwyvE?Y)d50Cby(5c5oU1w=K%Cb>TV>v!!RATU_MC zMXr7x7qm;g>@-vluCIa)gO8(D{&{w$pY}LTK6^H8d!hVkwi!!_A-R^C>d2F&DP|%q zl9x6I%Mey~q)EvfuQa5)Q|OS6EHgK69>?|DY4V-fxqeEL{dUCgq@UlUn6Z>NF4xlN z=Qk;-QjzLZzG!fQz7(lk*7-bA5$%>EsWD3lL;LH+^%+nB5=bmm;TU;ZX42`Ksc?#s zUb!}hPN%1t2@H-FC$Os)kz}biU0VF^6rNLrq3!fy^o&;?ODpkHP`R;tUPrh|Gh->y zE3bQ%n>nVRZfI-*TW*m}dTDk`S%#TN0AW{GIHhk9FLz0%AMU$aW@CR#Y^2-3ND|^HShTmpap3hM*J(+BlDq2GC)U&LE{ZMjm^%$H}&2)Z!RIm-H%0Lul zEJQ&Y?XYz!L!R_`T{KHJZeQ>P9Sh}0J~NKY_6)h=%R+7v{APg4TCx-d#xo~@48Xc< z$x2>CPpUzHCdbh?fd)a$3nQX3#|BL~>ZiMJ`{7Or%D?;R&XHjz5TkMvKa9jD#G?M>9Q~yG%1q1r}so#dpJC6o_>-j@pY( zIhyQ|gE`Jc+ZY|hE>YV?s)LaB2LvM+{bP39FN95%oS#p9FG9ocB6;3HE&{c*LtGk-GrzGwtzmS+~F} zSZ;IgvAGrY{U-Z3rsJ!FE-8u22^mI*sD46R(4PZvpv$D?T)8A#!cuo zxssJ#DB~Eqy3&~#sd*K{{khb1Oi2E!)Q=3-;Gt(s4a&tFkGB#gX_oraZ1epP=~yV6 zbAwWvQ{gC+Cvr>|{f=Sa{6cv#r%>DrJ>H54T@9^cAu^OFQMpPazdS;O%ZygeLxhQE zfNZ*Y)1)(ZIjZjET+>atdA5uM3PLiP=W#5Tx&-KwigZckbBj<$pgz!4 zm-_j;nD)@Z5O7T!y4?FBrktV-gP>@WJ(}aDR4h*8%qwt|s9U7L)oXB(3xgsDd2rhl zUKmrH@3)e^k;_tVTD`EqWEG3Q;0~z^dE|1A zTfLUy$lD?2%h4o`6=sh%bv$A^Db!bp(gui9^dA8NEPA?5gg0rULz~;Eh=5ZW|s$CMMcsk0$?mM~WbDSFkp}C63_?2FYTc8f@EbfNF-*Oisbqd?lY`SM~Re`nSQ2Bd$(eljOI9_nGTaG zvDc;Z&eW(ADws0ukiqB~P^OCUch_C0U-TNBo~_A8j7vp}Z}EsRWCupzykv3+s}VM* z!uv~)7(73yODtn|$x}-n4sQrF%>v*s&6XDHM~pkoI5HtW`G`@b(MLu~sV)r6!=awd z9wt>S!7NSRPNb(99-5A{4;f>GTVV756Dj>tmsl<=m1pi+|7VeMm}av}A|fRd@{^I~ z>qsMaaZ346O+y$Yg;$YGFHKi3IlJVqmLOU`T<0*SWXK6Znr*dX|9 zSe_b$$3gqnQ$^(7#hT;_q^?F~>&o7W-61E*MUiQRaMxYK)MP-^8N}F$8>Dv^6*A;t28KFK%vvX zKiX-t7xvh*=@Z)-jVJDm42o!%mcXP)lREO!bX}9Q#dZWp=sFOjZnh+f5aA zD~fv+o=P?u2L7q}<@*HsF>3G`6xT;q$>tibv{XC8AET(Ep!tE;T8iUpdC=)U*(=?{D-DjF+|l|J&T?X-!w#nBh~U$)x(Lr zr3tcptFbGuR^OQVs@-yRwI_~oLb85Ua~Yj#$LG@vZ?9xKwXEnJ;Q9pSAKbK!CmHu-mD7ZlX#f(EMx&pUbul(f2`_n#>|0k`&VV$q zi%=(Nl~1Z)B+gY=o56hQWNkqfNg72>l(^P<)q=s~ytAfRO)KZk2|yE&oT%rt2G`s0 z_(wD6jI++r*^1WU=PGN})ZQBr1;uEAA{gGcrZ9uIlqTyWdeX;0fwYD~KPMWo2Leu2 zgS8hmPF5IE(imGWu04$k#(h&@P@5uW8dQbx){+K7T=(5eEjfJO`@nRTl%&z|KLPbi37sq_Mh~OP#DbOcY6@h^Q`1jGj`?S?GQ|enaxTMm41k8=Uj? z?#bC^qSykM$U2ZVcwRC$n$xMs(K>nezPb6lqZ~OW&<||5_2xMw1shCXlU*Hp1EmLQ zkD}KbsEbURGd4(kV=$4o9H;eCMN;34A3fZU#}z5KAHPYsFC?cMJ!KR$AfODQ9|eWs ztJ7gJ#mzPl9yl?e0oziAT7^tRAFy^HR~`2=PaAj+QBdcKX`~~z6Sy7)g`M$iK;wMQ z0EHq>HxAJ(^+xZP=6i$ryrl`ULh#xGy44wUnrW27O_OI39aEE9I)zR$X-b_zfkvkc zZNL{-oI`}&vJvHm!E;TFEVC7e7@0nc7&r~G84xw(iH!@?J_QBq=O)G8$YYrb14!rq zga*A2&OZaA%sSm!)(|nSLlD)Onvjjn>FUKXl_?c!##jFJWxS;@SshRyX{C`V zbGg+HfOE<8hUDGmBpGT-OJKxw&&RA$SQwRr=JbMXw!EH7Vy7QA4NY!A;U!Z;^{T4`zZOsDGDW-j>^53H2aHmCFfd`DKCw_@5QbK6Q8usJ@|;;7jP5gkA+XHw*oUp@maV(ql)h2Ik zuf%&<&FlxWqfJV7R62&_30smSb+Jue1QTv-W(Sy6yTA-e(awMjwE1LsdyKMt5ko_} zu&*5{ZkIRO zDpf>%xD80=Zsd1YKrZg`DDEh@9g5ol?!0!38`zCELW+AD-2Lqy<*x(Wm_72lU4_!P z+hUytt6`6nw-?HBn-#MM&!T(e^X-M+%g7TO7ZgtdCa(d*m-ooeq2aD@CPoe&!%)#) z3GOcR_EH=za`-Zad-uvd4EKG^a1rMA!e06Q?m}r<;f#;egjUp^I~N_XwdQmB?WU`s z2o*wFj4=+Ubx7NuTE~FAyeGAX>unE8n2T)ZKCV6X`MXe`Sahg`hpmOR^AYT!SWY`o z3j^qPcVTIv-v`57KKpUcHM74fe;ZV=oDAdPN4bU!WA8(FdxZW#dp@Kv=P-_ISj4LV zu8lUNnk(Xw$FNSeTS~0@eNeoNem|UW=jftkv=<(CHeqs&JGPep8dY+1Z+R3x&i~uq zV9$U2urMhUgDmTdqmxupd(Yca8155mN{9Am-SP)mep40w^ zm+Jo!uMAU-#P4k#<=^c;fAZb0^LF5X#ovloT_;HT5C@jcS}|M0`-`06OuaCkE_C|!ZNKLJ^4yWmW86qS)%n>=+$+BEa{USJ4z1sM`WfyA-+gGXnVUdL$3MNp zm7jFvOW9ngO*g7maz&;T7kz=dZqMbIp&t}=yy|*rUu^R4|Msh2`@_n|lYVz~QC9k; t`d_``{#D1T-Cf;|zrOzH=dM5M07ZeKK{23MP#kC)$obvtk4`@p{eNZC1-<|P delta 12195 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 diff --git a/NetStream/NetStream.vcxproj b/NetStream/NetStream.vcxproj index a19b9d1..efc9e22 100644 --- a/NetStream/NetStream.vcxproj +++ b/NetStream/NetStream.vcxproj @@ -16,10 +16,12 @@ + + @@ -35,10 +37,12 @@ + + @@ -93,7 +97,7 @@ --no-standard-libraries $(SCE_PSP2_SDK_DIR)\target\lib\vdsuite;$(ProjectDir)libs\lib;%(AdditionalLibraryDirectories) FullMapFile - -lSceSysmem_stub;-lSceThreadMgr_stub;-lSceThreadmgrCoredumpTime_stub;-lSceModuleMgr_stub;-lSceProcessMgr_stub;-lSceTouch_stub;-lSceAppMgr_stub;-lSceAppMgrUser_stub;-lSceAppUtil_stub;-lSceAudio_stub;-lSceCtrl_stub;-lSceDisplay_stub;-lScePower_stub;-lSceSysmodule_stub;-lSceGxm_stub;-lSceDbg_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;-lSceCommonGuiDialog_stub;-lSceIniFileProcessor_stub;-lSceBEAVCorePlayer_stub;-lSceDmacmgr_stub;-lSceFiber_stub;-lSceVshBridge_stub;-ltaihenUnsafe_stub;-lInvidious_stub;-lcurl_stub;-lsnc;-lCurlFile;%(AdditionalDependencies) + -lSceIpmi_stub;-lSceSysmem_stub;-lSceThreadMgr_stub;-lSceThreadmgrCoredumpTime_stub;-lSceModuleMgr_stub;-lSceProcessMgr_stub;-lSceTouch_stub;-lSceAppMgr_stub;-lSceAppMgrUser_stub;-lSceAppUtil_stub;-lSceAudio_stub;-lSceCtrl_stub;-lSceDisplay_stub;-lScePower_stub;-lSceSysmodule_stub;-lSceGxm_stub;-lSceDbg_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;-lSceCommonGuiDialog_stub;-lSceIniFileProcessor_stub;-lSceBEAVCorePlayer_stub;-lSceDmacmgr_stub;-lSceFiber_stub;-lSceVshBridge_stub;-ltaihenUnsafe_stub;-lInvidious_stub;-lcurl_stub;-lsnc;-lCurlFile;%(AdditionalDependencies) "$(SCE_PSP2_SDK_DIR)/host_tools/build/bin/vdsuite-pubprx.exe" --boot-param "$(ProjectDir)ebootparam.bin" "$(LocalDebuggerCommand)" "$(OutDir)eboot.bin" diff --git a/NetStream/NetStream.vcxproj.filters b/NetStream/NetStream.vcxproj.filters index 3ba978d..de6d36f 100644 --- a/NetStream/NetStream.vcxproj.filters +++ b/NetStream/NetStream.vcxproj.filters @@ -68,6 +68,12 @@ Source Files + + Source Files + + + Source Files\menus + @@ -118,6 +124,12 @@ Header Files + + Header Files + + + Header Files\menus + diff --git a/NetStream/RES_RCO/netstream_plugin.xml b/NetStream/RES_RCO/netstream_plugin.xml index 03e94c3..822ff95 100644 --- a/NetStream/RES_RCO/netstream_plugin.xml +++ b/NetStream/RES_RCO/netstream_plugin.xml @@ -27,6 +27,22 @@ + + + + + + + + + + + + + + + + diff --git a/NetStream/include/http_server_browser.h b/NetStream/include/http_server_browser.h index 554ac81..7e3873d 100644 --- a/NetStream/include/http_server_browser.h +++ b/NetStream/include/http_server_browser.h @@ -5,6 +5,8 @@ #include #include +using namespace paf; + class HttpServerBrowser { public: diff --git a/NetStream/include/local_server_browser.h b/NetStream/include/local_server_browser.h new file mode 100644 index 0000000..433254b --- /dev/null +++ b/NetStream/include/local_server_browser.h @@ -0,0 +1,52 @@ +#ifndef _LOCAL_SERVER_BROWSER_H_ +#define _LOCAL_SERVER_BROWSER_H_ + +#include +#include +#include + +using namespace paf; + +class LocalServerBrowser +{ +public: + + class Entry + { + public: + + enum Type + { + Type_UnsupportedFile, + Type_SupportedFile, + Type_Folder + }; + + string ref; + Type type; + }; + + LocalServerBrowser(); + + ~LocalServerBrowser(); + + SceBool Probe(); + + SceBool IsAtRoot(string *current); + + SceBool IsAtRoot(); + + SceVoid SetPath(const char *ref); + + string GetPath(); + + string GetBEAVUrl(string *in); + + vector *GoTo(const char *ref, SceInt32 *result); + +private: + + string path; +}; + +#endif \ No newline at end of file diff --git a/NetStream/include/menus/menu_local.h b/NetStream/include/menus/menu_local.h new file mode 100644 index 0000000..d087ff6 --- /dev/null +++ b/NetStream/include/menus/menu_local.h @@ -0,0 +1,114 @@ +#ifndef _MENU_LOCAL_H_ +#define _MENU_LOCAL_H_ + +#include +#include + +#include "dialog.h" +#include "menu_generic.h" +#include "local_server_browser.h" +#include "menus/menu_player_simple.h" + +using namespace paf; + +namespace menu { + class Local : public GenericMenu + { + public: + + static SceVoid PlayerBackCb(PlayerSimple *player, ScePVoid pUserArg); + static SceVoid PlayerFailCb(PlayerSimple *player, ScePVoid pUserArg); + static SceVoid BackButtonCbFun(SceInt32 eventId, ui::Widget *self, SceInt32 a3, ScePVoid pUserData); + static SceVoid ListButtonCbFun(SceInt32 eventId, ui::Widget *self, SceInt32 a3, ScePVoid pUserData); + + class ListViewCb : public ui::ListView::ItemCallback + { + public: + + ~ListViewCb() + { + + } + + ui::ListItem *Create(Param *info); + + SceVoid Start(Param *info) + { + info->parent->PlayEffect(0.0f, effect::EffectType_Popup1); + } + + Local *workObj; + }; + + class GoToJob : public job::JobItem + { + public: + + using job::JobItem::JobItem; + + ~GoToJob() {} + + SceVoid Run(); + + SceVoid Finish() {} + + static SceVoid ConnectionFailedDialogHandler(dialog::ButtonCode buttonCode, ScePVoid pUserArg); + + Local *workObj; + string targetRef; + }; + + class BrowserPage + { + public: + + BrowserPage() : isLoaded(SCE_FALSE) + { + + } + + ~BrowserPage() + { + + } + + vector *itemList; + ui::ListView *list; + SceBool isLoaded; + }; + + Local(); + + ~Local(); + + MenuType GetMenuType() + { + return MenuType_Http; + } + + const SceUInt32 *GetSupportedSettingsItems(SceInt32 *count) + { + *count = sizeof(k_settingsIdList) / sizeof(char*); + return k_settingsIdList; + } + + SceBool PushBrowserPage(string *ref); + + SceBool PopBrowserPage(); + + LocalServerBrowser *browser; + ui::Widget *browserRoot; + ui::BusyIndicator *loaderIndicator; + ui::Text *topText; + vector pageList; + SceBool firstBoot; + + private: + + const SceUInt32 k_settingsIdList[1] = { + http_setting + }; + }; +} + +#endif \ No newline at end of file diff --git a/NetStream/include/netstream_plugin.h b/NetStream/include/netstream_plugin.h index ae89ee3..2d9e404 100644 --- a/NetStream/include/netstream_plugin.h +++ b/NetStream/include/netstream_plugin.h @@ -17,6 +17,13 @@ #define busyindicator_loader_page_http (0x0225f81e) #define button_back_page_http (0x3d5b0c73) #define button_settings_page_http (0x82e2e83c) +#define page_local (0x1332c3df) +#define plane_base_bg_page_local (0xa7a58bf5) +#define template_ref_top_title_bar_page_local (0xde4604fd) +#define plane_browser_root_page_local (0x137b43f7) +#define busyindicator_loader_page_local (0x262eecf2) +#define button_back_page_local (0xe24ed91b) +#define button_settings_page_local (0x6ce20cb2) #define page_youtube (0xd9d437d7) #define plane_base_bg_page_youtube (0x86efefd3) #define template_ref_top_title_bar_page_youtube (0xa1049fc2) diff --git a/NetStream/source/downloader.cpp b/NetStream/source/downloader.cpp index 5a470f2..bcfb1b2 100644 --- a/NetStream/source/downloader.cpp +++ b/NetStream/source/downloader.cpp @@ -92,22 +92,12 @@ SceInt32 Downloader::Enqueue(const char *url, const char *name) bfInfo.data1 = &minfo; bfInfo.data1Size = sizeof(sce::Download::MetadataInfo); - sceClibPrintf("download url: %s\n", hparam.url); - ret = dw.client->invokeSyncMethod(0x1234000D, &dtInfo, 2, &ret2, &bfInfo, 1); - sceClibPrintf("invokeSyncMethod ret: 0x%08X\n", ret); - sceClibPrintf("invokeSyncMethod ret2: 0x%08X\n", ret2); if (ret != SCE_OK) return ret; else if (ret2 != SCE_OK) return ret2; - sceClibPrintf("meta info:\n"); - sceClibPrintf("name: %s\n", minfo.name); - sceClibPrintf("size: %u\n", minfo.size); - sceClibPrintf("mimeType: %s\n", minfo.mimeType); - sceClibPrintf("creationDateString: %s\n", minfo.creationDateString); - sce_paf_memset(&minfo.name, 0, sizeof(minfo.name)); sce_paf_strcpy((char *)minfo.name, name); diff --git a/NetStream/source/http_server_browser.cpp b/NetStream/source/http_server_browser.cpp index 78dc58e..85b6c74 100644 --- a/NetStream/source/http_server_browser.cpp +++ b/NetStream/source/http_server_browser.cpp @@ -153,23 +153,23 @@ vector *HttpServerBrowser::GoTo(const char *ref, Sce { buffer[posInBuf - 1] = 0; - char *ref = SCE_NULL; + char *href = SCE_NULL; char *refEnd = buffer; while (1) { - ref = sce_paf_strstr(refEnd + 1, ""); + refEnd = sce_paf_strstr(href, "\">"); *refEnd = 0; - BEAVPlayer::SupportType beavType = BEAVPlayer::IsSupported(ref); + BEAVPlayer::SupportType beavType = BEAVPlayer::IsSupported(href); if (beavType != BEAVPlayer::SupportType_NotSupported) { - char *decoded = curl_easy_unescape(curl, ref, 0, SCE_NULL); + char *decoded = curl_easy_unescape(curl, href, 0, SCE_NULL); HttpServerBrowser::Entry *entry = new HttpServerBrowser::Entry(); entry->ref = decoded; entry->type = HttpServerBrowser::Entry::Type_UnsupportedFile; diff --git a/NetStream/source/local_server_browser.cpp b/NetStream/source/local_server_browser.cpp new file mode 100644 index 0000000..6833721 --- /dev/null +++ b/NetStream/source/local_server_browser.cpp @@ -0,0 +1,157 @@ +#include +#include +#include +#include + +#include "common.h" +#include "beav_player.h" +#include "local_server_browser.h" + +using namespace paf; + +const char *k_supportedRoots[] = { + "ux0:" +}; + +LocalServerBrowser::LocalServerBrowser() +{ + +} + +LocalServerBrowser::~LocalServerBrowser() +{ + +} + +SceBool LocalServerBrowser::Probe() +{ + return SCE_TRUE; +} + +SceBool LocalServerBrowser::IsAtRoot(string *current) +{ + return current->empty(); +} + +SceBool LocalServerBrowser::IsAtRoot() +{ + return path.empty(); +} + +string LocalServerBrowser::GetPath() +{ + return path; +} + +string LocalServerBrowser::GetBEAVUrl(string *in) +{ + string ret = "mp4://"; + ret += path + *in; + + return ret; +} + +SceVoid LocalServerBrowser::SetPath(const char *ref) +{ + if (ref) + { + if (!sce_paf_strcmp(ref, "..")) + { + char *tmp = (char *)sce_paf_malloc(path.length() + 1); + sce_paf_strcpy(tmp, path.c_str()); + char *sptr = sce_paf_strrchr(tmp, '/'); + if (!sptr) + { + path.clear(); + sce_paf_free(tmp); + return; + } + *sptr = 0; + sptr = sce_paf_strrchr(tmp, '/'); + if (!sptr) + { + sptr = sce_paf_strchr(tmp, ':'); + } + sptr += 1; + *sptr = 0; + path = tmp; + sce_paf_free(tmp); + } + else + { + path += ref; + } + } + else + { + path.clear(); + } +} + +vector *LocalServerBrowser::GoTo(const char *ref, SceInt32 *result) +{ + vector *ret = new vector; + CURLcode cret; + + SetPath(ref); + + SCE_DBG_LOG_INFO("[LOCAL] Attempt to open %s\n", path.c_str()); + + if (ref) + { + Dir dir; + Dir::Entry dentry; + + if (dir.Open(path.c_str()) >= 0) + { + while (dir.Read(&dentry) >= 0) + { + BEAVPlayer::SupportType beavType = BEAVPlayer::IsSupported(dentry.name.c_str()); + + if (beavType != BEAVPlayer::SupportType_NotSupported) + { + LocalServerBrowser::Entry *entry = new LocalServerBrowser::Entry(); + entry->ref = dentry.name.c_str(); + entry->type = LocalServerBrowser::Entry::Type_UnsupportedFile; + + if (beavType == BEAVPlayer::SupportType_MaybeSupported) + { + entry->ref += "/"; + entry->type = LocalServerBrowser::Entry::Type_Folder; + } + else if (beavType == BEAVPlayer::SupportType_Supported) + { + entry->type = LocalServerBrowser::Entry::Type_SupportedFile; + } + + ret->push_back(entry); + } + } + + dir.Close(); + + *result = SCE_OK; + } + else + { + *result = SCE_ERROR_ERRNO_ENOENT; + } + } + else + { + for (int i = 0; i < sizeof(k_supportedRoots) / sizeof(char *); i++) + { + if (LocalFile::Exists(k_supportedRoots[i])) + { + LocalServerBrowser::Entry *entry = new LocalServerBrowser::Entry(); + entry->ref = k_supportedRoots[i]; + entry->type = LocalServerBrowser::Entry::Type_Folder; + ret->push_back(entry); + } + } + + *result = SCE_OK; + } + + return ret; +} \ No newline at end of file diff --git a/NetStream/source/menus/menu_first.cpp b/NetStream/source/menus/menu_first.cpp index 490c8a5..2bd0d59 100644 --- a/NetStream/source/menus/menu_first.cpp +++ b/NetStream/source/menus/menu_first.cpp @@ -5,6 +5,7 @@ #include "utils.h" #include "menus/menu_first.h" #include "menus/menu_http.h" +#include "menus/menu_local.h" #include "menus/menu_youtube.h" #include "menus/menu_settings.h" @@ -23,6 +24,10 @@ SceVoid menu::First::ListButtonCbFun(SceInt32 eventId, ui::Widget *self, SceInt3 menu::Http *hmenu = new menu::Http(); hmenu->PushBrowserPage(SCE_NULL); break; + /*case 2: + menu::Local *lmenu = new menu::Local(); + lmenu->PushBrowserPage(SCE_NULL); + break;*/ } } diff --git a/NetStream/source/menus/menu_local.cpp b/NetStream/source/menus/menu_local.cpp new file mode 100644 index 0000000..220bcd6 --- /dev/null +++ b/NetStream/source/menus/menu_local.cpp @@ -0,0 +1,305 @@ +#include +#include + +#include "common.h" +#include "utils.h" +#include "dialog.h" +#include "beav_player.h" +#include "local_server_browser.h" +#include "menus/menu_local.h" +#include "menus/menu_settings.h" +#include "menus/menu_player_simple.h" + +using namespace paf; + +SceVoid menu::Local::PlayerBackCb(PlayerSimple *player, ScePVoid pUserArg) +{ + delete player; +} + +SceVoid menu::Local::PlayerFailCb(PlayerSimple *player, ScePVoid pUserArg) +{ + dialog::OpenError(g_appPlugin, SCE_ERROR_ERRNO_EUNSUP, utils::GetString("msg_error_load_file")); + delete player; +} + +SceVoid menu::Local::BackButtonCbFun(SceInt32 eventId, ui::Widget *self, SceInt32 a3, ScePVoid pUserData) +{ + Local *workObj = (Local *)pUserData; + + workObj->PopBrowserPage(); + if (workObj->pageList.empty()) + { + delete workObj; + } +} + +SceVoid menu::Local::ListButtonCbFun(SceInt32 eventId, ui::Widget *self, SceInt32 a3, ScePVoid pUserData) +{ + Local *workObj = (Local *)pUserData; + BrowserPage *workPage = workObj->pageList.back(); + LocalServerBrowser::Entry *entry = workPage->itemList->at(self->elem.hash); + + if (entry->type == LocalServerBrowser::Entry::Type_Folder) + { + workObj->PushBrowserPage(&entry->ref); + } + else if (entry->type == LocalServerBrowser::Entry::Type_SupportedFile) + { + new menu::PlayerSimple(workObj->browser->GetBEAVUrl(&entry->ref).c_str(), SCE_NULL, PlayerFailCb, PlayerBackCb, pUserData); + } +} + +ui::ListItem *menu::Local::ListViewCb::Create(Param *info) +{ + rco::Element searchParam; + Plugin::TemplateOpenParam tmpParam; + ui::Widget *item = SCE_NULL; + graph::Surface *tex = SCE_NULL; + wstring text16; + + BrowserPage *workPage = workObj->pageList.back(); + + LocalServerBrowser::Entry *entry = workPage->itemList->at(info->cellIndex); + ui::Widget *targetRoot = info->parent; + + searchParam.hash = template_list_item_generic; + g_appPlugin->TemplateOpen(targetRoot, &searchParam, &tmpParam); + item = targetRoot->GetChild(targetRoot->childNum - 1); + + ui::Widget *button = utils::GetChild(item, image_button_list_item); + button->elem.hash = info->cellIndex; + + ccc::UTF8toUTF16(&entry->ref, &text16); + button->SetLabel(&text16); + button->RegisterEventCallback(ui::EventMain_Decide, new utils::SimpleEventCallback(ListButtonCbFun, workObj)); + + switch (entry->type) + { + case LocalServerBrowser::Entry::Type_UnsupportedFile: + tex = utils::GetTexture(tex_file_icon_unsupported); + break; + case LocalServerBrowser::Entry::Type_SupportedFile: + tex = utils::GetTexture(tex_file_icon_video); + break; + case LocalServerBrowser::Entry::Type_Folder: + tex = utils::GetTexture(tex_file_icon_folder); + break; + } + + button->SetSurfaceBase(&tex); + tex->Release(); + + return (ui::ListItem *)item; +} + +SceVoid menu::Local::GoToJob::ConnectionFailedDialogHandler(dialog::ButtonCode buttonCode, ScePVoid pUserArg) +{ + Local *workObj = (Local *)pUserArg; + workObj->PopBrowserPage(); + menu::SettingsButtonCbFun(ui::EventMain_Decide, SCE_NULL, 0, SCE_NULL); + if (workObj->pageList.empty()) + { + delete workObj; + } + menu::GenericMenu *topMenu = menu::GetTopMenu(); + if (topMenu) { + ui::Widget::SetControlFlags(topMenu->root, 0); + } +} + +SceVoid menu::Local::GoToJob::Run() +{ + SceInt32 ret = SCE_OK; + string currentPath; + wstring text16; + + thread::s_mainThreadMutex.Lock(); + workObj->loaderIndicator->Start(); + thread::s_mainThreadMutex.Unlock(); + + BrowserPage *workPage = workObj->pageList.back(); + + if (targetRef.length() == 0) + { + workPage->itemList = workObj->browser->GoTo(SCE_NULL, &ret); + } + else + { + workPage->itemList = workObj->browser->GoTo(targetRef.c_str(), &ret); + } + if (ret != SCE_OK) + { + thread::s_mainThreadMutex.Lock(); + workObj->loaderIndicator->Stop(); + thread::s_mainThreadMutex.Unlock(); + workPage->isLoaded = SCE_TRUE; + dialog::OpenError(g_appPlugin, ret, utils::GetString("msg_error_load_file"), ConnectionFailedDialogHandler, workObj); + return; + } + if (workObj->firstBoot) + { + ui::Widget *backButton = utils::GetChild(workObj->root, button_back_page_local); + ui::Widget *settingsButton = utils::GetChild(workObj->root, button_settings_page_local); + thread::s_mainThreadMutex.Lock(); + backButton->PlayEffect(0.0f, effect::EffectType_Reset); + settingsButton->PlayEffect(0.0f, effect::EffectType_Reset); + thread::s_mainThreadMutex.Unlock(); + workObj->firstBoot = SCE_FALSE; + } + + currentPath = workObj->browser->GetPath(); + ccc::UTF8toUTF16(¤tPath, &text16); + + thread::s_mainThreadMutex.Lock(); + workObj->loaderIndicator->Stop(); + workPage->list->AddItem(0, 0, workPage->itemList->size()); + workObj->topText->SetLabel(&text16); + thread::s_mainThreadMutex.Unlock(); + + workPage->isLoaded = SCE_TRUE; +} + +menu::Local::Local() : + GenericMenu("page_local", + MenuOpenParam(false, 200.0f, Plugin::PageEffectType_SlideFromBottom), + MenuCloseParam(false, 200.0f, Plugin::PageEffectType_SlideFromBottom)) +{ + rco::Element searchParam; + Plugin::TemplateOpenParam tmpParam; + firstBoot = SCE_TRUE; + + ui::Widget *settingsButton = utils::GetChild(root, button_settings_page_local); + settingsButton->PlayEffectReverse(0.0f, effect::EffectType_Reset); + settingsButton->RegisterEventCallback(ui::EventMain_Decide, new utils::SimpleEventCallback(menu::SettingsButtonCbFun)); + + ui::Widget *backButton = utils::GetChild(root, button_back_page_local); + backButton->PlayEffectReverse(0.0f, effect::EffectType_Reset); + backButton->RegisterEventCallback(ui::EventMain_Decide, new utils::SimpleEventCallback(BackButtonCbFun, this)); + + browserRoot = utils::GetChild(root, plane_browser_root_page_local); + loaderIndicator = (ui::BusyIndicator *)utils::GetChild(root, busyindicator_loader_page_local); + topText = (ui::Text *)utils::GetChild(root, text_top); + + browser = new LocalServerBrowser(); +} + +menu::Local::~Local() +{ + while (PopBrowserPage()) + { + + } + + delete browser; +} + +SceBool menu::Local::PushBrowserPage(string *ref) +{ + rco::Element searchParam; + Plugin::TemplateOpenParam tmpParam; + + BrowserPage *page = new BrowserPage(); + + searchParam.hash = template_list_view_generic; + g_appPlugin->TemplateOpen(browserRoot, &searchParam, &tmpParam); + page->list = (ui::ListView *)browserRoot->GetChild(browserRoot->childNum - 1); + ListViewCb *lwCb = new ListViewCb(); + lwCb->workObj = this; + page->list->RegisterItemCallback(lwCb); + page->list->SetSegmentEnable(0, 1); + Vector4 sz(960.0f, 80.0f); + page->list->SetCellSize(0, &sz); + page->list->SetConfigurationType(0, ui::ListView::ConfigurationType_Simple); + + BrowserPage *wp; + if (!pageList.empty()) { + if (pageList.size() > 1) { + wp = pageList.rbegin()[1]; + wp->list->PlayEffectReverse(0.0f, effect::EffectType_Reset); + if (wp->list->animationStatus & 0x80) + wp->list->animationStatus &= ~0x80; + } + wp = pageList.back(); + wp->list->PlayEffect(0.0f, effect::EffectType_3D_SlideToBack1); + if (wp->list->animationStatus & 0x80) + wp->list->animationStatus &= ~0x80; + } + + pageList.push_back(page); + + GoToJob *job = new GoToJob("Local::GoToJob"); + job->workObj = this; + if (ref) + { + job->targetRef = *ref; + } + SharedPtr itemParam(job); + utils::GetJobQueue()->Enqueue(&itemParam); + + return SCE_TRUE; +} + +SceBool menu::Local::PopBrowserPage() +{ + BrowserPage *pageToPop; + SceBool isLastPage = SCE_FALSE; + + if (pageList.empty()) + { + return SCE_FALSE; + } + else if (pageList.size() == 1) + { + isLastPage = SCE_TRUE; + } + + pageToPop = pageList.back(); + while (!pageToPop->isLoaded) + { + thread::Sleep(10); + } + + if (!isLastPage) + { + effect::Play(-100.0f, pageToPop->list, effect::EffectType_3D_SlideFromFront, true, false); + } + + for (int i = 0; i < pageToPop->itemList->size(); i++) + { + delete pageToPop->itemList->at(i); + } + + delete pageToPop->itemList; + delete pageToPop; + pageList.pop_back(); + + if (!isLastPage) + { + BrowserPage *wp; + if (!pageList.empty()) { + wp = pageList.back(); + wp->list->PlayEffectReverse(0.0f, effect::EffectType_3D_SlideToBack1); + wp->list->PlayEffect(0.0f, effect::EffectType_Reset); + if (wp->list->animationStatus & 0x80) + wp->list->animationStatus &= ~0x80; + if (pageList.size() > 1) { + wp = pageList.rbegin()[1]; + wp->list->PlayEffect(0.0f, effect::EffectType_Reset); + if (wp->list->animationStatus & 0x80) + wp->list->animationStatus &= ~0x80; + } + } + } + + if (!isLastPage) + { + browser->SetPath(".."); + string currentPath = browser->GetPath(); + wstring text16; + ccc::UTF8toUTF16(¤tPath, &text16); + topText->SetLabel(&text16); + } + + return SCE_TRUE; +} \ No newline at end of file diff --git a/NetStream/source/menus/menu_player.cpp b/NetStream/source/menus/menu_player.cpp deleted file mode 100644 index 293bb67..0000000 --- a/NetStream/source/menus/menu_player.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include -#include - -#include "common.h" -#include "main.h" -#include "menus/menu_player.h" -#include "dialog.h" -#include "utils.h" -#include "yt_utils.h" -#include "beav_player.h" - -using namespace paf; - -static ui::Widget *s_playerPage = SCE_NULL; - -menu::player::Player::Player(const char *id) -{ - rco::Element searchParam; - Plugin::PageInitParam rwiParam; - Plugin::TemplateInitParam tmpParam; - ui::Widget *corePlane = SCE_NULL; - - g_rootPage->PlayEffectReverse(100.0f, effect::EffectType_Fadein1, SCE_NULL); - - // Create player scene - searchParam.hash = utils::GetHash("page_player"); - s_playerPage = g_appPlugin->PageOpen(&searchParam, &rwiParam); - - searchParam.hash = utils::GetHash("plane_player_core"); - corePlane = s_playerPage->GetChild(&searchParam, 0); - - InvItemVideo *vid; - - invParseVideo(id, &vid); - - BEAVPlayer *beavPlayer = SCE_NULL; - SceInt32 reqQuality = menu::settings::Settings::GetInstance()->quality; - if (reqQuality == 0) - beavPlayer = new BEAVPlayer(corePlane, vid->avcLqUrl); - else - beavPlayer = new BEAVPlayer(corePlane, vid->avcHqUrl); - - if (!beavPlayer->GetResult()) { - delete beavPlayer; - if (reqQuality == 0) - beavPlayer = new BEAVPlayer(corePlane, vid->avcHqUrl); - else - beavPlayer = new BEAVPlayer(corePlane, vid->avcLqUrl); - - if (!beavPlayer->GetResult()) { - delete beavPlayer; - // cannot play this video - } - } -} - -menu::player::Player::~Player() -{ - -} \ No newline at end of file diff --git a/NetStream/source/menus/menu_settings.cpp b/NetStream/source/menus/menu_settings.cpp index 03d36c3..2ef6bc3 100644 --- a/NetStream/source/menus/menu_settings.cpp +++ b/NetStream/source/menus/menu_settings.cpp @@ -78,7 +78,7 @@ SceVoid menu::Settings::Init() *verinfo = L"RELEASE "; #endif *verinfo += WIDE(__DATE__); - *verinfo += L" v 1.00"; + *verinfo += L" v 1.01"; s_verinfo = (wchar_t *)verinfo->c_str(); } diff --git a/NetStream/source/menus/menu_youtube.cpp b/NetStream/source/menus/menu_youtube.cpp index 0b583c9..aa8c144 100644 --- a/NetStream/source/menus/menu_youtube.cpp +++ b/NetStream/source/menus/menu_youtube.cpp @@ -294,6 +294,7 @@ SceVoid menu::YouTube::SearchSubmenu::GoToNextPage() SearchJob *job = new SearchJob("YouTube::SearchJob"); job->workObj = this; + job->isId = SCE_FALSE; SharedPtr itemParam(job); allJobsComplete = SCE_FALSE; utils::GetJobQueue()->Enqueue(&itemParam); @@ -306,6 +307,7 @@ SceVoid menu::YouTube::SearchSubmenu::GoToPrevPage() SearchJob *job = new SearchJob("YouTube::SearchJob"); job->workObj = this; + job->isId = SCE_FALSE; SharedPtr itemParam(job); allJobsComplete = SCE_FALSE; utils::GetJobQueue()->Enqueue(&itemParam); diff --git a/NetStream/source/menus/menu_youtube_fav.cpp b/NetStream/source/menus/menu_youtube_fav.cpp deleted file mode 100644 index 971252f..0000000 --- a/NetStream/source/menus/menu_youtube_fav.cpp +++ /dev/null @@ -1,337 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "menus/menu_youtube.h" -#include "utils.h" -#include "yt_utils.h" -#include "invidious.h" - -using namespace paf; - -static menu::youtube::FavPage *s_currentFavPage = SCE_NULL; - -SceVoid menu::youtube::FavParserThread::CreateVideoButton(FavPage *page, const char *data, SceUInt32 index, const char *keyWord) -{ - SceInt32 res; - wstring title16; - wstring subtext16; - string text8; - InvItemVideo *vidInfo; - rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; - ui::Widget *box; - ui::Widget *button; - ui::Widget *subtext; - VideoButtonCB *buttonCB; - SharedPtr fres; - graph::Surface *tmbTex; - - res = invParseVideo(data, &vidInfo); - if (res != 1) - return; - - if (keyWord) { - if (!sce_paf_strstr(vidInfo->title, keyWord)) { - invCleanupVideo(vidInfo); - return; - } - else { - dialog::Close(); - } - } - - searchParam.hash = utils::GetHash("youtube_scroll_box"); - box = page->thisPage->GetChild(&searchParam, 0); - - searchParam.hash = utils::GetHash("menu_template_youtube_result_button"); - thread::s_mainThreadMutex.Lock(); - g_appPlugin->TemplateOpen(box, &searchParam, &tmpParam); - thread::s_mainThreadMutex.Unlock(); - - button = (ui::ImageButton *)box->GetChild(box->childNum - 1); - - searchParam.hash = utils::GetHash("yt_text_button_subtext"); - subtext = button->GetChild(&searchParam, 0); - - text8 = vidInfo->title; - ccc::UTF8toUTF16(&text8, &title16); - - utils::ConvertSecondsToString(&text8, (SceUInt64)vidInfo->lengthSec, SCE_FALSE); - text8 += " | "; - text8 += vidInfo->author; - text8 += " | "; - text8 += vidInfo->published; - ccc::UTF8toUTF16(&text8, &subtext16); - - thread::s_mainThreadMutex.Lock(); - buttonCB = new VideoButtonCB; - buttonCB->pUserData = buttonCB; - buttonCB->mode = menu::youtube::Base::Mode_Fav; - buttonCB->id = vidInfo->id; - - button->SetLabel(&title16); - subtext->SetLabel(&subtext16); - button->RegisterEventCallback(ui::EventMain_Decide, buttonCB, 0); - thread::s_mainThreadMutex.Unlock(); - - fres = HttpFile::Open(vidInfo->thmbUrl, &res, 0); - invCleanupVideo(vidInfo); - if (res < 0) { - return; - } - - graph::Surface::Create(&tmbTex, g_appPlugin->memoryPool, (SharedPtr*)&fres); - - fres.reset(); - - if (tmbTex == SCE_NULL) { - return; - } - - thread::s_mainThreadMutex.Lock(); - tmbTex->UnsafeRelease(); - button->SetSurfaceBase(&tmbTex); - thread::s_mainThreadMutex.Unlock(); -} - -SceVoid menu::youtube::FavParserThread::EntryFunction() -{ - rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; - ui::Widget *commonWidget; - SceUInt32 prevResNum = 0; - SceInt32 parseRes = 0; - char key[SCE_INI_FILE_PROCESSOR_KEY_BUFFER_SIZE]; - - ytutils::GetFavLog()->Reset(); - - if (prevPage) { - prevResNum = prevPage->resNum; - for (SceInt32 i = 0; i < prevResNum; i++) { - ytutils::GetFavLog()->GetNext(key); - } - } - - searchParam.hash = utils::GetHash("yt_button_btmenu_right"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffectReverse(0.0f, effect::EffectType_Fadein1); - - searchParam.hash = utils::GetHash("yt_button_btmenu_left"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffectReverse(0.0f, effect::EffectType_Fadein1); - - searchParam.hash = utils::GetHash("menu_template_youtube"); - g_appPlugin->TemplateOpen(g_root, &searchParam, &tmpParam); - - searchParam.hash = utils::GetHash("plane_youtube_bg"); - workPage->thisPage = (ui::Plane *)g_root->GetChild(&searchParam, 0); - workPage->thisPage->elem.hash = (SceUInt32)workPage->thisPage; - - if (workPage->prev != SCE_NULL) { - if (workPage->prev->prev != SCE_NULL) { - workPage->prev->prev->thisPage->PlayEffectReverse(0.0f, effect::EffectType_Reset); - if (workPage->prev->prev->thisPage->animationStatus & 0x80) - workPage->prev->prev->thisPage->animationStatus &= ~0x80; - } - workPage->prev->thisPage->PlayEffect(0.0f, effect::EffectType_3D_SlideToBack1); - if (workPage->prev->thisPage->animationStatus & 0x80) - workPage->prev->thisPage->animationStatus &= ~0x80; - } - workPage->thisPage->PlayEffect(-5000.0f, effect::EffectType_3D_SlideFromFront); - if (workPage->thisPage->animationStatus & 0x80) - workPage->thisPage->animationStatus &= ~0x80; - - if (prevPage) { - searchParam.hash = utils::GetHash("yt_button_btmenu_left"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffect(0.0f, effect::EffectType_Fadein1); - } - - if (keyWord.length()) { - while (1) { - ytutils::WaitMenuParsers(); - if (IsCanceled()) { - Cancel(); - return; - } - parseRes = ytutils::GetFavLog()->GetNext(key); - if (parseRes) { - break; - } - CreateVideoButton(workPage, key, 0, keyWord.c_str()); - workPage->resNum++; - } - } - else { - for (SceInt32 i = prevResNum; i < menu::youtube::FavPage::k_resPerPage + prevResNum; i++) { - ytutils::WaitMenuParsers(); - if (IsCanceled()) { - Cancel(); - return; - } - parseRes = ytutils::GetFavLog()->GetNext(key); - if (parseRes) { - break; - } - CreateVideoButton(workPage, key, i, SCE_NULL); - workPage->resNum++; - } - - if (!parseRes) { - searchParam.hash = utils::GetHash("yt_button_btmenu_right"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffect(0.0f, effect::EffectType_Fadein1); - } - } - - dialog::Close(); - - Cancel(); -} - -SceVoid menu::youtube::FavPage::SearchActionButtonOp() -{ - rco::Element searchParam; - ui::TextBox *searchBox; - wstring text16; - string text8; - - dialog::OpenPleaseWait(g_appPlugin, SCE_NULL, utils::GetString("msg_wait"), SCE_TRUE); - - // In destructor s_current(...)Page->prev is assigned to s_current(...)Page - while (s_currentFavPage) { - delete s_currentFavPage; - } - - searchParam.hash = utils::GetHash("yt_text_box_top_search"); - searchBox = (ui::TextBox *)g_rootPage->GetChild(&searchParam, 0); - - searchBox->GetLabel(&text16); - - if (text16.length() != 0) { - - ccc::UTF16toUTF8(&text16, &text8); - - new FavPage(text8.c_str()); - } -} - -// Constructor for first page -menu::youtube::FavPage::FavPage() -{ - prev = SCE_NULL; - next = SCE_NULL; - parserThread = SCE_NULL; - resNum = 0; - - thread::Sleep(100); - parserThread = new FavParserThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_256KiB, "NS::YtFavParser"); - parserThread->prevPage = SCE_NULL; - parserThread->workPage = this; - parserThread->Start(); - - s_currentFavPage = this; -} - -// Constructor for next page -menu::youtube::FavPage::FavPage(FavPage *prevPage) -{ - prev = prevPage; - next = SCE_NULL; - parserThread = SCE_NULL; - resNum = 0; - - thread::Sleep(100); - if (prevPage) - prev->parserThread->Join(); - - parserThread = new FavParserThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_256KiB, "NS::YtFavParser"); - parserThread->prevPage = prevPage; - parserThread->workPage = this; - parserThread->Start(); - - s_currentFavPage = this; -} - -// Constructor for search page -menu::youtube::FavPage::FavPage(const char *keyWord) -{ - prev = SCE_NULL; - next = SCE_NULL; - parserThread = SCE_NULL; - resNum = 0; - - parserThread = new FavParserThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_256KiB, "EMPVA::YtFavParser"); - parserThread->prevPage = SCE_NULL; - parserThread->workPage = this; - parserThread->keyWord = keyWord; - parserThread->Start(); - - s_currentFavPage = this; -} - -menu::youtube::FavPage::~FavPage() -{ - rco::Element searchParam; - ui::Widget *commonWidget; - - parserThread->Cancel(); - thread::s_mainThreadMutex.Unlock(); - parserThread->Join(); - thread::s_mainThreadMutex.Lock(); - delete parserThread; - - effect::Play(-100.0f, thisPage, effect::EffectType_3D_SlideFromFront, SCE_TRUE, SCE_FALSE); - if (prev != SCE_NULL) { - prev->thisPage->PlayEffectReverse(0.0f, effect::EffectType_3D_SlideToBack1); - prev->thisPage->PlayEffect(0.0f, effect::EffectType_Reset); - if (prev->thisPage->animationStatus & 0x80) - prev->thisPage->animationStatus &= ~0x80; - if (prev->prev != SCE_NULL) { - prev->prev->thisPage->PlayEffect(0.0f, effect::EffectType_Reset); - if (prev->prev->thisPage->animationStatus & 0x80) - prev->prev->thisPage->animationStatus &= ~0x80; - } - else { - searchParam.hash = utils::GetHash("yt_button_btmenu_left"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffectReverse(0.0f, effect::EffectType_Fadein1); - } - } - - searchParam.hash = utils::GetHash("yt_button_btmenu_right"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffect(0.0f, effect::EffectType_Fadein1); - - s_currentFavPage = prev; -} - -SceVoid menu::youtube::FavPage::LeftButtonOp() -{ - delete s_currentFavPage; -} - -SceVoid menu::youtube::FavPage::RightButtonOp() -{ - new FavPage(s_currentFavPage); -} - -SceVoid menu::youtube::FavPage::TermOp() -{ - rco::Element searchParam; - ui::Widget *commonWidget; - - // In destructor s_current(...)Page->prev is assigned to s_current(...)Page - while (s_currentFavPage) { - delete s_currentFavPage; - } - - searchParam.hash = utils::GetHash("yt_button_btmenu_right"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffectReverse(0.0f, effect::EffectType_Fadein1); -} \ No newline at end of file diff --git a/NetStream/source/menus/menu_youtube_history.cpp b/NetStream/source/menus/menu_youtube_history.cpp deleted file mode 100644 index 821c7ae..0000000 --- a/NetStream/source/menus/menu_youtube_history.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "common.h" -#include "menus/menu_youtube.h" -#include "utils.h" -#include "yt_utils.h" -#include "invidious.h" - -using namespace paf; - -static menu::youtube::HistoryPage *s_currentHistoryPage = SCE_NULL; - -SceVoid menu::youtube::HistoryParserThread::CreateVideoButton(HistoryPage *page, const char *data, SceUInt32 index) -{ - SceInt32 res; - wstring title16; - wstring subtext16; - string text8; - InvItemVideo *vidInfo; - rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; - ui::Widget *box; - ui::Widget *button; - ui::Widget *subtext; - VideoButtonCB *buttonCB; - SharedPtr fres; - graph::Surface *tmbTex; - - searchParam.hash = utils::GetHash("youtube_scroll_box"); - box = page->thisPage->GetChild(&searchParam, 0); - - searchParam.hash = utils::GetHash("menu_template_youtube_result_button"); - thread::s_mainThreadMutex.Lock(); - g_appPlugin->TemplateOpen(box, &searchParam, &tmpParam); - thread::s_mainThreadMutex.Unlock(); - - button = (ui::ImageButton *)box->GetChild(box->childNum - 1); - - searchParam.hash = utils::GetHash("yt_text_button_subtext"); - subtext = button->GetChild(&searchParam, 0); - - res = invParseVideo(data, &vidInfo); - if (res != 1) - return; - - //TODO: playlist - /* - if (vidInfo->playlist.videos.size()) { - - sce_paf_memset(vidCount, 0, sizeof(vidCount)); - - text8 = vidInfo->playlist.title.c_str(); - ccc::UTF8toUTF16(&text8, &title16); - - sce_paf_snprintf(vidCount, sizeof(vidCount), "Playlist, %d videos ", vidInfo->playlist.videos.size()); - text8 = vidCount; - text8 += vidInfo->playlist.author_name.c_str(); - ccc::UTF8toUTF16(&text8, &subtext16); - - sce_paf_strncpy(tmb, vidInfo->playlist.videos[0].thumbnail_url.c_str(), sizeof(tmb)); - } - else - */ - { - text8 = vidInfo->title; - ccc::UTF8toUTF16(&text8, &title16); - - utils::ConvertSecondsToString(&text8, (SceUInt64)vidInfo->lengthSec, SCE_FALSE); - text8 += " | "; - text8 += vidInfo->author; - text8 += " | "; - text8 += vidInfo->published; - ccc::UTF8toUTF16(&text8, &subtext16); - } - - thread::s_mainThreadMutex.Lock(); - buttonCB = new VideoButtonCB; - buttonCB->pUserData = buttonCB; - buttonCB->mode = menu::youtube::Base::Mode_History; - buttonCB->id = vidInfo->id; - - button->SetLabel(&title16); - subtext->SetLabel(&subtext16); - button->RegisterEventCallback(ui::EventMain_Decide, buttonCB, 0); - thread::s_mainThreadMutex.Unlock(); - - fres = HttpFile::Open(vidInfo->thmbUrl, &res, 0); - invCleanupVideo(vidInfo); - if (res < 0) { - return; - } - - graph::Surface::Create(&tmbTex, g_appPlugin->memoryPool, (SharedPtr*)&fres); - - fres.reset(); - - if (tmbTex == SCE_NULL) { - return; - } - - thread::s_mainThreadMutex.Lock(); - tmbTex->UnsafeRelease(); - button->SetSurfaceBase(&tmbTex); - thread::s_mainThreadMutex.Unlock(); -} - -SceVoid menu::youtube::HistoryParserThread::EntryFunction() -{ - rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; - char *entryData; - - ytutils::GetHistLog()->Reset(); - SceInt32 totalNum = ytutils::GetHistLog()->GetSize(); - - entryData = (char *)sce_paf_calloc(totalNum, SCE_INI_FILE_PROCESSOR_KEY_BUFFER_SIZE); - - for (SceInt32 i = 0; i < totalNum; i++) { - ytutils::GetHistLog()->GetNext(entryData + (i * SCE_INI_FILE_PROCESSOR_KEY_BUFFER_SIZE)); - } - - searchParam.hash = utils::GetHash("menu_template_youtube"); - g_appPlugin->TemplateOpen(g_root, &searchParam, &tmpParam); - - searchParam.hash = utils::GetHash("plane_youtube_bg"); - workPage->thisPage = (ui::Plane *)g_root->GetChild(&searchParam, 0); - workPage->thisPage->elem.hash = (SceUInt32)workPage->thisPage; - - workPage->thisPage->PlayEffect(-5000.0f, effect::EffectType_3D_SlideFromFront); - if (workPage->thisPage->animationStatus & 0x80) - workPage->thisPage->animationStatus &= ~0x80; - - for (SceInt32 i = totalNum - 1; i != -1; i--) { - ytutils::WaitMenuParsers(); - if (IsCanceled()) { - break; - } - CreateVideoButton(workPage, entryData + (i * SCE_INI_FILE_PROCESSOR_KEY_BUFFER_SIZE), i); - } - - sce_paf_free(entryData); - - Cancel(); -} - -menu::youtube::HistoryPage::HistoryPage() -{ - parserThread = SCE_NULL; - - parserThread = new HistoryParserThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_256KiB, "EMPVA::YtHistoryParser"); - parserThread->workPage = this; - parserThread->Start(); - - s_currentHistoryPage = this; -} - -menu::youtube::HistoryPage::~HistoryPage() -{ - parserThread->Cancel(); - thread::s_mainThreadMutex.Unlock(); - parserThread->Join(); - thread::s_mainThreadMutex.Lock(); - delete parserThread; - - effect::Play(-100.0f, thisPage, effect::EffectType_3D_SlideFromFront, SCE_TRUE, SCE_FALSE); - - s_currentHistoryPage = SCE_NULL; -} - -SceVoid menu::youtube::HistoryPage::TermOp() -{ - delete s_currentHistoryPage; -} \ No newline at end of file diff --git a/NetStream/source/menus/menu_youtube_search.cpp b/NetStream/source/menus/menu_youtube_search.cpp deleted file mode 100644 index 6f57a0b..0000000 --- a/NetStream/source/menus/menu_youtube_search.cpp +++ /dev/null @@ -1,329 +0,0 @@ -#include -#include -#include -#include -#include - -#include "common.h" -#include "menus/menu_youtube.h" -#include "utils.h" -#include "yt_utils.h" -#include "invidious.h" - -using namespace paf; - -static menu::youtube::SearchPage *s_currentSearchPage = SCE_NULL; - -SceVoid menu::youtube::SearchParserThread::CreateVideoButton(SearchPage *page, SceUInt32 index) -{ - SceInt32 res; - wstring title16; - wstring subtext16; - string text8; - rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; - ui::Widget *box; - ui::Widget *button; - ui::Widget *subtext; - VideoButtonCB *buttonCB; - SharedPtr fres; - graph::Surface *tmbTex; - - if (page->parseResult[index].type == INV_ITEM_TYPE_CHANNEL || - page->parseResult[index].type == INV_ITEM_TYPE_PLAYLIST) - return; - - if (page->parseResult[index].type == INV_ITEM_TYPE_VIDEO) { - if (page->parseResult[index].videoItem->lengthSec == 0) //livestream - return; - } - - searchParam.hash = utils::GetHash("youtube_scroll_box"); - box = page->thisPage->GetChild(&searchParam, 0); - - searchParam.hash = utils::GetHash("menu_template_youtube_result_button"); - thread::s_mainThreadMutex.Lock(); - g_appPlugin->TemplateOpen(box, &searchParam, &tmpParam); - thread::s_mainThreadMutex.Unlock(); - - button = (ui::ImageButton *)box->GetChild(box->childNum - 1); - - searchParam.hash = utils::GetHash("yt_text_button_subtext"); - subtext = button->GetChild(&searchParam, 0); - - if (page->parseResult[index].type == INV_ITEM_TYPE_VIDEO) { - - text8 = page->parseResult[index].videoItem->title; - ccc::UTF8toUTF16(&text8, &title16); - - - text8.clear(); - utils::ConvertSecondsToString(&text8, (SceUInt64)page->parseResult[index].videoItem->lengthSec, SCE_FALSE); - text8 += " | "; - text8 += page->parseResult[index].videoItem->author; - text8 += " | "; - text8 += page->parseResult[index].videoItem->published; - ccc::UTF8toUTF16(&text8, &subtext16); - - fres = HttpFile::Open(page->parseResult[index].videoItem->thmbUrl, &res, 0); - - thread::s_mainThreadMutex.Lock(); - buttonCB = new VideoButtonCB; - buttonCB->pUserData = buttonCB; - buttonCB->mode = menu::youtube::Base::Mode_Search; - buttonCB->id = page->parseResult[index].videoItem->id; - - button->SetLabel(&title16); - subtext->SetLabel(&subtext16); - button->RegisterEventCallback(ui::EventMain_Decide, buttonCB, 0); - thread::s_mainThreadMutex.Unlock(); - } - //TODO: playlist - /* - else if (page->parseResult->results[index].type == YouTubeSuccinctItem::PLAYLIST) { - - text8 = page->parseResult->results[index].playlist.title.c_str(); - ccc::UTF8toUTF16(&text8, &title16); - - text8 = "Playlist, "; - text8 += page->parseResult->results[index].playlist.video_count_str.c_str(); - ccc::UTF8toUTF16(&text8, &subtext16); - - fres = HttpFile::Open(page->parseResult->results[index].playlist.thumbnail_url.c_str(), &res, 0); - - buttonCB = new VideoButtonCB; - buttonCB->pUserData = buttonCB; - buttonCB->mode = menu::youtube::Base::Mode_Search; - buttonCB->url = page->parseResult->results[index].playlist.url.c_str(); - - thread::s_mainThreadMutex.Lock(); - button->SetLabel(&title16); - subtext->SetLabel(&subtext16); - button->RegisterEventCallback(ui::EventMain_Decide, buttonCB, 0); - thread::s_mainThreadMutex.Unlock(); - } - */ - - if (res < 0) { - return; - } - - graph::Surface::Create(&tmbTex, g_appPlugin->memoryPool, (SharedPtr*)&fres); - - fres.reset(); - - if (tmbTex == SCE_NULL) { - return; - } - - thread::s_mainThreadMutex.Lock(); - tmbTex->UnsafeRelease(); - button->SetSurfaceBase(&tmbTex); - thread::s_mainThreadMutex.Unlock(); -} - -SceVoid menu::youtube::SearchParserThread::EntryFunction() -{ - rco::Element searchParam; - Plugin::TemplateInitParam tmpParam; - ui::Widget *commonWidget; - - searchParam.hash = utils::GetHash("yt_button_btmenu_right"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffectReverse(0.0f, effect::EffectType_Fadein1); - - searchParam.hash = utils::GetHash("yt_button_btmenu_left"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffectReverse(0.0f, effect::EffectType_Fadein1); - - workPage->resultCount = invParseSearch( - newRequset.c_str(), workPage->pageNum, - INV_ITEM_TYPE_VIDEO, - (InvSort)menu::settings::Settings::GetInstance()->searchSort, - (InvDate)menu::settings::Settings::GetInstance()->searchDate, - &workPage->parseResult); - - if (workPage->resultCount < 0) - workPage->resultCount = 0; - - searchParam.hash = utils::GetHash("menu_template_youtube"); - g_appPlugin->TemplateOpen(g_root, &searchParam, &tmpParam); - - searchParam.hash = utils::GetHash("plane_youtube_bg"); - workPage->thisPage = (ui::Plane *)g_root->GetChild(&searchParam, 0); - workPage->thisPage->elem.hash = (SceUInt32)workPage->thisPage; - - if (workPage->prev != SCE_NULL) { - if (workPage->prev->prev != SCE_NULL) { - workPage->prev->prev->thisPage->PlayEffectReverse(0.0f, effect::EffectType_Reset); - if (workPage->prev->prev->thisPage->animationStatus & 0x80) - workPage->prev->prev->thisPage->animationStatus &= ~0x80; - } - workPage->prev->thisPage->PlayEffect(0.0f, effect::EffectType_3D_SlideToBack1); - if (workPage->prev->thisPage->animationStatus & 0x80) - workPage->prev->thisPage->animationStatus &= ~0x80; - } - workPage->thisPage->PlayEffect(-5000.0f, effect::EffectType_3D_SlideFromFront); - if (workPage->thisPage->animationStatus & 0x80) - workPage->thisPage->animationStatus &= ~0x80; - - if (prevPage) { - searchParam.hash = utils::GetHash("yt_button_btmenu_left"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffect(0.0f, effect::EffectType_Fadein1); - } - - if (workPage->resultCount != 0) { - for (SceInt32 i = 0; i < workPage->resultCount; i++) { - ytutils::WaitMenuParsers(); - if (IsCanceled()) { - Cancel(); - return; - } - CreateVideoButton(workPage, i); - } - - searchParam.hash = utils::GetHash("yt_button_btmenu_right"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffect(0.0f, effect::EffectType_Fadein1); - } - - Cancel(); -} - -SceVoid menu::youtube::SearchPage::SearchActionButtonOp() -{ - rco::Element searchParam; - ui::TextBox *searchBox; - wstring text16; - string text8; - - // In destructor s_current(...)Page->prev is assigned to s_current(...)Page - while (s_currentSearchPage) { - delete s_currentSearchPage; - } - - searchParam.hash = utils::GetHash("yt_text_box_top_search"); - searchBox = (ui::TextBox *)g_rootPage->GetChild(&searchParam, 0); - - searchBox->GetLabel(&text16); - - if (text16.length() != 0) { - - ccc::UTF16toUTF8(&text16, &text8); - - if (!sce_paf_strncmp("playlist:", text8.c_str(), 9) || !sce_paf_strncmp("video:", text8.c_str(), 6)) { - - char *idptr = (char *)text8.c_str() + 6; - - ytutils::GetHistLog()->Add(idptr); - - //new menu::audioplayer::Audioplayer::Audioplayer(idptr, SCE_NULL, menu::audioplayer::Audioplayer::Mode_Youtube); - } - else { - new SearchPage(text8.c_str()); - } - } -} - -// Constructor for next page -menu::youtube::SearchPage::SearchPage(SearchPage *prevPage) -{ - prev = prevPage; - next = SCE_NULL; - parseResult = SCE_NULL; - parserThread = SCE_NULL; - - prev->parserThread->Join(); - - pageNum = prev->pageNum + 1; - - parserThread = new SearchParserThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_256KiB, "NS::YtSearchParser"); - parserThread->prevPage = prevPage; - parserThread->workPage = this; - parserThread->newRequset = prev->parserThread->newRequset; - parserThread->Start(); - - s_currentSearchPage = this; -} - -// Constructor for initial page -menu::youtube::SearchPage::SearchPage(const char *searchWord) -{ - prev = SCE_NULL; - next = SCE_NULL; - parseResult = SCE_NULL; - parserThread = SCE_NULL; - pageNum = 0; - - parserThread = new SearchParserThread(SCE_KERNEL_DEFAULT_PRIORITY_USER, SCE_KERNEL_256KiB, "NS::YtSearchParser"); - parserThread->prevPage = SCE_NULL; - parserThread->workPage = this; - parserThread->newRequset = searchWord; - parserThread->Start(); - - s_currentSearchPage = this; -} - -menu::youtube::SearchPage::~SearchPage() -{ - rco::Element searchParam; - ui::Widget *commonWidget; - - parserThread->Cancel(); - thread::s_mainThreadMutex.Unlock(); - parserThread->Join(); - thread::s_mainThreadMutex.Lock(); - delete parserThread; - - effect::Play(-100.0f, thisPage, effect::EffectType_3D_SlideFromFront, SCE_TRUE, SCE_FALSE); - if (prev != SCE_NULL) { - prev->thisPage->PlayEffectReverse(0.0f, effect::EffectType_3D_SlideToBack1); - prev->thisPage->PlayEffect(0.0f, effect::EffectType_Reset); - if (prev->thisPage->animationStatus & 0x80) - prev->thisPage->animationStatus &= ~0x80; - if (prev->prev != SCE_NULL) { - prev->prev->thisPage->PlayEffect(0.0f, effect::EffectType_Reset); - if (prev->prev->thisPage->animationStatus & 0x80) - prev->prev->thisPage->animationStatus &= ~0x80; - } - else { - searchParam.hash = utils::GetHash("yt_button_btmenu_left"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffectReverse(0.0f, effect::EffectType_Fadein1); - } - } - - searchParam.hash = utils::GetHash("yt_button_btmenu_right"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffect(0.0f, effect::EffectType_Fadein1); - - invCleanupSearch(this->parseResult); - - s_currentSearchPage = prev; -} - -SceVoid menu::youtube::SearchPage::LeftButtonOp() -{ - delete s_currentSearchPage; -} - -SceVoid menu::youtube::SearchPage::RightButtonOp() -{ - new SearchPage(s_currentSearchPage); -} - -SceVoid menu::youtube::SearchPage::TermOp() -{ - rco::Element searchParam; - ui::Widget *commonWidget; - - // In destructor s_current(...)Page->prev is assigned to s_current(...)Page - while (s_currentSearchPage) { - delete s_currentSearchPage; - } - - searchParam.hash = utils::GetHash("yt_button_btmenu_right"); - commonWidget = g_rootPage->GetChild(&searchParam, 0); - commonWidget->PlayEffectReverse(0.0f, effect::EffectType_Fadein1); -} \ No newline at end of file