prerender all text + get IME working flawlessly

This commit is contained in:
Soph :3 2025-11-17 12:12:44 +02:00
parent d245a92811
commit c4f12cfb65
2 changed files with 100 additions and 37 deletions

View file

@ -22,6 +22,7 @@
#include <psp2/libime.h>
#include <psp2/ime_dialog.h>
#include <psp2/io/stat.h>
#include <psp2/sysmodule.h>
#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<ArtRequest> 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<Item>& 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<Item>& 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<Item>& 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<Item> 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;

View file

@ -6,6 +6,7 @@
#include <curl/curl.h>
#include <jsoncpp/json/json.h>
#include <SDL2/SDL.h>
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);