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