diff options
-rw-r--r-- | minui/minui.h | 1 | ||||
-rw-r--r-- | minui/resources.c | 182 | ||||
-rw-r--r-- | res/images/icon_installing.png | bin | 25261 -> 118562 bytes | |||
-rw-r--r-- | res/images/icon_installing_overlay01.png | bin | 10095 -> 0 bytes | |||
-rw-r--r-- | res/images/icon_installing_overlay02.png | bin | 9990 -> 0 bytes | |||
-rw-r--r-- | res/images/icon_installing_overlay03.png | bin | 9782 -> 0 bytes | |||
-rw-r--r-- | res/images/icon_installing_overlay04.png | bin | 9817 -> 0 bytes | |||
-rw-r--r-- | res/images/icon_installing_overlay05.png | bin | 9863 -> 0 bytes | |||
-rw-r--r-- | res/images/icon_installing_overlay06.png | bin | 9944 -> 0 bytes | |||
-rw-r--r-- | res/images/icon_installing_overlay07.png | bin | 10062 -> 0 bytes | |||
-rw-r--r-- | res/images/indeterminate01.png | bin | 673 -> 0 bytes | |||
-rw-r--r-- | res/images/indeterminate02.png | bin | 687 -> 0 bytes | |||
-rw-r--r-- | res/images/indeterminate03.png | bin | 661 -> 0 bytes | |||
-rw-r--r-- | res/images/indeterminate04.png | bin | 665 -> 0 bytes | |||
-rw-r--r-- | res/images/indeterminate05.png | bin | 683 -> 0 bytes | |||
-rw-r--r-- | res/images/indeterminate06.png | bin | 676 -> 0 bytes | |||
-rw-r--r-- | screen_ui.cpp | 107 | ||||
-rw-r--r-- | screen_ui.h | 8 |
18 files changed, 203 insertions, 95 deletions
diff --git a/minui/minui.h b/minui/minui.h index 1b8dd059b..5c0defc40 100644 --- a/minui/minui.h +++ b/minui/minui.h @@ -72,6 +72,7 @@ void ev_dispatch(void); // Returns 0 if no error, else negative. int res_create_surface(const char* name, gr_surface* pSurface); +int res_create_multi_surface(const char* name, int* frames, gr_surface** pSurface); int res_create_localized_surface(const char* name, gr_surface* pSurface); void res_free_surface(gr_surface surface); diff --git a/minui/resources.c b/minui/resources.c index c0a9ccacb..5ad9b1d05 100644 --- a/minui/resources.c +++ b/minui/resources.c @@ -181,6 +181,182 @@ exit: return result; } +int res_create_multi_surface(const char* name, int* frames, gr_surface** pSurface) { + char resPath[256]; + int result = 0; + unsigned char header[8]; + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + int i; + GGLSurface** surface = NULL; + + *pSurface = NULL; + *frames = -1; + + snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.png", name); + resPath[sizeof(resPath)-1] = '\0'; + FILE* fp = fopen(resPath, "rb"); + if (fp == NULL) { + result = -1; + goto exit; + } + + size_t bytesRead = fread(header, 1, sizeof(header), fp); + if (bytesRead != sizeof(header)) { + result = -2; + goto exit; + } + + if (png_sig_cmp(header, 0, sizeof(header))) { + result = -3; + goto exit; + } + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { + result = -4; + goto exit; + } + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + result = -5; + goto exit; + } + + if (setjmp(png_jmpbuf(png_ptr))) { + result = -6; + goto exit; + } + + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, sizeof(header)); + png_read_info(png_ptr, info_ptr); + + int color_type, bit_depth; + png_uint_32 width, height; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, + &color_type, NULL, NULL, NULL); + + int channels = png_get_channels(png_ptr, info_ptr); + + if (!(bit_depth == 8 && + ((channels == 3 && color_type == PNG_COLOR_TYPE_RGB) || + (channels == 4 && color_type == PNG_COLOR_TYPE_RGBA) || + (channels == 1 && (color_type == PNG_COLOR_TYPE_PALETTE || + color_type == PNG_COLOR_TYPE_GRAY))))) { + return -7; + goto exit; + } + + *frames = 1; + png_textp text; + int num_text; + if (png_get_text(png_ptr, info_ptr, &text, &num_text)) { + for (i = 0; i < num_text; ++i) { + if (text[i].key && strcmp(text[i].key, "Frames") == 0 && text[i].text) { + *frames = atoi(text[i].text); + break; + } + } + printf(" found frames = %d\n", *frames); + } + + if (height % *frames != 0) { + printf("bad height (%d) for frame count (%d)\n", height, *frames); + result = -9; + goto exit; + } + + size_t stride = (color_type == PNG_COLOR_TYPE_GRAY ? 1 : 4) * width; + size_t pixelSize = stride * height / *frames; + + surface = malloc(*frames * sizeof(GGLSurface*)); + if (surface == NULL) { + result = -8; + goto exit; + } + for (i = 0; i < *frames; ++i) { + surface[i] = malloc(sizeof(GGLSurface) + pixelSize); + surface[i]->version = sizeof(GGLSurface); + surface[i]->width = width; + surface[i]->height = height / *frames; + surface[i]->stride = width; /* Yes, pixels, not bytes */ + surface[i]->data = (unsigned char*) (surface[i] + 1); + + if (channels == 3) { + surface[i]->format = GGL_PIXEL_FORMAT_RGBX_8888; + } else if (color_type == PNG_COLOR_TYPE_PALETTE) { + surface[i]->format = GGL_PIXEL_FORMAT_RGBA_8888; + } else if (channels == 1) { + surface[i]->format = GGL_PIXEL_FORMAT_L_8; + } else { + surface[i]->format = GGL_PIXEL_FORMAT_RGBA_8888; + } + } + + int alpha = (channels == 4); + if (color_type == PNG_COLOR_TYPE_PALETTE) { + png_set_palette_to_rgb(png_ptr); + } + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + png_set_tRNS_to_alpha(png_ptr); + alpha = 1; + } + if (color_type == PNG_COLOR_TYPE_GRAY) { + alpha = 1; + } + + png_uint_32 y; + if (channels == 3 || (channels == 1 && !alpha)) { + for (y = 0; y < height; ++y) { + int fy = y / *frames; + int fr = y % *frames; + unsigned char* pRow = surface[fr]->data + fy * stride; + png_read_row(png_ptr, pRow, NULL); + + int x; + for(x = width - 1; x >= 0; x--) { + int sx = x * 3; + int dx = x * 4; + unsigned char r = pRow[sx]; + unsigned char g = pRow[sx + 1]; + unsigned char b = pRow[sx + 2]; + unsigned char a = 0xff; + pRow[dx ] = r; // r + pRow[dx + 1] = g; // g + pRow[dx + 2] = b; // b + pRow[dx + 3] = a; + } + } + } else { + for (y = 0; y < height; ++y) { + int fy = y / *frames; + int fr = y % *frames; + unsigned char* pRow = surface[fr]->data + fy * stride; + png_read_row(png_ptr, pRow, NULL); + } + } + + *pSurface = (gr_surface*) surface; + +exit: + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + + if (fp != NULL) { + fclose(fp); + } + if (result < 0) { + if (surface) { + for (i = 0; i < *frames; ++i) { + if (surface[i]) free(surface[i]); + } + free(surface); + } + } + return result; +} + static int matches_locale(const char* loc) { if (locale == NULL) return 0; @@ -249,7 +425,7 @@ int res_create_localized_surface(const char* name, gr_surface* pSurface) { png_read_info(png_ptr, info_ptr); int color_type, bit_depth; - size_t width, height; + png_uint_32 width, height; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); int channels = png_get_channels(png_ptr, info_ptr); @@ -261,13 +437,13 @@ int res_create_localized_surface(const char* name, gr_surface* pSurface) { } unsigned char* row = malloc(width); - int y; + png_uint_32 y; for (y = 0; y < height; ++y) { png_read_row(png_ptr, row, NULL); int w = (row[1] << 8) | row[0]; int h = (row[3] << 8) | row[2]; int len = row[4]; - char* loc = row+5; + char* loc = (char*)row+5; if (y+1+h >= height || matches_locale(loc)) { printf(" %20s: %s (%d x %d @ %d)\n", name, loc, w, h, y); diff --git a/res/images/icon_installing.png b/res/images/icon_installing.png Binary files differindex 571eb8b0f..c2c020162 100644 --- a/res/images/icon_installing.png +++ b/res/images/icon_installing.png diff --git a/res/images/icon_installing_overlay01.png b/res/images/icon_installing_overlay01.png Binary files differdeleted file mode 100644 index e762d6cbe..000000000 --- a/res/images/icon_installing_overlay01.png +++ /dev/null diff --git a/res/images/icon_installing_overlay02.png b/res/images/icon_installing_overlay02.png Binary files differdeleted file mode 100644 index f7a853017..000000000 --- a/res/images/icon_installing_overlay02.png +++ /dev/null diff --git a/res/images/icon_installing_overlay03.png b/res/images/icon_installing_overlay03.png Binary files differdeleted file mode 100644 index 1a1d738e4..000000000 --- a/res/images/icon_installing_overlay03.png +++ /dev/null diff --git a/res/images/icon_installing_overlay04.png b/res/images/icon_installing_overlay04.png Binary files differdeleted file mode 100644 index a74903d33..000000000 --- a/res/images/icon_installing_overlay04.png +++ /dev/null diff --git a/res/images/icon_installing_overlay05.png b/res/images/icon_installing_overlay05.png Binary files differdeleted file mode 100644 index d17bdc006..000000000 --- a/res/images/icon_installing_overlay05.png +++ /dev/null diff --git a/res/images/icon_installing_overlay06.png b/res/images/icon_installing_overlay06.png Binary files differdeleted file mode 100644 index 1200b75cb..000000000 --- a/res/images/icon_installing_overlay06.png +++ /dev/null diff --git a/res/images/icon_installing_overlay07.png b/res/images/icon_installing_overlay07.png Binary files differdeleted file mode 100644 index 3838a85ad..000000000 --- a/res/images/icon_installing_overlay07.png +++ /dev/null diff --git a/res/images/indeterminate01.png b/res/images/indeterminate01.png Binary files differdeleted file mode 100644 index 933528d6d..000000000 --- a/res/images/indeterminate01.png +++ /dev/null diff --git a/res/images/indeterminate02.png b/res/images/indeterminate02.png Binary files differdeleted file mode 100644 index d760e2bdd..000000000 --- a/res/images/indeterminate02.png +++ /dev/null diff --git a/res/images/indeterminate03.png b/res/images/indeterminate03.png Binary files differdeleted file mode 100644 index 0e97399d1..000000000 --- a/res/images/indeterminate03.png +++ /dev/null diff --git a/res/images/indeterminate04.png b/res/images/indeterminate04.png Binary files differdeleted file mode 100644 index c7d5b4e04..000000000 --- a/res/images/indeterminate04.png +++ /dev/null diff --git a/res/images/indeterminate05.png b/res/images/indeterminate05.png Binary files differdeleted file mode 100644 index d6fb2a032..000000000 --- a/res/images/indeterminate05.png +++ /dev/null diff --git a/res/images/indeterminate06.png b/res/images/indeterminate06.png Binary files differdeleted file mode 100644 index 44867619f..000000000 --- a/res/images/indeterminate06.png +++ /dev/null diff --git a/screen_ui.cpp b/screen_ui.cpp index 8376341c3..38b21f84c 100644 --- a/screen_ui.cpp +++ b/screen_ui.cpp @@ -69,20 +69,8 @@ ScreenRecoveryUI::ScreenRecoveryUI() : menu_top(0), menu_items(0), menu_sel(0), - - // These values are correct for the default image resources - // provided with the android platform. Devices which use - // different resources should have a subclass of ScreenRecoveryUI - // that overrides Init() to set these values appropriately and - // then call the superclass Init(). animation_fps(20), - indeterminate_frames(6), - installing_frames(7), - install_overlay_offset_x(13), - install_overlay_offset_y(190), - overlay_offset_x(-1), - overlay_offset_y(-1) { - + installing_frames(-1) { for (int i = 0; i < 5; i++) backgroundIcon[i] = NULL; @@ -90,20 +78,6 @@ ScreenRecoveryUI::ScreenRecoveryUI() : self = this; } -// Draw the given frame over the installation overlay animation. The -// background is not cleared or draw with the base icon first; we -// assume that the frame already contains some other frame of the -// animation. Does nothing if no overlay animation is defined. -// Should only be called with updateMutex locked. -void ScreenRecoveryUI::draw_install_overlay_locked(int frame) { - if (installationOverlay == NULL || overlay_offset_x < 0) return; - gr_surface surface = installationOverlay[frame]; - int iconWidth = gr_get_width(surface); - int iconHeight = gr_get_height(surface); - gr_blit(surface, 0, 0, iconWidth, iconHeight, - overlay_offset_x, overlay_offset_y); -} - // Clear the screen and draw the currently selected background icon (if any). // Should only be called with updateMutex locked. void ScreenRecoveryUI::draw_background_locked(Icon icon) @@ -114,6 +88,9 @@ void ScreenRecoveryUI::draw_background_locked(Icon icon) if (icon) { gr_surface surface = backgroundIcon[icon]; + if (icon == INSTALLING_UPDATE || icon == ERASING) { + surface = installation[installingFrame]; + } gr_surface text_surface = backgroundText[icon]; int iconWidth = gr_get_width(surface); @@ -121,16 +98,13 @@ void ScreenRecoveryUI::draw_background_locked(Icon icon) int textWidth = gr_get_width(text_surface); int textHeight = gr_get_height(text_surface); - int iconX = (gr_fb_width() - iconWidth) / 2; - int iconY = (gr_fb_height() - (iconHeight+textHeight+40)) / 2; + iconX = (gr_fb_width() - iconWidth) / 2; + iconY = (gr_fb_height() - (iconHeight+textHeight+40)) / 2; int textX = (gr_fb_width() - textWidth) / 2; int textY = ((gr_fb_height() - (iconHeight+textHeight+40)) / 2) + iconHeight + 40; gr_blit(surface, 0, 0, iconWidth, iconHeight, iconX, iconY); - if (icon == INSTALLING_UPDATE || icon == ERASING) { - draw_install_overlay_locked(installingFrame); - } gr_color(255, 255, 255, 255); gr_texticon(textX, textY, text_surface); @@ -144,7 +118,8 @@ void ScreenRecoveryUI::draw_progress_locked() if (currentIcon == ERROR) return; if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) { - draw_install_overlay_locked(installingFrame); + gr_surface icon = installation[installingFrame]; + gr_blit(icon, 0, 0, gr_get_width(icon), gr_get_height(icon), iconX, iconY); } if (progressBarType != EMPTY) { @@ -181,18 +156,6 @@ void ScreenRecoveryUI::draw_progress_locked() } } } - - if (progressBarType == INDETERMINATE) { - static int frame = 0; - gr_blit(progressBarIndeterminate[frame], 0, 0, width, height, dx, dy); - // in RTL locales, we run the animation backwards, which - // makes the spinner spin the other way. - if (rtl_locale) { - frame = (frame + indeterminate_frames - 1) % indeterminate_frames; - } else { - frame = (frame + 1) % indeterminate_frames; - } - } } } @@ -319,12 +282,6 @@ void ScreenRecoveryUI::progress_loop() { redraw = 1; } - // update the progress bar animation, if active - // skip this if we have a text overlay (too expensive to update) - if (progressBarType == INDETERMINATE && !show_text) { - redraw = 1; - } - // move the progress bar forward on timed intervals, if configured int duration = progressScopeDuration; if (progressBarType == DETERMINATE && duration > 0) { @@ -355,6 +312,13 @@ void ScreenRecoveryUI::LoadBitmap(const char* filename, gr_surface* surface) { } } +void ScreenRecoveryUI::LoadBitmapArray(const char* filename, int* frames, gr_surface** surface) { + int result = res_create_multi_surface(filename, frames, surface); + if (result < 0) { + LOGE("missing bitmap %s\n(Code %d)\n", filename, result); + } +} + void ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, gr_surface* surface) { int result = res_create_localized_surface(filename, surface); if (result < 0) { @@ -376,7 +340,9 @@ void ScreenRecoveryUI::Init() text_cols = gr_fb_width() / char_width; if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1; - LoadBitmap("icon_installing", &backgroundIcon[INSTALLING_UPDATE]); + backgroundIcon[NONE] = NULL; + LoadBitmapArray("icon_installing", &installing_frames, &installation); + backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[0] : NULL; backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; LoadBitmap("icon_error", &backgroundIcon[ERROR]); backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR]; @@ -389,31 +355,6 @@ void ScreenRecoveryUI::Init() LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]); LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); - int i; - - progressBarIndeterminate = (gr_surface*)malloc(indeterminate_frames * - sizeof(gr_surface)); - for (i = 0; i < indeterminate_frames; ++i) { - char filename[40]; - // "indeterminate01.png", "indeterminate02.png", ... - sprintf(filename, "indeterminate%02d", i+1); - LoadBitmap(filename, progressBarIndeterminate+i); - } - - if (installing_frames > 0) { - installationOverlay = (gr_surface*)malloc(installing_frames * - sizeof(gr_surface)); - for (i = 0; i < installing_frames; ++i) { - char filename[40]; - // "icon_installing_overlay01.png", - // "icon_installing_overlay02.png", ... - sprintf(filename, "icon_installing_overlay%02d", i+1); - LoadBitmap(filename, installationOverlay+i); - } - } else { - installationOverlay = NULL; - } - pthread_create(&progress_t, NULL, progress_thread, NULL); RecoveryUI::Init(); @@ -446,16 +387,6 @@ void ScreenRecoveryUI::SetBackground(Icon icon) { pthread_mutex_lock(&updateMutex); - // Adjust the offset to account for the positioning of the - // base image on the screen. - if (backgroundIcon[icon] != NULL) { - gr_surface bg = backgroundIcon[icon]; - gr_surface text = backgroundText[icon]; - overlay_offset_x = install_overlay_offset_x + (gr_fb_width() - gr_get_width(bg)) / 2; - overlay_offset_y = install_overlay_offset_y + - (gr_fb_height() - (gr_get_height(bg) + gr_get_height(text) + 40)) / 2; - } - currentIcon = icon; update_screen_locked(); @@ -495,7 +426,7 @@ void ScreenRecoveryUI::SetProgress(float fraction) if (fraction > 1.0) fraction = 1.0; if (progressBarType == DETERMINATE && fraction > progress) { // Skip updates that aren't visibly different. - int width = gr_get_width(progressBarIndeterminate[0]); + int width = gr_get_width(progressBarEmpty); float scale = width * progressScopeSize; if ((int) (progress * scale) != (int) (fraction * scale)) { progress = fraction; diff --git a/screen_ui.h b/screen_ui.h index fc35d95b6..ada006d1e 100644 --- a/screen_ui.h +++ b/screen_ui.h @@ -69,8 +69,7 @@ class ScreenRecoveryUI : public RecoveryUI { pthread_mutex_t updateMutex; gr_surface backgroundIcon[5]; gr_surface backgroundText[5]; - gr_surface *installationOverlay; - gr_surface *progressBarIndeterminate; + gr_surface *installation; gr_surface progressBarEmpty; gr_surface progressBarFill; @@ -100,9 +99,9 @@ class ScreenRecoveryUI : public RecoveryUI { pthread_t progress_t; int animation_fps; - int indeterminate_frames; int installing_frames; - int overlay_offset_x, overlay_offset_y; + + int iconX, iconY; void draw_install_overlay_locked(int frame); void draw_background_locked(Icon icon); @@ -114,6 +113,7 @@ class ScreenRecoveryUI : public RecoveryUI { void progress_loop(); void LoadBitmap(const char* filename, gr_surface* surface); + void LoadBitmapArray(const char* filename, int* frames, gr_surface** surface); void LoadLocalizedBitmap(const char* filename, gr_surface* surface); }; |