Thin3DTexture *Thin3DContext::CreateTextureFromFile(const char *filename, T3DImageType type) { Thin3DTexture *tex = CreateTexture(); if (!tex->LoadFromFile(filename, type)) { tex->Release(); return NULL; } return tex; }
// TODO: Remove the code duplication between this and LoadFromFileData Thin3DTexture *Thin3DContext::CreateTextureFromFileData(const uint8_t *data, int size, T3DImageType type) { int width[16], height[16], zim_flags = 0; uint8_t *image[16] = { nullptr }; int num_levels = 0; T3DImageFormat fmt; if (type == DETECT) { type = DetectImageFileType(data, size); } if (type == TYPE_UNKNOWN) { ELOG("File has unknown format"); return nullptr; } switch (type) { case ZIM: num_levels = LoadZIMPtr((const uint8_t *)data, size, width, height, &zim_flags, image); fmt = ZimToT3DFormat(zim_flags & ZIM_FORMAT_MASK); break; case PNG: if (1 != pngLoadPtr((const unsigned char *)data, size, &width[0], &height[0], &image[0], false)) { return NULL; } num_levels = 1; fmt = RGBA8888; break; default: ELOG("Unknown image format"); return nullptr; } if (num_levels == 0) { return NULL; } Thin3DTexture *tex = CreateTexture(LINEAR2D, fmt, width[0], height[0], 1, num_levels); for (int i = 0; i < num_levels; i++) { tex->SetImageData(0, 0, 0, width[i], height[i], 1, i, width[i] * 4, image[i]); free(image[i]); } tex->Finalize(zim_flags); return tex; }
void AsyncImageFileView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { // TODO: involve sizemode if (texture_) { float texw = (float)texture_->Width(); float texh = (float)texture_->Height(); switch (sizeMode_) { case UI::IS_DEFAULT: default: w = texw; h = texh; break; } } else { w = 16; h = 16; } }
void HttpImageFileView::SetFilename(std::string filename) { if (path_ != filename) { textureFailed_ = false; path_ = filename; if (texture_) { texture_->Release(); texture_ = nullptr; } } }
// TODO: Remove the code duplication between this and LoadFromFileData Thin3DTexture *Thin3DContext::CreateTextureFromFileData(const uint8_t *data, int size, T3DImageType type) { int width[16], height[16]; int num_levels = 0; int zim_flags = 0; T3DImageFormat fmt; uint8_t *image[16] = { nullptr }; if (!LoadTextureLevels(data, size, type, width, height, &num_levels, &fmt, image, &zim_flags)) { return NULL; } Thin3DTexture *tex = CreateTexture(LINEAR2D, fmt, width[0], height[0], 1, num_levels); for (int i = 0; i < num_levels; i++) { tex->SetImageData(0, 0, 0, width[i], height[i], 1, i, width[i] * 4, image[i]); free(image[i]); } tex->Finalize(zim_flags); return tex; }
void HttpImageFileView::GetContentDimensions(const UIContext &dc, float &w, float &h) const { switch (sizeMode_) { case UI::IS_FIXED: w = fixedSizeW_; h = fixedSizeH_; break; case UI::IS_DEFAULT: default: if (texture_) { float texw = (float)texture_->Width(); float texh = (float)texture_->Height(); w = texw; h = texh; } else { w = 16; h = 16; } break; } }
void SavedataButton::Draw(UIContext &dc) { GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), savePath_, GAMEINFO_WANTSIZE); Thin3DTexture *texture = 0; u32 color = 0, shadowColor = 0; using namespace UI; if (ginfo->iconTexture) { texture = ginfo->iconTexture; } int x = bounds_.x; int y = bounds_.y; int w = 144; int h = bounds_.h; UI::Style style = dc.theme->itemStyle; if (down_) style = dc.theme->itemDownStyle; h = bounds_.h; if (HasFocus()) style = down_ ? dc.theme->itemDownStyle : dc.theme->itemFocusedStyle; Drawable bg = style.background; dc.Draw()->Flush(); dc.RebindTexture(); dc.FillRect(bg, bounds_); dc.Draw()->Flush(); if (texture) { color = whiteAlpha(ease((time_now_d() - ginfo->timeIconWasLoaded) * 2)); shadowColor = blackAlpha(ease((time_now_d() - ginfo->timeIconWasLoaded) * 2)); float tw = texture->Width(); float th = texture->Height(); // Adjust position so we don't stretch the image vertically or horizontally. // TODO: Add a param to specify fit? The below assumes it's never too wide. float nw = h * tw / th; x += (w - nw) / 2.0f; w = nw; } int txOffset = down_ ? 4 : 0; txOffset = 0; Bounds overlayBounds = bounds_; // Render button int dropsize = 10; if (texture) { if (txOffset) { dropsize = 3; y += txOffset * 2; overlayBounds.y += txOffset * 2; } if (HasFocus()) { dc.Draw()->Flush(); dc.RebindTexture(); float pulse = sinf(time_now() * 7.0f) * 0.25 + 0.8; dc.Draw()->DrawImage4Grid(dc.theme->dropShadow4Grid, x - dropsize*1.5f, y - dropsize*1.5f, x + w + dropsize*1.5f, y + h + dropsize*1.5f, alphaMul(color, pulse), 1.0f); dc.Draw()->Flush(); } else { dc.Draw()->Flush(); dc.RebindTexture(); dc.Draw()->DrawImage4Grid(dc.theme->dropShadow4Grid, x - dropsize, y - dropsize*0.5f, x + w + dropsize, y + h + dropsize*1.5, alphaMul(shadowColor, 0.5f), 1.0f); dc.Draw()->Flush(); } } if (texture) { dc.Draw()->Flush(); dc.GetThin3DContext()->SetTexture(0, texture); dc.Draw()->DrawTexRect(x, y, x + w, y + h, 0, 0, 1, 1, color); dc.Draw()->Flush(); } dc.Draw()->Flush(); dc.RebindTexture(); dc.SetFontStyle(dc.theme->uiFont); float tw, th; dc.Draw()->Flush(); dc.PushScissor(bounds_); if (title_.empty() && !ginfo->title.empty()) { title_ = CleanSaveString(ginfo->title); } if (subtitle_.empty() && ginfo->gameSize > 0) { std::string savedata_title = ginfo->paramSFO.GetValueString("SAVEDATA_TITLE"); subtitle_ = CleanSaveString(savedata_title) + StringFromFormat(" (%d kB)", ginfo->gameSize / 1024); } dc.MeasureText(dc.GetFontStyle(), title_.c_str(), &tw, &th, 0); int availableWidth = bounds_.w - 150; float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f; float tx = 150; if (availableWidth < tw) { float overageRatio = 1.5f * availableWidth * 1.0f / tw; tx -= (1.0f + sin(time_now_d() * overageRatio)) * sineWidth; Bounds tb = bounds_; tb.x = bounds_.x + 150; tb.w = bounds_.w - 150; dc.PushScissor(tb); } dc.DrawText(title_.c_str(), bounds_.x + tx, bounds_.y + 4, style.fgColor, ALIGN_TOPLEFT); dc.SetFontScale(0.6f, 0.6f); dc.DrawText(subtitle_.c_str(), bounds_.x + tx, bounds_.y2() - 7, style.fgColor, ALIGN_BOTTOM); dc.SetFontScale(1.0f, 1.0f); if (availableWidth < tw) { dc.PopScissor(); } dc.Draw()->Flush(); dc.PopScissor(); dc.RebindTexture(); }