From 9f65422fc0bfd9014dfc90ec868d6a039585dcbd Mon Sep 17 00:00:00 2001 From: LM Date: Wed, 6 Jan 2021 23:25:30 +0000 Subject: [PATCH] Version 1.2-V-2021-01-06T23:17:24 --- Store/Makefile | 4 +- Store/include/Header.h | 6 +- Store/include/KeyboardDialog.h | 14 +- Store/include/defines.h | 14 +- Store/include/utils.h | 51 +- Store/source/GLES2_ani.c | 41 +- Store/source/GLES2_menu.c | 123 ++++- Store/source/GLES2_panel.c | 15 +- Store/source/GLES2_q.c | 53 +- Store/source/GLES2_rects.c | 66 ++- Store/source/GLES2_scene_v2.c | 884 +++++++++++++++++++-------------- Store/source/GLES2_textures.c | 80 +-- Store/source/KeyboardDialog.c | 130 ++--- Store/source/common_init.c | 130 +++-- Store/source/http.c | 12 +- Store/source/json_simple.c | 152 +++--- Store/source/main.c | 72 ++- Store/source/utils.c | 185 +++---- 18 files changed, 1130 insertions(+), 902 deletions(-) diff --git a/Store/Makefile b/Store/Makefile index 1abf686..dd0aa27 100644 --- a/Store/Makefile +++ b/Store/Makefile @@ -21,7 +21,7 @@ install: @cp $(OutPath)/homebrew.self /hostapp/homebrew.self @echo "Installed!" oelf: - orbis-elf-create bin/homebrew.elf bin/homebrew.oelf + orbis-elf-create bin/homebrew.elf bin/homebrew.oelf >/dev/null 2>&1 AUTH_INFO = 000000000000000000000000001C004000FF000000000080000000000000000000000000000000000000008000400040000000000000008000000000000000080040FFFF000000F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -29,4 +29,4 @@ AUTH_INFO = 000000000000000000000000001C004000FF00000000008000000000000000000000 eboot: python2 $(ORBISDEV)/bin/make_fself.py --auth-info $(AUTH_INFO) bin/homebrew.oelf bin/homebrew.self pkg_build: - cp bin/homebrew.self pkg/eboot.bin && cd pkg && pkgTool pkg_build Project.gp4 . && cp *.pkg ../bin/ \ No newline at end of file + cp bin/homebrew.self pkg/eboot.bin && cd pkg && pkgTool pkg_build Project.gp4 . && cp *.pkg ../bin/ diff --git a/Store/include/Header.h b/Store/include/Header.h index d1401cc..f5d48aa 100644 --- a/Store/include/Header.h +++ b/Store/include/Header.h @@ -79,8 +79,6 @@ int jb(); #define DKS_TIMEOUT 0x804101E2 -#define klog printf - #define TRUE 1 #define FALSE 0 @@ -148,7 +146,7 @@ void logshit(char* format, ...); #define VERSION_MAJOR 1 -#define VERSION_MINOR 4 +#define VERSION_MINOR 2 #define BUILD_YEAR_CH0 (__DATE__[ 7]) #define BUILD_YEAR_CH1 (__DATE__[ 8]) @@ -245,4 +243,4 @@ void logshit(char* format, ...); #define VERSION_MINOR_INIT \ (VERSION_MINOR + '0') -#endif \ No newline at end of file +#endif diff --git a/Store/include/KeyboardDialog.h b/Store/include/KeyboardDialog.h index ae21ae3..36caeb6 100644 --- a/Store/include/KeyboardDialog.h +++ b/Store/include/KeyboardDialog.h @@ -1,7 +1,7 @@ -#pragma once - -#include -#include -#include - -char* StoreKeyboard(); \ No newline at end of file +#pragma once + +#include +#include +#include + +char *StoreKeyboard(const char *Title, char *initialTextBuffer); diff --git a/Store/include/defines.h b/Store/include/defines.h index ac5c33a..353f43f 100644 --- a/Store/include/defines.h +++ b/Store/include/defines.h @@ -190,10 +190,11 @@ enum views ON_LEFT_PANEL, ON_MAIN_SCREEN, // 0 ON_SUBMENU, // 1 - Queue - ON_SUBMENU3, // Ready - ON_SUBMENU_2, // 2 - Groups - ON_ITEM_PAGE, // 3 - aux/temp - ON_EXTRA_PAGE // 4 - pixelshader + ON_SUBMENU3, // 2 - Ready to install + ON_SUBMENU_2, // 3 - Groups + ON_ITEM_PAGE, // 4 - aux/temp + ON_EXTRA_PAGE, // 5 - pixelshader + ON_SETTINGS // 6 }; @@ -236,6 +237,7 @@ void pixelshader_init( int width, int height ); void pixelshader_fini( void ); void ORBIS_RenderSubMenu(int num); +void GLES2_render_submenu_text_v2( vertex_buffer_t *vbo, vec3 *offset ); void GLES2_init_submenu( void ); void GLES2_render_submenu_text( int num ); @@ -305,8 +307,10 @@ void destroy_item_t(item_idx_t **p); int df(char *out, const char *mountPoint); int get_item_index(layout_t *l); +// from GLES2_scene_v2.c +layout_t * GLES2_layout_init(int req_item_count); -/// pthreads +/// pthreads used in GLES2_q.c typedef enum pt_status { diff --git a/Store/include/utils.h b/Store/include/utils.h index af1b2e9..5d8fe80 100644 --- a/Store/include/utils.h +++ b/Store/include/utils.h @@ -1,6 +1,5 @@ #pragma once - #include "defines.h" @@ -8,6 +7,7 @@ #include #include #include +#include #define DIM(x) (sizeof(x)/sizeof(*(x))) @@ -16,16 +16,43 @@ #define WARNING 3 #define STORE_LOG "/user/app/NPXS39041/logs/log.txt" +static const char *option_panel_text[] = +{ + "Content Delivery Network", + "Temporary Path", + "Detected USB", + "INI Path", + "Custom FreeType font Path", + // following doesn't store strings for any Paths... + "Store Downloads on USB", + "Save Settings" +}; + +enum STR_type +{ + CDN_URL, + TMP_PATH, + USB_PATH, + INI_PATH, + FNT_PATH, + NUM_OF_STRINGS +}; +// indexed options typedef struct { - char* StoreCDN; - char* temppath; - int StoreOnUSB; - char* USBPath; - char* INIPath; + char *opt[ NUM_OF_STRINGS ]; + int StoreOnUSB; + // more options } StoreOptions; +char *usbpath(void); +int LoadOptions(StoreOptions *set); +int SaveOptions(StoreOptions *set); + +// sysctl +uint32_t SysctlByName_get_sdk_version(void); + char *checkedsize; char *calculateSize(uint64_t size); @@ -36,9 +63,11 @@ int loadmsg(char* format, ...); void klog(const char *format, ...); void CalcAppsize(char *path); char* cutoff(const char* str, int from, int to); -uint32_t SysctlByName_get_sdk_version(void); -char* usbpath(void); -void SaveOptions(StoreOptions* set); + int getjson(int Pagenumb, char* cdn); -int LoadOptions(StoreOptions* set); -int MD5_hash_compare(const char* file1, const char* hash); \ No newline at end of file +int MD5_hash_compare(const char* file1, const char* hash); + + + +#define assert(expr) if (!(expr)) msgok(FATAL, "Assetion Failed!"); + diff --git a/Store/source/GLES2_ani.c b/Store/source/GLES2_ani.c index 2b1764a..b6cfede 100644 --- a/Store/source/GLES2_ani.c +++ b/Store/source/GLES2_ani.c @@ -7,8 +7,6 @@ #include #include -/*clang *.c -I$PS4SDK/include/MiniAPI -L/Archive/PS4-work/OrbisLink/samples/pc_es2template/source -lMiniAPI -L/Archive/PS4-work/OrbisLink/samples/pc_es2template/source -lm -lGL -lEGL -lX11 -D_MAPI_ -I$PS4SDK/include/freetype2 -lfreetype -png -ggdb*/ - #include "defines.h" #include "ani.h" @@ -29,9 +27,9 @@ extern int selected_icon; // from main.c // shader and locations static GLuint program = 0; // default program static GLuint shader_fx = 0; // text_ani.[vf] -static mat4 model, view, projection; static float g_Time = 0.f; static GLuint meta_Slot = 0; +static mat4 model, view, projection; // ---------------------------------------------------------------- reshape --- static void reshape(int width, int height) { @@ -40,35 +38,29 @@ static void reshape(int width, int height) } // ---------------------------------------------------------- animation --- - static fx_entry_t *ani; // the fx info static vertex_buffer_t *line_buffer, *text_buffer, *vbo = NULL; - // bool flag static int ani_is_running = 0; -// callback when done looping all status +// callback when done looping all effect status static void ani_post_cb(void) { printf("%s()\n", __FUNCTION__); O_action_dispatch(); } + // ---------------------------------------------------------------- display --- static void render_ani( int text_num, int type_num ) { - // we already clean in main renderloop()! - - //type_num = 1; // which fx_entry_t test + // we already clean in main render loop! fx_entry_t *ani = &fx_entry[0]; - //* fx = &fx_entry[0]; - // int t_n = ani - fx; - program = shader_fx; - if(ani->t_now >= ani->t_life) // looping ani_state + if(ani->t_now >= ani->t_life) // looping animation status { switch(ani->status) // setup for next fx { @@ -79,10 +71,9 @@ static void render_ani( int text_num, int type_num ) /* CLOSED reached: looped once all status */ ani_is_running = 0 ; ani_post_cb(); break; } - ani->fcount = 0; // reset framecount - ani->t_now = 0.f; + ani->fcount = 0; // reset framecount (useless) + ani->t_now = 0.f; // yes, it's using time } - /* printf("program: %d [%d] fx state: %.1f, frame: %3d/%3.f %.3f\r", program, t_n, @@ -109,19 +100,17 @@ static void render_ani( int text_num, int type_num ) type_num /10.); if(1) /* draw whole VBO (storing all added texts) */ { - /* draw whole VBO item arrays */ vertex_buffer_render( line_buffer, GL_LINES ); vertex_buffer_render( vbo, GL_TRIANGLES ); } } glDisable( GL_BLEND ); - ani->fcount += 1; // increase frame counter + ani->fcount += 1; // increase frame counter (useless) - // we already swapframe in main renderloop()! + // we already swap frame in main render loop! } - /* wrapper from main */ void GLES2_ani_test( fx_entry_t *_ani ) { @@ -137,8 +126,6 @@ void GLES2_ani_test( fx_entry_t *_ani ) } } - - // --------------------------------------------------------- custom shaders --- static GLuint CreateProgram( void ) { @@ -150,8 +137,8 @@ static GLuint CreateProgram( void ) /* use embedded glsl source */ #include "ani_vert.h" #include "ani_frag.h" - const GLchar *vShader = &ani_vert[0]; - const GLchar *fShader = &ani_frag[0]; + GLchar *vShader = &ani_vert[0]; + GLchar *fShader = &ani_frag[0]; #endif GLuint programID = BuildProgram(vShader, fShader); // shader_common.c @@ -175,7 +162,6 @@ void GLES2_ani_init(int width, int height) line_buffer = vertex_buffer_new( "vertex:3f,color:4f" ); #if 0 // rects - vec2 pen = { .5, .5 }; for (int i = 0; i < 10; ++i) { @@ -311,6 +297,8 @@ for (int i = 0; i < 10; ++i) void GLES2_ani_update(double now) { + if(ani_is_running == 0) return; + ani->t_now += now - g_Time; g_Time = now; } @@ -351,10 +339,9 @@ void ani_notify(const char *message) } } -// draw one loop +// draw one effect loop void GLES2_ani_draw(void) { if(vbo && ani_is_running) render_ani(1, 0); //printf("%f %d\n", ani->t_now, ani->status); } - diff --git a/Store/source/GLES2_menu.c b/Store/source/GLES2_menu.c index de18ee6..68e3b3b 100644 --- a/Store/source/GLES2_menu.c +++ b/Store/source/GLES2_menu.c @@ -6,24 +6,31 @@ #include #include -#include // links against libfreetype-gl - #include "defines.h" -extern vec4 color; // GLES_rects.c - extern GLuint shader; extern texture_atlas_t *atlas; extern mat4 model, view, projection; + + +// to json-simple.c + +texture_font_t *sub_font = NULL, + *main_font = NULL, + *titl_font = NULL; + +/* older UI code is preprocessed out, but for reference */ +#if 0 +vertex_buffer_t *text_buffer[4]; + extern vec2 resolution; // freetype-gl pass last composed Text_Length in pixel, we use to align text! extern float tl; -// to json-simple.c -vertex_buffer_t *text_buffer[4]; -texture_font_t *sub_font = NULL, - *main_font = NULL, - *titl_font = NULL; +extern vec4 color; // GLES_rects.c + +#include // links against libfreetype-gl + // ------------------------------------------------------- typedef & struct --- typedef struct { float x, y, z; // position (3f) @@ -34,7 +41,7 @@ typedef struct { const char *left_menu[] = { "Games", - "Apps", + "Installed Apps", "Groups", "Ready to install", "Updates", @@ -68,6 +75,7 @@ const char *selection_menu[] = #define lines_num (sizeof(settings_menu) / sizeof(settings_menu[0])) +#define TEXTBOX_H (700) // vertical text box size, in px void GLES2_render_submenu_text( int num ) { @@ -90,6 +98,7 @@ void GLES2_render_submenu_text( int num ) glUseProgram( 0 ); glBindTexture(GL_TEXTURE_2D, 0); } +#endif mat4 bak; void GLES2_render_submenu_text_v2( vertex_buffer_t *vbo, vec3 *offset ) @@ -126,29 +135,105 @@ void GLES2_render_submenu_text_v2( vertex_buffer_t *vbo, vec3 *offset ) } } -#define TEXTBOX_H (700) // vertical text box size, in px + +// font reloading +static void ftgl_purge_fonts( void ) +{ + if(titl_font) texture_font_delete(titl_font); + if( sub_font) texture_font_delete( sub_font); + if(main_font) texture_font_delete(main_font); + + // discard cached glyphs, whole atlas from start + if(atlas) texture_atlas_delete(atlas); + //if(atlas->id) glDeleteTextures(1, &atlas->id), atlas->id = 0; + /* renew atlas map */ + atlas = texture_atlas_new( 1024, 1024, 1 ); +} + +// smallest part +static texture_font_t *font_from_buffer(unsigned char *data, size_t size, int fontsize) +{ + return texture_font_new_from_memory(atlas, fontsize, data, size); +} + +static bool ftgl_init_fonts( unsigned char *data, size_t size ) +{ + bool ret = 1; + titl_font = font_from_buffer(data, size, 32); + sub_font = font_from_buffer(data, size, 25); + main_font = font_from_buffer(data, size, 18); + + if( ! titl_font + || ! sub_font + || ! main_font ) ret = 0; + + return ret; +} + +void GLES2_fonts_from_ttf(const char *path) +{ + int ret = 0; + void *ttf = NULL; + size_t size = 0; + + if(path) + { /* load .ttf in memory */ + ttf = orbisFileGetFileContent(path); + size = _orbisFile_lastopenFile_size; + + if( ! ttf ) + { + msgok(NORMAL,"TTF Failed Loading from %s\n Switching to Embedded", path); goto default_embedded; + } + + } else { + +default_embedded: // fallback on error + + ttf = &font_ttf[0]; + size = font_ttf_len; + } + // recreate global glyph atlas + ftgl_purge_fonts(); + + // prepare our set of different size + if( ! ftgl_init_fonts( ttf, size ) ) + { // custom data failed... + char tmp[256]; + sprintf(&tmp[0], "%s failed to create font from %s\n", __FUNCTION__, path); + printf("%s\n", tmp); + + sceKernelIccSetBuzzer(3); + // loaded ttf, but failed fonts, flag to free()! + ret = 1; + // go back and fallback to default font + goto default_embedded; + } + // done with ttf data, release (to recheck for fix) + //if(ret) free(ttf), ttf = NULL; +} // init VBOs for menu texts void GLES2_init_submenu( void ) { +#if 0 // each vbo acts as temporary placeholder, per view // commons text_buffer[ON_MAIN_SCREEN] = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); text_buffer[ON_SUBMENU] = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); text_buffer[ON_SUBMENU_2] = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); text_buffer[ON_ITEM_PAGE] = NULL;//vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); -#if 0 + sub_font = texture_font_new_from_memory(atlas, 36, _hostapp_fonts_zrnic_rg_ttf, _hostapp_fonts_zrnic_rg_ttf_len); #else - titl_font = texture_font_new_from_memory(atlas, 32, font_ttf, - font_ttf_len); - sub_font = texture_font_new_from_memory(atlas, 25, font_ttf, - font_ttf_len); - main_font = texture_font_new_from_memory(atlas, 18, font_ttf, - font_ttf_len); + // load fonts once, don't delete them, but reuse! + titl_font = texture_font_new_from_memory(atlas, 32, font_ttf, font_ttf_len); + sub_font = texture_font_new_from_memory(atlas, 25, font_ttf, font_ttf_len); + main_font = texture_font_new_from_memory(atlas, 18, font_ttf, font_ttf_len); #endif +#if 0 vec2 pen = (0); // init pen: 0,0 is lower left vec4 col = (vec4)( 1. ); pen.y = (resolution.y - TEXTBOX_H) /2 + TEXTBOX_H @@ -191,7 +276,7 @@ void GLES2_init_submenu( void ) } add_text( text_buffer[ON_SUBMENU_2], sub_font, selection_menu[i], &col, &pen ); // set vertexes } -#if 1 + // Left panel pen = (vec2){ 0., resolution.y - 100 }; col = (vec4){ .8164, .8164, .8125, 1. }; diff --git a/Store/source/GLES2_panel.c b/Store/source/GLES2_panel.c index ac906d9..8ab1187 100644 --- a/Store/source/GLES2_panel.c +++ b/Store/source/GLES2_panel.c @@ -24,12 +24,9 @@ extern float tl; #include "json.h" -int group_c; // total counted Group - - // check for pattern in whitelist patterns, if there take count, if not fall in Other static char *group_label[] = -{ // 0 is reserved index (label, total count) +{ // 0 is reserved index for: (label, total count) "HB Game", "Emulator", "Emulator Add-On", @@ -38,13 +35,14 @@ static char *group_label[] = "Utility", "Other" }; + /* pattern from icon tokens, item for Group arrays */ static int check_for_token(char *pattern, item_t *item, int count) { int i, plen = strlen(pattern); item_idx_t *t = NULL; - /* loop over, skip very first (0), reserved - and (6) for Other, used as "unmatched labels" */ + /* loop over, skip very first one (0), reserved + and (6) for Other used as "unmatched labels" */ for(i = 1; i < count -1; i++) { t = &item[i].token_d[0]; @@ -68,7 +66,7 @@ static int check_for_token(char *pattern, item_t *item, int count) // we return an array of indexes and count number, per Group item_t *analyze_item_t_v2(item_t *items, int item_count) { - // same number of group_labels, +1 for main index + // same number of group_labels, +1 for reserved main index int i, count = sizeof(group_label) / sizeof(group_label[0]) +1; // dynalloc item_t *ret = calloc(count, sizeof(item_t)); @@ -106,6 +104,7 @@ item_t *analyze_item_t_v2(item_t *items, int item_count) // store the index for item related to icon_panel list! ret[ res ].token_d[ idx ].len = i; + // is installed? char tmp[128]; sprintf(&tmp[0], "/user/app/%s", items[i].token_d[ ID ].off); @@ -143,8 +142,6 @@ so we have 7 Groups, check:112 */ #endif - // update global variable - group_c = count; return ret; } diff --git a/Store/source/GLES2_q.c b/Store/source/GLES2_q.c index 098e3f9..ac61570 100644 --- a/Store/source/GLES2_q.c +++ b/Store/source/GLES2_q.c @@ -5,7 +5,7 @@ (shaders beware) - 2020, masterzorag + 2020, masterzorag & LM deals with dynamically queued items to move, following related posix thread note four threads are max used, we access each thread arguments data, @@ -29,11 +29,6 @@ // freetype-gl pass last composed Text_Length in pixel, we use to align text! extern float tl; -// from GLES2_menu.c -void GLES2_render_submenu_text_v2( vertex_buffer_t *vbo, vec3 *offset ); -// from GLES2_scene_v2.c -layout_t * GLES2_layout_init(int req_item_count); - extern texture_font_t *main_font, // small *sub_font, // left panel *titl_font; @@ -42,7 +37,7 @@ extern vec2 resolution; extern layout_t *left_panel, *icon_panel, *queue_panel; - +extern int http_ret; #define ENTRIES (4) dl_arg_t *pt_info = NULL; @@ -160,8 +155,8 @@ void GLES2_render_queue(layout_t *layout, int used) if(layout->texture[ idx ] == 0) { sprintf(&tmp[0], "%s", ta->token_d[ PICPATH ].off); - // on pc we use different path - //char *f = strstr(&tmp[0], "storedata"); + /* on pc we use different path + char *f = strstr(&tmp[0], "storedata"); */ layout->texture[ idx ] = load_png_asset_into_texture(&tmp[0]); } // gles render square texture @@ -228,9 +223,19 @@ void GLES2_render_queue(layout_t *layout, int used) case RUNNING: sprintf(&tmp[0], "Downloading"); break; case READY: - case COMPLETED: sprintf(&tmp[0], "Download Completed"); + case COMPLETED: + sprintf(&tmp[0], " Download Completed"); + break; + default: + sprintf(&tmp[0], " Download error: %i", ta->status); break; } + + if (http_ret != 200 && http_ret != 0) + { + sprintf(&tmp[0], ", Download Failed with %i", http_ret); + } + // we need to know Text_Length_in_px in advance, so we call this: texture_font_load_glyphs( main_font, &tmp[0] ); // we know 'tl' now, right align @@ -279,7 +284,7 @@ void queue_panel_init(void) if(queue_panel) { - // should matches the icon panel size + // should match the icon panel size queue_panel->bound_box = icon_panel->bound_box; queue_panel->fieldsize = (ivec2) { 1, ENTRIES }; queue_panel->item_c = ENTRIES; @@ -300,7 +305,7 @@ void *start_routine2(void *argument) i->status = RUNNING; i->progress = 0.f; - int ret = -1; + int ret = CANCELED; uint64_t total_read = 0; printf("i->url %s\n", i->url); @@ -316,18 +321,19 @@ void *start_routine2(void *argument) int fd = sceKernelOpen(i->dst, O_WRONLY | O_CREAT, 0777); // fchmod(fd, 777); - if (fd < 0) return fd; + if (fd < 0) { i->status = CANCELED; return fd; } while (1) { int read = sceHttpReadData(i->req, buf, sizeof(buf)); - if (read < 0) return read; - if (read == 0) break; + if (read < 0) { i->status = read; return read; } + if (read == 0) { i->status = CANCELED; break; } ret = sceKernelWrite(fd, buf, read); if (ret < 0 || ret != read) { - if (ret < 0) return ret; + if (ret < 0) { i->status = CANCELED; return ret; }; + i->status = CANCELED; return -1; } total_read += read; @@ -337,7 +343,11 @@ void *start_routine2(void *argument) i->progress = (double)(((float)total_read / i->contentLength) * 100.f); - if(i->progress >= 100.) break; + if (i->progress >= 100.) + { + i->status = COMPLETED; + break; + } if(total_read %(4096*128) == 0) fprintf(DEBUG, "thread[%d] reading data, %lub / %lub (%.2f%%)\n", i->idx, total_read, i->contentLength, i->progress); @@ -347,11 +357,12 @@ void *start_routine2(void *argument) // don't wait before returning //sleep(2); - i->status = COMPLETED; + // clean thread / reset if(i->req) sceHttpDeleteRequest(i->req); + return ret; } @@ -485,8 +496,12 @@ int dl_from_url_v2(const char *url_, const char *dst_, item_idx_t *t) ani_notify("Download thread start"); } + else + msgok(NORMAL, "Download Failed with code\n StatusCode: %i\n\n URL: %s\n\n DEST: %s", ret, url_, dst_); fprintf(DEBUG, "icon_panel->item_d[%d]\n\n", ta->g_idx); + + return ret; -} \ No newline at end of file +} diff --git a/Store/source/GLES2_rects.c b/Store/source/GLES2_rects.c index 3f012f1..78073be 100644 --- a/Store/source/GLES2_rects.c +++ b/Store/source/GLES2_rects.c @@ -77,28 +77,8 @@ static GLint u_color_location; static GLint u_time_location; // from main.c extern double u_t; -extern int selected_icon; -extern ivec4 rela_pos; - -typedef vec2 my_Point; -typedef vec4 my_FRect; // ( p1.xy, p2.xy ) - -#define COUNT 8 -vec4 r[COUNT]; - - -// old way, tetris uses it -vec4 px_pos_to_normalized2(vec2 *pos, vec2 *size) -{ - vec4 n; // 2 points .xy pair: (x, y), (x + texture.w, y + texture.h) - - n.xy = 2. / resolution * (*pos) - 1.; // (-1,-1) is BOTTOMLEFT, (1,1) is UPRIGHT - n.zw = 2. / resolution * (*size); - n.yw *= -1.; // flip Y axis! -// printf("%f,%f,%f,%f\n", n.x, n.y, n.w, n.w); - return n; -} +/* translate px vector to normalized coord */ vec2 px_pos_to_normalized(vec2 *pos) { return 2. / resolution * (*pos) - 1.; @@ -176,8 +156,6 @@ void ORBIS_RenderDrawLines(//SDL_Renderer *renderer, glEnableVertexAttribArray(a_position_location); /* write color to use to the shader location */ glUniform4f(u_color_location, color.r, color.g, color.b, color.a); - /* write time to use to the shader location */ -// glUniform1f(u_time_location, (float)u_t); /* floats pairs for points from 0-4 */ glDrawArrays(GL_LINES, 0, 2); } @@ -228,7 +206,7 @@ void ORBIS_RenderFillRects(enum SH_type SL_program, const vec4 *rgba, const vec4 /* emit a triangle strip for each rectangle */ for(int i = 0; i < count; ++i) { - const my_FRect *rect = &rects[i]; + const vec4 *rect = &rects[i]; GLfloat xMin = rect->x, xMax = rect->z, yMin = rect->y, yMax = rect->w; @@ -237,13 +215,11 @@ void ORBIS_RenderFillRects(enum SH_type SL_program, const vec4 *rgba, const vec4 vertices[2] = xMax; vertices[3] = yMin; vertices[4] = xMin; vertices[5] = yMax; vertices[6] = xMax; vertices[7] = yMax; - /* each (vec2)point comes from pairs of floats */ + /* each (vec2) point comes from pairs of floats */ glVertexAttribPointer (a_position_location, 2, GL_FLOAT, GL_FALSE, 0, vertices); glEnableVertexAttribArray(a_position_location); /* write color to use to the shader location */ glUniform4f(u_color_location, color.r, color.g, color.b, color.a); - /* write time to use to the shader location */ -// glUniform1f(u_time_location, (float)u_t); /* floats pairs for points from 0-4 */ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } @@ -253,6 +229,40 @@ void ORBIS_RenderFillRects(enum SH_type SL_program, const vec4 *rgba, const vec4 glUseProgram(0); } +/* draw filling color bar */ +void GLES2_DrawFillingRect(vec4 *r, // float/normalized rectangle + vec4 *c, // normalized color + double *percentage) // how much filled from left +{ // shrink frect RtoL by_percentage + r->z = r->x + (r->z - r->x) * (*percentage / 100.f); +// fprintf(INFO, "%.2f %.2f, %.2f, %.2f %f\n", r.x, r.y, r.z, r.w, dfp); + ORBIS_RenderFillRects(USE_COLOR, c, r, 1); +} + +/* older UI version code, for reference */ + +#if 0 +extern int selected_icon; +extern ivec4 rela_pos; + +typedef vec2 my_Point; +typedef vec4 my_FRect; // ( p1.xy, p2.xy ) + +#define COUNT 8 +vec4 r[COUNT]; + + +// old way, tetris uses it +vec4 px_pos_to_normalized2(vec2 *pos, vec2 *size) +{ + vec4 n; // 2 points .xy pair: (x, y), (x + texture.w, y + texture.h) + + n.xy = 2. / resolution * (*pos) - 1.; // (-1,-1) is BOTTOMLEFT, (1,1) is UPRIGHT + n.zw = 2. / resolution * (*size); + n.yw *= -1.; // flip Y axis! +// printf("%f,%f,%f,%f\n", n.x, n.y, n.w, n.w); + return n; +} // used in line_and_rects sample void ORBIS_RenderFillRects_rndr(void) @@ -415,3 +425,5 @@ void ORBIS_RenderSubMenu(int num) // texts GLES2_render_submenu_text(num); } +#endif + diff --git a/Store/source/GLES2_scene_v2.c b/Store/source/GLES2_scene_v2.c index db789e8..0aaed8f 100644 --- a/Store/source/GLES2_scene_v2.c +++ b/Store/source/GLES2_scene_v2.c @@ -5,7 +5,7 @@ (shaders beware) - 2020, masterzorag + 2020, masterzorag & LM */ #include @@ -29,9 +29,13 @@ extern float tl; #include "json.h" int jsoneq(const char *json, jsmntok_t *tok, const char *s); +#include "utils.h" + int install_ret = -1, http_ret = -1, last_item_dl = 999; -#include "utils.h" +#include "Header.h" + +extern const unsigned char completeVersion[]; typedef struct retries { @@ -41,9 +45,8 @@ typedef struct retries struct retries rrr[100]; bool install_done = false; -extern int group_c; // panel.c -extern StoreOptions *get; +extern StoreOptions set, *get; // related indexes from json.h enum // for sorting entries @@ -105,10 +108,8 @@ item_idx_t *aux = NULL, char title [128]; -void GLES2_render_submenu_text_v2( vertex_buffer_t *vbo, vec3 *offset ); - // index (write) all used_tokens -int json_index_used_tokens_v2(layout_t *layout, char *json_data) +int json_index_used_tokens_v2(layout_t *l, char *json_data) { int r, i, c = 0; jsmn_parser p; @@ -121,18 +122,18 @@ int json_index_used_tokens_v2(layout_t *layout, char *json_data) if (r < 0) { klog("Failed to parse JSON: %d\n", r); return -1; } // grab last added index from current item count - int idx = layout->item_c; + int idx = l->item_c; item_idx_t *token = NULL; for(i = 1; i < r; i++) { // entry - layout->item_d[idx].token_c = NUM_OF_USER_TOKENS; + l->item_d[idx].token_c = NUM_OF_USER_TOKENS; // dynalloc for json tokens - if(!layout->item_d[idx].token_d) - layout->item_d[idx].token_d = calloc(layout->item_d[idx].token_c, sizeof(item_idx_t)); /// XXX -// klog("%s %p\n", __FUNCTION__, layout->item_d[idx].token_d); - token = &layout->item_d[idx].token_d[0]; + if(!l->item_d[idx].token_d) + l->item_d[idx].token_d = calloc(l->item_d[idx].token_c, sizeof(item_idx_t)); /// XXX +// printf("%s %p\n", __FUNCTION__, l->item_d[idx].token_d); + token = &l->item_d[idx].token_d[0]; int j; for(j = 0; j < NUM_OF_USER_TOKENS; j++) @@ -141,12 +142,6 @@ int json_index_used_tokens_v2(layout_t *layout, char *json_data) if (jsoneq(json_data, &t[i], used_token[j]) == 0) { /* We may use strndup() to fetch string value */ -#if 0 - klog("- %d) %d %d [%s]: %.*s\n", c, i, j, - used_token[j], - t[i + 1].end - t[i + 1].start, - json_data + t[i + 1].start); -#endif token[j].off = strndup(json_data + t[i + 1].start, t[i + 1].end - t[i + 1].start); token[j].len = t[i + 1].end - t[i + 1].start; @@ -158,12 +153,12 @@ int json_index_used_tokens_v2(layout_t *layout, char *json_data) // if less, shrink buffer: realloc if(j < NUM_OF_USER_TOKENS) { // shrink - layout->item_d[idx].token_c = j; - layout->item_d[idx].token_d = realloc(layout->item_d[idx].token_d, - layout->item_d[idx].token_c * sizeof(item_idx_t)); + l->item_d[idx].token_c = j; + l->item_d[idx].token_d = realloc(l->item_d[idx].token_d, + l->item_d[idx].token_c * sizeof(item_idx_t)); } // save current index from current item count - layout->item_c = idx; + l->item_c = idx; } /* this is the number of all counted items * NUM_OF_USER_TOKENS ! */ @@ -171,36 +166,34 @@ int json_index_used_tokens_v2(layout_t *layout, char *json_data) } -void clean_textures(layout_t *layout) +void clean_textures(layout_t *l) { - //glBindTexture( GL_TEXTURE_2D, 0 ); - - if(layout->texture) + if(l->texture) { - printf("%s: layout: %p, %p\n", __FUNCTION__, layout, layout->texture); - for(int i = 0; i < layout->fieldsize.x * layout->fieldsize.y; i++) + printf("%s: layout: %p, %p\n", __FUNCTION__, l, l->texture); + for(int i = 0; i < l->fieldsize.x * l->fieldsize.y; i++) { - if(layout->texture[i] != 0) + if(l->texture[i] != 0) { - printf("glDeleteTextures texture[%d]: %8x\n", i, layout->texture[i]); - glDeleteTextures(1, &layout->texture[i] ), layout->texture[i] = 0; + printf("glDeleteTextures texture[%2d]: %d\n", i, l->texture[i]); + glDeleteTextures(1, &l->texture[i] ), l->texture[i] = 0; } } - free(layout->texture), layout->texture = NULL; + free(l->texture), l->texture = NULL; } } - -void GLES2_destroy_layout(layout_t *layout) +// unused +void GLES2_destroy_layout(layout_t *l) { - if(!layout) return; + if(!l) return; - clean_textures(layout); + clean_textures(l); item_idx_t *token_d = NULL; - for(int i = 0; i < layout->item_c; i++) + for(int i = 0; i < l->item_c; i++) { - token_d = &layout->item_d[i].token_d[0]; + token_d = &l->item_d[i].token_d[0]; for(int j = 0; j < NUM_OF_USER_TOKENS; j++) // < token_c { @@ -208,15 +201,15 @@ void GLES2_destroy_layout(layout_t *layout) } if(token_d) free(token_d); } - if(layout->item_d) free(layout->item_d); + if(l->item_d) free(l->item_d); - if(layout->vbo) vertex_buffer_delete(layout->vbo), layout->vbo = NULL; + if(l->vbo) vertex_buffer_delete(l->vbo), l->vbo = NULL; - if(layout) free(layout), layout = NULL; + if(l) free(l), l = NULL; } -int GLES2_create_layout_from_json(layout_t *layout) +int GLES2_create_layout_from_json(layout_t *l) { char json_file[128]; void *p; @@ -234,7 +227,7 @@ int GLES2_create_layout_from_json(layout_t *layout) // check if(!p) break; - int valid_tokens = json_index_used_tokens_v2(layout, p); + int valid_tokens = json_index_used_tokens_v2(l, p); fprintf(INFO, "%d valid_tokens!\n", valid_tokens); // passed, increase num of available pages @@ -253,49 +246,14 @@ const char *download_panel_text[] = "What more?" }; -const char *option_panel_text[] = -{ - "eat", - "drink", - "smoke", - "fuck", - "code", - "repeat", - "Games", - "Apps", - "Groups", - "Ready to install", - "Updates", - "Queue", - "Game Pass", - "Gold","Games", - "Apps", - "Groups", - "Ready to install", - "Updates", - "Queue", - "Game Pass", - "Gold", - "eat", - "drink", - "smoke", - "fuck", - "code", - "repeat", - "eat", - "drink", - "smoke", - "fuck", - "code", - "repeat" -}; +extern const char *option_panel_text[]; // menu entry strings #define LPANEL_Y (5) const char *new_panel_text[LPANEL_Y][10] = { { // Main page: 6 "Games", - "Apps", + "Installed Apps", "Groups", "Ready to install", "Queue", @@ -307,7 +265,7 @@ const char *new_panel_text[LPANEL_Y][10] = { "Sort by", "Filter by" }, -{ // +{ // unused "1: connect socket", "2: screenshot", "3: Alpha", @@ -316,7 +274,7 @@ const char *new_panel_text[LPANEL_Y][10] = { "6: Blue", "7: test" }, -{ // +{ // unused "CDNURL", "http...", "Background Path", @@ -341,37 +299,36 @@ const char *new_panel_text[LPANEL_Y][10] = { /* indexes item_t item_data */ -int GLES2_create_layout_from_list_v2(layout_t *layout, const char **i_list) +int GLES2_create_layout_from_list_v2(layout_t *l, const char **i_list) { int i, j; item_idx_t *token = NULL; - for(i = 0; i < layout->item_c; i++) + for(i = 0; i < l->item_c; i++) { // dynallocs for items - if(!layout->item_d[i].token_d) + if(!l->item_d[i].token_d) { - layout->item_d[i].token_c = 10; // minimum - layout->item_d[i].token_d = calloc(layout->item_d[i].token_c, sizeof(item_idx_t)); + l->item_d[i].token_c = 10; // minimum + l->item_d[i].token_d = calloc(l->item_d[i].token_c, sizeof(item_idx_t)); } // iterate token_data - for(j = 0; j < layout->item_d[i].token_c; j++) - {// klog("\n%d, %d %s\n", i, j, new_panel_text[i][j]); - //i_list[i][j]); - token = &layout->item_d[i].token_d[j]; + for(j = 0; j < l->item_d[i].token_c; j++) + { + token = &l->item_d[i].token_d[j]; token->off = new_panel_text[i][j]; if(!token->off) { token->len = -1; break; } // stop here else token->len = strlen( token->off ); // - klog("%s %d\n", layout->item_d[i].token_d[j].off, - layout->item_d[i].token_d[j].len); + klog("%s %d\n", l->item_d[i].token_d[j].off, + l->item_d[i].token_d[j].len); } - if(j < layout->item_d[i].token_c) + if(j < l->item_d[i].token_c) { // shrink - layout->item_d[i].token_c = j; - layout->item_d[i].token_d = realloc(layout->item_d[i].token_d, - layout->item_d[i].token_c * sizeof(item_idx_t)); } + l->item_d[i].token_c = j; + l->item_d[i].token_d = realloc(l->item_d[i].token_d, + l->item_d[i].token_c * sizeof(item_idx_t)); } } return i; } @@ -401,21 +358,20 @@ int get_item_index(layout_t *l) /* indexes item_idx_t* token_data in a single item_t item_data */ -int GLES2_create_layout_from_list(layout_t *layout, const char **i_list) +int GLES2_create_layout_from_list(layout_t *l, const char **i_list) { int i; item_idx_t *token = NULL; - for(i = 0; i < layout->item_c; i++) - { - // dynallocs - if(!layout->item_d[i].token_d) + for(i = 0; i < l->item_c; i++) // iterate item_d + { // dynallocs each token_d + if(!l->item_d[i].token_d) { - layout->item_d[i].token_c = 1; // minimum - layout->item_d[i].token_d = calloc(layout->item_d[i].token_c, sizeof(item_t)); + l->item_d[i].token_c = 1; // minimum, one token_d + l->item_d[i].token_d = calloc(l->item_d[i].token_c, sizeof(item_t)); } - - token = &layout->item_d[i].token_d[0]; + // we use just the first token_d + token = &l->item_d[i].token_d[0]; token->off = i_list[i]; token->len = strlen( i_list[i] ); } @@ -423,7 +379,8 @@ int GLES2_create_layout_from_list(layout_t *layout, const char **i_list) } // disk free percentage -float dfp = 0.; +double dfp_hdd = 0., + dfp_ext = 0.; // pthread extern atomic_ulong g_progress; /* @@ -494,7 +451,7 @@ void GLES2_render_layout(layout_t *layout, int unused) item_t *li = NULL; // layout item iterator if(layout == download_panel) - { //f_selection = icon_panel->item_sel.y * icon_panel->fieldsize.x + icon_panel->item_sel.x; + { // the field size, in items; field_s = layout->fieldsize.x * layout->fieldsize.y; // fullscreen frect (normalized coordinates) vec4 t = (vec4) { -1., -1., 1., 1. }; @@ -522,13 +479,13 @@ void GLES2_render_layout(layout_t *layout, int unused) sprintf(&title[0], "%s", icon_panel->item_d[i].token_d[NAME].off); - // apply a shader on top of background + // apply a shader on top of background image (shading, eh...) pixelshader_render(0); } // we cleaned vbo ? if( ! layout->vbo ) layout->vbo = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); - vec2 p, s, // position, size + vec2 p, s, b, // position, size, border in px pen; // text position, in px vec4 r, // normalized rectangle selection_box, @@ -539,6 +496,15 @@ void GLES2_render_layout(layout_t *layout, int unused) col = (vec4) { .8164, .8164, .8125, 1. }, t_sel = (vec4) { 256, 0, 0, 256 } / 256; // red + // default 3 px border between rectangles + b = (vec2) (3); + // override and set custom border .xy vector + if(layout == option_panel) + { + field_s = layout->item_c; + b = (vec2) { 40, 4 }; + } + int i; // iterate items we are about to draw for(i = 0; i < field_s; i++) @@ -552,7 +518,6 @@ void GLES2_render_layout(layout_t *layout, int unused) { if(aux) // we have an auxiliary serch result item list to show...l li = &icon_panel->item_d[ aux[ i_paged + i +1 /*skip first*/].len ]; - } /* compute origin position for this item */ s = (vec2) { layout->bound_box.z / layout->fieldsize.x, @@ -560,11 +525,11 @@ void GLES2_render_layout(layout_t *layout, int unused) p = (vec2) { (float)(layout->bound_box.x + (i % (int)layout->fieldsize.x) - * (s.x +3 /* px border */)) + * (s.x + b.x /* px border */)) , (float)(layout->bound_box.y - (i / layout->fieldsize.x) - * (s.y +3 /* px border */)) }; + * (s.y + b.y /* px border */)) }; // here we scroll page UP/DOWN if(layout == download_panel && offset.y != 0) p.y += offset.y; @@ -604,15 +569,14 @@ void GLES2_render_layout(layout_t *layout, int unused) #if defined (USE_NFS) char *p = strstr(&tmp[0], "storedata"); layout->texture[i] = load_png_asset_into_texture(p); -#else - +#else + // open int fd = sceKernelOpen(li->token_d[PICPATH].off, 0x0000, 0); // local path is directly token value if (fd < 0) { - - if(rrr[i].failed_dl != 1) - { + if(rrr[i].failed_dl != 1) + { loadmsg("Downloading Icons....\n"); klog("downloading %s from %s", li->token_d[PICPATH].off, li->token_d[IMAGE].off); if(dl_from_url(li->token_d[IMAGE].off, li->token_d[PICPATH].off, false) != 0) @@ -622,24 +586,16 @@ void GLES2_render_layout(layout_t *layout, int unused) fprintf(INFO, "texture[%2d] = %3d\n", i, layout->texture[i]); last_item_dl = i; - } - else if(rrr[i].failed_dl == 1) - layout->texture[i] = load_png_asset_into_texture("/user/appmeta/NPXS39041/icon0.png"); - - + } + else if(rrr[i].failed_dl == 1) + layout->texture[i] = load_png_asset_into_texture("/user/appmeta/NPXS39041/icon0.png"); } else { - printf("fd %i\n", fd); sceKernelClose(fd); layout->texture[i] = load_png_asset_into_texture(&tmp[0]); - } - - - - - - + } + // on the last item of the fieldsize... if(i == field_s -1) sceMsgDialogTerminate(); #endif @@ -651,10 +607,18 @@ void GLES2_render_layout(layout_t *layout, int unused) // save pen origin for text, in pixel coordinates! pen = p; + /* draw the related rectangle, for iterating item */ if(layout == download_panel) - { // draw bounding box for each button selector + { // draw bounding box for each button selector ORBIS_RenderDrawBox(USE_COLOR, &grey, &r); } + else + if(layout == option_panel) + { // normalize a new color + vec4 c = (vec4) { 41., 41., 41., 256. } / 256.; + // gles render the single iterated rectangle + ORBIS_RenderFillRects(USE_COLOR, &c, &r, 1); + } // is item the selected one? if(i == f_selection) @@ -697,9 +661,8 @@ void GLES2_render_layout(layout_t *layout, int unused) // save frect for optional glowing selection box or... selection_box = r; } - // LEFT PANEL: texts + // setup vbo texts from token data, for item -// if(layout->is_active) { if(layout == left_panel || layout == option_panel @@ -715,23 +678,76 @@ void GLES2_render_layout(layout_t *layout, int unused) { // address current layout item_t to Groups array sprintf(&tmp[0], "%s", groups[i +1].token_d[0].off); } - } else { // get the first indexed token value - snprintf(&tmp[0], li->token_d[0].len + 1, - "%s", li->token_d[0].off); } + } + else + if(layout == option_panel) + { // get the option label + sprintf(&tmp[0], "%s", li->token_d[0].off); + // append to vbo + vec2 tp = pen + 26.; + tp.y += 60.; + add_text( layout->vbo, sub_font, &tmp[0], &col, &tp); + // zerofill + memset(&tmp[0], 0, sizeof(tmp)); + // default text format + char *format = "%s"; + // get the option value + if(i < NUM_OF_STRINGS) + { // shorten any entry longer than n chars + if(strlen(get->opt[ i ]) > 40) format = "%.40s..."; + + sprintf(&tmp[0], format, get->opt[ i ]); + } + else + { // to extend for more options + sprintf(&tmp[0], format, get->StoreOnUSB ? "True" : "False"); + } + } + else + { // try to get the first indexed token value + if(li->token_d) { + snprintf(&tmp[0], li->token_d[0].len + 1, + "%s", li->token_d[0].off); + } else { // safe fallback + sprintf(&tmp[0], "%d, %p", i, li->token_d); + } + } // fprintf(INFO, "%.3f %.3f '%s'\n", pen.x, pen.y, tmp); // append the vbo pen += 26; - add_text( layout->vbo, sub_font, &tmp[0], &col, &pen); - - // draw Ready to install, Queue, Groups numbers + // on Settings change color and font for value + if(layout == option_panel) { + vec4 c = col * .75f; + add_text( layout->vbo, main_font, &tmp[0], &c, &pen); } + else // default + add_text( layout->vbo, sub_font, &tmp[0], &col, &pen); + + /* draw Ready to install, Queue, Groups numbers */ if(layout == left_panel) { - if(layout->page_sel.x == 0 && i == 2) // on main page + if(layout->page_sel.x == 0) // on main page { - sprintf(&tmp[0], "%d", groups->token_c); - texture_font_load_glyphs( sub_font, &tmp[0] ); - pen.x = 460 - tl; - add_text( layout->vbo, sub_font, &tmp[0], &col, &pen); + int ret = 0, + req_status = 0; + // one item label per line + switch(i) + { // Groups + case 2: ret = groups->token_c; break; + // Ready to install + case 3: req_status = COMPLETED; break; + // Queue + case 4: req_status = RUNNING; break; + } + // if requested, count threads + if(req_status) ret = thread_count_by_status( req_status ); + + if(ret) // we have at least counted one + { + sprintf(&tmp[0], "%d", ret); + texture_font_load_glyphs( sub_font, &tmp[0] ); + pen.x = 460 - tl; + add_text( layout->vbo, sub_font, &tmp[0], &col, &pen); + } } else if(layout->page_sel.x == LPANEL_Y) // on Group list page @@ -743,30 +759,6 @@ void GLES2_render_layout(layout_t *layout, int unused) add_text( layout->vbo, sub_font, &tmp[0], &col, &pen); } else - if(layout->page_sel.x == 0 && i == 3) // on main page, Ready to install - { - int ret = thread_count_by_status( COMPLETED ); - if(ret) - { - sprintf(&tmp[0], "%d", ret); - texture_font_load_glyphs( sub_font, &tmp[0] ); - pen.x = 460 - tl; - add_text( layout->vbo, sub_font, &tmp[0], &col, &pen); - } - } - else - if(layout->page_sel.x == 0 && i == 4) // on main page, Queue - { - int ret = thread_count_by_status( RUNNING ); - if(ret) - { - sprintf(&tmp[0], "%d", ret); - texture_font_load_glyphs( sub_font, &tmp[0] ); - pen.x = 460 - tl; - add_text( layout->vbo, sub_font, &tmp[0], &col, &pen); - } - } - else if(layout->page_sel.x == LPANEL_Y + 1) // on group item page { printf("QUEUE\n"); @@ -815,13 +807,22 @@ void GLES2_render_layout(layout_t *layout, int unused) // fill the vbo add_text( layout->vbo, main_font, &tmp[0], &c, &pen); + sprintf(&tmp[0], "Store Version: %s", completeVersion); + // we need to know Text_Length_in_px in advance, so we call this: + texture_font_load_glyphs( main_font, &tmp[0] ); + // we know 'tl' now, right align + pen.x = resolution.x - tl - 50, + pen.y -= 32; + // fill the vbo + add_text( layout->vbo, main_font, &tmp[0], &c, &pen); + //sprintf(&tmp[0], "Available Apps to download (Store)"); // snprintf(&title[0], li->token_d[f_selection].len + 1, // "%s", li->token_d[f_selection].off); pen = (vec2) { 670, resolution.y - 100 }; // fill the vbo - add_text( layout->vbo, sub_font, &title[0], &col, &pen); + add_text( layout->vbo, titl_font, &title[0], &col, &pen); // item and page index infos: ivec2 item_index = (ivec2)(0), @@ -841,6 +842,13 @@ void GLES2_render_layout(layout_t *layout, int unused) page_index.x = icon_panel->page_sel.x +1; page_index.y = icon_panel->page_sel.y +1; } + // Queue / Ready to install views overrides ! + if(menu_pos.z == ON_SUBMENU + || menu_pos.z == ON_SUBMENU3 + || menu_pos.z == ON_SETTINGS) { + item_index.y = 0; + } + // we have at least an entry ? if(item_index.y > 0) { @@ -853,6 +861,7 @@ void GLES2_render_layout(layout_t *layout, int unused) // fill the vbo add_text( layout->vbo, sub_font, &tmp[0], &col, &pen); + // draw again, lower left sprintf(&tmp[0], "%s", li->token_d[ID].off); // fill the vbo pen = (vec2) { 670, 150 }; @@ -861,13 +870,16 @@ void GLES2_render_layout(layout_t *layout, int unused) // eventually, skip dfp on some view... //if(layout->page_sel.x < LPANEL_Y) { /* text for disk_free stats */ - pen = (vec2) { 26, 100 }; - dfp = df(&tmp[0], "/user"); + pen = (vec2) { 26, 100 }; + vec4 c = col * .75f; // fill the vbo add_text( layout->vbo, sub_font, "Storage", &col, &pen); - pen.x = 26, - pen.y -= 32; - vec4 c = col * .75f; + // new line + pen.x = 26, + pen.y -= 32; + + + dfp_hdd = df(&tmp[0], "/user"); add_text( layout->vbo, main_font, &tmp[0], &c, &pen); } } @@ -910,13 +922,11 @@ void GLES2_render_layout(layout_t *layout, int unused) r.zw = px_pos_to_normalized(&s); // gles render the frect ORBIS_RenderFillRects(USE_COLOR, &grey, &r, 1); - // shrink frect RtoL by custom_percentage - r.z = r.x + (r.z - r.x) * (ta->progress / 100.f); -// fprintf(INFO, "%.2f %.2f, %.2f, %.2f %f\n", r.x, r.y, r.z, r.w, dfp); - ORBIS_RenderFillRects(USE_COLOR, &sele, &r, 1); + /* draw filling color bar, by percentage */ + GLES2_DrawFillingRect(&r, &sele, &ta->progress); switch(f_selection) - { // change color when disabled + { // change frect color when disabled case 0: if(ta->status == RUNNING ) t_sel = grey; break; case 1: if(ta->status != COMPLETED) t_sel = grey; break; } @@ -946,7 +956,15 @@ void GLES2_render_layout(layout_t *layout, int unused) case READY: case COMPLETED: sprintf(&tmp[0], ", Download Completed"); break; + default: sprintf(&tmp[0], ", Download error: %i", ta->status); + break; + } + + if (http_ret != 200 && http_ret != 0) + { + sprintf(&tmp[0], ", Download Failed with %i", http_ret); } + // fill the vbo add_text( layout->vbo, main_font, &tmp[0], &col, &pen); } @@ -1020,15 +1038,21 @@ void GLES2_render_layout(layout_t *layout, int unused) { // no thread is downloading item ORBIS_RenderFillRects(USE_COLOR, &t_sel, &r, 1); } - else + else // each other layout != download_panel { ORBIS_RenderFillRects(USE_COLOR, &grey, &r, 1); } // rightmost blue rect, just on selection! if(layout->is_active) - { // shrink frect LtoR - r.x = r.z - .0075f; - ORBIS_RenderFillRects(USE_COLOR, &sele, &r, 1); + { + if(layout == option_panel) + { // the glowing color box selector + ORBIS_RenderDrawBox(USE_UTIME, &sele, &r); + } else { + // shrink frect LtoR to paint rightmost blue selector + r.x = r.z - .0075f; + ORBIS_RenderFillRects(USE_COLOR, &sele, &r, 1); + } } // texts out of layout vbo GLES2_render_submenu_text_v2(layout->vbo, NULL); @@ -1053,10 +1077,8 @@ void GLES2_render_layout(layout_t *layout, int unused) r = (vec4) { -.975, -.900, -.505, -.905 }; // gles render the frect ORBIS_RenderFillRects(USE_COLOR, &grey, &r, 1); - // shrink frect RtoL by disk_free_percentage - r.z = r.x + (r.z - r.x) * (dfp / 100.f); -// fprintf(INFO, "%.2f %.2f, %.2f, %.2f %f\n", r.x, r.y, r.z, r.w, dfp); - ORBIS_RenderFillRects(USE_COLOR, &sele, &r, 1); + /* draw filling color bar, by percentage */ + GLES2_DrawFillingRect(&r, &sele, &dfp_hdd); } } } @@ -1069,7 +1091,7 @@ layout_t * GLES2_layout_init(int req_item_count) if( !l ) return NULL; l->page_sel.x = 0; - // dynalloc for max requested num of items + // dynalloc for max requested number of items l->item_c = req_item_count; l->item_d = calloc(l->item_c, sizeof(item_t)); @@ -1168,13 +1190,15 @@ void GLES2_scene_init( int w, int h ) { if( ! option_panel ) option_panel = calloc(1, sizeof(layout_t)); - option_panel->bound_box = (ivec4) { resolution.x -100 -1280, resolution.y -300, - 1280, 720 }; - option_panel->fieldsize = (ivec2) { 1, 16 }; - option_panel->page_sel.x = 0; +/* option_panel->bound_box = (ivec4) { resolution.x -100 -1280, resolution.y -300, + 1280, 720 }; */ + option_panel->bound_box.xy = icon_panel->bound_box.xy; + option_panel->bound_box.zw = (ivec2) { 980, 512 }; + option_panel->fieldsize = (ivec2) { 2, 4 }; + option_panel->page_sel.x = 0; // malloc for max items - option_panel->item_c = option_panel->fieldsize.x * option_panel->fieldsize.y; - option_panel->item_d = calloc(option_panel->item_c, sizeof(item_t)); + option_panel->item_c = sizeof(option_panel_text) / sizeof(option_panel_text[0]); + option_panel->item_d = calloc(option_panel->item_c, sizeof(item_t)); // create the first screen we will show GLES2_create_layout_from_list(option_panel, &option_panel_text[0]); @@ -1189,20 +1213,20 @@ void GLES2_scene_init( int w, int h ) { if( ! download_panel ) download_panel = calloc(1, sizeof(layout_t)); - download_panel->bound_box = (ivec4) { 500, (resolution.y -64) /8, - 1024, 64 }; - download_panel->fieldsize = (ivec2) { 3, 1 }; + download_panel->bound_box = (ivec4) { 500, (resolution.y -64) /8, + 1024, 64 }; + download_panel->fieldsize = (ivec2) { 3, 1 }; download_panel->page_sel.x = 0; // malloc for max items - download_panel->item_c = download_panel->fieldsize.x * download_panel->fieldsize.y; - download_panel->item_d = calloc(download_panel->item_c, sizeof(item_t)); + download_panel->item_c = download_panel->fieldsize.x * download_panel->fieldsize.y; + download_panel->item_d = calloc(download_panel->item_c, sizeof(item_t)); // create the first screen we will show GLES2_create_layout_from_list(download_panel, &download_panel_text[0]); fprintf(INFO, "layout->item_c: %d\n", download_panel->item_c); // flag as active - download_panel->is_shown = - download_panel->is_active = 0; + download_panel->is_shown = + download_panel->is_active = 0; // set max_pages download_panel->page_sel.y = download_panel->item_c / (download_panel->fieldsize.x * download_panel->fieldsize.y); } @@ -1214,25 +1238,22 @@ void GLES2_scene_init( int w, int h ) // init shaders for textures on_GLES2_Init_icons(w, h); - // init shaders for lines and rects ORBIS_RenderFillRects_init(w, h); - // init shaders for texts - GLES2_init_submenu(); - - // optional additions + // init ttf fonts + GLES2_fonts_from_ttf(get->opt[ FNT_PATH ]); + // init ani_notify() GLES2_ani_init(w, h); // pixelshader_init(w, h); } -void GLES2_UpdateVboForLayout(layout_t *layout) +void GLES2_UpdateVboForLayout(layout_t *l) { - if(layout->vbo) vertex_buffer_delete(layout->vbo), layout->vbo = NULL; - //for(int i= 0; i < layout->item_c; i++) - // { layout->item_d[i].in_atlas = 0; } - if(layout->vbo_s) layout->vbo_s = EMPTY; + if(l->vbo) vertex_buffer_delete(l->vbo), l->vbo = NULL; + + if(l->vbo_s) l->vbo_s = EMPTY; } @@ -1264,7 +1285,7 @@ void GLES2_scene_render(void) { case ON_TEST_ANI: { - render_text(); // freetype demo-font.c, renders text just from init_ + //render_text(); // freetype demo-font.c, renders text just from init_ /* GLES2_ani_test(NULL); GLES2_ani_update(u_t); */ @@ -1283,13 +1304,17 @@ void GLES2_scene_render(void) // Queue view case ON_SUBMENU: GLES2_render_queue (queue_panel, 0); - GLES2_render_layout(left_panel, 0); + GLES2_render_layout(left_panel, 0); break; // Ready to install view case ON_SUBMENU3: GLES2_render_queue (queue_panel, 9); - GLES2_render_layout(left_panel, 0); + GLES2_render_layout(left_panel, 0); break; + case ON_SETTINGS: + GLES2_render_layout(option_panel, 0); + GLES2_render_layout(left_panel, 0); + break; default: break; } @@ -1306,12 +1331,17 @@ void GLES2_scene_render(void) -// just used in download panel for now +// just used in download panel for now, +// can be extended to deal with Settings void X_action_dispatch(int action, layout_t *l) { + char tmp[256]; // selected item from active panel fprintf(INFO, "execute %d -> '%s'\n", action, l->item_d[ action ].token_d[0].off); + /* actually on Setting we jump there... */ + if(l == option_panel) goto actions_for_Settings; + char *trigger = l->item_d[ action ].token_d[0].off; int label = NAME; @@ -1329,11 +1359,10 @@ void X_action_dispatch(int action, layout_t *l) trigger, // icon_panel->item_d[ idx ].token_d[ label ].off, t[ label ].off); - char tmp[256]; // default //sprintf(&tmp[0], "/user/app/temp.pkg"); // avoid same donwload path - sprintf(&tmp[0], "%s/%s.pkg", get->temppath, t[ ID ].off); + sprintf(&tmp[0], "%s/%s.pkg", get->opt[ TMP_PATH ], t[ ID ].off); dl_arg_t *ta = NULL; int x = thread_find_by_item( idx ); @@ -1345,15 +1374,16 @@ void X_action_dispatch(int action, layout_t *l) } switch(action) - { + { /* Donwload */ case 0: { // a thread is downloading item, skip if(x > -1) return; http_ret = 0; - if( dl_from_url_v2( t[ label ].off, &tmp[0], t) ) + if(http_ret = dl_from_url_v2( t[ label ].off, &tmp[0], t) ) ls_dir("/user/app"); } break; + /* Install */ case 1: { if(ta && ta->status == COMPLETED) @@ -1373,15 +1403,118 @@ void X_action_dispatch(int action, layout_t *l) printf("%s\n", "more"); break; } + return; + +actions_for_Settings: + + switch(action) + { // use sceKbd to edit related field + case CDN_URL : + case TMP_PATH: + case INI_PATH: + case FNT_PATH: + + if(action == INI_PATH) + msgok(WARNING, "You are making a NEW INI\n The app WILL NOT use this INI\n also it will NOT be saved to the INI the app is using!"); + + klog("%p, %s\n", l, get->opt[action]); + snprintf(&tmp[0], 255, "%s\n", StoreKeyboard(l->item_d[action].token_d[0].off, get->opt[action])); + // clean string, works for LF, CR, CRLF, LFCR, ... + tmp[strcspn(tmp, "\r\n")] = 0; + // check for valid result + if (strlen(tmp) <= 1 || strlen(tmp) >= 255 ) { + msgok(NORMAL, "String is either too long or Invaild Please enter a vaild entry"); goto error; + } + + if(action != CDN_URL && strstr(tmp, "/user") == NULL) + { + if(strstr(tmp, "/mnt") == NULL) + { + if(strstr(tmp, "/data") == NULL) + { + if(strstr(tmp, "/system_ex") == NULL) + { + msgok(NORMAL, "Invaild Path!\n enter a vaild path"); goto error; + } + } + } + } + + if(action == TMP_PATH && strstr(tmp, "pkg") != NULL || strstr(tmp, "/data") != NULL) + { + msgok(NORMAL, "Pkg Suffix and /data path are disallowed for TEMP PATH\n NOTE: DO NOT include .pkg in your temp path"); goto error; + } + + // validate result (CDN) + if(action == CDN_URL && strstr(tmp, "http://") == NULL) + { + msgok(NORMAL, "Invaild CDN\n make sure its in the format http://CDN/ \n no Https urls are allowed"); goto error; + } + + // update + klog("Options: %i Before: %.30s -> After: %.30s\n", action, get->opt[action], tmp); + + // store + sprintf(get->opt[action], "%s", tmp); + + klog("get->opt[%i]: %.20s\n", action, get->opt[action]); + + // try to load custom font + if(action == FNT_PATH){ + if(strstr(get->opt[action],".ttf") != NULL) + GLES2_fonts_from_ttf(get->opt[action]); + else + msgok(NORMAL, "Invaild .ttf path\n Please ensure the file ext is .ttf"); goto error; + + } + + assert(strcmp(get->opt[action], tmp) == 0); + break; + + error: + klog("ERROR: entered %.20s \n", tmp); + break; + + case USB_PATH: + msgok(NORMAL, "This is NOT an editable Entry, it is created at App Boot"); + break; + + // execute action, set flags + case 5: //STORE_ON_USB + if(get->opt[action]) + { + get->opt[action] = 0; + sprintf(get->opt[TMP_PATH], "%s", "/user/app"); + } else { + get->opt[action] = 1; + sprintf(get->opt[TMP_PATH], "%s", "/mnt/usb0"); + } + break; + + case 6: //SAVE_OPTIONS: + klog("%p, %d\n", l, action); + + if( ! SaveOptions(get) ) + msgok(WARNING, "Save error, your changes were NOT saved\n"); + else + { + msgok(NORMAL, "Your changes were saved successfully\n"); + klog("Settings saved to %s\n", get->opt[INI_PATH]); + // reload settings + LoadOptions(get); + } + + //do_something(action); + break; + } + + return; } void O_action_dispatch(void) { // reset the auxiliary list if(menu_pos.z != ON_SUBMENU_2) aux = NULL; - // trigger textures refresh - if(menu_pos.z != ON_SUBMENU_2) - icon_panel->refresh = 1; // refresh vbo for common texts GLES2_UpdateVboForLayout(left_panel); @@ -1431,47 +1564,47 @@ void GLES2_scene_on_pressed_button(int button) f_size, f_selection; // pointer to current panel - layout_t *p = NULL; + layout_t *l = NULL; // on which VIEW are we? switch(menu_pos.z) // as view { - case ON_LEFT_PANEL : p = left_panel; break; + case ON_LEFT_PANEL : l = left_panel; break; case ON_SUBMENU : - case ON_SUBMENU3 : p = queue_panel; break; - case ON_SUBMENU_2 : p = download_panel; break; + case ON_SUBMENU3 : l = queue_panel; break; + case ON_SUBMENU_2 : l = download_panel; break; + case ON_SETTINGS : l = option_panel; break; case ON_MAIN_SCREEN: http_ret = 0; - default: p = icon_panel; break; + default: l = icon_panel; break; } - - -for(int i = 0; i < 12; i++) - rrr[i].failed_dl = 0; + + for(int i = 0; i < 12; i++) + rrr[i].failed_dl = 0; step1: - result = p->item_sel; - f_size = p->fieldsize.x * p->fieldsize.y; + result = l->item_sel; + f_size = l->fieldsize.x * l->fieldsize.y; - if(p == left_panel) - bounds = (ivec2) { p->fieldsize.x -1, p->item_d[p->page_sel.x].token_c -1 }; + if(l == left_panel) + bounds = (ivec2) { l->fieldsize.x -1, l->item_d[l->page_sel.x].token_c -1 }; else { // compute some indexes, first one of layout: i_paged = f_size - * p->page_sel.x; + * l->page_sel.x; // which icon is selected in field X*Y ? - f_selection = p->item_sel.y * p->fieldsize.x - + p->item_sel.x; + f_selection = l->item_sel.y * l->fieldsize.x + + l->item_sel.x; // which item is selected over all ? - p->curr_item = f_selection + i_paged; + l->curr_item = f_selection + i_paged; // set default bounds - result = p->item_sel; + result = l->item_sel; // bounds indexes from 0! - bounds = p->fieldsize -1; + bounds = l->fieldsize -1; /* if last page can't fill the field, how many are / REMains? */ - int rem = p->item_c - i_paged; + int rem = l->item_c - i_paged; // if we have an auxiliary item list to show... - if(p == icon_panel + if(l == icon_panel && aux) rem = aux->len - i_paged; // decrease the field size! @@ -1479,13 +1612,12 @@ for(int i = 0; i < 12; i++) { f_size = rem; //printf("f_size = %d\n", f_size); //3 - //int ret = p->item_c - p->curr_item; //fprintf(INFO, "we can't fill the page, just %d items\n", ret); fprintf(INFO, "last page, fieldsize: %d items\n", f_size); // max possible bounds - ivec2 ret = idx_to_pos_xy(f_size, p->fieldsize); + ivec2 ret = idx_to_pos_xy(f_size, l->fieldsize); // 7: 2, 1 - if(ret.y > 0) ret.x = p->fieldsize.x; + if(ret.y > 0) ret.x = l->fieldsize.x; // remember we indexes bounds from 0! ret.x -= 1; bounds = ret; @@ -1516,14 +1648,14 @@ for(int i = 0; i < 12; i++) case L1 : { if(menu_pos.z == ON_SUBMENU_2) { - p = icon_panel; posi.x--; we_moved = 1; + l = icon_panel; posi.x--; we_moved = 1; goto step1; } } break; case R1 : { if(menu_pos.z == ON_SUBMENU_2) { - p = icon_panel; posi.x++; we_moved = 1; + l = icon_panel; posi.x++; we_moved = 1; goto step1; } } break; @@ -1531,68 +1663,78 @@ for(int i = 0; i < 12; i++) case CRO: { we_moved = 1; // trigger vbo refresh - fprintf(INFO, "execute: (%d/%d), %d, %d\n", p->page_sel.x, p->page_sel.y, - p->item_sel.x, p->item_sel.y); + fprintf(INFO, "execute: (%d/%d), %d, %d\n", l->page_sel.x, l->page_sel.y, + l->item_sel.x, l->item_sel.y); // token value - //klog("%s\n", p->item_d[p->curr_page].token_d[p->curr_item].off); - + //printf("%s\n", l->item_d[l->curr_page].token_d[l->curr_item].off); if(menu_pos.z == ON_LEFT_PANEL) { /* "Main" page (0) */ - if(p->page_sel.x == 0 // first page - && p->item_sel.y < 1) // first entry + if(l->page_sel.x == 0 // first page + && l->item_sel.y < 1) // first entry { // switch menu entry, lose focus - p->page_sel.x = 1; p->is_active = 0, + l->page_sel.x = 1; l->is_active = 0, // activate and set focus icon_panel->is_active = 1; menu_pos.z = ON_MAIN_SCREEN; break; } - - if(p->page_sel.x == 0 && // first page, - ( p->item_sel.y == 1 // first entry - || p->item_sel.y == 5 // or sixth - || p->item_sel.y == 6 )) // or seventh + // LP: X on + if(l->page_sel.x == 0 && // first page, + ( l->item_sel.y == 1 // first entry + || l->item_sel.y == 5 )) // or sixth { //ani_notify("Cooming soon!"); msgok(NORMAL, "Coming Soon!"); break; } - - // LP: X on Groups - if(p->page_sel.x == 0 // first page - && p->item_sel.y == 2) // second entry - { - p->page_sel.x = 5; // switch page - result = (ivec2)(0); // reset first entry - break; + // LP: X on Settings + if(l->page_sel.x == 0 // first page + && l->item_sel.y == 6) // seventh entry + { // switch menu entry, lose focus + l->is_active = 0; + // activate and set focus + l = option_panel; // switch control + l->is_active = l->is_shown = 1; menu_pos.z = ON_SETTINGS; + result = (ivec2)(0); // reset first entry + break; } - if(p->page_sel.x == 0 // first page - &&(p->item_sel.y == 3 // fourth entry, or - || p->item_sel.y == 4)) // fifth entry + // LP: X on + if(l->page_sel.x == 0 // first page + &&(l->item_sel.y == 3 // fourth entry, or + || l->item_sel.y == 4)) // fifth entry { // switch menu entry, lose focus - p->page_sel.x = 0; p->is_active = 0; + l->page_sel.x = 0; l->is_active = 0; left_panel->is_active = icon_panel->is_active = 0; - if(p->item_sel.y == 3) menu_pos.z = ON_SUBMENU3; + if(l->item_sel.y == 3) menu_pos.z = ON_SUBMENU3; else - if(p->item_sel.y == 4) menu_pos.z = ON_SUBMENU; + if(l->item_sel.y == 4) menu_pos.z = ON_SUBMENU; // activate and set focus queue_panel_init(); - p = queue_panel; // switch control - p->page_sel.x = 0; - p->is_active = p->is_shown = 1; + l = queue_panel; // switch control + l->page_sel.x = 0; + l->is_active = l->is_shown = 1; // reset selection to first entry - p->item_sel = + l->item_sel = result = (ivec2) (0); break; } + // LP: X on Groups + if(l->page_sel.x == 0 // first page + && l->item_sel.y == 2) // second entry + { + l->page_sel.x = 5; // switch page + result = (ivec2)(0); // reset first entry + break; + } + // LP: X on Sort token: trigger action - if(p->page_sel.x == 4) // trigger sort selection by token + if(l->page_sel.x == 4) // trigger sort selection by token { - set_cmp_token(p->item_sel.y); + set_cmp_token(l->item_sel.y); /* resort using custom comparision function */ qsort(icon_panel->item_d, icon_panel->item_c, sizeof(item_t), struct_cmp_by_token); // refresh Groups item_idx_t* array @@ -1601,8 +1743,8 @@ for(int i = 0; i < 12; i++) icon_panel->refresh = 1; // switch focus, set back Games view menu_pos.z = ON_MAIN_SCREEN; // switch view - p->is_active = 0; p->page_sel.x = 1; - icon_panel->is_active = 1; p->item_sel.y = 1; + l->is_active = 0; l->page_sel.x = 1; + icon_panel->is_active = 1; l->item_sel.y = 1; // first page, reset selection to first item icon_panel->page_sel.x = 0; // reset selection to first entry @@ -1614,13 +1756,13 @@ for(int i = 0; i < 12; i++) /* "Games" page (1) */ // LP: X on Search - if(p->page_sel.x == 1 // second page - && p->item_sel.y == 0) // first entry + if(l->page_sel.x == 1 // second page + && l->item_sel.y == 0) // first entry { - char pattern[32]; + char pattern[70]; klog("execute openDialogForSearch()\n"); // get char *pattern - sprintf(&pattern[0], "%s", StoreKeyboard()); + sprintf(&pattern[0], "%s", StoreKeyboard(NULL, "Search...")); klog("@@@@@@@@@ Search for: %s\n", pattern); loadmsg("Searching...."); @@ -1645,8 +1787,8 @@ for(int i = 0; i < 12; i++) icon_panel->refresh = 1; // switch focus menu_pos.z = ON_MAIN_SCREEN; // switch view - p->is_active = 0; //p->page_sel.x = 1; - icon_panel->is_active = 1; //p->item_sel.y = 1; + l->is_active = 0; + icon_panel->is_active = 1; // first page, reset selection to first item icon_panel->page_sel.x = 0; // set max_pages by search results count! @@ -1670,26 +1812,26 @@ for(int i = 0; i < 12; i++) } // LP: X on Sort: switch LP page - if(p->page_sel.x == 1 // second page - && p->item_sel.y == 1) // second entry + if(l->page_sel.x == 1 // second page + && l->item_sel.y == 1) // second entry { - p->page_sel.x = 4; // switch entry + l->page_sel.x = 4; // switch entry result = (ivec2)(0); // reset first entry } /* "Group" page (5 (LPANEL_Y)) */ // LP: X on Group item - if(p->page_sel.x == LPANEL_Y) // Group page + if(l->page_sel.x == LPANEL_Y) // Group page { - printf("%d: %s %d\n", p->item_sel.y, - groups[p->item_sel.y +1].token_d[0].off, - groups[p->item_sel.y +1].token_c); + printf("%d: %s %d\n", l->item_sel.y, + groups[l->item_sel.y +1].token_d[0].off, + groups[l->item_sel.y +1].token_c); - aux = &groups[p->item_sel.y +1].token_d[0]; - aux->len = groups[p->item_sel.y +1].token_c; + aux = &groups[l->item_sel.y +1].token_d[0]; + aux->len = groups[l->item_sel.y +1].token_c; // leave selection saved - result = p->item_sel; + result = l->item_sel; // jump there to complete the job goto wen_found_hit; } @@ -1697,7 +1839,6 @@ for(int i = 0; i < 12; i++) else if(menu_pos.z == ON_MAIN_SCREEN) { - // we have an auxiliary serch result item list to show... if(aux) { @@ -1719,13 +1860,13 @@ for(int i = 0; i < 12; i++) switch_to_download: menu_pos.z = ON_SUBMENU_2; // switch view - p = download_panel; // switch control - p->page_sel.x = 0; - p->is_active = p->is_shown = 1; + l = download_panel; // switch control + l->page_sel.x = 0; + l->is_active = l->is_shown = 1; left_panel->is_active = icon_panel->is_active = 0; // reset selection to first item - p->item_sel = + l->item_sel = result = (ivec2) (0); // reset vertical displace offset = (vec3) (0); @@ -1735,7 +1876,6 @@ for(int i = 0; i < 12; i++) if(menu_pos.z == ON_ITEM_PAGE) { - //klog("package: %s\n", get_json_token_value(&selected_row->item[selected_icon].token[0], PACKAGE)); } else if(menu_pos.z == ON_SUBMENU @@ -1743,22 +1883,21 @@ for(int i = 0; i < 12; i++) { int req_status; switch(left_panel->item_sel.y) - { - case 3: // Ready to install - req_status = COMPLETED; break; - queue_panel->fieldsize.y = thread_count_by_status( req_status ); break; - case 4: // Queue - req_status = RUNNING; break; - queue_panel->fieldsize.y = thread_count_by_status( req_status ); break; + { // Ready to install + case 3: req_status = COMPLETED; break; + // Queue + case 4: req_status = RUNNING; break; } + // update panel field_size to match the number of requested threads + queue_panel->fieldsize.y = thread_count_by_status( req_status ); // which thread is the 'i'th - int idx = thread_find_by_status(p->item_sel.y, req_status); + int idx = thread_find_by_status(l->item_sel.y, req_status); // no results, skip if(idx < 0) return; dl_arg_t *ta = &pt_info[ idx ]; - printf("item_sel.y:%d -> ta[%d]->g_idx:%d\n", p->item_sel.y, - idx, ta->g_idx); +/* printf("item_sel.y:%d -> ta[%d]->g_idx:%d\n", l->item_sel.y, + idx, ta->g_idx); */ /* install fpkg */ if(ta @@ -1769,7 +1908,7 @@ for(int i = 0; i < 12; i++) ani_notify(&tmp[0]); // install - sprintf(&tmp[0], "%s/%s.pkg", get->temppath, ta->token_d[ ID ].off); + sprintf(&tmp[0], "%s/%s.pkg", get->opt[ TMP_PATH ], ta->token_d[ ID ].off); printf("pkginstall(%s)\n", tmp); pkginstall(&tmp[0]); @@ -1779,7 +1918,7 @@ for(int i = 0; i < 12; i++) memset(ta, 0, sizeof(dl_arg_t)); ta->g_idx = -1; ta->status = READY; - p->item_sel = (ivec2)(0); + l->item_sel = (ivec2)(0); return; } @@ -1790,10 +1929,6 @@ for(int i = 0; i < 12; i++) // get vector from selected item index ivec2 x = idx_to_pos_xy( ta->g_idx, icon_panel->fieldsize ); - printf("x (%d, %d), %d %d\n", x.x, x.y, - x.y % icon_panel->fieldsize.y, - x.y / icon_panel->fieldsize.y); - ivec3 X = (ivec3) { x.x, x.y % icon_panel->fieldsize.y, x.y / icon_panel->fieldsize.y }; @@ -1808,9 +1943,16 @@ for(int i = 0; i < 12; i++) } } else - if(menu_pos.z == ON_SUBMENU_2) + if(menu_pos.z == ON_SUBMENU_2) // download_panel { - X_action_dispatch(f_selection, p); + X_action_dispatch(f_selection, l); + } + else + if(menu_pos.z == ON_SETTINGS) // Settiongs: option_panel + { // drop auxiliary list + aux = NULL; + + X_action_dispatch(f_selection, l); } } break; @@ -1818,14 +1960,15 @@ for(int i = 0; i < 12; i++) if(aux && left_panel->page_sel.x != LPANEL_Y) - { + { // drop auxiliary list aux = NULL; + // set texture refreshed trigger icon_panel->refresh = 1; } if(menu_pos.z == ON_LEFT_PANEL) { // switch menu entry, set focus - p ->is_active = 1; p->page_sel.x = 0, + l ->is_active = 1; l->page_sel.x = 0, icon_panel->is_active = 0; left_panel->item_sel = (ivec2)(0); // reset to first icon page @@ -1840,6 +1983,7 @@ for(int i = 0; i < 12; i++) option_panel->is_active = option_panel->is_shown = 0, icon_panel ->is_active = 0; left_panel ->is_active = 1; // back + // set texture refreshed trigger if(queue_panel) queue_panel->refresh = 1; } else @@ -1851,17 +1995,23 @@ for(int i = 0; i < 12; i++) download_panel->is_active = left_panel ->is_active = 0; icon_panel ->is_active = 1; // back + // set texture refreshed trigger download_panel->refresh = icon_panel ->refresh = 1; } + else + if(menu_pos.z == ON_SETTINGS) + { + menu_pos.z = ON_LEFT_PANEL; + option_panel->is_active = option_panel->is_shown = 0, + icon_panel ->is_active = 0; + left_panel ->is_active = 1; // back + } + we_moved = 1; // trigger vbo refresh // fprintf(INFO, "CIR %d\n", menu_pos.z); } break; case TRI: { - menu_pos.z = ON_SUBMENU; rela_pos = (0); // reset on open - left_panel ->is_active = - icon_panel ->is_active = 0; - option_panel->is_active = 1; option_panel->is_shown = 1; } break; case SQU: { //menu_pos.z = ON_TEST_ANI; @@ -1877,18 +2027,18 @@ for(int i = 0; i < 12; i++) result += posi; // handle the movement: - fprintf(INFO, "layout:%p, bounds: %d %d\n", p, bounds.x, bounds.y); + fprintf(INFO, "layout:%p, bounds: %d %d\n", l, bounds.x, bounds.y); /* keep main bounds on available items */ // left panel if(result.x < 0) { - result.x = bounds.x;//p->fieldsize.x -1; // max + result.x = bounds.x; // max - if(p == icon_panel) + if(l == icon_panel) { // switch active panel, don't move - menu_pos.z = ON_LEFT_PANEL; p = left_panel; - bounds = p->fieldsize -1; - result = p->item_sel; + menu_pos.z = ON_LEFT_PANEL; l = left_panel; + bounds = l->fieldsize -1; + result = l->item_sel; left_panel->is_active = 1; icon_panel->is_active = 0; } @@ -1898,11 +2048,11 @@ for(int i = 0; i < 12; i++) { result.x = 0; // min - if(p == left_panel) + if(l == left_panel) { // switch active panel, don't move - menu_pos.z = ON_MAIN_SCREEN; p = icon_panel; - bounds = p->fieldsize -1; - result = p->item_sel; + menu_pos.z = ON_MAIN_SCREEN; l = icon_panel; + bounds = l->fieldsize -1; + result = l->item_sel; left_panel->is_active = 0; icon_panel->is_active = 1; } @@ -1912,10 +2062,9 @@ for(int i = 0; i < 12; i++) { result.y = bounds.y; // max XXX - //if(p == left_panel) p->page_num = 0; - if(p == icon_panel && p->page_sel.y != 0) + if(l == icon_panel && l->page_sel.y != 0) { // change page, refresh textures - p->refresh = 1; p->page_sel.x -= 1; + l->refresh = 1; l->page_sel.x -= 1; } we_moved = 1; //GLES2_UpdateVboForLayout(left_panel); } @@ -1924,36 +2073,37 @@ for(int i = 0; i < 12; i++) { result.y = 0; - if(p == icon_panel && p->page_sel.y != 0) + if(l == icon_panel && l->page_sel.y != 0) { // change page, refresh textures - p->refresh = 1; p->page_sel.x += 1; + l->refresh = 1; l->page_sel.x += 1; } we_moved = 1; //GLES2_UpdateVboForLayout(left_panel); } // keep bounds on pages - if(p->page_sel.x < 0) + if(l->page_sel.x < 0) { // go to last page!, take care - p->page_sel.x = p->page_sel.y, result = (ivec2)(0); + l->page_sel.x = l->page_sel.y, result = (ivec2)(0); } else - if(p->page_sel.x > p->page_sel.y) - p->page_sel.x = 0; + if(l->page_sel.x > l->page_sel.y) + l->page_sel.x = 0; fprintf(INFO, "%s result( %d, %d)\n", __FUNCTION__, result.x, result.y); //menu_pos.xy = result; - p->item_sel = result; + l->item_sel = result; - if(p == icon_panel) + if(l == icon_panel + || l == option_panel) { // keep bounds on remaining entries - int idx = pos_xy_to_idx(result, p->fieldsize); + int idx = pos_xy_to_idx(result, l->fieldsize); if(idx > f_size -1) { - p->page_sel.x = 0; - p->item_sel = (ivec2)(0); + l->page_sel.x = 0; + l->item_sel = (ivec2)(0); // refresh icons from first page - p->refresh = 1; + l->refresh = 1; } } @@ -1966,26 +2116,24 @@ for(int i = 0; i < 12; i++) GLES2_UpdateVboForLayout(option_panel); } // if we dropped auxiliary list, refresh max_page - if(p == icon_panel && !aux) + if(l == icon_panel && !aux) { - p->page_sel.y = p->item_c - / (p->fieldsize.x * p->fieldsize.y); + l->page_sel.y = l->item_c + / (l->fieldsize.x * l->fieldsize.y); } // compute some indexes, first one of layout: - i_paged = p->fieldsize.y * p->fieldsize.x - * p->page_sel.x; + i_paged = l->fieldsize.y * l->fieldsize.x + * l->page_sel.x; // which icon is selected in field X*Y ? - f_selection = p->item_sel.y * p->fieldsize.x - + p->item_sel.x; + f_selection = l->item_sel.y * l->fieldsize.x + + l->item_sel.x; // which item is selected over all ? - p->curr_item = f_selection + i_paged; + l->curr_item = f_selection + i_paged; fprintf(INFO, "p:%d/%d, s:%d/%d (%d, %d):%d\n", - p->page_sel.x, p->page_sel.y, - p->curr_item, p->item_c, - p->item_sel.x, p->item_sel.y, f_selection); - - idx_to_pos_xy(p->curr_item, p->fieldsize); + l->page_sel.x, l->page_sel.y, + l->curr_item, l->item_c, + l->item_sel.x, l->item_sel.y, f_selection); fprintf(INFO, "dpad:%d, %d\n", confPad->padDataCurrent->lx, confPad->padDataCurrent->ly); diff --git a/Store/source/GLES2_textures.c b/Store/source/GLES2_textures.c index e0fdfc0..12247f5 100644 --- a/Store/source/GLES2_textures.c +++ b/Store/source/GLES2_textures.c @@ -12,8 +12,8 @@ #include "defines.h" #include "json.h" - #include "icons_shaders.h" + /* we setup two SL programs: 0. use default color from texture @@ -36,11 +36,9 @@ static GLuint curr_Program; // the current one #define BUFFER_OFFSET(i) ((void*)(i)) -// my_Frect position(.xy) and size (.zw) -static vec4 rects[NUM_OF_TEXTURES]; // the png we apply glowing effect by switching shader -extern int selected_icon; +//extern int selected_icon; extern ivec4 menu_pos; // shaders locations @@ -51,6 +49,9 @@ static GLint u_texture_unit_location, vec2 resolution; // (shared and constant!) +#if 0 +// my_Frect position(.xy) and size (.zw) +static vec4 rects[NUM_OF_TEXTURES]; // fill all our "rects" info with normalized coordinates static void setup_texture_position(int i, vec2 pos, const float scale_f) { @@ -70,22 +71,11 @@ static void setup_texture_position(int i, vec2 pos, const float scale_f) rects[i].zw = px_pos_to_normalized(&s); } } +#endif -//https://github.com/learnopengles/airhockey/commit/228ce050da304258feca8d82690341cb50c27532 -//OpenGLES2 handlers : init , final , update , render , touch-input void on_GLES2_Init_icons(int view_w, int view_h) { - resolution = (vec2){ view_w, view_h }; // setup resolution for next setup_texture_position() - - for(int i = 0; i < NUM_OF_TEXTURES; i++) - { -// texture[i] = load_png_asset_into_texture(pngs[i]); -// if(!texture[i]) -// debugNetPrintf(DEBUG, "load_png_asset_into_texture '%s' ret: %d\n", pngs[i], texture[i]); - - // fill Frects with positions and sizes - setup_texture_position( i, (vec2){ i *100, 480 /*ATTR_ORBISGL_HEIGHT*/ /2 }, 0.25 /* scale_f */); - } + resolution = (vec2){ view_w, view_h }; for(int i = 0; i < NUM_OF_PROGRAMS; i++) { @@ -95,7 +85,7 @@ void on_GLES2_Init_icons(int view_w, int view_h) #else CreateProgramFromBinary(i); #endif - debugNetPrintf(DEBUG, "glsl_Program[%d]: %u\n", i, glsl_Program[i]); + fprintf(DEBUG, "glsl_Program[%d]: %u\n", i, glsl_Program[i]); // make program the current one curr_Program = glsl_Program[i]; @@ -121,14 +111,11 @@ void on_GLES2_Final(void) void on_GLES2_Update(double time) { - float t = (float)time; for(int i = 0; i < NUM_OF_PROGRAMS; ++i) { glUseProgram(glsl_Program[i]); // write the value to the shaders -//printf("%s pro:%d glUniform1f before.\n", __FUNCTION__, i); - glUniform1f(glGetUniformLocation(glsl_Program[i], "u_time"), t); -//printf("%s pro:%d glUniform1f after.\n", __FUNCTION__, i); + glUniform1f(glGetUniformLocation(glsl_Program[i], "u_time"), time); } //printf("time:%.6f\n", time); } @@ -158,7 +145,6 @@ void on_GLES2_Render_icon(GLuint texture, int num, vec4 *frect) // which texture glUniform1i (u_texture_unit_location, num); // tell to shader // setup positions - //const vec4 *rect = &rects[num]; const vec4 *rect = frect; /* vec4 r;// = (vec4) { .2, .2, .3, .3 }; @@ -201,51 +187,3 @@ void on_GLES2_Render_icon(GLuint texture, int num, vec4 *frect) // which texture // we already flip/swap } -// UI: pngs -static vec4 selection_box; -static int to_ani = 0; -void on_GLES2_Render_icons(page_info_t *row) -{ - if(!row) return; - - vec4 r; - vec2 p, s; - for(int i = 0; i < NUM_OF_TEXTURES; i++) - { -#if 1 - // position, size in px - p = row->item[i].origin; - s = row->item[i].frect.zw; - // turn size into the second point - s += p; - // compute the normalized frect - r.xy = px_pos_to_normalized(&p); - r.zw = px_pos_to_normalized(&s); - // save the currently selected frect! - if(i == selected_icon - &&(((row->page_num -1) %2) == menu_pos.y %2) - ) selection_box = r; - // render texture using normalized frect - on_GLES2_Render_icon(row->item[i].texture, i, &r); -#else - // take px coordinates - p = row->item[i].origin; - s = p - + (vec2) ( 128. ); - // do something - s *= sin(to_ani++); - // compute the normalized frect - r.xy = px_pos_to_normalized(&p); - r.zw = px_pos_to_normalized(&s); - // update the item frect and draw - row->item[i].frect = r; - on_GLES2_Render_icon(row->item[i].texture, i, &row->item[i].frect); -#endif - } -} - -void on_GLES2_Render_box(vec4 *frect) -{ - vec4 white = (vec4)( 1. ); - ORBIS_RenderDrawBox(USE_UTIME, &white, &selection_box); -} diff --git a/Store/source/KeyboardDialog.c b/Store/source/KeyboardDialog.c index 03698b8..0286238 100644 --- a/Store/source/KeyboardDialog.c +++ b/Store/source/KeyboardDialog.c @@ -1,59 +1,71 @@ - -#include "defines.h" - -wchar_t inputTextBuffer[33]; -static char storebuffer[34]; - -char * StoreKeyboard() { - - sceSysmoduleLoadModule(ORBIS_SYSMODULE_IME_DIALOG); - - wchar_t title[100]; - - memset(inputTextBuffer, 0, sizeof(inputTextBuffer)); - memset(&storebuffer[0], 0, sizeof(storebuffer)); - - mbstowcs(inputTextBuffer, storebuffer, strlen(storebuffer) + 1); - mbstowcs(title, "Store Keyboard", strlen("Store Keyboard") + 1); - - OrbisImeDialogParam param; - memset( & param, 0, sizeof(OrbisImeDialogParam)); - - param.maxTextLength = 33; - param.inputTextBuffer = inputTextBuffer; - param.title = title; - param.userId = 0xFE; - param.type = ORBIS_IME_TYPE_BASIC_LATIN; - param.enterLabel = ORBIS_IME_ENTER_LABEL_DEFAULT; - - int init_log = sceImeDialogInit( & param, NULL); - - while (1) { - int status = sceImeDialogGetStatus(); - - if (status == ORBIS_IME_DIALOG_STATUS_FINISHED) { - OrbisImeDialogResult result; - memset( & result, 0, sizeof(OrbisImeDialogResult)); - sceImeDialogGetResult( & result); - - if (result.endstatus == ORBIS_IME_DIALOG_END_STATUS_USER_CANCELED) - goto Finished; - - if (result.endstatus == ORBIS_IME_DIALOG_END_STATUS_OK) { - klog("status %i, endstatus %i \n", status, result.endstatus); - wcstombs(&storebuffer[0], inputTextBuffer, 33); - goto Finished; - - } - } - - if (status == ORBIS_IME_DIALOG_STATUS_NONE) - goto Finished; - - } - - Finished: - sceImeDialogTerm(); - return storebuffer; - -} \ No newline at end of file + +#include "defines.h" + +wchar_t inputTextBuffer[70]; +static char storebuffer[70]; + +char *StoreKeyboard(const char *Title, char *initialTextBuffer) +{ + sceSysmoduleLoadModule(ORBIS_SYSMODULE_IME_DIALOG); + + wchar_t title[100]; + char titl [100]; + + if(initialTextBuffer && strlen(initialTextBuffer) > 69) return "Too Long"; + + memset(inputTextBuffer, 0, sizeof(inputTextBuffer)); + memset(&storebuffer[0], 0, sizeof(storebuffer)); + + if(initialTextBuffer) + sprintf(&storebuffer[0], "%s", initialTextBuffer); + //converts the multibyte string src to a wide-character string starting at dest. + mbstowcs(inputTextBuffer, storebuffer, strlen(storebuffer) + 1); + // use custom title + if(Title) + sprintf(&titl[0], "%s", Title); + else // default + sprintf(&titl[0], "%s", "Store Keyboard"); + //converts the multibyte string src to a wide-character string starting at dest. + mbstowcs(title, titl, strlen(titl) + 1); + + OrbisImeDialogParam param; + memset(¶m, 0, sizeof(OrbisImeDialogParam)); + + param.maxTextLength = 70; + param.inputTextBuffer = inputTextBuffer; + param.title = title; + param.userId = 0xFE; + param.type = ORBIS_IME_TYPE_BASIC_LATIN; + param.enterLabel = ORBIS_IME_ENTER_LABEL_DEFAULT; + + int init_log = sceImeDialogInit( & param, NULL); + + int status; + while(1) + { + status = sceImeDialogGetStatus(); + + if (status == ORBIS_IME_DIALOG_STATUS_FINISHED) + { + OrbisImeDialogResult result; + memset(&result, 0, sizeof(OrbisImeDialogResult)); + sceImeDialogGetResult(&result); + + if(result.endstatus == ORBIS_IME_DIALOG_END_STATUS_USER_CANCELED) + goto Finished; + + if(result.endstatus == ORBIS_IME_DIALOG_END_STATUS_OK) + { + klog("status %i, endstatus %i \n", status, result.endstatus); + wcstombs(&storebuffer[0], inputTextBuffer, 70); + goto Finished; + } + } + + if (status == ORBIS_IME_DIALOG_STATUS_NONE) goto Finished; + } + +Finished: + sceImeDialogTerm(); + return storebuffer; +} diff --git a/Store/source/common_init.c b/Store/source/common_init.c index a4c32ba..c1bc585 100644 --- a/Store/source/common_init.c +++ b/Store/source/common_init.c @@ -31,6 +31,7 @@ #endif +#include #include #include @@ -41,8 +42,37 @@ int s_shcomp_module = -1; int JsonErr = 0, page; -StoreOptions set, - *get; +const unsigned char completeVersion[] = { + VERSION_MAJOR_INIT, + '.', + VERSION_MINOR_INIT, + '-', + 'V', + '-', + BUILD_YEAR_CH0, + BUILD_YEAR_CH1, + BUILD_YEAR_CH2, + BUILD_YEAR_CH3, + '-', + BUILD_MONTH_CH0, + BUILD_MONTH_CH1, + '-', + BUILD_DAY_CH0, + BUILD_DAY_CH1, + 'T', + BUILD_HOUR_CH0, + BUILD_HOUR_CH1, + ':', + BUILD_MIN_CH0, + BUILD_MIN_CH1, + ':', + BUILD_SEC_CH0, + BUILD_SEC_CH1, + '\0' +}; + +extern StoreOptions set, + *get; /* XXX: patches below are given for Piglet module from 4.74 Devkit PUP */ static void pgl_patches_cb(void* arg, uint8_t* base, uint64_t size) @@ -66,7 +96,11 @@ int initGL_for_the_store(void) { int ret = 0; - get = &set; // address main get StoreOptions pointer + klog("------------------------ Store[GL] Compiled Time: %s @ %s -------------------------\n", __DATE__, __TIME__); + klog(" -------------------------------- STORE Version: %s -----------------\n", completeVersion); + klog("----------------------------------------------- -------------------------\n"); + + get = &set; // internals: net, user_service, system_service ret = loadModulesVanilla(); @@ -74,10 +108,6 @@ int initGL_for_the_store(void) // pad ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_PAD); if(ret) return -1; - - - - //Ime ret = sceSysmoduleLoadModule(ORBIS_SYSMODULE_IME_DIALOG); if(ret) return -1; @@ -85,69 +115,65 @@ int initGL_for_the_store(void) ret = sceSysmoduleLoadModule(ORBIS_SYSMODULE_MESSAGE_DIALOG); if(ret) return -1; + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_NETCTL); + if(ret) return -1; - ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_NETCTL); - if(ret) return -1; - ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_NET); - if(ret) return -1; - - ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_HTTP); - if(ret) return -1; - - ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_SSL); - if(ret) return -1; - + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_NET); + if(ret) return -1; + + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_HTTP); + if(ret) return -1; - ret = sceSysmoduleLoadModuleInternal(0x80000018); - if(ret) return -1; - - ret = sceSysmoduleLoadModuleInternal(0x80000026); // 0x80000026 - if(ret) return -1; - - ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_BGFT); // 0x80000026 - if(ret) return -1; - - ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_APPINSTUTIL); // 0x80000026 0x80000037 - if(ret) return -1; - + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_SSL); + if(ret) return -1; + ret = sceSysmoduleLoadModuleInternal(0x80000018); + if(ret) return -1; + + ret = sceSysmoduleLoadModuleInternal(0x80000026); // 0x80000026 + if(ret) return -1; + + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_BGFT); // 0x80000026 + if(ret) return -1; + + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_APPINSTUTIL); // 0x80000026 0x80000037 + if(ret) return -1; + sceCommonDialogInitialize(); sceMsgDialogInitialize(); - ret = orbisPadInit(); if(ret != 1) return -2; + if(MD5_hash_compare("/user/app/NPXS39041/pig.sprx", "854a0e5556eeb68c23a97ba024ed2aca") == SAME_HASH && MD5_hash_compare("/user/app/NPXS39041/shacc.sprx", "8a21eb3ed8a6786d3fa1ebb1dcbb8ed0") == SAME_HASH) + { + globalConf.confPad = orbisPadGetConf(); - if(MD5_hash_compare("/user/app/NPXS39041/pig.sprx", "854a0e5556eeb68c23a97ba024ed2aca") == SAME_HASH && MD5_hash_compare("/user/app/NPXS39041/shacc.sprx", "8a21eb3ed8a6786d3fa1ebb1dcbb8ed0") == SAME_HASH) - { - globalConf.confPad = orbisPadGetConf(); - - // customs - s_piglet_module = sceKernelLoadStartModule("/user/app/NPXS39041/pig.sprx", 0, NULL, 0, NULL, NULL); - s_shcomp_module = sceKernelLoadStartModule("/user/app/NPXS39041/shacc.sprx", 0, NULL, 0, NULL, NULL); + // customs + s_piglet_module = sceKernelLoadStartModule("/user/app/NPXS39041/pig.sprx", 0, NULL, 0, NULL, NULL); + s_shcomp_module = sceKernelLoadStartModule("/user/app/NPXS39041/shacc.sprx", 0, NULL, 0, NULL, NULL); - if(! patch_module("pig.sprx", &pgl_patches_cb, NULL, /*debugnetlevel*/3)) return -3; + if(! patch_module("pig.sprx", &pgl_patches_cb, NULL, /*debugnetlevel*/3)) return -3; + ret = LoadOptions(get); + if(!ret) + msgok(2, "Could NOT find/open the INI File"); - ret = LoadOptions(get); - if(!ret) - msgok(2, "Could NOT find/open the INI File"); + loadmsg("Downloading and Caching Website files....\n"); - loadmsg("Downloading and Caching Website files....\n"); + page = 1; //first + while(JsonErr == 0) + { + JsonErr = getjson(page, get->opt[CDN_URL]); + page++; + } - page = 1; //first - while(JsonErr == 0) - { - JsonErr = getjson(page, get->StoreCDN); - page++; + sceMsgDialogTerminate(); } - - sceMsgDialogTerminate(); - } else - msgok(FATAL, "SPRX ARE NOT THE SAME HASH\n ABORTING"); + msgok(FATAL, "SPRX ARE NOT THE SAME HASH\n ABORTING"); + // all fine. return 0; } diff --git a/Store/source/http.c b/Store/source/http.c index 9c3bd91..e3461c4 100644 --- a/Store/source/http.c +++ b/Store/source/http.c @@ -230,7 +230,6 @@ int ini_dl_req(struct dl_args *i) return statusCode; } - //int download_file(int libnetMemId, int libhttpCtxId, const char* src, const char* dst) void *start_routine(void *argument) { @@ -278,8 +277,6 @@ void *start_routine(void *argument) if(total_read >= i->contentLength || prog >= 100) { // reset prog = 100; break;//runn = 0; // stop } - - //_InterlockedExchange(&g_progress, prog); } ret = sceKernelClose(fd); @@ -317,28 +314,22 @@ int netInit(void) void Network_Init() { #if defined (__ORBIS__) - - - int ret = netInit(); if (ret < 0) { klog("netInit() error: 0x%08X\n", ret); } libnetMemId = ret; - - klog("after http\n"); ret = sceHttpInit(libnetMemId, libsslCtxId, HTTP_HEAP_SIZE); if (ret < 0) { klog("sceHttpInit() error: 0x%08X\n", ret); } libhttpCtxId = ret; #endif } +// the _v2 version is used in download panel int dl_from_url(const char *url_, const char *dst_, bool is_threaded) { - //avoid Pool error if(libhttpCtxId == 0xFF || libnetMemId == 0xFF) Network_Init(); - dl_args.src = url_; dl_args.dst = dst_; @@ -361,6 +352,5 @@ int dl_from_url(const char *url_, const char *dst_, bool is_threaded) ret = start_routine(&dl_args); } - return ret; } diff --git a/Store/source/json_simple.c b/Store/source/json_simple.c index c56ec3c..5d7e8e7 100644 --- a/Store/source/json_simple.c +++ b/Store/source/json_simple.c @@ -1,17 +1,12 @@ -#include "jsmn.h" #include #include #include #include "defines.h" +#include "jsmn.h" #include "json.h" - -extern int selected_icon; -extern GLuint shader; -extern mat4 model, view, projection; - extern texture_atlas_t *atlas; /* @@ -27,8 +22,72 @@ int jsoneq(const char *json, jsmntok_t *tok, const char *s) { return -1; } +// recreate fonts glyphs atlas +void refresh_atlas(void) +{ + // fprintf(INFO, "* atlas to gpu *\n"); + if(1) + { /* discard old texture, we eventually added glyphs! */ + if(atlas->id) glDeleteTextures(1, &atlas->id), atlas->id = 0; + + /* re-create texture and upload atlas into gpu memory */ + glGenTextures ( 1, &atlas->id ); + glBindTexture ( GL_TEXTURE_2D, atlas->id ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexImage2D ( GL_TEXTURE_2D, 0, GL_ALPHA, atlas->width, atlas->height, + 0, GL_ALPHA, GL_UNSIGNED_BYTE, atlas->data ); + glBindTexture(GL_TEXTURE_2D, 0); + } +} + +int count_availables_json(void) +{ + int count = 0; + char json_file[128]; + void *p; + + while(1) + { // json page_num starts from 1 !!! + sprintf(&json_file[0], "/user/app/NPXS39041/homebrew-page%d.json", count +1); + // read the file +#if defined (USE_NFS) + #warning "we use nfs!" +// p = &json_file[20]; +// fprintf(INFO, "open:%s\n", p); + // move pointer to address nfs share + p = (void*)orbisNfsGetFileContent(&json_file[20]); +#else + p = (void*)orbisFileGetFileContent(&json_file[0]); +#endif + // check + if(p) free(p), p = NULL; else break; + // passed, increase num of available pages + count++; + } + return count; +} + +/* old UI code now useless, for reference */ + +#if 0 +extern int selected_icon; +extern GLuint shader; +extern mat4 model, view, projection; + +/* + three shared fonts +*/ +texture_font_t *stock_font = NULL; +texture_font_t *title_font = NULL; +texture_font_t *curr_font = NULL; + +extern int num_of_pages; -unsigned char *http_fetch_from(const char *url); +// freetype-gl pass last composed Text_Length in pixel, we use to align text! +extern float tl; // index (write) all used_tokens static int json_index_used_tokens(page_info_t *page) @@ -74,10 +133,6 @@ static int json_index_used_tokens(page_info_t *page) } -// freetype-gl pass last composed Text_Length in pixel, we use to align text! -extern float tl; - -//static page_info_t *page = NULL; void destroy_page(page_info_t *page) { @@ -95,68 +150,6 @@ void destroy_page(page_info_t *page) if(page) free(page), page = NULL; } -// dummmy, to catch my GL bug -void refresh_atlas(void) -{ - // fprintf(INFO, "* atlas to gpu *\n"); - //glUseProgram ( shader ); - // setup state - //glActiveTexture( GL_TEXTURE0 ); - - if(1)//(page_num > num_of_pages) - { - //printf("to gpu!\n"); - /* discard old texture, we eventually added glyphs! */ - if(atlas->id) glDeleteTextures(1, &atlas->id), atlas->id = 0; - - /* re-create texture and upload atlas into gpu memory */ - glGenTextures ( 1, &atlas->id ); - glBindTexture ( GL_TEXTURE_2D, atlas->id ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexImage2D ( GL_TEXTURE_2D, 0, GL_ALPHA, atlas->width, atlas->height, - 0, GL_ALPHA, GL_UNSIGNED_BYTE, atlas->data ); - glBindTexture(GL_TEXTURE_2D, 0); - } -} - -texture_font_t *stock_font = NULL; -texture_font_t *title_font = NULL; -texture_font_t *curr_font = NULL; -/* - -*/ -extern int num_of_pages; - -int count_availables_json(void) -{ - int count = 0; - char json_file[128]; - void *p; - - while(1) - { // json page_num starts from 1 !!! - sprintf(&json_file[0], "/user/app/NPXS39041/homebrew-page%d.json", count +1); - // read the file -#if defined (USE_NFS) - #warning "we use nfs!" -// p = &json_file[20]; -// fprintf(INFO, "open:%s\n", p); - // move pointer to address nfs share - p = (void*)orbisNfsGetFileContent(&json_file[20]); -#else - p = (void*)orbisFileGetFileContent(&json_file[0]); -#endif - // check - if(p) free(p), p = NULL; else break; - // passed, increase num of available pages - count++; - } - return count; -} - // this draws the page layout: // texts from indexed json token name, value page_info_t *compose_page(int page_num) @@ -180,12 +173,12 @@ page_info_t *compose_page(int page_num) page->vbo = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); - int valid_t = json_index_used_tokens(page); + int valid_tokens = json_index_used_tokens(page); // json describe max 8 items per page - int ret = valid_t /NUM_OF_USER_TOKENS; - + page->num_of_items = valid_tokens /NUM_OF_USER_TOKENS; // if < 8 realloc page - //printf("%d\n", ret); + printf("json %d holds %d items\n", page_num, page->num_of_items); + if(!stock_font) stock_font = texture_font_new_from_memory(atlas, 17, _hostapp_fonts_zrnic_rg_ttf, _hostapp_fonts_zrnic_rg_ttf_len); @@ -194,7 +187,7 @@ page_info_t *compose_page(int page_num) _hostapp_fonts_zrnic_rg_ttf_len); // now prepare all the texts textures, use indexed json_data int count; - for(int i = 0; i < ret; i++) + for(int i = 0; i < page->num_of_items; i++) { // compute item origin position, in px page->item[i].origin = (vec2) @@ -563,7 +556,7 @@ void GLES2_RenderPageForItem(page_item_t *item) // case PV: sprintf(&lbl[0], "Name: "); break; case RELEASEDATE: sprintf(&lbl[0], "Released: "); pen = (vec2) { 480, 500 - TEXT_VSTEP *4 }; - break; + break; default: continue; // skip unknown names } /* append to VBO */ @@ -606,3 +599,4 @@ void GLES2_RenderPageForItem(page_item_t *item) if(!item->in_atlas) refresh_atlas(), item->in_atlas = 1; } +#endif diff --git a/Store/source/main.c b/Store/source/main.c index 04bb20d..27ee5ee 100644 --- a/Store/source/main.c +++ b/Store/source/main.c @@ -10,18 +10,18 @@ int (*jailbreak_me)(void); int64_t sys_dynlib_load_prx(char* prxPath, int* moduleID) { - return (int64_t)syscall4(594, prxPath, 0, moduleID, 0); + return (int64_t)syscall4(594, prxPath, 0, moduleID, 0); } int64_t sys_dynlib_unload_prx(int64_t prxID) { - return (int64_t)syscall1(595, (void*)prxID); + return (int64_t)syscall1(595, (void*)prxID); } int64_t sys_dynlib_dlsym(int64_t moduleHandle, const char* functionName, void *destFuncOffset) { - return (int64_t)syscall3(591, (void*)moduleHandle, (void*)functionName, destFuncOffset); + return (int64_t)syscall3(591, (void*)moduleHandle, (void*)functionName, destFuncOffset); } @@ -143,19 +143,13 @@ ly : 0-255 u-d if(orbisPadGetButtonPressed(ORBISPAD_R1)) { fprintf(INFO, "R1 pressed\n"); - int mId, hcId; - + /* int mId, hcId; int ret = pingtest(mId, hcId, "https://10.0.0.2"); - fprintf(INFO, "pingtest ret:%d\n", ret); + fprintf(INFO, "pingtest ret:%d\n", ret); */ } if(orbisPadGetButtonPressed(ORBISPAD_R2)) { fprintf(INFO, "R2 pressed\n"); - - uint64_t numb; - uint32_t ret = sceKernelGetCpuTemperature(&numb); -// printf( "sceKernelGetCpuTemperature returned %i\n", ret); - fprintf(INFO, "TEMP %d°C\n", numb); } } } @@ -203,7 +197,6 @@ bool initApp() sceSystemServiceHideSplashScreen(); - confPad = orbisPadGetConf(); if( ! initAppGl() ) return false; @@ -220,9 +213,7 @@ unsigned int frame = 1, int main(int argc, char *argv[]) { StoreOptions set; - int ret = sceKernelIccSetBuzzer(1); - - sleep(2); + int ret = -1; /* prepare pad and piglet modules in advance, read /data/orbislink/orbislink_config.ini for debugnet @@ -231,28 +222,16 @@ int main(int argc, char *argv[]) */ //debugNetInit("10.0.0.2", 18198, 3); - // to access /user and notify we need full privileges - //escalate_priv(); - -sys_dynlib_load_prx("/app0/Media/jb.prx", &libcmi); - -ret = sys_dynlib_dlsym(libcmi, "jailbreak_me", &jailbreak_me); -if (!ret) -{ - klog("jailbreak_me resolved from PRX\n"); - - if(ret = jailbreak_me() != 0) - goto error; -} -else - goto error; - + // to access /user and notify() we need full privileges... /* load some required modules */ #if defined (USE_NFS) + + // to access /user and notify() we need full privileges +// escalate_priv(); ret = initOrbisLinkAppVanillaGl(); - /* my setup */ + /* some nfs setup */ // ret = orbisNfsInit("nfs://10.0.0.2/hostapp"); ret = orbisNfsInit("nfs://10.0.0.2/Archive/PS4-work/orbisdev/orbisdev-samples/linux_es2goodness"); // ret = orbisNfsInit("nfs://192.168.2.61/home/alfa/NFS/hostapp"); @@ -260,11 +239,24 @@ else fprintf(INFO, "orbisNfsInit return: %x\n", ret); sleep(1); #else - if(ret = initGL_for_the_store() < 0) - goto error; - + + /* load custom .prx, resolve and call a function */ + sys_dynlib_load_prx("/app0/Media/jb.prx", &libcmi); + + ret = sys_dynlib_dlsym(libcmi, "jailbreak_me", &jailbreak_me); + if (!ret) + { + klog("jailbreak_me resolved from PRX\n"); + + if(ret = jailbreak_me() != 0) goto error; + } + else + goto error; + + if(ret = initGL_for_the_store() < 0) goto error; #endif + if(!ret) sceKernelIccSetBuzzer(1); @@ -312,10 +304,8 @@ else //goto err; } - /// draw + /// draw ! - // freetype demo-font.c, renders text just from init_ - //render_text(); // ES_UI GLES2_scene_render(); @@ -341,13 +331,11 @@ else } orbisGlSwapBuffers(); /// flip frame - - sceKernelUsleep(10); // haha, control your rendering properly , use delta time for animations not wait } error: - sceKernelIccSetBuzzer(2); - msgok(FATAL, "App has Died with exit code %i", ret); + sceKernelIccSetBuzzer(2); + msgok(FATAL, "App has Died with exit code %i", ret); // destructors ORBIS_RenderFillRects_fini(); diff --git a/Store/source/utils.c b/Store/source/utils.c index 9b7475f..35d3afe 100644 --- a/Store/source/utils.c +++ b/Store/source/utils.c @@ -3,6 +3,8 @@ #include #include +StoreOptions set, + *get; int Lastlogcheck = 0; static const char *sizes[] = { "EiB", "PiB", "TiB", "GiB", "MiB", "KiB", "B" }; @@ -14,11 +16,11 @@ char* usbpath() int usb; static char usbbuf[100]; usbbuf[0] = '\0'; - for (int x = 0; x <= 7; x++) + for(int x = 0; x <= 7; x++) { snprintf(usbbuf, sizeof(usbbuf), "/mnt/usb%i/.dirtest", x); usb = sceKernelOpen(usbbuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); - if (usb > 0) + if(usb > 0) { sceKernelClose(usb); @@ -26,10 +28,8 @@ char* usbpath() klog("found usb = %s\n", usbbuf); return usbbuf; - } } - klog("FOUND NO USB\n"); return ""; @@ -37,102 +37,98 @@ char* usbpath() int MD5_hash_compare(const char* file1, const char* hash) { - unsigned char c[MD5_HASH_LENGTH]; - int i; - FILE* f1 = fopen(file1, "rb"); - MD5_CTX mdContext; - - int bytes = 0; - unsigned char data[1024]; + unsigned char c[MD5_HASH_LENGTH]; + int i; + FILE* f1 = fopen(file1, "rb"); + MD5_CTX mdContext; - MD5_Init(&mdContext); - while ((bytes = fread(data, 1, 1024, f1)) != 0) - MD5_Update(&mdContext, data, bytes); - MD5_Final(c, &mdContext); + int bytes = 0; + unsigned char data[1024]; + MD5_Init(&mdContext); + while ((bytes = fread(data, 1, 1024, f1)) != 0) + MD5_Update(&mdContext, data, bytes); + MD5_Final(c, &mdContext); - char md5_string[33] = {0}; + char md5_string[33] = {0}; - for(int i = 0; i < 16; ++i) { - sprintf(&md5_string[i*2], "%02x", (unsigned int)c[i]); - } + for(int i = 0; i < 16; ++i) { + sprintf(&md5_string[i*2], "%02x", (unsigned int)c[i]); + } klog("FILE HASH: %s\n", md5_string); - md5_string[32] = 0; + md5_string[32] = 0; - if (strcmp(md5_string, hash) != 0) { - return DIFFERENT_HASH; - } - - - klog("Input HASH: %s\n", hash); - + if (strcmp(md5_string, hash) != 0) { + return DIFFERENT_HASH; + } + klog("Input HASH: %s\n", hash); - return SAME_HASH; + return SAME_HASH; } -int LoadOptions(StoreOptions* Settings) +int LoadOptions(StoreOptions *set) { - char *buff = (char *)malloc(256 * sizeof(char)); - char *CDNBuf = (char *)malloc(256 * sizeof(char)); - char *temppath = (char *)malloc(256 * sizeof(char)); - + for(int i=0; i< NUM_OF_STRINGS; i++) + { // dynalloc and zerofill + set->opt[ i ] = calloc(256, sizeof(char)); + } /* Initialize INI structure */ pl_ini_file file; + char buff[256]; + if (strstr(usbpath(), "/mnt/usb")) + { + snprintf(buff, 256, "%s/settings.ini", usbpath()); - if (strstr(usbpath(), "/mnt/usb")) { - snprintf(buff, 256, "%s/settings.ini", usbpath()); - - if (sceKernelOpen(buff, 0x0000, 0000) < 0){ - klog("No INI on USB\n"); - if (sceKernelOpen("/user/app/NPXS39041/settings.ini", 0x0000, 0000) > 0) - Settings->INIPath = "/user/app/NPXS39041/settings.ini"; - else - return -1; - + if (sceKernelOpen(buff, 0x0000, 0000) < 0) + { + klog("No INI on USB\n"); + if (sceKernelOpen("/user/app/NPXS39041/settings.ini", 0x0000, 0000) > 0) + sprintf(set->opt[INI_PATH], "%s", "/user/app/NPXS39041/settings.ini"); + else + return -1; + } else { + pl_ini_load(&file, buff); + klog("Loading ini from USB\n"); + sprintf(set->opt[INI_PATH], "%s", buff); + } } - else { - pl_ini_load(&file, buff); - klog("Loading ini from USB\n"); - Settings->INIPath = buff; + else + if (sceKernelOpen("/user/app/NPXS39041/settings.ini", 0x0000, 0000) < 0) + { + klog("CANT FIND INI\n"); return -1; + } else { + pl_ini_load( &file, "/user/app/NPXS39041/settings.ini"); + klog("Loading ini from APP DIR\n"); + sprintf(set->opt[INI_PATH], "%s", "/user/app/NPXS39041/settings.ini"); } - } else if (sceKernelOpen("/user/app/NPXS39041/settings.ini", 0x0000, 0000) < 0) { - klog("CANT FIND INI\n"); - return -1; - } else { - pl_ini_load( &file, "/user/app/NPXS39041/settings.ini"); - klog("Loading ini from APP DIR\n"); - Settings->INIPath = "/user/app/NPXS39041/settings.ini"; - - } - /* Read the file */ - pl_ini_load(&file, Settings->INIPath); - - + pl_ini_load(&file, set->opt[INI_PATH]); /* Load values */ - if (strstr(usbpath(), "/mnt/usb")){ - Settings->USBPath = usbpath(); - } - pl_ini_get_string(&file, "Settings", "CDN", "http://api.pkg-zone.com", CDNBuf, 256); - Settings->StoreCDN = CDNBuf; - pl_ini_get_string(&file, "Settings", "temppath", "/user/app/", temppath, 256); - Settings->temppath = temppath; - Settings->StoreOnUSB = pl_ini_get_int(&file, "Settings", "StoreOnUSB", 0); - - - klog("Settings.INIPath: %s\n", Settings->INIPath); - klog("Settings.USBPath: %s\n", Settings->USBPath); - klog("Settings.temppath: %s\n", Settings->temppath); - klog("Settings.StoreOnUSB: %i\n",Settings->StoreOnUSB); - klog("Settings.StoreCDN: %s\n",Settings->StoreCDN); + if(strstr(usbpath(), "/mnt/usb")) + sprintf(set->opt[USB_PATH], "%s", usbpath()); + + pl_ini_get_string(&file, "Settings", "CDN", "http://api.pkg-zone.com", + set->opt[CDN_URL], 256); + pl_ini_get_string(&file, "Settings", "temppath", "/user/app/", + set->opt[TMP_PATH], 256); + pl_ini_get_string(&file, "Settings", "TTF_Font", "/system_ex/app/NPXS20113/bdjstack/lib/fonts/SCE-PS3-RD-R-LATIN.TTF", + set->opt[FNT_PATH], 256); + // get an int + set->StoreOnUSB = pl_ini_get_int(&file, "Settings", "StoreOnUSB", 0); + + klog("set->opt[INI_PATH]: %s\n", set->opt[INI_PATH]); + klog("set->opt[USB_PATH]: %s\n", set->opt[USB_PATH]); + klog("set->opt[FNT_PATH]: %s\n", set->opt[FNT_PATH]); + klog("set->opt[TMP_PATH]: %s\n", set->opt[TMP_PATH]); + klog("set->opt[CDN_URL ]: %s\n", set->opt[CDN_URL]); + klog("set->StoreOnUSB : %i\n", set->StoreOnUSB); /* Clean up */ pl_ini_destroy(&file); - return 1; } @@ -154,32 +150,41 @@ char* cutoff(const char* str, int from, int to) return begin; } -void SaveOptions(StoreOptions* set) +int SaveOptions(StoreOptions *set) { - - /* Initialize INI structure */ pl_ini_file file; + int ret = 0; + /* Read the file */ - pl_ini_load(&file, set->INIPath); + if (ret = sceKernelOpen(set->opt[INI_PATH], 0x000, 0x0000) < 0) { + pl_ini_create(&file); + klog("INI NOT AVAIL Creating... \n"); + } + else + pl_ini_load(&file, set->opt[INI_PATH]); + klog("set->opt[INI_PATH] ret %x: %s\n", ret, set->opt[INI_PATH]); - klog("Settings.INIPath: %s\n", set->INIPath); - klog("Settings.USBPath: %s\n", set->USBPath); - klog("Settings.temppath: %s\n", set->temppath); - klog("Settings.StoreOnUSB: %i\n", set->StoreOnUSB); - klog("Settings.StoreCDN: %s\n", set->StoreCDN); + klog("set->opt[USB_PATH]: %s\n", set->opt[USB_PATH]); + klog("set->opt[TMP_PATH]: %s\n", set->opt[TMP_PATH]); + klog("set->opt[FNT_PATH]: %.20s...\n", set->opt[FNT_PATH]); + klog("set->opt[CDN_URL ]: %s\n", set->opt[CDN_URL ]); + klog("set->StoreOnUSB : %i\n", set->StoreOnUSB); /* Load values */ - pl_ini_set_string(&file, "Settings", "CDN", set->StoreCDN); - pl_ini_set_string(&file, "Settings", "temppath", set->temppath); - pl_ini_set_int(&file, "Settings", "StoreOnUSB",set->StoreOnUSB); + pl_ini_set_string(&file, "Settings", "CDN", set->opt[CDN_URL ]); + pl_ini_set_string(&file, "Settings", "temppath", set->opt[TMP_PATH]); + pl_ini_set_string(&file, "Settings", "TTF_Font", set->opt[FNT_PATH]); + pl_ini_set_int (&file, "Settings", "StoreOnUSB", set->StoreOnUSB); - pl_ini_save(&file, set->INIPath); + ret = pl_ini_save(&file, set->opt[INI_PATH]); + chmod(set->opt[INI_PATH], 0777); /* Clean up */ pl_ini_destroy(&file); + return ret; } @@ -444,7 +449,7 @@ int getjson(int Pagenumb, char* cdn) snprintf(buff, 300, "%s/homebrew-page%i.json", cdn, Pagenumb); snprintf(destbuf, 300, "/user/app/NPXS39041/homebrew-page%i.json", Pagenumb); - printf(buff); + printf("%s", buff); return dl_from_url(buff, destbuf, false); }