diff --git a/src/main.cpp b/src/main.cpp index a4fdb28..85ae440 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #define SCREEN_W 960 #define SCREEN_H 544 @@ -38,6 +39,9 @@ struct Item { std::string coverId; // <-- NEW: Subsonic coverArt ID bool isTrack = false; int trackNum = 0; + SDL_Texture* titleTex = nullptr; + SDL_Texture* artistTex = nullptr; + }; struct ArtRequest { std::string id; @@ -55,10 +59,13 @@ struct AudioQueueEntry { struct InputBox { int x, y, w, h; std::string text; + std::string title; bool focused = false; int caretPos = 0; // caret index Uint32 lastBlink = 0; // for caret blinking bool caretVisible = true; + bool openedKeyboard = false; + }; std::queue gArtRequestQ; @@ -249,17 +256,15 @@ void renderLeftList( SDL_RenderCopy(rd, artTex, NULL, &art); // TEXTURES - SDL_Texture* t1 = text(rd, fontSmall, items[i].title, {255,255,255}); + SDL_Texture* t1 = items[i].titleTex; int tw1,th1; SDL_QueryTexture(t1,NULL,NULL,&tw1,&th1); SDL_Rect td1 = { rt1.x, rt1.y, tw1, th1 }; - SDL_RenderCopy(rd, t1, NULL, &td1); - SDL_DestroyTexture(t1); + SDL_RenderCopy(rd, items[i].titleTex, NULL, &td1); - SDL_Texture* t2 = text(rd, fontSmall, items[i].artist, {180,180,180}); - int tw2,th2; SDL_QueryTexture(t2,NULL,NULL,&tw2,&th2); + SDL_Texture* t2 = items[i].artistTex; + int tw2,th2; SDL_QueryTexture(t2,NULL,NULL,&tw2,&th1); SDL_Rect td2 = { rt2.x, rt2.y, tw2, th2 }; - SDL_RenderCopy(rd, t2, NULL, &td2); - SDL_DestroyTexture(t2); + SDL_RenderCopy(rd, items[i].artistTex, NULL, &td2); } SDL_SetRenderTarget(rd, NULL); @@ -429,8 +434,8 @@ static bool PollIME(char* utf8Out, int maxlen) return true; } -void handleInputBoxEvent(InputBox& box, const SDL_Event& e) -{ +void handleInputBoxEvent(InputBox& box, const SDL_Event& e) { + // Click = focus + open IME keyboard if (e.type == SDL_FINGERDOWN) { int mx = e.tfinger.x * SCREEN_W; @@ -441,21 +446,8 @@ void handleInputBoxEvent(InputBox& box, const SDL_Event& e) if (inside) { box.focused = true; - ShowIME("testing.. testing..", box.text.c_str()); - char* result; - while(true) { - if(PollIME(result, 256)) { - // Replace the entire input content - box.text = result; - - box.caretPos = box.text.size(); - box.lastBlink = SDL_GetTicks(); - box.caretVisible = true; - - box.focused = false; - break; - } - } + ShowIME(box.title.c_str(), box.text.c_str()); + box.openedKeyboard = true; } else { box.focused = false; } @@ -465,6 +457,23 @@ void handleInputBoxEvent(InputBox& box, const SDL_Event& e) return; } +void HandleKeyboardInputBox(InputBox& box) { + if(box.openedKeyboard) { + char result[256]; + if(PollIME(result, 256)) { + // Replace the entire input content + box.text = result; + + box.caretPos = box.text.size(); + box.lastBlink = SDL_GetTicks(); + box.caretVisible = true; + box.openedKeyboard = false; + box.focused = false; + } + + } +} + void renderRightPanel( SDL_Renderer* rd, TTF_Font* fontBig, TTF_Font* fontMed, @@ -545,6 +554,8 @@ void loadTracks( std::vector& items, const SubsonicClient& ss, const std::string& albumId, + SDL_Renderer* rd, + TTF_Font* font, SDL_Window* win) { std::string err; @@ -552,6 +563,10 @@ void loadTracks( if (!err.empty()) log(win, "getAlbum error: %s", err.c_str()); + for (auto& it : items) { + if (it.titleTex) SDL_DestroyTexture(it.titleTex); + if (it.artistTex) SDL_DestroyTexture(it.artistTex); + } items.clear(); items.reserve(tracks.size()); @@ -577,6 +592,10 @@ void loadTracks( it.titleRect = { 20 + artSize + 15, y + 10, 240, 24 }; it.artistRect = { 20 + artSize + 15, y + 36, 240, 22 }; + it.titleTex = text(rd, font, it.title, {255,255,255}); + it.artistTex = text(rd, font, it.artist, {180,180,180}); + + items.push_back(it); } @@ -587,13 +606,18 @@ void loadTracks( void loadArtists( std::vector& items, - const SubsonicClient& ss + const SubsonicClient& ss, + SDL_Renderer* rd, + TTF_Font* font ) { std::string err; auto allArtists = ss.getArtists(&err); if (!err.empty()) SDL_Log("getArtists error: %s", err.c_str()); - + for (auto& it : items) { + if (it.titleTex) SDL_DestroyTexture(it.titleTex); + if (it.artistTex) SDL_DestroyTexture(it.artistTex); + } items.clear(); items.reserve(allArtists.size()); @@ -617,6 +641,9 @@ void loadArtists( it.titleRect = {20 + artSize + 15, y + 10, 200, 20}; it.artistRect = {20 + artSize + 15, y + 35, 200, 20}; + it.titleTex = text(rd, font, it.title, {255,255,255}); + it.artistTex = text(rd, font, it.artist, {180,180,180}); + items.push_back(it); } @@ -627,13 +654,18 @@ void loadArtists( void loadAlbums( std::vector& items, const SubsonicClient& ss, + SDL_Renderer* rd, + TTF_Font* font, std::string artist = "" ) { std::string err; auto allAlbums = ss.getAllAlbums(&err); if (!err.empty()) SDL_Log("getAlbum error: %s", err.c_str()); - + for (auto& it : items) { + if (it.titleTex) SDL_DestroyTexture(it.titleTex); + if (it.artistTex) SDL_DestroyTexture(it.artistTex); + } items.clear(); const int artSize = 80; @@ -664,6 +696,10 @@ void loadAlbums( it.titleRect = {20 + artSize + 15, y + 10, 200, 20}; it.artistRect = {20 + artSize + 15, y + 35, 200, 20}; + it.titleTex = text(rd, font, it.title, {255,255,255}); + it.artistTex = text(rd, font, it.artist, {180,180,180}); + + items.push_back(it); k2=k2+1; @@ -690,6 +726,8 @@ int main() SDL_setenv("VITA_DISABLE_TOUCH_BACK", "1", 1); + sceSysmoduleLoadModule(SCE_SYSMODULE_IME); + Audio_Init(); SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); IMG_Init(IMG_INIT_PNG); @@ -729,7 +767,7 @@ int main() }; std::vector items; - loadAlbums(items, ss); + loadAlbums(items, ss, rd, fontSmall); int artSize = 80; int rowHeight = 100; int startY = 70; @@ -755,16 +793,19 @@ int main() InputBox serverUrl { 10,10+50+10,350,30, - settings.server + settings.server, + "Server URL" }; InputBox password { 10,10+50+10+30+10,350,30, - settings.user + settings.pass, + "Password" }; InputBox username { 10,10+50+10+30+10+30+10,350,30, - settings.pass + settings.user, + "Username" }; Button btnSettingsSave = { @@ -821,6 +862,10 @@ int main() } } + HandleKeyboardInputBox(username); + HandleKeyboardInputBox(password); + HandleKeyboardInputBox(serverUrl); + if (touch) { if(settingsOpened) { @@ -832,11 +877,19 @@ int main() } if(hit(tx,ty,rS)) { - settings.pass = password.text; settings.server = serverUrl.text; settings.user = username.text; + settings.pass = password.text; settings.save(); + + ss = SubsonicClient( + settings.server, + settings.user, + settings.pass, + "vita-player", + "1.16.1" + ); } } else { // Tabs @@ -848,10 +901,10 @@ int main() for(int j=0;j<3;j++) tabs[j].active=false; tabs[i].active=true; if (strcmp(tabs[i].label, "albums") == 0) { - loadAlbums(items, ss); + loadAlbums(items, ss, rd, fontSmall); } if (strcmp(tabs[i].label, "artists") == 0) { - loadArtists(items, ss); + loadArtists(items, ss, rd, fontSmall); } } } @@ -861,13 +914,13 @@ int main() r.y -= scrollOffset; if (hit(tx, ty, {LEFT_X + r.x, r.y, r.w, r.h})) { if (tabs[0].active) { - loadTracks(items, ss, items[i].id, win); + loadTracks(items, ss, items[i].id, rd, fontSmall, win); // switch to Tracks tab for (int j = 0; j < 3; j++) tabs[j].active = false; tabs[2].active = true; } else if(tabs[1].active) { - loadAlbums(items, ss, items[i].id); + loadAlbums(items, ss, rd, fontSmall, items[i].id); for (int j = 0; j < 3; j++) tabs[j].active = false; tabs[0].active = true; diff --git a/src/subsonic.hpp b/src/subsonic.hpp index 1c46265..ce4d39e 100644 --- a/src/subsonic.hpp +++ b/src/subsonic.hpp @@ -6,6 +6,7 @@ #include #include +#include struct ArtistInfo { std::string id; @@ -141,6 +142,9 @@ public: curl_easy_setopt(c, CURLOPT_CONNECTTIMEOUT, 10L); curl_easy_setopt(c, CURLOPT_TIMEOUT, 30L); + curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(c, CURLOPT_SSL_VERIFYHOST, 0L); + CURLcode res = curl_easy_perform(c); char* ctype = NULL; @@ -288,7 +292,10 @@ public: const Json::Value& albumList = sub["albumList2"]; if (!albumList.isObject()) { - if (outError) *outError = "Missing 'albumList2'"; + if (outError) { + SDL_Log("full json: %s", body.c_str()); + *outError = "Missing 'albumList2'"; + } return {}; } @@ -584,6 +591,9 @@ private: curl_easy_setopt(c, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, &curlWriteCallback); curl_easy_setopt(c, CURLOPT_WRITEDATA, &outBody); + curl_easy_setopt(c, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(c, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(c, CURLOPT_USE_SSL, CURLUSESSL_TRY); // Reasonable defaults; tweak if Vita/curl complains curl_easy_setopt(c, CURLOPT_CONNECTTIMEOUT, 10L);